1
0

Prettify disassembly output

This commit is contained in:
Jeff 2024-09-09 20:55:00 -04:00
parent c406039c99
commit 5b8ec74d05
4 changed files with 68 additions and 25 deletions

View File

@ -1,4 +1,7 @@
use std::fmt::{self, Debug, Display, Formatter}; use std::{
fmt::{self, Debug, Display, Formatter},
rc::Weak,
};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
@ -112,16 +115,18 @@ impl Chunk {
output.push_str("== "); output.push_str("== ");
output.push_str(name); 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; let mut previous = None;
for (offset, (byte, position)) in self.code.iter().enumerate() { for (offset, (byte, position)) in self.code.iter().enumerate() {
if let Some(Instruction::Constant) = previous { 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; previous = None;
output.push_str(&display); output.push_str(&display_with_postion);
continue; continue;
} }
@ -130,18 +135,44 @@ impl Chunk {
Instruction::DefineVariable | Instruction::GetVariable | Instruction::SetVariable, Instruction::DefineVariable | Instruction::GetVariable | Instruction::SetVariable,
) = previous ) = 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; previous = None;
output.push_str(&display); output.push_str(&display_with_postion);
continue; continue;
} }
let instruction = Instruction::from_byte(*byte).unwrap(); 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); 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); output.push_str(&display);
} }

View File

@ -65,6 +65,10 @@ impl IdentifierStack {
depth: self.scope_depth, depth: self.scope_depth,
}); });
} }
pub fn iter(&self) -> impl Iterator<Item = &Local> {
self.locals.iter()
}
} }
impl Default for IdentifierStack { impl Default for IdentifierStack {

View File

@ -13,6 +13,14 @@ pub fn run(source: &str) -> Result<Option<Value>, DustError> {
mod tests { mod tests {
use super::*; 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] #[test]
fn variable() { fn variable() {
let source = "let foo = 42; foo"; let source = "let foo = 42; foo";

View File

@ -305,7 +305,7 @@ impl Instruction {
(index, value) (index, value)
}; };
format!("{offset:04} CONSTANT {index_display} {value_display}") format!("CONSTANT {index_display} {value_display}")
} }
Instruction::Return => format!("{offset:04} RETURN"), Instruction::Return => format!("{offset:04} RETURN"),
Instruction::Pop => format!("{offset:04} POP"), Instruction::Pop => format!("{offset:04} POP"),
@ -318,7 +318,7 @@ impl Instruction {
Err(error) => format!("{:?}", error), Err(error) => format!("{:?}", error),
}; };
format!("{offset:04} DEFINE_VARIABLE {identifier_display} {index}") format!("DEFINE_VARIABLE {identifier_display} {index}")
} }
Instruction::GetVariable => { Instruction::GetVariable => {
let (index, _) = chunk.read(offset + 1).unwrap(); let (index, _) = chunk.read(offset + 1).unwrap();
@ -327,7 +327,7 @@ impl Instruction {
Err(error) => format!("{:?}", error), Err(error) => format!("{:?}", error),
}; };
format!("{offset:04} GET_VARIABLE {identifier_display} {index}") format!("GET_VARIABLE {identifier_display} {index}")
} }
Instruction::SetVariable => { Instruction::SetVariable => {
@ -337,26 +337,26 @@ impl Instruction {
Err(error) => format!("{:?}", error), Err(error) => format!("{:?}", error),
}; };
format!("{offset:04} SET_VARIABLE {identifier_display} {index}") format!("SET_VARIABLE {identifier_display} {index}")
} }
// Unary // Unary
Instruction::Negate => format!("{offset:04} NEGATE"), Instruction::Negate => "NEGATE".to_string(),
Instruction::Not => format!("{offset:04} NOT"), Instruction::Not => "NOT".to_string(),
// Binary // Binary
Instruction::Add => format!("{offset:04} ADD"), Instruction::Add => "ADD".to_string(),
Instruction::Subtract => format!("{offset:04} SUBTRACT"), Instruction::Subtract => "SUBTRACT".to_string(),
Instruction::Multiply => format!("{offset:04} MULTIPLY"), Instruction::Multiply => "MULTIPLY".to_string(),
Instruction::Divide => format!("{offset:04} DIVIDE"), Instruction::Divide => "DIVIDE".to_string(),
Instruction::Greater => format!("{offset:04} GREATER"), Instruction::Greater => "GREATER".to_string(),
Instruction::Less => format!("{offset:04} LESS"), Instruction::Less => "LESS".to_string(),
Instruction::GreaterEqual => format!("{offset:04} GREATER_EQUAL"), Instruction::GreaterEqual => "GREATER_EQUAL".to_string(),
Instruction::LessEqual => format!("{offset:04} LESS_EQUAL"), Instruction::LessEqual => "LESS_EQUAL".to_string(),
Instruction::Equal => format!("{offset:04} EQUAL"), Instruction::Equal => "EQUAL".to_string(),
Instruction::NotEqual => format!("{offset:04} NOT_EQUAL"), Instruction::NotEqual => "NOT_EQUAL".to_string(),
Instruction::And => format!("{offset:04} AND"), Instruction::And => "AND".to_string(),
Instruction::Or => format!("{offset:04} OR"), Instruction::Or => "OR".to_string(),
} }
} }
} }