Finished assembler paser

The assembler parser is finished and all tests do pass but the "load" command keeps pointing to "sub" for some reason.
This commit is contained in:
Anthony Foxclaw 2020-02-07 23:53:59 -05:00
parent fe69c0d0c8
commit afb68e46b3
5 changed files with 33 additions and 32 deletions

View file

@ -18,7 +18,7 @@ impl AssemblerInstruction {
pub fn to_bytes(&self) -> Vec<u8> { pub fn to_bytes(&self) -> Vec<u8> {
let mut results = vec![]; let mut results = vec![];
match self.opcode.clone() { match self.opcode.to_owned() {
Token::Opcode { code } => match code { Token::Opcode { code } => match code {
_ => { _ => {
results.push(code as u8); results.push(code as u8);
@ -26,7 +26,7 @@ impl AssemblerInstruction {
}, },
_ => { _ => {
println!("Incorrect opcode!"); println!("Incorrect opcode!");
std::process::exit(0); std::process::exit(1);
} }
}; };
@ -49,6 +49,7 @@ impl AssemblerInstruction {
let conv = *value as u16; let conv = *value as u16;
let byte1 = conv; let byte1 = conv;
let byte2 = conv >> 8; let byte2 = conv >> 8;
results.push(byte2 as u8); results.push(byte2 as u8);
results.push(byte1 as u8); results.push(byte1 as u8);
}, },
@ -56,7 +57,7 @@ impl AssemblerInstruction {
println!("Opcode found in operand field"); println!("Opcode found in operand field");
std::process::exit(1); std::process::exit(1);
} }
} };
} }
} }
@ -83,7 +84,7 @@ mod instruction_parser_test {
use crate::instruction::Opcode; use crate::instruction::Opcode;
#[test] #[test]
fn test_parse_instruction() { fn test_parse_instruction_form_one() {
let result = instruction_one(CompleteStr("load $0 #100\n")); let result = instruction_one(CompleteStr("load $0 #100\n"));
assert_eq!( assert_eq!(
result, result,

View file

@ -17,6 +17,7 @@ mod opcode_parser_test {
fn test_parser_op_load() { fn test_parser_op_load() {
// Test that opcode is dected and parsed correctly // Test that opcode is dected and parsed correctly
let result = opcode_load(CompleteStr("load")); let result = opcode_load(CompleteStr("load"));
assert_eq!(result.is_ok(), true);
let (rest, token) = result.unwrap(); let (rest, token) = result.unwrap();
assert_eq!(token, Token::Opcode { code: Opcode::LOAD }); assert_eq!(token, Token::Opcode { code: Opcode::LOAD });
assert_eq!(rest, CompleteStr("")); assert_eq!(rest, CompleteStr(""));

View file

@ -44,6 +44,7 @@ mod instruction_parser_test {
#[test] #[test]
fn test_program_to_bytes() { fn test_program_to_bytes() {
let result = program(CompleteStr("load $0 #100\n")); let result = program(CompleteStr("load $0 #100\n"));
assert_eq!(result.is_ok(), true);
let (_, prog) = result.unwrap(); let (_, prog) = result.unwrap();
let bytecode = prog.to_bytes(); let bytecode = prog.to_bytes();
assert_eq!(bytecode.len(), 4); assert_eq!(bytecode.len(), 4);

View file

@ -17,3 +17,17 @@ named!(pub register <CompleteStr, Token>,
) )
) )
); );
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);
}
}

View file

@ -1,11 +1,12 @@
use std; use std;
use std::io; use std::io;
use std::io::Write; use std::io::Write;
use std::num::ParseIntError;
use crate::vm::VM; use crate::vm::VM;
use crate::assembler::program_parser::program;
use metacrate::crate_version; use metacrate::crate_version;
use rbtag::{BuildDateTime, BuildInfo}; use rbtag::{BuildDateTime, BuildInfo};
use nom::types::CompleteStr;
#[derive(BuildDateTime, BuildInfo)] #[derive(BuildDateTime, BuildInfo)]
struct BuildTag; struct BuildTag;
@ -76,37 +77,20 @@ impl REPL {
println!("{:#?}", self.vm.registers); println!("{:#?}", self.vm.registers);
} }
_ => { _ => {
let results = self.parse_hex(buffer); let prog = program(CompleteStr(buffer));
match results { if !prog.is_ok() {
Ok(bytes) => { println!("Unable to parse input");
for byte in bytes { continue;
self.vm.add_byte(byte);
}
}
Err(_er) => {
println!("Unable to decode hex string. Please enter 4 groups of 2 hex characters.");
}
} }
let (_, result) = prog.unwrap();
let bytecode = result.to_bytes();
for byte in bytecode {
self.vm.add_byte(byte);
}
self.vm.run_once(); 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<Vec<u8>, ParseIntError> {
let split = i.split(" ").collect::<Vec<&str>>();
let mut results: Vec<u8> = 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)
}
} }