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};
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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 {
|
||||||
|
@ -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";
|
||||||
|
@ -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(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user