From 8c39c3826c00469f767ab28057aa66d2439d8a04 Mon Sep 17 00:00:00 2001 From: Jeremy Wall Date: Tue, 13 Aug 2019 18:16:00 -0500 Subject: [PATCH] DEV: LtEq, GtEq, and in operators work. --- src/build/opcode/mod.rs | 3 ++- src/build/opcode/test.rs | 4 ++++ src/build/opcode/translate.rs | 31 +++++++++++++++++++++++++------ src/build/opcode/vm.rs | 9 +++++++-- 4 files changed, 38 insertions(+), 9 deletions(-) diff --git a/src/build/opcode/mod.rs b/src/build/opcode/mod.rs index 046d635..442ef25 100644 --- a/src/build/opcode/mod.rs +++ b/src/build/opcode/mod.rs @@ -190,7 +190,8 @@ pub enum Op { And(i32), Or(i32), // Spacer operation, Does nothing. - Index, // indexing operation + Index, // indexing operation + SafeIndex, // Safe indexing operation. Does Null Coelescing Noop, // Pending Computation InitThunk(i32), // Basically just used for module return expressions diff --git a/src/build/opcode/test.rs b/src/build/opcode/test.rs index 2f4f511..050b324 100644 --- a/src/build/opcode/test.rs +++ b/src/build/opcode/test.rs @@ -620,6 +620,8 @@ fn simple_binary_expr() { "1<1;" => P(Bool(false)), "2>1;" => P(Bool(true)), "2<1;" => P(Bool(false)), + "2<=1;" => P(Bool(false)), + "2>=1;" => P(Bool(true)), "1!=1;" => P(Bool(false)), "\"foo\" ~ \"bar\";" => P(Bool(false)), "\"foo\" !~ \"bar\";" => P(Bool(true)), @@ -632,6 +634,8 @@ fn simple_binary_expr() { "true || false;" => P(Bool(true)), "false || true;" => P(Bool(true)), "true || true;" => P(Bool(true)), + "foo in {foo = 1};" => P(Bool(true)), + "bar in {foo = 1};" => P(Bool(false)), ) } diff --git a/src/build/opcode/translate.rs b/src/build/opcode/translate.rs index 44971e0..faee138 100644 --- a/src/build/opcode/translate.rs +++ b/src/build/opcode/translate.rs @@ -89,13 +89,14 @@ impl AST { ops.push(Op::Lt); } BinaryExprType::GTEqual => { - // An Equal and an And - //ops.push(Op::GtEqual); - unimplemented!("Binary expressions are not implmented yet") + Self::translate_expr(*def.right, &mut ops); + Self::translate_expr(*def.left, &mut ops); + ops.push(Op::GtEq); } BinaryExprType::LTEqual => { - //ops.push(Op::LtEqual); - unimplemented!("Binary expressions are not implmented yet") + Self::translate_expr(*def.right, &mut ops); + Self::translate_expr(*def.left, &mut ops); + ops.push(Op::LtEq); } BinaryExprType::NotEqual => { Self::translate_expr(*def.right, &mut ops); @@ -144,7 +145,25 @@ impl AST { ops.push(Op::Mod); } BinaryExprType::IN => { - unimplemented!("Binary expressions are not implmented yet") + // Dot expressions expect the left side to be pushed first + Self::translate_expr(*def.right, &mut ops); + // Symbols on the right side should be converted to strings to satisfy + // the Index operation contract. + match *def.left { + 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::SafeIndex); + ops.push(Op::Val(Primitive::Empty)); + ops.push(Op::Equal); + ops.push(Op::Not); } BinaryExprType::DOT => { // Dot expressions expect the left side to be pushed first diff --git a/src/build/opcode/vm.rs b/src/build/opcode/vm.rs index 7abdb99..fa034af 100644 --- a/src/build/opcode/vm.rs +++ b/src/build/opcode/vm.rs @@ -100,7 +100,8 @@ impl<'a> VM { Op::InitTuple => self.push(Rc::new(C(Tuple(Vec::new()))))?, Op::Field => self.op_field()?, Op::Element => self.op_element()?, - Op::Index => self.op_index()?, + Op::Index => self.op_index(false)?, + Op::SafeIndex => self.op_index(true)?, Op::Cp => self.op_copy()?, //TODO(jwall): Should this take a user provided message? Op::Bang => return dbg!(Err(Error {})), @@ -558,7 +559,7 @@ impl<'a> VM { } } - fn op_index(&mut self) -> Result<(), Error> { + fn op_index(&mut self, safe: bool) -> Result<(), Error> { // left and then right let right = self.pop()?; let left = self.pop()?; @@ -585,6 +586,10 @@ impl<'a> VM { // noop } }; + if safe { + self.push(Rc::new(P(Empty))); + return Ok(()); + } return Err(dbg!(Error {})); }