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