[rlox] Add line information to chunk

This commit is contained in:
ctsk
2023-03-29 21:15:41 +02:00
parent d6e6b1d3ab
commit 73a3d93f82
2 changed files with 51 additions and 10 deletions

View File

@@ -2,6 +2,8 @@ mod vm;
fn main() { fn main() {
let mut chunk = vm::Chunk::new("TEST".to_string()); 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); println!("{:?}", chunk);
} }

View File

@@ -1,34 +1,73 @@
use std::convert::From;
use std::fmt; use std::fmt;
#[repr(u8)] #[repr(u8)]
#[derive(Debug)] #[derive(Copy, Clone, Debug)]
pub enum Op { pub enum Op {
Return Return,
Constant { offset: usize },
}
#[derive(Debug)]
pub struct Value {
val: f64,
}
impl From<f64> for Value {
fn from(value: f64) -> Self {
Value { val: value }
}
} }
pub struct Chunk { pub struct Chunk {
code: Vec<Op>, code: Vec<Op>,
name: String name: String,
debug_info: Vec<usize>,
constants: Vec<Value>,
} }
impl Chunk { impl Chunk {
pub fn new(name: String) -> Chunk { pub fn new(name: String) -> Self {
Chunk { Chunk {
code: Vec::new(), code: Vec::new(),
name name: name,
debug_info: Vec::new(),
constants: Vec::new(),
} }
} }
pub fn add(&mut self, op: Op) { pub fn add_op(&mut self, op: Op, line: usize) {
self.code.push(op) 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 { impl fmt::Debug for Chunk {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
writeln!(f, "-*-*- {} -*-*-", self.name)?; writeln!(f, "-*-*- {} -*-*-", self.name)?;
for (idx, op) in self.code.iter().enumerate() { for (idx, op) in self.code.iter().copied().enumerate() {
write!(f, "{:04} {:?}", idx, op)?; 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(()); return Ok(());