enumtostr.nim 3.2 KB

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