add more arithmetic instructions

This commit is contained in:
Michael Sippel 2024-05-13 16:03:43 +02:00
parent ed5e3453b0
commit 09cd134406
Signed by: senvas
GPG key ID: 060F22F65102F95C
2 changed files with 115 additions and 15 deletions

View file

@ -16,17 +16,17 @@ fn test_vm() {
.inst( crate::VM_Instruction::Store ) .inst( crate::VM_Instruction::Store )
.build()); .build());
linker.add_procedure("i+", linker.add_procedure("int-add",
crate::Assembler::new() crate::Assembler::new()
.inst( crate::VM_Instruction::Add ) .inst( crate::VM_Instruction::IntAdd )
.build()); .build());
linker.add_procedure("i-", linker.add_procedure("int-sub",
crate::Assembler::new() crate::Assembler::new()
.inst( crate::VM_Instruction::BitwiseNot ) .inst( crate::VM_Instruction::BitNeg )
.lit(1) .lit(1)
.inst( crate::VM_Instruction::Add ) .inst( crate::VM_Instruction::IntAdd )
.inst( crate::VM_Instruction::Add ) .inst( crate::VM_Instruction::IntAdd )
.build()); .build());
// declare variable 'x' at address 0x86 // declare variable 'x' at address 0x86
@ -50,13 +50,13 @@ fn test_vm() {
linker.add_procedure("main", linker.add_procedure("main",
crate::Assembler::new() crate::Assembler::new()
// x = 123 // x = 123
.lit(100).lit(23).call("i+") .lit(100).lit(23).call("int-add")
.call("x").call("!") .call("x").call("!")
// if ( 123 - x ) { emit '*' } else { emit '+' } // if ( 123 - x ) { emit '*' } else { emit '+' }
.lit(123) .lit(123)
.call("x").call("@") .call("x").call("@")
.call("i-") .call("int-sub")
.branch( .branch(
crate::Assembler::new() crate::Assembler::new()
.lit(42).inst(crate::VM_Instruction::Emit) .lit(42).inst(crate::VM_Instruction::Emit)

112
src/vm.rs
View file

@ -7,9 +7,10 @@ pub enum VM_Instruction {
Lit, Pick, Roll, Dup, Drop, Swap, Rot, Lit, Pick, Roll, Dup, Drop, Swap, Rot,
Fetch, Store, Fetch, Store,
Accept, Emit, Accept, Emit,
Add, //Sub, Mul, Div, Rem, IntAdd, IntSub, IntMul, IntDiv, IntRem,
Addf,//Subf, Mulf, Divf FltAdd, FltSub, FltMul, FltDiv, FltRem,
BitwiseNot, BitNeg, BitAnd, BitOr, BitXor,
BitShl, BitShr,
} }
impl VM_Instruction { impl VM_Instruction {
@ -162,12 +163,32 @@ impl VM {
self.data_stack.push(c); self.data_stack.push(c);
self.data_stack.push(b); self.data_stack.push(b);
} }
VM_Instruction::Add => { VM_Instruction::IntAdd => {
let a = self.data_stack.pop().expect("add expects value"); let a = self.data_stack.pop().expect("add expects value");
let b = self.data_stack.pop().expect("add expects value"); let b = self.data_stack.pop().expect("add expects value");
self.data_stack.push( a + b ); 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 a = self.data_stack.pop().expect("addf expects value");
let af : f64 = unsafe{ std::mem::transmute(a) }; let af : f64 = unsafe{ std::mem::transmute(a) };
@ -179,10 +200,89 @@ impl VM {
self.data_stack.push(c); 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"); let a = self.data_stack.pop().expect("bitwise not expects value");
self.data_stack.push( !a ); 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 true