Skip to content

Commit

Permalink
refactor: remove push and pop from the main machine
Browse files Browse the repository at this point in the history
  • Loading branch information
heypoom committed Sep 24, 2023
1 parent ab74bfc commit 8a14f00
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 37 deletions.
24 changes: 11 additions & 13 deletions src/machine/execute.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,13 @@ impl Execute for Machine {
fn tick(&mut self) {
let op = self.decode();
let mut s = self.stack();
println!("Operation: {:?}", op);

// Should we jump to a different instruction?
let mut jump: Option<u16> = None;

match op {
I::None => {}

I::Push(v) => { self.push(v); }
I::Pop => { self.pop(); }
I::Push(v) => { s.push(v).expect("push error"); }
I::Pop => { s.pop().expect("pop error"); }

// Addition, subtraction, multiplication and division.
I::Add => s.apply_two(|a, b| a + b),
Expand All @@ -52,36 +49,37 @@ impl Execute for Machine {
I::Jump(addr) => self.reg.set(PC, addr),

I::JumpZero(addr) => {
if self.pop() == 0 {
if s.pop().unwrap() == 0 {
jump = Some(addr);
}
}

I::JumpNotZero(addr) => {
if self.pop() != 0 {
if s.pop().unwrap() != 0 {
jump = Some(addr);
}
}

I::Dup => {
let v = s.peek();
self.push(v);
s.push(v).unwrap();
}

I::Swap => {
let a = self.pop();
let b = self.pop();
let a = s.pop().unwrap();
let b = s.pop().unwrap();

self.push(a);
self.push(b);
s.push(a).unwrap();
s.push(b).unwrap();
}

I::Over => {
let v = s.get(1);
self.push(v);
s.push(v).unwrap();
}

I::Halt => {}
I::None => {}
};

if let Some(addr) = jump {
Expand Down
32 changes: 8 additions & 24 deletions src/machine/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,40 +17,24 @@ pub struct Machine {
impl Machine {
/// Creates a new machine.
pub fn new() -> Machine {
let mem = Memory::new();
let reg = Registers::new();

Machine { mem, reg }
Machine { mem: Memory::new(), reg: Registers::new() }
}

/// Returns a stack manager for the current machine.
fn stack(&mut self) -> StackManager {
pub fn stack(&mut self) -> StackManager {
StackManager::new(&mut self.mem, &mut self.reg)
}

/// Pops a value from the stack.
fn pop(&mut self) -> u16 {
self.stack().pop().unwrap()
}

/// Pushes a value onto the stack.
fn push(&mut self, value: u16) {
self.stack().push(value).unwrap();
}

pub fn load(&mut self, ops: Vec<I>) {
// Append a [halt] instruction to the code.
let mut code = ops.clone();
code.push(I::Halt);

self.mem.load_code(code);
}
}

impl From<Vec<Instruction>> for Machine {
fn from(code: Vec<Instruction>) -> Self {
let mut m = Machine::new();
m.load(code);

// Add a halt instruction to the end of the code.
let mut code = code.clone();
code.push(I::Halt);

m.mem.load_code(code);
m
}
}
Expand Down

0 comments on commit 8a14f00

Please sign in to comment.