pull lines back out

main
Alpha Chen 2 years ago
parent 934cebc598
commit a5533ea58b
Signed by: alpha
SSH Key Fingerprint: SHA256:3fOT8fiYQG/aK9ntivV3Bqtg8AYQ7q4nV6ZgihOA20g

@ -8,21 +8,17 @@ pub enum OpCode {
Return, Return,
} }
#[derive(Debug)]
pub struct Instruction {
op_code: OpCode,
line: usize,
}
#[derive(Debug, Default)] #[derive(Debug, Default)]
pub struct Chunk { pub struct Chunk {
pub code: Vec<Instruction>, pub code: Vec<OpCode>,
pub lines: Vec<usize>,
pub constants: Vec<Value>, pub constants: Vec<Value>,
} }
impl Chunk { impl Chunk {
pub fn push(&mut self, op_code: OpCode, line: usize) { 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) { 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 { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let mut last_line: Option<usize> = None; 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)?; write!(f, "{:04} ", i)?;
if last_line == Some(instruction.line) { let line = self.lines[i];
if last_line == Some(line) {
write!(f, " | ")?; write!(f, " | ")?;
} else { } 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) => { OpCode::Constant(constant) => {
let value = self.constants[constant]; let value = self.constants[*constant];
writeln!(f, "{:<16} {:4} '{}'", "OP_CONSTANT", constant, value)?; writeln!(f, "{:<16} {:4} '{}'", "OP_CONSTANT", constant, value)?;
} }
OpCode::Return => writeln!(f, "OP_RETURN")?, OpCode::Return => writeln!(f, "OP_RETURN")?,

@ -1,13 +1,22 @@
use chunk::{Chunk, OpCode}; use chunk::{Chunk, OpCode};
use vm::VM;
use anyhow::Result;
mod chunk; mod chunk;
mod value; mod value;
mod vm;
fn main() { fn main() -> Result<()> {
let mut chunk = Chunk::default(); let mut chunk = Chunk::default();
chunk.push_constant(1.2, 123); chunk.push_constant(1.2, 123);
chunk.push(OpCode::Return, 123); chunk.push(OpCode::Return, 123);
chunk.disassemble("test chunk"); chunk.disassemble("test chunk");
let mut vm = VM::new(chunk);
vm.interpret()?;
Ok(())
} }

@ -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;
}
}
}
Loading…
Cancel
Save