Wrote AssemblerInstruction and Program parser

This commit is contained in:
Anthony Foxclaw 2020-02-07 21:49:56 -05:00
parent 1af8f089c3
commit 4bfde58cc5
5 changed files with 98 additions and 7 deletions

View file

@ -1,13 +1,15 @@
#![allow(dead_code)]
pub mod instruction_parser;
pub mod opcode_parser;
pub mod operand_parser;
pub mod program_parser;
pub mod register_parser;
use crate::instruction::Opcode;
#[derive(Debug, PartialEq)]
pub enum Token {
Op { code: Opcode },
Opcode { code: Opcode },
Register { reg_num: u8 },
IntegerOperand { value: i32 },
Number { value: i32 },
}

View file

@ -0,0 +1,55 @@
use nom::*;
use crate::assembler::Token;
use crate::assembler::opcode_parser::opcode_load;
use crate::assembler::operand_parser::integer_operand;
use crate::assembler::register_parser::register;
use nom::types::CompleteStr;
use nom::*;
#[derive(Debug, PartialEq)]
pub struct AssemblerInstruction {
opcode: Token,
op1: Option<Token>,
op2: Option<Token>,
op3: Option<Token>,
}
named!(pub instruction_one<CompleteStr, AssemblerInstruction>,
do_parse!(
o: opcode_load >>
r: register >>
i: integer_operand >>
(
AssemblerInstruction{
opcode: o,
op1: Some(r),
op2: Some(i),
op3: None
}
)
)
);
#[cfg(test)]
mod instruction_parser_test {
use super::*;
use crate::instruction::Opcode;
#[test]
fn test_parse_instruction() {
let result = instruction_one(CompleteStr("load $0 #100\n"));
assert_eq!(
result,
Ok((
CompleteStr(""),
AssemblerInstruction {
opcode: Token::Opcode { code: Opcode::LOAD },
op1: Some(Token::Register { reg_num: 0 }),
op2: Some(Token::Number { value: 100 }),
op3: None
}
))
);
}
}

View file

@ -5,8 +5,8 @@ use nom::{digit, types::CompleteStr};
use crate::assembler::Token;
use crate::instruction::Opcode;
named!(opcode_load<CompleteStr, Token>,
do_parse!(tag!("load") >> (Token::Op{code: Opcode::LOAD}))
named!(pub opcode_load<CompleteStr, Token>,
do_parse!(tag!("load") >> (Token::Opcode{code: Opcode::LOAD}))
);
#[cfg(test)]
@ -18,7 +18,7 @@ mod opcode_parser_test {
// Test that opcode is dected and parsed correctly
let result = opcode_load(CompleteStr("load"));
let (rest, token) = result.unwrap();
assert_eq!(token, Token::Op { code: Opcode::LOAD });
assert_eq!(token, Token::Opcode { code: Opcode::LOAD });
assert_eq!(rest, CompleteStr(""));
}
}

View file

@ -10,7 +10,7 @@ named!(pub integer_operand<CompleteStr, Token>,
tag!("#") >>
reg_num: digit >>
(
Token::IntegerOperand{value: reg_num.parse::<i32>().unwrap()}
Token::Number{value: reg_num.parse::<i32>().unwrap()}
)
)
)
@ -25,6 +25,6 @@ mod reg_parser_test {
let result = integer_operand(CompleteStr("#10"));
let (rest, value) = result.unwrap();
assert_eq!(rest, CompleteStr(""));
assert_eq!(value, Token::IntegerOperand { value: 10 });
assert_eq!(value, Token::Number { value: 10 });
}
}

View file

@ -0,0 +1,34 @@
use nom::types::CompleteStr;
use nom::*;
use crate::assembler::instruction_parser::{instruction_one, AssemblerInstruction};
#[derive(Debug, PartialEq)]
pub struct Program {
instructions: Vec<AssemblerInstruction>,
}
named!(pub program<CompleteStr, Program>,
do_parse!(
instructions: many1!(instruction_one) >>
(
Program {
instructions
}
)
)
);
#[cfg(test)]
mod instruction_parser_test {
use super::*;
use crate::instruction::Opcode;
#[test]
fn test_parse_instruction() {
let result = program(CompleteStr("load $0 #100\n"));
let (leftover, p) = result.unwrap();
assert_eq!(leftover, CompleteStr(""));
assert_eq!(1, p.instructions.len());
}
}