mirror of
https://github.com/zaphar/ucg.git
synced 2025-07-22 18:19:54 -04:00
DEV: List indexing works.
This commit is contained in:
parent
40fc6fe15f
commit
c792d758d7
@ -453,11 +453,9 @@ fn index_operation() {
|
|||||||
Val(Int(1)),
|
Val(Int(1)),
|
||||||
Field,
|
Field,
|
||||||
Field,
|
Field,
|
||||||
InitList,
|
|
||||||
Val(Str("foo".to_owned())),
|
Val(Str("foo".to_owned())),
|
||||||
Element,
|
Index,
|
||||||
Val(Str("bar".to_owned())),
|
Val(Str("bar".to_owned())),
|
||||||
Element,
|
|
||||||
Index,
|
Index,
|
||||||
] => P(Int(1)),
|
] => P(Int(1)),
|
||||||
vec![
|
vec![
|
||||||
@ -466,9 +464,7 @@ fn index_operation() {
|
|||||||
Element,
|
Element,
|
||||||
Val(Str("bar".to_owned())),
|
Val(Str("bar".to_owned())),
|
||||||
Element,
|
Element,
|
||||||
InitList,
|
|
||||||
Val(Int(0)),
|
Val(Int(0)),
|
||||||
Element,
|
|
||||||
Index,
|
Index,
|
||||||
] => P(Str("foo".to_owned())),
|
] => P(Str("foo".to_owned())),
|
||||||
vec![
|
vec![
|
||||||
@ -480,11 +476,9 @@ fn index_operation() {
|
|||||||
Val(Str("bar".to_owned())),
|
Val(Str("bar".to_owned())),
|
||||||
Element,
|
Element,
|
||||||
Field,
|
Field,
|
||||||
InitList,
|
|
||||||
Val(Str("field".to_owned())),
|
Val(Str("field".to_owned())),
|
||||||
Element,
|
Index,
|
||||||
Val(Int(0)),
|
Val(Int(0)),
|
||||||
Element,
|
|
||||||
Index,
|
Index,
|
||||||
] => P(Str("foo".to_owned())),
|
] => P(Str("foo".to_owned())),
|
||||||
];
|
];
|
||||||
@ -612,6 +606,27 @@ fn simple_binary_expr() {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn dot_expressions() {
|
||||||
|
let mut ops = vec![
|
||||||
|
Sym("foo".to_owned()),
|
||||||
|
InitList,
|
||||||
|
Val(Int(0)),
|
||||||
|
Element,
|
||||||
|
Val(Int(1)),
|
||||||
|
Element,
|
||||||
|
Val(Int(2)),
|
||||||
|
Element,
|
||||||
|
Bind,
|
||||||
|
];
|
||||||
|
|
||||||
|
let stmts = parse(OffsetStrIter::from(dbg!("foo.0;")), None).unwrap();
|
||||||
|
ops.append(&mut translate::AST::translate(stmts));
|
||||||
|
let ops = Rc::new(ops);
|
||||||
|
let mut vm = VM::new("foo.ucg", ops.clone());
|
||||||
|
vm.run().unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn simple_not_expr() {
|
fn simple_not_expr() {
|
||||||
assert_parse_cases!(
|
assert_parse_cases!(
|
||||||
|
@ -136,9 +136,26 @@ impl AST {
|
|||||||
Self::translate_expr(*def.left, &mut ops);
|
Self::translate_expr(*def.left, &mut ops);
|
||||||
ops.push(Op::Mod);
|
ops.push(Op::Mod);
|
||||||
}
|
}
|
||||||
BinaryExprType::IN | BinaryExprType::DOT => {
|
BinaryExprType::IN => {
|
||||||
unimplemented!("Binary expressions are not implmented yet")
|
unimplemented!("Binary expressions are not implmented yet")
|
||||||
// TODO
|
}
|
||||||
|
BinaryExprType::DOT => {
|
||||||
|
// Dot expressions expect the left side to be pushed first
|
||||||
|
Self::translate_expr(*def.left, &mut ops);
|
||||||
|
// Symbols on the right side should be converted to strings to satisfy
|
||||||
|
// the Index operation contract.
|
||||||
|
match *def.right {
|
||||||
|
Expression::Simple(Value::Symbol(name)) => {
|
||||||
|
Self::translate_expr(
|
||||||
|
Expression::Simple(Value::Str(name)),
|
||||||
|
&mut ops,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
expr => {
|
||||||
|
Self::translate_expr(expr, &mut ops);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ops.push(Op::Index);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -171,7 +188,9 @@ impl AST {
|
|||||||
Value::Str(s) => ops.push(Op::Val(Primitive::Str(s.val))),
|
Value::Str(s) => ops.push(Op::Val(Primitive::Str(s.val))),
|
||||||
Value::Empty(_pos) => ops.push(Op::Val(Primitive::Empty)),
|
Value::Empty(_pos) => ops.push(Op::Val(Primitive::Empty)),
|
||||||
Value::Boolean(b) => ops.push(Op::Val(Primitive::Bool(b.val))),
|
Value::Boolean(b) => ops.push(Op::Val(Primitive::Bool(b.val))),
|
||||||
Value::Symbol(s) => ops.push(Op::Sym(s.val)),
|
Value::Symbol(s) => {
|
||||||
|
ops.push(Op::DeRef(s.val));
|
||||||
|
}
|
||||||
Value::Tuple(_flds) => unimplemented!("Select expression are not implmented yet"),
|
Value::Tuple(_flds) => unimplemented!("Select expression are not implmented yet"),
|
||||||
Value::List(_els) => unimplemented!("Select expression are not implmented yet"),
|
Value::List(_els) => unimplemented!("Select expression are not implmented yet"),
|
||||||
}
|
}
|
||||||
|
@ -541,25 +541,33 @@ impl<'a> VM {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn op_index(&mut self) -> Result<(), Error> {
|
fn op_index(&mut self) -> Result<(), Error> {
|
||||||
let path_val = self.pop()?;
|
// left and then right
|
||||||
let path = if let &C(List(ref elems)) = path_val.as_ref() {
|
let right = dbg!(self.pop()?);
|
||||||
elems.clone()
|
let left = dbg!(self.pop()?);
|
||||||
} else {
|
match right.as_ref() {
|
||||||
return Err(dbg!(Error {}));
|
&P(Int(i)) => {
|
||||||
};
|
if let &C(List(ref elems)) = left.as_ref() {
|
||||||
let target_val = self.pop()?;
|
if i < (elems.len() as i64) && i >= 0 {
|
||||||
match target_val.as_ref() {
|
self.push(elems[i as usize].clone())?;
|
||||||
&P(_) | &S(_) | &T(_) | &F(_) | &M(_) => return Err(dbg!(Error {})),
|
return Ok(());
|
||||||
_ => {
|
}
|
||||||
let mut out = target_val.clone();
|
|
||||||
for p in path {
|
|
||||||
let tgt = self.find_in_value(&p, &out)?;
|
|
||||||
out = tgt;
|
|
||||||
}
|
}
|
||||||
self.push(out)?;
|
}
|
||||||
|
&P(Str(ref s)) => {
|
||||||
|
if let &C(Tuple(ref flds)) = left.as_ref() {
|
||||||
|
for &(ref key, ref val) in flds.iter() {
|
||||||
|
if key == s {
|
||||||
|
self.push(val.clone())?;
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
// noop
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
Ok(())
|
return Err(dbg!(Error {}));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn op_copy(&mut self) -> Result<(), Error> {
|
fn op_copy(&mut self) -> Result<(), Error> {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user