diff options
| Commit | 0e5324f0b0cb01f624bd28ff5b8a646000d33c96 (patch) | |
|---|---|---|
| Author | 2025-02-13 22:40:13 +0200 | |
| Committer | 2025-02-13 22:40:13 +0200 | |
| Files | c90bea68ca0ee94f9cfe190bcda2b9cd78e6a56e /assembler/src/parser | |
| tonkobali-0e5324f0b0cb01f624bd28ff5b8a646000d33c96.tar tonkobali-0e5324f0b0cb01f624bd28ff5b8a646000d33c96.tar.gz tonkobali-0e5324f0b0cb01f624bd28ff5b8a646000d33c96.zip | ||
| Parent | d17f1356cbe20f8c464668c74a2eb005643b80ba (diff) | |
feat(assembler): Add instruction collapse code gen step
3 files changed, 53 insertions, 9 deletions
| -rw-r--r-- | assembler/src/parser/code_gen.rs | 22 | ||||
| -rw-r--r-- | assembler/src/parser/instruction.rs | 23 | ||||
| -rw-r--r-- | assembler/src/parser/mod.rs | 17 |
diff --git a/assembler/src/parser/code_gen.rs b/assembler/src/parser/code_gen.rs index 375a8cb..dd1b872 100644 --- a/assembler/src/parser/code_gen.rs +++ b/assembler/src/parser/code_gen.rs @@ -1,4 +1,4 @@ -use super::{ Program, Address }; +use super::{ Program, Address, Instruction }; impl Program { pub(crate) fn remove_definition_addresses(&mut self) { @@ -10,4 +10,24 @@ impl Program { } } } + + pub(crate) fn collapse_instructions(&mut self) { + let mut collapsed = Vec::new(); + let mut update_addrs = Vec::new(); + + for instr in &mut self.instructions { + update_addrs.push(collapsed.len()); + collapsed.extend(instr.collapse()); + } + + for instr in &mut self.instructions { + for arg in &mut instr.args { + if let Address::Instruction(num) = arg { + *arg = Address::Instruction(update_addrs[*num]); + } + } + } + + self.instructions = collapsed; + } } diff --git a/assembler/src/parser/instruction.rs b/assembler/src/parser/instruction.rs index e69de29..8c8e8aa 100644 --- a/assembler/src/parser/instruction.rs +++ b/assembler/src/parser/instruction.rs @@ -0,0 +1,23 @@ +use super::{ Instruction, Address }; + +impl Instruction { + fn new_subleq(a: &Address, b: &Address, c: &Address) -> Instruction { + Instruction { + name: "subleq".to_string(), + args: vec![a.clone(), b.clone(), c.clone()], + } + } + + pub(crate) fn collapse(&mut self) -> Vec<Instruction> { + self.name = self.name.to_lowercase(); + static Z: Address = Address::Memory(0); + + match &*self.name { + "subleq" | "add" | "mult" => vec![self.clone()], + "jmp" => vec![ + Instruction::new_subleq(&Z, &Z, &self.args[0]), + ], + _ => panic!("Unknown instruction {}!", self.name), + } + } +} diff --git a/assembler/src/parser/mod.rs b/assembler/src/parser/mod.rs index af78478..5dbedf6 100644 --- a/assembler/src/parser/mod.rs +++ b/assembler/src/parser/mod.rs @@ -1,13 +1,15 @@ mod code_gen; mod syntax; +mod instruction; use std::collections::HashMap; use crate::Word; #[derive(Debug, Default)] -pub(crate) struct Instruction { - name: String, - args: Vec<Address>, +pub(crate) struct Program { + definitions: HashMap<String, Address>, + constants: Vec<Word>, + instructions: Vec<Instruction>, } #[derive(Debug, Default, PartialEq, Eq, Clone)] @@ -28,9 +30,8 @@ impl Address { } } -#[derive(Debug, Default)] -pub(crate) struct Program { - definitions: HashMap<String, Address>, - constants: Vec<Word>, - instructions: Vec<Instruction>, +#[derive(Debug, Default, Clone)] +pub(crate) struct Instruction { + name: String, + args: Vec<Address>, } |
