From c3f0aec79529902967f4b8157e0cf73de8db9632 Mon Sep 17 00:00:00 2001 From: Dmitry Volyntsev Date: Mon, 5 Jun 2017 14:59:28 +0300 Subject: [PATCH] Added support of scientific notation literals. --- njs/njs_number.c | 46 ++++++++++++++-- njs/test/njs_unit_test.c | 110 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 152 insertions(+), 4 deletions(-) diff --git a/njs/njs_number.c b/njs/njs_number.c index 3df8f36e..cd1179f3 100644 --- a/njs/njs_number.c +++ b/njs/njs_number.c @@ -80,10 +80,9 @@ njs_value_to_index(njs_value_t *value) double njs_number_dec_parse(u_char **start, u_char *end) { - u_char c, *p; - double num, frac, scale; - - /* TODO: "1e2" */ + u_char c, *e, *p; + double num, frac, scale, exponent; + nxt_bool_t minus; p = *start; @@ -121,6 +120,45 @@ njs_number_dec_parse(u_char **start, u_char *end) num += frac / scale; } + e = p + 1; + + if (e < end && (*p == 'e' || *p == 'E')) { + minus = 0; + + if (e + 1 < end) { + if (*e == '-') { + e++; + minus = 1; + + } else if (*e == '+') { + e++; + } + } + + /* Values below '0' become >= 208. */ + c = *e - '0'; + + if (nxt_fast_path(c <= 9)) { + exponent = c; + p = e + 1; + + while (p < end) { + /* Values below '0' become >= 208. */ + c = *p - '0'; + + if (nxt_slow_path(c > 9)) { + break; + } + + exponent = exponent * 10 + c; + p++; + } + + exponent = minus ? -exponent : exponent; + num = num * pow(10.0, exponent); + } + } + *start = p; return num; diff --git a/njs/test/njs_unit_test.c b/njs/test/njs_unit_test.c index fdff83a3..167cff7c 100644 --- a/njs/test/njs_unit_test.c +++ b/njs/test/njs_unit_test.c @@ -150,6 +150,62 @@ static njs_unit_test_t njs_test[] = { nxt_string("\n +1"), nxt_string("1") }, + /* Scientific notation. */ + + { nxt_string("0e0"), + nxt_string("0") }, + + { nxt_string("0.0e0"), + nxt_string("0") }, + + { nxt_string("1e0"), + nxt_string("1") }, + + { nxt_string("1e1"), + nxt_string("10") }, + + { nxt_string("1.e01"), + nxt_string("10") }, + + { nxt_string("5.7e1"), + nxt_string("57") }, + + { nxt_string("5.7e-1"), + nxt_string("0.570000") }, + + { nxt_string("-5.7e-1"), + nxt_string("-0.570000") }, + + { nxt_string("1.1e-01"), + nxt_string("0.110000") }, + + { nxt_string("5.7e-2"), + nxt_string("0.057000") }, + + { nxt_string("1.1e+01"), + nxt_string("11") }, + + { nxt_string("1e9"), + nxt_string("1000000000") }, + + { nxt_string("1.0e308"), + nxt_string("1e+308") }, + + { nxt_string("1e"), + nxt_string("SyntaxError: Unexpected token \"e\" in 1") }, + + { nxt_string("1.e"), + nxt_string("SyntaxError: Unexpected token \"e\" in 1") }, + + { nxt_string("1e+"), + nxt_string("SyntaxError: Unexpected token \"e\" in 1") }, + + { nxt_string("1.e-"), + nxt_string("SyntaxError: Unexpected token \"e\" in 1") }, + + { nxt_string("1eZ"), + nxt_string("SyntaxError: Unexpected token \"eZ\" in 1") }, + /* Indexes. */ { nxt_string("var a = []; a[-1] = 2; a[-1] == a['-1']"), @@ -299,6 +355,33 @@ static njs_unit_test_t njs_test[] = { nxt_string("5 - '0x2 z'"), nxt_string("NaN") }, + { nxt_string("12 - '5.7e1'"), + nxt_string("-45") }, + + { nxt_string("12 - '5.e1'"), + nxt_string("-38") }, + + { nxt_string("12 - '5.7e+01'"), + nxt_string("-45") }, + + { nxt_string("12 - '5.7e-01'"), + nxt_string("11.43") }, + + { nxt_string("12 - ' 5.7e1 '"), + nxt_string("-45") }, + + { nxt_string("12 - '5.7e'"), + nxt_string("NaN") }, + + { nxt_string("12 - '5.7e+'"), + nxt_string("NaN") }, + + { nxt_string("12 - '5.7e-'"), + nxt_string("NaN") }, + + { nxt_string("12 - ' 5.7e1 z'"), + nxt_string("NaN") }, + { nxt_string("5 - '0x'"), nxt_string("NaN") }, @@ -7210,6 +7293,33 @@ static njs_unit_test_t njs_test[] = { nxt_string("parseFloat('Infinit')"), nxt_string("NaN") }, + { nxt_string("parseFloat('5.7e1')"), + nxt_string("57") }, + + { nxt_string("parseFloat('-5.7e-1')"), + nxt_string("-0.570000") }, + + { nxt_string("parseFloat('-5.e-1')"), + nxt_string("-0.500000") }, + + { nxt_string("parseFloat('5.7e+01')"), + nxt_string("57") }, + + { nxt_string("parseFloat(' 5.7e+01abc')"), + nxt_string("57") }, + + { nxt_string("parseFloat('-5.7e-1abc')"), + nxt_string("-0.570000") }, + + { nxt_string("parseFloat('-5.7e')"), + nxt_string("-5.7") }, + + { nxt_string("parseFloat('-5.7e+')"), + nxt_string("-5.7") }, + + { nxt_string("parseFloat('-5.7e+abc')"), + nxt_string("-5.7") }, + /* Trick: number to boolean. */ { nxt_string("var a = 0; !!a"), -- 2.47.3