Website Summary Files Commits Branches @commit @diff @stats
path: root / assembler / src / parser
diff options
context:
space:
mode:
Commit0e5324f0b0cb01f624bd28ff5b8a646000d33c96 (patch)
Author
 Syndamia <kamen@syndamia.com>
2025-02-13 22:40:13 +0200
Committer
 Syndamia <kamen@syndamia.com>
2025-02-13 22:40:13 +0200
Filesc90bea68ca0ee94f9cfe190bcda2b9cd78e6a56e /assembler/src/parser
tonkobali-0e5324f0b0cb01f624bd28ff5b8a646000d33c96.tar
tonkobali-0e5324f0b0cb01f624bd28ff5b8a646000d33c96.tar.gz
tonkobali-0e5324f0b0cb01f624bd28ff5b8a646000d33c96.zip
Parentd17f1356cbe20f8c464668c74a2eb005643b80ba (diff)
feat(assembler): Add instruction collapse code gen step
3 files changed, 53 insertions, 9 deletions
-rw-r--r--assembler/src/parser/code_gen.rs22
-rw-r--r--assembler/src/parser/instruction.rs23
-rw-r--r--assembler/src/parser/mod.rs17
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>,
}