preserves_schema_nim: represent embeds with EmbeddedRef
Use EmbeddedRef for embbeded values, unless a schema does not name an embedded type.
This commit is contained in:
parent
74da21f3d5
commit
416af8ff5f
|
@ -1,6 +1,6 @@
|
|||
# Package
|
||||
|
||||
version = "20240106"
|
||||
version = "20240107"
|
||||
author = "Emery Hemingway"
|
||||
description = "data model and serialization format"
|
||||
license = "Unlicense"
|
||||
|
|
|
@ -6,10 +6,7 @@
|
|||
# the schema module must be regenerated!
|
||||
# nim c --path:../../../nim --path:.. -r ./preserves_schema_nim ../../../preserves/schema/schema.bin
|
||||
|
||||
# This module formally parameterized types wherever embedded values were found.
|
||||
# This is no longer the case but some of that code is lingering around.
|
||||
|
||||
import std/[hashes, strutils, sets, tables]
|
||||
import std/[hashes, sets, strutils, tables]
|
||||
|
||||
# Cannot use std/macros, must use compiler modules because
|
||||
# we are generating code at run-time.
|
||||
|
@ -126,6 +123,23 @@ proc deref(loc: Location; r: Ref): (Location, Definition) =
|
|||
except KeyError:
|
||||
raise newException(KeyError, "reference not found in bundle: " & $r)
|
||||
|
||||
proc hasEmbeddedType(scm: Schema): bool =
|
||||
case scm.field0.embeddedType.orKind
|
||||
of EmbeddedtypenameKind.false: false
|
||||
of EmbeddedtypenameKind.Ref: true
|
||||
|
||||
proc embeddedIdentString(scm: Schema): string =
|
||||
doAssert $scm.field0.embeddedType.ref.name != ""
|
||||
"Value"
|
||||
|
||||
proc embeddedIdent(scm: Schema): PNode =
|
||||
ident(embeddedIdentString(scm))
|
||||
|
||||
proc parameterize(loc: Location; node: PNode; embeddable: bool): PNode = node
|
||||
|
||||
proc parameterize(loc: Location; spec: TypeSpec): PNode =
|
||||
parameterize(loc, spec.node, spec.isEmbedded)
|
||||
|
||||
proc hash(r: Ref): Hash = r.toPreserves.hash
|
||||
type RefSet = HashSet[Ref]
|
||||
|
||||
|
@ -138,8 +152,7 @@ proc attrs(loc: Location; n: NamedAlternative|NamedPattern; seen: RefSet): Attri
|
|||
proc attrs(loc: Location; sp: SimplePattern; seen: RefSet): Attributes =
|
||||
case sp.orKind
|
||||
of SimplepatternKind.atom, SimplepatternKind.lit, SimplepatternKind.any: {}
|
||||
of SimplepatternKind.embedded:
|
||||
attrs(loc, sp.embedded.interface, seen)
|
||||
of SimplepatternKind.embedded: {embedded}
|
||||
of SimplepatternKind.seqof:
|
||||
attrs(loc, sp.seqof.pattern, seen)
|
||||
of SimplepatternKind.setof:
|
||||
|
@ -297,7 +310,8 @@ proc isLiteral(loc: Location; sp: SimplePattern): bool =
|
|||
of SimplepatternKind.lit:
|
||||
result = true
|
||||
of SimplepatternKind.embedded:
|
||||
result = isLiteral(loc, sp.embedded.interface)
|
||||
if not loc.schema.hasEmbeddedType:
|
||||
result = isLiteral(loc, sp.embedded.interface)
|
||||
else: discard
|
||||
|
||||
proc isLiteral(loc: Location; np: NamedPattern): bool =
|
||||
|
@ -436,8 +450,12 @@ proc typeIdent(loc: Location; sp: SimplePattern): TypeSpec =
|
|||
result.attrs = key.attrs + val.attrs
|
||||
of SimplepatternKind.Ref:
|
||||
result = TypeSpec(node: ident(sp.ref), attrs: attrs(loc, sp))
|
||||
result.node = parameterize(loc, result)
|
||||
of SimplepatternKind.embedded:
|
||||
result = typeIdent(loc, sp.embedded.interface)
|
||||
if loc.schema.hasEmbeddedType:
|
||||
result = TypeSpec(node: ident"EmbeddedRef")
|
||||
else:
|
||||
result = TypeSpec(node: ident"Value")
|
||||
incl(result.attrs, embedded)
|
||||
of SimplepatternKind.any, SimplepatternKind.lit:
|
||||
result = TypeSpec(node: ident"Value")
|
||||
|
@ -466,6 +484,7 @@ proc toStrLit(loc: Location; sp: SimplePattern): PNode =
|
|||
var (loc, def) = deref(loc, sp.ref)
|
||||
result = toStrLit(loc, def)
|
||||
of SimplePatternKind.embedded:
|
||||
doAssert not loc.schema.hasEmbeddedType
|
||||
result = PNode(kind: nkStrLit, strVal: "#!" & toStrLit(loc, sp.embedded.interface).strVal)
|
||||
else: raiseAssert $sp
|
||||
|
||||
|
@ -484,6 +503,9 @@ proc toFieldIdent(loc: Location, label: string; pat: Pattern): PNode =
|
|||
|
||||
proc newEmpty(): PNode = newNode(nkEmpty)
|
||||
|
||||
proc embeddingParams(loc: Location; embeddable: bool): PNode =
|
||||
newEmpty()
|
||||
|
||||
proc identDef(scm: Schema; a, b: PNode; embeddable: bool): PNode =
|
||||
nkIdentDefs.newTree(a, b, newEmpty())
|
||||
|
||||
|
@ -534,7 +556,7 @@ proc typeDef(loc: Location; name: string; pat: SimplePattern; ty: PNode): PNode
|
|||
|
||||
proc typeDef(loc: Location; name: string; pat: Pattern; ty: PNode): PNode =
|
||||
let
|
||||
embedParams = newEmpty()
|
||||
embedParams = embeddingParams(loc, isEmbedded(loc, pat))
|
||||
id = name.ident.toExport
|
||||
case pat.orKind
|
||||
of PatternKind.CompoundPattern:
|
||||
|
@ -576,7 +598,7 @@ proc typeDef(loc: Location; name: string; def: Definition; ty: PNode): PNode =
|
|||
nkPragmaExpr.newTree(
|
||||
name.ident.accQuote.toExport,
|
||||
pragma),
|
||||
newEmpty(),
|
||||
embeddingParams(loc, isEmbedded(loc, def)),
|
||||
ty)
|
||||
of DefinitionKind.and:
|
||||
var pragma = nkPragma.newNode
|
||||
|
@ -586,7 +608,7 @@ proc typeDef(loc: Location; name: string; def: Definition; ty: PNode): PNode =
|
|||
nkPragmaExpr.newTree(
|
||||
name.ident.accQuote.toExport,
|
||||
pragma),
|
||||
newEmpty(),
|
||||
embeddingParams(loc, isEmbedded(loc, def)),
|
||||
ty)
|
||||
of DefinitionKind.Pattern:
|
||||
typeDef(loc, name, def.pattern, ty)
|
||||
|
@ -682,7 +704,7 @@ proc addFields(recList: PNode; loc: Location; known: var TypeTable; parentName:
|
|||
nkPragmaExpr.newTree(
|
||||
ident(cp.tuplePrefix.variable, parentName).accQuote.toExport,
|
||||
nkPragma.newTree(ident"preservesTupleTail")),
|
||||
variableType.node,
|
||||
parameterize(loc, variableType),
|
||||
variableType.isEmbedded)
|
||||
of CompoundPatternKind.dict:
|
||||
for nameVal, nsp in cp.dict.entries:
|
||||
|
@ -794,6 +816,8 @@ proc nimTypeOf(loc: Location; known: var TypeTable; name: string; orDef: Definit
|
|||
known[memberPath] =
|
||||
typeDef(loc, memberTypeName, na.pattern, ty.node)
|
||||
addAttrs(result, memberType)
|
||||
memberType.node = parameterize(
|
||||
loc, memberType.node, isEmbedded(loc, na.pattern))
|
||||
branchRecList.add nkIdentDefs.newTree(
|
||||
toFieldIdent(loc, na.variantLabel.normalize, na.pattern),
|
||||
memberType.node, newEmpty())
|
||||
|
@ -982,19 +1006,16 @@ proc renderNimBundle*(bundle: Bundle): Table[string, string] =
|
|||
var
|
||||
typeSection = newNode nkTypeSection
|
||||
procs: seq[PNode]
|
||||
unembeddableType, embeddableType: PNode
|
||||
unembeddableType: PNode
|
||||
for name, def in scm.field0.definitions.pairs:
|
||||
if isLiteral(loc, def):
|
||||
generateConstProcs(procs, scm, string name, def)
|
||||
else:
|
||||
var name = string name
|
||||
name[0] = name[0].toUpperAscii
|
||||
var defIdent = ident(name)
|
||||
var defIdent = parameterize(loc, ident(name), isEmbedded(loc, def))
|
||||
if not isSymbolEnum(loc, def) and not isAny(loc, def):
|
||||
if isEmbedded(loc, def):
|
||||
mergeType(embeddableType, defIdent)
|
||||
else:
|
||||
mergeType(unembeddableType, defIdent)
|
||||
mergeType(unembeddableType, defIdent)
|
||||
let typeSpec = nimTypeOf(loc, typeDefs, name, def)
|
||||
typeDefs[scmPath & @[Symbol name]] = typeDef(loc, name, def, typeSpec.node)
|
||||
generateProcs(procs, scm, name, def)
|
||||
|
@ -1003,45 +1024,12 @@ proc renderNimBundle*(bundle: Bundle): Table[string, string] =
|
|||
if typepath.hasPrefix(scmPath):
|
||||
add(typeSection, typeDef)
|
||||
|
||||
|
||||
let imports = nkImportStmt.newNode.add(ident"preserves")
|
||||
block:
|
||||
var importSet: HashSet[string]
|
||||
collectRefImports(importSet, loc, scm)
|
||||
for module in importSet:
|
||||
add(imports, ident(module))
|
||||
if not embeddableType.isNil:
|
||||
let genericParams = newEmpty()
|
||||
procs.add nkProcDef.newTree(
|
||||
"$".toFieldIdent,
|
||||
newEmpty(),
|
||||
genericParams,
|
||||
nkFormalParams.newTree(
|
||||
ident"string",
|
||||
nkIdentDefs.newTree(
|
||||
ident"x",
|
||||
embeddableType,
|
||||
newEmpty())),
|
||||
newEmpty(),
|
||||
newEmpty(),
|
||||
nkStmtList.newTree(
|
||||
nkCall.newTree(ident"$",
|
||||
nkCall.newTree(ident"toPreserves", ident"x"))))
|
||||
procs.add nkProcDef.newTree(
|
||||
"encode".ident.toExport,
|
||||
newEmpty(),
|
||||
genericParams,
|
||||
nkFormalParams.newTree(
|
||||
nkBracketExpr.newTree(ident"seq", ident"byte"),
|
||||
nkIdentDefs.newTree(
|
||||
ident"x",
|
||||
embeddableType,
|
||||
newEmpty())),
|
||||
newEmpty(),
|
||||
newEmpty(),
|
||||
nkStmtList.newTree(
|
||||
nkCall.newTree(ident"encode",
|
||||
nkCall.newTree(ident"toPreserves", ident"x"))))
|
||||
if not unembeddableType.isNil:
|
||||
procs.add nkProcDef.newTree(
|
||||
"$".toFieldIdent,
|
||||
|
|
Loading…
Reference in New Issue