Compare commits

...

2 Commits

Author SHA1 Message Date
Emery Hemingway 7187a45f9c Hash nil embedded pointers 2023-11-02 13:33:52 +00:00
Emery Hemingway 0c4ef8269f Add pop for dictionaries 2023-11-02 13:33:47 +00:00
2 changed files with 20 additions and 3 deletions

View File

@ -1,6 +1,6 @@
# Package
version = "20231028"
version = "20231102"
author = "Emery Hemingway"
description = "data model and serialization format"
license = "Unlicense"

View File

@ -223,7 +223,7 @@ proc cannonicalize*[E](pr: var Preserve[E]) =
else:
discard
proc hash*(pr: Preserve): Hash =
proc hash*[E](pr: Preserve[E]): Hash =
## Produce a `Hash` of `pr` for use with a `HashSet` or `Table`.
var h = hash(pr.kind.int) !& hash(pr.embedded)
case pr.kind
@ -254,7 +254,13 @@ proc hash*(pr: Preserve): Hash =
for (key, val) in pr.dict.items:
h = h !& hash(key) !& hash(val)
of pkEmbedded:
when E is void:
h = h !& hash(pr.embed)
else:
if pr.embed.isNil:
h = h !& hash(false)
else:
h = h !& hash(pr.embed)
!$h
proc `[]`*(pr: Preserve; i: int): Preserve =
@ -284,6 +290,18 @@ proc getOrDefault(pr: Preserve; key: Preserve): Preserve =
result = v
break
proc pop*(pr: var Preserve; key: Preserve; val: var Preserve): bool =
## Deletes the `key` from a Preserves dictionary.
## Returns true, if the key existed, and sets `val` to the mapping
## of the key. Otherwise, returns false, and the `val` is unchanged.
if pr.kind == pkDictionary:
var i = 0
while i < pr.dict.len:
if pr.dict[i].key == key:
val = move pr.dict[i].val
delete(pr.dict, i, i)
return true
proc incl*(pr: var Preserve; key: Preserve) =
## Include `key` in the Preserves set `pr`.
for i in 0..pr.set.high:
@ -638,7 +656,6 @@ proc encode*[E](pr: Preserve[E]): seq[byte] =
s.write pr
result = cast[seq[byte]](move s.data)
proc decodePreserves*(s: Stream; E = void): Preserve[E] =
## Decode a Preserves value from a binary-encoded stream.
if s.atEnd: raise newException(IOError, "End of Preserves stream")