Impement Preserves decoding and encoding in Nim

This commit is contained in:
Emery Hemingway 2024-04-23 14:41:00 +02:00
parent 4b0550b543
commit e572357dcb
2 changed files with 133 additions and 0 deletions

9
min_syndicate.nimble Normal file
View File

@ -0,0 +1,9 @@
# Package
version = "20240423"
author = "Emery Hemingway"
description = "Syndicate bindings for the Min language"
license = "unlicense"
bin = @["mindicate"]
srcDir = "pkg"
requires "min >= 0.40.0", "http://git.syndicate-lang.org/ehmry/syndicate-nim.git >= 20240422"

124
pkg/min_preserves.nim Normal file
View File

@ -0,0 +1,124 @@
# SPDX-FileCopyrightText: ☭ Emery Hemingway
# SPDX-License-Identifier: Unlicense
import
std/critbits,
min,
preserves
proc toMin(i: In; pr: sink Value): MinValue =
case pr.kind
of pkBoolean:
result = pr.bool.newVal
of pkFloat:
result = pr.float.newVal
of pkRegister:
result = pr.register.newVal
of pkBigInt:
raiseAssert "big integers not supported by Min bindings"
of pkString:
result = pr.string.newVal
of pkByteString:
result = newDict(i.scope)
result.objType = "preserves-bytestring"
i.dset(result, "bytes", cast[string](pr.bytes).newVal)
of pkSymbol:
result = pr.symbol.string.newSym
of pkRecord:
result = newDict(i.scope)
result.objType = "preserves-record"
var fields = newSeq[MinValue](pr.record.len.pred)
for j, _ in fields:
fields[j] = i.toMin pr.record[j].move
i.dset(result, "fields", fields.newVal)
i.dset(result, "label", i.toMin pr.record[pr.record.high].move)
of pkSequence:
var entries = newSeq[MinValue](pr.sequence.len)
for j, _ in pr.sequence:
entries[j] = i.toMin pr.sequence[j].move
result = entries.newVal
of pkSet:
result = newDict(i.scope)
result.objType = "preserves-set"
var set = newSeq[MinValue](pr.set.len)
for j, _ in pr.set:
set[j] = i.toMin pr.set[j].move
i.dset(result, "set", set.newVal)
of pkDictionary:
result = newDict(i.scope)
result.objType = "preserves-dictionary"
for (k, v) in pr.dict.mitems:
i.dset(result, i.toMin k.move, i.toMin v.move)
of pkEmbedded:
result = newDict(i.scope)
result.objType = "preserves-embedded"
result.obj = pr.embeddedRef[].addr
proc toPreserves(i: In; val: MinValue): Value =
case val.kind
of minInt:
result = val.intVal.toPreserves
of minFloat:
result = val.floatVal.toPreserves
of minQuotation:
result = initSequence val.qVal.len
for j, v in val.qVal:
result.sequence[j] = i.toPreserves v
of minCommand:
discard
of minDictionary:
case val.objType
of "preserves-record":
let fields = i.dget(val, "fields")
result = initRecord(
i.toPreserves i.dget(val, "label"),
fields.qVal.len,
)
for j, f in fields.qVal:
result.record[j] = i.toPreserves f
of "preserves-set":
result = initSet()
for e in i.dget(val, "set").qVal:
result.incl i.toPreserves e
else:
result = initDictionary()
for k, v in val.dVal.pairs:
result[toSymbol k] = i.toPreserves v.val
of minString:
result = val.strVal.toPreserves
of minSymbol:
result = val.symVal.Symbol.toPreserves
of minNull:
result = initRecord"null"
of minBool:
result = val.boolVal.toPreserves
proc preserves_module*(i: In) =
let def = i.define()
def.symbol("from-preserves") do (i: In):
let vals = i.expect("str")
let s = vals[0].getString()
try:
var pr: Value
if s[0].ord < 0x20:
pr = decodePreserves s
else:
pr = parsePreserves s
i.push(i.toMin pr)
except CatchableError as err:
raiseInvalid(err.msg)
def.symbol("to-text") do (i: In):
let vals = i.expect("a")
var pr = i.toPreserves vals[0]
i.push ($pr).newVal
def.symbol("to-binary") do (i: In):
let vals = i.expect("a")
var pr = i.toPreserves vals[0]
i.push cast[string](pr.encode).newVal
def.finalize("preserves")