From 90b2a5f5e7135da7683ebf777464f2f74693d6ee Mon Sep 17 00:00:00 2001 From: Hazem Krimi Date: Fri, 8 Mar 2024 20:11:44 +0100 Subject: [PATCH] Translate A instructions without symbols --- src/code.rs | 9 +++++++++ src/main.rs | 38 +++++++++++++++++++++++++------------- src/parser.rs | 42 +++++++++++++++++++++++++++++++++--------- src/types.rs | 22 +++++++++++++--------- 4 files changed, 80 insertions(+), 31 deletions(-) create mode 100644 src/code.rs diff --git a/src/code.rs b/src/code.rs new file mode 100644 index 0000000..f58426b --- /dev/null +++ b/src/code.rs @@ -0,0 +1,9 @@ +pub fn decimal_to_binary(decimal: &i32) -> String { + String::from(format!("{decimal:015b}")) +} + +// fn translate_dest(dest: &String) -> String { +// let cloned = dest.clone(); + +// cloned +// } \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index 432c3b5..8319369 100644 --- a/src/main.rs +++ b/src/main.rs @@ -8,22 +8,34 @@ use std::process; use regex::Regex; use types::Instruction; -mod parser; mod types; +mod parser; +mod code; fn process(instruction: String) -> String { - // let parsed = parser::parse(instruction); + match parser::parse(&instruction) { + Some(parsed) => match parsed { + Instruction::AInstruction(parsed_instruction) => { + let translated = code::decimal_to_binary(&parsed_instruction.decimal.parse::().unwrap()); - // match parsed { - // Instruction::AInstruction { .. } => { - // let a_instruction: Instruction::AInstruction = parsed; + String::from(format!("0{}", translated)) + } + Instruction::CInstruction(parsed_instruction) => { + println!( + "C: {}, {}, {}", + parsed_instruction.dest, + parsed_instruction.comp, + parsed_instruction.jump.unwrap_or_else(|| "".to_string()) + ); - // println!("{}", a_instruction.decimal) - // }, - // _ => () - // } - - instruction + instruction + } + }, + None => { + println!("Unexpected error!"); + process::exit(1) + } + } } fn main() { @@ -43,7 +55,7 @@ fn main() { let mut file = fs::File::create(format!("{}.hack", filename)).unwrap(); let content = fs::read_to_string(&path).expect("You must provide a correct filepath!"); let re = Regex::new(r"\s*\/\/.*").unwrap(); - let without_whitespace: String = content + let processed: String = content .lines() .filter(|line| !line.starts_with("//") && !line.is_empty()) .map(|line| re.replace_all(line, "")) @@ -51,7 +63,7 @@ fn main() { .map(|line| format!("{}\n", line)) .collect(); - file.write_all(without_whitespace.as_bytes()).unwrap(); + file.write_all(processed.as_bytes()).unwrap(); } _ => { println!("The file extension must be asm!"); diff --git a/src/parser.rs b/src/parser.rs index ff856e7..4cec0e3 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -1,14 +1,38 @@ -use crate::types::Instruction; +use crate::types::{AInstruction, CInstruction, Instruction}; -pub fn parse(mut instruction: String) -> Instruction { - if instruction.chars().nth(0).unwrap() == '@' { - instruction.remove(0); - return Instruction::AInstruction { decimal: instruction }; +pub fn parse(instruction: &String) -> Option { + let mut cloned = instruction.clone(); + + if cloned.chars().nth(0).unwrap() == '@' { + cloned.remove(0); + + return Some(Instruction::AInstruction(AInstruction { + decimal: cloned.to_string(), + })); } - Instruction::CInstruction { - dest: "1".to_owned(), - comp: "2".to_owned(), - jump: "3".to_owned(), + let slice: Vec<&str> = cloned.split("=").collect(); + + match slice.as_slice() { + [dest, comp_and_jump] => match comp_and_jump.find(";") { + Some(with_jump) => { + let second_slice: Vec<&str> = comp_and_jump.split(";").collect(); + + match second_slice.as_slice() { + [comp, jump] => Some(Instruction::CInstruction(CInstruction { + dest: dest.to_string(), + comp: comp.to_string(), + jump: Some(jump.to_string()), + })), + _ => None, + } + } + None => Some(Instruction::CInstruction(CInstruction { + dest: dest.to_string(), + comp: comp_and_jump.to_string(), + jump: None, + })), + }, + _ => None, } } diff --git a/src/types.rs b/src/types.rs index 8320589..35a4264 100644 --- a/src/types.rs +++ b/src/types.rs @@ -1,10 +1,14 @@ +pub struct AInstruction { + pub decimal: String, +} + +pub struct CInstruction { + pub dest: String, + pub comp: String, + pub jump: Option, +} + pub enum Instruction { - AInstruction { - decimal: String - }, - CInstruction { - dest: String, - comp: String, - jump: String - } -} \ No newline at end of file + AInstruction(AInstruction), + CInstruction(CInstruction), +}