From afb68e46b34dd6bb6a342448b0d4ee8287013d21 Mon Sep 17 00:00:00 2001 From: Anthony Foxclaw <35226681+tonytins@users.noreply.github.com> Date: Fri, 7 Feb 2020 23:53:59 -0500 Subject: [PATCH] Finished assembler paser The assembler parser is finished and all tests do pass but the "load" command keeps pointing to "sub" for some reason. --- src/assembler/instruction_parser.rs | 9 ++++--- src/assembler/opcode_parser.rs | 1 + src/assembler/program_parser.rs | 1 + src/assembler/register_parser.rs | 14 ++++++++++ src/repl.rs | 40 +++++++++-------------------- 5 files changed, 33 insertions(+), 32 deletions(-) diff --git a/src/assembler/instruction_parser.rs b/src/assembler/instruction_parser.rs index 100c366..7f77d5f 100644 --- a/src/assembler/instruction_parser.rs +++ b/src/assembler/instruction_parser.rs @@ -18,7 +18,7 @@ impl AssemblerInstruction { pub fn to_bytes(&self) -> Vec { let mut results = vec![]; - match self.opcode.clone() { + match self.opcode.to_owned() { Token::Opcode { code } => match code { _ => { results.push(code as u8); @@ -26,7 +26,7 @@ impl AssemblerInstruction { }, _ => { println!("Incorrect opcode!"); - std::process::exit(0); + std::process::exit(1); } }; @@ -49,6 +49,7 @@ impl AssemblerInstruction { let conv = *value as u16; let byte1 = conv; let byte2 = conv >> 8; + results.push(byte2 as u8); results.push(byte1 as u8); }, @@ -56,7 +57,7 @@ impl AssemblerInstruction { println!("Opcode found in operand field"); std::process::exit(1); } - } + }; } } @@ -83,7 +84,7 @@ mod instruction_parser_test { use crate::instruction::Opcode; #[test] - fn test_parse_instruction() { + fn test_parse_instruction_form_one() { let result = instruction_one(CompleteStr("load $0 #100\n")); assert_eq!( result, diff --git a/src/assembler/opcode_parser.rs b/src/assembler/opcode_parser.rs index 900515b..65f2386 100644 --- a/src/assembler/opcode_parser.rs +++ b/src/assembler/opcode_parser.rs @@ -17,6 +17,7 @@ mod opcode_parser_test { fn test_parser_op_load() { // Test that opcode is dected and parsed correctly let result = opcode_load(CompleteStr("load")); + assert_eq!(result.is_ok(), true); let (rest, token) = result.unwrap(); assert_eq!(token, Token::Opcode { code: Opcode::LOAD }); assert_eq!(rest, CompleteStr("")); diff --git a/src/assembler/program_parser.rs b/src/assembler/program_parser.rs index c0e8a33..a0ac7bf 100644 --- a/src/assembler/program_parser.rs +++ b/src/assembler/program_parser.rs @@ -44,6 +44,7 @@ mod instruction_parser_test { #[test] fn test_program_to_bytes() { let result = program(CompleteStr("load $0 #100\n")); + assert_eq!(result.is_ok(), true); let (_, prog) = result.unwrap(); let bytecode = prog.to_bytes(); assert_eq!(bytecode.len(), 4); diff --git a/src/assembler/register_parser.rs b/src/assembler/register_parser.rs index d4a0135..1482e1a 100644 --- a/src/assembler/register_parser.rs +++ b/src/assembler/register_parser.rs @@ -17,3 +17,17 @@ named!(pub register , ) ) ); + +mod register_parser_tests { + use super::*; + + #[test] + fn test_parse_register() { + let result = register(CompleteStr("$0")); + assert_eq!(result.is_ok(), true); + let result = register(CompleteStr("0")); + assert_eq!(result.is_ok(), false); + let result = register(CompleteStr("$a")); + assert_eq!(result.is_ok(), false); + } +} diff --git a/src/repl.rs b/src/repl.rs index 1de1668..5859e44 100644 --- a/src/repl.rs +++ b/src/repl.rs @@ -1,11 +1,12 @@ use std; use std::io; use std::io::Write; -use std::num::ParseIntError; use crate::vm::VM; +use crate::assembler::program_parser::program; use metacrate::crate_version; use rbtag::{BuildDateTime, BuildInfo}; +use nom::types::CompleteStr; #[derive(BuildDateTime, BuildInfo)] struct BuildTag; @@ -76,37 +77,20 @@ impl REPL { println!("{:#?}", self.vm.registers); } _ => { - let results = self.parse_hex(buffer); - match results { - Ok(bytes) => { - for byte in bytes { - self.vm.add_byte(byte); - } - } - Err(_er) => { - println!("Unable to decode hex string. Please enter 4 groups of 2 hex characters."); - } + let prog = program(CompleteStr(buffer)); + if !prog.is_ok() { + println!("Unable to parse input"); + continue; } + let (_, result) = prog.unwrap(); + let bytecode = result.to_bytes(); + for byte in bytecode { + self.vm.add_byte(byte); + } + self.vm.run_once(); } } } } - - /// Accepts the hexadecimal without a leading '0x' and returns a Vec of a - /// u8. Example: 00 01 03 E8 - fn parse_hex(&mut self, i: &str) -> Result, ParseIntError> { - let split = i.split(" ").collect::>(); - let mut results: Vec = vec![]; - for hex_string in split { - let byte = u8::from_str_radix(&hex_string, 16); - match byte { - Ok(result) => { - results.push(result); - } - Err(err) => return Err(err), - } - } - Ok(results) - } }