[rlox] refactor
This commit is contained in:
112
rlox/src/bc.rs
Normal file
112
rlox/src/bc.rs
Normal file
@@ -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<f64> for Value {
|
||||||
|
fn from(value: f64) -> Self {
|
||||||
|
Value { val: value }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Chunk {
|
||||||
|
pub code: Vec<Op>,
|
||||||
|
pub name: String,
|
||||||
|
pub debug_info: Vec<usize>,
|
||||||
|
pub constants: Vec<Value>,
|
||||||
|
}
|
||||||
|
|
||||||
|
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, "")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,7 +1,8 @@
|
|||||||
use std::collections::BTreeSet;
|
|
||||||
use std::iter::Peekable;
|
use std::iter::Peekable;
|
||||||
use std::str::CharIndices;
|
use std::str::CharIndices;
|
||||||
|
|
||||||
|
use crate::bc::Chunk;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
enum TokenType {
|
enum TokenType {
|
||||||
Eof,
|
Eof,
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
mod vm;
|
mod bc;
|
||||||
mod lc;
|
mod lc;
|
||||||
|
mod vm;
|
||||||
|
|
||||||
use std::env;
|
use std::env;
|
||||||
|
|
||||||
fn repl() {
|
fn repl() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run_file() {
|
fn run_file() {
|
||||||
|
|||||||
114
rlox/src/vm.rs
114
rlox/src/vm.rs
@@ -1,116 +1,4 @@
|
|||||||
use std::convert::From;
|
use crate::bc::{Chunk, Op, TraceInfo, Value};
|
||||||
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<f64> for Value {
|
|
||||||
fn from(value: f64) -> Self {
|
|
||||||
Value { val: value }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct Chunk {
|
|
||||||
code: Vec<Op>,
|
|
||||||
name: String,
|
|
||||||
debug_info: Vec<usize>,
|
|
||||||
constants: Vec<Value>,
|
|
||||||
}
|
|
||||||
|
|
||||||
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, "")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct VM {
|
pub struct VM {
|
||||||
pub trace: bool,
|
pub trace: bool,
|
||||||
|
|||||||
Reference in New Issue
Block a user