Use dedicated types for record alternates
This commit is contained in:
parent
ea50b05bad
commit
2451b441ad
|
@ -118,6 +118,21 @@ proc toEnumDef(name: string; sn: SchemaNode): PNode =
|
||||||
newEmpty(),
|
newEmpty(),
|
||||||
sn.toEnumTy)
|
sn.toEnumTy)
|
||||||
|
|
||||||
|
proc typeDef(sn: SchemaNode; name: string; ty: PNode): PNode =
|
||||||
|
case sn.kind
|
||||||
|
of snkRecord:
|
||||||
|
nn(nkTypeDef,
|
||||||
|
nn(nkPragmaExpr,
|
||||||
|
name.ident.toExport,
|
||||||
|
nn(nkPragma,
|
||||||
|
nn(nkExprColonExpr,
|
||||||
|
ident"record",
|
||||||
|
PNode(kind: nkStrLit, strVal: sn.nodes[0].value.symbol)))),
|
||||||
|
newEmpty(),
|
||||||
|
ty)
|
||||||
|
else:
|
||||||
|
nn(nkTypeDef, name.ident.toExport, newEmpty(), ty)
|
||||||
|
|
||||||
proc nimTypeOf(scm: Schema; known: var TypeTable; sn: SchemaNode; name = ""): PNode =
|
proc nimTypeOf(scm: Schema; known: var TypeTable; sn: SchemaNode; name = ""): PNode =
|
||||||
case sn.kind
|
case sn.kind
|
||||||
of snkOr:
|
of snkOr:
|
||||||
|
@ -136,6 +151,16 @@ proc nimTypeOf(scm: Schema; known: var TypeTable; sn: SchemaNode; name = ""): PN
|
||||||
newEmpty()))
|
newEmpty()))
|
||||||
for bn in sn.nodes:
|
for bn in sn.nodes:
|
||||||
assert(bn.kind == snkAlt, $bn.kind)
|
assert(bn.kind == snkAlt, $bn.kind)
|
||||||
|
doAssert(name != "", " no name for " & $sn)
|
||||||
|
var memberTypeIdent: PNode
|
||||||
|
if bn.altbranch.kind == snkRef:
|
||||||
|
memberTypeIdent = bn.altBranch.typeIdent
|
||||||
|
else:
|
||||||
|
let memberTypeName = name & bn.altLabel.nimIdentNormalize
|
||||||
|
memberTypeIdent = ident memberTypeName
|
||||||
|
if memberTypeName notin known:
|
||||||
|
let ty = nimTypeOf(scm, known, bn.altBranch, memberTypeName)
|
||||||
|
known[memberTypeName] = typeDef(bn.altBranch, memberTypeName, ty)
|
||||||
var recList = nkRecList.newNode
|
var recList = nkRecList.newNode
|
||||||
case bn.altBranch.kind
|
case bn.altBranch.kind
|
||||||
of snkRecord:
|
of snkRecord:
|
||||||
|
@ -149,13 +174,10 @@ proc nimTypeOf(scm: Schema; known: var TypeTable; sn: SchemaNode; name = ""): PN
|
||||||
nimTypeOf(scm, known, bn.altBranch.nodes[1], $label),
|
nimTypeOf(scm, known, bn.altBranch.nodes[1], $label),
|
||||||
newEmpty())
|
newEmpty())
|
||||||
else:
|
else:
|
||||||
for i, field in bn.altBranch.nodes:
|
recList.add nkIdentDefs.newNode.add(
|
||||||
if i > 0 and (not isConst(scm, field)):
|
bn.ident.toExport,
|
||||||
let label = field.ident
|
memberTypeIdent,
|
||||||
recList.add nkIdentDefs.newNode.add(
|
newEmpty())
|
||||||
label.toExport,
|
|
||||||
nimTypeOf(scm, known, field, $label),
|
|
||||||
newEmpty())
|
|
||||||
else:
|
else:
|
||||||
if isConst(scm, bn.altBranch):
|
if isConst(scm, bn.altBranch):
|
||||||
recList.add nkDiscardStmt.newNode.add(newEmpty())
|
recList.add nkDiscardStmt.newNode.add(newEmpty())
|
||||||
|
@ -168,7 +190,10 @@ proc nimTypeOf(scm: Schema; known: var TypeTable; sn: SchemaNode; name = ""): PN
|
||||||
let disc = nkDotExpr.newNode.add(
|
let disc = nkDotExpr.newNode.add(
|
||||||
enumIdent, bn.altLabel.nimIdentNormalize.ident.accQuote)
|
enumIdent, bn.altLabel.nimIdentNormalize.ident.accQuote)
|
||||||
if recList.len == 0:
|
if recList.len == 0:
|
||||||
recList.add nn(nkDiscardStmt, newEmpty())
|
recList.add nkIdentDefs.newNode.add(
|
||||||
|
bn.ident.toExport,
|
||||||
|
memberTypeIdent,
|
||||||
|
newEmpty())
|
||||||
recCase.add nkOfBranch.newNode.add(disc, recList)
|
recCase.add nkOfBranch.newNode.add(disc, recList)
|
||||||
result = nn(nkRefTy, nn(nkObjectTy,
|
result = nn(nkRefTy, nn(nkObjectTy,
|
||||||
newEmpty(),
|
newEmpty(),
|
||||||
|
@ -370,7 +395,7 @@ proc generateProcs(result: var seq[PNode]; scm: Schema; name: string; sn: Schema
|
||||||
of snkOr:
|
of snkOr:
|
||||||
var
|
var
|
||||||
enumId = name.ident
|
enumId = name.ident
|
||||||
paramId = name.toLowerAscii.ident.accQuote
|
paramId = ident"v"
|
||||||
orStmts = nn(nkStmtList)
|
orStmts = nn(nkStmtList)
|
||||||
if sn.isSymbolEnum:
|
if sn.isSymbolEnum:
|
||||||
let caseStmt = nn(nkCaseStmt, paramId)
|
let caseStmt = nn(nkCaseStmt, paramId)
|
||||||
|
@ -399,8 +424,9 @@ proc generateProcs(result: var seq[PNode]; scm: Schema; name: string; sn: Schema
|
||||||
of snkTuple, snkVariableTuple:
|
of snkTuple, snkVariableTuple:
|
||||||
stmts.add tupleConstructor(scm, sn, nn(nkDotExpr, paramId, fieldId))
|
stmts.add tupleConstructor(scm, sn, nn(nkDotExpr, paramId, fieldId))
|
||||||
of snkAtom, snkSequenceOf:
|
of snkAtom, snkSequenceOf:
|
||||||
# already handled by toPreserve
|
stmts.add nn(nkCall,
|
||||||
discard
|
ident"toPreserve",
|
||||||
|
nn(nkDotExpr, paramId, fieldId))
|
||||||
else:
|
else:
|
||||||
raiseAssert("no case statement for " & $sn.kind & " " & $sn)
|
raiseAssert("no case statement for " & $sn.kind & " " & $sn)
|
||||||
for bn in sn.nodes:
|
for bn in sn.nodes:
|
||||||
|
@ -539,15 +565,7 @@ proc generateNimFile*(scm: Schema; path: string) =
|
||||||
name.ident.toExport, newEmpty(), t)
|
name.ident.toExport, newEmpty(), t)
|
||||||
else:
|
else:
|
||||||
if def.kind == snkRecord:
|
if def.kind == snkRecord:
|
||||||
knownTypes[name] = nn(nkTypeDef,
|
knownTypes[name] = typeDef(def, name, t)
|
||||||
nn(nkPragmaExpr,
|
|
||||||
name.ident.toExport,
|
|
||||||
nn(nkPragma,
|
|
||||||
nn(nkExprColonExpr,
|
|
||||||
ident"record",
|
|
||||||
PNode(kind: nkStrLit, strVal: $def.nodes[0].value.symbol)))),
|
|
||||||
newEmpty(),
|
|
||||||
t)
|
|
||||||
else:
|
else:
|
||||||
case t.kind
|
case t.kind
|
||||||
of nkEnumTy:
|
of nkEnumTy:
|
||||||
|
|
Loading…
Reference in New Issue