From 5b8ec74d05753730b715d8ce7d36725cbc204c24 Mon Sep 17 00:00:00 2001 From: Jeff Date: Mon, 9 Sep 2024 20:55:00 -0400 Subject: [PATCH] Prettify disassembly output --- dust-lang/src/chunk.rs | 45 ++++++++++++++++++++++++++----- dust-lang/src/identifier_stack.rs | 4 +++ dust-lang/src/run.rs | 8 ++++++ dust-lang/src/vm.rs | 36 ++++++++++++------------- 4 files changed, 68 insertions(+), 25 deletions(-) diff --git a/dust-lang/src/chunk.rs b/dust-lang/src/chunk.rs index 5f18987..d36a728 100644 --- a/dust-lang/src/chunk.rs +++ b/dust-lang/src/chunk.rs @@ -1,4 +1,7 @@ -use std::fmt::{self, Debug, Display, Formatter}; +use std::{ + fmt::{self, Debug, Display, Formatter}, + rc::Weak, +}; use serde::{Deserialize, Serialize}; @@ -112,16 +115,18 @@ impl Chunk { output.push_str("== "); output.push_str(name); - output.push_str(" ==\n"); + output.push_str(" ==\n--code--\n"); + output.push_str("OFFSET INSTRUCTION POSITION\n"); let mut previous = None; for (offset, (byte, position)) in self.code.iter().enumerate() { if let Some(Instruction::Constant) = previous { - let display = format!("{position} {offset:04} CONSTANT_INDEX {byte}\n"); + let display = format!("{offset:04} CONSTANT_INDEX {byte}"); + let display_with_postion = format!("{display:26} {position}\n"); previous = None; - output.push_str(&display); + output.push_str(&display_with_postion); continue; } @@ -130,18 +135,44 @@ impl Chunk { Instruction::DefineVariable | Instruction::GetVariable | Instruction::SetVariable, ) = previous { - let display = format!("{position} {offset:04} IDENTIFIER_INDEX {byte}\n"); + let display = format!("{offset:04} IDENTIFIER_INDEX {byte}"); + let display_with_postion = format!("{display:26} {position}\n"); + previous = None; - output.push_str(&display); + output.push_str(&display_with_postion); continue; } let instruction = Instruction::from_byte(*byte).unwrap(); - let display = format!("{} {}\n", position, instruction.disassemble(self, offset)); + let display = format!("{offset:04} {}", instruction.disassemble(self, offset)); + let display_with_postion = format!("{display:26} {position}\n"); + previous = Some(instruction); + output.push_str(&display_with_postion); + } + + output.push_str("--constants--\n"); + output.push_str("INDEX KIND VALUE\n"); + + for (index, value) in self.constants.iter().enumerate() { + let value_kind_display = match value { + Value::Raw(_) => "RAW ", + Value::Reference(_) => "REF ", + Value::Mutable(_) => "MUT ", + }; + let display = format!("{index:04} {value_kind_display} {value}\n"); + + output.push_str(&display); + } + + output.push_str("--identifiers--\n"); + output.push_str("INDEX IDENTIFIER DEPTH\n"); + + for (index, Local { identifier, depth }) in self.identifiers.iter().enumerate() { + let display = format!("{index:04} {:10} {depth}\n", identifier.as_str()); output.push_str(&display); } diff --git a/dust-lang/src/identifier_stack.rs b/dust-lang/src/identifier_stack.rs index 811278b..4f717d1 100644 --- a/dust-lang/src/identifier_stack.rs +++ b/dust-lang/src/identifier_stack.rs @@ -65,6 +65,10 @@ impl IdentifierStack { depth: self.scope_depth, }); } + + pub fn iter(&self) -> impl Iterator { + self.locals.iter() + } } impl Default for IdentifierStack { diff --git a/dust-lang/src/run.rs b/dust-lang/src/run.rs index ad99885..8077798 100644 --- a/dust-lang/src/run.rs +++ b/dust-lang/src/run.rs @@ -13,6 +13,14 @@ pub fn run(source: &str) -> Result, DustError> { mod tests { use super::*; + #[test] + fn add_variables() { + let source = "let foo = 21; let bar = 21; foo + bar"; + let result = run(source); + + assert_eq!(result, Ok(Some(Value::integer(42)))); + } + #[test] fn variable() { let source = "let foo = 42; foo"; diff --git a/dust-lang/src/vm.rs b/dust-lang/src/vm.rs index 005dcea..4bafa2f 100644 --- a/dust-lang/src/vm.rs +++ b/dust-lang/src/vm.rs @@ -305,7 +305,7 @@ impl Instruction { (index, value) }; - format!("{offset:04} CONSTANT {index_display} {value_display}") + format!("CONSTANT {index_display} {value_display}") } Instruction::Return => format!("{offset:04} RETURN"), Instruction::Pop => format!("{offset:04} POP"), @@ -318,7 +318,7 @@ impl Instruction { Err(error) => format!("{:?}", error), }; - format!("{offset:04} DEFINE_VARIABLE {identifier_display} {index}") + format!("DEFINE_VARIABLE {identifier_display} {index}") } Instruction::GetVariable => { let (index, _) = chunk.read(offset + 1).unwrap(); @@ -327,7 +327,7 @@ impl Instruction { Err(error) => format!("{:?}", error), }; - format!("{offset:04} GET_VARIABLE {identifier_display} {index}") + format!("GET_VARIABLE {identifier_display} {index}") } Instruction::SetVariable => { @@ -337,26 +337,26 @@ impl Instruction { Err(error) => format!("{:?}", error), }; - format!("{offset:04} SET_VARIABLE {identifier_display} {index}") + format!("SET_VARIABLE {identifier_display} {index}") } // Unary - Instruction::Negate => format!("{offset:04} NEGATE"), - Instruction::Not => format!("{offset:04} NOT"), + Instruction::Negate => "NEGATE".to_string(), + Instruction::Not => "NOT".to_string(), // Binary - Instruction::Add => format!("{offset:04} ADD"), - Instruction::Subtract => format!("{offset:04} SUBTRACT"), - Instruction::Multiply => format!("{offset:04} MULTIPLY"), - Instruction::Divide => format!("{offset:04} DIVIDE"), - Instruction::Greater => format!("{offset:04} GREATER"), - Instruction::Less => format!("{offset:04} LESS"), - Instruction::GreaterEqual => format!("{offset:04} GREATER_EQUAL"), - Instruction::LessEqual => format!("{offset:04} LESS_EQUAL"), - Instruction::Equal => format!("{offset:04} EQUAL"), - Instruction::NotEqual => format!("{offset:04} NOT_EQUAL"), - Instruction::And => format!("{offset:04} AND"), - Instruction::Or => format!("{offset:04} OR"), + Instruction::Add => "ADD".to_string(), + Instruction::Subtract => "SUBTRACT".to_string(), + Instruction::Multiply => "MULTIPLY".to_string(), + Instruction::Divide => "DIVIDE".to_string(), + Instruction::Greater => "GREATER".to_string(), + Instruction::Less => "LESS".to_string(), + Instruction::GreaterEqual => "GREATER_EQUAL".to_string(), + Instruction::LessEqual => "LESS_EQUAL".to_string(), + Instruction::Equal => "EQUAL".to_string(), + Instruction::NotEqual => "NOT_EQUAL".to_string(), + Instruction::And => "AND".to_string(), + Instruction::Or => "OR".to_string(), } } }