[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}"
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [elpa] externals/js2-mode d3144b5466 2/2: Merge pull request #584 from DamienCassou/numeric-separator,
ELPA Syncer <=