From ad54d804fef1e1eb646d8ea4bd7ce65363e94fa8 Mon Sep 17 00:00:00 2001 From: dec05eba Date: Wed, 13 Mar 2019 00:22:31 +0100 Subject: Fix bugs Fix hash map bug on rorder (invalid size). Fix string to int/float conversion in tokenizer. Add more ssa functions --- src/tokenizer.c | 33 ++++++++++++++++++++++----------- 1 file changed, 22 insertions(+), 11 deletions(-) (limited to 'src/tokenizer.c') diff --git a/src/tokenizer.c b/src/tokenizer.c index 4f1871b..5f6e59c 100644 --- a/src/tokenizer.c +++ b/src/tokenizer.c @@ -82,6 +82,7 @@ static CHECK_RESULT int find_end_of_string(BufferView buf, int index) { return -1; } +/* TODO: Optimize string to integer and string to float */ #define I64_OVERFLOW_ERROR -1 static CHECK_RESULT int string_to_integer_unchecked(BufferView str, i64 *result) { int i; @@ -91,7 +92,7 @@ static CHECK_RESULT int string_to_integer_unchecked(BufferView str, i64 *result) for(i = 0; i < (int)str.size; ++i) { i64 value_before; value_before = value; - value *= 10 + str.data[i]; + value = value * 10 + (str.data[i] - '0'); /* overflow */ if(value < value_before) return I64_OVERFLOW_ERROR; @@ -102,21 +103,31 @@ static CHECK_RESULT int string_to_integer_unchecked(BufferView str, i64 *result) } #define F64_OVERFLOW_ERROR -1 -static CHECK_RESULT int string_to_float_unchecked(BufferView str, f64 *result) { +static CHECK_RESULT int string_to_float_unchecked(BufferView str, int dot_index, f64 *result) { int i; - f64 value; + f64 value_before_dot; + f64 value_after_dot; + f64 div_factor; - value = 0.0; - for(i = 0; i < (int)str.size; ++i) { + value_before_dot = 0.0; + for(i = 0; i < dot_index; ++i) { f64 value_before; - value_before = value; - value *= 10.0 + str.data[i]; + value_before = value_before_dot; + value_before_dot = value_before_dot * 10.0 + (str.data[i] - '0'); /* overflow */ - if(value < value_before) + if(value_before_dot < value_before) return F64_OVERFLOW_ERROR; } - *result = value; + value_after_dot = 0.0; + div_factor = 1.0; + for(i = dot_index + 1; i < (int)str.size; ++i) { + value_after_dot = value_after_dot * 10.0 + (str.data[i] - '0'); + div_factor *= 10.0; + /* TODO: Check mantissa overflow */ + } + + *result = value_before_dot + (value_after_dot / div_factor); return 0; } @@ -201,7 +212,7 @@ static CHECK_RESULT int __tokenizer_next(Tokenizer *self, Token *token) { if(isDigit(c)) ++self->index; else if(c == '.' && dot_index == -1) { - dot_index = self->index; + dot_index = self->index - number_start; ++self->index; } else { break; @@ -221,7 +232,7 @@ static CHECK_RESULT int __tokenizer_next(Tokenizer *self, Token *token) { self->number_is_integer = bool_true; } else { int result; - result = string_to_float_unchecked(number_str, &self->value.floating); + result = string_to_float_unchecked(number_str, dot_index, &self->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); -- cgit v1.2.3