emacs-elpa-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[elpa] externals/js2-mode d3144b5466 2/2: Merge pull request #584 from D


From: ELPA Syncer
Subject: [elpa] externals/js2-mode d3144b5466 2/2: Merge pull request #584 from DamienCassou/numeric-separator
Date: Wed, 16 Mar 2022 11:57:38 -0400 (EDT)

branch: externals/js2-mode
commit d3144b54666bf466f4c46982c557efb95048baa7
Merge: 997cac4c80 d3f667ba89
Author: Dmitry Gutov <dgutov@yandex.ru>
Commit: GitHub <noreply@github.com>

    Merge pull request #584 from DamienCassou/numeric-separator
    
    Add support for numbers with numeric separator
---
 NEWS.md         |  5 +++++
 js2-mode.el     | 45 +++++++++++++++++++++++++++++++++++++++------
 tests/parser.el | 33 +++++++++++++++++++++++++++++++++
 3 files changed, 77 insertions(+), 6 deletions(-)

diff --git a/NEWS.md b/NEWS.md
index 3a87444f12..930c17fd17 100644
--- a/NEWS.md
+++ b/NEWS.md
@@ -1,5 +1,10 @@
 # History of user-visible changes
 
+## Next
+
+* Support for `_` separator in numbers (i.e., numeric separator)
+  ([#584](https://github.com/mooz/js2-mode/pull/584)).
+
 ## 2021-12-29
 
 * Imenu support for mocha-like (includes Jasmine and Cypress) test
diff --git a/js2-mode.el b/js2-mode.el
index 38cc28def0..3f42dc3ea9 100644
--- a/js2-mode.el
+++ b/js2-mode.el
@@ -1974,6 +1974,15 @@ the correct number of ARGS must be provided."
          "not a valid default namespace statement. "
          "Syntax is: default xml namespace = EXPRESSION;")
 
+(js2-msg "msg.no.trailing.numeric.literal"
+         "underscore cannot appear after last digit")
+
+(js2-msg "msg.no.consecutive.numeric.literal"
+         "underscores cannot be next to each other")
+
+(js2-msg "msg.no.numeric.separator.after.leading.zero"
+         "underscore cannot appear after leading zero")
+
 ;; TokensStream warnings
 (js2-msg "msg.bad.octal.literal"
          "illegal octal literal digit %s; "
@@ -5898,6 +5907,22 @@ the token is flagged as such."
       (string-to-number str base)
     (overflow-error -1)))
 
+(defun js2-handle-numeric-separator ()
+  "Detect and handle numeric separator ?_."
+  (let ((buffer (nreverse js2-ts-string-buffer))
+        (res nil))
+    (while (> (length buffer) 0)
+      (let ((current-c (car buffer))
+            (next-c (cadr buffer)))
+        (if (eq current-c ?_)
+            (if (or (= (length buffer) 1) (memq next-c '(?. ?e ?E)))
+                (js2-report-scan-error "msg.no.trailing.numeric.literal")
+              (when (= (cadr buffer) ?_)
+                (js2-report-scan-error "msg.no.consecutive.numeric.literal")))
+          (push (car buffer) res)))
+      (setq buffer (cdr buffer)))
+    (setq js2-ts-string-buffer res)))
+
 (defun js2-get-token-internal-1 (modifier)
   "Return next JavaScript token type, an int such as js2-RETURN.
 During operation, creates an instance of `js2-token' struct, sets
@@ -6025,6 +6050,7 @@ its relevant fields and puts it into `js2-ti-tokens'."
            (when (eq c ?0)
              (setq c (js2-get-char))
              (cond
+              ((eq c ?_) (js2-report-scan-error 
"msg.no.numeric.separator.after.leading.zero"))
               ((or (eq c ?x) (eq c ?X))
                (setq base 16)
                (setq c (js2-get-char)))
@@ -6045,23 +6071,23 @@ its relevant fields and puts it into `js2-ti-tokens'."
             ((eq base 16)
              (if (> 0 (js2-x-digit-to-int c 0))
                  (js2-report-scan-error "msg.missing.hex.digits")
-               (while (<= 0 (js2-x-digit-to-int c 0))
+               (while (or (<= 0 (js2-x-digit-to-int c 0)) (= c ?_))
                  (js2-add-to-string c)
                  (setq c (js2-get-char)))))
             ((eq base 2)
              (if (not (memq c '(?0 ?1)))
                  (js2-report-scan-error "msg.missing.binary.digits")
-               (while (memq c '(?0 ?1))
+               (while (memq c '(?0 ?1 ?_))
                  (js2-add-to-string c)
                  (setq c (js2-get-char)))))
             ((eq base 8)
              (if (or (> ?0 c) (< ?7 c))
                  (js2-report-scan-error "msg.missing.octal.digits")
-               (while (and (<= ?0 c) (>= ?7 c))
+               (while (or (and (<= ?0 c) (>= ?7 c)) (= c ?_))
                  (js2-add-to-string c)
                  (setq c (js2-get-char)))))
             (t
-             (while (and (<= ?0 c) (<= c ?9))
+             (while (or (and (<= ?0 c) (<= c ?9)) (= c ?_))
                ;; We permit 08 and 09 as decimal numbers, which
                ;; makes our behavior a superset of the ECMA
                ;; numeric grammar.  We might not always be so
@@ -6080,7 +6106,7 @@ its relevant fields and puts it into `js2-ti-tokens'."
                (cl-loop do
                         (js2-add-to-string c)
                         (setq c (js2-get-char))
-                        while (js2-digit-p c)))
+                        while (or (js2-digit-p c) (= c ?_))))
              (when (memq c '(?e ?E))
                (js2-add-to-string c)
                (setq c (js2-get-char))
@@ -6092,8 +6118,15 @@ its relevant fields and puts it into `js2-ti-tokens'."
                (cl-loop do
                         (js2-add-to-string c)
                         (setq c (js2-get-char))
-                        while (js2-digit-p c))))
+                        while (or (js2-digit-p c) (= c ?_)))))
            (js2-unget-char)
+           (js2-handle-numeric-separator)
+           (let ((string js2-ts-string-buffer))
+             (while (> (length string) 0)
+               (when (and (eq (car string) ?_))
+                 (if (= (length string) 1)
+                     (js2-report-scan-error 
"msg.no.trailing.numeric.literal")))
+               (setq string (cdr string))))
            (let ((str (js2-set-string-from-buffer token)))
              (setf (js2-token-number token) (js2-string-to-number str base)
                    (js2-token-number-base token) base
diff --git a/tests/parser.el b/tests/parser.el
index d9742a0dee..339f17731b 100644
--- a/tests/parser.el
+++ b/tests/parser.el
@@ -624,6 +624,39 @@ the test."
 (js2-deftest-parse octal-number-broken "0o812;"
   :syntax-error "0o8" :errors-count 2)
 
+;;; Numbers with numeric separator (examples from
+;;; 
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Lexical_grammar#numeric_separators)
+
+(js2-deftest-parse decimal-with-numeric-separator "1_000_000_000_000;"
+  :reference "1000000000000;")
+
+(js2-deftest-parse decimal-with-dot-and-numeric-separator "1_050.95;"
+  :reference "1050.95;")
+
+(js2-deftest-parse binary-number-with-numeric-separator 
"0b1010_0001_1000_0101;" :reference "41349;")
+
+(js2-deftest-parse octal-with-numeric-separator "0o2_2_5_6;"
+  :reference "1198;")
+
+(js2-deftest-parse hex-number-with-numeric-separator "0xA0_B0_C0;"
+  :reference "10531008;")
+
+(js2-deftest-parse decimal-with-consecutive-numeric-separators-broken 
"100__000"
+  :syntax-error "100__000"
+  :errors-count 2)
+
+(js2-deftest-parse decimal-with-trailing-numeric-separator-broken "100_"
+  :syntax-error "100_"
+  :errors-count 2)
+
+(js2-deftest-parse decimal-with-numeric-separator-before-dot-broken "100_.12"
+  :syntax-error "100_.12"
+  :errors-count 2)
+
+(js2-deftest-parse decimal-with-numeric-separator-after-leading-0-broken "0_1"
+  :syntax-error "0_"
+  :errors-count 2)
+
 ;;; Modules
 
 (js2-deftest parse-export-bindings "{one, two as dos}"



reply via email to

[Prev in Thread] Current Thread [Next in Thread]