Add hex support
This commit is contained in:
46
lexing.cpp
46
lexing.cpp
@@ -37,6 +37,13 @@ lex_is_numeric(U8 c){
|
||||
return result;
|
||||
}
|
||||
|
||||
function B32
|
||||
lex_is_numeric_base16(U8 c){
|
||||
B32 result = (c >= '0' && c <= '9') || (c >= 'A' && c <= 'F') ||
|
||||
(c >= 'a' && c <= 'f');
|
||||
return result;
|
||||
}
|
||||
|
||||
function B32
|
||||
lex_is_alphanumeric(U8 c){
|
||||
B32 result = lex_is_numeric(c) || lex_is_alphabetic(c);
|
||||
@@ -73,20 +80,25 @@ token_error(Token *t, String error_val){
|
||||
}
|
||||
|
||||
function void
|
||||
lex_parse_u64(Lexer *lexer, Token *t){
|
||||
lex_parse_u64(Lexer *lexer, Token *t, S64 base){
|
||||
Scratch scratch;
|
||||
Set_BigInt_Allocator(scratch);
|
||||
|
||||
t->kind = TK_Integer;
|
||||
BigInt m = bigint_u64(1); // @leak, it accumulates and potentially needs allocation
|
||||
BigInt val10 = bigint_u64(10);
|
||||
BigInt m = bigint_u64(1);
|
||||
BigInt base_mul = bigint_u64(base);
|
||||
BigInt result = bigint_u64(0);
|
||||
|
||||
for(S64 i = t->len - 1; i >= 0; --i){
|
||||
BigInt val = bigint_u64(t->str[i] - '0'); // I dont think this is a leak, too small
|
||||
BigInt new_val = bigint_mul(&val, &m); // @leak
|
||||
result = bigint_add(&result, &new_val); // @leak
|
||||
m = bigint_mul(&m, &val10); // @leak
|
||||
U64 value = t->str[i];
|
||||
if(t->str[i] >= 'a') value = value - 'a' + 10;
|
||||
else if(t->str[i] >= 'A') value = value - 'A' + 10;
|
||||
else value -= '0';
|
||||
|
||||
BigInt val = bigint_u64(value);
|
||||
BigInt new_val = bigint_mul(&val, &m);
|
||||
result = bigint_add(&result, &new_val);
|
||||
m = bigint_mul(&m, &base_mul);
|
||||
}
|
||||
|
||||
t->int_val = bigint_copy(lexer->arena, &result);
|
||||
@@ -475,7 +487,23 @@ lex__stream(Lexer *lexer){
|
||||
}
|
||||
} break;
|
||||
|
||||
case '0':case '1':case '2':case '3':case '4':
|
||||
case '0':{
|
||||
if(lexc(s) == 'x'){
|
||||
lex_advance(s);
|
||||
while(lex_is_numeric_base16(lexc(s)))
|
||||
lex_advance(s);
|
||||
lex_set_len(s, &t);
|
||||
t.str += 2;
|
||||
t.len -= 2;
|
||||
if(t.len == 0)
|
||||
token_error(&t, "Hex constant doesn't have value"_s);
|
||||
else
|
||||
lex_parse_u64(lexer, &t, 16);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
case '1':case '2':case '3':case '4':
|
||||
case '5':case '6':case '7':case '8':case '9':{
|
||||
B32 found_dot = false;
|
||||
for(;;){
|
||||
@@ -494,7 +522,7 @@ lex__stream(Lexer *lexer){
|
||||
}
|
||||
lex_set_len(s, &t);
|
||||
if(found_dot) lex_parse_f64(&t);
|
||||
else lex_parse_u64(lexer, &t);
|
||||
else lex_parse_u64(lexer, &t, 10);
|
||||
|
||||
} break;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user