From 987df5fb45c32788ee23050d7cf5945ef7cb4250 Mon Sep 17 00:00:00 2001 From: Ross Andrews Date: Sat, 19 Mar 2022 13:07:27 -0500 Subject: [PATCH] Cleaned up .db string handling --- vasm/src/ast.rs | 2 +- vasm/src/vasm.pest | 5 +++-- vasm/src/vasm_evaluator.rs | 3 --- vasm/src/vasm_parser.rs | 23 ++++++++++++----------- 4 files changed, 16 insertions(+), 17 deletions(-) diff --git a/vasm/src/ast.rs b/vasm/src/ast.rs index cac6b73..3ff4df7 100644 --- a/vasm/src/ast.rs +++ b/vasm/src/ast.rs @@ -22,7 +22,6 @@ pub enum Node<'a> { RelativeLabel(&'a str), AbsoluteOffset(i32), RelativeOffset(i32), - String(String), // TODO: this shouldn't exist Expr(Box>, Vec<(Operator, Node<'a>)>), } @@ -39,6 +38,7 @@ impl<'a> Display for Label<'a> { pub enum VASMLine<'a> { Instruction(Option>, Opcode, Option>), Db(Option>, Node<'a>), + StringDb(Option>, String), Org(Option>, Node<'a>), Equ(Label<'a>, Node<'a>), LabelDef(Label<'a>), diff --git a/vasm/src/vasm.pest b/vasm/src/vasm.pest index 469bd8b..2f208bb 100644 --- a/vasm/src/vasm.pest +++ b/vasm/src/vasm.pest @@ -63,9 +63,10 @@ string = ${ "\"" ~ string_inner* ~ "\"" } // - .db to embed some data // - .equ to define some constants instruction = { label_def? ~ opcode ~ expr? } -db_directive = { label_def? ~ ".db" ~ (expr | string) } +db_word = { label_def? ~ ".db" ~ expr } +db_string = { label_def? ~ ".db" ~ string } org_directive = { label_def? ~ ".org" ~ expr } equ_directive = { label_def ~ ".equ" ~ expr } // Finally the entire pattern for an assembly line: -line = { SOI ~ (db_directive | org_directive | equ_directive | instruction | label_def) ~ EOI } \ No newline at end of file +line = { SOI ~ (db_word | db_string | org_directive | equ_directive | instruction | label_def) ~ EOI } \ No newline at end of file diff --git a/vasm/src/vasm_evaluator.rs b/vasm/src/vasm_evaluator.rs index d0c5526..2261831 100644 --- a/vasm/src/vasm_evaluator.rs +++ b/vasm/src/vasm_evaluator.rs @@ -59,9 +59,6 @@ pub fn eval<'a>( Err(EvalError::UnknownAddress(line_num + offset)) } } - Node::String(_) => { - unreachable!() - } Node::Expr(car, cdr) => { let car = eval(*car, line_num, line_addresses, scope); if let Ok(mut acc) = car { diff --git a/vasm/src/vasm_parser.rs b/vasm/src/vasm_parser.rs index f564617..374757d 100644 --- a/vasm/src/vasm_parser.rs +++ b/vasm/src/vasm_parser.rs @@ -66,11 +66,11 @@ impl From> for Operator { } } -/// Create a `Node` containing the string represented by a given pair. Since the pair will +/// Create a String containing the string represented by a given pair. Since the pair will /// reference bytes containing escape sequences, this isn't the same as an &str to the /// original code; this is a new string translating those escape sequences to their actual /// bytes. -fn create_string_node(pair: Pair) -> Node { +fn create_string(pair: Pair) -> String { let mut string = String::with_capacity(pair.as_str().len()); for inner in pair.into_inner() { let string_inner = inner.as_str(); @@ -84,7 +84,7 @@ fn create_string_node(pair: Pair) -> Node { _ => string.push_str(string_inner), } } - Node::String(string) + string } /// Create a `Node` containing the line offset represented by a pair. @@ -134,7 +134,6 @@ fn parse(pair: Pair) -> Node { Rule::oct_number => { Node::Number(i32::from_str_radix(pair.as_str().get(2..).unwrap(), 8).unwrap()) } - Rule::string => create_string_node(pair), Rule::label => Node::Label(pair.as_str()), Rule::relative_label => Node::RelativeLabel(pair.as_str().get(1..).unwrap()), Rule::absolute_line_offset | Rule::relative_line_offset => create_line_offset_node(pair), @@ -167,12 +166,18 @@ pub fn parse_vasm_line(line: &str) -> Result> { .map(|expr| shake(parse(expr))); return Ok(VASMLine::Instruction(label, opcode, argument)); } - Rule::db_directive => { + Rule::db_word => { let mut iter = line.into_inner().peekable(); let label = optional_label(iter.next_if(|pair| pair.as_rule() == Rule::label_def)); let argument = shake(parse(iter.next().unwrap())); return Ok(VASMLine::Db(label, argument)); } + Rule::db_string => { + let mut iter = line.into_inner().peekable(); + let label = optional_label(iter.next_if(|pair| pair.as_rule() == Rule::label_def)); + let argument = create_string(iter.next().unwrap()); + return Ok(VASMLine::StringDb(label, argument)); + } Rule::org_directive => { let mut iter = line.into_inner().peekable(); let label = optional_label(iter.next_if(|pair| pair.as_rule() == Rule::label_def)); @@ -203,10 +208,6 @@ mod test { Node::Number(number) } - fn string(s: &str) -> Node<'static> { - Node::String(s.to_string()) - } - #[test] fn test_parse() { assert_eq!( @@ -264,11 +265,11 @@ mod test { fn test_dbs() { assert_eq!( parse_vasm_line(".db \"blah\""), - Ok(VASMLine::Db(None, string("blah"))) + Ok(VASMLine::StringDb(None, "blah".into())) ); assert_eq!( parse_vasm_line(".db \"blah\\twith escapes\\0\""), - Ok(VASMLine::Db(None, string("blah\twith escapes\0"))) + Ok(VASMLine::StringDb(None, "blah\twith escapes\0".into())) ); assert_eq!( parse_vasm_line("foo: .db 47"),