Website Summary Files Commits Branches @commit @diff @stats
path: root / assembler / src / parser
diff options
context:
space:
mode:
Commit9c656c296827172589243d588f57f9ab2745efc6 (patch)
Author
 Syndamia <kamen@syndamia.com>
2025-02-14 08:50:49 +0200
Committer
 Syndamia <kamen@syndamia.com>
2025-02-14 08:50:49 +0200
Filesac637c6034d5e8e2dcb50f609b4b063ca7422add /assembler/src/parser
tonkobali-9c656c296827172589243d588f57f9ab2745efc6.tar
tonkobali-9c656c296827172589243d588f57f9ab2745efc6.tar.gz
tonkobali-9c656c296827172589243d588f57f9ab2745efc6.zip
Parent9517d3d05e86621b6c4ed58edd7f5821632e0872 (diff)
feat(assembler): Implement beq and mov instructions
2 files changed, 54 insertions, 0 deletions
-rw-r--r--assembler/src/parser/code_gen.rs16
-rw-r--r--assembler/src/parser/instruction.rs38
diff --git a/assembler/src/parser/code_gen.rs b/assembler/src/parser/code_gen.rs
index 74a4fad..1c5b95a 100644
--- a/assembler/src/parser/code_gen.rs
+++ b/assembler/src/parser/code_gen.rs
@@ -5,6 +5,22 @@ impl Program {
/* Intermediate code generation */
pub(crate) fn collapse_instructions(&mut self) {
+ // Fix instruction addresses
+ let mut offsets = Vec::new();
+ for instr in &self.instructions {
+ offsets.push(instr.collapse_len() + offsets.last().unwrap_or(&0));
+ }
+ offsets.insert(0, 0);
+
+ for instr in &mut self.instructions {
+ for arg in &mut instr.args {
+ if let Address::Instruction(num) = arg {
+ *arg = Address::Instruction(offsets[*num]);
+ }
+ }
+ }
+
+ // Collapse all instructions
let mut collapsed = Vec::new();
for instr in &mut self.instructions {
diff --git a/assembler/src/parser/instruction.rs b/assembler/src/parser/instruction.rs
index 18d67b7..cc0523f 100644
--- a/assembler/src/parser/instruction.rs
+++ b/assembler/src/parser/instruction.rs
@@ -52,6 +52,20 @@ impl Instruction {
"add" => {
self.check_args_len(2)?;
},
+ "mov" => {
+ self.check_args_len(2)?;
+
+ if ! self.args[1].is_location() {
+ return Err(ArgumentError::NotLocation);
+ }
+ },
+ "beq" => {
+ self.check_args_len(2)?;
+
+ if ! self.args[1].is_location() {
+ return Err(ArgumentError::NotLocation);
+ }
+ },
_ => return Err(ArgumentError::UnknownInstruction),
}
Ok(())
@@ -71,6 +85,30 @@ impl Instruction {
Instruction::new_subleq(&Z, &self.args[1], &Address::Instruction(next + 2)),
Instruction::new_subleq(&Z, &Z, &Address::Instruction(next + 3)),
],
+ "mov" => vec![
+ Instruction::new_subleq(&self.args[1], &self.args[1], &Address::Instruction(next + 1)),
+ Instruction::new_subleq(&self.args[0], &Z, &Address::Instruction(next + 2)),
+ Instruction::new_subleq(&Z, &self.args[1], &Address::Instruction(next + 3)),
+ Instruction::new_subleq(&Z, &Z, &Address::Instruction(next + 4)),
+ ],
+ "beq" => vec![
+ Instruction::new_subleq(&self.args[0], &Z, &Address::Instruction(next + 2)),
+ Instruction::new_subleq(&Z, &Z, &Address::Instruction(next + 4)),
+ Instruction::new_subleq(&Z, &Z, &Address::Instruction(next + 3)),
+ Instruction::new_subleq(&Z, &self.args[0], &self.args[1] ),
+ ],
+ _ => panic!("Unknown instruction {}!", self.name),
+ }
+ }
+
+ pub(crate) fn collapse_len(&self) -> usize {
+ match &*self.name {
+ "subleq" | "jmp"
+ => 1,
+ "add"
+ => 3,
+ "mov" | "beq"
+ => 4,
_ => panic!("Unknown instruction {}!", self.name),
}
}