aboutsummaryrefslogtreecommitdiff
path: root/src/tokenizer.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/tokenizer.c')
-rw-r--r--src/tokenizer.c83
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;