feat: support binary octal and hexadecimal integer literals

This commit is contained in:
2026-10-29 21:14:06 +01:00
parent e804f027f3
commit 00984d1728
5 changed files with 184 additions and 5 deletions
+22 -5
View File
@@ -239,6 +239,7 @@ parse_type_constant :: proc(parser: ^Parser) -> (u64, bool) {
advance(parser)
value, ok := parse_integer_magnitude(token_text(parser, tok))
if !ok {
source.add(parser.diagnostics, tok.span, "integer literal magnitude does not fit in u64")
return 0, false
}
if negative {
@@ -906,21 +907,37 @@ parse_anonymous_struct_type_expr :: proc(parser: ^Parser) -> ast.Expr_Id {
}
parse_integer_magnitude :: proc(text: string) -> (u64, bool) {
base := u64(10)
digits := text
if len(text) >= 2 && text[0] == '0' {
switch text[1] {
case 'b', 'B': base = 2
case 'o', 'O': base = 8
case 'x', 'X': base = 16
}
if base != 10 {
digits = text[2:]
}
}
value: u64
for byte in transmute([]byte)text {
if byte < '0' || byte > '9' {
for byte in transmute([]byte)digits {
if !(byte >= '0' && byte <= '9' || byte >= 'a' && byte <= 'f' || byte >= 'A' && byte <= 'F') {
return 0, false
}
next, overflow := intrinsics.overflow_mul(value, u64(10))
digit := u64(decode_hex_digit(byte))
if digit >= base {
return 0, false
}
next, overflow := intrinsics.overflow_mul(value, base)
if overflow {
return 0, false
}
value, overflow = intrinsics.overflow_add(next, u64(byte-'0'))
value, overflow = intrinsics.overflow_add(next, digit)
if overflow {
return 0, false
}
}
return value, len(text) > 0
return value, len(digits) > 0
}
parse_primary :: proc(parser: ^Parser, nesting: int) -> ast.Expr_Id {