diff --git a/rlox/src/main.rs b/rlox/src/main.rs index a65eff0..c71c35a 100644 --- a/rlox/src/main.rs +++ b/rlox/src/main.rs @@ -2,6 +2,8 @@ mod vm; fn main() { let mut chunk = vm::Chunk::new("TEST".to_string()); - chunk.add(vm::Op::Return); + chunk.add_op(vm::Op::Return, 1); + chunk.add_op(vm::Op::Constant { offset: 0 }, 1); + chunk.add_constant(vm::Value::from(3.14)); println!("{:?}", chunk); } diff --git a/rlox/src/vm.rs b/rlox/src/vm.rs index 1715a2a..535e75c 100644 --- a/rlox/src/vm.rs +++ b/rlox/src/vm.rs @@ -1,34 +1,73 @@ +use std::convert::From; use std::fmt; #[repr(u8)] -#[derive(Debug)] +#[derive(Copy, Clone, Debug)] pub enum Op { - Return + Return, + Constant { offset: usize }, +} + +#[derive(Debug)] +pub struct Value { + val: f64, +} + +impl From for Value { + fn from(value: f64) -> Self { + Value { val: value } + } } pub struct Chunk { code: Vec, - name: String + name: String, + debug_info: Vec, + constants: Vec, } impl Chunk { - pub fn new(name: String) -> Chunk { + pub fn new(name: String) -> Self { Chunk { code: Vec::new(), - name + name: name, + debug_info: Vec::new(), + constants: Vec::new(), } } - pub fn add(&mut self, op: Op) { - self.code.push(op) + pub fn add_op(&mut self, op: Op, line: usize) { + self.code.push(op); + self.debug_info.push(line); + + } + + pub fn add_constant(&mut self, value: Value) { + self.constants.push(value); } } impl fmt::Debug for Chunk { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { writeln!(f, "-*-*- {} -*-*-", self.name)?; - for (idx, op) in self.code.iter().enumerate() { - write!(f, "{:04} {:?}", idx, op)?; + for (idx, op) in self.code.iter().copied().enumerate() { + write!(f, "{:04} ", idx)?; + + let line = self.debug_info[idx]; + + if idx > 0 && self.debug_info[idx-1] == line { + write!(f, " | ")?; + } else { + write!(f, "{:4} ", line)?; + } + + match op { + Op::Return => writeln!(f, "{:?}", op), + Op::Constant { offset } => + f.debug_struct("Constant") + .field("val", &self.constants[offset].val) + .finish(), + }?; } return Ok(());