diff --git a/src/preserves/private/preserves_schema_nim.nim b/src/preserves/private/preserves_schema_nim.nim index 6969612..4f4d494 100644 --- a/src/preserves/private/preserves_schema_nim.nim +++ b/src/preserves/private/preserves_schema_nim.nim @@ -118,6 +118,21 @@ proc toEnumDef(name: string; sn: SchemaNode): PNode = newEmpty(), 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 = case sn.kind of snkOr: @@ -136,6 +151,16 @@ proc nimTypeOf(scm: Schema; known: var TypeTable; sn: SchemaNode; name = ""): PN newEmpty())) for bn in sn.nodes: 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 case bn.altBranch.kind 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), newEmpty()) else: - for i, field in bn.altBranch.nodes: - if i > 0 and (not isConst(scm, field)): - let label = field.ident - recList.add nkIdentDefs.newNode.add( - label.toExport, - nimTypeOf(scm, known, field, $label), - newEmpty()) + recList.add nkIdentDefs.newNode.add( + bn.ident.toExport, + memberTypeIdent, + newEmpty()) else: if isConst(scm, bn.altBranch): 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( enumIdent, bn.altLabel.nimIdentNormalize.ident.accQuote) 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) result = nn(nkRefTy, nn(nkObjectTy, newEmpty(), @@ -370,7 +395,7 @@ proc generateProcs(result: var seq[PNode]; scm: Schema; name: string; sn: Schema of snkOr: var enumId = name.ident - paramId = name.toLowerAscii.ident.accQuote + paramId = ident"v" orStmts = nn(nkStmtList) if sn.isSymbolEnum: let caseStmt = nn(nkCaseStmt, paramId) @@ -399,8 +424,9 @@ proc generateProcs(result: var seq[PNode]; scm: Schema; name: string; sn: Schema of snkTuple, snkVariableTuple: stmts.add tupleConstructor(scm, sn, nn(nkDotExpr, paramId, fieldId)) of snkAtom, snkSequenceOf: - # already handled by toPreserve - discard + stmts.add nn(nkCall, + ident"toPreserve", + nn(nkDotExpr, paramId, fieldId)) else: raiseAssert("no case statement for " & $sn.kind & " " & $sn) for bn in sn.nodes: @@ -539,15 +565,7 @@ proc generateNimFile*(scm: Schema; path: string) = name.ident.toExport, newEmpty(), t) else: if def.kind == snkRecord: - knownTypes[name] = nn(nkTypeDef, - nn(nkPragmaExpr, - name.ident.toExport, - nn(nkPragma, - nn(nkExprColonExpr, - ident"record", - PNode(kind: nkStrLit, strVal: $def.nodes[0].value.symbol)))), - newEmpty(), - t) + knownTypes[name] = typeDef(def, name, t) else: case t.kind of nkEnumTy: