preserves_schema_nim: rearrange some internal parameters

This commit is contained in:
Emery Hemingway 2023-12-28 18:30:27 +02:00
parent a5cc0a431d
commit 43498a4b94
1 changed files with 79 additions and 36 deletions

View File

@ -399,13 +399,20 @@ proc identDef(scm: Schema; l: PNode; ts: TypeSpec): PNode =
proc label(pat: Pattern): string = proc label(pat: Pattern): string =
raiseAssert "need to derive record label for " & $pat raiseAssert "need to derive record label for " & $pat
proc label(na: NamedPattern; index: int): string = proc label(na: NamedPattern; parentLabel: string; index: int): string =
case na.orKind case na.orKind
of NamedPatternKind.named: of NamedPatternKind.named:
string na.named.name string na.named.name
of NamedPatternKind.anonymous: of NamedPatternKind.anonymous:
"field" & $index "field" & $index
proc label(nsp: NamedSimplePattern; parentLabel: string; index: int): string =
case nsp.orKind
of NamedSimplePatternKind.named:
string nsp.named.name
of NamedSimplePatternKind.anonymous:
parentLabel & $index
proc idStr(sp: SimplePattern): string = proc idStr(sp: SimplePattern): string =
if sp.orKind == SimplepatternKind.lit: if sp.orKind == SimplepatternKind.lit:
case sp.lit.value.kind case sp.lit.value.kind
@ -427,6 +434,10 @@ proc idStr(np: NamedPattern): string =
of NamedPatternKind.anonymous: of NamedPatternKind.anonymous:
np.anonymous.idStr np.anonymous.idStr
proc typeDef(loc: Location; name: string; pat: SimplePattern; ty: PNode): PNode =
let id = name.ident.toExport
nkTypeDef.newTree(id, newEmpty(), ty)
proc typeDef(loc: Location; name: string; pat: Pattern; ty: PNode): PNode = proc typeDef(loc: Location; name: string; pat: Pattern; ty: PNode): PNode =
let let
embedParams = newEmpty() embedParams = newEmpty()
@ -478,11 +489,11 @@ proc typeDef(loc: Location; name: string; def: Definition; ty: PNode): PNode =
of DefinitionKind.Pattern: of DefinitionKind.Pattern:
typeDef(loc, name, def.pattern, ty) typeDef(loc, name, def.pattern, ty)
proc nimTypeOf(loc: Location; known: var TypeTable; nsp: NamedSimplePattern; name = ""): TypeSpec proc nimTypeOf(loc: Location; known: var TypeTable; name: string; nsp: NamedSimplePattern): TypeSpec
proc nimTypeOf(loc: Location; known: var TypeTable; pat: Pattern; name = ""): TypeSpec proc nimTypeOf(loc: Location; known: var TypeTable; name: string; pat: Pattern): TypeSpec
proc nimTypeOf(loc: Location; known: var TypeTable; cp: CompoundPattern; name = ""): TypeSpec proc nimTypeOf(loc: Location; known: var TypeTable; name: string; cp: CompoundPattern): TypeSpec
proc nimTypeOf(loc: Location; known: var TypeTable; sp: SimplePattern; name = ""): TypeSpec = proc nimTypeOf(loc: Location; known: var TypeTable; name: string; sp: SimplePattern): TypeSpec =
typeIdent(loc, sp) typeIdent(loc, sp)
proc addField(recList: PNode; loc: Location; known: var TypeTable; sp: SimplePattern; label: string): PNode {.discardable.} = proc addField(recList: PNode; loc: Location; known: var TypeTable; sp: SimplePattern; label: string): PNode {.discardable.} =
@ -500,15 +511,45 @@ proc addField(recList: PNode; loc: Location; known: var TypeTable; sp: SimplePat
elif sp.orKind == SimplePatternKind.embedded and not scm.hasEmbeddedType: elif sp.orKind == SimplePatternKind.embedded and not scm.hasEmbeddedType:
let id = nkPragmaExpr.newTree( let id = nkPragmaExpr.newTree(
id, nkPragma.newTree(ident"preservesEmbedded")) id, nkPragma.newTree(ident"preservesEmbedded"))
recList.add identDef(scm, id, nimTypeOf(loc, known, sp)) recList.add identDef(scm, id, nimTypeOf(loc, known, "", sp))
else: else:
recList.add identDef(scm, id, nimTypeOf(loc, known, sp)) recList.add identDef(scm, id, nimTypeOf(loc, known, "", sp))
proc addFields(recList: PNode; loc: Location; known: var TypeTable; cp: CompoundPattern; parentName: string): PNode {.discardable.} = proc addField(recList: PNode; loc: Location; known: var TypeTable; parentName: string; np: NamedPattern; index = 0) =
let
label = label(np, parentName, index)
id = label.toFieldIdent
pattern = np.pattern
if pattern.isRef or pattern.isSimple:
addField(recList, loc, known, pattern.simplePattern, label)
else:
var
typeName = parentName & capitalizeAscii(label)
typePath = loc.schemaPath & @[Symbol typeName]
fieldSpec = nimTypeOf(loc, known, label, pattern)
known[typePath] = typeDef(loc, typeName, pattern, fieldSpec.node)
recList.add identDef(loc.schema, id, ident(typeName), isEmbedded(loc, pattern))
proc addField(recList: PNode; loc: Location; known: var TypeTable; parentName: string; nsp: NamedSimplePattern; index = 0) =
let
label = label(nsp, parentName, index)
id = label.toFieldIdent
pattern = nsp.pattern
if pattern.isRef:
addField(recList, loc, known, pattern, label)
else:
var
typeName = parentName & capitalizeAscii(label)
typePath = loc.schemaPath & @[Symbol typeName]
fieldSpec = nimTypeOf(loc, known, label, pattern)
known[typePath] = typeDef(loc, typeName, pattern, fieldSpec.node)
recList.add identDef(loc.schema, id, ident(typeName), false)
proc addFields(recList: PNode; loc: Location; known: var TypeTable; parentName: string; cp: CompoundPattern): PNode {.discardable.} =
let scm = loc.schema let scm = loc.schema
template addField(np: NamedPattern; index: int) = template addField(np: NamedPattern; index: int) =
let let
label = label(np, index) label = label(np, parentName, index)
id = label.toFieldIdent id = label.toFieldIdent
pattern = np.pattern pattern = np.pattern
if pattern.isRef or pattern.isSimple: if pattern.isRef or pattern.isSimple:
@ -517,18 +558,18 @@ proc addFields(recList: PNode; loc: Location; known: var TypeTable; cp: Compound
var var
typeName = parentName & capitalizeAscii(label) typeName = parentName & capitalizeAscii(label)
typePath = loc.schemaPath & @[Symbol typeName] typePath = loc.schemaPath & @[Symbol typeName]
fieldSpec = nimTypeOf(loc, known, pattern, label) fieldSpec = nimTypeOf(loc, known, label, pattern)
known[typePath] = typeDef(loc, typeName, pattern, fieldSpec.node) known[typePath] = typeDef(loc, typeName, pattern, fieldSpec.node)
recList.add identDef(scm, id, ident(typeName), isEmbedded(loc, pattern)) recList.add identDef(scm, id, ident(typeName), isEmbedded(loc, pattern))
case cp.orKind case cp.orKind
of CompoundPatternKind.rec: of CompoundPatternKind.rec:
# recList.add identDef(scm, ident(label), nimTypeOf(loc, known, cp, "")) # recList.add identDef(scm, ident(label), nimTypeOf(loc, known, "", cp))
raiseassert "unexpected record of fields " #& $cp.rec raiseassert "unexpected record of fields " #& $cp.rec
of CompoundPatternKind.tuple: of CompoundPatternKind.tuple:
for i, np in cp.tuple.patterns: addField(np, i) for i, np in cp.tuple.patterns: addField(np, i)
of CompoundPatternKind.tuplePrefix: of CompoundPatternKind.tuplePrefix:
for i, np in cp.tuplePrefix.fixed: addField(np, i) for i, np in cp.tuplePrefix.fixed: addField(np, i)
let variableType = nimTypeOf(loc, known, cp.tuplePrefix.variable) let variableType = nimTypeOf(loc, known, "", cp.tuplePrefix.variable)
recList.add identDef( recList.add identDef(
scm, scm,
nkPragmaExpr.newTree( nkPragmaExpr.newTree(
@ -539,15 +580,18 @@ proc addFields(recList: PNode; loc: Location; known: var TypeTable; cp: Compound
else: raiseAssert "not adding fields for " #& $cp else: raiseAssert "not adding fields for " #& $cp
reclist reclist
proc addFields(recList: PNode; loc: Location; known: var TypeTable; pat: Pattern; parentName: string): PNode {.discardable.} = proc addFields(recList: PNode; loc: Location; known: var TypeTable; name: string; pat: SimplePattern): PNode {.discardable.} =
addField(recList, loc, known, pat, name)
proc addFields(recList: PNode; loc: Location; known: var TypeTable; parentName: string; pat: Pattern): PNode {.discardable.} =
case pat.orKind case pat.orKind
of PatternKind.SimplePattern: of PatternKind.SimplePattern:
addField(recList, loc, known, pat.simplePattern, "field0") discard addFields(recList, loc, known, parentName, pat.simplePattern)
of PatternKind.CompoundPattern: of PatternKind.CompoundPattern:
discard addFields(recList, loc, known, pat.compoundPattern, parentName) discard addFields(recList, loc, known, parentName, pat.compoundPattern)
reclist reclist
proc addFields(recList: PNode; loc: Location; known: var TypeTable; entries: DictionaryEntries; parentName: string): PNode {.discardable.} = proc addFields(recList: PNode; loc: Location; known: var TypeTable; parentName: string; entries: DictionaryEntries): PNode {.discardable.} =
var sortedEntries = var sortedEntries =
initOrderedTable[Value, NamedSimplePattern](entries.len) initOrderedTable[Value, NamedSimplePattern](entries.len)
for key, val in entries.pairs: for key, val in entries.pairs:
@ -560,44 +604,43 @@ proc addFields(recList: PNode; loc: Location; known: var TypeTable; entries: Dic
addField(recList, loc, known, val.pattern, label) addField(recList, loc, known, val.pattern, label)
recList recList
proc nimTypeOf(loc: Location; known: var TypeTable; nsp: NamedSimplePattern; name: string): TypeSpec = proc nimTypeOf(loc: Location; known: var TypeTable; name: string; nsp: NamedSimplePattern): TypeSpec =
case nsp.orKind case nsp.orKind
of NamedsimplepatternKind.named: of NamedsimplepatternKind.named:
nimTypeOf(loc, known, nsp.named.pattern, string nsp.named.name) nimTypeOf(loc, known, string nsp.named.name, nsp.named.pattern)
of NamedsimplepatternKind.anonymous: of NamedsimplepatternKind.anonymous:
nimTypeOf(loc, known, nsp.anonymous, name) nimTypeOf(loc, known, name, nsp.anonymous)
proc nimTypeOf(loc: Location; known: var TypeTable; rec: CompoundPatternRec; name: string): TypeSpec = proc nimTypeOf(loc: Location; known: var TypeTable; name: string; rec: CompoundPatternRec): TypeSpec =
if isLiteral(loc, rec.label): if isLiteral(loc, rec.label):
result.node = nkObjectTy.newTree( result.node = nkObjectTy.newTree(
newEmpty(), newEmpty(), newEmpty(), newEmpty(),
newNode(nkRecList).addFields(loc, known, rec.fields.pattern, name)) newNode(nkRecList).addFields(loc, known, name, rec.fields.pattern))
else: else:
result.node = ident"Value" result.node = ident"Value"
proc nimTypeOf(loc: Location; known: var TypeTable; cp: CompoundPattern; name: string): TypeSpec = proc nimTypeOf(loc: Location; known: var TypeTable; name: string; cp: CompoundPattern): TypeSpec =
case cp.orKind case cp.orKind
of CompoundPatternKind.`rec`: of CompoundPatternKind.`rec`:
result = nimTypeOf(loc, known, cp.rec, name) result = nimTypeOf(loc, known, name, cp.rec)
of CompoundPatternKind.`tuple`, CompoundPatternKind.`tupleprefix`: of CompoundPatternKind.`tuple`, CompoundPatternKind.`tupleprefix`:
result.node = nkObjectTy.newTree( result.node = nkObjectTy.newTree(
newEmpty(), newEmpty(), newEmpty(), newEmpty(),
newNode(nkRecList).addFields(loc, known, cp, name)) newNode(nkRecList).addFields(loc, known, name, cp))
of CompoundPatternKind.`dict`: of CompoundPatternKind.`dict`:
result.node = nkObjectTy.newTree(newEmpty(), newEmpty(), result.node = nkObjectTy.newTree(newEmpty(), newEmpty(),
newNode(nkRecList).addFields(loc, known, cp.dict.entries, name)) newNode(nkRecList).addFields(loc, known, name, cp.dict.entries))
if result.node.kind == nkObjectTy and isRecursive(loc, cp): if result.node.kind == nkObjectTy and isRecursive(loc, cp):
result.node = nkRefTy.newTree(result.node) result.node = nkRefTy.newTree(result.node)
proc nimTypeOf(loc: Location; known: var TypeTable; pat: Pattern; name: string): TypeSpec = proc nimTypeOf(loc: Location; known: var TypeTable; name: string; pat: Pattern): TypeSpec =
case pat.orKind case pat.orKind
of PatternKind.SimplePattern: of PatternKind.SimplePattern:
nimTypeOf(loc, known, pat.simplePattern, name) nimTypeOf(loc, known, name, pat.simplePattern)
of PatternKind.CompoundPattern: of PatternKind.CompoundPattern:
nimTypeOf(loc, known, pat.compoundPattern, name) nimTypeOf(loc, known, name, pat.compoundPattern)
proc nimTypeOf(loc: Location; known: var TypeTable; orDef: DefinitionOr; name: string): TypeSpec = proc nimTypeOf(loc: Location; known: var TypeTable; name: string; orDef: DefinitionOr): TypeSpec =
let scm = loc.schema
proc toEnumTy(): PNode = proc toEnumTy(): PNode =
let ty = nkEnumTy.newNode.add newEmpty() let ty = nkEnumTy.newNode.add newEmpty()
proc add (na: NamedAlternative) = proc add (na: NamedAlternative) =
@ -638,7 +681,7 @@ proc nimTypeOf(loc: Location; known: var TypeTable; orDef: DefinitionOr; name: s
memberTypeName = name & na.variantLabel.capitalizeAscii memberTypeName = name & na.variantLabel.capitalizeAscii
memberPath = loc.schemaPath & @[Symbol memberTypeName] memberPath = loc.schemaPath & @[Symbol memberTypeName]
memberType.node = ident memberTypeName memberType.node = ident memberTypeName
let ty = nimTypeOf(loc, known, na.pattern, memberTypeName) let ty = nimTypeOf(loc, known, memberTypeName, na.pattern)
addAttrs(memberType, ty) addAttrs(memberType, ty)
if memberPath notin known and not isLiteral(loc, na.pattern): if memberPath notin known and not isLiteral(loc, na.pattern):
known[memberPath] = known[memberPath] =
@ -662,14 +705,14 @@ proc nimTypeOf(loc: Location; known: var TypeTable; orDef: DefinitionOr; name: s
if result.node.kind == nkObjectTy and (recursive in attrs(loc, orDef)): if result.node.kind == nkObjectTy and (recursive in attrs(loc, orDef)):
result.node = nkRefTy.newTree(result.node) result.node = nkRefTy.newTree(result.node)
proc nimTypeOf(loc: Location; known: var TypeTable; def: Definition; name: string): TypeSpec = proc nimTypeOf(loc: Location; known: var TypeTable; name: string; def: Definition): TypeSpec =
case def.orKind case def.orKind
of DefinitionKind.or: of DefinitionKind.or:
nimTypeOf(loc, known, def.or, name) nimTypeOf(loc, known, name, def.or)
of DefinitionKind.and: of DefinitionKind.and:
TypeSpec(node: ident"Value") nimTypeOf(loc, known, name, def.and)
of DefinitionKind.Pattern: of DefinitionKind.Pattern:
nimTypeOf(loc, known, def.pattern, name) nimTypeOf(loc, known, name, def.pattern)
proc generateConstProcs(result: var seq[PNode]; scm: Schema, name: string; def: Definition) = proc generateConstProcs(result: var seq[PNode]; scm: Schema, name: string; def: Definition) =
discard discard
@ -761,7 +804,7 @@ proc renderNimBundle*(bundle: Bundle): Table[string, string] =
mergeType(embeddableType, defIdent) mergeType(embeddableType, defIdent)
else: else:
mergeType(unembeddableType, defIdent) mergeType(unembeddableType, defIdent)
let typeSpec = nimTypeOf(loc, typeDefs, def, name) let typeSpec = nimTypeOf(loc, typeDefs, name, def)
typeDefs[scmPath & @[Symbol name]] = typeDef(loc, name, def, typeSpec.node) typeDefs[scmPath & @[Symbol name]] = typeDef(loc, name, def, typeSpec.node)
generateProcs(procs, scm, name, def) generateProcs(procs, scm, name, def)