Port preserves_schema_nim to Nim-2.0.0

This commit is contained in:
Emery Hemingway 2023-08-05 20:22:43 +01:00
parent b563de9ac4
commit ec77872467
3 changed files with 87 additions and 93 deletions

View File

@ -11,4 +11,4 @@ bin = @["preserves/preserves_schema_nim", "preserves/private/preserves
# Dependencies
requires "nim >= 1.4.8", "compiler >= 1.4.8", "npeg"
requires "nim >= 2.0.0", "compiler >= 1.4.8", "npeg"

View File

@ -8,6 +8,7 @@
import std/[hashes, strutils, sets, tables]
# Cannot use std/macros, must uss compiler because we are generating code at run-time.
import compiler/[ast, idents, renderer, lineinfos]
import ../preserves, ./schema
@ -37,14 +38,6 @@ proc add(parent: PNode; children: varargs[PNode]): PNode {.discardable.} =
parent.sons.add children
parent
proc nn(kind: TNodeKind; children: varargs[PNode]): PNode =
result = newNode(kind)
result.sons.add(children)
proc nn(kind: TNodeKind; child: PNode): PNode =
result = newNode(kind)
result.sons.add(child)
proc ident(s: string): PNode =
newIdentNode(PIdent(s: s), TLineInfo())
@ -112,7 +105,7 @@ proc addAttrs(x: var TypeSpec; y: TypeSpec) =
proc dotExtend(result: var PNode; label: string) =
var id = ident(label)
if result.isNil: result = id
else: result = nn(nkDotExpr, result, id)
else: result = nkDotExpr.newTree(result, id)
proc ident(`ref`: Ref): PNode =
for m in `ref`.module: dotExtend(result, string m)
@ -147,13 +140,13 @@ proc embeddedIdent(scm: Schema): PNode =
proc preserveIdent(scm: Schema): Pnode =
if scm.hasEmbeddedType:
nn(nkBracketExpr, ident"Preserve", embeddedIdent(scm))
nkBracketExpr.newTree(ident"Preserve", embeddedIdent(scm))
else:
nn(nkBracketExpr, ident"Preserve", ident"void")
nkBracketExpr.newTree(ident"Preserve", ident"void")
proc parameterize(scm: Schema; node: PNode; embeddable: bool): PNode =
if embeddable and node.kind notin {nkBracketExpr}:
nn(nkBracketExpr, node, scm.embeddedIdent)
nkBracketExpr.newTree(node, scm.embeddedIdent)
else: node
proc parameterize(scm: Schema; spec: TypeSpec): PNode =
@ -346,7 +339,7 @@ proc typeIdent(atom: AtomKind): PNode =
of AtomKind.Double: ident"float64"
of AtomKind.Signedinteger: ident"BiggestInt"
of AtomKind.String: ident"string"
of AtomKind.Bytestring: nn(nkBracketExpr, ident"seq", ident"byte")
of AtomKind.Bytestring: nkBracketExpr.newTree(ident"seq", ident"byte")
of AtomKind.Symbol: ident"Symbol"
proc typeIdent(loc: Location; sp: SimplePattern): TypeSpec =
@ -356,19 +349,19 @@ proc typeIdent(loc: Location; sp: SimplePattern): TypeSpec =
result = TypeSpec(node: typeIdent(sp.atom.atomKind))
of SimplepatternKind.seqof:
result = typeIdent(loc, sp.seqof.pattern)
result.node = nn(nkBracketExpr, ident"seq", result.node)
result.node = nkBracketExpr.newTree(ident"seq", result.node)
of SimplepatternKind.setof:
result = typeIdent(loc, sp.setof.pattern)
result.node =
if isSymbolEnum(loc, sp.setof.pattern):
nn(nkBracketExpr, ident"set", result.node)
nkBracketExpr.newTree(ident"set", result.node)
else:
nn(nkBracketExpr, ident"HashSet", result.node)
nkBracketExpr.newTree(ident"HashSet", result.node)
of SimplepatternKind.dictof:
let
key = typeIdent(loc, sp.dictof.key)
val = typeIdent(loc, sp.dictof.value)
result.node = nn(nkBracketExpr, ident"Table", key.node, val.node)
result.node = nkBracketExpr.newTree(ident"Table", key.node, val.node)
result.attrs = key.attrs + val.attrs
of SimplepatternKind.Ref:
result = TypeSpec(node: ident(sp.ref), attrs: attrs(loc, sp))
@ -411,15 +404,15 @@ proc toStrLit(loc: Location; sp: SimplePattern): PNode =
else: raiseAssert $sp
proc toFieldIdent(s: string): PNode =
nn(nkPostFix, ident("*"), nn(nkAccQuoted, ident(s)))
nkPostFix.newTree(ident("*"), nkAccQuoted.newTree(ident(s)))
proc toFieldIdent(loc: Location, label: string; pat: Pattern): PNode =
result = label.toFieldIdent
if isLiteral(loc, pat):
result = nn(nkPragmaExpr,
result = nkPragmaExpr.newTree(
result,
nn(nkPragma,
nn(nkExprColonExpr,
nkPragma.newTree(
nkExprColonExpr.newTree(
ident"preservesLiteral",
toStrLit(loc, pat.simplePattern))))
@ -427,16 +420,16 @@ proc newEmpty(): PNode = newNode(nkEmpty)
proc embeddingParams(scm: Schema; embeddable: bool): PNode =
if embeddable:
nn(nkGenericParams, nn(nkIdentDefs, embeddedIdent(scm), newEmpty(), newEmpty()))
nkGenericParams.newTree(nkIdentDefs.newTree(embeddedIdent(scm), newEmpty(), newEmpty()))
else:
newEmpty()
proc identDef(scm: Schema; a, b: PNode; embeddable: bool): PNode =
if embeddable and scm.hasEmbeddedType and b.kind notin {nkBracketExpr, nkTupleTy} and
(b.kind != nkIdent or b.ident.s != scm.embeddedIdentString):
nn(nkIdentDefs, a, nn(nkBracketExpr, b, embeddedIdent(scm)), newEmpty())
nkIdentDefs.newTree(a, nkBracketExpr.newTree(b, embeddedIdent(scm)), newEmpty())
else:
nn(nkIdentDefs, a, b, newEmpty())
nkIdentDefs.newTree(a, b, newEmpty())
proc identDef(scm: Schema; l: PNode; ts: TypeSpec): PNode =
identDef(scm, l, ts.node, ts.isEmbedded)
@ -482,45 +475,45 @@ proc typeDef(loc: Location; name: string; pat: Pattern; ty: PNode): PNode =
case pat.compoundPattern.orKind
of CompoundPatternKind.rec:
if isLiteral(loc, pat.compoundPattern.rec.label):
nn(nkTypeDef,
nn(nkPragmaExpr,
nkTypeDef.newTree(
nkPragmaExpr.newTree(
id,
nn(nkPragma,
nn(nkExprColonExpr,
nkPragma.newTree(
nkExprColonExpr.newTree(
ident"preservesRecord",
PNode(kind: nkStrLit, strVal: pat.compoundPattern.rec.label.idStr)))),
embedParams,
ty)
else:
nn(nkTypeDef, name.ident.toExport, embedParams, ty)
nkTypeDef.newTree(name.ident.toExport, embedParams, ty)
of CompoundPatternKind.tuple, CompoundPatternKind.tuplePrefix:
nn(nkTypeDef,
nn(nkPragmaExpr, id, nn(nkPragma, ident"preservesTuple")),
nkTypeDef.newTree(
nkPragmaExpr.newTree(id, nkPragma.newTree(ident"preservesTuple")),
embedParams,
ty)
of CompoundPatternKind.dict:
nn(nkTypeDef,
nn(nkPragmaExpr,
id, nn(nkPragma, ident"preservesDictionary")),
nkTypeDef.newTree(
nkPragmaExpr.newTree(
id, nkPragma.newTree(ident"preservesDictionary")),
embedParams,
ty)
else:
nn(nkTypeDef, name.ident.toExport, embedParams, ty)
nkTypeDef.newTree(name.ident.toExport, embedParams, ty)
proc typeDef(loc: Location; name: string; def: Definition; ty: PNode): PNode =
case def.orKind
of DefinitionKind.or:
let pragma = nn(nkPragma, ident"preservesOr")
let pragma = nkPragma.newTree(ident"preservesOr")
if isSymbolEnum(loc, def):
pragma.add ident"pure"
nn(nkTypeDef,
nn(nkPragmaExpr,
nkTypeDef.newTree(
nkPragmaExpr.newTree(
name.ident.accQuote.toExport,
pragma),
embeddingParams(loc.schema, isEmbedded(loc, def)),
ty)
of DefinitionKind.and:
nn(nkTypeDef,
nkTypeDef.newTree(
name.ident.toExport,
embeddingParams(loc.schema, isEmbedded(loc, def)),
preserveIdent(loc.schema))
@ -539,16 +532,16 @@ proc addField(recList: PNode; loc: Location; known: var TypeTable; sp: SimplePat
scm = loc.schema
id = label.toFieldIdent
if isLiteral(loc, sp):
let id = nn(nkPragmaExpr,
let id = nkPragmaExpr.newTree(
id,
nn(nkPragma,
nn(nkExprColonExpr,
nkPragma.newTree(
nkExprColonExpr.newTree(
ident"preservesLiteral",
toStrLit(loc, sp))))
recList.add identDef(scm, id, TypeSpec(node: ident"tuple[]"))
elif sp.orKind == SimplePatternKind.embedded and not scm.hasEmbeddedType:
let id = nn(nkPragmaExpr,
id, nn(nkPragma, ident"preservesEmbedded"))
let id = nkPragmaExpr.newTree(
id, nkPragma.newTree(ident"preservesEmbedded"))
recList.add identDef(scm, id, nimTypeOf(loc, known, sp))
else:
recList.add identDef(scm, id, nimTypeOf(loc, known, sp))
@ -580,9 +573,9 @@ proc addFields(recList: PNode; loc: Location; known: var TypeTable; cp: Compound
let variableType = nimTypeOf(loc, known, cp.tuplePrefix.variable)
recList.add identDef(
scm,
nn(nkPragmaExpr,
nkPragmaExpr.newTree(
ident(cp.tuplePrefix.variable, parentName).accQuote.toExport,
nn(nkPragma, ident"preservesTupleTail")),
nkPragma.newTree(ident"preservesTupleTail")),
parameterize(scm, variableType),
variableType.isEmbedded)
else: raiseAssert "not adding fields for " #& $cp
@ -618,9 +611,9 @@ proc nimTypeOf(loc: Location; known: var TypeTable; nsp: NamedSimplePattern; nam
proc nimTypeOf(loc: Location; known: var TypeTable; rec: CompoundPatternRec; name: string): TypeSpec =
if isLiteral(loc, rec.label):
result.node = nn(nkObjectTy,
result.node = nkObjectTy.newTree(
newEmpty(), newEmpty(),
nn(nkRecList).addFields(loc, known, rec.fields.pattern, name))
newNode(nkRecList).addFields(loc, known, rec.fields.pattern, name))
else:
result.node = preserveIdent(loc.schema)
@ -629,14 +622,14 @@ proc nimTypeOf(loc: Location; known: var TypeTable; cp: CompoundPattern; name: s
of CompoundPatternKind.`rec`:
result = nimTypeOf(loc, known, cp.rec, name)
of CompoundPatternKind.`tuple`, CompoundPatternKind.`tupleprefix`:
result.node = nn(nkObjectTy,
result.node = nkObjectTy.newTree(
newEmpty(), newEmpty(),
nn(nkRecList).addFields(loc, known, cp, name))
newNode(nkRecList).addFields(loc, known, cp, name))
of CompoundPatternKind.`dict`:
result.node = nn(nkObjectTy, newEmpty(), newEmpty(),
nn(nkRecList).addFields(loc, known, cp.dict.entries, name))
result.node = nkObjectTy.newTree(newEmpty(), newEmpty(),
newNode(nkRecList).addFields(loc, known, cp.dict.entries, name))
if result.node.kind == nkObjectTy and isRecursive(loc, cp):
result.node = nn(nkRefTy, result.node)
result.node = nkRefTy.newTree(result.node)
proc nimTypeOf(loc: Location; known: var TypeTable; pat: Pattern; name: string): TypeSpec =
case pat.orKind
@ -664,10 +657,10 @@ proc nimTypeOf(loc: Location; known: var TypeTable; orDef: DefinitionOr; name: s
enumPath = loc.schemaPath & @[Symbol enumName]
enumIdent = ident(enumName)
if enumPath notin known:
known[enumPath] = nn(nkTypeDef,
nn(nkPragmaExpr,
known[enumPath] = nkTypeDef.newTree(
nkPragmaExpr.newTree(
enumName.ident.toExport,
nn(nkPragma, ident"pure")),
nkPragma.newTree(ident"pure")),
newEmpty(),
toEnumTy())
let recCase = nkRecCase.newNode.add(
@ -676,7 +669,7 @@ proc nimTypeOf(loc: Location; known: var TypeTable; orDef: DefinitionOr; name: s
enumName.ident,
newEmpty()))
template addCase(na: NamedAlternative) =
let branchRecList = nn(nkRecList)
let branchRecList = newNode(nkRecList)
var memberType: TypeSpec
if isLiteral(loc, na.pattern):
memberType.node = ident"bool"
@ -695,23 +688,23 @@ proc nimTypeOf(loc: Location; known: var TypeTable; orDef: DefinitionOr; name: s
addAttrs(result, memberType)
memberType.node = parameterize(
scm, memberType.node, isEmbedded(loc, na.pattern))
branchRecList.add nn(nkIdentDefs,
branchRecList.add nkIdentDefs.newTree(
toFieldIdent(loc, na.variantLabel.normalize, na.pattern),
memberType.node, newEmpty())
recCase.add nn(nkOfBranch,
nn(nkDotExpr,
recCase.add nkOfBranch.newTree(
nkDotExpr.newTree(
enumIdent, na.variantLabel.ident.accQuote),
branchRecList)
addCase(orDef.field0.pattern0)
addCase(orDef.field0.pattern1)
for na in orDef.field0.patternN: addCase(na)
result.node = nn(nkObjectTy,
result.node = nkObjectTy.newTree(
newEmpty(),
newEmpty(),
nn(nkRecList, recCase))
nkRecList.newTree(recCase))
# result.attrs = attrs(loc, orDef)
if result.node.kind == nkObjectTy and (recursive in attrs(loc, orDef)):
result.node = nn(nkRefTy, result.node)
result.node = nkRefTy.newTree(result.node)
proc nimTypeOf(loc: Location; known: var TypeTable; def: Definition; name: string): TypeSpec =
case def.orKind
@ -783,7 +776,7 @@ proc collectRefImports(imports: var StringSet; loc: Location; scm: Schema) =
proc mergeType(x: var PNode; y: PNode) =
if x.isNil: x = y
else: x = nn(nkInfix, ident"|", x, y)
else: x = nkInfix.newTree(ident"|", x, y)
proc hasPrefix(a, b: ModulePath): bool =
for i, e in b:
@ -829,67 +822,67 @@ proc renderNimBundle*(bundle: Bundle): Table[string, string] =
add(imports, ident(module))
if not embeddableType.isNil:
let genericParams =
nn(nkGenericParams, nn(nkIdentDefs, embeddedIdent(scm), newEmpty(), newEmpty()))
procs.add nn(nkProcDef,
nkGenericParams.newTree(nkIdentDefs.newTree(embeddedIdent(scm), newEmpty(), newEmpty()))
procs.add nkProcDef.newTree(
"$".toFieldIdent,
newEmpty(),
genericParams,
nn(nkFormalParams,
nkFormalParams.newTree(
ident"string",
nn(nkIdentDefs,
nkIdentDefs.newTree(
ident"x",
embeddableType,
newEmpty())),
newEmpty(),
newEmpty(),
nn(nkStmtList,
nn(nkCall, ident"$",
nn(nkCall, ident"toPreserve", ident"x", embeddedIdent(scm)))))
procs.add nn(nkProcDef,
nkStmtList.newTree(
nkCall.newTree(ident"$",
nkCall.newTree(ident"toPreserve", ident"x", embeddedIdent(scm)))))
procs.add nkProcDef.newTree(
"encode".ident.toExport,
newEmpty(),
genericParams,
nn(nkFormalParams,
nn(nkBracketExpr, ident"seq", ident"byte"),
nn(nkIdentDefs,
nkFormalParams.newTree(
nkBracketExpr.newTree(ident"seq", ident"byte"),
nkIdentDefs.newTree(
ident"x",
embeddableType,
newEmpty())),
newEmpty(),
newEmpty(),
nn(nkStmtList,
nn(nkCall, ident"encode",
nn(nkCall, ident"toPreserve", ident"x", embeddedIdent(scm)))))
nkStmtList.newTree(
nkCall.newTree(ident"encode",
nkCall.newTree(ident"toPreserve", ident"x", embeddedIdent(scm)))))
if not unembeddableType.isNil:
procs.add nn(nkProcDef,
procs.add nkProcDef.newTree(
"$".toFieldIdent,
newEmpty(),
newEmpty(),
nn(nkFormalParams,
nkFormalParams.newTree(
ident"string",
nn(nkIdentDefs,
nkIdentDefs.newTree(
ident"x",
unembeddableType,
newEmpty())),
newEmpty(),
newEmpty(),
nn(nkStmtList,
nn(nkCall, ident"$",
nn(nkCall, ident"toPreserve", ident"x"))))
procs.add nn(nkProcDef,
nkStmtList.newTree(
nkCall.newTree(ident"$",
nkCall.newTree(ident"toPreserve", ident"x"))))
procs.add nkProcDef.newTree(
"encode".ident.toExport,
newEmpty(),
newEmpty(),
nn(nkFormalParams,
nn(nkBracketExpr, ident"seq", ident"byte"),
nn(nkIdentDefs,
nkFormalParams.newTree(
nkBracketExpr.newTree(ident"seq", ident"byte"),
nkIdentDefs.newTree(
ident"x",
unembeddableType,
newEmpty())),
newEmpty(),
newEmpty(),
nn(nkStmtList,
nn(nkCall, ident"encode", nn(nkCall,
nkStmtList.newTree(
nkCall.newTree(ident"encode", nkCall.newTree(
ident"toPreserve", ident"x"))))
var module = newNode(nkStmtList).add(
imports,
@ -900,7 +893,8 @@ proc renderNimBundle*(bundle: Bundle): Table[string, string] =
if filePath != "": add(filePath, '/')
add(filePath, string p)
add(filePath, ".nim")
result[filePath] = renderTree(module, {renderNone, renderIr})
result[filePath] = renderTree(module, {renderIds, renderSyms, renderIr, renderNonExportedFields, renderExpandUsing})
# not sure what all these flags do
when isMainModule:
import ./schemaparse

View File

@ -1,7 +1,7 @@
# SPDX-FileCopyrightText: 2021 ☭ Emery Hemingway
# SPDX-License-Identifier: Unlicense
import std/[strutils, unittest]
import std/unittest
import preserves
suite "BufferedDecoder":