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)),
|
||||
Field,
|
||||
Field,
|
||||
InitList,
|
||||
Val(Str("foo".to_owned())),
|
||||
Element,
|
||||
Index,
|
||||
Val(Str("bar".to_owned())),
|
||||
Element,
|
||||
Index,
|
||||
] => P(Int(1)),
|
||||
vec![
|
||||
@ -466,9 +464,7 @@ fn index_operation() {
|
||||
Element,
|
||||
Val(Str("bar".to_owned())),
|
||||
Element,
|
||||
InitList,
|
||||
Val(Int(0)),
|
||||
Element,
|
||||
Index,
|
||||
] => P(Str("foo".to_owned())),
|
||||
vec![
|
||||
@ -480,11 +476,9 @@ fn index_operation() {
|
||||
Val(Str("bar".to_owned())),
|
||||
Element,
|
||||
Field,
|
||||
InitList,
|
||||
Val(Str("field".to_owned())),
|
||||
Element,
|
||||
Index,
|
||||
Val(Int(0)),
|
||||
Element,
|
||||
Index,
|
||||
] => 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]
|
||||
fn simple_not_expr() {
|
||||
assert_parse_cases!(
|
||||
|
@ -136,9 +136,26 @@ impl AST {
|
||||
Self::translate_expr(*def.left, &mut ops);
|
||||
ops.push(Op::Mod);
|
||||
}
|
||||
BinaryExprType::IN | BinaryExprType::DOT => {
|
||||
BinaryExprType::IN => {
|
||||
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::Empty(_pos) => ops.push(Op::Val(Primitive::Empty)),
|
||||
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::List(_els) => unimplemented!("Select expression are not implmented yet"),
|
||||
}
|
||||
|
@ -541,25 +541,33 @@ impl<'a> VM {
|
||||
}
|
||||
|
||||
fn op_index(&mut self) -> Result<(), Error> {
|
||||
let path_val = self.pop()?;
|
||||
let path = if let &C(List(ref elems)) = path_val.as_ref() {
|
||||
elems.clone()
|
||||
} else {
|
||||
return Err(dbg!(Error {}));
|
||||
};
|
||||
let target_val = self.pop()?;
|
||||
match target_val.as_ref() {
|
||||
&P(_) | &S(_) | &T(_) | &F(_) | &M(_) => return Err(dbg!(Error {})),
|
||||
_ => {
|
||||
let mut out = target_val.clone();
|
||||
for p in path {
|
||||
let tgt = self.find_in_value(&p, &out)?;
|
||||
out = tgt;
|
||||
// left and then right
|
||||
let right = dbg!(self.pop()?);
|
||||
let left = dbg!(self.pop()?);
|
||||
match right.as_ref() {
|
||||
&P(Int(i)) => {
|
||||
if let &C(List(ref elems)) = left.as_ref() {
|
||||
if i < (elems.len() as i64) && i >= 0 {
|
||||
self.push(elems[i as usize].clone())?;
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
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> {
|
||||
|
Loading…
x
Reference in New Issue
Block a user