mirror of
https://github.com/zaphar/ucg.git
synced 2025-07-22 18:19:54 -04:00
DEV: Modules work now.
This commit is contained in:
parent
e998e582ae
commit
100d963f41
@ -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)),
|
||||
];
|
||||
}
|
||||
|
@ -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"),
|
||||
}
|
||||
}
|
||||
|
@ -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))))?;
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
|
Loading…
x
Reference in New Issue
Block a user