summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBen Bridle <ben@derelict.engineering>2025-04-12 10:08:09 +1200
committerBen Bridle <ben@derelict.engineering>2025-04-12 10:08:09 +1200
commitc724c9157dbc4721fa8ed93033cd9699c9652277 (patch)
tree8bb3e9cd2b35ee98ec2a883fe20afa818d9abb0c /src
parent6d016989b0ff5f600f3bdaced1ebf443d2f32da7 (diff)
downloadtorque-asm-c724c9157dbc4721fa8ed93033cd9699c9652277.zip
Implement negative integer literals
Negative literals take the forms -29, -0x1D, and -0b11101 for decimal, hexadecimal, and binary.
Diffstat (limited to 'src')
-rw-r--r--src/stages/syntactic.rs24
1 files changed, 16 insertions, 8 deletions
diff --git a/src/stages/syntactic.rs b/src/stages/syntactic.rs
index 14f8815..45d5e60 100644
--- a/src/stages/syntactic.rs
+++ b/src/stages/syntactic.rs
@@ -168,22 +168,27 @@ fn parse_syntactic_from_tokeniser(mut t: Tokeniser) -> Result<Vec<Tracked<Syntac
c => {
let token = format!("{c}{}", t.eat_token());
- if let Some(hex_string) = token.strip_prefix("0x") {
+ let (stripped, neg) = match token.strip_prefix('-') {
+ Some(stripped) => (stripped, true),
+ None => (token.as_str(), false),
+ };
+ if let Some(hex_string) = stripped.strip_prefix("0x") {
let hex_string = hex_string.to_string();
- match parse_integer_literal(&hex_string, 16) {
+ match parse_integer_literal(&hex_string, 16, neg) {
Ok(value) => SyntacticToken::IntegerLiteral(value),
Err(_) => err!(SyntacticError::InvalidHexadecimalLiteral(hex_string)),
}
- } else if let Some(binary_string) = token.strip_prefix("0b") {
+ } else if let Some(binary_string) = stripped.strip_prefix("0b") {
let binary_string = binary_string.to_string();
- match parse_integer_literal(&binary_string, 2) {
+ match parse_integer_literal(&binary_string, 2, neg) {
Ok(value) => SyntacticToken::IntegerLiteral(value),
Err(_) => err!(SyntacticError::InvalidBinaryLiteral(binary_string)),
}
} else {
- match parse_integer_literal(&token, 10) {
+ let decimal_string = stripped.to_string();
+ match parse_integer_literal(&decimal_string, 10, neg) {
Ok(value) => SyntacticToken::IntegerLiteral(value),
- Err(true) => err!(SyntacticError::InvalidDecimalLiteral(token)),
+ Err(true) => err!(SyntacticError::InvalidDecimalLiteral(decimal_string)),
Err(false) => SyntacticToken::Symbol(ScopedSymbol::Global(token)),
}
}
@@ -200,10 +205,13 @@ fn parse_syntactic_from_tokeniser(mut t: Tokeniser) -> Result<Vec<Tracked<Syntac
}
-fn parse_integer_literal(token: &str, radix: u32) -> Result<isize, bool> {
+fn parse_integer_literal(token: &str, radix: u32, neg: bool) -> Result<isize, bool> {
match usize::from_str_radix(&token.replace('_', ""), radix) {
Ok(value) => match isize::try_from(value) {
- Ok(value) => Ok(value),
+ Ok(value) => match neg {
+ true => Ok(-value),
+ false => Ok(value),
+ }
Err(_) => Err(true),
}
Err(_) => Err(false),