add disassembly & display functions
This commit is contained in:
parent
7efee58c4d
commit
4fb80fe158
3 changed files with 62 additions and 1 deletions
|
@ -5,7 +5,7 @@ use {
|
|||
}
|
||||
};
|
||||
|
||||
#[derive(Clone)]
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum AssemblyWord {
|
||||
Symbol( LinkAddr ),
|
||||
Lit( VM_Word )
|
||||
|
@ -25,6 +25,38 @@ impl AssemblyWord {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn disassemble(bytecode: &Vec< AssemblyWord >) -> Vec< String > {
|
||||
let mut words = bytecode.iter();
|
||||
let mut result = Vec::new();
|
||||
|
||||
let mut remaining_params = 0;
|
||||
|
||||
while let Some(w) = words.next() {
|
||||
match w {
|
||||
AssemblyWord::Symbol( addr ) => {
|
||||
result.push( format!("{}", addr) );
|
||||
remaining_params -= 1;
|
||||
}
|
||||
AssemblyWord::Lit(w) => {
|
||||
if remaining_params == 0 {
|
||||
if *w < 18 {
|
||||
let inst : VM_Instruction = unsafe { std::mem::transmute(*w) };
|
||||
result.push(format!("{:?}", inst));
|
||||
remaining_params = inst.param_length();
|
||||
} else {
|
||||
result.push(format!("invalid opcode {}", w));
|
||||
}
|
||||
} else {
|
||||
remaining_params -= 1;
|
||||
result.push(format!("{}", w));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
result
|
||||
}
|
||||
|
||||
pub struct Assembler {
|
||||
words: Vec< AssemblyWord >,
|
||||
}
|
||||
|
|
|
@ -12,6 +12,21 @@ pub enum LinkAddr {
|
|||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Display for LinkAddr {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
|
||||
match self {
|
||||
LinkAddr::Absolute(addr) =>
|
||||
write!(f, "{:x}", addr),
|
||||
LinkAddr::Relative{ symbol, offset } =>
|
||||
if *offset == 0 {
|
||||
write!(f, "{}", symbol)
|
||||
} else {
|
||||
write!(f, "{}+{:x}", symbol, offset)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Section {
|
||||
addr: VM_Word,
|
||||
data: Vec< AssemblyWord >
|
||||
|
|
14
src/vm.rs
14
src/vm.rs
|
@ -12,6 +12,20 @@ pub enum VM_Instruction {
|
|||
BitwiseNot,
|
||||
}
|
||||
|
||||
impl VM_Instruction {
|
||||
pub fn param_length(&self) -> usize {
|
||||
match self {
|
||||
VM_Instruction::Jmp |
|
||||
VM_Instruction::Call |
|
||||
VM_Instruction::Branch |
|
||||
VM_Instruction::Lit => {
|
||||
1
|
||||
},
|
||||
_ => 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct VM {
|
||||
pub data_stack: Vec< VM_Word >,
|
||||
pub call_stack: Vec< VM_Word >,
|
||||
|
|
Loading…
Reference in a new issue