diff --git a/vasm/src/ast.rs b/vasm/src/ast.rs index 4f3103b..c1b7d62 100644 --- a/vasm/src/ast.rs +++ b/vasm/src/ast.rs @@ -5,11 +5,16 @@ use pest::iterators::Pair; use vcore::opcodes::Opcode; -use crate::vasm_parser::*; +use crate::parse_error::ParseError; +use crate::vasm_parser::{Rule, VASMParser}; /// A non-opcode directive to the assembler #[derive(Debug, PartialEq, Copy, Clone)] -pub enum Directive { Db, Equ, Org } +pub enum Directive { + Db, + Equ, + Org, +} impl From> for Directive { fn from(value: Pair) -> Self { @@ -18,7 +23,7 @@ impl From> for Directive { ".db" => Db, ".equ" => Equ, ".org" => Org, - _ => unreachable!() + _ => unreachable!(), } } } @@ -38,14 +43,20 @@ impl<'a> TryFrom> for Instruction { match pair.as_rule() { Rule::opcode => Ok(Instruction::Opcode(Opcode::try_from(pair.as_str())?)), Rule::directive => Ok(Instruction::Directive(Directive::from(pair))), - _ => Err(ParseError::InvalidInstruction(pair.as_str())) + _ => Err(ParseError::InvalidInstruction(pair.as_str())), } } } /// One of the five arithmetical operators #[derive(Debug, PartialEq, Copy, Clone)] -pub enum Operator { Add, Sub, Mul, Div, Mod } +pub enum Operator { + Add, + Sub, + Mul, + Div, + Mod, +} impl From> for Operator { fn from(s: Pair) -> Self { @@ -56,7 +67,7 @@ impl From> for Operator { "*" => Mul, "/" => Div, "%" => Mod, - _ => unreachable!() + _ => unreachable!(), } } } @@ -91,7 +102,7 @@ impl<'a> Node<'a> { "\\0" => string.push_str("\0"), "\\\\" => string.push_str("\\"), "\\\"" => string.push_str("\""), - _ => string.push_str(string_inner) + _ => string.push_str(string_inner), } } Node::String(string) @@ -103,11 +114,13 @@ impl<'a> Node<'a> { let mut inner = pair.into_inner(); let sign = inner.next().unwrap().as_str(); let mut num = i32::from_str(inner.next().unwrap().as_str()).unwrap(); - if sign == "-" { num *= -1 } + if sign == "-" { + num *= -1 + } match outer { Rule::relative_line_offset => Node::RelativeOffset(num), Rule::absolute_line_offset => Node::AbsoluteOffset(num), - _ => unreachable!() + _ => unreachable!(), } } } @@ -133,20 +146,24 @@ impl<'a> TryFrom> for Node<'a> { } Ok(Node::Expr(Box::from(first), rest)) } - Rule::fact | Rule::number => { - Ok(Node::try_from(pair.into_inner().next().unwrap())?) - } + Rule::fact | Rule::number => Ok(Node::try_from(pair.into_inner().next().unwrap())?), Rule::dec_number | Rule::dec_zero | Rule::neg_number => { Ok(Node::Number(i32::from_str(pair.as_str()).unwrap())) } - Rule::hex_number => { Ok(Node::Number(i32::from_str_radix(pair.as_str().get(2..).unwrap(), 16).unwrap())) } - Rule::bin_number => { Ok(Node::Number(i32::from_str_radix(pair.as_str().get(2..).unwrap(), 2).unwrap())) } - Rule::oct_number => { Ok(Node::Number(i32::from_str_radix(pair.as_str().get(2..).unwrap(), 8).unwrap())) } - Rule::string => { Ok(Node::string(pair)) } + Rule::hex_number => Ok(Node::Number( + i32::from_str_radix(pair.as_str().get(2..).unwrap(), 16).unwrap(), + )), + Rule::bin_number => Ok(Node::Number( + i32::from_str_radix(pair.as_str().get(2..).unwrap(), 2).unwrap(), + )), + Rule::oct_number => Ok(Node::Number( + i32::from_str_radix(pair.as_str().get(2..).unwrap(), 8).unwrap(), + )), + Rule::string => Ok(Node::string(pair)), Rule::label => Ok(Node::Label(pair.as_str())), Rule::relative_label => Ok(Node::RelativeLabel(pair.as_str().get(1..).unwrap())), Rule::absolute_line_offset | Rule::relative_line_offset => Ok(Node::line_offset(pair)), - _ => todo!() + _ => todo!(), } } } diff --git a/vasm/src/vasm_parser.rs b/vasm/src/vasm_parser.rs index 655d133..107041f 100644 --- a/vasm/src/vasm_parser.rs +++ b/vasm/src/vasm_parser.rs @@ -6,9 +6,8 @@ use pest::Parser; use vcore::opcodes::Opcode; -pub use crate::ast::*; -use crate::ast::{Node, VASMLine}; -pub use crate::parse_error::ParseError; +use crate::ast::{Directive, Instruction, Node, Operator, VASMLine}; +use crate::parse_error::ParseError; #[derive(Parser)] #[grammar = "vasm.pest"] @@ -26,7 +25,7 @@ fn shake(node: Node) -> Node { Node::Expr(Box::from(shaken_car), shaken_cdr) } } - _ => node + _ => node, } } @@ -45,7 +44,8 @@ pub fn parse_vasm_line(line: &str) -> Result> { vasm_line = vasm_line.with_label(label.as_str()) } - if let Some(instruction_group) = pairs.next_if(|pair| pair.as_rule() == Rule::instruction_group) { + if let Some(instruction_group) = pairs.next_if(|pair| pair.as_rule() == Rule::instruction_group) + { let mut pairs = instruction_group.into_inner(); vasm_line = vasm_line.with_instruction(Instruction::try_from(pairs.next().unwrap())?); @@ -61,8 +61,8 @@ pub fn parse_vasm_line(line: &str) -> Result> { mod test { use vcore::opcodes::Opcode::*; - use super::*; use super::Directive::*; + use super::*; impl<'a> VASMLine<'a> { pub fn op(opcode: Opcode) -> VASMLine<'a> { @@ -70,15 +70,21 @@ mod test { } fn op_number(opcode: Opcode, argument: i32) -> VASMLine<'a> { - Self::blank().with_opcode(opcode).with_argument(Node::Number(argument)) + Self::blank() + .with_opcode(opcode) + .with_argument(Node::Number(argument)) } fn op_label(opcode: Opcode, argument: &'a str) -> VASMLine<'a> { - Self::blank().with_opcode(opcode).with_argument(Node::Label(argument)) + Self::blank() + .with_opcode(opcode) + .with_argument(Node::Label(argument)) } fn op_rel_label(opcode: Opcode, argument: &'a str) -> VASMLine<'a> { - Self::blank().with_opcode(opcode).with_argument(Node::RelativeLabel(argument)) + Self::blank() + .with_opcode(opcode) + .with_argument(Node::RelativeLabel(argument)) } fn op_off(opcode: Opcode, argument: Node<'a>) -> VASMLine<'a> { @@ -86,7 +92,9 @@ mod test { } pub fn dir_str(directive: Directive, string: &str) -> VASMLine<'a> { - Self::blank().with_directive(directive).with_argument(Node::String(string.to_string())) + Self::blank() + .with_directive(directive) + .with_argument(Node::String(string.to_string())) } } @@ -94,7 +102,10 @@ mod test { fn test_parse() { assert_eq!(parse_vasm_line("add"), Ok(VASMLine::op(Add))); assert_eq!(parse_vasm_line("sub"), Ok(VASMLine::op(Sub))); - assert_eq!(parse_vasm_line("blah"), Err(ParseError::InvalidInstruction("blah"))); + assert_eq!( + parse_vasm_line("blah"), + Err(ParseError::InvalidInstruction("blah")) + ); assert_eq!(parse_vasm_line("47"), Err(ParseError::LineParseFailure)); } @@ -102,65 +113,111 @@ mod test { fn test_numbers() { assert_eq!(parse_vasm_line("add 45"), Ok(VASMLine::op_number(Add, 45))); assert_eq!(parse_vasm_line("add 0"), Ok(VASMLine::op_number(Add, 0))); - assert_eq!(parse_vasm_line("add 0x10"), Ok(VASMLine::op_number(Add, 16))); - assert_eq!(parse_vasm_line("add 0b1111"), Ok(VASMLine::op_number(Add, 15))); - assert_eq!(parse_vasm_line("add 0o377"), Ok(VASMLine::op_number(Add, 255))); - assert_eq!(parse_vasm_line("add -17"), Ok(VASMLine::op_number(Add, -17))); + assert_eq!( + parse_vasm_line("add 0x10"), + Ok(VASMLine::op_number(Add, 16)) + ); + assert_eq!( + parse_vasm_line("add 0b1111"), + Ok(VASMLine::op_number(Add, 15)) + ); + assert_eq!( + parse_vasm_line("add 0o377"), + Ok(VASMLine::op_number(Add, 255)) + ); + assert_eq!( + parse_vasm_line("add -17"), + Ok(VASMLine::op_number(Add, -17)) + ); } #[test] fn test_strings() { - assert_eq!(parse_vasm_line(".db \"blah\""), Ok(VASMLine::dir_str(Db, "blah"))); - assert_eq!(parse_vasm_line(".db \"blah\\twith escapes\\0\""), Ok(VASMLine::dir_str(Db, "blah\twith escapes\0"))) + assert_eq!( + parse_vasm_line(".db \"blah\""), + Ok(VASMLine::dir_str(Db, "blah")) + ); + assert_eq!( + parse_vasm_line(".db \"blah\\twith escapes\\0\""), + Ok(VASMLine::dir_str(Db, "blah\twith escapes\0")) + ) } #[test] fn test_exprs() { - assert_eq!(parse_vasm_line("add 2 + 3 * (4 - 5) + 6"), Ok( - VASMLine::op(Add) - .with_argument( - Node::Expr( - Box::from(Node::Number(2)), - vec![ - ( - Operator::Add, + assert_eq!( + parse_vasm_line("add 2 + 3 * (4 - 5) + 6"), + Ok(VASMLine::op(Add).with_argument(Node::Expr( + Box::from(Node::Number(2)), + vec![ + ( + Operator::Add, + Node::Expr( + Box::from(Node::Number(3)), + vec![( + Operator::Mul, Node::Expr( - Box::from(Node::Number(3)), - vec![ - ( - Operator::Mul, - Node::Expr( - Box::from(Node::Number(4)), - vec![(Operator::Sub, Node::Number(5))], - ))], )), - ( - Operator::Add, - Node::Number(6) - )], )))); + Box::from(Node::Number(4)), + vec![(Operator::Sub, Node::Number(5))], + ) + )], + ) + ), + (Operator::Add, Node::Number(6)) + ], + ))) + ); } #[test] fn test_expr_labels() { - assert_eq!(parse_vasm_line("loadw foo"), Ok(VASMLine::op_label(Loadw, "foo"))); - assert_eq!(parse_vasm_line("brz @blah"), Ok(VASMLine::op_rel_label(Brz, "blah"))) + assert_eq!( + parse_vasm_line("loadw foo"), + Ok(VASMLine::op_label(Loadw, "foo")) + ); + assert_eq!( + parse_vasm_line("brz @blah"), + Ok(VASMLine::op_rel_label(Brz, "blah")) + ) } #[test] fn test_expr_offsets() { - assert_eq!(parse_vasm_line("jmp $-2"), Ok(VASMLine::op_off(Jmp, Node::AbsoluteOffset(-2)))); - assert_eq!(parse_vasm_line("brz @+3"), Ok(VASMLine::op_off(Brz, Node::RelativeOffset(3)))) + assert_eq!( + parse_vasm_line("jmp $-2"), + Ok(VASMLine::op_off(Jmp, Node::AbsoluteOffset(-2))) + ); + assert_eq!( + parse_vasm_line("brz @+3"), + Ok(VASMLine::op_off(Brz, Node::RelativeOffset(3))) + ) } #[test] fn test_parse_labels() { - assert_eq!(parse_vasm_line("foo: add"), Ok(VASMLine::op(Add).with_label("foo"))); - assert_eq!(parse_vasm_line("bar:"), Ok(VASMLine::blank().with_label("bar"))); - assert_eq!(parse_vasm_line("foo: add 43"), Ok(VASMLine::op_number(Add, 43).with_label("foo"))); + assert_eq!( + parse_vasm_line("foo: add"), + Ok(VASMLine::op(Add).with_label("foo")) + ); + assert_eq!( + parse_vasm_line("bar:"), + Ok(VASMLine::blank().with_label("bar")) + ); + assert_eq!( + parse_vasm_line("foo: add 43"), + Ok(VASMLine::op_number(Add, 43).with_label("foo")) + ); } #[test] fn test_parse_directives() { - assert_eq!(parse_vasm_line("foo: .equ"), Ok(VASMLine::blank().with_label("foo").with_directive(Equ))); - assert_eq!(parse_vasm_line(".db"), Ok(VASMLine::blank().with_directive(Db))); + assert_eq!( + parse_vasm_line("foo: .equ"), + Ok(VASMLine::blank().with_label("foo").with_directive(Equ)) + ); + assert_eq!( + parse_vasm_line(".db"), + Ok(VASMLine::blank().with_directive(Db)) + ); } }