diff options
| author | Miquel Sabaté Solà <mikisabate@gmail.com> | 2024-12-19 12:59:03 +0100 |
|---|---|---|
| committer | Miquel Sabaté Solà <mikisabate@gmail.com> | 2024-12-19 12:59:03 +0100 |
| commit | 69b878d11984b3cf2e1cccc33318bc64c9f62554 (patch) | |
| tree | cc9780abb2a1e8951dffc870a6848976f5628c9b | |
| parent | 42ebea54e35062a1a998f25e8fe019a5e0205fd9 (diff) | |
| download | tools.nes-69b878d11984b3cf2e1cccc33318bc64c9f62554.tar.gz tools.nes-69b878d11984b3cf2e1cccc33318bc64c9f62554.zip | |
parser: Allow for parenthesized expressions
Some expressions might be enclosed with parenthesis in order to avoid
ambiguations when evaluating them. Account for this on the parser when
parsing expressions. Note that this is strictly only on the
`parse_expression` function; statements or other top level constructs
cannot be enclosed inside of parenthesis.
Signed-off-by: Miquel Sabaté Solà <mikisabate@gmail.com>
| -rw-r--r-- | lib/xixanta/src/parser.rs | 43 |
1 files changed, 43 insertions, 0 deletions
diff --git a/lib/xixanta/src/parser.rs b/lib/xixanta/src/parser.rs index 19b4530..d2bb75b 100644 --- a/lib/xixanta/src/parser.rs +++ b/lib/xixanta/src/parser.rs @@ -634,6 +634,24 @@ impl Parser { // and the offset has been set accordingly). Returns a new node for the // expression at hand. fn parse_expression(&mut self, line: &str) -> Result<PNode, ParseError> { + let first = line.chars().next().unwrap_or_default(); + + if first == '(' { + // Skip '(' character and whitespace characters in between. + self.next(); + self.skip_whitespace(line); + + // Extract what's inside of the enclosing parenthesis. + let paren = self.find_matching_paren(line, self.offset)?; + let l = line.get(self.offset..paren).unwrap_or_default(); + + // And return what you can parse from the inner expression. + self.offset = 0; + return self.parse_expression(l); + } + + // There's no complex expression going on. Hence, we can try to parse an + // "identifier" and pass it along. let (id, nt) = self.parse_identifier(line)?; if nt == NodeType::Label { @@ -1024,6 +1042,31 @@ mod tests { } #[test] + fn parse_paren_expression() { + let line = "ldx #(Variable)"; + let mut parser = Parser::default(); + assert!(parser.parse(line.as_bytes()).is_ok()); + + let instr = parser.nodes.last().unwrap(); + assert_eq!(instr.node_type, NodeType::Instruction); + assert!(instr.right.is_none()); + assert!(instr.args.is_none()); + + let node = instr.left.clone().unwrap(); + assert_eq!(node.node_type, NodeType::Literal); + assert!(node.right.is_none()); + assert!(node.args.is_none()); + + let inner = node.left.clone().unwrap(); + assert_eq!(inner.node_type, NodeType::Value); + assert_eq!(inner.value.value, "Variable"); + assert_eq!( + line.get(inner.value.start..inner.value.end).unwrap(), + "Variable" + ); + } + + #[test] fn parse_bad_literals() { for line in vec!["#", "#%", "$"].into_iter() { let mut parser = Parser::default(); |
