diff options
2 files changed, 14 insertions, 8 deletions
| -rw-r--r-- | assembler/src/parser/code_gen.rs | 3 | ||||
| -rw-r--r-- | assembler/src/parser/instruction.rs | 19 |
diff --git a/assembler/src/parser/code_gen.rs b/assembler/src/parser/code_gen.rs index 1c5b95a..ec4a2d2 100644 --- a/assembler/src/parser/code_gen.rs +++ b/assembler/src/parser/code_gen.rs @@ -50,9 +50,10 @@ impl Program { self.instructions.clear(); } - pub(crate) fn to_bytes(self, absolute_start: usize) -> Vec<u8> { + pub(crate) fn to_bytes(self, absolute_start: usize, pc: usize) -> Vec<u8> { let mut res = Vec::new(); res.resize(absolute_start, Default::default()); + res[pc] = self.constants[0]; res.extend(self.constants); res .into_iter() diff --git a/assembler/src/parser/instruction.rs b/assembler/src/parser/instruction.rs index cc0523f..ed3051d 100644 --- a/assembler/src/parser/instruction.rs +++ b/assembler/src/parser/instruction.rs @@ -1,5 +1,9 @@ use super::{ Instruction, Address }; +static Z: Address = Address::Memory(0); +static E: Address = Address::Memory(1); +static N: Address = Address::Memory(2); + #[derive(Debug)] pub(crate) enum ArgumentError { UnknownInstruction, @@ -25,7 +29,7 @@ impl Instruction { if self.args.len() < expected { return Err(ArgumentError::TooFew); } - else if self.args.len() > 3 { + else if self.args.len() > expected { return Err(ArgumentError::TooMany); } Ok(()) @@ -49,15 +53,14 @@ impl Instruction { return Err(ArgumentError::NotLocation); } }, + "dec" => { + self.check_args_len(1)?; + }, "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)?; @@ -73,13 +76,15 @@ impl Instruction { pub(crate) fn collapse(&mut self, next: usize) -> Vec<Instruction> { self.name = self.name.to_lowercase(); - static Z: Address = Address::Memory(0); match &*self.name { "subleq" => vec![self.clone()], "jmp" => vec![ Instruction::new_subleq(&Z, &Z, &self.args[0]), ], + "dec" => vec![ + Instruction::new_subleq(&E, &self.args[0], &Address::Instruction(next + 1)), + ], "add" => vec![ Instruction::new_subleq(&self.args[0], &Z, &Address::Instruction(next + 1)), Instruction::new_subleq(&Z, &self.args[1], &Address::Instruction(next + 2)), @@ -103,7 +108,7 @@ impl Instruction { pub(crate) fn collapse_len(&self) -> usize { match &*self.name { - "subleq" | "jmp" + "subleq" | "jmp" | "dec" => 1, "add" => 3, |
