From 615575655a8ed250c1c8b4e9df82dc54ffd7bc8b Mon Sep 17 00:00:00 2001 From: Hazem Krimi Date: Wed, 13 Mar 2024 00:19:15 +0100 Subject: [PATCH] Parsing wip --- src/code.rs | 2 +- src/main.rs | 32 ++++++++++++------------ src/parser.rs | 67 ++++++++++++++++++++++++++++++++------------------- src/types.rs | 4 +-- 4 files changed, 61 insertions(+), 44 deletions(-) diff --git a/src/code.rs b/src/code.rs index 6d32301..af96c7e 100644 --- a/src/code.rs +++ b/src/code.rs @@ -66,7 +66,7 @@ pub fn translate_comp(comp: &String) -> String { "M-D" => "1000111", "D&M" => "1000000", "D|M" => "1010101", - _ => panic!("Unexpected error converting the code!"), + _ => "0000000", } .to_string() } diff --git a/src/main.rs b/src/main.rs index 1a077e0..c6ce411 100644 --- a/src/main.rs +++ b/src/main.rs @@ -14,25 +14,25 @@ mod types; fn process(instruction: String) -> String { match parser::parse(&instruction) { - Some(parsed) => match parsed { - Instruction::AInstruction(parsed_instruction) => { - let translated = code::decimal_to_fifteen_bits_binary( - &parsed_instruction.decimal.parse::().unwrap(), - ); + Instruction::AInstruction(parsed_instruction) => { + match parsed_instruction.decimal.parse::() { + Ok(decimal) => { + let translated = code::decimal_to_fifteen_bits_binary(&decimal); - String::from(format!("0{}", translated)) + String::from(format!("0{}", translated)) + } + Err(_) => panic!("Failed to parse A instruction {}", instruction), } - Instruction::CInstruction(parsed_instruction) => { - String::from("111") - + code::translate_comp(&parsed_instruction.comp).as_str() - + code::translate_dest(&parsed_instruction.dest).as_str() - + code::translate_jump( - &parsed_instruction.jump.unwrap_or_else(|| "".to_string()), - ) + } + Instruction::CInstruction(parsed_instruction) => { + String::from("111") + + code::translate_comp(&parsed_instruction.comp.unwrap_or_else(|| "".to_string())) .as_str() - } - }, - None => panic!("Unexpected error!"), + + code::translate_dest(&parsed_instruction.dest.unwrap_or_else(|| "".to_string())) + .as_str() + + code::translate_jump(&parsed_instruction.jump.unwrap_or_else(|| "".to_string())) + .as_str() + } } } diff --git a/src/parser.rs b/src/parser.rs index 9b62201..d351c7f 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -1,38 +1,55 @@ use crate::types::{AInstruction, CInstruction, Instruction}; +use regex::Regex; -pub fn parse(instruction: &String) -> Option { +pub fn parse(instruction: &String) -> Instruction { let mut cloned = instruction.clone(); if cloned.chars().nth(0).unwrap() == '@' { cloned.remove(0); - return Some(Instruction::AInstruction(AInstruction { - decimal: cloned.to_string(), - })); - } + return Instruction::AInstruction(AInstruction { + decimal: cloned.trim().to_string(), + }); + } else { + let re_dest_and_comp = Regex::new(r"=").unwrap(); + let re_comp_and_jump = Regex::new(r";").unwrap(); - let slice: Vec<&str> = cloned.split("=").collect(); + let dest_and_comp_exist = re_dest_and_comp.is_match(&cloned); + let comp_and_jump_exist = re_comp_and_jump.is_match(&cloned); - match slice.as_slice() { - [dest, comp_and_jump] => match comp_and_jump.find(";") { - Some(_) => { - let second_slice: Vec<&str> = comp_and_jump.split(";").collect(); + let dest = match dest_and_comp_exist { + true => { + let slice: Vec<&str> = cloned.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, - } + Some(slice.as_slice()[0].to_string()) } - None => Some(Instruction::CInstruction(CInstruction { - dest: dest.to_string(), - comp: comp_and_jump.to_string(), - jump: None, - })), - }, - _ => None, + false => None, + }; + + let comp = match comp_and_jump_exist { + true => { + let slice: Vec<&str> = cloned.split("=").collect(); + + // if jump_exist { + // let another_slice: Vec<&str> = slice.as_slice()[1].split(";").collect(); + + // Some(another_slice.as_slice()[0].to_string()); + // } + + Some(slice.as_slice()[1].to_string()) + } + false => None, + }; + + let jump = match comp_and_jump_exist { + true => { + let slice: Vec<&str> = cloned.split(";").collect(); + + Some(slice.as_slice()[1].to_string()) + } + false => None, + }; + + Instruction::CInstruction(CInstruction { dest, comp, jump }) } } diff --git a/src/types.rs b/src/types.rs index 3a57559..84b859b 100644 --- a/src/types.rs +++ b/src/types.rs @@ -3,8 +3,8 @@ pub struct AInstruction { } pub struct CInstruction { - pub dest: String, - pub comp: String, + pub dest: Option, + pub comp: Option, pub jump: Option, }