Compare commits
2 commits
92fc7ff44b
...
b94723f1ba
Author | SHA1 | Date | |
---|---|---|---|
b94723f1ba | |||
ca6fd92932 |
2 changed files with 38 additions and 3 deletions
|
@ -42,8 +42,26 @@ impl Assembler {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn while_loop(mut self, mut condition: Assembler, mut body: Assembler) -> Assembler {
|
||||||
|
let cond_len = condition.instructions.len();
|
||||||
|
let body_len = body.instructions.len();
|
||||||
|
self.instructions.append( &mut condition.instructions );
|
||||||
|
|
||||||
|
// jump to end
|
||||||
|
self.instructions.push( VM_Instruction::Branch as VM_Word );
|
||||||
|
self.instructions.push( body_len as VM_Word + 2 );
|
||||||
|
|
||||||
|
self.instructions.append( &mut body.instructions );
|
||||||
|
|
||||||
|
// jump back to condition
|
||||||
|
self.instructions.push( VM_Instruction::Jmp as VM_Word );
|
||||||
|
self.instructions.push( -2-(body_len as VM_Word)-2-(cond_len as VM_Word) );
|
||||||
|
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
pub fn branch(mut self, mut if_branch: Assembler, mut else_branch: Assembler) -> Assembler {
|
pub fn branch(mut self, mut if_branch: Assembler, mut else_branch: Assembler) -> Assembler {
|
||||||
self.instructions.push(VM_Instruction::Branch as VM_Word );
|
self.instructions.push(VM_Instruction::Branch as VM_Word);
|
||||||
self.instructions.push( if_branch.instructions.len() as VM_Word + 2);
|
self.instructions.push( if_branch.instructions.len() as VM_Word + 2);
|
||||||
|
|
||||||
self.instructions.append( &mut if_branch.instructions );
|
self.instructions.append( &mut if_branch.instructions );
|
||||||
|
|
21
src/vm.rs
21
src/vm.rs
|
@ -4,7 +4,7 @@ pub type VM_Word = i64;
|
||||||
#[repr(u64)]
|
#[repr(u64)]
|
||||||
pub enum VM_Instruction {
|
pub enum VM_Instruction {
|
||||||
Nop, Jmp, Call, Branch, Ret,
|
Nop, Jmp, Call, Branch, Ret,
|
||||||
Lit, Dup, Drop, Swap, Rot,
|
Lit, Pick, Roll, Dup, Drop, Swap, Rot,
|
||||||
Fetch, Store,
|
Fetch, Store,
|
||||||
Accept, Emit,
|
Accept, Emit,
|
||||||
Add, //Sub, Mul, Div, Rem,
|
Add, //Sub, Mul, Div, Rem,
|
||||||
|
@ -103,6 +103,23 @@ impl VM {
|
||||||
let val = char::from(self.data_stack.pop().expect("emit expects value") as u8);
|
let val = char::from(self.data_stack.pop().expect("emit expects value") as u8);
|
||||||
print!("{}", val);
|
print!("{}", val);
|
||||||
}
|
}
|
||||||
|
VM_Instruction::Pick => {
|
||||||
|
let n = self.data_stack.pop().expect("pick requires index") as usize;
|
||||||
|
self.data_stack.push( *self.data_stack.get( self.data_stack.len() - n ).expect("pick invalid index") );
|
||||||
|
}
|
||||||
|
VM_Instruction::Roll => {
|
||||||
|
let n = self.data_stack.pop().expect("pick requires index") as usize;
|
||||||
|
let l = self.data_stack.len();
|
||||||
|
if n <= l {
|
||||||
|
if n > 1 {
|
||||||
|
let val = self.data_stack.remove( l-n );
|
||||||
|
self.data_stack.push( val );
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
eprintln!("stack = {:?}", self.data_stack);
|
||||||
|
eprintln!("roll invalid index");
|
||||||
|
}
|
||||||
|
}
|
||||||
VM_Instruction::Dup => {
|
VM_Instruction::Dup => {
|
||||||
self.data_stack.push( *self.data_stack.last().expect("dup expect val") );
|
self.data_stack.push( *self.data_stack.last().expect("dup expect val") );
|
||||||
}
|
}
|
||||||
|
@ -114,7 +131,7 @@ impl VM {
|
||||||
let b = self.data_stack.pop().expect("swap expects value");
|
let b = self.data_stack.pop().expect("swap expects value");
|
||||||
self.data_stack.push(a);
|
self.data_stack.push(a);
|
||||||
self.data_stack.push(b);
|
self.data_stack.push(b);
|
||||||
}
|
}
|
||||||
VM_Instruction::Rot => {
|
VM_Instruction::Rot => {
|
||||||
let a = self.data_stack.pop().expect("rot expects value");
|
let a = self.data_stack.pop().expect("rot expects value");
|
||||||
let b = self.data_stack.pop().expect("rot expects value");
|
let b = self.data_stack.pop().expect("rot expects value");
|
||||||
|
|
Loading…
Reference in a new issue