DEV: LtEq, GtEq, and in operators work.

This commit is contained in:
Jeremy Wall 2019-08-13 18:16:00 -05:00
parent cd23430f5f
commit 8c39c3826c
4 changed files with 38 additions and 9 deletions

View File

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

View File

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

View File

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

View File

@ -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 {}));
}