diff options
Diffstat (limited to 'lib/xixanta/src/node.rs')
| -rw-r--r-- | lib/xixanta/src/node.rs | 39 |
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 |
