enumtostr.nim 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. import ast, idents, lineinfos, modulegraphs, magicsys
  2. when defined(nimPreviewSlimSystem):
  3. import std/assertions
  4. proc genEnumToStrProc*(t: PType; info: TLineInfo; g: ModuleGraph; idgen: IdGenerator): PSym =
  5. result = newSym(skProc, getIdent(g.cache, "$"), idgen, t.owner, info)
  6. let dest = newSym(skParam, getIdent(g.cache, "e"), idgen, result, info)
  7. dest.typ = t
  8. let res = newSym(skResult, getIdent(g.cache, "result"), idgen, result, info)
  9. res.typ = getSysType(g, info, tyString)
  10. result.typ = newType(tyProc, idgen, t.owner)
  11. result.typ.n = newNodeI(nkFormalParams, info)
  12. rawAddSon(result.typ, res.typ)
  13. result.typ.n.add newNodeI(nkEffectList, info)
  14. result.typ.addParam dest
  15. var body = newNodeI(nkStmtList, info)
  16. var caseStmt = newNodeI(nkCaseStmt, info)
  17. caseStmt.add(newSymNode dest)
  18. # copy the branches over, but replace the fields with the for loop body:
  19. for i in 0..<t.n.len:
  20. assert(t.n[i].kind == nkSym)
  21. var field = t.n[i].sym
  22. let val = if field.ast == nil: field.name.s else: field.ast.strVal
  23. caseStmt.add newTree(nkOfBranch, newIntTypeNode(field.position, t),
  24. newTree(nkStmtList, newTree(nkFastAsgn, newSymNode(res), newStrNode(val, info))))
  25. #newIntTypeNode(nkIntLit, field.position, t)
  26. # safety branch for invalid data:
  27. caseStmt.add newTree(nkElse,
  28. newTree(nkStmtList, newTree(nkFastAsgn, newSymNode(res),
  29. newStrNode("", info))))
  30. body.add(caseStmt)
  31. var n = newNodeI(nkProcDef, info, bodyPos+2)
  32. for i in 0..<n.len: n[i] = newNodeI(nkEmpty, info)
  33. n[namePos] = newSymNode(result)
  34. n[paramsPos] = result.typ.n
  35. n[bodyPos] = body
  36. n[resultPos] = newSymNode(res)
  37. result.ast = n
  38. incl result.flags, sfFromGeneric
  39. incl result.flags, sfNeverRaises
  40. proc searchObjCaseImpl(obj: PNode; field: PSym): PNode =
  41. case obj.kind
  42. of nkSym:
  43. result = nil
  44. of nkElse, nkOfBranch:
  45. result = searchObjCaseImpl(obj.lastSon, field)
  46. else:
  47. if obj.kind == nkRecCase and obj[0].kind == nkSym and obj[0].sym == field:
  48. result = obj
  49. else:
  50. result = nil
  51. for x in obj:
  52. result = searchObjCaseImpl(x, field)
  53. if result != nil: break
  54. proc searchObjCase(t: PType; field: PSym): PNode =
  55. result = searchObjCaseImpl(t.n, field)
  56. if result == nil and t.baseClass != nil:
  57. result = searchObjCase(t.baseClass.skipTypes({tyAlias, tyGenericInst, tyRef, tyPtr}), field)
  58. doAssert result != nil
  59. proc genCaseObjDiscMapping*(t: PType; field: PSym; info: TLineInfo; g: ModuleGraph; idgen: IdGenerator): PSym =
  60. result = newSym(skProc, getIdent(g.cache, "objDiscMapping"), idgen, t.owner, info)
  61. let dest = newSym(skParam, getIdent(g.cache, "e"), idgen, result, info)
  62. dest.typ = field.typ
  63. let res = newSym(skResult, getIdent(g.cache, "result"), idgen, result, info)
  64. res.typ = getSysType(g, info, tyUInt8)
  65. result.typ = newType(tyProc, idgen, t.owner)
  66. result.typ.n = newNodeI(nkFormalParams, info)
  67. rawAddSon(result.typ, res.typ)
  68. result.typ.n.add newNodeI(nkEffectList, info)
  69. result.typ.addParam dest
  70. var body = newNodeI(nkStmtList, info)
  71. var caseStmt = newNodeI(nkCaseStmt, info)
  72. caseStmt.add(newSymNode dest)
  73. let subObj = searchObjCase(t, field)
  74. for i in 1..<subObj.len:
  75. let ofBranch = subObj[i]
  76. var newBranch = newNodeI(ofBranch.kind, ofBranch.info)
  77. for j in 0..<ofBranch.len-1:
  78. newBranch.add ofBranch[j]
  79. newBranch.add newTree(nkStmtList, newTree(nkFastAsgn, newSymNode(res), newIntNode(nkInt8Lit, i)))
  80. caseStmt.add newBranch
  81. body.add(caseStmt)
  82. var n = newNodeI(nkProcDef, info, bodyPos+2)
  83. for i in 0..<n.len: n[i] = newNodeI(nkEmpty, info)
  84. n[namePos] = newSymNode(result)
  85. n[paramsPos] = result.typ.n
  86. n[bodyPos] = body
  87. n[resultPos] = newSymNode(res)
  88. result.ast = n
  89. incl result.flags, sfFromGeneric
  90. incl result.flags, sfNeverRaises