add more arithmetic instructions
This commit is contained in:
parent
ed5e3453b0
commit
09cd134406
2 changed files with 115 additions and 15 deletions
16
src/test.rs
16
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)
|
||||
|
|
112
src/vm.rs
112
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
|
||||
|
|
Loading…
Reference in a new issue