From 596254394f5d9beff4ad2ecade81e8d9da1a17f3 Mon Sep 17 00:00:00 2001 From: c0repwn3r Date: Mon, 8 May 2023 18:01:50 -0400 Subject: [PATCH] cc! assembler and examples --- src/asm.rs | 4 +- src/disasm.rs | 6 +- src/main.rs | 12 +-- src/normalizer.rs | 58 ++++++++++--- src/ops.rs | 177 +++++++++++++++++++++++--------------- src/opt_sim_asm.rs | 204 ++++++++++++++++++++++++++++---------------- src/preprocessor.rs | 6 +- 7 files changed, 298 insertions(+), 169 deletions(-) diff --git a/src/asm.rs b/src/asm.rs index c6f6d9a..e5c7306 100644 --- a/src/asm.rs +++ b/src/asm.rs @@ -1,7 +1,7 @@ +use crate::opt_sim_asm::SimpleAssemblySimulator; use std::error::Error; use std::fs; use std::path::PathBuf; -use crate::opt_sim_asm::SimpleAssemblySimulator; pub fn assemble(processed: String, out: PathBuf) -> Result<(), Box> { let mut simple_sim = SimpleAssemblySimulator { @@ -33,4 +33,4 @@ pub fn assemble(processed: String, out: PathBuf) -> Result<(), Box> { fs::write(out, asm)?; Ok(()) -} \ No newline at end of file +} diff --git a/src/disasm.rs b/src/disasm.rs index 43c1f80..4c0ec45 100644 --- a/src/disasm.rs +++ b/src/disasm.rs @@ -1,6 +1,8 @@ use std::error::Error; use std::path::PathBuf; -pub fn disassemble(file: PathBuf, out: PathBuf) -> Result<(), Box> { +// TODO + +pub fn disassemble(_file: PathBuf, _out: PathBuf) -> Result<(), Box> { Ok(()) -} \ No newline at end of file +} diff --git a/src/main.rs b/src/main.rs index dc090c4..9bd86d3 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,16 +1,16 @@ -use std::path::PathBuf; -use clap::{Parser, ArgAction}; use crate::asm::assemble; use crate::disasm::disassemble; use crate::normalizer::normalize; use crate::preprocessor::preprocess; +use clap::{ArgAction, Parser}; +use std::path::PathBuf; -pub mod ops; +pub mod asm; pub mod disasm; pub mod normalizer; -pub mod asm; -pub mod preprocessor; +pub mod ops; pub mod opt_sim_asm; +pub mod preprocessor; #[derive(Parser)] pub struct Cli { @@ -25,7 +25,7 @@ pub struct Cli { #[clap(short, long, action = ArgAction::SetTrue)] pub preprocess_only: bool, #[clap(short, long, action = ArgAction::SetTrue)] - pub disassemble: bool + pub disassemble: bool, } fn main() { diff --git a/src/normalizer.rs b/src/normalizer.rs index f5a5fa3..791d15d 100644 --- a/src/normalizer.rs +++ b/src/normalizer.rs @@ -14,30 +14,47 @@ pub fn normalize(file: PathBuf) -> Result> { match line_split[0] { "lsh" => { if line_split.len() != 3 { - return Err(format!("line {}: expected exactly 2 arguments to 'lsh', instead got {}", line_num, line_split.len() - 1).into()); + return Err(format!( + "line {}: expected exactly 2 arguments to 'lsh', instead got {}", + line_num, + line_split.len() - 1 + ) + .into()); } let dest = line_split[1]; if !dest.ends_with(',') { return Err(format!("line {}: arg 1 to 'lsh' must end in ','", line_num).into()); } - let dest = &dest[..dest.len()-1]; + let dest = &dest[..dest.len() - 1]; let rg = line_split[2]; - normalized += &format!("add {}, {} {} ; normalizer: originally '{}'\n", dest, rg, rg, line); - - }, + normalized += &format!( + "add {}, {} {} ; normalizer: originally '{}'\n", + dest, rg, rg, line + ); + } "cmp" => { if line_split.len() != 3 { - return Err(format!("line {}: expected exactly 2 arguments to 'cmp', instead got {}", line_num, line_split.len() - 1).into()); + return Err(format!( + "line {}: expected exactly 2 arguments to 'cmp', instead got {}", + line_num, + line_split.len() - 1 + ) + .into()); } let a = line_split[1]; let b = line_split[2]; normalized += &format!("sub r0, {} {} ; normalizer: originally '{}'\n", a, b, line); - }, + } "cpy" => { if line_split.len() != 3 { - return Err(format!("line {}: expected exactly 2 arguments to 'cpy', instead got {}", line_num, line_split.len() - 1).into()); + return Err(format!( + "line {}: expected exactly 2 arguments to 'cpy', instead got {}", + line_num, + line_split.len() - 1 + ) + .into()); } let dest = line_split[1]; let a = line_split[2]; @@ -47,11 +64,21 @@ pub fn normalize(file: PathBuf) -> Result> { } normalized += "ldi r0, 0 ; normalizer: originally below\n"; - normalized += &format!("add {}, {} r0 ; normalizer: originally '{}'\n", &dest[..dest.len()-1], a, line); - }, + normalized += &format!( + "add {}, {} r0 ; normalizer: originally '{}'\n", + &dest[..dest.len() - 1], + a, + line + ); + } "not" => { if line_split.len() != 3 { - return Err(format!("line {}: expected exactly 2 arguments to 'not', instead got {}", line_num, line_split.len() - 1).into()); + return Err(format!( + "line {}: expected exactly 2 arguments to 'not', instead got {}", + line_num, + line_split.len() - 1 + ) + .into()); } let dest = line_split[1]; let a = line_split[2]; @@ -61,7 +88,12 @@ pub fn normalize(file: PathBuf) -> Result> { } normalized += "ldi r0, 0 ; normalizer: originally below\n"; - normalized += &format!("nor {}, {} r0 ; normalizer: originally '{}'\n", &dest[..dest.len()-1], a, line); + normalized += &format!( + "nor {}, {} r0 ; normalizer: originally '{}'\n", + &dest[..dest.len() - 1], + a, + line + ); } _ => { normalized += line; @@ -71,4 +103,4 @@ pub fn normalize(file: PathBuf) -> Result> { } Ok(normalized) -} \ No newline at end of file +} diff --git a/src/ops.rs b/src/ops.rs index 907a57f..3a25670 100644 --- a/src/ops.rs +++ b/src/ops.rs @@ -13,7 +13,7 @@ pub enum Register { RD, RE, PC, - FLG + FLG, } impl Register { fn byte(&self) -> u8 { @@ -32,73 +32,73 @@ impl Register { pub fn add(reg_dest: Register, reg_a: Register, reg_b: Register) -> Vec { vec![ - 0b1111_1101, // opcode + 0b1111_1101, // opcode reg_dest.byte() << 5 | reg_a.byte() << 2, // operands 1 - reg_b.byte() << 5, // operands 2, - 0b0000_0000 // operands 3 + reg_b.byte() << 5, // operands 2, + 0b0000_0000, // operands 3 ] } pub fn sub(reg_dest: Register, reg_a: Register, reg_b: Register) -> Vec { vec![ - 0b1111_1100, // opcode + 0b1111_1100, // opcode reg_dest.byte() << 5 | reg_a.byte() << 2, // operands 1 - reg_b.byte() << 5, // operands 2, - 0b0000_0000 // operands 3 + reg_b.byte() << 5, // operands 2, + 0b0000_0000, // operands 3 ] } pub fn or(reg_dest: Register, reg_a: Register, reg_b: Register) -> Vec { vec![ - 0b1111_1011, // opcode + 0b1111_1011, // opcode reg_dest.byte() << 5 | reg_a.byte() << 2, // operands 1 - reg_b.byte() << 5, // operands 2, - 0b0000_0000 // operands 3 + reg_b.byte() << 5, // operands 2, + 0b0000_0000, // operands 3 ] } pub fn nor(reg_dest: Register, reg_a: Register, reg_b: Register) -> Vec { vec![ - 0b1111_1010, // opcode + 0b1111_1010, // opcode reg_dest.byte() << 5 | reg_a.byte() << 2, // operands 1 - reg_b.byte() << 5, // operands 2, - 0b0000_0000 // operands 3 + reg_b.byte() << 5, // operands 2, + 0b0000_0000, // operands 3 ] } pub fn and(reg_dest: Register, reg_a: Register, reg_b: Register) -> Vec { vec![ - 0b1111_1001, // opcode + 0b1111_1001, // opcode reg_dest.byte() << 5 | reg_a.byte() << 2, // operands 1 - reg_b.byte() << 5, // operands 2, - 0b0000_0000 // operands 3 + reg_b.byte() << 5, // operands 2, + 0b0000_0000, // operands 3 ] } pub fn xor(reg_dest: Register, reg_a: Register, reg_b: Register) -> Vec { vec![ - 0b1111_1000, // opcode + 0b1111_1000, // opcode reg_dest.byte() << 5 | reg_a.byte() << 2, // operands 1 - reg_b.byte() << 5, // operands 2, - 0b0000_0000 // operands 3 + reg_b.byte() << 5, // operands 2, + 0b0000_0000, // operands 3 ] } pub fn rsh(reg_dest: Register, reg_a: Register) -> Vec { vec![ - 0b1111_0111, // opcode + 0b1111_0111, // opcode reg_dest.byte() << 5 | reg_a.byte() << 2, // operands 1 - 0b0000_0000, // operands 2, - 0b0000_0000 // operands 3 + 0b0000_0000, // operands 2, + 0b0000_0000, // operands 3 ] } pub fn ldi(reg_dest: Register, immediate: u8) -> Vec { vec![ - 0b1111_0110, // opcode + 0b1111_0110, // opcode reg_dest.byte() << 5, // operands 1 - immediate, // operands 2, - 0b0000_0000 // operands 3 + immediate, // operands 2, + 0b0000_0000, // operands 3 ] } @@ -108,65 +108,55 @@ pub fn mmr(reg_dest: Register, address: u16) -> Vec { // &0000 1111 1111 0000, >> 4 // &0000 0000 0000 1111, << 4 vec![ - 0b1111_0101, // opcode, - reg_dest.byte() << 5, // operands 1 + 0b1111_0101, // opcode, + reg_dest.byte() << 5, // operands 1 address_higher_half(address), // operands 2 - address_lower_half(address), // operands 3 + address_lower_half(address), // operands 3 ] } pub fn mrm(reg_src: Register, address: u16) -> Vec { vec![ - 0b1111_0100, // opcode - reg_src.byte() << 5, // operands 1 + 0b1111_0100, // opcode + reg_src.byte() << 5, // operands 1 address_higher_half(address), // operands 2 - address_lower_half(address), // operands 3 + address_lower_half(address), // operands 3 ] } pub fn jmp(address: u16) -> Vec { vec![ - 0b1111_0011, // opcode + 0b1111_0011, // opcode address_higher_half(address), // operands 1 - address_lower_half(address), // operands 2, - 0b0000_0000 + address_lower_half(address), // operands 2, + 0b0000_0000, ] } pub fn jez(address: u16) -> Vec { vec![ - 0b1111_0010, // opcode + 0b1111_0010, // opcode address_higher_half(address), // operands 1 - address_lower_half(address), // operands 2, - 0b0000_0000 + address_lower_half(address), // operands 2, + 0b0000_0000, ] } pub fn rmmr(reg_dest: Register, address: u16) -> Vec { vec![ - 0b1111_0001, // opcode, - reg_dest.byte() << 5, // operands 1 + 0b1111_0001, // opcode, + reg_dest.byte() << 5, // operands 1 address_higher_half(address), // operands 2 - address_lower_half(address), // operands 3 + address_lower_half(address), // operands 3 ] } pub fn r#in(reg_dest: Register, port: u8) -> Vec { - vec![ - 0b1111_0000, - reg_dest.byte() << 5, - port, - 0b0000_0000 - ] + vec![0b1111_0000, reg_dest.byte() << 5, port, 0b0000_0000] } pub fn out(reg_src: Register, port: u8) -> Vec { - vec![ - 0b1110_1111, - reg_src.byte() << 5, - port, - 0b0000_0000 - ] + vec![0b1110_1111, reg_src.byte() << 5, port, 0b0000_0000] } // See `mmr` for how these values are calculated @@ -178,8 +168,12 @@ fn address_lower_half(address: u16) -> u8 { ((address & 0b0000_0000_0000_1111) << 4).try_into().unwrap() } +#[cfg(test)] mod tests { - use crate::ops::{add, and, hcf, jez, jmp, ldi, mmr, mrm, nop, nor, or, out, r#in, Register, rmmr, rsh, sub, xor}; + use crate::ops::{ + add, and, hcf, jez, jmp, ldi, mmr, mrm, nop, nor, or, out, r#in, rmmr, rsh, sub, xor, + Register, + }; #[test] fn test_nop() { @@ -193,76 +187,121 @@ mod tests { #[test] fn test_add() { - assert_eq!(add(Register::R0, Register::RA, Register::RB), vec![0b1111_1101, 0b0000_0100, 0b0100_0000, 0b0000_0000]) + assert_eq!( + add(Register::R0, Register::RA, Register::RB), + vec![0b1111_1101, 0b0000_0100, 0b0100_0000, 0b0000_0000] + ) } #[test] fn test_sub() { - assert_eq!(sub(Register::R0, Register::RA, Register::RB), vec![0b1111_1100, 0b0000_0100, 0b0100_0000, 0b0000_0000]) + assert_eq!( + sub(Register::R0, Register::RA, Register::RB), + vec![0b1111_1100, 0b0000_0100, 0b0100_0000, 0b0000_0000] + ) } #[test] fn test_or() { - assert_eq!(or(Register::R0, Register::RA, Register::RB), vec![0b1111_1011, 0b0000_0100, 0b0100_0000, 0b0000_0000]) + assert_eq!( + or(Register::R0, Register::RA, Register::RB), + vec![0b1111_1011, 0b0000_0100, 0b0100_0000, 0b0000_0000] + ) } #[test] fn test_nor() { - assert_eq!(nor(Register::R0, Register::RA, Register::RB), vec![0b1111_1010, 0b0000_0100, 0b0100_0000, 0b0000_0000]) + assert_eq!( + nor(Register::R0, Register::RA, Register::RB), + vec![0b1111_1010, 0b0000_0100, 0b0100_0000, 0b0000_0000] + ) } #[test] fn test_and() { - assert_eq!(and(Register::R0, Register::RA, Register::RB), vec![0b1111_1001, 0b0000_0100, 0b0100_0000, 0b0000_0000]) + assert_eq!( + and(Register::R0, Register::RA, Register::RB), + vec![0b1111_1001, 0b0000_0100, 0b0100_0000, 0b0000_0000] + ) } #[test] fn test_xor() { - assert_eq!(xor(Register::R0, Register::RA, Register::RB), vec![0b1111_1000, 0b0000_0100, 0b0100_0000, 0b0000_0000]) + assert_eq!( + xor(Register::R0, Register::RA, Register::RB), + vec![0b1111_1000, 0b0000_0100, 0b0100_0000, 0b0000_0000] + ) } #[test] fn test_rsh() { - assert_eq!(rsh(Register::R0, Register::RA), vec![0b1111_0111, 0b0000_0100, 0b0000_0000, 0b0000_0000]) + assert_eq!( + rsh(Register::R0, Register::RA), + vec![0b1111_0111, 0b0000_0100, 0b0000_0000, 0b0000_0000] + ) } #[test] fn test_ldi() { - assert_eq!(ldi(Register::R0, 0b0101_1010), vec![0b1111_0110, 0b0000_0000, 0b0101_1010, 0b0000_0000]) + assert_eq!( + ldi(Register::R0, 0b0101_1010), + vec![0b1111_0110, 0b0000_0000, 0b0101_1010, 0b0000_0000] + ) } #[test] fn test_mmr() { - assert_eq!(mmr(Register::R0, 0b0000_0101_1010_0110), vec![0b1111_0101, 0b0000_0000, 0b0101_1010, 0b0110_0000]) + assert_eq!( + mmr(Register::R0, 0b0000_0101_1010_0110), + vec![0b1111_0101, 0b0000_0000, 0b0101_1010, 0b0110_0000] + ) } #[test] fn test_mrm() { - assert_eq!(mrm(Register::R0, 0b0000_0101_1010_0110), vec![0b1111_0100, 0b0000_0000, 0b0101_1010, 0b0110_0000]) + assert_eq!( + mrm(Register::R0, 0b0000_0101_1010_0110), + vec![0b1111_0100, 0b0000_0000, 0b0101_1010, 0b0110_0000] + ) } #[test] fn test_jmp() { - assert_eq!(jmp(0b0000_0101_1010_0110), vec![0b1111_0011, 0b0101_1010, 0b0110_0000, 0b0000_0000]) + assert_eq!( + jmp(0b0000_0101_1010_0110), + vec![0b1111_0011, 0b0101_1010, 0b0110_0000, 0b0000_0000] + ) } #[test] fn test_jez() { - assert_eq!(jez(0b0000_0101_1010_0110), vec![0b1111_0010, 0b0101_1010, 0b0110_0000, 0b0000_0000]) + assert_eq!( + jez(0b0000_0101_1010_0110), + vec![0b1111_0010, 0b0101_1010, 0b0110_0000, 0b0000_0000] + ) } #[test] fn test_rmmr() { - assert_eq!(rmmr(Register::R0, 0b0000_0101_1010_0110), vec![0b1111_0001, 0b0000_0000, 0b0101_1010, 0b0110_0000]) + assert_eq!( + rmmr(Register::R0, 0b0000_0101_1010_0110), + vec![0b1111_0001, 0b0000_0000, 0b0101_1010, 0b0110_0000] + ) } #[test] fn test_in() { - assert_eq!(r#in(Register::R0, 0b0101_1010), vec![0b1111_0000, 0b0000_0000, 0b0101_1010, 0b0000_0000]) + assert_eq!( + r#in(Register::R0, 0b0101_1010), + vec![0b1111_0000, 0b0000_0000, 0b0101_1010, 0b0000_0000] + ) } #[test] fn test_out() { - assert_eq!(out(Register::R0, 0b0101_1010), vec![0b1110_1111, 0b0000_0000, 0b0101_1010, 0b0000_0000]) + assert_eq!( + out(Register::R0, 0b0101_1010), + vec![0b1110_1111, 0b0000_0000, 0b0101_1010, 0b0000_0000] + ) } -} \ No newline at end of file +} diff --git a/src/opt_sim_asm.rs b/src/opt_sim_asm.rs index 46df26c..7355907 100644 --- a/src/opt_sim_asm.rs +++ b/src/opt_sim_asm.rs @@ -1,5 +1,7 @@ +use crate::ops::{ + add, and, hcf, ldi, mmr, mrm, nop, nor, or, out, r#in, rmmr, rsh, sub, xor, Register, +}; use std::error::Error; -use crate::ops::{add, and, hcf, ldi, mmr, mrm, nop, nor, or, out, r#in, Register, rmmr, rsh, sub, xor}; #[derive(Clone, Eq, PartialEq, Debug)] pub struct SimpleAssemblySimulator { @@ -13,7 +15,7 @@ pub struct SimpleAssemblySimulator { pub rd: u8, pub re: u8, pub pc: u16, - pub flg: u8 + pub flg: u8, } impl SimpleAssemblySimulator { pub fn line(&mut self, line: &str) -> Result, Box> { @@ -23,10 +25,14 @@ impl SimpleAssemblySimulator { "nop" => Ok(nop()), "hcf" => Ok(hcf()), // ignored for the simulator "add" => { - if line_split.len() != 4 { return Err("add requires exactly 3 arguments".into()) } + if line_split.len() != 4 { + return Err("add requires exactly 3 arguments".into()); + } let dest = line_split[1]; - if !dest.ends_with(',') { return Err("1st argument of add must end in , ".into()) } + if !dest.ends_with(',') { + return Err("1st argument of add must end in , ".into()); + } let dest = to_reg(&dest[..dest.len() - 1])?; let a = to_reg(line_split[2])?; @@ -38,7 +44,7 @@ impl SimpleAssemblySimulator { Register::RD => self.rd, Register::RE => self.re, Register::PC => return Err("Cannot use program counter as a register".into()), - Register::FLG => self.flg + Register::FLG => self.flg, }; let b = to_reg(line_split[3])?; @@ -51,7 +57,7 @@ impl SimpleAssemblySimulator { Register::RD => self.rd, Register::RE => self.re, Register::PC => return Err("Cannot use program counter as a register".into()), - Register::FLG => self.flg + Register::FLG => self.flg, }; let mut val = (a_val as u16) + (b_val as u16); @@ -67,16 +73,20 @@ impl SimpleAssemblySimulator { Register::RD => self.rd = val as u8, Register::RE => self.re = val as u8, Register::PC => self.pc = (val as u8) as u16, - Register::FLG => self.flg = val as u8 + Register::FLG => self.flg = val as u8, } Ok(add(dest, a, b)) - }, + } "sub" => { - if line_split.len() != 4 { return Err("sub requires exactly 3 arguments".into()) } + if line_split.len() != 4 { + return Err("sub requires exactly 3 arguments".into()); + } let dest = line_split[1]; - if !dest.ends_with(',') { return Err("1st argument of sub must end in , ".into()) } + if !dest.ends_with(',') { + return Err("1st argument of sub must end in , ".into()); + } let dest = to_reg(&dest[..dest.len() - 1])?; let a = to_reg(line_split[2])?; @@ -88,7 +98,7 @@ impl SimpleAssemblySimulator { Register::RD => self.rd, Register::RE => self.re, Register::PC => return Err("Cannot use program counter as a register".into()), - Register::FLG => self.flg + Register::FLG => self.flg, }; let b = to_reg(line_split[3])?; @@ -101,15 +111,15 @@ impl SimpleAssemblySimulator { Register::RD => self.rd, Register::RE => self.re, Register::PC => return Err("Cannot use program counter as a register".into()), - Register::FLG => self.flg + Register::FLG => self.flg, }; - - let val; - if b_val > a_val { - val = 0; + + + let val = if b_val > a_val { + 0 } else { - val = a_val - b_val; - } + a_val - b_val + }; match dest { Register::R0 => self.r0 = val, @@ -119,16 +129,20 @@ impl SimpleAssemblySimulator { Register::RD => self.rd = val, Register::RE => self.re = val, Register::PC => self.pc = (val) as u16, - Register::FLG => self.flg = val + Register::FLG => self.flg = val, } Ok(sub(dest, a, b)) - }, + } "or" => { - if line_split.len() != 4 { return Err("or requires exactly 3 arguments".into()) } + if line_split.len() != 4 { + return Err("or requires exactly 3 arguments".into()); + } let dest = line_split[1]; - if !dest.ends_with(',') { return Err("1st argument of or must end in , ".into()) } + if !dest.ends_with(',') { + return Err("1st argument of or must end in , ".into()); + } let dest = to_reg(&dest[..dest.len() - 1])?; let a = to_reg(line_split[2])?; @@ -140,7 +154,7 @@ impl SimpleAssemblySimulator { Register::RD => self.rd, Register::RE => self.re, Register::PC => return Err("Cannot use program counter as a register".into()), - Register::FLG => self.flg + Register::FLG => self.flg, }; let b = to_reg(line_split[3])?; @@ -153,7 +167,7 @@ impl SimpleAssemblySimulator { Register::RD => self.rd, Register::RE => self.re, Register::PC => return Err("Cannot use program counter as a register".into()), - Register::FLG => self.flg + Register::FLG => self.flg, }; match dest { @@ -164,16 +178,20 @@ impl SimpleAssemblySimulator { Register::RD => self.rd = a_val | b_val, Register::RE => self.re = a_val | b_val, Register::PC => self.pc = (a_val | b_val) as u16, - Register::FLG => self.flg = a_val | b_val + Register::FLG => self.flg = a_val | b_val, } Ok(or(dest, a, b)) - }, + } "nor" => { - if line_split.len() != 4 { return Err("nor requires exactly 3 arguments".into()) } + if line_split.len() != 4 { + return Err("nor requires exactly 3 arguments".into()); + } let dest = line_split[1]; - if !dest.ends_with(',') { return Err("1st argument of nor must end in , ".into()) } + if !dest.ends_with(',') { + return Err("1st argument of nor must end in , ".into()); + } let dest = to_reg(&dest[..dest.len() - 1])?; let a = to_reg(line_split[2])?; @@ -185,7 +203,7 @@ impl SimpleAssemblySimulator { Register::RD => self.rd, Register::RE => self.re, Register::PC => return Err("Cannot use program counter as a register".into()), - Register::FLG => self.flg + Register::FLG => self.flg, }; let b = to_reg(line_split[3])?; @@ -198,7 +216,7 @@ impl SimpleAssemblySimulator { Register::RD => self.rd, Register::RE => self.re, Register::PC => return Err("Cannot use program counter as a register".into()), - Register::FLG => self.flg + Register::FLG => self.flg, }; match dest { @@ -209,16 +227,20 @@ impl SimpleAssemblySimulator { Register::RD => self.rd = !(a_val | b_val), Register::RE => self.re = !(a_val | b_val), Register::PC => self.pc = !(a_val | b_val) as u16, - Register::FLG => self.flg = !(a_val | b_val) + Register::FLG => self.flg = !(a_val | b_val), } Ok(nor(dest, a, b)) - }, + } "and" => { - if line_split.len() != 4 { return Err("and requires exactly 3 arguments".into()) } + if line_split.len() != 4 { + return Err("and requires exactly 3 arguments".into()); + } let dest = line_split[1]; - if !dest.ends_with(',') { return Err("1st argument of and must end in , ".into()) } + if !dest.ends_with(',') { + return Err("1st argument of and must end in , ".into()); + } let dest = to_reg(&dest[..dest.len() - 1])?; let a = to_reg(line_split[2])?; @@ -230,7 +252,7 @@ impl SimpleAssemblySimulator { Register::RD => self.rd, Register::RE => self.re, Register::PC => return Err("Cannot use program counter as a register".into()), - Register::FLG => self.flg + Register::FLG => self.flg, }; let b = to_reg(line_split[3])?; @@ -243,7 +265,7 @@ impl SimpleAssemblySimulator { Register::RD => self.rd, Register::RE => self.re, Register::PC => return Err("Cannot use program counter as a register".into()), - Register::FLG => self.flg + Register::FLG => self.flg, }; match dest { @@ -254,16 +276,20 @@ impl SimpleAssemblySimulator { Register::RD => self.rd = a_val & b_val, Register::RE => self.re = a_val & b_val, Register::PC => self.pc = (a_val & b_val) as u16, - Register::FLG => self.flg = a_val & b_val + Register::FLG => self.flg = a_val & b_val, } Ok(and(dest, a, b)) - }, + } "xor" => { - if line_split.len() != 4 { return Err("xor requires exactly 3 arguments".into()) } + if line_split.len() != 4 { + return Err("xor requires exactly 3 arguments".into()); + } let dest = line_split[1]; - if !dest.ends_with(',') { return Err("1st argument of xor must end in , ".into()) } + if !dest.ends_with(',') { + return Err("1st argument of xor must end in , ".into()); + } let dest = to_reg(&dest[..dest.len() - 1])?; let a = to_reg(line_split[2])?; @@ -275,7 +301,7 @@ impl SimpleAssemblySimulator { Register::RD => self.rd, Register::RE => self.re, Register::PC => return Err("Cannot use program counter as a register".into()), - Register::FLG => self.flg + Register::FLG => self.flg, }; let b = to_reg(line_split[3])?; @@ -288,7 +314,7 @@ impl SimpleAssemblySimulator { Register::RD => self.rd, Register::RE => self.re, Register::PC => return Err("Cannot use program counter as a register".into()), - Register::FLG => self.flg + Register::FLG => self.flg, }; match dest { @@ -299,16 +325,20 @@ impl SimpleAssemblySimulator { Register::RD => self.rd = a_val ^ b_val, Register::RE => self.re = a_val ^ b_val, Register::PC => self.pc = (a_val ^ b_val) as u16, - Register::FLG => self.flg = a_val ^ b_val + Register::FLG => self.flg = a_val ^ b_val, } Ok(xor(dest, a, b)) - }, + } "rsh" => { - if line_split.len() != 3 { return Err("rsh requires exactly 2 arguments".into()) } + if line_split.len() != 3 { + return Err("rsh requires exactly 2 arguments".into()); + } let dest = line_split[1]; - if !dest.ends_with(',') { return Err("1st argument of rsh must end in , ".into()) } + if !dest.ends_with(',') { + return Err("1st argument of rsh must end in , ".into()); + } let dest = to_reg(&dest[..dest.len() - 1])?; let a = to_reg(line_split[2])?; @@ -320,7 +350,7 @@ impl SimpleAssemblySimulator { Register::RD => self.rd, Register::RE => self.re, Register::PC => return Err("Cannot use program counter as a register".into()), - Register::FLG => self.flg + Register::FLG => self.flg, }; match dest { @@ -331,16 +361,20 @@ impl SimpleAssemblySimulator { Register::RD => self.rd = a_val >> 1, Register::RE => self.re = a_val >> 1, Register::PC => self.pc = (a_val >> 1) as u16, - Register::FLG => self.flg = a_val >> 1 + Register::FLG => self.flg = a_val >> 1, } Ok(rsh(dest, a)) - }, + } "ldi" => { - if line_split.len() != 3 { return Err("rsh requires exactly 2 arguments".into()) } + if line_split.len() != 3 { + return Err("rsh requires exactly 2 arguments".into()); + } let dest = line_split[1]; - if !dest.ends_with(',') { return Err("1st argument of rsh must end in , ".into()) } + if !dest.ends_with(',') { + return Err("1st argument of rsh must end in , ".into()); + } let dest = to_reg(&dest[..dest.len() - 1])?; let data: u8 = parse_int::parse(line_split[2])?; @@ -352,16 +386,20 @@ impl SimpleAssemblySimulator { Register::RD => self.rd = data, Register::RE => self.re = data, Register::PC => self.pc = data as u16, - Register::FLG => self.flg = data + Register::FLG => self.flg = data, } Ok(ldi(dest, data)) - }, + } "mmr" => { - if line_split.len() != 3 { return Err("mmr requires exactly 2 arguments".into()) } + if line_split.len() != 3 { + return Err("mmr requires exactly 2 arguments".into()); + } let dest = line_split[1]; - if !dest.ends_with(',') { return Err("1st argument of mmr must end in , ".into()) } + if !dest.ends_with(',') { + return Err("1st argument of mmr must end in , ".into()); + } let dest = to_reg(&dest[..dest.len() - 1])?; let address: u16 = parse_int::parse(line_split[2])?; @@ -373,21 +411,25 @@ impl SimpleAssemblySimulator { Register::RD => self.rd = self.ram[address as usize], Register::RE => self.re = self.ram[address as usize], Register::PC => self.pc = self.ram[address as usize] as u16, - Register::FLG => self.flg = self.ram[address as usize] + Register::FLG => self.flg = self.ram[address as usize], } Ok(mmr(dest, address)) - }, + } "mrm" => { - if line_split.len() != 3 { return Err("mrm requires exactly 2 arguments".into()) } + if line_split.len() != 3 { + return Err("mrm requires exactly 2 arguments".into()); + } let dest = line_split[1]; - if !dest.ends_with(',') { return Err("1st argument of mrm must end in , ".into()) } + if !dest.ends_with(',') { + return Err("1st argument of mrm must end in , ".into()); + } let src = line_split[2]; let src = to_reg(src)?; - let address: u16 = parse_int::parse(&line_split[1][..line_split[1].len()-1])?; + let address: u16 = parse_int::parse(&line_split[1][..line_split[1].len() - 1])?; match src { Register::R0 => self.ram[address as usize] = self.r0, @@ -397,39 +439,51 @@ impl SimpleAssemblySimulator { Register::RD => self.ram[address as usize] = self.rd, Register::RE => self.ram[address as usize] = self.re, Register::PC => self.ram[address as usize] = self.pc.try_into().unwrap(), - Register::FLG => self.ram[address as usize] = self.flg + Register::FLG => self.ram[address as usize] = self.flg, } Ok(mrm(src, address)) - }, + } "in" => { - if line_split.len() != 3 { return Err("in requires exactly 2 arguments".into()) } + if line_split.len() != 3 { + return Err("in requires exactly 2 arguments".into()); + } let dest = line_split[1]; - if !dest.ends_with(',') { return Err("1st argument of in must end in , ".into()) } + if !dest.ends_with(',') { + return Err("1st argument of in must end in , ".into()); + } let dest = to_reg(&dest[..dest.len() - 1])?; let port: u8 = parse_int::parse(line_split[2])?; Ok(r#in(dest, port)) - }, + } "out" => { - if line_split.len() != 3 { return Err("in requires exactly 2 arguments".into()) } + if line_split.len() != 3 { + return Err("in requires exactly 2 arguments".into()); + } let dest = line_split[1]; - if !dest.ends_with(',') { return Err("1st argument of in must end in , ".into()) } + if !dest.ends_with(',') { + return Err("1st argument of in must end in , ".into()); + } let src = line_split[2]; let src = to_reg(src)?; - let port: u8 = parse_int::parse(&line_split[1][..line_split[1].len()-1])?; + let port: u8 = parse_int::parse(&line_split[1][..line_split[1].len() - 1])?; Ok(out(src, port)) - }, + } "rmmr" => { - if line_split.len() != 3 { return Err("rmmr requires exactly 2 arguments".into()) } + if line_split.len() != 3 { + return Err("rmmr requires exactly 2 arguments".into()); + } let dest = line_split[1]; - if !dest.ends_with(',') { return Err("1st argument of rmmr must end in , ".into()) } + if !dest.ends_with(',') { + return Err("1st argument of rmmr must end in , ".into()); + } let dest = to_reg(&dest[..dest.len() - 1])?; let address: u16 = parse_int::parse(line_split[2])?; @@ -441,12 +495,12 @@ impl SimpleAssemblySimulator { Register::RD => self.rd = self.ram[address as usize], Register::RE => self.re = self.ram[address as usize], Register::PC => self.pc = self.ram[address as usize] as u16, - Register::FLG => self.flg = self.ram[address as usize] + Register::FLG => self.flg = self.ram[address as usize], } Ok(rmmr(dest, address)) } - _ => Err(format!("Unknown instruction {}", line_split[0]).into()) + _ => Err(format!("Unknown instruction {}", line_split[0]).into()), } } } @@ -461,6 +515,6 @@ fn to_reg(s: &str) -> Result> { "re" => Ok(Register::RE), "pc" => Ok(Register::PC), "flg" => Ok(Register::FLG), - _ => Err(format!("Unknown register {}", s).into()) + _ => Err(format!("Unknown register {}", s).into()), } -} \ No newline at end of file +} diff --git a/src/preprocessor.rs b/src/preprocessor.rs index 56468df..3efeb80 100644 --- a/src/preprocessor.rs +++ b/src/preprocessor.rs @@ -14,10 +14,12 @@ pub fn preprocess(normalized: String) -> Result> { } if !line_comments_removed.is_empty() { - processed += line_comments_removed.trim_start_matches(' ').trim_end_matches(' '); + processed += line_comments_removed + .trim_start_matches(' ') + .trim_end_matches(' '); processed += "\n"; } } Ok(processed) -} \ No newline at end of file +}