diff --git a/src/assembler.rs b/src/assembler.rs index 74a3049..4e1f560 100644 --- a/src/assembler.rs +++ b/src/assembler.rs @@ -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 >, } diff --git a/src/linker.rs b/src/linker.rs index 1095954..5c48f5b 100644 --- a/src/linker.rs +++ b/src/linker.rs @@ -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 > diff --git a/src/vm.rs b/src/vm.rs index 1e27a86..0d71434 100644 --- a/src/vm.rs +++ b/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 >,