diff --git a/rust/src/chunk.rs b/rust/src/chunk.rs index c57fa76..0fc8169 100644 --- a/rust/src/chunk.rs +++ b/rust/src/chunk.rs @@ -8,21 +8,17 @@ pub enum OpCode { Return, } -#[derive(Debug)] -pub struct Instruction { - op_code: OpCode, - line: usize, -} - #[derive(Debug, Default)] pub struct Chunk { - pub code: Vec, + pub code: Vec, + pub lines: Vec, pub constants: Vec, } impl Chunk { pub fn push(&mut self, op_code: OpCode, line: usize) { - self.code.push(Instruction { op_code, line }); + self.code.push(op_code); + self.lines.push(line); } pub fn push_constant(&mut self, value: Value, line: usize) { @@ -39,18 +35,19 @@ impl fmt::Display for Chunk { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let mut last_line: Option = None; - for (i, instruction) in self.code.iter().enumerate() { + for (i, op_code) in self.code.iter().enumerate() { write!(f, "{:04} ", i)?; - if last_line == Some(instruction.line) { + let line = self.lines[i]; + if last_line == Some(line) { write!(f, " | ")?; } else { - write!(f, "{:>4} ", instruction.line)?; + write!(f, "{:>4} ", line)?; } - last_line = Some(instruction.line); + last_line = Some(line); - match instruction.op_code { + match op_code { OpCode::Constant(constant) => { - let value = self.constants[constant]; + let value = self.constants[*constant]; writeln!(f, "{:<16} {:4} '{}'", "OP_CONSTANT", constant, value)?; } OpCode::Return => writeln!(f, "OP_RETURN")?, diff --git a/rust/src/main.rs b/rust/src/main.rs index 71cc773..344475d 100644 --- a/rust/src/main.rs +++ b/rust/src/main.rs @@ -1,13 +1,22 @@ use chunk::{Chunk, OpCode}; +use vm::VM; + +use anyhow::Result; mod chunk; mod value; +mod vm; -fn main() { +fn main() -> Result<()> { let mut chunk = Chunk::default(); chunk.push_constant(1.2, 123); chunk.push(OpCode::Return, 123); chunk.disassemble("test chunk"); + + let mut vm = VM::new(chunk); + vm.interpret()?; + + Ok(()) } diff --git a/rust/src/vm.rs b/rust/src/vm.rs new file mode 100644 index 0000000..4f4a2c8 --- /dev/null +++ b/rust/src/vm.rs @@ -0,0 +1,37 @@ +use anyhow::Result; +use thiserror::Error; + +use crate::chunk::{Chunk, OpCode}; + +#[derive(Error, Debug)] +pub enum InterpretError { + #[error("compile error")] + Compile, + #[error("runtime error")] + Runtime, +} + +pub struct VM { + chunk: Chunk, + ip: usize, +} + +impl VM { + pub fn new(chunk: Chunk) -> Self { + Self { chunk, ip: 0 } + } + + pub fn interpret(&mut self) -> Result<()> { + loop { + match self.chunk.code[self.ip] { + OpCode::Constant(constant) => { + let value = self.chunk.constants[constant]; + println!("{}", value); + }, + OpCode::Return => return Ok(()), + } + + self.ip += 1; + } + } +}