DEV: List indexing works.

This commit is contained in:
Jeremy Wall 2019-08-02 18:55:18 -05:00
parent 40fc6fe15f
commit c792d758d7
3 changed files with 69 additions and 27 deletions

View File

@ -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!(

View File

@ -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"),
}

View File

@ -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 {})),
// 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(());
}
}
}
&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(());
}
}
}
}
_ => {
let mut out = target_val.clone();
for p in path {
let tgt = self.find_in_value(&p, &out)?;
out = tgt;
}
self.push(out)?;
// noop
}
};
Ok(())
return Err(dbg!(Error {}));
}
fn op_copy(&mut self) -> Result<(), Error> {