DEV: And and Or operators work

This commit is contained in:
Jeremy Wall 2019-08-01 19:04:58 -05:00
parent 48ea8b30ef
commit a36322461e
6 changed files with 133 additions and 62 deletions

View File

@ -130,9 +130,8 @@ pub enum Op {
JumpIfTrue(i32),
JumpIfFalse(i32),
SelectJump(i32),
// FIXME(jwall): Short circuiting operations
// - And(usize)
// - Or(usize)
And(i32),
Or(i32),
// Spacer operation, Does nothing.
Index, // indexing operation
Noop,

View File

@ -49,7 +49,7 @@ impl OpPointer {
self.ptr = Some(ptr);
return Ok(());
}
Err(Error {})
Err(dbg!(Error {}))
}
pub fn op(&self) -> Option<&Op> {

View File

@ -145,7 +145,7 @@ impl Builtins {
return Ok(());
}
}
return Err(Error {});
return Err(dbg!(Error {}));
}
fn include(&self, stack: &mut Vec<Rc<Value>>) -> Result<(), Error> {
@ -156,19 +156,19 @@ impl Builtins {
if let &Value::P(Str(ref path)) = val.as_ref() {
path.clone()
} else {
return dbg!(Err(Error {}));
return Err(dbg!(Error {}));
}
} else {
return dbg!(Err(Error {}));
return Err(dbg!(Error {}));
};
let typ = if let Some(val) = typ.as_ref() {
if let &Value::P(Str(ref typ)) = val.as_ref() {
typ.clone()
} else {
return dbg!(Err(Error {}));
return Err(dbg!(Error {}));
}
} else {
return dbg!(Err(Error {}));
return Err(dbg!(Error {}));
};
if typ == "str" {
stack.push(Rc::new(P(Str(self.get_file_as_string(&path)?))));
@ -182,14 +182,14 @@ impl Builtins {
} else {
match importer.import(contents.as_bytes()) {
Ok(v) => v.try_into()?,
Err(_e) => return dbg!(Err(Error {})),
Err(_e) => return Err(dbg!(Error {})),
}
}
}
None => return dbg!(Err(Error {})),
None => return Err(dbg!(Error {})),
}));
}
return Err(Error {});
return Err(dbg!(Error {}));
}
fn assert(&mut self, stack: &mut Vec<Rc<Value>>) -> Result<(), Error> {
@ -237,14 +237,14 @@ impl Builtins {
Ok(_) => {
// noop
}
Err(_e) => return Err(Error {}),
Err(_e) => return Err(dbg!(Error {})),
}
return Ok(());
}
}
}
}
return Err(Error {});
return Err(dbg!(Error {}));
}
fn convert(&self, stack: &mut Vec<Rc<Value>>) -> Result<(), Error> {
@ -262,14 +262,14 @@ impl Builtins {
String::from_utf8_lossy(buf.as_slice()).to_string()
))));
}
Err(_e) => return Err(Error {}),
Err(_e) => return Err(dbg!(Error {})),
}
return Ok(());
}
}
}
}
return Err(Error {});
return Err(dbg!(Error {}));
}
fn map<P: AsRef<Path>>(&self, path: P, stack: &mut Vec<Rc<Value>>) -> Result<(), Error> {
@ -277,25 +277,25 @@ impl Builtins {
let list = if let Some(list) = stack.pop() {
list
} else {
return dbg!(Err(Error {}));
return Err(dbg!(Error {}));
};
let elems = if let &C(List(ref elems)) = list.as_ref() {
elems
} else {
return dbg!(Err(Error {}));
return Err(dbg!(Error {}));
};
// get the func ptr from the stack
let fptr = if let Some(ptr) = stack.pop() {
ptr
} else {
return dbg!(Err(Error {}));
return Err(dbg!(Error {}));
};
let f = if let &F(ref f) = fptr.as_ref() {
f
} else {
return dbg!(Err(Error {}));
return Err(dbg!(Error {}));
};
let mut result_elems = Vec::new();
@ -314,19 +314,19 @@ impl Builtins {
let list = if let Some(list) = stack.pop() {
list
} else {
return dbg!(Err(Error {}));
return Err(dbg!(Error {}));
};
let elems = if let &C(List(ref elems)) = list.as_ref() {
elems
} else {
return dbg!(Err(Error {}));
return Err(dbg!(Error {}));
};
// get the func ptr from the stack
let fptr = if let Some(ptr) = stack.pop() {
ptr
} else {
return dbg!(Err(Error {}));
return Err(dbg!(Error {}));
};
let f = if let &F(ref f) = fptr.as_ref() {

View File

@ -551,7 +551,7 @@ use crate::parse::parse;
macro_rules! assert_parse_cases {
(__impl__ $cases:expr) => {
for case in $cases.drain(0..) {
let stmts = parse(OffsetStrIter::from(case.0), None).unwrap();
let stmts = parse(OffsetStrIter::from(dbg!(case.0)), None).unwrap();
let ops = Rc::new(translate::AST::translate(stmts));
assert!(ops.len() > 0);
let mut vm = VM::new("foo.ucg", ops.clone());
@ -597,8 +597,16 @@ fn simple_binary_expr() {
"2<1;" => P(Bool(false)),
"1!=1;" => P(Bool(false)),
"\"foo\" ~ \"bar\";" => P(Bool(false)),
"\"foo\" !~ \"bar\";" => P(Bool(true)),
"\"foo\" is \"str\";" => P(Bool(true)),
//"true && false;" => P(Bool(false)),
"true && true;" => P(Bool(true)),
"true && false;" => P(Bool(false)),
"false && false;" => P(Bool(false)),
"false && true;" => P(Bool(false)),
"false || false;" => P(Bool(false)),
"true || false;" => P(Bool(true)),
"false || true;" => P(Bool(true)),
"true || true;" => P(Bool(true)),
)
}

View File

@ -40,33 +40,45 @@ impl AST {
}
fn translate_expr(expr: Expression, mut ops: &mut Vec<Op>) {
match dbg!(expr) {
match expr {
Expression::Simple(v) => {
Self::translate_value(v, &mut ops);
}
Expression::Binary(def) => {
Self::translate_expr(*def.right, &mut ops);
Self::translate_expr(*def.left, &mut ops);
match def.kind {
BinaryExprType::Add => {
Self::translate_expr(*def.right, &mut ops);
Self::translate_expr(*def.left, &mut ops);
ops.push(Op::Add);
}
BinaryExprType::Sub => {
Self::translate_expr(*def.right, &mut ops);
Self::translate_expr(*def.left, &mut ops);
ops.push(Op::Sub);
}
BinaryExprType::Div => {
Self::translate_expr(*def.right, &mut ops);
Self::translate_expr(*def.left, &mut ops);
ops.push(Op::Div);
}
BinaryExprType::Mul => {
Self::translate_expr(*def.right, &mut ops);
Self::translate_expr(*def.left, &mut ops);
ops.push(Op::Mul);
}
BinaryExprType::Equal => {
Self::translate_expr(*def.right, &mut ops);
Self::translate_expr(*def.left, &mut ops);
ops.push(Op::Equal);
}
BinaryExprType::GT => {
Self::translate_expr(*def.right, &mut ops);
Self::translate_expr(*def.left, &mut ops);
ops.push(Op::Gt);
}
BinaryExprType::LT => {
Self::translate_expr(*def.right, &mut ops);
Self::translate_expr(*def.left, &mut ops);
ops.push(Op::Lt);
}
BinaryExprType::GTEqual => {
@ -79,25 +91,47 @@ impl AST {
unimplemented!("Binary expressions are not implmented yet")
}
BinaryExprType::NotEqual => {
Self::translate_expr(*def.right, &mut ops);
Self::translate_expr(*def.left, &mut ops);
ops.push(Op::Equal);
ops.push(Op::Not);
}
BinaryExprType::REMatch => {
Self::translate_expr(*def.right, &mut ops);
Self::translate_expr(*def.left, &mut ops);
ops.push(Op::Runtime(Hook::Regex));
}
BinaryExprType::NotREMatch => {
Self::translate_expr(*def.right, &mut ops);
Self::translate_expr(*def.left, &mut ops);
ops.push(Op::Runtime(Hook::Regex));
ops.push(Op::Not);
}
BinaryExprType::IS => {
Self::translate_expr(*def.right, &mut ops);
Self::translate_expr(*def.left, &mut ops);
ops.push(Op::Typ);
ops.push(Op::Equal);
}
BinaryExprType::IN
| BinaryExprType::Mod
| BinaryExprType::OR
| BinaryExprType::AND
| BinaryExprType::DOT => {
BinaryExprType::AND => {
Self::translate_expr(*def.left, &mut ops);
ops.push(Op::Noop);
let idx = ops.len() - 1;
Self::translate_expr(*def.right, &mut ops);
let jptr = (ops.len() - 1 - idx) as i32;
ops[idx] = Op::And(dbg!(jptr));
dbg!(ops);
}
BinaryExprType::OR => {
// FIXME(jwall): This needs to be handled very differently
Self::translate_expr(*def.left, &mut ops);
ops.push(Op::Noop); // Placeholder used for
let idx = ops.len() - 1;
Self::translate_expr(*def.right, &mut ops);
let jptr = (ops.len() - 1 - idx) as i32;
ops[idx] = Op::Or(jptr);
}
BinaryExprType::IN | BinaryExprType::Mod | BinaryExprType::DOT => {
unimplemented!("Binary expressions are not implmented yet")
// TODO
}
@ -126,7 +160,7 @@ impl AST {
}
fn translate_value(value: Value, ops: &mut Vec<Op>) {
match dbg!(value) {
match value {
Value::Int(i) => ops.push(Op::Val(Primitive::Int(i.val))),
Value::Float(f) => ops.push(Op::Val(Primitive::Float(f.val))),
Value::Str(s) => ops.push(Op::Val(Primitive::Str(s.val))),

View File

@ -72,15 +72,15 @@ impl<'a> VM {
pub fn run(&mut self) -> Result<(), Error> {
loop {
let op = if let Some(op) = dbg!(self.ops.next()) {
let op = if let Some(op) = self.ops.next() {
op.clone()
} else {
break;
};
let idx = self.ops.idx()?;
match op {
Op::Val(p) => self.push(Rc::new(dbg!(P(p.clone()))))?,
Op::Sym(s) => self.push(Rc::new(dbg!(S(s.clone()))))?,
Op::Val(p) => self.push(Rc::new(P(p.clone())))?,
Op::Sym(s) => self.push(Rc::new(S(s.clone())))?,
Op::DeRef(s) => self.op_deref(s.clone())?,
Op::Add => self.op_add()?,
Op::Sub => self.op_sub()?,
@ -111,6 +111,8 @@ impl<'a> VM {
Op::JumpIfTrue(jp) => self.op_jump_if_true(jp)?,
Op::JumpIfFalse(jp) => self.op_jump_if_false(jp)?,
Op::SelectJump(jp) => self.op_select_jump(jp)?,
Op::And(jp) => self.op_and(jp)?,
Op::Or(jp) => self.op_or(jp)?,
Op::Module(mptr) => self.op_module(idx, mptr)?,
Op::Func(jptr) => self.op_func(idx, jptr)?,
Op::FCall => self.op_fcall()?,
@ -126,7 +128,7 @@ impl<'a> VM {
}
fn op_typ(&mut self) -> Result<(), Error> {
let val = dbg!(self.pop())?;
let val = self.pop()?;
let typ_name = match val.as_ref() {
P(Int(_)) => "int",
P(Float(_)) => "float",
@ -147,7 +149,7 @@ impl<'a> VM {
}
fn op_deref(&mut self, name: String) -> Result<(), Error> {
let val = dbg!(self.get_binding(&name)?.clone());
let val = self.get_binding(&name)?.clone();
self.push(val)
}
@ -161,12 +163,40 @@ impl<'a> VM {
Ok(())
}
fn op_and(&mut self, jp: i32) -> Result<(), Error> {
let cond = self.pop()?;
let cc = cond.clone();
if let &P(Bool(cond)) = cond.as_ref() {
if !cond {
self.push(cc)?;
self.op_jump(jp)?;
}
} else {
return Err(dbg!(Error {}));
}
Ok(())
}
fn op_or(&mut self, jp: i32) -> Result<(), Error> {
let cond = self.pop()?;
let cc = cond.clone();
if let &P(Bool(cond)) = cond.as_ref() {
if cond {
self.push(cc)?;
self.op_jump(jp)?;
}
}
Ok(())
}
fn op_jump_if_true(&mut self, jp: i32) -> Result<(), Error> {
let cond = self.pop()?;
if let &P(Bool(cond)) = cond.as_ref() {
if cond {
self.op_jump(jp)?;
}
} else {
return Err(dbg!(Error {}));
}
Ok(())
}
@ -175,7 +205,7 @@ impl<'a> VM {
let cond = self.pop()?;
if let &P(Bool(cond)) = cond.as_ref() {
if !cond {
self.op_jump(jp)?;
self.op_jump(dbg!(jp))?;
}
}
Ok(())
@ -318,7 +348,7 @@ impl<'a> VM {
(&P(Float(f)), &P(Float(ff))) => {
self.push(Rc::new(P(Bool(f > ff))))?;
}
_ => return Err(Error {}),
_ => return Err(dbg!(Error {})),
}
Ok(())
}
@ -333,7 +363,7 @@ impl<'a> VM {
(&P(Float(f)), &P(Float(ff))) => {
self.push(Rc::new(P(Bool(f < ff))))?;
}
_ => return Err(Error {}),
_ => return Err(dbg!(Error {})),
}
Ok(())
}
@ -348,7 +378,7 @@ impl<'a> VM {
(&P(Float(f)), &P(Float(ff))) => {
self.push(Rc::new(P(Bool(f <= ff))))?;
}
_ => return Err(Error {}),
_ => return Err(dbg!(Error {})),
}
Ok(())
}
@ -363,7 +393,7 @@ impl<'a> VM {
(&P(Float(f)), &P(Float(ff))) => {
self.push(Rc::new(P(Bool(f >= ff))))?;
}
_ => return Err(Error {}),
_ => return Err(dbg!(Error {})),
}
Ok(())
}
@ -412,7 +442,7 @@ impl<'a> VM {
if let &S(ref name) = name.as_ref() {
self.binding_push(name.clone(), val)?;
} else {
return Err(Error {});
return Err(dbg!(Error {}));
}
Ok(())
}
@ -426,7 +456,7 @@ impl<'a> VM {
let name = if let &S(ref s) | &P(Str(ref s)) = name_val.as_ref() {
s
} else {
return Err(Error {});
return Err(dbg!(Error {}));
};
// get composite tuple from stack
let tpl = self.pop()?;
@ -439,7 +469,7 @@ impl<'a> VM {
// place composite tuple back on stack
self.push(Rc::new(C(Tuple(flds))))?;
} else {
return Err(Error {});
return Err(dbg!(Error {}));
};
Ok(())
}
@ -458,7 +488,7 @@ impl<'a> VM {
// Add that value to the list and put list back on stack.
self.push(Rc::new(C(List(elems))))?;
} else {
return Err(Error {});
return Err(dbg!(Error {}));
};
Ok(())
}
@ -470,7 +500,7 @@ impl<'a> VM {
};
match elems.get(idx as usize) {
Some(v) => Ok(v.clone()),
None => Err(Error {}),
None => Err(dbg!(Error {})),
}
}
@ -489,14 +519,14 @@ impl<'a> VM {
return Ok(f.1.clone());
}
}
Err(Error {})
Err(dbg!(Error {}))
}
fn find_in_value(&self, index: &Value, target: &Value) -> Result<Rc<Value>, Error> {
match target {
C(Tuple(flds)) => self.find_in_flds(index, flds),
C(List(elements)) => self.find_in_list(index, elements),
_ => return Err(Error {}),
_ => return Err(dbg!(Error {})),
}
}
@ -505,11 +535,11 @@ impl<'a> VM {
let path = if let &C(List(ref elems)) = path_val.as_ref() {
elems.clone()
} else {
return dbg!(Err(Error {}));
return Err(dbg!(Error {}));
};
let target_val = self.pop()?;
match target_val.as_ref() {
&P(_) | &S(_) | &T(_) | &F(_) | &M(_) => return dbg!(Err(Error {})),
&P(_) | &S(_) | &T(_) | &F(_) | &M(_) => return Err(dbg!(Error {})),
_ => {
let mut out = target_val.clone();
for p in path {
@ -531,7 +561,7 @@ impl<'a> VM {
let overrides = if let &C(Tuple(ref oflds)) = override_val.as_ref() {
oflds.clone()
} else {
return dbg!(Err(Error {}));
return Err(dbg!(Error {}));
};
match tgt.as_ref() {
&C(Tuple(ref flds)) => {
@ -571,7 +601,7 @@ impl<'a> VM {
}
}
_ => {
return Err(Error {});
return Err(dbg!(Error {}));
}
}
Ok(())
@ -600,7 +630,7 @@ impl<'a> VM {
pub fn binding_push(&mut self, name: String, val: Rc<Value>) -> Result<(), Error> {
if self.symbols.is_bound(&name) {
return Err(Error {});
return Err(dbg!(Error {}));
}
self.symbols.add(name, val);
Ok(())
@ -609,14 +639,14 @@ impl<'a> VM {
pub fn get_binding(&'a self, name: &str) -> Result<Rc<Value>, Error> {
match self.symbols.get(name) {
Some(v) => Ok(v),
None => Err(Error {}),
None => Err(dbg!(Error {})),
}
}
pub fn pop(&mut self) -> Result<Rc<Value>, Error> {
match self.stack.pop() {
Some(v) => Ok(v),
None => Err(Error {}),
None => Err(dbg!(Error {})),
}
}
@ -624,7 +654,7 @@ impl<'a> VM {
Ok(match (left, right) {
(P(Int(i)), P(Int(ii))) => Int(i * ii),
(P(Float(f)), P(Float(ff))) => Float(f * ff),
_ => return Err(Error {}),
_ => return Err(dbg!(Error {})),
})
}
@ -632,7 +662,7 @@ impl<'a> VM {
Ok(match (left, right) {
(P(Int(i)), P(Int(ii))) => Int(i / ii),
(P(Float(f)), P(Float(ff))) => Float(f / ff),
_ => return Err(Error {}),
_ => return Err(dbg!(Error {})),
})
}
@ -640,7 +670,7 @@ impl<'a> VM {
Ok(match (left, right) {
(P(Int(i)), Value::P(Int(ii))) => Int(i - ii),
(P(Float(f)), Value::P(Float(ff))) => Float(f - ff),
_ => return Err(Error {}),
_ => return Err(dbg!(Error {})),
})
}
@ -654,7 +684,7 @@ impl<'a> VM {
ns.push_str(&ss);
Str(ns)
}
_ => return Err(Error {}),
_ => return Err(dbg!(Error {})),
})
}