mirror of
https://github.com/zaphar/ucg.git
synced 2025-07-22 18:19:54 -04:00
DEV: Self references in tuples.
This commit is contained in:
parent
b024d23110
commit
d1014d4b6e
@ -211,6 +211,9 @@ pub enum Op {
|
||||
// Runtime hooks
|
||||
Runtime(Hook),
|
||||
Render,
|
||||
// The self lookup for tuples.
|
||||
PushSelf,
|
||||
PopSelf,
|
||||
}
|
||||
|
||||
use super::ir::Val;
|
||||
|
@ -220,10 +220,7 @@ fn tuple_ops() {
|
||||
("foo".to_owned(), Rc::new(P(Int(2)))),
|
||||
])),
|
||||
vec![
|
||||
InitTuple, // Override tuple
|
||||
Val(Str("foo".to_owned())),
|
||||
Val(Int(2)),
|
||||
Field,
|
||||
Sym("tpl".to_owned()),
|
||||
InitTuple, // Target tuple
|
||||
Sym("bar".to_owned()),
|
||||
Val(Str("ux".to_owned())),
|
||||
@ -233,6 +230,13 @@ fn tuple_ops() {
|
||||
Val(Str("foo".to_owned())),
|
||||
Val(Int(1)),
|
||||
Field,
|
||||
Bind,
|
||||
DeRef("tpl".to_owned()),
|
||||
InitTuple,
|
||||
// Begin the field overrides
|
||||
Val(Str("foo".to_owned())),
|
||||
Val(Int(2)),
|
||||
Field,
|
||||
Cp, // Do the tuple copy operation
|
||||
] => C(Tuple(vec![
|
||||
("bar".to_owned(), Rc::new(P(Str("quux".to_owned())))),
|
||||
@ -400,10 +404,6 @@ fn function_definition_and_call() {
|
||||
fn module_call() {
|
||||
assert_cases![
|
||||
vec![
|
||||
InitTuple, // 0 // override tuple
|
||||
Sym("one".to_owned()), // 1
|
||||
Val(Int(11)), // 2
|
||||
Field, // 3
|
||||
Sym("m".to_owned()), // 4 // binding name for module
|
||||
InitTuple, // 5 // Module tuple bindings
|
||||
Sym("one".to_owned()), // 6
|
||||
@ -422,15 +422,15 @@ fn module_call() {
|
||||
Return, // 19 // end the module
|
||||
Bind, // 20 // bind module to the binding name
|
||||
DeRef("m".to_owned()), // 21
|
||||
InitTuple, // 0 // override tuple
|
||||
Sym("one".to_owned()), // 1
|
||||
Val(Int(11)), // 2
|
||||
Field, // 3
|
||||
Cp, // 22 // Call the module
|
||||
] => C(Tuple(vec![
|
||||
("foo".to_owned(), Rc::new(P(Int(11)))),
|
||||
])),
|
||||
vec![
|
||||
InitTuple, // 0 // override tuple
|
||||
Sym("one".to_owned()), // 1
|
||||
Val(Int(11)), // 2
|
||||
Field, // 3
|
||||
Sym("m".to_owned()), // 4 // binding name for module
|
||||
InitTuple, // 5 // Module tuple bindings
|
||||
Sym("one".to_owned()), // 6
|
||||
@ -450,6 +450,10 @@ fn module_call() {
|
||||
Return, // 20 // end the module
|
||||
Bind, // 21 // bind module to the binding name
|
||||
DeRef("m".to_owned()), // 22
|
||||
InitTuple, // 0 // override tuple
|
||||
Sym("one".to_owned()), // 1
|
||||
Val(Int(11)), // 2
|
||||
Field, // 3
|
||||
Cp, // 23
|
||||
] => P(Int(1)),
|
||||
];
|
||||
@ -737,6 +741,11 @@ fn tuple_copies() {
|
||||
assert_parse_cases![
|
||||
"let tpl = { v = 1, }; tpl{};" => C(Tuple(vec![("v".to_owned(), Rc::new(P(Int(1))))])),
|
||||
"let tpl = { v = 1, }; tpl{v=2};" => C(Tuple(vec![("v".to_owned(), Rc::new(P(Int(2))))])),
|
||||
// Tests for Self lookups
|
||||
"let tpl = { v = 1, w = 2}; tpl{v=self.w};" => C(Tuple(vec![
|
||||
("v".to_owned(), Rc::new(P(Int(2)))),
|
||||
("w".to_owned(), Rc::new(P(Int(2)))),
|
||||
])),
|
||||
];
|
||||
}
|
||||
|
||||
|
@ -442,14 +442,16 @@ impl AST {
|
||||
ops.push(Op::FCall, func_pos);
|
||||
}
|
||||
Expression::Copy(def) => {
|
||||
Self::translate_value(def.selector, &mut ops, root);
|
||||
ops.push(Op::PushSelf, def.pos.clone());
|
||||
ops.push(Op::InitTuple, def.pos.clone());
|
||||
for (t, e) in def.fields {
|
||||
ops.push(Op::Sym(t.fragment), t.pos.clone());
|
||||
Self::translate_expr(e, &mut ops, root);
|
||||
ops.push(Op::Field, t.pos.clone());
|
||||
}
|
||||
Self::translate_value(def.selector, &mut ops, root);
|
||||
ops.push(Op::Cp, def.pos);
|
||||
ops.push(Op::Cp, def.pos.clone());
|
||||
ops.push(Op::PopSelf, def.pos);
|
||||
}
|
||||
Expression::Debug(def) => {
|
||||
let mut buffer: Vec<u8> = Vec::new();
|
||||
|
@ -39,6 +39,7 @@ where
|
||||
ops: OpPointer,
|
||||
pub env: Rc<RefCell<Environment<O, E>>>,
|
||||
pub last: Option<(Rc<Value>, Position)>,
|
||||
self_stack: Vec<(Rc<Value>, Position)>,
|
||||
}
|
||||
|
||||
impl<'a, O, E> VM<O, E>
|
||||
@ -58,6 +59,7 @@ where
|
||||
ops: ops,
|
||||
env: env,
|
||||
last: None,
|
||||
self_stack: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
@ -69,6 +71,7 @@ where
|
||||
ops: self.ops.clone(),
|
||||
env: self.env.clone(),
|
||||
last: self.last,
|
||||
self_stack: self.self_stack,
|
||||
}
|
||||
}
|
||||
|
||||
@ -144,6 +147,8 @@ where
|
||||
Op::Typ => self.op_typ()?,
|
||||
Op::Runtime(h) => self.op_runtime(h, pos)?,
|
||||
Op::Render => self.op_render()?,
|
||||
Op::PushSelf => self.op_push_self()?,
|
||||
Op::PopSelf => self.op_pop_self()?,
|
||||
};
|
||||
}
|
||||
Ok(())
|
||||
@ -574,6 +579,20 @@ where
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn op_push_self(&mut self) -> Result<(), Error> {
|
||||
// We'll need a self stack.
|
||||
let (val, pos) = self.pop()?;
|
||||
self.self_stack.push((val.clone(), pos.clone()));
|
||||
self.push(val.clone(), pos)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn op_pop_self(&mut self) -> Result<(), Error> {
|
||||
// We'll need a self stack.
|
||||
self.self_stack.pop();
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn op_bind(&mut self, strict: bool) -> Result<(), Error> {
|
||||
// pop val off stack.
|
||||
let (val, val_pos) = self.pop()?;
|
||||
@ -671,10 +690,10 @@ where
|
||||
}
|
||||
|
||||
fn op_copy(&mut self, pos: Position) -> Result<(), Error> {
|
||||
// get next value. It should be a Module or Tuple.
|
||||
let (tgt, tgt_pos) = dbg!(self.pop()?);
|
||||
// This value should always be a tuple
|
||||
let (override_val, _) = dbg!(self.pop()?);
|
||||
// get targett value. It should be a Module or Tuple.
|
||||
let (tgt, tgt_pos) = dbg!(self.pop()?);
|
||||
let overrides = if let &C(Tuple(ref oflds)) = override_val.as_ref() {
|
||||
oflds.clone()
|
||||
} else {
|
||||
@ -782,6 +801,15 @@ where
|
||||
name: &str,
|
||||
pos: &Position,
|
||||
) -> Result<(Rc<Value>, Position), Error> {
|
||||
if name == "self" {
|
||||
if let Some((val, pos)) = self.self_stack.last() {
|
||||
return Ok((val.clone(), pos.clone()));
|
||||
}
|
||||
return Err(dbg!(Error::new(
|
||||
format!("No such binding {}", name),
|
||||
pos.clone()
|
||||
)));
|
||||
}
|
||||
match self.symbols.get(name) {
|
||||
Some((ref v, ref pos)) => Ok((v.clone(), pos.clone())),
|
||||
None => Err(dbg!(Error::new(
|
||||
|
Loading…
x
Reference in New Issue
Block a user