From b6f2d3f8bf503efde672f4bb1a34e2ee8f985c38 Mon Sep 17 00:00:00 2001 From: Miquel Sabaté Solà Date: Wed, 15 Jan 2025 08:05:06 +0100 Subject: Parse a string literal as a single object MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Before this it was left to the `parse_identifier` to figure things out, but this was prone to silly errors like "a: b", in which it would mistake it as the start of a label. Instead of any of this, just consume a string literal if it has been detected. Signed-off-by: Miquel Sabaté Solà --- lib/xixanta/src/parser.rs | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) (limited to 'lib/xixanta') diff --git a/lib/xixanta/src/parser.rs b/lib/xixanta/src/parser.rs index eb06040..5a46daf 100644 --- a/lib/xixanta/src/parser.rs +++ b/lib/xixanta/src/parser.rs @@ -896,6 +896,36 @@ impl Parser { // And return what you can parse from the inner expression. self.offset = 0; return self.parse_expression(l); + } else if first == '"' { + let start = self.offset; + let start_column = self.column; + self.next(); + + let mut prev = '"'; + + for ch in line.get(self.offset..).unwrap_or("").chars() { + if ch == '"' && prev != '\\' { + self.next(); + + return Ok(PNode { + node_type: NodeType::Literal, + value: PString { + value: line.get(start..self.offset).unwrap().to_string(), + line: self.line, + start: start_column, + end: self.column, + }, + left: None, + right: None, + args: None, + source: self.current_source, + }); + } + + self.next(); + prev = ch; + } + return Err(self.parser_error("unclosed string")); } else if let Some(node_type) = self.get_unary_from_line(line) { // This is a unary operation. Just parse the right side and return // early. @@ -1524,6 +1554,23 @@ mod tests { } } + #[test] + fn parse_string() { + let mut parser = Parser::default(); + let line = ".asciiz \"a: b\""; + + assert!(parser.parse(line.as_bytes(), SourceInfo::default()).is_ok()); + + let stmt = parser.nodes.last().unwrap().last().unwrap(); + let inner = stmt.args.as_ref().unwrap().first().clone().unwrap(); + assert_eq!(inner.node_type, NodeType::Literal); + assert_eq!(inner.value.value, "\"a: b\""); + assert_eq!( + line.get(inner.value.start..inner.value.end).unwrap(), + "\"a: b\"" + ); + } + // Regular instructions. #[test] -- cgit v1.2.3