diff --git a/rlox/src/bc.rs b/rlox/src/bc.rs new file mode 100644 index 0000000..c611397 --- /dev/null +++ b/rlox/src/bc.rs @@ -0,0 +1,112 @@ +use std::convert::From; +use std::fmt; + +#[derive(Copy, Clone, Debug)] +pub enum Op { + Return, + Constant { offset: usize }, + Negate, + Add, + Subtract, + Multiply, + Divide, +} + +#[derive(Copy, Clone, PartialEq)] +pub struct Value { + pub val: f64, +} + +impl fmt::Debug for Value { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { + write!(f, "{}", self.val) + } +} + +impl From for Value { + fn from(value: f64) -> Self { + Value { val: value } + } +} + +pub struct Chunk { + pub code: Vec, + pub name: String, + pub debug_info: Vec, + pub constants: Vec, +} + +impl Chunk { + pub fn new(name: String) -> Self { + Chunk { + code: Vec::new(), + name, + debug_info: Vec::new(), + constants: Vec::new(), + } + } + + 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().copied().enumerate() { + writeln!( + f, + "{:?}", + TraceInfo { + offset: idx, + op: op, + chunk: &self + } + )?; + } + + return Ok(()); + } +} + +pub struct TraceInfo<'a> { + pub offset: usize, + pub op: Op, + pub chunk: &'a Chunk, +} + +impl fmt::Debug for TraceInfo<'_> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { + let chunk = self.chunk; + let op = self.op; + let offset = self.offset; + + write!(f, "{:04} ", offset)?; + + let line = chunk.debug_info[offset]; + + if offset > 0 && chunk.debug_info[offset - 1] == line { + write!(f, " | ") + } else { + write!(f, "{:4} ", line) + }?; + + match op { + Op::Return | Op::Negate | Op::Add | Op::Subtract | Op::Multiply | Op::Divide => { + write!(f, "{:?}", op) + } + Op::Constant { offset } => { + f.debug_struct("Constant") + .field("val", &chunk.constants[offset].val) + .finish()?; + write!(f, "") + } + } + } +} diff --git a/rlox/src/lc.rs b/rlox/src/lc.rs index da44da1..5843645 100644 --- a/rlox/src/lc.rs +++ b/rlox/src/lc.rs @@ -1,7 +1,8 @@ -use std::collections::BTreeSet; use std::iter::Peekable; use std::str::CharIndices; +use crate::bc::Chunk; + #[derive(Debug)] enum TokenType { Eof, diff --git a/rlox/src/main.rs b/rlox/src/main.rs index f2f4d54..ea0563f 100644 --- a/rlox/src/main.rs +++ b/rlox/src/main.rs @@ -1,9 +1,11 @@ -mod vm; +mod bc; mod lc; +mod vm; use std::env; fn repl() { + } fn run_file() { diff --git a/rlox/src/vm.rs b/rlox/src/vm.rs index fe2b9d6..ff228b1 100644 --- a/rlox/src/vm.rs +++ b/rlox/src/vm.rs @@ -1,116 +1,4 @@ -use std::convert::From; -use std::fmt; - -#[repr(u8)] -#[derive(Copy, Clone, Debug)] -pub enum Op { - Return, - Constant { offset: usize }, - Negate, - Add, - Subtract, - Multiply, - Divide, -} - -#[derive(Copy, Clone, PartialEq)] -pub struct Value { - val: f64, -} - -impl fmt::Debug for Value { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { - write!(f, "{}", self.val) - } -} - -impl From for Value { - fn from(value: f64) -> Self { - Value { val: value } - } -} - -pub struct Chunk { - code: Vec, - name: String, - debug_info: Vec, - constants: Vec, -} - -impl Chunk { - pub fn new(name: String) -> Self { - Chunk { - code: Vec::new(), - name: name, - debug_info: Vec::new(), - constants: Vec::new(), - } - } - - 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().copied().enumerate() { - writeln!( - f, - "{:?}", - TraceInfo { - offset: idx, - op: op, - chunk: &self - } - )?; - } - - return Ok(()); - } -} - -struct TraceInfo<'a> { - offset: usize, - op: Op, - chunk: &'a Chunk, -} - -impl fmt::Debug for TraceInfo<'_> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { - let chunk = self.chunk; - let op = self.op; - let offset = self.offset; - - write!(f, "{:04} ", offset)?; - - let line = chunk.debug_info[offset]; - - if offset > 0 && chunk.debug_info[offset - 1] == line { - write!(f, " | ") - } else { - write!(f, "{:4} ", line) - }?; - - match op { - Op::Return | Op::Negate | Op::Add | Op::Subtract | Op::Multiply | Op::Divide => { - write!(f, "{:?}", op) - } - Op::Constant { offset } => { - f.debug_struct("Constant") - .field("val", &chunk.constants[offset].val) - .finish()?; - write!(f, "") - } - } - } -} +use crate::bc::{Chunk, Op, TraceInfo, Value}; pub struct VM { pub trace: bool,