aboutsummaryrefslogtreecommitdiff
path: root/lib/xixanta
diff options
context:
space:
mode:
authorMiquel Sabaté Solà <mikisabate@gmail.com>2025-01-16 23:13:44 +0100
committerMiquel Sabaté Solà <mikisabate@gmail.com>2025-01-16 23:13:44 +0100
commite4e71cda739c9af83302af85520518b838739f91 (patch)
treeb9a79f8fdad598af3d714d4845b387e8e8d59022 /lib/xixanta
parentbc0f8fa2607f1ef570996baa88bb9a6de06cbd5a (diff)
downloadtools.nes-e4e71cda739c9af83302af85520518b838739f91.tar.gz
tools.nes-e4e71cda739c9af83302af85520518b838739f91.zip
Whitelist valid identifier characters
Instead of making up a list of characters that end an identifier, do the other way around since it's far less cumbersome and it prevents from silly bugs such as "var+1" being considered a single identifier. Signed-off-by: Miquel Sabaté Solà <mikisabate@gmail.com>
Diffstat (limited to 'lib/xixanta')
-rw-r--r--lib/xixanta/src/assembler.rs19
-rw-r--r--lib/xixanta/src/parser.rs16
2 files changed, 27 insertions, 8 deletions
diff --git a/lib/xixanta/src/assembler.rs b/lib/xixanta/src/assembler.rs
index e189b08..5e94070 100644
--- a/lib/xixanta/src/assembler.rs
+++ b/lib/xixanta/src/assembler.rs
@@ -2385,15 +2385,24 @@ mod tests {
r#"
Variable = 4
adc Variable
+ adc Variable + 1
+ adc Variable+1
"#,
);
- assert_eq!(res.len(), 1);
+ assert_eq!(res.len(), 3);
+
+ assert_eq!(res[0].size, 2);
+ assert_eq!(res[0].bytes[0], 0x65);
+ assert_eq!(res[0].bytes[1], 0x04);
- let instr = res.first().unwrap();
- assert_eq!(instr.size, 2);
- assert_eq!(instr.bytes[0], 0x65);
- assert_eq!(instr.bytes[1], 0x04);
+ assert_eq!(res[1].size, 2);
+ assert_eq!(res[1].bytes[0], 0x65);
+ assert_eq!(res[1].bytes[1], 0x05);
+
+ assert_eq!(res[2].size, 2);
+ assert_eq!(res[2].bytes[0], 0x65);
+ assert_eq!(res[2].bytes[1], 0x05);
}
#[test]
diff --git a/lib/xixanta/src/parser.rs b/lib/xixanta/src/parser.rs
index 50f2af1..e47f115 100644
--- a/lib/xixanta/src/parser.rs
+++ b/lib/xixanta/src/parser.rs
@@ -239,8 +239,18 @@ impl Parser {
.chars()
.peekable();
while let Some(c) = chars.next() {
- // Check for characters that end an identifier.
- if c.is_whitespace() || c == ':' || c == '(' || c == ')' || c == '=' {
+ // Check for the end of the identifier. For this, it's easier to
+ // simply list what is allowed and negate it.
+ if !(c.is_ascii_alphanumeric()
+ || c == '.'
+ || c == '#'
+ || c == '$'
+ || c == '%'
+ || c == '@'
+ || c == '_'
+ || c == '\''
+ || c == '"')
+ {
// This next match looks scarier than what it actually is. To
// sum things up, the ':' character is quite troublesome, since
// it can mean three things depending on the context.
@@ -2160,7 +2170,7 @@ mod tests {
assert!(node.right.is_none());
let literal = &node.left.clone().unwrap();
- assert_node(literal, NodeType::Literal, line, "#<NUM_SPRITES");
+ assert_node(literal, NodeType::Literal, line, "#");
let op = &literal.left.clone().unwrap();
assert_eq!(op.node_type, NodeType::Operation(OperationType::LoByte));