mirror of
https://github.com/zaphar/ucg.git
synced 2025-07-24 18:39:50 -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);
|
assert!(ops.len() > 0);
|
||||||
let mut vm = VM::new("foo.ucg", ops.clone());
|
let mut vm = VM::new("foo.ucg", ops.clone());
|
||||||
vm.run().unwrap();
|
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)),
|
"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 {
|
impl AST {
|
||||||
pub fn translate(stmts: Vec<Statement>) -> Vec<Op> {
|
pub fn translate(stmts: Vec<Statement>) -> Vec<Op> {
|
||||||
let mut ops = Vec::new();
|
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 {
|
for stmt in stmts {
|
||||||
match stmt {
|
match stmt {
|
||||||
Statement::Expression(expr) => Self::translate_expr(expr, &mut ops),
|
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>) {
|
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::FuncOp(_) => unimplemented!("FuncOp expressions are not implmented yet"),
|
||||||
Expression::Import(_) => unimplemented!("Import expressions are not implmented yet"),
|
Expression::Import(_) => unimplemented!("Import expressions are not implmented yet"),
|
||||||
Expression::Include(_) => unimplemented!("Include 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) => {
|
Expression::Not(def) => {
|
||||||
Self::translate_expr(*def.expr, &mut ops);
|
Self::translate_expr(*def.expr, &mut ops);
|
||||||
ops.push(Op::Not);
|
ops.push(Op::Not);
|
||||||
@ -284,7 +321,16 @@ impl AST {
|
|||||||
ops.push(Op::FCall);
|
ops.push(Op::FCall);
|
||||||
dbg!(ops);
|
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"),
|
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> {
|
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() {
|
let (result_ptr, flds) = match mod_val.as_ref() {
|
||||||
&C(Tuple(ref flds)) => (None, flds.clone()),
|
&C(Tuple(ref flds)) => (None, flds.clone()),
|
||||||
&T(ptr) => {
|
&T(ptr) => {
|
||||||
@ -602,9 +602,9 @@ impl<'a> VM {
|
|||||||
fn op_copy(&mut self) -> Result<(), Error> {
|
fn op_copy(&mut self) -> Result<(), Error> {
|
||||||
// TODO Use Cow pointers for this?
|
// TODO Use Cow pointers for this?
|
||||||
// get next value. It should be a Module or Tuple.
|
// 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
|
// 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() {
|
let overrides = if let &C(Tuple(ref oflds)) = override_val.as_ref() {
|
||||||
oflds.clone()
|
oflds.clone()
|
||||||
} else {
|
} else {
|
||||||
@ -642,9 +642,10 @@ impl<'a> VM {
|
|||||||
if let Some(ptr) = result_ptr {
|
if let Some(ptr) = result_ptr {
|
||||||
vm.ops.jump(ptr.clone())?;
|
vm.ops.jump(ptr.clone())?;
|
||||||
vm.run()?;
|
vm.run()?;
|
||||||
self.push(vm.pop()?)?;
|
self.push(dbg!(vm.pop())?)?;
|
||||||
} else {
|
} 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