From 09cd134406d0b7413229bb80af5925ab9620be44 Mon Sep 17 00:00:00 2001 From: Michael Sippel Date: Mon, 13 May 2024 16:03:43 +0200 Subject: [PATCH] add more arithmetic instructions --- src/test.rs | 18 ++++----- src/vm.rs | 112 +++++++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 115 insertions(+), 15 deletions(-) diff --git a/src/test.rs b/src/test.rs index e66287f..fe5d419 100644 --- a/src/test.rs +++ b/src/test.rs @@ -16,17 +16,17 @@ fn test_vm() { .inst( crate::VM_Instruction::Store ) .build()); - linker.add_procedure("i+", + linker.add_procedure("int-add", crate::Assembler::new() - .inst( crate::VM_Instruction::Add ) + .inst( crate::VM_Instruction::IntAdd ) .build()); - - linker.add_procedure("i-", + + linker.add_procedure("int-sub", crate::Assembler::new() - .inst( crate::VM_Instruction::BitwiseNot ) + .inst( crate::VM_Instruction::BitNeg ) .lit(1) - .inst( crate::VM_Instruction::Add ) - .inst( crate::VM_Instruction::Add ) + .inst( crate::VM_Instruction::IntAdd ) + .inst( crate::VM_Instruction::IntAdd ) .build()); // declare variable 'x' at address 0x86 @@ -50,13 +50,13 @@ fn test_vm() { linker.add_procedure("main", crate::Assembler::new() // x = 123 - .lit(100).lit(23).call("i+") + .lit(100).lit(23).call("int-add") .call("x").call("!") // if ( 123 - x ) { emit '*' } else { emit '+' } .lit(123) .call("x").call("@") - .call("i-") + .call("int-sub") .branch( crate::Assembler::new() .lit(42).inst(crate::VM_Instruction::Emit) diff --git a/src/vm.rs b/src/vm.rs index 0d71434..1d097a0 100644 --- a/src/vm.rs +++ b/src/vm.rs @@ -7,9 +7,10 @@ pub enum VM_Instruction { Lit, Pick, Roll, Dup, Drop, Swap, Rot, Fetch, Store, Accept, Emit, - Add, //Sub, Mul, Div, Rem, - Addf,//Subf, Mulf, Divf - BitwiseNot, + IntAdd, IntSub, IntMul, IntDiv, IntRem, + FltAdd, FltSub, FltMul, FltDiv, FltRem, + BitNeg, BitAnd, BitOr, BitXor, + BitShl, BitShr, } impl VM_Instruction { @@ -162,12 +163,32 @@ impl VM { self.data_stack.push(c); self.data_stack.push(b); } - VM_Instruction::Add => { + VM_Instruction::IntAdd => { let a = self.data_stack.pop().expect("add expects value"); let b = self.data_stack.pop().expect("add expects value"); self.data_stack.push( a + b ); } - VM_Instruction::Addf => { + VM_Instruction::IntSub => { + let a = self.data_stack.pop().expect("add expects value"); + let b = self.data_stack.pop().expect("add expects value"); + self.data_stack.push( a - b ); + } + VM_Instruction::IntMul => { + let a = self.data_stack.pop().expect("add expects value"); + let b = self.data_stack.pop().expect("add expects value"); + self.data_stack.push( a * b ); + } + VM_Instruction::IntDiv => { + let a = self.data_stack.pop().expect("add expects value"); + let b = self.data_stack.pop().expect("add expects value"); + self.data_stack.push( a / b ); + } + VM_Instruction::IntRem => { + let a = self.data_stack.pop().expect("add expects value"); + let b = self.data_stack.pop().expect("add expects value"); + self.data_stack.push( a % b ); + } + VM_Instruction::FltAdd => { let a = self.data_stack.pop().expect("addf expects value"); let af : f64 = unsafe{ std::mem::transmute(a) }; @@ -179,10 +200,89 @@ impl VM { self.data_stack.push(c); } - VM_Instruction::BitwiseNot => { + VM_Instruction::FltSub => { + let a = self.data_stack.pop().expect("addf expects value"); + let af : f64 = unsafe{ std::mem::transmute(a) }; + + let b = self.data_stack.pop().expect("addf expects value"); + let bf : f64 = unsafe{ std::mem::transmute(a) }; + + let cf = af - bf; + let c : i64 = unsafe{ std::mem::transmute(cf) }; + + self.data_stack.push(c); + } + VM_Instruction::FltMul => { + let a = self.data_stack.pop().expect("addf expects value"); + let af : f64 = unsafe{ std::mem::transmute(a) }; + + let b = self.data_stack.pop().expect("addf expects value"); + let bf : f64 = unsafe{ std::mem::transmute(a) }; + + let cf = af * bf; + let c : i64 = unsafe{ std::mem::transmute(cf) }; + + self.data_stack.push(c); + } + VM_Instruction::FltDiv => { + let a = self.data_stack.pop().expect("addf expects value"); + let af : f64 = unsafe{ std::mem::transmute(a) }; + + let b = self.data_stack.pop().expect("addf expects value"); + let bf : f64 = unsafe{ std::mem::transmute(a) }; + + let cf = af / bf; + let c : i64 = unsafe{ std::mem::transmute(cf) }; + + self.data_stack.push(c); + } + VM_Instruction::FltRem => { + let a = self.data_stack.pop().expect("addf expects value"); + let af : f64 = unsafe{ std::mem::transmute(a) }; + + let b = self.data_stack.pop().expect("addf expects value"); + let bf : f64 = unsafe{ std::mem::transmute(a) }; + + let cf = af % bf; + let c : i64 = unsafe{ std::mem::transmute(cf) }; + + self.data_stack.push(c); + } + + VM_Instruction::BitNeg => { let a = self.data_stack.pop().expect("bitwise not expects value"); self.data_stack.push( !a ); } + VM_Instruction::BitAnd => { + let a = self.data_stack.pop().expect("bitwise and expects value"); + let b = self.data_stack.pop().expect("bitwise and expects value"); + self.data_stack.push( a & b ); + } + VM_Instruction::BitOr => { + let a = self.data_stack.pop().expect("bitwise and expects value"); + let b = self.data_stack.pop().expect("bitwise and expects value"); + self.data_stack.push( a | b ); + } + VM_Instruction::BitXor => { + let a = self.data_stack.pop().expect("bitwise and expects value"); + let b = self.data_stack.pop().expect("bitwise and expects value"); + self.data_stack.push( a ^ b ); + } + VM_Instruction::BitAnd => { + let a = self.data_stack.pop().expect("bitwise and expects value"); + let b = self.data_stack.pop().expect("bitwise and expects value"); + self.data_stack.push( a & b ); + } + VM_Instruction::BitShl => { + let x = self.data_stack.pop().expect("bitwise and expects value"); + let n = self.data_stack.pop().expect("bitwise and expects value"); + self.data_stack.push( x << n ); + } + VM_Instruction::BitShr => { + let x = self.data_stack.pop().expect("bitwise and expects value"); + let n = self.data_stack.pop().expect("bitwise and expects value"); + self.data_stack.push( x >> n ); + } } true