Be more consistent about sorting dictionary keys

This commit is contained in:
Emery Hemingway 2023-07-23 08:27:01 +01:00
parent 335dcd2987
commit 5fa72cd25b
1 changed files with 9 additions and 5 deletions

View File

@ -195,7 +195,8 @@ proc `<`*[A, B](x: Preserve[A]; y: Preserve[B]): bool =
when (not A is void) and (A is B):
result = x.embed < y.embed
proc cmp*[E](x, y: var Preserve[E]): int =
func cmp*[E](x, y: Preserve[E]): int =
## Compare by Preserves total ordering.
if x == y: 0
elif x < y: -1
else: 1
@ -203,6 +204,10 @@ proc cmp*[E](x, y: var Preserve[E]): int =
proc sort*[E](pr: var Preserve[E]) = sort(pr.sequence, cmp)
## Sort a Preserves array by total ordering.
proc sortDict[E](pr: var Preserve[E]) =
sort(pr.dict) do (x, y: DictEntry[E]) -> int:
cmp(x.key, y.key)
proc cannonicalize*[E](pr: var Preserve[E]) {.gcsafe.} =
## Cannonicalize a compound Preserves value by total ordering.
case pr.kind
@ -214,8 +219,7 @@ proc cannonicalize*[E](pr: var Preserve[E]) {.gcsafe.} =
of pkDictionary:
apply(pr.dict) do (e: var DictEntry[E]):
cannonicalize(e.val)
sort(pr.dict) do (x, y: DictEntry[E]) -> int:
cmp(x.key, y.key)
sortDict(pr)
else:
discard
@ -943,7 +947,7 @@ proc toPreserve*[T](x: T; E = void): Preserve[E] =
var pr = fieldToPreserve(key, val)
applyEmbed(key, pr)
result[toSymbol(key, E)] = pr
cannonicalize(result)
sortDict(result)
else:
{.warning: "failed to preserve object " & $T .}
result = toPreserveHook(x, E)
@ -964,7 +968,7 @@ proc toPreserveHook*[A, B](table: Table[A, B]|TableRef[A, B], E: typedesc): Pres
result = initDictionary(E)
for k, v in table.pairs:
result[toPreserve(k, E)] = toPreserve(v, E)
cannonicalize(result)
sortDict(result)
func containsNativeEmbeds[E](pr: Preserve[E]): bool =
## Check if a `Preserve[E]` is convertible to `Preserve[void]`.