jstypes.nim 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. #
  2. #
  3. # The Nim Compiler
  4. # (c) Copyright 2013 Andreas Rumpf
  5. #
  6. # See the file "copying.txt", included in this
  7. # distribution, for details about the copyright.
  8. #
  9. # included from jsgen.nim
  10. ## Type info generation for the JS backend.
  11. proc rope(arg: Int128): Rope = rope($arg)
  12. proc genTypeInfo(p: PProc, typ: PType): Rope
  13. proc genObjectFields(p: PProc, typ: PType, n: PNode): Rope =
  14. var
  15. s, u: Rope
  16. field: PSym
  17. b: PNode
  18. result = ""
  19. case n.kind
  20. of nkRecList:
  21. if n.len == 1:
  22. result = genObjectFields(p, typ, n[0])
  23. else:
  24. s = ""
  25. for i in 0..<n.len:
  26. if i > 0: s.add(", \L")
  27. s.add(genObjectFields(p, typ, n[i]))
  28. result = ("{kind: 2, len: $1, offset: 0, " &
  29. "typ: null, name: null, sons: [$2]}") % [rope(n.len), s]
  30. of nkSym:
  31. field = n.sym
  32. s = genTypeInfo(p, field.typ)
  33. result = ("{kind: 1, offset: \"$1\", len: 0, " &
  34. "typ: $2, name: $3, sons: null}") %
  35. [mangleName(p.module, field), s,
  36. makeJSString(field.name.s)]
  37. of nkRecCase:
  38. if (n[0].kind != nkSym): internalError(p.config, n.info, "genObjectFields")
  39. field = n[0].sym
  40. s = genTypeInfo(p, field.typ)
  41. for i in 1..<n.len:
  42. b = n[i] # branch
  43. u = ""
  44. case b.kind
  45. of nkOfBranch:
  46. if b.len < 2:
  47. internalError(p.config, b.info, "genObjectFields; nkOfBranch broken")
  48. for j in 0..<b.len - 1:
  49. if u != "": u.add(", ")
  50. if b[j].kind == nkRange:
  51. u.addf("[$1, $2]", [rope(getOrdValue(b[j][0])),
  52. rope(getOrdValue(b[j][1]))])
  53. else:
  54. u.add(rope(getOrdValue(b[j])))
  55. of nkElse:
  56. u = rope(lengthOrd(p.config, field.typ))
  57. else: internalError(p.config, n.info, "genObjectFields(nkRecCase)")
  58. if result != "": result.add(", \L")
  59. result.addf("[setConstr($1), $2]",
  60. [u, genObjectFields(p, typ, lastSon(b))])
  61. result = ("{kind: 3, offset: \"$1\", len: $3, " &
  62. "typ: $2, name: $4, sons: [$5]}") % [
  63. mangleName(p.module, field), s,
  64. rope(lengthOrd(p.config, field.typ)), makeJSString(field.name.s), result]
  65. else: internalError(p.config, n.info, "genObjectFields")
  66. proc objHasTypeField(t: PType): bool {.inline.} =
  67. tfInheritable in t.flags or t.baseClass != nil
  68. proc genObjectInfo(p: PProc, typ: PType, name: Rope) =
  69. let kind = if objHasTypeField(typ): tyObject else: tyTuple
  70. var s = ("var $1 = {size: 0, kind: $2, base: null, node: null, " &
  71. "finalizer: null};$n") % [name, rope(ord(kind))]
  72. prepend(p.g.typeInfo, s)
  73. p.g.typeInfo.addf("var NNI$1 = $2;$n",
  74. [rope(typ.id), genObjectFields(p, typ, typ.n)])
  75. p.g.typeInfo.addf("$1.node = NNI$2;$n", [name, rope(typ.id)])
  76. if (typ.kind == tyObject) and (typ.baseClass != nil):
  77. p.g.typeInfo.addf("$1.base = $2;$n",
  78. [name, genTypeInfo(p, typ.baseClass.skipTypes(skipPtrs))])
  79. proc genTupleFields(p: PProc, typ: PType): Rope =
  80. var s: Rope = ""
  81. for i in 0..<typ.len:
  82. if i > 0: s.add(", \L")
  83. s.addf("{kind: 1, offset: \"Field$1\", len: 0, " &
  84. "typ: $2, name: \"Field$1\", sons: null}",
  85. [i.rope, genTypeInfo(p, typ[i])])
  86. result = ("{kind: 2, len: $1, offset: 0, " &
  87. "typ: null, name: null, sons: [$2]}") % [rope(typ.len), s]
  88. proc genTupleInfo(p: PProc, typ: PType, name: Rope) =
  89. var s = ("var $1 = {size: 0, kind: $2, base: null, node: null, " &
  90. "finalizer: null};$n") % [name, rope(ord(typ.kind))]
  91. prepend(p.g.typeInfo, s)
  92. p.g.typeInfo.addf("var NNI$1 = $2;$n",
  93. [rope(typ.id), genTupleFields(p, typ)])
  94. p.g.typeInfo.addf("$1.node = NNI$2;$n", [name, rope(typ.id)])
  95. proc genEnumInfo(p: PProc, typ: PType, name: Rope) =
  96. var s: Rope = ""
  97. for i in 0..<typ.n.len:
  98. if (typ.n[i].kind != nkSym): internalError(p.config, typ.n.info, "genEnumInfo")
  99. let field = typ.n[i].sym
  100. if i > 0: s.add(", \L")
  101. let extName = if field.ast == nil: field.name.s else: field.ast.strVal
  102. s.addf("\"$1\": {kind: 1, offset: $1, typ: $2, name: $3, len: 0, sons: null}",
  103. [rope(field.position), name, makeJSString(extName)])
  104. var n = ("var NNI$1 = {kind: 2, offset: 0, typ: null, " &
  105. "name: null, len: $2, sons: {$3}};$n") % [rope(typ.id), rope(typ.n.len), s]
  106. s = ("var $1 = {size: 0, kind: $2, base: null, node: null, " &
  107. "finalizer: null};$n") % [name, rope(ord(typ.kind))]
  108. prepend(p.g.typeInfo, s)
  109. p.g.typeInfo.add(n)
  110. p.g.typeInfo.addf("$1.node = NNI$2;$n", [name, rope(typ.id)])
  111. if typ.baseClass != nil:
  112. p.g.typeInfo.addf("$1.base = $2;$n",
  113. [name, genTypeInfo(p, typ.baseClass)])
  114. proc genTypeInfo(p: PProc, typ: PType): Rope =
  115. let t = typ.skipTypes({tyGenericInst, tyDistinct, tyAlias, tySink, tyOwned})
  116. result = "NTI$1" % [rope(t.id)]
  117. if containsOrIncl(p.g.typeInfoGenerated, t.id): return
  118. case t.kind
  119. of tyDistinct:
  120. result = genTypeInfo(p, t.skipModifier)
  121. of tyPointer, tyProc, tyBool, tyChar, tyCstring, tyString, tyInt..tyUInt64:
  122. var s =
  123. "var $1 = {size: 0,kind: $2,base: null,node: null,finalizer: null};$n" %
  124. [result, rope(ord(t.kind))]
  125. prepend(p.g.typeInfo, s)
  126. of tyVar, tyLent, tyRef, tyPtr, tySequence, tyRange, tySet, tyOpenArray:
  127. var s =
  128. "var $1 = {size: 0, kind: $2, base: null, node: null, finalizer: null};$n" %
  129. [result, rope(ord(t.kind))]
  130. prepend(p.g.typeInfo, s)
  131. p.g.typeInfo.addf("$1.base = $2;$n",
  132. [result, genTypeInfo(p, t.elementType)])
  133. of tyArray:
  134. var s =
  135. "var $1 = {size: 0, kind: $2, base: null, node: null, finalizer: null};$n" %
  136. [result, rope(ord(t.kind))]
  137. prepend(p.g.typeInfo, s)
  138. p.g.typeInfo.addf("$1.base = $2;$n",
  139. [result, genTypeInfo(p, t.elementType)])
  140. of tyEnum: genEnumInfo(p, t, result)
  141. of tyObject: genObjectInfo(p, t, result)
  142. of tyTuple: genTupleInfo(p, t, result)
  143. of tyStatic:
  144. if t.n != nil: result = genTypeInfo(p, skipModifier t)
  145. else: internalError(p.config, "genTypeInfo(" & $t.kind & ')')
  146. else: internalError(p.config, "genTypeInfo(" & $t.kind & ')')