aboutsummaryrefslogtreecommitdiff
path: root/src/tokenizer.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/tokenizer.c')
-rw-r--r--src/tokenizer.c33
1 files changed, 22 insertions, 11 deletions
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);