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<Instruction>,
+ pub code: Vec<OpCode>,
+ pub lines: Vec<usize>,
pub constants: Vec<Value>,
}
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<usize> = 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;
+ }
+ }
+}