DEV: Modules work now.

This commit is contained in:
Jeremy Wall 2019-08-15 18:11:54 -05:00
parent e998e582ae
commit 100d963f41
3 changed files with 66 additions and 9 deletions

View File

@ -579,7 +579,7 @@ macro_rules! assert_parse_cases {
assert!(ops.len() > 0);
let mut vm = VM::new("foo.ucg", ops.clone());
vm.run().unwrap();
assert_eq!(dbg!(vm.pop()).unwrap(), Rc::new(case.1));
assert_eq!(vm.pop().unwrap(), Rc::new(case.1));
}
};
@ -716,3 +716,13 @@ fn simple_functions() {
"let f = func(val1, val2) => val1 + val2; f(1, 1);" => P(Int(2)),
];
}
#[test]
fn simple_modules() {
assert_parse_cases![
"let m = module{} => { let v = 1; }; m{};" => C(Tuple(vec![("v".to_owned(), Rc::new(P(Int(1))))])),
"let m = module{} => (v) { let v = 1; }; m{};" => P(Int(1)),
"let m = module{val=NULL} => (v) { let v = mod.val; }; m{val=1};" => P(Int(1)),
"let m = module{val=NULL} => (v) { let v = mod.val + 1; }; m{val=1};" => P(Int(2)),
];
}

View File

@ -22,6 +22,11 @@ pub struct AST();
impl AST {
pub fn translate(stmts: Vec<Statement>) -> Vec<Op> {
let mut ops = Vec::new();
Self::translate_stmts(stmts, &mut ops);
return ops;
}
fn translate_stmts(stmts: Vec<Statement>, mut ops: &mut Vec<Op>) {
for stmt in stmts {
match stmt {
Statement::Expression(expr) => Self::translate_expr(expr, &mut ops),
@ -42,7 +47,6 @@ impl AST {
}
}
}
return ops;
}
fn translate_expr(expr: Expression, mut ops: &mut Vec<Op>) {
@ -267,7 +271,40 @@ impl AST {
Expression::FuncOp(_) => unimplemented!("FuncOp expressions are not implmented yet"),
Expression::Import(_) => unimplemented!("Import expressions are not implmented yet"),
Expression::Include(_) => unimplemented!("Include expressions are not implmented yet"),
Expression::Module(_) => unimplemented!("Module expressions are not implmented yet"),
Expression::Module(def) => {
let argset = def.arg_set;
let out_expr = def.out_expr;
let stmts = def.statements;
// Init our module tuple bindings
ops.push(Op::InitTuple);
for (t, e) in argset {
ops.push(Op::Sym(t.fragment));
Self::translate_expr(e, &mut ops);
ops.push(Op::Field);
}
// If there is one then emit our return expression
if let Some(expr) = out_expr {
// Insert placeholder until we know jptr for this thunk
ops.push(Op::Noop);
let idx = ops.len() - 1;
Self::translate_expr(*expr, &mut ops);
ops.push(Op::Return);
let jptr = ops.len() - idx - 1;
ops[idx] = Op::InitThunk(jptr as i32);
}
// Insert a placeholder Opcode until we know jptr for the
// module.
ops.push(Op::Noop);
let idx = ops.len() - 1;
// Bind our mod tuple.
ops.push(Op::Bind);
// emit all of our statements;
Self::translate_stmts(stmts, &mut ops);
// Return from the module
ops.push(Op::Return);
let jptr = ops.len() - idx - 1;
ops[idx] = Op::Module(jptr as i32);
}
Expression::Not(def) => {
Self::translate_expr(*def.expr, &mut ops);
ops.push(Op::Not);
@ -284,7 +321,16 @@ impl AST {
ops.push(Op::FCall);
dbg!(ops);
}
Expression::Copy(_) => unimplemented!("Copy expressions are not implmented yet"),
Expression::Copy(def) => {
ops.push(Op::InitTuple);
for (t, e) in def.fields {
ops.push(Op::Sym(t.fragment));
Self::translate_expr(e, &mut ops);
ops.push(Op::Field);
}
Self::translate_value(def.selector, &mut ops);
ops.push(Op::Cp);
}
Expression::Debug(_) => unimplemented!("Debug expressions are not implmented yet"),
}
}

View File

@ -235,7 +235,7 @@ impl<'a> VM {
}
fn op_module(&'a mut self, idx: usize, jptr: i32) -> Result<(), Error> {
let mod_val = self.pop()?;
let mod_val = dbg!(self.pop())?;
let (result_ptr, flds) = match mod_val.as_ref() {
&C(Tuple(ref flds)) => (None, flds.clone()),
&T(ptr) => {
@ -602,9 +602,9 @@ impl<'a> VM {
fn op_copy(&mut self) -> Result<(), Error> {
// TODO Use Cow pointers for this?
// get next value. It should be a Module or Tuple.
let tgt = self.pop()?;
let tgt = dbg!(self.pop()?);
// This value should always be a tuple
let override_val = self.pop()?;
let override_val = dbg!(self.pop()?);
let overrides = if let &C(Tuple(ref oflds)) = override_val.as_ref() {
oflds.clone()
} else {
@ -642,9 +642,10 @@ impl<'a> VM {
if let Some(ptr) = result_ptr {
vm.ops.jump(ptr.clone())?;
vm.run()?;
self.push(vm.pop()?)?;
self.push(dbg!(vm.pop())?)?;
} else {
self.push(Rc::new(vm.symbols_to_tuple(false)))?;
dbg!(&vm.symbols);
self.push(Rc::new(dbg!(vm.symbols_to_tuple(false))))?;
}
}
_ => {