DEV: JumpIfFalse op code.

This commit is contained in:
Jeremy Wall 2019-07-06 17:31:08 -05:00
parent 56174cbe52
commit 3bb6f6e8eb
2 changed files with 27 additions and 1 deletions

View File

@ -101,6 +101,7 @@ pub enum Op {
Bang, Bang,
Jump(usize), Jump(usize),
JumpIfTrue(usize), JumpIfTrue(usize),
JumpIfFalse(usize),
// FIXME(jwall): Short circuiting operations // FIXME(jwall): Short circuiting operations
// - And(usize) // - And(usize)
// - Or(usize) // - Or(usize)
@ -181,6 +182,7 @@ impl<'a> VM<'a> {
} }
Op::Jump(jp) => self.op_jump(*jp)?, Op::Jump(jp) => self.op_jump(*jp)?,
Op::JumpIfTrue(jp) => self.op_jump_if_true(*jp)?, Op::JumpIfTrue(jp) => self.op_jump_if_true(*jp)?,
Op::JumpIfFalse(jp) => self.op_jump_if_false(*jp)?,
Op::Module(mptr) => self.op_module(idx, *mptr)?, Op::Module(mptr) => self.op_module(idx, *mptr)?,
Op::Func(jptr) => self.op_func(idx, *jptr)?, Op::Func(jptr) => self.op_func(idx, *jptr)?,
Op::FCall => self.op_fcall()?, Op::FCall => self.op_fcall()?,
@ -212,6 +214,15 @@ impl<'a> VM<'a> {
Ok(()) Ok(())
} }
fn op_jump_if_false(&mut self, jp: usize) -> Result<(), Error> {
if let P(Bool(cond)) = self.pop()? {
if !cond {
self.op_jump(jp)?;
}
}
Ok(())
}
fn op_module(&mut self, idx: usize, jptr: usize) -> Result<(), Error> { fn op_module(&mut self, idx: usize, jptr: usize) -> Result<(), Error> {
let (result_ptr, flds) = match self.pop()? { let (result_ptr, flds) = match self.pop()? {
C(Tuple(flds)) => (None, flds), C(Tuple(flds)) => (None, flds),

View File

@ -16,7 +16,7 @@ use super::scope::Stack;
use super::Composite::{List, Tuple}; use super::Composite::{List, Tuple};
use super::Op::{ use super::Op::{
Add, Bind, Cp, DeRef, Div, Element, Equal, FCall, Field, Func, InitList, InitThunk, InitTuple, Add, Bind, Cp, DeRef, Div, Element, Equal, FCall, Field, Func, InitList, InitThunk, InitTuple,
Jump, JumpIfTrue, Module, Mul, Noop, Return, Sub, Sym, Val, Jump, JumpIfFalse, JumpIfTrue, Module, Mul, Noop, Return, Sub, Sym, Val,
}; };
use super::Primitive::{Bool, Float, Int, Str}; use super::Primitive::{Bool, Float, Int, Str};
use super::Value::{C, P, T}; use super::Value::{C, P, T};
@ -355,6 +355,21 @@ fn test_conditional_jump_ops() {
], ],
P(Int(1)), P(Int(1)),
), ),
(
vec![
Val(Int(1)),
Val(Int(2)),
Equal,
JumpIfFalse(2),
Val(Bool(false)),
JumpIfTrue(2),
Val(Int(1)),
Jump(1),
Val(Int(2)),
Noop,
],
P(Int(1)),
),
]; ];
for case in cases.drain(0..) { for case in cases.drain(0..) {
let mut vm = VM::new(&case.0); let mut vm = VM::new(&case.0);