diff --git a/src/preserves.nim b/src/preserves.nim index 837a92d..7f09b3b 100644 --- a/src/preserves.nim +++ b/src/preserves.nim @@ -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]`.