magicsys.nim 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. #
  2. #
  3. # The Nim Compiler
  4. # (c) Copyright 2012 Andreas Rumpf
  5. #
  6. # See the file "copying.txt", included in this
  7. # distribution, for details about the copyright.
  8. #
  9. # Built-in types and compilerprocs are registered here.
  10. import
  11. ast, astalgo, msgs, platform, idents,
  12. modulegraphs, lineinfos
  13. export createMagic
  14. proc nilOrSysInt*(g: ModuleGraph): PType = g.sysTypes[tyInt]
  15. proc registerSysType*(g: ModuleGraph; t: PType) =
  16. if g.sysTypes[t.kind] == nil: g.sysTypes[t.kind] = t
  17. proc newSysType(g: ModuleGraph; kind: TTypeKind, size: int): PType =
  18. result = newType(kind, g.systemModule)
  19. result.size = size
  20. result.align = size.int16
  21. proc getSysSym*(g: ModuleGraph; info: TLineInfo; name: string): PSym =
  22. result = strTableGet(g.systemModule.tab, getIdent(g.cache, name))
  23. if result == nil:
  24. localError(g.config, info, "system module needs: " & name)
  25. result = newSym(skError, getIdent(g.cache, name), g.systemModule, g.systemModule.info, {})
  26. result.typ = newType(tyError, g.systemModule)
  27. if result.kind == skAlias: result = result.owner
  28. proc getSysMagic*(g: ModuleGraph; info: TLineInfo; name: string, m: TMagic): PSym =
  29. var ti: TIdentIter
  30. let id = getIdent(g.cache, name)
  31. var r = initIdentIter(ti, g.systemModule.tab, id)
  32. while r != nil:
  33. if r.magic == m:
  34. # prefer the tyInt variant:
  35. if r.typ[0] != nil and r.typ[0].kind == tyInt: return r
  36. result = r
  37. r = nextIdentIter(ti, g.systemModule.tab)
  38. if result != nil: return result
  39. localError(g.config, info, "system module needs: " & name)
  40. result = newSym(skError, id, g.systemModule, g.systemModule.info, {})
  41. result.typ = newType(tyError, g.systemModule)
  42. proc sysTypeFromName*(g: ModuleGraph; info: TLineInfo; name: string): PType =
  43. result = getSysSym(g, info, name).typ
  44. proc getSysType*(g: ModuleGraph; info: TLineInfo; kind: TTypeKind): PType =
  45. template sysTypeFromName(s: string): untyped = sysTypeFromName(g, info, s)
  46. result = g.sysTypes[kind]
  47. if result == nil:
  48. case kind
  49. of tyInt: result = sysTypeFromName("int")
  50. of tyInt8: result = sysTypeFromName("int8")
  51. of tyInt16: result = sysTypeFromName("int16")
  52. of tyInt32: result = sysTypeFromName("int32")
  53. of tyInt64: result = sysTypeFromName("int64")
  54. of tyUInt: result = sysTypeFromName("uint")
  55. of tyUInt8: result = sysTypeFromName("uint8")
  56. of tyUInt16: result = sysTypeFromName("uint16")
  57. of tyUInt32: result = sysTypeFromName("uint32")
  58. of tyUInt64: result = sysTypeFromName("uint64")
  59. of tyFloat: result = sysTypeFromName("float")
  60. of tyFloat32: result = sysTypeFromName("float32")
  61. of tyFloat64: result = sysTypeFromName("float64")
  62. of tyFloat128: result = sysTypeFromName("float128")
  63. of tyBool: result = sysTypeFromName("bool")
  64. of tyChar: result = sysTypeFromName("char")
  65. of tyString: result = sysTypeFromName("string")
  66. of tyCString: result = sysTypeFromName("cstring")
  67. of tyPointer: result = sysTypeFromName("pointer")
  68. of tyNil: result = newSysType(g, tyNil, g.config.target.ptrSize)
  69. else: internalError(g.config, "request for typekind: " & $kind)
  70. g.sysTypes[kind] = result
  71. if result.kind != kind:
  72. if kind == tyFloat64 and result.kind == tyFloat: discard # because of aliasing
  73. else:
  74. internalError(g.config, "wanted: " & $kind & " got: " & $result.kind)
  75. if result == nil: internalError(g.config, "type not found: " & $kind)
  76. proc resetSysTypes*(g: ModuleGraph) =
  77. g.systemModule = nil
  78. initStrTable(g.compilerprocs)
  79. initStrTable(g.exposed)
  80. for i in low(g.sysTypes)..high(g.sysTypes):
  81. g.sysTypes[i] = nil
  82. for i in low(g.intTypeCache)..high(g.intTypeCache):
  83. g.intTypeCache[i] = nil
  84. proc getIntLitType*(g: ModuleGraph; literal: PNode): PType =
  85. # we cache some common integer literal types for performance:
  86. let value = literal.intVal
  87. if value >= low(g.intTypeCache) and value <= high(g.intTypeCache):
  88. result = g.intTypeCache[value.int]
  89. if result == nil:
  90. let ti = getSysType(g, literal.info, tyInt)
  91. result = copyType(ti, ti.owner, false)
  92. result.n = literal
  93. g.intTypeCache[value.int] = result
  94. else:
  95. let ti = getSysType(g, literal.info, tyInt)
  96. result = copyType(ti, ti.owner, false)
  97. result.n = literal
  98. proc getFloatLitType*(g: ModuleGraph; literal: PNode): PType =
  99. # for now we do not cache these:
  100. result = newSysType(g, tyFloat, size=8)
  101. result.n = literal
  102. proc skipIntLit*(t: PType): PType {.inline.} =
  103. if t.n != nil and t.kind in {tyInt, tyFloat}:
  104. result = copyType(t, t.owner, false)
  105. result.n = nil
  106. else:
  107. result = t
  108. proc addSonSkipIntLit*(father, son: PType) =
  109. when not defined(nimNoNilSeqs):
  110. if isNil(father.sons): father.sons = @[]
  111. let s = son.skipIntLit
  112. father.sons.add(s)
  113. propagateToOwner(father, s)
  114. proc setIntLitType*(g: ModuleGraph; result: PNode) =
  115. let i = result.intVal
  116. case g.config.target.intSize
  117. of 8: result.typ = getIntLitType(g, result)
  118. of 4:
  119. if i >= low(int32) and i <= high(int32):
  120. result.typ = getIntLitType(g, result)
  121. else:
  122. result.typ = getSysType(g, result.info, tyInt64)
  123. of 2:
  124. if i >= low(int16) and i <= high(int16):
  125. result.typ = getIntLitType(g, result)
  126. elif i >= low(int32) and i <= high(int32):
  127. result.typ = getSysType(g, result.info, tyInt32)
  128. else:
  129. result.typ = getSysType(g, result.info, tyInt64)
  130. of 1:
  131. # 8 bit CPUs are insane ...
  132. if i >= low(int8) and i <= high(int8):
  133. result.typ = getIntLitType(g, result)
  134. elif i >= low(int16) and i <= high(int16):
  135. result.typ = getSysType(g, result.info, tyInt16)
  136. elif i >= low(int32) and i <= high(int32):
  137. result.typ = getSysType(g, result.info, tyInt32)
  138. else:
  139. result.typ = getSysType(g, result.info, tyInt64)
  140. else:
  141. internalError(g.config, result.info, "invalid int size")
  142. proc getCompilerProc*(g: ModuleGraph; name: string): PSym =
  143. let ident = getIdent(g.cache, name)
  144. result = strTableGet(g.compilerprocs, ident)
  145. proc registerCompilerProc*(g: ModuleGraph; s: PSym) =
  146. strTableAdd(g.compilerprocs, s)
  147. proc registerNimScriptSymbol*(g: ModuleGraph; s: PSym) =
  148. # Nimscript symbols must be al unique:
  149. let conflict = strTableGet(g.exposed, s.name)
  150. if conflict == nil:
  151. strTableAdd(g.exposed, s)
  152. else:
  153. localError(g.config, s.info,
  154. "symbol conflicts with other .exportNims symbol at: " & g.config$conflict.info)
  155. proc getNimScriptSymbol*(g: ModuleGraph; name: string): PSym =
  156. strTableGet(g.exposed, getIdent(g.cache, name))
  157. proc resetNimScriptSymbols*(g: ModuleGraph) = initStrTable(g.exposed)
  158. proc getMagicEqSymForType*(g: ModuleGraph; t: PType; info: TLineInfo): PSym =
  159. case t.kind
  160. of tyInt, tyInt8, tyInt16, tyInt32, tyInt64,
  161. tyUInt, tyUInt8, tyUInt16, tyUInt32, tyUInt64:
  162. result = getSysMagic(g, info, "==", mEqI)
  163. of tyEnum:
  164. result = getSysMagic(g, info, "==", mEqEnum)
  165. of tyBool:
  166. result = getSysMagic(g, info, "==", mEqB)
  167. of tyRef, tyPtr, tyPointer:
  168. result = getSysMagic(g, info, "==", mEqRef)
  169. of tyString:
  170. result = getSysMagic(g, info, "==", mEqStr)
  171. of tyChar:
  172. result = getSysMagic(g, info, "==", mEqCh)
  173. of tySet:
  174. result = getSysMagic(g, info, "==", mEqSet)
  175. of tyProc:
  176. result = getSysMagic(g, info, "==", mEqProc)
  177. else:
  178. globalError(g.config, info,
  179. "can't find magic equals operator for type kind " & $t.kind)