diff options
author | Ben Bridle <ben@derelict.engineering> | 2025-04-12 10:08:09 +1200 |
---|---|---|
committer | Ben Bridle <ben@derelict.engineering> | 2025-04-12 10:08:09 +1200 |
commit | c724c9157dbc4721fa8ed93033cd9699c9652277 (patch) | |
tree | 8bb3e9cd2b35ee98ec2a883fe20afa818d9abb0c /src | |
parent | 6d016989b0ff5f600f3bdaced1ebf443d2f32da7 (diff) | |
download | torque-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.rs | 24 |
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), |