diff options
Diffstat (limited to 'bytecode/src/bytecode.rs')
| -rw-r--r-- | bytecode/src/bytecode.rs | 61 |
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), } } } |
