aboutsummaryrefslogtreecommitdiffstats
path: root/bytecode/src/bytecode.rs
diff options
context:
space:
mode:
Diffstat (limited to 'bytecode/src/bytecode.rs')
-rw-r--r--bytecode/src/bytecode.rs61
1 files changed, 37 insertions, 24 deletions
diff --git a/bytecode/src/bytecode.rs b/bytecode/src/bytecode.rs
index 73c8f53..8d24840 100644
--- a/bytecode/src/bytecode.rs
+++ b/bytecode/src/bytecode.rs
@@ -336,6 +336,36 @@ impl Interpreter {
self.set_arg(dest, Value::from_bool(self.read_arg(x) == self.read_arg(y)));
}
+ fn eval_op(&mut self, op: Op, ip: &mut usize) -> Result<Option<u8>, String> {
+ match op {
+ Op::Add(dest, x, y) => self.add(dest, x, y)?,
+ Op::Sub(dest, x, y) => self.sub(dest, x, y)?,
+ Op::Mul(dest, x, y) => self.mul(dest, x, y)?,
+ Op::Div(dest, x, y) => self.div(dest, x, y)?,
+ Op::Mod(dest, x, y) => self.fn_mod(dest, x, y)?,
+ Op::Less(dest, x, y) => self.less(dest, x, y)?,
+ Op::Alloc(dest, size) => self.alloc(dest, size)?,
+ Op::AllocBytevector(dest, size) => self.alloc_bytevector(dest, size)?,
+ Op::Peek(dest, ptr, offset) => self.peek(dest, ptr, offset)?,
+ Op::Poke(word, ptr, offset) => self.poke(word, ptr, offset)?,
+ Op::PeekByte(dest, ptr, offset) => self.peek_byte(dest, ptr, offset)?,
+ Op::PokeByte(word, ptr, offset) => self.poke_byte(word, ptr, offset)?,
+ Op::Cons(dest, x, y) => self.cons(dest, x, y)?,
+ Op::Len(dest, l) => self.len(dest, l)?,
+ Op::AssertSingleton(dest, l) => self.assert_singleton(dest, l)?,
+ Op::Mov(dest, src) => self.mov(dest, src),
+ Op::Jmp(addr) => self.jmp(ip, addr)?,
+ Op::JmpIf(cond, addr) => self.jmp_if(ip, cond, addr)?,
+ Op::Exit(code) => {
+ let n = self.read_arg(code).to_int()?;
+ return Ok(Some((n & 0xff) as u8));
+ }
+ Op::TypeOf(dest, arg) => self.type_of(dest, arg)?,
+ Op::Equal(dest, x, y) => self.equal(dest, x, y),
+ }
+ return Ok(None);
+ }
+
fn eval(&mut self, prog: &[Op]) -> Result<u8, String> {
let mut ip = 0;
loop {
@@ -344,31 +374,14 @@ impl Interpreter {
}
let op = prog[ip];
ip += 1;
- match op {
- Op::Add(dest, x, y) => self.add(dest, x, y)?,
- Op::Sub(dest, x, y) => self.sub(dest, x, y)?,
- Op::Mul(dest, x, y) => self.mul(dest, x, y)?,
- Op::Div(dest, x, y) => self.div(dest, x, y)?,
- Op::Mod(dest, x, y) => self.fn_mod(dest, x, y)?,
- Op::Less(dest, x, y) => self.less(dest, x, y)?,
- Op::Alloc(dest, size) => self.alloc(dest, size)?,
- Op::AllocBytevector(dest, size) => self.alloc_bytevector(dest, size)?,
- Op::Peek(dest, ptr, offset) => self.peek(dest, ptr, offset)?,
- Op::Poke(word, ptr, offset) => self.poke(word, ptr, offset)?,
- Op::PeekByte(dest, ptr, offset) => self.peek_byte(dest, ptr, offset)?,
- Op::PokeByte(word, ptr, offset) => self.poke_byte(word, ptr, offset)?,
- Op::Cons(dest, x, y) => self.cons(dest, x, y)?,
- Op::Len(dest, l) => self.len(dest, l)?,
- Op::AssertSingleton(dest, l) => self.assert_singleton(dest, l)?,
- Op::Mov(dest, src) => self.mov(dest, src),
- Op::Jmp(addr) => self.jmp(&mut ip, addr)?,
- Op::JmpIf(cond, addr) => self.jmp_if(&mut ip, cond, addr)?,
- Op::Exit(code) => {
- let n = self.read_arg(code).to_int()?;
- return Ok((n & 0xff) as u8);
+ match self.eval_op(op, &mut ip) {
+ Ok(None) => (),
+ Ok(Some(code)) => {
+ return Ok(code);
+ }
+ Err(err) => {
+ return Err(format!("{}: failed ({:?}): {}", ip, op, err));
}
- Op::TypeOf(dest, arg) => self.type_of(dest, arg)?,
- Op::Equal(dest, x, y) => self.equal(dest, x, y),
}
}
}