diff options
| Commit | 9c656c296827172589243d588f57f9ab2745efc6 (patch) | |
|---|---|---|
| Author | 2025-02-14 08:50:49 +0200 | |
| Committer | 2025-02-14 08:50:49 +0200 | |
| Files | ac637c6034d5e8e2dcb50f609b4b063ca7422add /assembler/src/parser | |
| tonkobali-9c656c296827172589243d588f57f9ab2745efc6.tar tonkobali-9c656c296827172589243d588f57f9ab2745efc6.tar.gz tonkobali-9c656c296827172589243d588f57f9ab2745efc6.zip | ||
| Parent | 9517d3d05e86621b6c4ed58edd7f5821632e0872 (diff) | |
feat(assembler): Implement beq and mov instructions
2 files changed, 54 insertions, 0 deletions
| -rw-r--r-- | assembler/src/parser/code_gen.rs | 16 | ||||
| -rw-r--r-- | assembler/src/parser/instruction.rs | 38 |
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), } } |
