commit 7ef5e4df3b35586fd09c4bab3e54b0cfcfbda6d4
parent 02a82de541b029abf90ed8113d0faa1a484a9acc
Author: spxtr <me@spxtr.net>
Date: Sat, 17 Feb 2024 20:27:43 +0000
hare::lex: lex hex.
Signed-off-by: Joe Finney <me@spxtr.net>
Diffstat:
2 files changed, 10 insertions(+), 6 deletions(-)
diff --git a/hare/lex/+test.ha b/hare/lex/+test.ha
@@ -274,7 +274,7 @@ fn loc(line: uint, col: uint) location = location {
const in = "1e5 -1i32 9223372036854775809 1e2z 255u8 0o42u16\n"
"0b1000101u32 0xDEADBEEFu64 -0b10i8 -5e0i16 -0o16i32\n"
"0b00000010000001100000011100001111000000100000011000000111i64\n"
- "13.37 13.37f32 13.37f64 6.022e23 1.616255e-35f64 1e-1";
+ "13.37 13.37f32 13.37f64 6.022e23 1.616255e-35f64 1e-1 0x1p-2";
const expected: [_]token = [
(ltok::LIT_ICONST, 1e5u64, loc(1, 1)),
(ltok::MINUS, void, loc(1, 5)),
@@ -298,6 +298,7 @@ fn loc(line: uint, col: uint) location = location {
(ltok::LIT_FCONST, 6.022e23, loc(4, 25)),
(ltok::LIT_F64, 1.616255e-35, loc(4, 34)),
(ltok::LIT_FCONST, 1e-1, loc(4, 50)),
+ (ltok::LIT_FCONST, 0x1p-2, loc(4, 55)),
];
lextest(in, expected);
};
diff --git a/hare/lex/lex.ha b/hare/lex/lex.ha
@@ -461,7 +461,6 @@ fn lex_literal(lex: *lexer) (token | error) = {
"Expected integer literal");
};
if (float || exp is size || suff is size
- || base != strconv::base::DEC
|| lex.require_int) {
unget(lex, r.0);
break;
@@ -481,13 +480,17 @@ fn lex_literal(lex: *lexer) (token | error) = {
float = true;
append(chars, utf8::encoderune('.')...);
};
- case 'e', 'E' =>
+ case 'e', 'E', 'p', 'P' =>
if (!started) {
return syntaxerr(loc,
"Expected integer literal");
};
- if (exp is size || suff is size
- || base != strconv::base::DEC) {
+ if ((r.0 == 'e' || r.0 == 'E') !=
+ (base == strconv::base::DEC)) {
+ unget(lex, r.0);
+ break;
+ };
+ if (exp is size || suff is size) {
unget(lex, r.0);
break;
} else {
@@ -597,7 +600,7 @@ fn lex_literal(lex: *lexer) (token | error) = {
let val = switch (suff) {
case ltok::LIT_F32, ltok::LIT_F64, ltok::LIT_FCONST =>
val = strings::fromutf8(chars[..floatend])!;
- yield strconv::stof64(val);
+ yield strconv::stof64b(val, base);
case =>
yield strconv::stou64b(val, base);
};