docs: bring EBNF grammar and project docs up to date

- grammar.ebnf: rewrite the number rule to cover the literal syntaxes the reader
  now accepts — 0x/0X hex, N (bigint) / M (bigdec) suffixes, ratios a/b, radixed
  integers (NrXXX, base 2..36), exponents, and the ##Inf/##-Inf/##NaN symbolic
  floats — noting Jolt reads them as plain Janet numbers.
- README: Numbers bullet notes the literal syntaxes read; conformance count.
- reader-syntax-spec: drop the stale 'ratio not supported' case; add coverage
  for hex-uppercase/N/M/ratio/radix/exponent/##Inf/##NaN.
- PLAN.md: refresh the stale Current State snapshot for the 3-layer test
  structure (spec/integration/unit), ~3,920 suite assertions, 218/218
  conformance, current source size.

jpm test green.
This commit is contained in:
Yogthos 2026-06-05 14:40:47 -04:00
parent ac33124ed4
commit 858c7fed14
4 changed files with 37 additions and 15 deletions

View file

@ -50,16 +50,26 @@ collection = list | vector | map ;
nil = "nil" ;
boolean = "true" | "false" ;
(* Numbers: decimal integer, hexadecimal integer, or decimal float, each with
an optional leading sign. No ratios, radix (NrXXX), BigInt (N) or BigDecimal
(M) suffixes, octal, or exponents Jolt numbers are Janet ints/doubles. *)
number = [ sign ] , ( hex-int | float | integer ) ;
(* Numbers. Jolt accepts Clojure's numeric literal syntaxes, but since Jolt
numbers are Janet ints/doubles it has no distinct bignum, ratio or
BigDecimal types: the BigInt suffix N and BigDecimal suffix M are read as the
plain number, a ratio a/b is read as its double quotient, and radixed
integers are computed by base. The symbolic floats ##Inf/##-Inf/##NaN are
also read. (No octal-with-leading-0 literal.) *)
number = symbolic-value
| [ sign ] , ( radix-int | ratio | hex-int | decimal ) ;
sign = "+" | "-" ;
integer = digit , { digit } ;
hex-int = "0x" , hex-digit , { hex-digit } ;
float = digit , { digit } , "." , digit , { digit } ;
hex-int = "0" , ( "x" | "X" ) , hex-digit , { hex-digit } , [ "N" ] ;
radix-int = integer , ( "r" | "R" ) , alnum , { alnum } ; (* base 2..36: 2r1010, 16rFF, 36rZ *)
ratio = integer , "/" , integer ; (* read as a double quotient *)
decimal = integer , [ "." , digit , { digit } ] , [ exponent ] , [ num-suffix ] ;
exponent = ( "e" | "E" ) , [ sign ] , digit , { digit } ;
num-suffix = "N" | "M" ; (* BigInt / BigDecimal in Clojure; plain number in Jolt *)
symbolic-value = "##Inf" | "##-Inf" | "##NaN" ;
digit = "0".."9" ;
hex-digit = digit | "a".."f" | "A".."F" ;
alnum = digit | "a".."z" | "A".."Z" ;
(* Strings: double-quoted with backslash escapes. *)
string = '"' , { string-char } , '"' ;