Prettify disassembly output
This commit is contained in:
parent
c406039c99
commit
5b8ec74d05
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -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";
|
||||
|
@ -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(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user