[njs] Added support of scientific notation literals.

Dmitry Volyntsev xeioex at nginx.com
Mon Jun 5 12:03:43 UTC 2017


details:   http://hg.nginx.org/njs/rev/02a59fe82c7a
branches:  
changeset: 351:02a59fe82c7a
user:      Dmitry Volyntsev <xeioex at nginx.com>
date:      Mon Jun 05 14:59:28 2017 +0300
description:
Added support of scientific notation literals.

diffstat:

 njs/njs_number.c         |   46 +++++++++++++++++-
 njs/test/njs_unit_test.c |  110 +++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 152 insertions(+), 4 deletions(-)

diffs (197 lines):

diff -r a782bc08b927 -r 02a59fe82c7a njs/njs_number.c
--- a/njs/njs_number.c	Wed May 31 20:42:15 2017 +0300
+++ b/njs/njs_number.c	Mon Jun 05 14:59:28 2017 +0300
@@ -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_c
         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 -r a782bc08b927 -r 02a59fe82c7a njs/test/njs_unit_test.c
--- a/njs/test/njs_unit_test.c	Wed May 31 20:42:15 2017 +0300
+++ b/njs/test/njs_unit_test.c	Mon Jun 05 14:59:28 2017 +0300
@@ -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"),


More information about the nginx-devel mailing list