[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[nongnu] elpa/parseclj f34b8460a8 055/185: Correctly parse numbers in sc
From: |
ELPA Syncer |
Subject: |
[nongnu] elpa/parseclj f34b8460a8 055/185: Correctly parse numbers in scientific notation |
Date: |
Tue, 28 Dec 2021 14:05:16 -0500 (EST) |
branch: elpa/parseclj
commit f34b8460a8467b1923510982ac759ac4f599c06d
Author: Arne Brasseur <arne@arnebrasseur.net>
Commit: Arne Brasseur <arne@arnebrasseur.net>
Correctly parse numbers in scientific notation
---
DESIGN.md | 15 +++++++++
clj-lex.el | 34 ++++++++++++++++---
tests/edn-el-test-suite.el | 82 ++++++++++++++++++++++++----------------------
3 files changed, 86 insertions(+), 45 deletions(-)
diff --git a/DESIGN.md b/DESIGN.md
index 65d22ae503..064618274e 100644
--- a/DESIGN.md
+++ b/DESIGN.md
@@ -231,6 +231,21 @@ The EDN parser functions will take an optional tag handler
function. This functi
When parsing code to an AST the situation is different, here tags simply
become part of the AST, without caring about their semantics.
+## Representing EDN as Emacs Lisp values
+
+See also the section at the top regarding differences between Clojure's data
types vs those available in Emacs Lisp.
+
+These are the choices that the edn.el library has made:
+
+- represent sets as `'(edn-set (... set values ...))`
+- parse maps as hash tables
+- represent characters as integers, *but* parse `\newline` `\return` `\space`
and `\tab` as the symbols `'newline` `'return` etc.
+- parse `true` as `t`, `nil` and `false` as `nil`.
+
+### Differences with EDN.el
+
+At the moment the `clj-parse-edn-*` copy the parsing behavior of edn.el,
*except* that the character literals `\newline`, `\return`, `\space`, and
`\tab` are parsed to their character code (10, 13, 32, and 9 respectively),
instead of to symbols.
+
## AST
An AST (abstract syntax tree) is a tree structure made up of nodes. A node
looks like this
diff --git a/clj-lex.el b/clj-lex.el
index 66f307deef..c5570331a6 100644
--- a/clj-lex.el
+++ b/clj-lex.el
@@ -59,14 +59,38 @@
(buffer-substring-no-properties pos (point))
pos)))
+(defun clj-lex-skip-digits ()
+ (while (and (char-after (point))
+ (<= ?0 (char-after (point)))
+ (<= (char-after (point)) ?9))
+ (right-char)))
+
+(defun clj-lex-skip-number ()
+ ;; [\+\-]?\d+\.\d+
+ (when (member (char-after (point)) '(?+ ?-))
+ (right-char))
+
+ (clj-lex-skip-digits)
+
+ (when (eq (char-after (point)) ?.)
+ (right-char))
+
+ (clj-lex-skip-digits))
+
(defun clj-lex-number ()
(let ((pos (point)))
- (while (and (char-after (point))
- (or (and (<= ?0 (char-after (point))) (<= (char-after (point))
?9))
- (eq (char-after (point)) ?.)
- (eq (char-after (point)) ?M)
- (eq (char-after (point)) ?r)))
+ (clj-lex-skip-number)
+
+ ;; 10110r2 or 4.3e+22
+ (when (member (char-after (point)) '(?E ?e ?r))
(right-char))
+
+ (clj-lex-skip-number)
+
+ ;; trailing M
+ (when (eq (char-after (point)) ?M)
+ (right-char))
+
(clj-lex-token :number
(buffer-substring-no-properties pos (point))
pos)))
diff --git a/tests/edn-el-test-suite.el b/tests/edn-el-test-suite.el
index 7e11b695df..7a2387b021 100644
--- a/tests/edn-el-test-suite.el
+++ b/tests/edn-el-test-suite.el
@@ -79,46 +79,48 @@
(should (equal :\#/:a (clj-parse-edn-str ":#/:a")))
(should (equal :\#foo (clj-parse-edn-str ":#foo"))))
-;; (ert-deftest integers ()
-;; :tags '(edn integers)
-;; (should (= 0 (clj-parse-edn-str "0")))
-;; (should (= 0 (clj-parse-edn-str "+0")))
-;; (should (= 0 (clj-parse-edn-str "-0")))
-;; (should (= 100 (clj-parse-edn-str "100")))
-;; (should (= -100 (clj-parse-edn-str "-100"))))
-
-;; (ert-deftest floats ()
-;; :tags '(edn floats)
-;; (should (= 12.32 (clj-parse-edn-str "12.32")))
-;; (should (= -12.32 (clj-parse-edn-str "-12.32")))
-;; (should (= 9923.23 (clj-parse-edn-str "+9923.23")))
-;; (should (= 4.5e+044 (clj-parse-edn-str "45e+43")))
-;; (should (= -4.5e-042 (clj-parse-edn-str "-45e-43")))
-;; (should (= 4.5e+044 (clj-parse-edn-str "45E+43"))))
-
-;; (ert-deftest lists ()
-;; :tags '(edn lists)
-;; (should-not (clj-parse-edn-str "()"))
-;; (should (equal '(1 2 3) (clj-parse-edn-str "( 1 2 3)")))
-;; (should (equal '(12.1 ?a foo :bar) (clj-parse-edn-str "(12.1 \\a foo
:bar)")))
-;; (should (equal '((:foo bar :bar 12)) (clj-parse-edn-str "( (:foo bar :bar
12))")))
-;; (should (equal
-;; '(defproject com\.thortech/data\.edn "0.1.0-SNAPSHOT")
-;; (clj-parse-edn-str "(defproject com.thortech/data.edn
\"0.1.0-SNAPSHOT\")"))))
-
-;; (ert-deftest vectors ()
-;; :tags '(edn vectors)
-;; (should (equal [] (clj-parse-edn-str "[]")))
-;; (should (equal [] (clj-parse-edn-str "[ ]")))
-;; (should (equal '[1 2 3] (clj-parse-edn-str "[ 1 2 3 ]")))
-;; (should (equal '[12.1 ?a foo :bar] (clj-parse-edn-str "[ 12.1 \\a foo
:bar]")))
-;; (should (equal '[[:foo bar :bar 12]] (clj-parse-edn-str "[[:foo bar :bar
12]]")))
-;; (should (equal '[( :foo bar :bar 12 ) "foo"]
-;; (clj-parse-edn-str "[(:foo bar :bar 12) \"foo\"]")))
-;; (should (equal '[/ \. * ! _ \? $ % & = - +]
-;; (clj-parse-edn-str "[/ . * ! _ ? $ % & = - +]")))
-;; (should (equal [99 newline return space tab]
-;; (clj-parse-edn-str "[\\c \\newline \\return \\space
\\tab]"))))
+(ert-deftest integers ()
+ :tags '(edn integers)
+ (should (= 0 (clj-parse-edn-str "0")))
+ (should (= 0 (clj-parse-edn-str "+0")))
+ (should (= 0 (clj-parse-edn-str "-0")))
+ (should (= 100 (clj-parse-edn-str "100")))
+ (should (= -100 (clj-parse-edn-str "-100"))))
+
+(ert-deftest floats ()
+ :tags '(edn floats)
+ (should (= 12.32 (clj-parse-edn-str "12.32")))
+ (should (= -12.32 (clj-parse-edn-str "-12.32")))
+ (should (= 9923.23 (clj-parse-edn-str "+9923.23")))
+ (should (= 4.5e+044 (clj-parse-edn-str "45e+43")))
+ (should (= -4.5e-042 (clj-parse-edn-str "-45e-43")))
+ (should (= 4.5e+044 (clj-parse-edn-str "45E+43"))))
+
+(ert-deftest lists ()
+ :tags '(edn lists)
+ (should-not (clj-parse-edn-str "()"))
+ (should (equal '(1 2 3) (clj-parse-edn-str "( 1 2 3)")))
+ (should (equal '(12.1 ?a foo :bar) (clj-parse-edn-str "(12.1 \\a foo
:bar)")))
+ (should (equal '((:foo bar :bar 12)) (clj-parse-edn-str "( (:foo bar :bar
12))")))
+ (should (equal
+ '(defproject com\.thortech/data\.edn "0.1.0-SNAPSHOT")
+ (clj-parse-edn-str "(defproject com.thortech/data.edn
\"0.1.0-SNAPSHOT\")"))))
+
+(ert-deftest vectors ()
+ :tags '(edn vectors)
+ (should (equal [] (clj-parse-edn-str "[]")))
+ (should (equal [] (clj-parse-edn-str "[ ]")))
+ (should (equal '[1 2 3] (clj-parse-edn-str "[ 1 2 3 ]")))
+ (should (equal '[12.1 ?a foo :bar] (clj-parse-edn-str "[ 12.1 \\a foo
:bar]")))
+ (should (equal '[[:foo bar :bar 12]] (clj-parse-edn-str "[[:foo bar :bar
12]]")))
+ (should (equal '[( :foo bar :bar 12 ) "foo"]
+ (clj-parse-edn-str "[(:foo bar :bar 12) \"foo\"]")))
+ (should (equal '[/ \. * ! _ \? $ % & = - +]
+ (clj-parse-edn-str "[/ . * ! _ ? $ % & = - +]")))
+ (should (equal
+ ;;[99 newline return space tab]
+ [99 10 13 32 9]
+ (clj-parse-edn-str "[\\c \\newline \\return \\space \\tab]"))))
(defun map-equal (m1 m2)
(and (and (hash-table-p m1) (hash-table-p m2))
- [nongnu] elpa/parseclj 4f54ba52fe 033/185: Add support for sets, (continued)
- [nongnu] elpa/parseclj 4f54ba52fe 033/185: Add support for sets, ELPA Syncer, 2021/12/28
- [nongnu] elpa/parseclj 4f647c8cff 036/185: Remove duplicate defination of clj-lex--token-token, ELPA Syncer, 2021/12/28
- [nongnu] elpa/parseclj 1b2b221c98 038/185: Add AST to Elisp and Clojure/EDN printers, ELPA Syncer, 2021/12/28
- [nongnu] elpa/parseclj 9404763e11 042/185: Make sure Travis uses the right Emacs, ELPA Syncer, 2021/12/28
- [nongnu] elpa/parseclj 29411e2103 045/185: Add a design document to share vision and collect feedback, ELPA Syncer, 2021/12/28
- [nongnu] elpa/parseclj 0702332e5d 046/185: Merge branch 'master' of https://github.com/lambdaisland/clj-parse, ELPA Syncer, 2021/12/28
- [nongnu] elpa/parseclj 553f8618e1 044/185: Rework `clj-parse-deftest` macro, ELPA Syncer, 2021/12/28
- [nongnu] elpa/parseclj da89bf82a3 050/185: Allow colons inside symbols, ELPA Syncer, 2021/12/28
- [nongnu] elpa/parseclj 81fe979450 051/185: Handle parsing of semicolon-based comments., ELPA Syncer, 2021/12/28
- [nongnu] elpa/parseclj a424f87c1b 054/185: :#/# is a valid keyword. :::hello is not, ELPA Syncer, 2021/12/28
- [nongnu] elpa/parseclj f34b8460a8 055/185: Correctly parse numbers in scientific notation,
ELPA Syncer <=
- [nongnu] elpa/parseclj 6fe4ce6095 058/185: Add script to compare speed of edn.el and clj-parse.el, ELPA Syncer, 2021/12/28
- [nongnu] elpa/parseclj 7d70ee4c38 059/185: Add support for tagged literals, ELPA Syncer, 2021/12/28
- [nongnu] elpa/parseclj 4367db07aa 061/185: Move tests to tests/, bench to benchmark/, ELPA Syncer, 2021/12/28
- [nongnu] elpa/parseclj 46570ce843 060/185: A # can be part of a symbol, ELPA Syncer, 2021/12/28
- [nongnu] elpa/parseclj fcd1a086f6 081/185: Rename clj-ast to parseclj-ast, ELPA Syncer, 2021/12/28
- [nongnu] elpa/parseclj 987bd16a57 089/185: Position starts at 1, not at 0 (just like (point)), ELPA Syncer, 2021/12/28
- [nongnu] elpa/parseclj 313fc4e630 077/185: Rename to parseclj, ELPA Syncer, 2021/12/28
- [nongnu] elpa/parseclj 7f8bcd405e 095/185: Make checkdoc happy with parseclj.el, ELPA Syncer, 2021/12/28
- [nongnu] elpa/parseclj 0f16fcf2fa 084/185: Implement parsing with lexical preservation (keep whitespace, comments), ELPA Syncer, 2021/12/28
- [nongnu] elpa/parseclj ca854455f6 099/185: Add missing requirement to `parseedn`, ELPA Syncer, 2021/12/28