Cleaned up .db string handling

This commit is contained in:
2022-03-19 13:07:27 -05:00
parent 36dc5d5ed4
commit 987df5fb45
4 changed files with 16 additions and 17 deletions
+1 -1
View File
@@ -22,7 +22,6 @@ pub enum Node<'a> {
RelativeLabel(&'a str),
AbsoluteOffset(i32),
RelativeOffset(i32),
String(String), // TODO: this shouldn't exist
Expr(Box<Node<'a>>, Vec<(Operator, Node<'a>)>),
}
@@ -39,6 +38,7 @@ impl<'a> Display for Label<'a> {
pub enum VASMLine<'a> {
Instruction(Option<Label<'a>>, Opcode, Option<Node<'a>>),
Db(Option<Label<'a>>, Node<'a>),
StringDb(Option<Label<'a>>, String),
Org(Option<Label<'a>>, Node<'a>),
Equ(Label<'a>, Node<'a>),
LabelDef(Label<'a>),
+3 -2
View File
@@ -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 }
line = { SOI ~ (db_word | db_string | org_directive | equ_directive | instruction | label_def) ~ EOI }
-3
View File
@@ -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 {
+12 -11
View File
@@ -66,11 +66,11 @@ impl From<Pair<'_>> 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<VASMLine, ParseError<'_>> {
.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"),