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 )
|
.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
112
src/vm.rs
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue