Racket impl; update test data; tweak spec
This commit is contained in:
parent
2d3df32749
commit
5a18b192ba
Binary file not shown.
|
@ -74,9 +74,35 @@
|
||||||
dict3: @"Duplicate key" <ParseError "{ a: 1, a: 2 }">
|
dict3: @"Duplicate key" <ParseError "{ a: 1, a: 2 }">
|
||||||
dict4: @"Unexpected close brace" <ParseError "}">
|
dict4: @"Unexpected close brace" <ParseError "}">
|
||||||
dict5: @"Missing value" <DecodeError #x"b7 91 92 93 84">
|
dict5: @"Missing value" <DecodeError #x"b7 91 92 93 84">
|
||||||
|
double0: <Test #x"830000000000000000" 0.0>
|
||||||
|
double+0: <Test #x"830000000000000000" +0.0>
|
||||||
|
double-0: <Test #x"838000000000000000" -0.0>
|
||||||
double1: <Test #x"833ff0000000000000" 1.0>
|
double1: <Test #x"833ff0000000000000" 1.0>
|
||||||
double2: <Test #x"83fe3cb7b759bf0426" -1.202e300>
|
double2: <Test #x"83fe3cb7b759bf0426" -1.202e300>
|
||||||
|
double3: <Test #x"83123456789abcdef0" #xd"123456789abcdef0">
|
||||||
|
double4: @"Fewer than 16 digits" <ParseError "#xd\"12345678\"">
|
||||||
|
double5: @"More than 16 digits" <ParseError "#xd\"123456789abcdef012\"">
|
||||||
|
double6: @"Invalid chars" <ParseError "#xd\"12zz56789abcdef0\"">
|
||||||
|
double7: @"Positive infinity" <Test #x"837ff0000000000000" #xd"7ff0000000000000">
|
||||||
|
double8: @"Negative infinity" <Test #x"83fff0000000000000" #xd"fff0000000000000">
|
||||||
|
double9: @"-NaN" <Test #x"83fff0000000000001" #xd"fff0000000000001">
|
||||||
|
double10: @"-NaN" <Test #x"83fff0000000000111" #xd"fff0000000000111">
|
||||||
|
double11: @"+NaN" <Test #x"837ff0000000000001" #xd"7ff0000000000001">
|
||||||
|
double12: @"+NaN" <Test #x"837ff0000000000111" #xd"7ff0000000000111">
|
||||||
|
float0: <Test #x"8200000000" 0.0f>
|
||||||
|
float+0: <Test #x"8200000000" +0.0f>
|
||||||
|
float-0: <Test #x"8280000000" -0.0f>
|
||||||
float1: <Test #x"823f800000" 1.0f>
|
float1: <Test #x"823f800000" 1.0f>
|
||||||
|
float2: <Test #x"8212345678" #xf"12345678">
|
||||||
|
float3: @"Fewer than 8 digits" <ParseError "#xf\"123456\"">
|
||||||
|
float4: @"More than 8 digits" <ParseError "#xf\"123456789a\"">
|
||||||
|
float5: @"Invalid chars" <ParseError "#xf\"12zz5678\"">
|
||||||
|
float6: @"Positive infinity" <Test #x"827f800000" #xf"7f800000">
|
||||||
|
float7: @"Negative infinity" <Test #x"82ff800000" #xf"ff800000">
|
||||||
|
float8: @"+NaN" <Test #x"827f800001" #xf"7f800001">
|
||||||
|
float9: @"+NaN" <Test #x"827f800111" #xf"7f800111">
|
||||||
|
float10: @"-NaN" <Test #x"82ff800001" #xf"ff800001">
|
||||||
|
float11: @"-NaN" <Test #x"82ff800111" #xf"ff800111">
|
||||||
int-257: <Test #x"a1feff" -257>
|
int-257: <Test #x"a1feff" -257>
|
||||||
int-256: <Test #x"a1ff00" -256>
|
int-256: <Test #x"a1ff00" -256>
|
||||||
int-255: <Test #x"a1ff01" -255>
|
int-255: <Test #x"a1ff01" -255>
|
||||||
|
@ -89,10 +115,13 @@
|
||||||
int-2: <Test #x"9e" -2>
|
int-2: <Test #x"9e" -2>
|
||||||
int-1: <Test #x"9f" -1>
|
int-1: <Test #x"9f" -1>
|
||||||
int0: <Test #x"90" 0>
|
int0: <Test #x"90" 0>
|
||||||
|
int+0: <Test #x"90" +0>
|
||||||
|
int-0: <Test #x"90" -0>
|
||||||
int1: <Test #x"91" 1>
|
int1: <Test #x"91" 1>
|
||||||
int12: <Test #x"9c" 12>
|
int12: <Test #x"9c" 12>
|
||||||
int13: <Test #x"a00d" 13>
|
int13: <Test #x"a00d" 13>
|
||||||
int127: <Test #x"a07f" 127>
|
int127: <Test #x"a07f" 127>
|
||||||
|
int+127: <Test #x"a07f" +127>
|
||||||
int128: <Test #x"a10080" 128>
|
int128: <Test #x"a10080" 128>
|
||||||
int255: <Test #x"a100ff" 255>
|
int255: <Test #x"a100ff" 255>
|
||||||
int256: <Test #x"a10100" 256>
|
int256: <Test #x"a10100" 256>
|
||||||
|
@ -112,6 +141,8 @@
|
||||||
list8: @"Missing close bracket" <ParseShort "[">
|
list8: @"Missing close bracket" <ParseShort "[">
|
||||||
list9: @"Unexpected close bracket" <ParseError "]">
|
list9: @"Unexpected close bracket" <ParseError "]">
|
||||||
list10: @"Missing end byte" <DecodeShort #x"b58080">
|
list10: @"Missing end byte" <DecodeShort #x"b58080">
|
||||||
|
list11: <Test #x"b59184" [01]>
|
||||||
|
list12: <Test #x"b59c84" [12]>
|
||||||
noinput0: @"No input at all" <DecodeEOF #x"">
|
noinput0: @"No input at all" <DecodeEOF #x"">
|
||||||
embed0: <Test #x"8690" #!0>
|
embed0: <Test #x"8690" #!0>
|
||||||
embed1: <Test #x"868690" #!#!0>
|
embed1: <Test #x"868690" #!#!0>
|
||||||
|
@ -138,17 +169,22 @@
|
||||||
string5: <Test #x"b104f09d849e" "\uD834\uDD1E">
|
string5: <Test #x"b104f09d849e" "\uD834\uDD1E">
|
||||||
symbol0: <Test #x"b300" ||>
|
symbol0: <Test #x"b300" ||>
|
||||||
symbol2: <Test #x"b30568656c6c6f" hello>
|
symbol2: <Test #x"b30568656c6c6f" hello>
|
||||||
|
symbol3: <Test #x"b305312d322d33" 1-2-3>
|
||||||
|
symbol4: <Test #x"b305612d622d63" a-b-c>
|
||||||
|
symbol5: <Test #x"b305612b622b63" a+b+c>
|
||||||
|
symbol6: <Test #x"b3012b" +>
|
||||||
|
symbol7: <Test #x"b3032b2b2b" +++>
|
||||||
|
symbol8: <Test #x"b3012d" ->
|
||||||
|
symbol9: <Test #x"b3032d2d2d" --->
|
||||||
|
symbol10: <Test #x"b3022d61" -a>
|
||||||
|
symbol11: <Test #x"b3042d2d2d61" ---a>
|
||||||
|
symbol12: <Test #x"b3042d2d2d31" ---1>
|
||||||
|
symbol13: <Test #x"b3042b312e78" +1.x>
|
||||||
tag0: @"Unexpected end tag" <DecodeError #x"84">
|
tag0: @"Unexpected end tag" <DecodeError #x"84">
|
||||||
tag1: @"Invalid tag" <DecodeError #x"10">
|
tag1: @"Invalid tag" <DecodeError #x"10">
|
||||||
tag2: @"Invalid tag" <DecodeError #x"61b10110">
|
tag2: @"Invalid tag" <DecodeError #x"61b10110">
|
||||||
whitespace0: @"Leading spaces have to eventually yield something" <ParseShort " ">
|
whitespace0: @"Leading spaces have to eventually yield something" <ParseShort " ">
|
||||||
whitespace1: @"No input at all" <ParseEOF "">
|
whitespace1: @"No input at all" <ParseEOF "">
|
||||||
value1: <Test #"\xB2\x06corymb" #=#"\xB2\x06corymb">
|
|
||||||
value2: <Test #"\x81" #=#"\x81">
|
|
||||||
value3: <Test #"\x81" #=#[gQ]>
|
|
||||||
value4: <Test #"\x81" #=#[gQ==]>
|
|
||||||
value5: <Test #"\x81" #= #[gQ==]>
|
|
||||||
value6: <Test #x"b591929384" #=#x"b591929384">
|
|
||||||
|
|
||||||
longlist14: <Test #x"b5808080808080808080808080808084"
|
longlist14: <Test #x"b5808080808080808080808080808084"
|
||||||
[#f #f #f #f #f
|
[#f #f #f #f #f
|
||||||
|
|
|
@ -67,8 +67,6 @@
|
||||||
(define (next*)
|
(define (next*)
|
||||||
(skip-whitespace)
|
(skip-whitespace)
|
||||||
(match (next-char)
|
(match (next-char)
|
||||||
[#\- (read-intpart (list #\-) (next-char))]
|
|
||||||
[(and c (or #\0 #\1 #\2 #\3 #\4 #\5 #\6 #\7 #\8 #\9)) (read-intpart '() c)]
|
|
||||||
[#\" (read-string #\")]
|
[#\" (read-string #\")]
|
||||||
[(== PIPE) (string->symbol (read-string PIPE))]
|
[(== PIPE) (string->symbol (read-string PIPE))]
|
||||||
|
|
||||||
|
@ -82,21 +80,12 @@
|
||||||
[#\t #t]
|
[#\t #t]
|
||||||
[#\{ (sequence-fold (set) set-add* values #\})]
|
[#\{ (sequence-fold (set) set-add* values #\})]
|
||||||
[#\" (read-literal-binary)]
|
[#\" (read-literal-binary)]
|
||||||
[#\x (if (eqv? (next-char) #\")
|
[#\x (match (next-char)
|
||||||
(read-hex-binary '())
|
[#\" (read-hex-binary '())]
|
||||||
(parse-error "Expected open-quote at start of hex ByteString"))]
|
[#\f (float (read-hex-float 4))]
|
||||||
|
[#\d (read-hex-float 8)]
|
||||||
|
[c (parse-error "Invalid #x syntax: ~v" c)])]
|
||||||
[#\[ (read-base64-binary '())]
|
[#\[ (read-base64-binary '())]
|
||||||
[#\= (define bs (read-preserve/text in-port #:read-syntax? #t #:source source))
|
|
||||||
(when (not (bytes? (annotated-item bs)))
|
|
||||||
(parse-error "ByteString must follow #="))
|
|
||||||
(when (not (null? (annotated-annotations bs)))
|
|
||||||
(parse-error "Annotations not permitted after #="))
|
|
||||||
(bytes->preserve
|
|
||||||
(annotated-item bs)
|
|
||||||
(lambda (message . args)
|
|
||||||
(apply parse-error (string-append "Inline binary value: " message) args))
|
|
||||||
#:read-syntax? read-syntax?
|
|
||||||
#:on-short (lambda () (parse-error "Incomplete inline binary value")))]
|
|
||||||
[#\! (embedded (decode-embedded (next)))]
|
[#\! (embedded (decode-embedded (next)))]
|
||||||
[c (parse-error "Invalid # syntax: ~v" c)])]
|
[c (parse-error "Invalid # syntax: ~v" c)])]
|
||||||
|
|
||||||
|
@ -110,7 +99,7 @@
|
||||||
[#\] (parse-error "Unexpected ]")]
|
[#\] (parse-error "Unexpected ]")]
|
||||||
[#\} (parse-error "Unexpected }")]
|
[#\} (parse-error "Unexpected }")]
|
||||||
|
|
||||||
[c (read-raw-symbol (list c))]))
|
[c (read-raw-symbol-or-number (list c))]))
|
||||||
|
|
||||||
(define (set-add* s e)
|
(define (set-add* s e)
|
||||||
(when (set-member? s e) (parse-error "Duplicate set element: ~v" e))
|
(when (set-member? s e) (parse-error "Duplicate set element: ~v" e))
|
||||||
|
@ -159,49 +148,6 @@
|
||||||
(annotated '() loc v))))
|
(annotated '() loc v))))
|
||||||
(lambda (pos0 v) v)))
|
(lambda (pos0 v) v)))
|
||||||
|
|
||||||
;;---------------------------------------------------------------------------
|
|
||||||
;; Numbers
|
|
||||||
|
|
||||||
(define (read-intpart acc-rev ch)
|
|
||||||
(match ch
|
|
||||||
[#\0 (read-fracexp (cons ch acc-rev))]
|
|
||||||
[_ (read-digit+ acc-rev read-fracexp ch)]))
|
|
||||||
|
|
||||||
(define (read-digit* acc-rev k)
|
|
||||||
(match (peek-char in-port)
|
|
||||||
[(? char? (? char-numeric?)) (read-digit* (cons (read-char in-port) acc-rev) k)]
|
|
||||||
[_ (k acc-rev)]))
|
|
||||||
|
|
||||||
(define (read-digit+ acc-rev k [ch (read-char in-port)])
|
|
||||||
(match ch
|
|
||||||
[(? char? (? char-numeric?)) (read-digit* (cons ch acc-rev) k)]
|
|
||||||
[_ (parse-error "Incomplete number")]))
|
|
||||||
|
|
||||||
(define (read-fracexp acc-rev)
|
|
||||||
(match (peek-char in-port)
|
|
||||||
[#\. (read-digit+ (cons (read-char in-port) acc-rev) read-exp)]
|
|
||||||
[_ (read-exp acc-rev)]))
|
|
||||||
|
|
||||||
(define (read-exp acc-rev)
|
|
||||||
(match (peek-char in-port)
|
|
||||||
[(or #\e #\E) (read-sign-and-exp (cons (read-char in-port) acc-rev))]
|
|
||||||
[_ (finish-number acc-rev)]))
|
|
||||||
|
|
||||||
(define (read-sign-and-exp acc-rev)
|
|
||||||
(match (peek-char in-port)
|
|
||||||
[(or #\+ #\-) (read-digit+ (cons (read-char in-port) acc-rev) finish-number)]
|
|
||||||
[_ (read-digit+ acc-rev finish-number)]))
|
|
||||||
|
|
||||||
(define (finish-number acc-rev)
|
|
||||||
(define s (list->string (reverse acc-rev)))
|
|
||||||
(define n (string->number s 10))
|
|
||||||
(when (not n) (parse-error "Invalid number: ~v" s))
|
|
||||||
(if (flonum? n)
|
|
||||||
(match (peek-char in-port)
|
|
||||||
[(or #\f #\F) (read-char in-port) (float n)]
|
|
||||||
[_ n])
|
|
||||||
n))
|
|
||||||
|
|
||||||
;;---------------------------------------------------------------------------
|
;;---------------------------------------------------------------------------
|
||||||
;; String-like things
|
;; String-like things
|
||||||
|
|
||||||
|
@ -279,6 +225,17 @@
|
||||||
[else
|
[else
|
||||||
(parse-error "Invalid hex character")]))
|
(parse-error "Invalid hex character")]))
|
||||||
|
|
||||||
|
;;---------------------------------------------------------------------------
|
||||||
|
;; Hex-encoded floating point numbers
|
||||||
|
|
||||||
|
(define (read-hex-float byte-count)
|
||||||
|
(unless (eqv? (next-char) #\")
|
||||||
|
(parse-error "Missing open-double-quote in hex-encoded floating-point number"))
|
||||||
|
(define bs (read-hex-binary '()))
|
||||||
|
(unless (= (bytes-length bs) byte-count)
|
||||||
|
(parse-error "Incorrect number of bytes in hex-encoded floating-point number"))
|
||||||
|
(floating-point-bytes->real bs #t 0 byte-count))
|
||||||
|
|
||||||
;;---------------------------------------------------------------------------
|
;;---------------------------------------------------------------------------
|
||||||
;; Base64-encoded ByteStrings
|
;; Base64-encoded ByteStrings
|
||||||
|
|
||||||
|
@ -334,16 +291,56 @@
|
||||||
#\}))
|
#\}))
|
||||||
|
|
||||||
;;---------------------------------------------------------------------------
|
;;---------------------------------------------------------------------------
|
||||||
;; "Raw" symbols
|
;; "Raw" symbols and numbers
|
||||||
|
|
||||||
(define (read-raw-symbol acc)
|
(define (read-raw-symbol-or-number acc)
|
||||||
(match (peek-char in-port)
|
(match (peek-char in-port)
|
||||||
[(or (? eof-object?)
|
[(or (? eof-object?)
|
||||||
(? char? (or #\( #\) #\{ #\} #\[ #\] #\< #\>
|
(? char? (or #\( #\) #\{ #\} #\[ #\] #\< #\>
|
||||||
#\" #\; #\, #\@ #\# #\: (== PIPE)
|
#\" #\; #\, #\@ #\# #\: (== PIPE)
|
||||||
(? char-whitespace?))))
|
(? char-whitespace?))))
|
||||||
(string->symbol (list->string (reverse acc)))]
|
(let ((input (reverse acc)))
|
||||||
[_ (read-raw-symbol (cons (read-char in-port) acc))]))
|
(or (analyze-number input)
|
||||||
|
(string->symbol (list->string input))))]
|
||||||
|
[_ (read-raw-symbol-or-number (cons (read-char in-port) acc))]))
|
||||||
|
|
||||||
|
(define (analyze-number input)
|
||||||
|
(match input
|
||||||
|
[(cons (and sign (or #\+ #\-)) input) (read-digit+ (list sign) read-fracexp input)]
|
||||||
|
[_ (read-digit+ (list) read-fracexp input)]))
|
||||||
|
|
||||||
|
(define (read-digit* acc-rev k input)
|
||||||
|
(match input
|
||||||
|
[(cons (? char? (? char-numeric? d)) input) (read-digit* (cons d acc-rev) k input)]
|
||||||
|
[_ (k acc-rev input)]))
|
||||||
|
|
||||||
|
(define (read-digit+ acc-rev k input)
|
||||||
|
(match input
|
||||||
|
[(cons (? char? (? char-numeric? d)) input) (read-digit* (cons d acc-rev) k input)]
|
||||||
|
[_ #f]))
|
||||||
|
|
||||||
|
(define (read-fracexp acc-rev input)
|
||||||
|
(match input
|
||||||
|
[(cons #\. input) (read-digit+ (cons #\. acc-rev) read-exp input)]
|
||||||
|
[_ (read-exp acc-rev input)]))
|
||||||
|
|
||||||
|
(define (read-exp acc-rev input)
|
||||||
|
(match input
|
||||||
|
[(cons (and e (or #\e #\E)) input) (read-sign-and-exp (cons e acc-rev) input)]
|
||||||
|
[_ (finish-number acc-rev input)]))
|
||||||
|
|
||||||
|
(define (read-sign-and-exp acc-rev input)
|
||||||
|
(match input
|
||||||
|
[(cons (and sign (or #\+ #\-)) input) (read-digit+ (cons sign acc-rev) finish-number input)]
|
||||||
|
[_ (read-digit+ acc-rev finish-number input)]))
|
||||||
|
|
||||||
|
(define (finish-number acc-rev input)
|
||||||
|
(define s (list->string (reverse acc-rev)))
|
||||||
|
(define n (string->number s 10))
|
||||||
|
(cond [(not n) #f]
|
||||||
|
[(and (flonum? n) (member input '((#\f) (#\F)))) (float n)]
|
||||||
|
[(equal? input '()) n]
|
||||||
|
[else #f]))
|
||||||
|
|
||||||
;;---------------------------------------------------------------------------
|
;;---------------------------------------------------------------------------
|
||||||
;; Main entry point to parser
|
;; Main entry point to parser
|
||||||
|
|
|
@ -74,9 +74,35 @@
|
||||||
dict3: @"Duplicate key" <ParseError "{ a: 1, a: 2 }">
|
dict3: @"Duplicate key" <ParseError "{ a: 1, a: 2 }">
|
||||||
dict4: @"Unexpected close brace" <ParseError "}">
|
dict4: @"Unexpected close brace" <ParseError "}">
|
||||||
dict5: @"Missing value" <DecodeError #x"b7 91 92 93 84">
|
dict5: @"Missing value" <DecodeError #x"b7 91 92 93 84">
|
||||||
|
double0: <Test #x"830000000000000000" 0.0>
|
||||||
|
double+0: <Test #x"830000000000000000" +0.0>
|
||||||
|
double-0: <Test #x"838000000000000000" -0.0>
|
||||||
double1: <Test #x"833ff0000000000000" 1.0>
|
double1: <Test #x"833ff0000000000000" 1.0>
|
||||||
double2: <Test #x"83fe3cb7b759bf0426" -1.202e300>
|
double2: <Test #x"83fe3cb7b759bf0426" -1.202e300>
|
||||||
|
double3: <Test #x"83123456789abcdef0" #xd"123456789abcdef0">
|
||||||
|
double4: @"Fewer than 16 digits" <ParseError "#xd\"12345678\"">
|
||||||
|
double5: @"More than 16 digits" <ParseError "#xd\"123456789abcdef012\"">
|
||||||
|
double6: @"Invalid chars" <ParseError "#xd\"12zz56789abcdef0\"">
|
||||||
|
double7: @"Positive infinity" <Test #x"837ff0000000000000" #xd"7ff0000000000000">
|
||||||
|
double8: @"Negative infinity" <Test #x"83fff0000000000000" #xd"fff0000000000000">
|
||||||
|
double9: @"-NaN" <Test #x"83fff0000000000001" #xd"fff0000000000001">
|
||||||
|
double10: @"-NaN" <Test #x"83fff0000000000111" #xd"fff0000000000111">
|
||||||
|
double11: @"+NaN" <Test #x"837ff0000000000001" #xd"7ff0000000000001">
|
||||||
|
double12: @"+NaN" <Test #x"837ff0000000000111" #xd"7ff0000000000111">
|
||||||
|
float0: <Test #x"8200000000" 0.0f>
|
||||||
|
float+0: <Test #x"8200000000" +0.0f>
|
||||||
|
float-0: <Test #x"8280000000" -0.0f>
|
||||||
float1: <Test #x"823f800000" 1.0f>
|
float1: <Test #x"823f800000" 1.0f>
|
||||||
|
float2: <Test #x"8212345678" #xf"12345678">
|
||||||
|
float3: @"Fewer than 8 digits" <ParseError "#xf\"123456\"">
|
||||||
|
float4: @"More than 8 digits" <ParseError "#xf\"123456789a\"">
|
||||||
|
float5: @"Invalid chars" <ParseError "#xf\"12zz5678\"">
|
||||||
|
float6: @"Positive infinity" <Test #x"827f800000" #xf"7f800000">
|
||||||
|
float7: @"Negative infinity" <Test #x"82ff800000" #xf"ff800000">
|
||||||
|
float8: @"+NaN" <Test #x"827f800001" #xf"7f800001">
|
||||||
|
float9: @"+NaN" <Test #x"827f800111" #xf"7f800111">
|
||||||
|
float10: @"-NaN" <Test #x"82ff800001" #xf"ff800001">
|
||||||
|
float11: @"-NaN" <Test #x"82ff800111" #xf"ff800111">
|
||||||
int-257: <Test #x"a1feff" -257>
|
int-257: <Test #x"a1feff" -257>
|
||||||
int-256: <Test #x"a1ff00" -256>
|
int-256: <Test #x"a1ff00" -256>
|
||||||
int-255: <Test #x"a1ff01" -255>
|
int-255: <Test #x"a1ff01" -255>
|
||||||
|
@ -89,10 +115,13 @@
|
||||||
int-2: <Test #x"9e" -2>
|
int-2: <Test #x"9e" -2>
|
||||||
int-1: <Test #x"9f" -1>
|
int-1: <Test #x"9f" -1>
|
||||||
int0: <Test #x"90" 0>
|
int0: <Test #x"90" 0>
|
||||||
|
int+0: <Test #x"90" +0>
|
||||||
|
int-0: <Test #x"90" -0>
|
||||||
int1: <Test #x"91" 1>
|
int1: <Test #x"91" 1>
|
||||||
int12: <Test #x"9c" 12>
|
int12: <Test #x"9c" 12>
|
||||||
int13: <Test #x"a00d" 13>
|
int13: <Test #x"a00d" 13>
|
||||||
int127: <Test #x"a07f" 127>
|
int127: <Test #x"a07f" 127>
|
||||||
|
int+127: <Test #x"a07f" +127>
|
||||||
int128: <Test #x"a10080" 128>
|
int128: <Test #x"a10080" 128>
|
||||||
int255: <Test #x"a100ff" 255>
|
int255: <Test #x"a100ff" 255>
|
||||||
int256: <Test #x"a10100" 256>
|
int256: <Test #x"a10100" 256>
|
||||||
|
@ -112,6 +141,8 @@
|
||||||
list8: @"Missing close bracket" <ParseShort "[">
|
list8: @"Missing close bracket" <ParseShort "[">
|
||||||
list9: @"Unexpected close bracket" <ParseError "]">
|
list9: @"Unexpected close bracket" <ParseError "]">
|
||||||
list10: @"Missing end byte" <DecodeShort #x"b58080">
|
list10: @"Missing end byte" <DecodeShort #x"b58080">
|
||||||
|
list11: <Test #x"b59184" [01]>
|
||||||
|
list12: <Test #x"b59c84" [12]>
|
||||||
noinput0: @"No input at all" <DecodeEOF #x"">
|
noinput0: @"No input at all" <DecodeEOF #x"">
|
||||||
embed0: <Test #x"8690" #!0>
|
embed0: <Test #x"8690" #!0>
|
||||||
embed1: <Test #x"868690" #!#!0>
|
embed1: <Test #x"868690" #!#!0>
|
||||||
|
@ -138,17 +169,22 @@
|
||||||
string5: <Test #x"b104f09d849e" "\uD834\uDD1E">
|
string5: <Test #x"b104f09d849e" "\uD834\uDD1E">
|
||||||
symbol0: <Test #x"b300" ||>
|
symbol0: <Test #x"b300" ||>
|
||||||
symbol2: <Test #x"b30568656c6c6f" hello>
|
symbol2: <Test #x"b30568656c6c6f" hello>
|
||||||
|
symbol3: <Test #x"b305312d322d33" 1-2-3>
|
||||||
|
symbol4: <Test #x"b305612d622d63" a-b-c>
|
||||||
|
symbol5: <Test #x"b305612b622b63" a+b+c>
|
||||||
|
symbol6: <Test #x"b3012b" +>
|
||||||
|
symbol7: <Test #x"b3032b2b2b" +++>
|
||||||
|
symbol8: <Test #x"b3012d" ->
|
||||||
|
symbol9: <Test #x"b3032d2d2d" --->
|
||||||
|
symbol10: <Test #x"b3022d61" -a>
|
||||||
|
symbol11: <Test #x"b3042d2d2d61" ---a>
|
||||||
|
symbol12: <Test #x"b3042d2d2d31" ---1>
|
||||||
|
symbol13: <Test #x"b3042b312e78" +1.x>
|
||||||
tag0: @"Unexpected end tag" <DecodeError #x"84">
|
tag0: @"Unexpected end tag" <DecodeError #x"84">
|
||||||
tag1: @"Invalid tag" <DecodeError #x"10">
|
tag1: @"Invalid tag" <DecodeError #x"10">
|
||||||
tag2: @"Invalid tag" <DecodeError #x"61b10110">
|
tag2: @"Invalid tag" <DecodeError #x"61b10110">
|
||||||
whitespace0: @"Leading spaces have to eventually yield something" <ParseShort " ">
|
whitespace0: @"Leading spaces have to eventually yield something" <ParseShort " ">
|
||||||
whitespace1: @"No input at all" <ParseEOF "">
|
whitespace1: @"No input at all" <ParseEOF "">
|
||||||
value1: <Test #"\xB2\x06corymb" #=#"\xB2\x06corymb">
|
|
||||||
value2: <Test #"\x81" #=#"\x81">
|
|
||||||
value3: <Test #"\x81" #=#[gQ]>
|
|
||||||
value4: <Test #"\x81" #=#[gQ==]>
|
|
||||||
value5: <Test #"\x81" #= #[gQ==]>
|
|
||||||
value6: <Test #x"b591929384" #=#x"b591929384">
|
|
||||||
|
|
||||||
longlist14: <Test #x"b5808080808080808080808080808084"
|
longlist14: <Test #x"b5808080808080808080808080808084"
|
||||||
[#f #f #f #f #f
|
[#f #f #f #f #f
|
||||||
|
|
|
@ -17,6 +17,8 @@
|
||||||
(require racket/dict)
|
(require racket/dict)
|
||||||
(require racket/set)
|
(require racket/set)
|
||||||
(require (only-in racket/port with-output-to-string))
|
(require (only-in racket/port with-output-to-string))
|
||||||
|
(require (only-in racket/math nan? infinite?))
|
||||||
|
(require (only-in file/sha1 bytes->hex-string))
|
||||||
|
|
||||||
(define PIPE #\|)
|
(define PIPE #\|)
|
||||||
|
|
||||||
|
@ -132,6 +134,13 @@
|
||||||
(write-binary-stringlike v)
|
(write-binary-stringlike v)
|
||||||
(write-binary-base64 outer-distance v)))))
|
(write-binary-base64 outer-distance v)))))
|
||||||
|
|
||||||
|
(define (write-float v byte-count hextype suffix)
|
||||||
|
(if (or (nan? v) (infinite? v))
|
||||||
|
(! "#x~a\"~a\""
|
||||||
|
hextype
|
||||||
|
(bytes->hex-string (real->floating-point-bytes v byte-count #t)))
|
||||||
|
(! "~v~a" v suffix)))
|
||||||
|
|
||||||
(define (write-value distance v)
|
(define (write-value distance v)
|
||||||
(match v
|
(match v
|
||||||
[(annotated annotations _ item)
|
[(annotated annotations _ item)
|
||||||
|
@ -143,8 +152,8 @@
|
||||||
(write-value distance item)]
|
(write-value distance item)]
|
||||||
[#f (! "#f")]
|
[#f (! "#f")]
|
||||||
[#t (! "#t")]
|
[#t (! "#t")]
|
||||||
[(float v) (! "~vf" v)]
|
[(float v) (write-float v 4 "f" "f")]
|
||||||
[(? flonum?) (! "~v" v)]
|
[(? flonum?) (write-float v 8 "d" "")]
|
||||||
[(? integer? x) (! "~v" v)]
|
[(? integer? x) (! "~v" v)]
|
||||||
[(? string?)
|
[(? string?)
|
||||||
(! "\"")
|
(! "\"")
|
||||||
|
|
|
@ -42,7 +42,8 @@ Any `Value` may be preceded by whitespace.
|
||||||
|
|
||||||
Value = ws (Record / Collection / Atom / Embedded)
|
Value = ws (Record / Collection / Atom / Embedded)
|
||||||
Collection = Sequence / Dictionary / Set
|
Collection = Sequence / Dictionary / Set
|
||||||
Atom = Boolean / String / ByteString / QuotedSymbol / SymbolOrNumber
|
Atom = Boolean / String / ByteString /
|
||||||
|
QuotedSymbol / SymbolOrNumber
|
||||||
|
|
||||||
Each `Record` is an angle-bracket enclosed grouping of its
|
Each `Record` is an angle-bracket enclosed grouping of its
|
||||||
label-`Value` followed by its field-`Value`s.
|
label-`Value` followed by its field-`Value`s.
|
||||||
|
@ -211,13 +212,14 @@ represented as raw hexadecimal strings similar to hexadecimal
|
||||||
syntax whereever convenient, even for values representable using the
|
syntax whereever convenient, even for values representable using the
|
||||||
grammar above.[^rationale-no-general-machine-syntax]
|
grammar above.[^rationale-no-general-machine-syntax]
|
||||||
|
|
||||||
Float =/ "#xf" %x22 8HEXDIG %x22
|
Value =/ HexFloat / HexDouble
|
||||||
Double =/ "#xd" %x22 16HEXDIG %x22
|
HexFloat = "#xf" %x22 4(ws 2HEXDIG) ws %x22
|
||||||
|
HexDouble = "#xd" %x22 8(ws 2HEXDIG) ws %x22
|
||||||
|
|
||||||
[^rationale-no-general-machine-syntax]: **Rationale.** Previous versions
|
[^rationale-no-general-machine-syntax]: **Rationale.** Previous versions
|
||||||
of this specification included an escape to the [machine-oriented
|
of this specification included an escape to the [machine-oriented
|
||||||
binary syntax](preserves-binary.html) by prefixing a `ByteString`
|
binary syntax](preserves-binary.html) by prefixing a `ByteString`
|
||||||
containing the binary representation of the `Value` with `#=`. The only
|
containing the binary representation of a `Value` with `#=`. The only
|
||||||
true need for this feature was to represent otherwise-unrepresentable
|
true need for this feature was to represent otherwise-unrepresentable
|
||||||
floating-point values. Instead, this specification allows such
|
floating-point values. Instead, this specification allows such
|
||||||
floating-point values to be written directly. Removing the `#=` syntax
|
floating-point values to be written directly. Removing the `#=` syntax
|
||||||
|
|
Binary file not shown.
|
@ -74,9 +74,35 @@
|
||||||
dict3: @"Duplicate key" <ParseError "{ a: 1, a: 2 }">
|
dict3: @"Duplicate key" <ParseError "{ a: 1, a: 2 }">
|
||||||
dict4: @"Unexpected close brace" <ParseError "}">
|
dict4: @"Unexpected close brace" <ParseError "}">
|
||||||
dict5: @"Missing value" <DecodeError #x"b7 91 92 93 84">
|
dict5: @"Missing value" <DecodeError #x"b7 91 92 93 84">
|
||||||
|
double0: <Test #x"830000000000000000" 0.0>
|
||||||
|
double+0: <Test #x"830000000000000000" +0.0>
|
||||||
|
double-0: <Test #x"838000000000000000" -0.0>
|
||||||
double1: <Test #x"833ff0000000000000" 1.0>
|
double1: <Test #x"833ff0000000000000" 1.0>
|
||||||
double2: <Test #x"83fe3cb7b759bf0426" -1.202e300>
|
double2: <Test #x"83fe3cb7b759bf0426" -1.202e300>
|
||||||
|
double3: <Test #x"83123456789abcdef0" #xd"123456789abcdef0">
|
||||||
|
double4: @"Fewer than 16 digits" <ParseError "#xd\"12345678\"">
|
||||||
|
double5: @"More than 16 digits" <ParseError "#xd\"123456789abcdef012\"">
|
||||||
|
double6: @"Invalid chars" <ParseError "#xd\"12zz56789abcdef0\"">
|
||||||
|
double7: @"Positive infinity" <Test #x"837ff0000000000000" #xd"7ff0000000000000">
|
||||||
|
double8: @"Negative infinity" <Test #x"83fff0000000000000" #xd"fff0000000000000">
|
||||||
|
double9: @"-NaN" <Test #x"83fff0000000000001" #xd"fff0000000000001">
|
||||||
|
double10: @"-NaN" <Test #x"83fff0000000000111" #xd"fff0000000000111">
|
||||||
|
double11: @"+NaN" <Test #x"837ff0000000000001" #xd"7ff0000000000001">
|
||||||
|
double12: @"+NaN" <Test #x"837ff0000000000111" #xd"7ff0000000000111">
|
||||||
|
float0: <Test #x"8200000000" 0.0f>
|
||||||
|
float+0: <Test #x"8200000000" +0.0f>
|
||||||
|
float-0: <Test #x"8280000000" -0.0f>
|
||||||
float1: <Test #x"823f800000" 1.0f>
|
float1: <Test #x"823f800000" 1.0f>
|
||||||
|
float2: <Test #x"8212345678" #xf"12345678">
|
||||||
|
float3: @"Fewer than 8 digits" <ParseError "#xf\"123456\"">
|
||||||
|
float4: @"More than 8 digits" <ParseError "#xf\"123456789a\"">
|
||||||
|
float5: @"Invalid chars" <ParseError "#xf\"12zz5678\"">
|
||||||
|
float6: @"Positive infinity" <Test #x"827f800000" #xf"7f800000">
|
||||||
|
float7: @"Negative infinity" <Test #x"82ff800000" #xf"ff800000">
|
||||||
|
float8: @"+NaN" <Test #x"827f800001" #xf"7f800001">
|
||||||
|
float9: @"+NaN" <Test #x"827f800111" #xf"7f800111">
|
||||||
|
float10: @"-NaN" <Test #x"82ff800001" #xf"ff800001">
|
||||||
|
float11: @"-NaN" <Test #x"82ff800111" #xf"ff800111">
|
||||||
int-257: <Test #x"a1feff" -257>
|
int-257: <Test #x"a1feff" -257>
|
||||||
int-256: <Test #x"a1ff00" -256>
|
int-256: <Test #x"a1ff00" -256>
|
||||||
int-255: <Test #x"a1ff01" -255>
|
int-255: <Test #x"a1ff01" -255>
|
||||||
|
@ -89,10 +115,13 @@
|
||||||
int-2: <Test #x"9e" -2>
|
int-2: <Test #x"9e" -2>
|
||||||
int-1: <Test #x"9f" -1>
|
int-1: <Test #x"9f" -1>
|
||||||
int0: <Test #x"90" 0>
|
int0: <Test #x"90" 0>
|
||||||
|
int+0: <Test #x"90" +0>
|
||||||
|
int-0: <Test #x"90" -0>
|
||||||
int1: <Test #x"91" 1>
|
int1: <Test #x"91" 1>
|
||||||
int12: <Test #x"9c" 12>
|
int12: <Test #x"9c" 12>
|
||||||
int13: <Test #x"a00d" 13>
|
int13: <Test #x"a00d" 13>
|
||||||
int127: <Test #x"a07f" 127>
|
int127: <Test #x"a07f" 127>
|
||||||
|
int+127: <Test #x"a07f" +127>
|
||||||
int128: <Test #x"a10080" 128>
|
int128: <Test #x"a10080" 128>
|
||||||
int255: <Test #x"a100ff" 255>
|
int255: <Test #x"a100ff" 255>
|
||||||
int256: <Test #x"a10100" 256>
|
int256: <Test #x"a10100" 256>
|
||||||
|
@ -112,6 +141,8 @@
|
||||||
list8: @"Missing close bracket" <ParseShort "[">
|
list8: @"Missing close bracket" <ParseShort "[">
|
||||||
list9: @"Unexpected close bracket" <ParseError "]">
|
list9: @"Unexpected close bracket" <ParseError "]">
|
||||||
list10: @"Missing end byte" <DecodeShort #x"b58080">
|
list10: @"Missing end byte" <DecodeShort #x"b58080">
|
||||||
|
list11: <Test #x"b59184" [01]>
|
||||||
|
list12: <Test #x"b59c84" [12]>
|
||||||
noinput0: @"No input at all" <DecodeEOF #x"">
|
noinput0: @"No input at all" <DecodeEOF #x"">
|
||||||
embed0: <Test #x"8690" #!0>
|
embed0: <Test #x"8690" #!0>
|
||||||
embed1: <Test #x"868690" #!#!0>
|
embed1: <Test #x"868690" #!#!0>
|
||||||
|
@ -138,17 +169,22 @@
|
||||||
string5: <Test #x"b104f09d849e" "\uD834\uDD1E">
|
string5: <Test #x"b104f09d849e" "\uD834\uDD1E">
|
||||||
symbol0: <Test #x"b300" ||>
|
symbol0: <Test #x"b300" ||>
|
||||||
symbol2: <Test #x"b30568656c6c6f" hello>
|
symbol2: <Test #x"b30568656c6c6f" hello>
|
||||||
|
symbol3: <Test #x"b305312d322d33" 1-2-3>
|
||||||
|
symbol4: <Test #x"b305612d622d63" a-b-c>
|
||||||
|
symbol5: <Test #x"b305612b622b63" a+b+c>
|
||||||
|
symbol6: <Test #x"b3012b" +>
|
||||||
|
symbol7: <Test #x"b3032b2b2b" +++>
|
||||||
|
symbol8: <Test #x"b3012d" ->
|
||||||
|
symbol9: <Test #x"b3032d2d2d" --->
|
||||||
|
symbol10: <Test #x"b3022d61" -a>
|
||||||
|
symbol11: <Test #x"b3042d2d2d61" ---a>
|
||||||
|
symbol12: <Test #x"b3042d2d2d31" ---1>
|
||||||
|
symbol13: <Test #x"b3042b312e78" +1.x>
|
||||||
tag0: @"Unexpected end tag" <DecodeError #x"84">
|
tag0: @"Unexpected end tag" <DecodeError #x"84">
|
||||||
tag1: @"Invalid tag" <DecodeError #x"10">
|
tag1: @"Invalid tag" <DecodeError #x"10">
|
||||||
tag2: @"Invalid tag" <DecodeError #x"61b10110">
|
tag2: @"Invalid tag" <DecodeError #x"61b10110">
|
||||||
whitespace0: @"Leading spaces have to eventually yield something" <ParseShort " ">
|
whitespace0: @"Leading spaces have to eventually yield something" <ParseShort " ">
|
||||||
whitespace1: @"No input at all" <ParseEOF "">
|
whitespace1: @"No input at all" <ParseEOF "">
|
||||||
value1: <Test #"\xB2\x06corymb" #=#"\xB2\x06corymb">
|
|
||||||
value2: <Test #"\x81" #=#"\x81">
|
|
||||||
value3: <Test #"\x81" #=#[gQ]>
|
|
||||||
value4: <Test #"\x81" #=#[gQ==]>
|
|
||||||
value5: <Test #"\x81" #= #[gQ==]>
|
|
||||||
value6: <Test #x"b591929384" #=#x"b591929384">
|
|
||||||
|
|
||||||
longlist14: <Test #x"b5808080808080808080808080808084"
|
longlist14: <Test #x"b5808080808080808080808080808084"
|
||||||
[#f #f #f #f #f
|
[#f #f #f #f #f
|
||||||
|
|
Loading…
Reference in New Issue