diff options
| author | Rose Hogenson <rhogenson@posteo.net> | 2022-08-07 15:55:13 -0700 |
|---|---|---|
| committer | Rose Hogenson <rhogenson@posteo.net> | 2022-08-07 15:55:47 -0700 |
| commit | 35d375807bd84f9c7ca82e28042d20ded7b65498 (patch) | |
| tree | ba0f34d009cff54ae69adc07eca4cd066f2f5cb7 /bytecode/src/bytecode.rs | |
| parent | 72294a6a1a690d396d13a7e3861f4b720e78cdb3 (diff) | |
| download | chromatopelma-35d375807bd84f9c7ca82e28042d20ded7b65498.tar.zst | |
Add int<? and eq?.
Diffstat (limited to 'bytecode/src/bytecode.rs')
| -rw-r--r-- | bytecode/src/bytecode.rs | 29 |
1 files changed, 27 insertions, 2 deletions
diff --git a/bytecode/src/bytecode.rs b/bytecode/src/bytecode.rs index bde3721..313b2fb 100644 --- a/bytecode/src/bytecode.rs +++ b/bytecode/src/bytecode.rs @@ -29,6 +29,9 @@ pub enum Op { // Remainder from Div. Mod(Local, Arg, Arg), + // x < y + Less(Local, Arg, Arg), + // Heap // ====== @@ -75,6 +78,9 @@ pub enum Op { // - nil: 3 // - symbol: 4 TypeOf(Local, Arg), + + // Loads #t if the arguments are equal, #f otherwise. + Equal(Local, Arg, Arg), } struct Interpreter { @@ -119,14 +125,27 @@ impl Interpreter { fn div(&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_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<u8, String> { 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), } } } |
