diff --git a/test/programs/edn.flan b/test/programs/edn.flan index d54739a..a1d7b2c 100644 --- a/test/programs/edn.flan +++ b/test/programs/edn.flan @@ -145,7 +145,9 @@ (dump "-1 +2 0") ; the signs are part of the number (dump "1.5 -2.5e3 .5") ; f, and a leading dot is a float (dump "true false nil") ; b b n — and not three symbols - (dump "foo foo/bar -") ; `-` alone is a symbol; `foo/bar` is NOT a ratio + ;; `-` alone is a symbol, `foo/bar` is NOT a ratio, and the uppercase half + ;; of the alphabet test is only exercised by a name that has one in it. + (dump "foo Enemy/Goblin -") (dump ":a :foo/bar") ; k, text without the colon (newline) @@ -215,6 +217,11 @@ (refusal "[1 2}") ; the wrong closer (refusal "]") ; a closer with nothing open (refusal "[1 2") ; end of input with something still open + ;; 33 opening brackets against a 32-deep stack. The error message is the + ;; least of what this checks: a `>` where the guard needs `>=` writes one + ;; past the end of a fixed array, and the answer is a bounds trap rather + ;; than a wrong message. The offset is the 33rd bracket. + (refusal "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[") (newline) ;; ── The struct reader ───────────────────────────────────────────── diff --git a/test/test_acceptance.ml b/test/test_acceptance.ml index ccfd5cf..9ea3694 100644 --- a/test/test_acceptance.ml +++ b/test/test_acceptance.ml @@ -404,7 +404,7 @@ let () = i<-1>i<+2>i<0> f<1.5>f<-2.5e3>f<.5> bbn -yyy<-> +yyy<-> kk [<>i<1>]<> @@ -452,6 +452,7 @@ s 4 unbalanced: this closing delimiter does not match the one that is open 0 unbalanced: this closing delimiter does not match the one that is open 4 unbalanced: this closing delimiter does not match the one that is open +32 nesting is too deep: the balance stack is a fixed array and it is full [goblin] hp=12 speed=1.5 boss=no [dragon] hp=40 speed=0 boss=yes diff --git a/vendor/edn/edn.flan b/vendor/edn/edn.flan index eb41be4..72df9df 100644 --- a/vendor/edn/edn.flan +++ b/vendor/edn/edn.flan @@ -53,6 +53,17 @@ ;;;; a byte once anything is non-ASCII, and there is no ;;;; code point type. ;;;; +;;;; ── One place this is not EDN, on the record ──────────────────────── +;;;; +;;;; `.5` is a float here. In EDN a number must begin with a digit and `.` is +;;;; a legal symbol-start byte, so strictly `.5` is the *symbol* `.5` — which +;;;; makes this a reinterpretation of a legal token and not an extension, and +;;;; therefore the kind of thing that gets written down rather than discovered. +;;;; It is this way because number-start? runs before the symbol case and +;;;; parse-f64 accepts a leading dot; a caller who needs the symbol reading +;;;; should not be writing `.5` at all. `-`, by contrast, is a symbol, because +;;;; number-start? requires a digit after the sign. +;;;; ;;;; ── Errors ────────────────────────────────────────────────────────── ;;;; ;;;; On the cursor, not in the return type. `next` answers a Token whose kind @@ -221,6 +232,10 @@ (= b \/))) ;; ── Internal helpers ──────────────────────────────────────────────── +;; +;; "Internal" by intent and not by enforcement: a package has no visibility +;; yet, so edn/scan-atom and edn/push-open are as callable as edn/next is. +;; Nothing below is part of the API and none of it will keep its shape. (defn at-end? [c (Ptr Cursor)] bool (>= (.pos c) (len (.src c))))