From ac8a70f33d37eb38a9250db2e556bc5b987f3929 Mon Sep 17 00:00:00 2001 From: Hazem Krimi Date: Tue, 12 Mar 2024 00:29:41 +0100 Subject: [PATCH] C instruction wip --- MaxL.asm | 25 ++++++++++++++++++ src/code.rs | 73 +++++++++++++++++++++++++++++++++++++++++++++++---- src/main.rs | 28 +++++++++----------- src/parser.rs | 2 +- src/types.rs | 2 +- 5 files changed, 108 insertions(+), 22 deletions(-) create mode 100644 MaxL.asm diff --git a/MaxL.asm b/MaxL.asm new file mode 100644 index 0000000..70ea3e9 --- /dev/null +++ b/MaxL.asm @@ -0,0 +1,25 @@ +// This file is part of www.nand2tetris.org +// and the book "The Elements of Computing Systems" +// by Nisan and Schocken, MIT Press. +// File name: projects/06/max/MaxL.asm + +// Symbol-less version of the Max.asm program. + +@0 +D=M +@1 +D=D-M +@12 +D;JGT +@1 +D=M +@2 +M=D +@16 +0;JMP +@0 +D=M +@2 +M=D +@16 +0;JMP diff --git a/src/code.rs b/src/code.rs index f58426b..6d32301 100644 --- a/src/code.rs +++ b/src/code.rs @@ -1,9 +1,72 @@ -pub fn decimal_to_binary(decimal: &i32) -> String { +pub fn decimal_to_fifteen_bits_binary(decimal: &i32) -> String { String::from(format!("{decimal:015b}")) } -// fn translate_dest(dest: &String) -> String { -// let cloned = dest.clone(); +pub fn translate_dest(dest: &String) -> String { + let cloned = dest.clone(); -// cloned -// } \ No newline at end of file + match cloned.as_str() { + "M" => "001", + "D" => "010", + "MD" => "011", + "A" => "100", + "AM" => "101", + "AD" => "110", + "AMD" => "111", + _ => "000", + } + .to_string() +} + +pub fn translate_jump(jump: &String) -> String { + let cloned = jump.clone(); + + match cloned.as_str() { + "JGT" => "001", + "JEQ" => "010", + "JGE" => "011", + "JLT" => "100", + "JNE" => "101", + "JLE" => "110", + "JMP" => "111", + _ => "000", + } + .to_string() +} + +pub fn translate_comp(comp: &String) -> String { + let cloned = comp.clone(); + + match cloned.as_str() { + "0" => "0101010", + "1" => "0111111", + "-1" => "0111010", + "D" => "0001100", + "A" => "0110000", + "!D" => "0001101", + "!A" => "0110001", + "-D" => "0001111", + "-A" => "0110011", + "D+1" => "0011111", + "A+1" => "0110111", + "D-1" => "0001110", + "A-1" => "0110010", + "D+A" => "0000010", + "D-A" => "0010011", + "A-D" => "0000111", + "D&A" => "0000000", + "D|A" => "0010101", + "M" => "1110000", + "!M" => "1110001", + "-M" => "1110011", + "M+1" => "1110111", + "M-1" => "1110010", + "D+M" => "1000010", + "D-M" => "1010011", + "M-D" => "1000111", + "D&M" => "1000000", + "D|M" => "1010101", + _ => panic!("Unexpected error converting the code!"), + } + .to_string() +} diff --git a/src/main.rs b/src/main.rs index 8319369..1a077e0 100644 --- a/src/main.rs +++ b/src/main.rs @@ -8,33 +8,31 @@ use std::process; use regex::Regex; use types::Instruction; -mod types; -mod parser; mod code; +mod parser; +mod types; fn process(instruction: String) -> String { match parser::parse(&instruction) { Some(parsed) => match parsed { Instruction::AInstruction(parsed_instruction) => { - let translated = code::decimal_to_binary(&parsed_instruction.decimal.parse::().unwrap()); + let translated = code::decimal_to_fifteen_bits_binary( + &parsed_instruction.decimal.parse::().unwrap(), + ); 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()) - ); - - 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()), + ) + .as_str() } }, - None => { - println!("Unexpected error!"); - process::exit(1) - } + None => panic!("Unexpected error!"), } } diff --git a/src/parser.rs b/src/parser.rs index 4cec0e3..9b62201 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -15,7 +15,7 @@ pub fn parse(instruction: &String) -> Option { match slice.as_slice() { [dest, comp_and_jump] => match comp_and_jump.find(";") { - Some(with_jump) => { + Some(_) => { let second_slice: Vec<&str> = comp_and_jump.split(";").collect(); match second_slice.as_slice() { diff --git a/src/types.rs b/src/types.rs index 35a4264..3a57559 100644 --- a/src/types.rs +++ b/src/types.rs @@ -11,4 +11,4 @@ pub struct CInstruction { pub enum Instruction { AInstruction(AInstruction), CInstruction(CInstruction), -} +} \ No newline at end of file