Port preserves_schema_nim to Nim-2.0.0
This commit is contained in:
parent
b563de9ac4
commit
ec77872467
|
@ -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"
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# SPDX-FileCopyrightText: 2021 ☭ Emery Hemingway
|
||||
# SPDX-License-Identifier: Unlicense
|
||||
|
||||
import std/[strutils, unittest]
|
||||
import std/unittest
|
||||
import preserves
|
||||
|
||||
suite "BufferedDecoder":
|
||||
|
|
Loading…
Reference in New Issue