Add raw floats and doubles to parser
This commit is contained in:
parent
82631b1a01
commit
dbe9f3566f
|
@ -1,6 +1,6 @@
|
|||
# Package
|
||||
|
||||
version = "20231219"
|
||||
version = "20231220"
|
||||
author = "Emery Hemingway"
|
||||
description = "data model and serialization format"
|
||||
license = "Unlicense"
|
||||
|
|
|
@ -9,6 +9,8 @@ when defined(nimHasUsed): {.used.}
|
|||
|
||||
grammar "Preserves":
|
||||
|
||||
ws <- *(' ' | '\t' | '\r' | '\n' | ',')
|
||||
|
||||
Document <- Value * ws * !1
|
||||
|
||||
Value <-
|
||||
|
@ -18,7 +20,7 @@ grammar "Preserves":
|
|||
|
||||
Collection <- Sequence | Dictionary | Set
|
||||
|
||||
Atom <- Boolean | Float | Double | SignedInteger | String | ByteString | Symbol
|
||||
Atom <- Boolean | Float | Double | FloatRaw | DoubleRaw | SignedInteger | String | ByteString | Symbol
|
||||
|
||||
Record <- '<' * Value * *Value * ws * '>'
|
||||
|
||||
|
@ -30,29 +32,28 @@ grammar "Preserves":
|
|||
|
||||
Boolean <- "#f" | "#t"
|
||||
|
||||
Float <- >flt * 'f'
|
||||
Double <- flt
|
||||
SignedInteger <- int
|
||||
|
||||
nat <- '0' | (Digit-'0') * *Digit
|
||||
int <- ?'-' * nat
|
||||
frac <- '.' * +Digit
|
||||
exp <- 'e' * ?('-'|'+') * +Digit
|
||||
flt <- int * ((frac * exp) | frac | exp)
|
||||
|
||||
Float <- >flt * 'f'
|
||||
Double <- flt
|
||||
|
||||
SignedInteger <- int
|
||||
|
||||
char <- unescaped | '|' | (escape * (escaped | '"' | ('u' * Xdigit[4])))
|
||||
String <- '"' * >(*char) * '"'
|
||||
|
||||
ByteString <- charByteString | hexByteString | b64ByteString
|
||||
charByteString <- "#\"" * >(*binchar) * '"'
|
||||
hexByteString <- "#x\"" * ws * >(*(Xdigit[2] * ws)) * '"'
|
||||
b64ByteString <- "#[" * ws * >(*(base64char * ws)) * ']'
|
||||
hexByteString <- "#x\"" * >(*(ws * Xdigit[2])) * ws * '"'
|
||||
base64char <- {'A'..'Z', 'a'..'z', '0'..'9', '+', '/', '-', '_', '='}
|
||||
b64ByteString <- "#[" * >(*(ws * base64char)) * ws * ']'
|
||||
|
||||
binchar <- binunescaped | (escape * (escaped | '"' | ('x' * Xdigit[2])))
|
||||
binunescaped <- {' '..'!', '#'..'[', ']'..'~'}
|
||||
base64char <- {'A'..'Z', 'a'..'z', '0'..'9', '+', '/', '-', '_', '='}
|
||||
|
||||
Symbol <- >(symstart * *symcont) | ('|' * >(*symchar) * '|')
|
||||
|
||||
symstart <- Alpha | sympunct | symustart
|
||||
symcont <- Alpha | sympunct | symustart | symucont | Digit | '-'
|
||||
|
@ -61,6 +62,7 @@ grammar "Preserves":
|
|||
symustart <- utf8.any - {0..127}
|
||||
symucont <- utf8.any - {0..127}
|
||||
# TODO: exclude some unicode ranges
|
||||
Symbol <- >(symstart * *symcont) | ('|' * >(*symchar) * '|')
|
||||
|
||||
Embedded <- "#!" * Value
|
||||
|
||||
|
@ -73,4 +75,5 @@ grammar "Preserves":
|
|||
escaped <- {'\\', '/', 'b', 'f', 'n', 'r', 't'}
|
||||
escape <- '\\'
|
||||
|
||||
ws <- *(' ' | '\t' | '\r' | '\n' | ',')
|
||||
FloatRaw <- "#xf\"" * >((ws * Xdigit[2])[4]) * ws * '"'
|
||||
DoubleRaw <- "#xd\"" * >((ws * Xdigit[2])[8]) * ws * '"'
|
||||
|
|
|
@ -74,6 +74,14 @@ template unescape(buf: var seq[byte]; capture: string) =
|
|||
add(buf, byte capture[i])
|
||||
inc(i)
|
||||
|
||||
proc pushHexNibble[T](result: var T; c: char) =
|
||||
var n = case c
|
||||
of '0'..'9': T(ord(c) - ord('0'))
|
||||
of 'a'..'f': T(ord(c) - ord('a') + 10)
|
||||
of 'A'..'F': T(ord(c) - ord('A') + 10)
|
||||
else: 0
|
||||
result = (result shl 4) or n
|
||||
|
||||
proc parsePreserves*(text: string): Preserve[void] =
|
||||
## Parse a text-encoded Preserves `string` to a `Preserve` value.
|
||||
runnableExamples:
|
||||
|
@ -138,6 +146,16 @@ proc parsePreserves*(text: string): Preserve[void] =
|
|||
let i = stack.high
|
||||
discard parseBiggestFloat($0, stack[i].value.double)
|
||||
|
||||
Preserves.FloatRaw <- Preserves.FloatRaw:
|
||||
var reg: uint32
|
||||
for c in $1: pushHexNibble(reg, c)
|
||||
pushStack Value(kind: pkFloat, float: cast[float32](reg))
|
||||
|
||||
Preserves.DoubleRaw <- Preserves.DoubleRaw:
|
||||
var reg: uint64
|
||||
for c in $1: pushHexNibble(reg, c)
|
||||
pushStack Value(kind: pkDouble, double: cast[float64](reg))
|
||||
|
||||
Preserves.SignedInteger <- Preserves.SignedInteger:
|
||||
pushStack Value(kind: pkSignedInteger, int: parseInt($0))
|
||||
|
||||
|
|
Loading…
Reference in New Issue