diff --git a/src/main.rs b/src/main.rs index f3d1d66..00e32cf 100644 --- a/src/main.rs +++ b/src/main.rs @@ -5,7 +5,7 @@ use crate::vm::block::{Block, OpCode}; use colored::Colorize; #[cfg(feature = "disassemble")] -use crate::vm::block::BlockDbg; +use vm::block::BlockDbg; fn main() { println!( @@ -15,15 +15,15 @@ fn main() { let mut block = Block::new("ZeBlock"); - let constant_index = block.push_constant(1234.56); - block.push_op_code(OpCode::Constant); + let constant_index = block.push_constant(1234.56, 2); + block.push_op_code(OpCode::Constant, 2); block.write_byte(constant_index); - let constant_index = block.push_constant(789.10); - block.push_op_code(OpCode::Constant); + let constant_index = block.push_constant(789.10, 4); + block.push_op_code(OpCode::Constant, 4); block.write_byte(constant_index); - block.push_op_code(OpCode::Return); + block.push_op_code(OpCode::Return, 4); #[cfg(feature = "disassemble")] block.disassemble_block(); diff --git a/src/vm/block.rs b/src/vm/block.rs index 5d9f9a7..2fcdcc7 100644 --- a/src/vm/block.rs +++ b/src/vm/block.rs @@ -13,24 +13,28 @@ pub enum OpCode { #[allow(dead_code)] pub struct Block { name: String, - instructions: Vec, constants: Constants, + instructions: Vec, + lines: Vec, } impl Block { pub fn new(name: &str) -> Self { Block { name: String::from(name), - instructions: Vec::new(), constants: Constants::new(), + instructions: Vec::new(), + lines: Vec::new(), } } - pub fn push_op_code(&mut self, op_code: OpCode) { + pub fn push_op_code(&mut self, op_code: OpCode, line: usize) { + self.lines.push(line); self.instructions.push(op_code as u8) } - pub fn push_constant(&mut self, value: f64) -> i8 { + pub fn push_constant(&mut self, value: f64, line: usize) -> i8 { + self.lines.push(line); self.constants.push_value(value) } @@ -64,6 +68,12 @@ impl BlockDbg for Block { fn disassemble_instruction(&self, offset: usize) -> usize { print!("{:04x} ", offset); + if offset > 0 && self.lines[offset] == self.lines[offset - 1] { + print!(" | "); + } else { + print!("{:6} ", self.lines[offset]); + } + let instruction = OpCode::from_u8(self.instructions[offset]).unwrap(); return match instruction { OpCode::Constant => self.constant_instruction(OpCode::Constant, offset), @@ -100,7 +110,7 @@ mod tests { #[test] fn op_code_can_be_pushed_to_an_block() { let mut block = Block::new("jenny"); - block.push_op_code(OpCode::Return); + block.push_op_code(OpCode::Return, 123); assert_eq!(1, block.instructions.len()); assert_eq!(OpCode::Return as u8, block.instructions[0]);