diff options
Diffstat (limited to 'src/tokenizer.c')
-rw-r--r-- | src/tokenizer.c | 83 |
1 files changed, 70 insertions, 13 deletions
diff --git a/src/tokenizer.c b/src/tokenizer.c index 2c27809..c93add3 100644 --- a/src/tokenizer.c +++ b/src/tokenizer.c @@ -35,7 +35,6 @@ int tokenizer_init(Tokenizer *self, ArenaAllocator *allocator, BufferView code, self->token = TOK_NONE; self->needs_update = bool_true; self->code_name = code_name.data ? code_name : create_buffer_view("<buffer>", 8); - self->number_is_integer = bool_false; self->allocator = allocator; self->compiler_options = compiler_options; @@ -236,11 +235,9 @@ static CHECK_RESULT int __tokenizer_next(Tokenizer *self, Token *token) { } *token = TOK_IDENTIFIER; } else if(isDigit(c)) { - int number_start; - int dot_index; BufferView number_str; - number_start = self->index; - dot_index = -1; + int number_start = self->index; + int dot_index = -1; ++self->index; while(self->index < (int)self->code.size) { @@ -256,26 +253,86 @@ static CHECK_RESULT int __tokenizer_next(Tokenizer *self, Token *token) { } number_str = create_buffer_view(self->code.data + number_start, self->index - number_start); + /* TODO: Support octal (0o...), hex (0x...) and binary (0b...) syntax */ + if(number_str.size > 1 && number_str.data[0] == '0') { + tokenizer_print_error(self, number_start, "Invalid number %.*s", (int)number_str.size, number_str.data); + return TOKENIZER_ERR; + } if(dot_index == -1) { - int result; - result = string_to_integer_unchecked(number_str, &self->value.integer); + int result = string_to_integer_unchecked(number_str, &self->number.value.integer); if(result != 0) { /* TODO */ - tokenizer_print_error(self, self->prev_index, "Integer value %.*s is too large to fit in signed 64-bit. Support for large integers is not supported yet.", number_str.size, number_str.data); + tokenizer_print_error(self, self->prev_index, "Integer value %.*s is too large to fit in signed 64-bit. Support for large integers is not supported yet", number_str.size, number_str.data); return TOKENIZER_ERR; } - self->number_is_integer = bool_true; + self->number.type = AMAL_NUMBER_SIGNED_INTEGER; + self->number.bits = 32; } else { - int result; - result = string_to_float_unchecked(number_str, dot_index, &self->value.floating); + int result = string_to_float_unchecked(number_str, dot_index, &self->number.value.floating); if(result != 0) { /* TODO */ - tokenizer_print_error(self, self->prev_index, "Float value %.*s is too large to fit in 64-bit. Support for large floating numbers is not supported yet.", number_str.size, number_str.data); + tokenizer_print_error(self, self->prev_index, "Float value %.*s is too large to fit in 64-bit. Support for large floating numbers is not supported yet", number_str.size, number_str.data); return TOKENIZER_ERR; } - self->number_is_integer = bool_false; + self->number.type = AMAL_NUMBER_FLOAT; + self->number.bits = 32; + } + + if(self->index < (int)self->code.size) { + AmalNumberType number_type = -1; + char suffix_char = self->code.data[self->index]; + + if(suffix_char == 'i') { + number_type = AMAL_NUMBER_SIGNED_INTEGER; + } else if(suffix_char == 'u') { + number_type = AMAL_NUMBER_UNSIGNED_INTEGER; + } else if(suffix_char == 'f') { + number_type = AMAL_NUMBER_FLOAT; + } + + if((int)number_type != -1) { + usize suffix_num_start; + usize suffix_num_len; + i64 suffix_num; + + if(dot_index != -1 && number_type != AMAL_NUMBER_FLOAT) { + tokenizer_print_error(self, self->index, "Floating point number has invalid suffix '%c'. Expected 'f' or nothing", suffix_char); + return TOKENIZER_ERR; + } + + ++self->index; + suffix_num_start = self->index; + while(self->index < (int)self->code.size) { + c = tokenizer_get_char(self); + if(isDigit(c)) + ++self->index; + else + break; + } + + suffix_num_len = self->index - suffix_num_start; + if(suffix_num_len == 0) { + tokenizer_print_error(self, self->index, "Missing number suffix"); + return TOKENIZER_ERR; + } + + number_str = create_buffer_view(self->code.data + suffix_num_start, self->index - suffix_num_start); + int result = string_to_integer_unchecked(number_str, &suffix_num); + /* TODO: Allow larger than 256 bits suffix */ + if(result != 0 || suffix_num > 256) { + /* TODO */ + tokenizer_print_error(self, suffix_num_start, "Number suffix can't be larger than 256"); + return TOKENIZER_ERR; + } + + self->number.type = number_type; + self->number.bits = (int)suffix_num; + } } + + self->value.identifier.data = self->code.data + number_start; + self->value.identifier.size = self->index - number_start; *token = TOK_NUMBER; } else if(c == '"') { int string_end; |