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};
@ -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);
}

View File

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

View File

@ -13,6 +13,14 @@ pub fn run(source: &str) -> Result<Option<Value>, 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";

View File

@ -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(),
}
}
}