expanddefaults.nim 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. #
  2. #
  3. # The Nim Compiler
  4. # (c) Copyright 2023 Andreas Rumpf
  5. #
  6. # See the file "copying.txt", included in this
  7. # distribution, for details about the copyright.
  8. #
  9. import lineinfos, ast, types
  10. proc caseObjDefaultBranch*(obj: PNode; branch: Int128): int =
  11. result = 0
  12. for i in 1 ..< obj.len:
  13. for j in 0 .. obj[i].len - 2:
  14. if obj[i][j].kind == nkRange:
  15. let x = getOrdValue(obj[i][j][0])
  16. let y = getOrdValue(obj[i][j][1])
  17. if branch >= x and branch <= y:
  18. return i
  19. elif getOrdValue(obj[i][j]) == branch:
  20. return i
  21. if obj[i].len == 1:
  22. # else branch
  23. return i
  24. return 1
  25. template newZero(t: PType; info: TLineInfo; k = nkIntLit): PNode = newNodeIT(k, info, t)
  26. proc expandDefault*(t: PType; info: TLineInfo): PNode
  27. proc expandField(s: PSym; info: TLineInfo): PNode =
  28. result = newNodeIT(nkExprColonExpr, info, s.typ)
  29. result.add newSymNode(s)
  30. result.add expandDefault(s.typ, info)
  31. proc expandDefaultN(n: PNode; info: TLineInfo; res: PNode) =
  32. case n.kind
  33. of nkRecList:
  34. for i in 0..<n.len:
  35. expandDefaultN(n[i], info, res)
  36. of nkRecCase:
  37. res.add expandField(n[0].sym, info)
  38. var branch = Zero
  39. let constOrNil = n[0].sym.astdef
  40. if constOrNil != nil:
  41. branch = getOrdValue(constOrNil)
  42. let selectedBranch = caseObjDefaultBranch(n, branch)
  43. let b = lastSon(n[selectedBranch])
  44. expandDefaultN b, info, res
  45. of nkSym:
  46. res.add expandField(n.sym, info)
  47. else:
  48. discard
  49. proc expandDefaultObj(t: PType; info: TLineInfo; res: PNode) =
  50. if t.baseClass != nil:
  51. expandDefaultObj(t.baseClass, info, res)
  52. expandDefaultN(t.n, info, res)
  53. proc expandDefault(t: PType; info: TLineInfo): PNode =
  54. case t.kind
  55. of tyInt: result = newZero(t, info, nkIntLit)
  56. of tyInt8: result = newZero(t, info, nkInt8Lit)
  57. of tyInt16: result = newZero(t, info, nkInt16Lit)
  58. of tyInt32: result = newZero(t, info, nkInt32Lit)
  59. of tyInt64: result = newZero(t, info, nkInt64Lit)
  60. of tyUInt: result = newZero(t, info, nkUIntLit)
  61. of tyUInt8: result = newZero(t, info, nkUInt8Lit)
  62. of tyUInt16: result = newZero(t, info, nkUInt16Lit)
  63. of tyUInt32: result = newZero(t, info, nkUInt32Lit)
  64. of tyUInt64: result = newZero(t, info, nkUInt64Lit)
  65. of tyFloat: result = newZero(t, info, nkFloatLit)
  66. of tyFloat32: result = newZero(t, info, nkFloat32Lit)
  67. of tyFloat64: result = newZero(t, info, nkFloat64Lit)
  68. of tyFloat128: result = newZero(t, info, nkFloat64Lit)
  69. of tyChar: result = newZero(t, info, nkCharLit)
  70. of tyBool: result = newZero(t, info, nkIntLit)
  71. of tyEnum:
  72. # Could use low(T) here to finally fix old language quirks
  73. result = newZero(t, info, nkIntLit)
  74. of tyRange:
  75. # Could use low(T) here to finally fix old language quirks
  76. result = expandDefault(skipModifier t, info)
  77. of tyVoid: result = newZero(t, info, nkEmpty)
  78. of tySink, tyGenericInst, tyDistinct, tyAlias, tyOwned:
  79. result = expandDefault(t.skipModifier, info)
  80. of tyOrdinal, tyGenericBody, tyGenericParam, tyInferred, tyStatic:
  81. if t.hasElementType:
  82. result = expandDefault(t.skipModifier, info)
  83. else:
  84. result = newZero(t, info, nkEmpty)
  85. of tyFromExpr:
  86. if t.n != nil and t.n.typ != nil:
  87. result = expandDefault(t.n.typ, info)
  88. else:
  89. result = newZero(t, info, nkEmpty)
  90. of tyArray:
  91. result = newZero(t, info, nkBracket)
  92. let n = toInt64(lengthOrd(nil, t))
  93. for i in 0..<n:
  94. result.add expandDefault(t.elementType, info)
  95. of tyPtr, tyRef, tyProc, tyPointer, tyCstring:
  96. result = newZero(t, info, nkNilLit)
  97. of tyVar, tyLent:
  98. let e = t.elementType
  99. if e.skipTypes(abstractInst).kind in {tyOpenArray, tyVarargs}:
  100. # skip the modifier, `var openArray` is a (ptr, len) pair too:
  101. result = expandDefault(e, info)
  102. else:
  103. result = newZero(e, info, nkNilLit)
  104. of tySet:
  105. result = newZero(t, info, nkCurly)
  106. of tyObject:
  107. result = newNodeIT(nkObjConstr, info, t)
  108. result.add newNodeIT(nkType, info, t)
  109. expandDefaultObj(t, info, result)
  110. of tyTuple:
  111. result = newZero(t, info, nkTupleConstr)
  112. for it in t.kids:
  113. result.add expandDefault(it, info)
  114. of tyVarargs, tyOpenArray, tySequence, tyUncheckedArray:
  115. result = newZero(t, info, nkBracket)
  116. of tyString:
  117. result = newZero(t, info, nkStrLit)
  118. of tyNone, tyEmpty, tyUntyped, tyTyped, tyTypeDesc,
  119. tyNil, tyGenericInvocation, tyError, tyBuiltInTypeClass,
  120. tyUserTypeClass, tyUserTypeClassInst, tyCompositeTypeClass,
  121. tyAnd, tyOr, tyNot, tyAnything, tyConcept, tyIterable, tyForward:
  122. result = newZero(t, info, nkEmpty) # bug indicator