Skip to content

Commit

Permalink
VM can now disassemble instructions while executing
Browse files Browse the repository at this point in the history
- Added better line data representation
- Also still moving files around and got rid of the Disassembler trait
  • Loading branch information
patbuc committed Nov 12, 2023
1 parent 9286324 commit 0c0b548
Show file tree
Hide file tree
Showing 7 changed files with 60 additions and 38 deletions.
3 changes: 0 additions & 3 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,6 @@ fn main() {
block.write_op_code(OpCode::Return, 5);
block.write_op_code(OpCode::Return, 6);

#[cfg(feature = "disassemble")]
block.disassemble();

let mut vm = VirtualMachine::new(block);
vm.interpret();
}
11 changes: 3 additions & 8 deletions src/vm/block/block.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
#[cfg(feature = "disassemble")]
use crate::vm::block::disassembler::Disassembler;
use crate::vm::block::opcodes::OpCode;
use crate::vm::block::{Block, Constants};

Expand All @@ -12,9 +10,11 @@ impl Block {
lines: Vec::new(),
}
}
}

impl Block {
pub fn write_op_code(&mut self, op_code: OpCode, line: usize) {
self.lines.push(line);
self.add_line(self.instructions.len(), line);
self.instructions.push(op_code as u8)
}

Expand Down Expand Up @@ -68,9 +68,4 @@ impl Block {
let byte4 = self.instructions[offset + 3] as u32;
(byte4 << 24) | (byte3 << 16) | (byte2 << 8) | byte1
}

#[cfg(feature = "disassemble")]
pub fn disassemble(&self) {
self.disassemble_block();
}
}
7 changes: 2 additions & 5 deletions src/vm/block/constants.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use crate::vm::block::{Constants, Value};
use crate::vm::block::Constants;
use crate::vm::vm::Value;

impl Constants {
pub fn new() -> Self {
Expand All @@ -21,10 +22,6 @@ impl Constants {
}
}

// pub fn print_value(value: Value) {
// print!("{}", value);
// }

#[cfg(test)]
mod tests {
use super::*;
Expand Down
24 changes: 9 additions & 15 deletions src/vm/block/disassembler.rs
Original file line number Diff line number Diff line change
@@ -1,35 +1,29 @@
use crate::vm::block::{Block, OpCode};
use num_traits::FromPrimitive;

pub trait Disassembler {
fn disassemble_block(&self);
fn disassemble_instruction(&self, offset: usize, line: usize) -> usize;
fn simple_instruction(&self, op_code: OpCode, offset: usize) -> usize;
fn constant_instruction(&self, op_code: OpCode, offset: usize) -> usize;
}

impl Disassembler for Block {
fn disassemble_block(&self) {
#[cfg(feature = "disassemble")]
impl Block {
#[allow(dead_code)]
pub(crate) fn disassemble_block(&self) {
println!();
println!("=== <{}> ===", self.name);

let mut offset: usize = 0;
let mut line: usize = 0;
while offset < self.instructions.len() {
offset = self.disassemble_instruction(offset, line);
line += 1;
offset = self.disassemble_instruction(offset);
}

println!("=== </{}> ===", self.name);
}

fn disassemble_instruction(&self, offset: usize, line: usize) -> usize {
pub(crate) fn disassemble_instruction(&self, offset: usize) -> usize {
print!("{:04x} ", offset);

if line > 0 && self.lines[line] == self.lines[line - 1] {
let line = self.get_line(offset);
if offset > 0 && line == self.get_line(offset - 1) {
print!(" | ");
} else {
print!("{:6} ", self.lines[line]);
print!("{:6} ", line);
}

let instruction = OpCode::from_u8(self.instructions[offset]).unwrap();
Expand Down
25 changes: 25 additions & 0 deletions src/vm/block/lines.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
use crate::vm::block::{Block, Line};

impl Block {
pub(super) fn add_line(&mut self, offset: usize, line: usize) {
self.lines.push(Line { offset, line });
}

pub(super) fn get_line(&self, offset: usize) -> usize {
let mut line = 0;
let mut low = 0;
let mut high = self.lines.len() - 1;

while low <= high {
let mid = (low + high) / 2;
let l = self.lines.get(mid).unwrap();
if l.offset > offset {
high = mid - 1;
} else {
line = l.line;
low = mid + 1;
}
}
line
}
}
15 changes: 10 additions & 5 deletions src/vm/block/mod.rs
Original file line number Diff line number Diff line change
@@ -1,24 +1,29 @@
pub(self) mod block;
mod constants;
mod lines;
mod opcodes;

#[cfg(feature = "disassemble")]
mod disassembler;
pub(super) mod disassembler;

pub(crate) use crate::vm::block::opcodes::OpCode;
use crate::vm::vm::Value;

#[allow(dead_code)]
pub struct Block {
name: String,
constants: Constants,
instructions: Vec<u8>,
lines: Vec<usize>,
lines: Vec<Line>,
}

type Value = f64;
pub struct Constants {
struct Constants {
values: Vec<Value>,
}

struct Line {
pub line: usize,
pub offset: usize,
}

#[cfg(test)]
mod tests;
13 changes: 11 additions & 2 deletions src/vm/vm.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
use crate::vm::block::{Block, OpCode};
use num_traits::FromPrimitive;

pub(in crate::vm) type Value = f64;

pub struct VirtualMachine {
block: Block,
ip: usize,
block: Block,
stack: Vec<Value>,
}

pub enum Result {
Expand All @@ -14,7 +17,11 @@ pub enum Result {

impl VirtualMachine {
pub fn new(block: Block) -> Self {
VirtualMachine { block, ip: 0 }
VirtualMachine {
ip: 0,
block,
stack: Vec::new(),
}
}
pub fn interpret(&mut self) -> Result {
return self.run();
Expand All @@ -23,6 +30,8 @@ impl VirtualMachine {
#[inline(always)]
fn run(&mut self) -> Result {
loop {
#[cfg(feature = "disassemble")]
self.block.disassemble_instruction(self.ip);
match OpCode::from_u8(self.block.read_u8(self.ip)).unwrap() {
OpCode::Return => return Result::Ok,
OpCode::Constant => {
Expand Down

0 comments on commit 0c0b548

Please sign in to comment.