Compare commits
3 Commits
5e1e97e4df
...
2825bceecf
Author | SHA1 | Date |
---|---|---|
Emery Hemingway | 2825bceecf | |
Emery Hemingway | 9134fecb36 | |
Emery Hemingway | c0a8a1a76c |
|
@ -1,6 +1,6 @@
|
||||||
# Package
|
# Package
|
||||||
|
|
||||||
version = "20240118"
|
version = "20240208"
|
||||||
author = "Emery Hemingway"
|
author = "Emery Hemingway"
|
||||||
description = "data model and serialization format"
|
description = "data model and serialization format"
|
||||||
license = "Unlicense"
|
license = "Unlicense"
|
||||||
|
|
|
@ -41,7 +41,7 @@ SimplePattern =
|
||||||
; special builtins: bool, float, double, int, string, bytes, symbol
|
; special builtins: bool, float, double, int, string, bytes, symbol
|
||||||
/ <atom @atomKind AtomKind>
|
/ <atom @atomKind AtomKind>
|
||||||
|
|
||||||
; matches an embedded value in the input: #!p
|
; matches an embedded value in the input: #:p
|
||||||
/ <embedded @interface SimplePattern>
|
/ <embedded @interface SimplePattern>
|
||||||
|
|
||||||
; =symbol, <<lit> any>, or plain non-symbol atom
|
; =symbol, <<lit> any>, or plain non-symbol atom
|
||||||
|
|
|
@ -56,8 +56,7 @@ func isFalse*(pr: Value): bool {.inline.} =
|
||||||
func isFloat*(pr: Value): bool {.inline.} = pr.kind == pkFloat
|
func isFloat*(pr: Value): bool {.inline.} = pr.kind == pkFloat
|
||||||
## Check if ``pr`` is a Preserve float.
|
## Check if ``pr`` is a Preserve float.
|
||||||
|
|
||||||
func isDouble*(pr: Value): bool {.inline.} = pr.kind == pkDouble
|
func isDouble*(pr: Value): bool {.deprecated: "use isFloat".} = pr.kind == pkFloat
|
||||||
## Check if ``pr`` is a Preserve double.
|
|
||||||
|
|
||||||
func isInteger*(pr: Value): bool {.inline.} =
|
func isInteger*(pr: Value): bool {.inline.} =
|
||||||
## Check if ``pr`` is a Preserve integer.
|
## Check if ``pr`` is a Preserve integer.
|
||||||
|
@ -363,10 +362,8 @@ proc toPreserves*[T](x: T): Value {.gcsafe.} =
|
||||||
cannonicalize(result)
|
cannonicalize(result)
|
||||||
elif T is bool:
|
elif T is bool:
|
||||||
result = Value(kind: pkBoolean, bool: x)
|
result = Value(kind: pkBoolean, bool: x)
|
||||||
elif T is float32:
|
elif T is SomeFloat:
|
||||||
result = Value(kind: pkFloat, float: x)
|
result = Value(kind: pkFloat, float: float(x))
|
||||||
elif T is float64:
|
|
||||||
result = Value(kind: pkDouble, double: x)
|
|
||||||
elif T is tuple:
|
elif T is tuple:
|
||||||
result = Value(kind: pkSequence,
|
result = Value(kind: pkSequence,
|
||||||
sequence: newSeqOfCap[Value](tupleLen(T)))
|
sequence: newSeqOfCap[Value](tupleLen(T)))
|
||||||
|
@ -469,8 +466,6 @@ proc toPreservesHook*(a: Atom): Value =
|
||||||
result.bool = a.bool
|
result.bool = a.bool
|
||||||
of pkFloat:
|
of pkFloat:
|
||||||
result.float = a.float
|
result.float = a.float
|
||||||
of pkDouble:
|
|
||||||
result.double = a.double
|
|
||||||
of pkRegister:
|
of pkRegister:
|
||||||
result.register = a.register
|
result.register = a.register
|
||||||
of pkBigInt:
|
of pkBigInt:
|
||||||
|
@ -530,17 +525,10 @@ proc fromAtom*[T](v: var T; a: ATom): bool =
|
||||||
if a.kind == pkByteString:
|
if a.kind == pkByteString:
|
||||||
v = a.bytes
|
v = a.bytes
|
||||||
result = true
|
result = true
|
||||||
elif T is float32:
|
elif T is SomeFloat:
|
||||||
if a.kind == pkFloat:
|
|
||||||
v = a.float
|
|
||||||
result = true
|
|
||||||
elif T is float64:
|
|
||||||
case a.kind
|
case a.kind
|
||||||
of pkFloat:
|
of pkFloat:
|
||||||
v = a.float
|
v = T a.float
|
||||||
result = true
|
|
||||||
of pkDouble:
|
|
||||||
v = a.double
|
|
||||||
result = true
|
result = true
|
||||||
else: discard
|
else: discard
|
||||||
elif T is Ordinal | SomeInteger:
|
elif T is Ordinal | SomeInteger:
|
||||||
|
@ -615,19 +603,10 @@ proc fromPreserves*[T](v: var T; pr: Value): bool {.gcsafe.} =
|
||||||
if not result:
|
if not result:
|
||||||
v.setLen 0
|
v.setLen 0
|
||||||
break
|
break
|
||||||
elif T is float32:
|
elif T is SomeFloat:
|
||||||
if pr.kind == pkFloat:
|
if pr.kind == pkFloat:
|
||||||
v = pr.float
|
v = (T)pr.float
|
||||||
result = true
|
result = true
|
||||||
elif T is float64:
|
|
||||||
case pr.kind
|
|
||||||
of pkFloat:
|
|
||||||
v = pr.float
|
|
||||||
result = true
|
|
||||||
of pkDouble:
|
|
||||||
v = pr.double
|
|
||||||
result = true
|
|
||||||
else: discard
|
|
||||||
elif T is Ordinal | SomeInteger:
|
elif T is Ordinal | SomeInteger:
|
||||||
case pr.kind
|
case pr.kind
|
||||||
of pkRegister:
|
of pkRegister:
|
||||||
|
@ -884,7 +863,7 @@ proc apply*(result: var Value; op: proc(_: var Value) {.gcsafe.}) {.gcsafe.} =
|
||||||
proc recurse(result: var Value) = apply(result, op)
|
proc recurse(result: var Value) = apply(result, op)
|
||||||
op(result)
|
op(result)
|
||||||
case result.kind
|
case result.kind
|
||||||
of pkBoolean, pkFloat, pkDouble, pkRegister, pkBigInt,
|
of pkBoolean, pkFloat, pkRegister, pkBigInt,
|
||||||
pkString, pkByteString, pkSymbol, pkEmbedded:
|
pkString, pkByteString, pkSymbol, pkEmbedded:
|
||||||
discard
|
discard
|
||||||
of pkRecord:
|
of pkRecord:
|
||||||
|
@ -902,7 +881,7 @@ proc apply*(result: var Value; op: proc(_: var Value) {.gcsafe.}) {.gcsafe.} =
|
||||||
proc mapEmbeds*(pr: sink Value; op: proc (x: Value): Value {.gcsafe.}): Value {.gcsafe.} =
|
proc mapEmbeds*(pr: sink Value; op: proc (x: Value): Value {.gcsafe.}): Value {.gcsafe.} =
|
||||||
## Process all embeds in a `Value`.
|
## Process all embeds in a `Value`.
|
||||||
case pr.kind
|
case pr.kind
|
||||||
of pkBoolean, pkFloat, pkDouble, pkRegister, pkBigInt,
|
of pkBoolean, pkFloat, pkRegister, pkBigInt,
|
||||||
pkString, pkByteString, pkSymbol, pkEmbedded:
|
pkString, pkByteString, pkSymbol, pkEmbedded:
|
||||||
result = pr
|
result = pr
|
||||||
of pkRecord:
|
of pkRecord:
|
||||||
|
|
|
@ -41,8 +41,6 @@ proc fromPreservesHook*(js: var JsonNode; pr: Value): bool =
|
||||||
js = newJBool(pr.bool)
|
js = newJBool(pr.bool)
|
||||||
of pkFloat:
|
of pkFloat:
|
||||||
js = newJFloat(pr.float)
|
js = newJFloat(pr.float)
|
||||||
of pkDouble:
|
|
||||||
js = newJFloat(pr.double)
|
|
||||||
of pkRegister:
|
of pkRegister:
|
||||||
js = newJInt(pr.register)
|
js = newJInt(pr.register)
|
||||||
of pkString:
|
of pkString:
|
||||||
|
|
|
@ -15,7 +15,7 @@ grammar "Preserves":
|
||||||
|
|
||||||
Document <- Value * ws * !1
|
Document <- Value * ws * !1
|
||||||
|
|
||||||
Atom <- Boolean | Float | Double | FloatRaw | DoubleRaw | SignedInteger | String | ByteString | Symbol
|
Atom <- Boolean | Double | DoubleRaw | SignedInteger | String | ByteString | Symbol
|
||||||
|
|
||||||
Collection <- Sequence | Dictionary | Set
|
Collection <- Sequence | Dictionary | Set
|
||||||
|
|
||||||
|
@ -40,8 +40,7 @@ grammar "Preserves":
|
||||||
exp <- 'e' * ?('-'|'+') * +Digit
|
exp <- 'e' * ?('-'|'+') * +Digit
|
||||||
flt <- int * ((frac * exp) | frac | exp)
|
flt <- int * ((frac * exp) | frac | exp)
|
||||||
|
|
||||||
Float <- >flt * {'f','F'} * &delimiter
|
Double <- >flt * &delimiter
|
||||||
Double <- flt * &delimiter
|
|
||||||
|
|
||||||
SignedInteger <- int * &delimiter
|
SignedInteger <- int * &delimiter
|
||||||
|
|
||||||
|
@ -69,11 +68,10 @@ grammar "Preserves":
|
||||||
SymbolOrNumber <- >(+(Alpha | Digit | sympunct | symuchar))
|
SymbolOrNumber <- >(+(Alpha | Digit | sympunct | symuchar))
|
||||||
Symbol <- QuotedSymbol | (SymbolOrNumber * &delimiter)
|
Symbol <- QuotedSymbol | (SymbolOrNumber * &delimiter)
|
||||||
|
|
||||||
Embedded <- "#!" * Value
|
Embedded <- "#:" * Value
|
||||||
|
|
||||||
Annotation <- '@' * Value * Value
|
Annotation <- '@' * Value * Value
|
||||||
|
|
||||||
Compact <- "#=" * ws * ByteString
|
Compact <- "#=" * ws * ByteString
|
||||||
|
|
||||||
FloatRaw <- "#xf\"" * >((ws * Xdigit[2])[4]) * ws * '"'
|
|
||||||
DoubleRaw <- "#xd\"" * >((ws * Xdigit[2])[8]) * ws * '"'
|
DoubleRaw <- "#xd\"" * >((ws * Xdigit[2])[8]) * ws * '"'
|
||||||
|
|
|
@ -411,8 +411,7 @@ proc isAny(loc: Location; def: Definition): bool =
|
||||||
proc typeIdent(atom: AtomKind): PNode =
|
proc typeIdent(atom: AtomKind): PNode =
|
||||||
case atom
|
case atom
|
||||||
of AtomKind.Boolean: ident"bool"
|
of AtomKind.Boolean: ident"bool"
|
||||||
of AtomKind.Float: ident"float32"
|
of AtomKind.Double: ident"float"
|
||||||
of AtomKind.Double: ident"float64"
|
|
||||||
of AtomKind.Signedinteger: ident"BiggestInt"
|
of AtomKind.Signedinteger: ident"BiggestInt"
|
||||||
of AtomKind.String: ident"string"
|
of AtomKind.String: ident"string"
|
||||||
of AtomKind.Bytestring: nkBracketExpr.newTree(ident"seq", ident"byte")
|
of AtomKind.Bytestring: nkBracketExpr.newTree(ident"seq", ident"byte")
|
||||||
|
@ -475,7 +474,7 @@ proc toStrLit(loc: Location; sp: SimplePattern): PNode =
|
||||||
result = toStrLit(loc, def)
|
result = toStrLit(loc, def)
|
||||||
of SimplePatternKind.embedded:
|
of SimplePatternKind.embedded:
|
||||||
doAssert not loc.schema.hasEmbeddedType
|
doAssert not loc.schema.hasEmbeddedType
|
||||||
result = PNode(kind: nkStrLit, strVal: "#!" & toStrLit(loc, sp.embedded.interface).strVal)
|
result = PNode(kind: nkStrLit, strVal: "#:" & toStrLit(loc, sp.embedded.interface).strVal)
|
||||||
else: raiseAssert $sp
|
else: raiseAssert $sp
|
||||||
|
|
||||||
proc toFieldIdent(s: string): PNode =
|
proc toFieldIdent(s: string): PNode =
|
||||||
|
@ -931,10 +930,15 @@ proc collectRefImports(imports: var StringSet; loc: Location; pat: Pattern)
|
||||||
|
|
||||||
proc collectRefImports(imports: var StringSet; loc: Location; sp: SimplePattern) =
|
proc collectRefImports(imports: var StringSet; loc: Location; sp: SimplePattern) =
|
||||||
case sp.orKind
|
case sp.orKind
|
||||||
|
of SimplePatternKind.seqof:
|
||||||
|
collectRefImports(imports, loc, sp.seqof.pattern)
|
||||||
of SimplePatternKind.setof:
|
of SimplePatternKind.setof:
|
||||||
incl(imports, "std/sets")
|
incl(imports, "std/sets")
|
||||||
|
collectRefImports(imports, loc, sp.setof.pattern)
|
||||||
of SimplePatternKind.dictof:
|
of SimplePatternKind.dictof:
|
||||||
incl(imports, "std/tables")
|
incl(imports, "std/tables")
|
||||||
|
collectRefImports(imports, loc, sp.dictof.key)
|
||||||
|
collectRefImports(imports, loc, sp.dictof.value)
|
||||||
of SimplePatternKind.Ref:
|
of SimplePatternKind.Ref:
|
||||||
if sp.ref.module != @[] and sp.ref.module != loc.schemaPath:
|
if sp.ref.module != @[] and sp.ref.module != loc.schemaPath:
|
||||||
incl(imports, string sp.ref.module[0])
|
incl(imports, string sp.ref.module[0])
|
||||||
|
|
|
@ -30,19 +30,21 @@ proc decodePreserves*(s: Stream): Value =
|
||||||
result = decodePreserves(s)
|
result = decodePreserves(s)
|
||||||
result.embedded = true
|
result.embedded = true
|
||||||
of 0x87:
|
of 0x87:
|
||||||
|
result = Value(kind: pkFloat)
|
||||||
var N: int
|
var N: int
|
||||||
let n = int s.readUint8()
|
let n = int s.readUint8()
|
||||||
case n
|
case n
|
||||||
of 4:
|
of 4:
|
||||||
result = Value(kind: pkFloat)
|
var
|
||||||
var buf: uint32
|
buf: uint32
|
||||||
|
float: float32
|
||||||
N = s.readData(addr buf, sizeof(buf))
|
N = s.readData(addr buf, sizeof(buf))
|
||||||
bigEndian32(addr result.float, addr buf)
|
bigEndian32(addr float, addr buf)
|
||||||
|
result.float = BiggestFloat float
|
||||||
of 8:
|
of 8:
|
||||||
result = Value(kind: pkDouble)
|
|
||||||
var buf: uint64
|
var buf: uint64
|
||||||
N = s.readData(addr buf, sizeof(buf))
|
N = s.readData(addr buf, sizeof(buf))
|
||||||
bigEndian64(addr result.double, addr buf)
|
bigEndian64(addr result.float, addr buf)
|
||||||
else:
|
else:
|
||||||
raise newException(IOError, "unhandled IEEE754 value of " & $n & " bytes")
|
raise newException(IOError, "unhandled IEEE754 value of " & $n & " bytes")
|
||||||
if N != n: raise newException(IOError, "short read")
|
if N != n: raise newException(IOError, "short read")
|
||||||
|
|
|
@ -21,20 +21,12 @@ proc write*(str: Stream; pr: Value) =
|
||||||
of false: str.write(0x80'u8)
|
of false: str.write(0x80'u8)
|
||||||
of true: str.write(0x81'u8)
|
of true: str.write(0x81'u8)
|
||||||
of pkFloat:
|
of pkFloat:
|
||||||
str.write("\x87\x04")
|
|
||||||
when system.cpuEndian == bigEndian:
|
|
||||||
str.write(pr.float)
|
|
||||||
else:
|
|
||||||
var be: float32
|
|
||||||
swapEndian32(be.addr, pr.float.unsafeAddr)
|
|
||||||
str.write(be)
|
|
||||||
of pkDouble:
|
|
||||||
str.write("\x87\x08")
|
str.write("\x87\x08")
|
||||||
when system.cpuEndian == bigEndian:
|
when system.cpuEndian == bigEndian:
|
||||||
str.write(pr.double)
|
str.write(pr.double)
|
||||||
else:
|
else:
|
||||||
var be: float64
|
var be: float64
|
||||||
swapEndian64(be.addr, pr.double.unsafeAddr)
|
swapEndian64(be.addr, pr.float.unsafeAddr)
|
||||||
str.write(be)
|
str.write(be)
|
||||||
of pkRegister:
|
of pkRegister:
|
||||||
if pr.register == 0: str.write("\xb0\x00")
|
if pr.register == 0: str.write("\xb0\x00")
|
||||||
|
|
|
@ -155,23 +155,13 @@ proc parsePreserves*(text: string): Value =
|
||||||
of "#t": pushStack Value(kind: pkBoolean, bool: true)
|
of "#t": pushStack Value(kind: pkBoolean, bool: true)
|
||||||
else: discard
|
else: discard
|
||||||
|
|
||||||
Preserves.Float <- Preserves.Float:
|
|
||||||
pushStack Value(kind: pkFloat, float: parseFloat($1))
|
|
||||||
|
|
||||||
Preserves.Double <- Preserves.Double:
|
Preserves.Double <- Preserves.Double:
|
||||||
pushStack Value(kind: pkDouble)
|
pushStack Value(kind: pkFloat, float: parseFloat($1))
|
||||||
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:
|
Preserves.DoubleRaw <- Preserves.DoubleRaw:
|
||||||
var reg: uint64
|
var reg: uint64
|
||||||
for c in $1: pushHexNibble(reg, c)
|
for c in $1: pushHexNibble(reg, c)
|
||||||
pushStack Value(kind: pkDouble, double: cast[float64](reg))
|
pushStack Value(kind: pkFloat, float: cast[float64](reg))
|
||||||
|
|
||||||
Preserves.SignedInteger <- Preserves.SignedInteger:
|
Preserves.SignedInteger <- Preserves.SignedInteger:
|
||||||
var
|
var
|
||||||
|
@ -230,7 +220,7 @@ proc parsePreservesAtom*(text: string): Atom =
|
||||||
let pegParser = peg("Atom", a: Atom):
|
let pegParser = peg("Atom", a: Atom):
|
||||||
# Override rules from pegs.nim
|
# Override rules from pegs.nim
|
||||||
|
|
||||||
Atom <- ?"#!" * Preserves.Atom
|
Atom <- ?"#:" * Preserves.Atom
|
||||||
|
|
||||||
Preserves.Boolean <- Preserves.Boolean:
|
Preserves.Boolean <- Preserves.Boolean:
|
||||||
case $0
|
case $0
|
||||||
|
@ -239,21 +229,13 @@ proc parsePreservesAtom*(text: string): Atom =
|
||||||
else: discard
|
else: discard
|
||||||
|
|
||||||
Preserves.Float <- Preserves.Float:
|
Preserves.Float <- Preserves.Float:
|
||||||
a = Atom(kind: pkFloat, float: parseFloat($1))
|
a = Atom(kind: pkFloat)
|
||||||
|
validate(parseBiggestFloat($0, a.float) == len($0))
|
||||||
Preserves.Double <- Preserves.Double:
|
|
||||||
a = Atom(kind: pkDouble)
|
|
||||||
discard parseBiggestFloat($0, a.double)
|
|
||||||
|
|
||||||
Preserves.FloatRaw <- Preserves.FloatRaw:
|
Preserves.FloatRaw <- Preserves.FloatRaw:
|
||||||
var reg: uint32
|
|
||||||
for c in $1: pushHexNibble(reg, c)
|
|
||||||
a = Atom(kind: pkFloat, float: cast[float32](reg))
|
|
||||||
|
|
||||||
Preserves.DoubleRaw <- Preserves.DoubleRaw:
|
|
||||||
var reg: uint64
|
var reg: uint64
|
||||||
for c in $1: pushHexNibble(reg, c)
|
for c in $1: pushHexNibble(reg, c)
|
||||||
a = Atom(kind: pkDouble, double: cast[float64](reg))
|
a = Atom(kind: pkFloat, float: cast[float64](reg))
|
||||||
|
|
||||||
Preserves.SignedInteger <- Preserves.SignedInteger:
|
Preserves.SignedInteger <- Preserves.SignedInteger:
|
||||||
var
|
var
|
||||||
|
|
|
@ -44,7 +44,7 @@ proc writeSymbol(stream: Stream; sym: string) =
|
||||||
|
|
||||||
proc writeText*(stream: Stream; pr: Value; mode = textPreserves) =
|
proc writeText*(stream: Stream; pr: Value; mode = textPreserves) =
|
||||||
## Encode Preserves to a `Stream` as text.
|
## Encode Preserves to a `Stream` as text.
|
||||||
if pr.embedded: write(stream, "#!")
|
if pr.embedded: write(stream, "#:")
|
||||||
case pr.kind:
|
case pr.kind:
|
||||||
of pkBoolean:
|
of pkBoolean:
|
||||||
case pr.bool
|
case pr.bool
|
||||||
|
@ -54,22 +54,9 @@ proc writeText*(stream: Stream; pr: Value; mode = textPreserves) =
|
||||||
case pr.float.classify:
|
case pr.float.classify:
|
||||||
of fcNormal, fcZero, fcNegZero:
|
of fcNormal, fcZero, fcNegZero:
|
||||||
write(stream, $pr.float)
|
write(stream, $pr.float)
|
||||||
write(stream, 'f')
|
|
||||||
else:
|
|
||||||
var buf: array[4, byte]
|
|
||||||
bigEndian32(addr buf[0], addr pr.float)
|
|
||||||
write(stream, "#xf\"")
|
|
||||||
for b in buf:
|
|
||||||
write(stream, hexAlphabet[b shr 4])
|
|
||||||
write(stream, hexAlphabet[b and 0xf])
|
|
||||||
write(stream, '"')
|
|
||||||
of pkDouble:
|
|
||||||
case pr.double.classify:
|
|
||||||
of fcNormal, fcZero, fcNegZero:
|
|
||||||
write(stream, $pr.double)
|
|
||||||
else:
|
else:
|
||||||
var buf: array[8, byte]
|
var buf: array[8, byte]
|
||||||
bigEndian64(addr buf[0], addr pr.double)
|
bigEndian64(addr buf[0], addr pr.float)
|
||||||
write(stream, "#xd\"")
|
write(stream, "#xd\"")
|
||||||
for b in buf:
|
for b in buf:
|
||||||
write(stream, hexAlphabet[b shr 4])
|
write(stream, hexAlphabet[b shr 4])
|
||||||
|
@ -152,7 +139,7 @@ proc writeText*(stream: Stream; pr: Value; mode = textPreserves) =
|
||||||
writeText(stream, value, mode)
|
writeText(stream, value, mode)
|
||||||
write(stream, '}')
|
write(stream, '}')
|
||||||
of pkEmbedded:
|
of pkEmbedded:
|
||||||
if not pr.embedded: write(stream, "#!")
|
if not pr.embedded: write(stream, "#:")
|
||||||
if pr.embeddedRef.isNil:
|
if pr.embeddedRef.isNil:
|
||||||
write(stream, "<null>")
|
write(stream, "<null>")
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -7,11 +7,11 @@ import bigints
|
||||||
|
|
||||||
type
|
type
|
||||||
PreserveKind* = enum
|
PreserveKind* = enum
|
||||||
pkBoolean, pkFloat, pkDouble, pkRegister, pkBigInt, pkString, pkByteString, pkSymbol,
|
pkBoolean, pkFloat, pkRegister, pkBigInt, pkString, pkByteString, pkSymbol,
|
||||||
pkRecord, pkSequence, pkSet, pkDictionary, pkEmbedded
|
pkRecord, pkSequence, pkSet, pkDictionary, pkEmbedded
|
||||||
|
|
||||||
const
|
const
|
||||||
atomKinds* = {pkBoolean, pkFloat, pkDouble, pkRegister, pkBigInt, pkString, pkByteString, pkSymbol}
|
atomKinds* = {pkBoolean, pkFloat, pkRegister, pkBigInt, pkString, pkByteString, pkSymbol}
|
||||||
compoundKinds* = {pkRecord, pkSequence, pkSet, pkDictionary}
|
compoundKinds* = {pkRecord, pkSequence, pkSet, pkDictionary}
|
||||||
|
|
||||||
type Symbol* = distinct string
|
type Symbol* = distinct string
|
||||||
|
@ -28,9 +28,7 @@ type
|
||||||
of pkBoolean:
|
of pkBoolean:
|
||||||
bool*: bool
|
bool*: bool
|
||||||
of pkFloat:
|
of pkFloat:
|
||||||
float*: float32
|
float*: float
|
||||||
of pkDouble:
|
|
||||||
double*: float64
|
|
||||||
of pkRegister:
|
of pkRegister:
|
||||||
register*: int
|
register*: int
|
||||||
of pkBigInt:
|
of pkBigInt:
|
||||||
|
@ -49,9 +47,7 @@ type
|
||||||
of pkBoolean:
|
of pkBoolean:
|
||||||
bool*: bool
|
bool*: bool
|
||||||
of pkFloat:
|
of pkFloat:
|
||||||
float*: float32
|
float*: float
|
||||||
of pkDouble:
|
|
||||||
double*: float64
|
|
||||||
of pkRegister:
|
of pkRegister:
|
||||||
register*: int
|
register*: int
|
||||||
of pkBigInt:
|
of pkBigInt:
|
||||||
|
@ -97,8 +93,6 @@ func `==`*(x, y: Value): bool =
|
||||||
result = x.bool == y.bool
|
result = x.bool == y.bool
|
||||||
of pkFloat:
|
of pkFloat:
|
||||||
result = x.float === y.float
|
result = x.float === y.float
|
||||||
of pkDouble:
|
|
||||||
result = x.double === y.double
|
|
||||||
of pkRegister:
|
of pkRegister:
|
||||||
result = x.register == y.register
|
result = x.register == y.register
|
||||||
of pkBigInt:
|
of pkBigInt:
|
||||||
|
@ -151,8 +145,6 @@ proc `<`*(x, y: Value): bool =
|
||||||
result = (not x.bool) and y.bool
|
result = (not x.bool) and y.bool
|
||||||
of pkFloat:
|
of pkFloat:
|
||||||
result = x.float < y.float
|
result = x.float < y.float
|
||||||
of pkDouble:
|
|
||||||
result = x.double < y.double
|
|
||||||
of pkRegister:
|
of pkRegister:
|
||||||
result = x.register < y.register
|
result = x.register < y.register
|
||||||
of pkBigInt:
|
of pkBigInt:
|
||||||
|
@ -206,8 +198,6 @@ proc hash*(pr: Value): Hash =
|
||||||
h = h !& hash(pr.bool)
|
h = h !& hash(pr.bool)
|
||||||
of pkFloat:
|
of pkFloat:
|
||||||
h = h !& hash(pr.float)
|
h = h !& hash(pr.float)
|
||||||
of pkDouble:
|
|
||||||
h = h !& hash(pr.double)
|
|
||||||
of pkRegister:
|
of pkRegister:
|
||||||
h = h !& hash(pr.register)
|
h = h !& hash(pr.register)
|
||||||
of pkBigInt:
|
of pkBigInt:
|
||||||
|
|
|
@ -54,10 +54,9 @@ type
|
||||||
`ref`*: Ref
|
`ref`*: Ref
|
||||||
|
|
||||||
|
|
||||||
Definitions* = Table[Symbol, Definition]
|
|
||||||
`AtomKind`* {.preservesOr, pure.} = enum
|
`AtomKind`* {.preservesOr, pure.} = enum
|
||||||
`Boolean`, `Float`, `Double`, `SignedInteger`, `String`, `ByteString`,
|
`Boolean`, `Double`, `SignedInteger`, `String`, `ByteString`, `Symbol`
|
||||||
`Symbol`
|
Definitions* = Table[Symbol, Definition]
|
||||||
DictionaryEntries* = Table[Value, NamedSimplePattern]
|
DictionaryEntries* = Table[Value, NamedSimplePattern]
|
||||||
NamedPatternKind* {.pure.} = enum
|
NamedPatternKind* {.pure.} = enum
|
||||||
`named`, `anonymous`
|
`named`, `anonymous`
|
||||||
|
|
|
@ -128,7 +128,6 @@ const parser = peg("Schema", p: ParseState):
|
||||||
|
|
||||||
AltLiteralPattern <-
|
AltLiteralPattern <-
|
||||||
>Preserves.Boolean |
|
>Preserves.Boolean |
|
||||||
>Preserves.Float |
|
|
||||||
>Preserves.Double |
|
>Preserves.Double |
|
||||||
>Preserves.SignedInteger |
|
>Preserves.SignedInteger |
|
||||||
>Preserves.String |
|
>Preserves.String |
|
||||||
|
@ -161,14 +160,11 @@ const parser = peg("Schema", p: ParseState):
|
||||||
AnyPattern <- "any":
|
AnyPattern <- "any":
|
||||||
pushStack toSymbol"any"
|
pushStack toSymbol"any"
|
||||||
|
|
||||||
AtomKindPattern <- Boolean | Float | Double | SignedInteger | String | ByteString | Symbol
|
AtomKindPattern <- Boolean | Double | SignedInteger | String | ByteString | Symbol
|
||||||
|
|
||||||
Boolean <- "bool":
|
Boolean <- "bool":
|
||||||
pushStack initRecord(toSymbol"atom", toSymbol"Boolean")
|
pushStack initRecord(toSymbol"atom", toSymbol"Boolean")
|
||||||
|
|
||||||
Float <- "float":
|
|
||||||
pushStack initRecord(toSymbol"atom", toSymbol"Float")
|
|
||||||
|
|
||||||
Double <- "double":
|
Double <- "double":
|
||||||
pushStack initRecord(toSymbol"atom", toSymbol"Double")
|
pushStack initRecord(toSymbol"atom", toSymbol"Double")
|
||||||
|
|
||||||
|
@ -184,7 +180,7 @@ const parser = peg("Schema", p: ParseState):
|
||||||
Symbol <- "symbol":
|
Symbol <- "symbol":
|
||||||
pushStack initRecord(toSymbol"atom", toSymbol"Symbol")
|
pushStack initRecord(toSymbol"atom", toSymbol"Symbol")
|
||||||
|
|
||||||
EmbeddedPattern <- "#!" * SimplePattern:
|
EmbeddedPattern <- "#:" * SimplePattern:
|
||||||
var n = initRecord(toSymbol"embedded", popStack())
|
var n = initRecord(toSymbol"embedded", popStack())
|
||||||
pushStack n
|
pushStack n
|
||||||
|
|
||||||
|
@ -283,7 +279,6 @@ const parser = peg("Schema", p: ParseState):
|
||||||
|
|
||||||
nonSymbolAtom <-
|
nonSymbolAtom <-
|
||||||
Preserves.Boolean |
|
Preserves.Boolean |
|
||||||
Preserves.Float |
|
|
||||||
Preserves.Double |
|
Preserves.Double |
|
||||||
Preserves.SignedInteger |
|
Preserves.SignedInteger |
|
||||||
Preserves.String |
|
Preserves.String |
|
||||||
|
|
|
@ -14,7 +14,7 @@ proc toPreservesFromString*(s: string): Value =
|
||||||
else:
|
else:
|
||||||
var
|
var
|
||||||
n: BiggestInt
|
n: BiggestInt
|
||||||
f: BiggestFloat
|
f: float
|
||||||
if parseBiggestInt(s, n) == s.len:
|
if parseBiggestInt(s, n) == s.len:
|
||||||
result = toPreserves(n)
|
result = toPreserves(n)
|
||||||
elif parseHex(s, n) == s.len:
|
elif parseHex(s, n) == s.len:
|
||||||
|
|
|
@ -23,7 +23,7 @@ suite "conversions":
|
||||||
c = Foobar(a: 1, b: @[2], c: ("ku", ), e: some(true))
|
c = Foobar(a: 1, b: @[2], c: ("ku", ), e: some(true))
|
||||||
b = toPreserves(c)
|
b = toPreserves(c)
|
||||||
a = preservesTo(b, Foobar)
|
a = preservesTo(b, Foobar)
|
||||||
check($b == """{a: 1 b: [2] c: #!["ku"] e: #t}""")
|
check($b == """{a: 1 b: [2] c: #:["ku"] e: #t}""")
|
||||||
check(a.isSome)
|
check(a.isSome)
|
||||||
if a.isSome: check(get(a) == c)
|
if a.isSome: check(get(a) == c)
|
||||||
check(b.kind == pkDictionary)
|
check(b.kind == pkDictionary)
|
||||||
|
|
|
@ -16,7 +16,6 @@ const examples = [
|
||||||
("""0""", "\xB0\x00"),
|
("""0""", "\xB0\x00"),
|
||||||
("""1""", "\xB0\x01\x01"),
|
("""1""", "\xB0\x01\x01"),
|
||||||
("""255""", "\xB0\x02\x00\xFF"),
|
("""255""", "\xB0\x02\x00\xFF"),
|
||||||
("""1.0f""", "\x87\x04\x3F\x80\x00\x00"),
|
|
||||||
("""1.0""", "\x87\x08\x3F\xF0\x00\x00\x00\x00\x00\x00"),
|
("""1.0""", "\x87\x08\x3F\xF0\x00\x00\x00\x00\x00\x00"),
|
||||||
("""-1.202e300""", "\x87\x08\xFE\x3C\xB7\xB7\x59\xBF\x04\x26"),
|
("""-1.202e300""", "\x87\x08\xFE\x3C\xB7\xB7\x59\xBF\x04\x26"),
|
||||||
("""#=#x"B4B30763617074757265B4B307646973636172648484"""", "\xB4\xB3\x07capture\xB4\xB3\x07discard\x84\x84"),
|
("""#=#x"B4B30763617074757265B4B307646973636172648484"""", "\xB4\xB3\x07capture\xB4\xB3\x07discard\x84\x84"),
|
||||||
|
|
Loading…
Reference in New Issue