From 35d375807bd84f9c7ca82e28042d20ded7b65498 Mon Sep 17 00:00:00 2001 From: Rose Hogenson Date: Sun, 7 Aug 2022 15:55:13 -0700 Subject: Add int Result<(), String> { let n1 = self.read_arg(x).to_int()?; let n2 = self.read_arg(y).to_int()?; - self.set_arg(dest, Value::from_int(n1.wrapping_div(n2))); + self.set_arg( + dest, + Value::from_int(n1.checked_div(n2).expect("division by zero")), + ); Ok(()) } fn fn_mod(&mut self, dest: Local, x: Arg, y: Arg) -> Result<(), String> { let n1 = self.read_arg(x).to_int()?; let n2 = self.read_arg(y).to_int()?; - self.set_arg(dest, Value::from_int(n1.wrapping_rem(n2))); + self.set_arg( + dest, + Value::from_int(n1.checked_rem(n2).expect("division by zero")), + ); + Ok(()) + } + + fn less(&mut self, dest: Local, x: Arg, y: Arg) -> Result<(), String> { + let n1 = self.read_arg(x).to_int()?; + let n2 = self.read_arg(y).to_int()?; + self.set_arg(dest, Value::from_bool(n1 < n2)); Ok(()) } @@ -250,6 +269,10 @@ impl Interpreter { Ok(()) } + fn equal(&mut self, dest: Local, x: Arg, y: Arg) { + self.set_arg(dest, Value::from_bool(self.read_arg(x) == self.read_arg(y))); + } + fn eval(&mut self, prog: &[Op]) -> Result { let mut ip = 0; loop { @@ -264,6 +287,7 @@ impl Interpreter { 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)?, @@ -278,6 +302,7 @@ impl Interpreter { return Ok((n & 0xff) as u8); } Op::TypeOf(dest, arg) => self.type_of(dest, arg)?, + Op::Equal(dest, x, y) => self.equal(dest, x, y), } } } diff --git a/bytecode/src/encoding.rs b/bytecode/src/encoding.rs index b3e84ac..6e86103 100644 --- a/bytecode/src/encoding.rs +++ b/bytecode/src/encoding.rs @@ -103,6 +103,11 @@ fn op_decoding(prog: &mut T) -> Result, String> { 13 => Op::Exit(read_arg(prog, arg1_const)?), 14 => Op::AllocBytevector(read_local(prog)?, read_arg(prog, arg1_const)?), 15 => Op::TypeOf(read_local(prog)?, read_arg(prog, arg1_const)?), + 16 => Op::Less( + read_local(prog)?, + read_arg(prog, arg1_const)?, + read_arg(prog, arg2_const)?, + ), _ => { return Err(String::from("invalid opcode")); } diff --git a/lib/csc/encoding.csc b/lib/csc/encoding.csc index 9afa40f..83258c8 100644 --- a/lib/csc/encoding.csc +++ b/lib/csc/encoding.csc @@ -175,6 +175,11 @@ (make-opcode w 15 (is-const? x) #f) (arg->le-bytes w dest) (arg->le-bytes w x)) + (('intle-bytes w dest) + (arg->le-bytes w x) + (arg->le-bytes w y)) (_ (error "invalid opcode" opcode)))) -- cgit v1.3.1