aboutsummaryrefslogtreecommitdiff
path: root/lib/xixanta/src/node.rs
diff options
context:
space:
mode:
authorMiquel Sabaté Solà <mikisabate@gmail.com>2024-10-31 16:10:48 +0100
committerMiquel Sabaté Solà <mikisabate@gmail.com>2024-12-12 07:54:58 +0100
commitb768b2c6749986b0efe8610c023b42eb0d9e2ce6 (patch)
tree66dda2259ca11022454b0d88948ffe145fb1d090 /lib/xixanta/src/node.rs
parentd2d6d90acf2e9a8ccb4cbcec619d2a0d49cd462a (diff)
downloadtools.nes-b768b2c6749986b0efe8610c023b42eb0d9e2ce6.tar.gz
tools.nes-b768b2c6749986b0efe8610c023b42eb0d9e2ce6.zip
Add support for anonymous labels
Allow for anonymous labels to be defined and referenced by using the same syntax as cc65. Signed-off-by: Miquel Sabaté Solà <mikisabate@gmail.com>
Diffstat (limited to 'lib/xixanta/src/node.rs')
-rw-r--r--lib/xixanta/src/node.rs39
1 files changed, 39 insertions, 0 deletions
diff --git a/lib/xixanta/src/node.rs b/lib/xixanta/src/node.rs
index c787394..993d9c1 100644
--- a/lib/xixanta/src/node.rs
+++ b/lib/xixanta/src/node.rs
@@ -80,6 +80,45 @@ impl PString {
Ok(())
}
+
+ /// Returns true if this is an anonymous relative reference (i.e. the ':+'
+ /// in something like "beq :+").
+ pub fn is_anonymous_relative_reference(&self) -> bool {
+ let mut it = self.value.chars();
+
+ // An anonymous relative reference must start with ':'. If that's not
+ // the case, return early.
+ if it.next().unwrap_or(' ') != ':' {
+ return false;
+ }
+
+ // Get the first character of the reference. The rest of the string must
+ // be the same as this character.
+ let init = it.next().unwrap_or(' ');
+ if init != '+' && init != '-' {
+ return false;
+ }
+
+ // The rest of the string should match the initial 'c' character (i.e.
+ // either '+' or '-', but never mixed in).
+ it.all(|current| init == current)
+ }
+
+ // Returns the isize value that can be computed assuming that this is an
+ // anonymous relative reference. References to a previous label will have a
+ // negative value, while references to next labels have a positive one.
+ pub fn to_isize(&self) -> isize {
+ let c = self.value.chars().nth(1).unwrap_or(' ');
+
+ // As stated from the documentation, this *has to be* a valid reference.
+ assert!(c == '+' || c == '-', "bad relative reference");
+
+ let res = self.value.chars().filter(|x| *x == c).count() as isize;
+ if c == '-' {
+ return -res;
+ }
+ res
+ }
}
/// The type of control function being used. Use this enum in order to detect