customast.nim 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. # This file exists to make it overridable via
  2. # patchFile("plugins", "customast.nim", "customast.nim")
  3. ## This also serves as a blueprint for a possible implementation.
  4. import "$nim" / compiler / [lineinfos, idents]
  5. when defined(nimPreviewSlimSystem):
  6. import std/assertions
  7. import "$nim" / compiler / nodekinds
  8. export nodekinds
  9. type
  10. PNode* = ref TNode
  11. TNode*{.final, acyclic.} = object
  12. case kind*: TNodeKind
  13. of nkCharLit..nkUInt64Lit:
  14. intVal: BiggestInt
  15. of nkFloatLit..nkFloat128Lit:
  16. floatVal: BiggestFloat
  17. of nkStrLit..nkTripleStrLit:
  18. strVal: string
  19. of nkSym:
  20. discard
  21. of nkIdent:
  22. ident: PIdent
  23. else:
  24. son, next, last: PNode # linked structure instead of a `seq`
  25. info*: TLineInfo
  26. const
  27. bodyPos* = 6
  28. paramsPos* = 3
  29. proc comment*(n: PNode): string =
  30. result = ""
  31. proc `comment=`*(n: PNode, a: string) =
  32. discard "XXX implement me"
  33. proc add*(father, son: PNode) =
  34. assert son != nil
  35. if father.son == nil:
  36. father.son = son
  37. father.last = son
  38. else:
  39. father.last.next = son
  40. father.last = son
  41. template firstSon*(n: PNode): PNode = n.son
  42. template secondSon*(n: PNode): PNode = n.son.next
  43. proc replaceFirstSon*(n, newson: PNode) {.inline.} =
  44. let old = n.son
  45. n.son = newson
  46. newson.next = old
  47. proc replaceSon*(n: PNode; i: int; newson: PNode) =
  48. assert i > 0
  49. assert newson.next == nil
  50. var i = i
  51. var it = n.son
  52. while i > 0:
  53. it = it.next
  54. dec i
  55. let old = it.next
  56. it.next = newson
  57. newson.next = old
  58. template newNodeImpl(info2) =
  59. result = PNode(kind: kind, info: info2)
  60. proc newNode*(kind: TNodeKind): PNode =
  61. ## new node with unknown line info, no type, and no children
  62. newNodeImpl(unknownLineInfo)
  63. proc newNode*(kind: TNodeKind, info: TLineInfo): PNode =
  64. ## new node with line info, no type, and no children
  65. newNodeImpl(info)
  66. proc newTree*(kind: TNodeKind; info: TLineInfo; child: PNode): PNode =
  67. result = newNode(kind, info)
  68. result.son = child
  69. proc newAtom*(ident: PIdent, info: TLineInfo): PNode =
  70. result = newNode(nkIdent)
  71. result.ident = ident
  72. result.info = info
  73. proc newAtom*(kind: TNodeKind, intVal: BiggestInt, info: TLineInfo): PNode =
  74. result = newNode(kind, info)
  75. result.intVal = intVal
  76. proc newAtom*(kind: TNodeKind, floatVal: BiggestFloat, info: TLineInfo): PNode =
  77. result = newNode(kind, info)
  78. result.floatVal = floatVal
  79. proc newAtom*(kind: TNodeKind; strVal: sink string; info: TLineInfo): PNode =
  80. result = newNode(kind, info)
  81. result.strVal = strVal
  82. proc lastSon*(n: PNode): PNode {.inline.} = n.last
  83. proc setLastSon*(n: PNode, s: PNode) =
  84. assert s.next == nil
  85. n.last = s
  86. if n.son == nil: n.son = s
  87. proc newProcNode*(kind: TNodeKind, info: TLineInfo, body: PNode,
  88. params,
  89. name, pattern, genericParams,
  90. pragmas, exceptions: PNode): PNode =
  91. result = newNode(kind, info)
  92. result.add name
  93. result.add pattern
  94. result.add genericParams
  95. result.add params
  96. result.add pragmas
  97. result.add exceptions
  98. result.add body
  99. template transitionNodeKindCommon(k: TNodeKind) =
  100. let obj {.inject.} = n[]
  101. n[] = TNode(kind: k, info: obj.info)
  102. # n.comment = obj.comment # shouldn't be needed, the address doesnt' change
  103. proc transitionSonsKind*(n: PNode, kind: range[nkComesFrom..nkTupleConstr]) =
  104. transitionNodeKindCommon(kind)
  105. n.son = obj.son
  106. template hasSon*(n: PNode): bool = n.son != nil
  107. template has2Sons*(n: PNode): bool = n.son != nil and n.son.next != nil
  108. proc isNewStyleConcept*(n: PNode): bool {.inline.} =
  109. assert n.kind == nkTypeClassTy
  110. result = n.firstSon.kind == nkEmpty