Compare commits
4 Commits
9ae435a83c
...
fd498c6457
Author | SHA1 | Date |
---|---|---|
Emery Hemingway | fd498c6457 | |
Emery Hemingway | a83ca8b31c | |
Emery Hemingway | ea698bedcc | |
Emery Hemingway | 8d48ae60e9 |
|
@ -1,6 +1,6 @@
|
||||||
# Package
|
# Package
|
||||||
|
|
||||||
version = "20240312"
|
version = "20240422"
|
||||||
author = "Emery Hemingway"
|
author = "Emery Hemingway"
|
||||||
description = "data model and serialization format"
|
description = "data model and serialization format"
|
||||||
license = "Unlicense"
|
license = "Unlicense"
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# SPDX-FileCopyrightText: ☭ Emery Hemingway
|
# SPDX-FileCopyrightText: ☭ Emery Hemingway
|
||||||
# SPDX-License-Identifier: Unlicense
|
# SPDX-License-Identifier: Unlicense
|
||||||
|
|
||||||
import std/[options, sets, sequtils, strutils, tables, typetraits]
|
import std/[assertions, options, sets, sequtils, strutils, tables, typetraits]
|
||||||
from std/algorithm import sort
|
from std/algorithm import sort
|
||||||
from std/json import escapeJson, escapeJsonUnquoted
|
from std/json import escapeJson, escapeJsonUnquoted
|
||||||
import bigints
|
import bigints
|
||||||
|
@ -335,6 +335,9 @@ template unpreservable*() {.pragma.}
|
||||||
## as its native type.
|
## as its native type.
|
||||||
## Unpreservability is asserted at runtime.
|
## Unpreservability is asserted at runtime.
|
||||||
|
|
||||||
|
converter preserve*(i: SomeInteger): Value =
|
||||||
|
Value(kind: pkRegister, register: BiggestInt i)
|
||||||
|
|
||||||
proc toPreserves*[T](x: T): Value {.gcsafe.} =
|
proc toPreserves*[T](x: T): Value {.gcsafe.} =
|
||||||
## Serializes ``x`` to Preserves. Can be customized by defining
|
## Serializes ``x`` to Preserves. Can be customized by defining
|
||||||
## ``toPreservesHook(x: T; E: typedesc)`` in the calling scope.
|
## ``toPreservesHook(x: T; E: typedesc)`` in the calling scope.
|
||||||
|
@ -565,7 +568,7 @@ proc fromPreserves*[T](v: var T; pr: Value): bool =
|
||||||
type Foo {.preservesRecord: "foo".} = object
|
type Foo {.preservesRecord: "foo".} = object
|
||||||
x, y: int
|
x, y: int
|
||||||
var foo: Foo
|
var foo: Foo
|
||||||
assert(fromPreserve(foo, parsePreserves("""<foo 1 2>""")))
|
assert(fromPreserves(foo, parsePreserves("""<foo 1 2>""")))
|
||||||
assert(foo.x == 1)
|
assert(foo.x == 1)
|
||||||
assert(foo.y == 2)
|
assert(foo.y == 2)
|
||||||
when T is Value:
|
when T is Value:
|
||||||
|
@ -843,9 +846,9 @@ func step*(pr: Value; path: varargs[Value, toPreserves]): Option[Value] =
|
||||||
## Works for sequences, records, and dictionaries.
|
## Works for sequences, records, and dictionaries.
|
||||||
runnableExamples:
|
runnableExamples:
|
||||||
import std/options
|
import std/options
|
||||||
assert step(parsePreserves("""<foo 1 2>"""), 1.toPreserve) == some(2.toPreserve)
|
assert step(parsePreserves("""<foo 1 2>"""), 1.toPreserves) == some(2.toPreserves)
|
||||||
assert step(parsePreserves("""{ foo: 1 bar: 2}"""), "foo".toSymbol) == some(1.toPreserve)
|
assert step(parsePreserves("""{ foo: 1 bar: 2}"""), "foo".toSymbol) == some(1.toPreserves)
|
||||||
assert step(parsePreserves("""[ ]"""), 1.toPreserve) == none(Value)
|
assert step(parsePreserves("""[ ]"""), 1.toPreserves) == none(Value)
|
||||||
result = some(pr)
|
result = some(pr)
|
||||||
for index in path:
|
for index in path:
|
||||||
if result.isSome:
|
if result.isSome:
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# SPDX-FileCopyrightText: ☭ Emery Hemingway
|
# SPDX-FileCopyrightText: ☭ Emery Hemingway
|
||||||
# SPDX-License-Identifier: Unlicense
|
# SPDX-License-Identifier: Unlicense
|
||||||
|
|
||||||
import std/[endians, options, streams, strutils]
|
import std/[assertions, endians, options, streams, strutils]
|
||||||
import bigints
|
import bigints
|
||||||
import ./decoding, ./parsing, ./values
|
import ./decoding, ./parsing, ./values
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# SPDX-FileCopyrightText: ☭ Emery Hemingway
|
# SPDX-FileCopyrightText: ☭ Emery Hemingway
|
||||||
# SPDX-License-Identifier: Unlicense
|
# SPDX-License-Identifier: Unlicense
|
||||||
|
|
||||||
import std/[endians, streams]
|
import std/[assertions, endians, streams]
|
||||||
import bigints
|
import bigints
|
||||||
import ./values
|
import ./values
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
# distribution, for details about the copyright.
|
# distribution, for details about the copyright.
|
||||||
#
|
#
|
||||||
|
|
||||||
import std/macros
|
import std/[assertions, macros]
|
||||||
|
|
||||||
const
|
const
|
||||||
nnkPragmaCallKinds = {nnkExprColonExpr, nnkCall, nnkCallStrLit}
|
nnkPragmaCallKinds = {nnkExprColonExpr, nnkCall, nnkCallStrLit}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# SPDX-FileCopyrightText: ☭ Emery Hemingway
|
# SPDX-FileCopyrightText: ☭ Emery Hemingway
|
||||||
# SPDX-License-Identifier: Unlicense
|
# SPDX-License-Identifier: Unlicense
|
||||||
|
|
||||||
import std/[base64, options, parseutils, strutils, unicode]
|
import std/[assertions, base64, options, parseutils, strutils, unicode]
|
||||||
from std/sequtils import insert
|
from std/sequtils import insert
|
||||||
|
|
||||||
import bigints, npeg
|
import bigints, npeg
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
# SPDX-FileCopyrightText: ☭ Emery Hemingway
|
# SPDX-FileCopyrightText: ☭ Emery Hemingway
|
||||||
# SPDX-License-Identifier: Unlicense
|
# SPDX-License-Identifier: Unlicense
|
||||||
|
|
||||||
import std/[base64, endians, math, sequtils, streams, strutils]
|
import std/[assertions, base64, endians, sequtils, streams, strutils]
|
||||||
|
when not defined(nimNoLibc):
|
||||||
|
import std/math
|
||||||
import bigints
|
import bigints
|
||||||
import ./values
|
import ./values
|
||||||
|
|
||||||
|
@ -42,6 +44,15 @@ proc writeSymbol(stream: Stream; sym: string) =
|
||||||
writeEscaped(stream, sym, '|')
|
writeEscaped(stream, sym, '|')
|
||||||
write(stream, '|')
|
write(stream, '|')
|
||||||
|
|
||||||
|
proc writeFloatBytes(stream: Stream; f: float) =
|
||||||
|
var buf: array[8, byte]
|
||||||
|
bigEndian64(addr buf[0], addr f)
|
||||||
|
write(stream, "#xd\"")
|
||||||
|
for b in buf:
|
||||||
|
write(stream, hexAlphabet[b shr 4])
|
||||||
|
write(stream, hexAlphabet[b and 0xf])
|
||||||
|
write(stream, '"')
|
||||||
|
|
||||||
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, "#:")
|
||||||
|
@ -51,17 +62,14 @@ proc writeText*(stream: Stream; pr: Value; mode = textPreserves) =
|
||||||
of false: write(stream, "#f")
|
of false: write(stream, "#f")
|
||||||
of true: write(stream, "#t")
|
of true: write(stream, "#t")
|
||||||
of pkFloat:
|
of pkFloat:
|
||||||
case pr.float.classify:
|
when defined(nimNoLibc):
|
||||||
of fcNormal, fcZero, fcNegZero:
|
writeFloatBytes(stream, pr.float)
|
||||||
write(stream, $pr.float)
|
# IEE754-to-decimal is non-trivial
|
||||||
else:
|
else:
|
||||||
var buf: array[8, byte]
|
if pr.float.classify in {fcNormal, fcZero, fcNegZero}:
|
||||||
bigEndian64(addr buf[0], addr pr.float)
|
write(stream, $pr.float)
|
||||||
write(stream, "#xd\"")
|
else:
|
||||||
for b in buf:
|
writeFloatBytes(stream, pr.float)
|
||||||
write(stream, hexAlphabet[b shr 4])
|
|
||||||
write(stream, hexAlphabet[b and 0xf])
|
|
||||||
write(stream, '"')
|
|
||||||
of pkRegister:
|
of pkRegister:
|
||||||
write(stream, $pr.register)
|
write(stream, $pr.register)
|
||||||
of pkBigInt:
|
of pkBigInt:
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
# SPDX-FileCopyrightText: ☭ Emery Hemingway
|
# SPDX-FileCopyrightText: ☭ Emery Hemingway
|
||||||
# SPDX-License-Identifier: Unlicense
|
# SPDX-License-Identifier: Unlicense
|
||||||
|
|
||||||
import std/[algorithm, hashes, math, options, sets, sequtils, tables]
|
import std/[algorithm, hashes, options, sets, sequtils, tables]
|
||||||
|
|
||||||
import bigints
|
import bigints
|
||||||
|
|
||||||
type
|
type
|
||||||
|
@ -80,11 +79,6 @@ type
|
||||||
## Object refs embedded in Preserves `Value`s must inherit from `EmbeddedObj`.
|
## Object refs embedded in Preserves `Value`s must inherit from `EmbeddedObj`.
|
||||||
## At the moment this is just an alias to `RootObj` but this may change in the future.
|
## At the moment this is just an alias to `RootObj` but this may change in the future.
|
||||||
|
|
||||||
func `===`[T: SomeFloat](a, b: T): bool =
|
|
||||||
## Compare where Nan == NaN.
|
|
||||||
let class = a.classify
|
|
||||||
(class == b.classify) and ((class notin {fcNormal,fcSubnormal}) or (a == b))
|
|
||||||
|
|
||||||
func `==`*(x, y: Value): bool =
|
func `==`*(x, y: Value): bool =
|
||||||
## Check `x` and `y` for equivalence.
|
## Check `x` and `y` for equivalence.
|
||||||
if x.kind == y.kind and x.embedded == y.embedded:
|
if x.kind == y.kind and x.embedded == y.embedded:
|
||||||
|
@ -92,7 +86,7 @@ func `==`*(x, y: Value): bool =
|
||||||
of pkBoolean:
|
of pkBoolean:
|
||||||
result = x.bool == y.bool
|
result = x.bool == y.bool
|
||||||
of pkFloat:
|
of pkFloat:
|
||||||
result = x.float === y.float
|
result = cast[uint64](x.float) == cast[uint64](y.float)
|
||||||
of pkRegister:
|
of pkRegister:
|
||||||
result = x.register == y.register
|
result = x.register == y.register
|
||||||
of pkBigInt:
|
of pkBigInt:
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
# SPDX-FileCopyrightText: ☭ Emery Hemingway
|
||||||
|
# SPDX-License-Identifier: Unlicense
|
||||||
|
|
||||||
|
import ../preserves, ./private/macros
|
||||||
|
|
||||||
|
proc `%`*(n: SomeInteger): Value {.inline.} = n.toPreserves
|
Loading…
Reference in New Issue