magicsys.nim 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  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 newSysType(g: ModuleGraph; kind: TTypeKind, size: int): PType =
  16. result = newType(kind, g.idgen, g.systemModule)
  17. result.size = size
  18. result.align = size.int16
  19. proc getSysSym*(g: ModuleGraph; info: TLineInfo; name: string): PSym =
  20. result = systemModuleSym(g, getIdent(g.cache, name))
  21. if result == nil:
  22. localError(g.config, info, "system module needs: " & name)
  23. result = newSym(skError, getIdent(g.cache, name), g.idgen, g.systemModule, g.systemModule.info, {})
  24. result.typ = newType(tyError, g.idgen, g.systemModule)
  25. proc getSysMagic*(g: ModuleGraph; info: TLineInfo; name: string, m: TMagic): PSym =
  26. result = nil
  27. let id = getIdent(g.cache, name)
  28. for r in systemModuleSyms(g, id):
  29. if r.magic == m:
  30. # prefer the tyInt variant:
  31. if r.typ.returnType != nil and r.typ.returnType.kind == tyInt: return r
  32. result = r
  33. if result != nil: return result
  34. localError(g.config, info, "system module needs: " & name)
  35. result = newSym(skError, id, g.idgen, g.systemModule, g.systemModule.info, {})
  36. result.typ = newType(tyError, g.idgen, g.systemModule)
  37. proc sysTypeFromName*(g: ModuleGraph; info: TLineInfo; name: string): PType =
  38. result = getSysSym(g, info, name).typ
  39. proc getSysType*(g: ModuleGraph; info: TLineInfo; kind: TTypeKind): PType =
  40. template sysTypeFromName(s: string): untyped = sysTypeFromName(g, info, s)
  41. result = g.sysTypes[kind]
  42. if result == nil:
  43. case kind
  44. of tyVoid: result = sysTypeFromName("void")
  45. of tyInt: result = sysTypeFromName("int")
  46. of tyInt8: result = sysTypeFromName("int8")
  47. of tyInt16: result = sysTypeFromName("int16")
  48. of tyInt32: result = sysTypeFromName("int32")
  49. of tyInt64: result = sysTypeFromName("int64")
  50. of tyUInt: result = sysTypeFromName("uint")
  51. of tyUInt8: result = sysTypeFromName("uint8")
  52. of tyUInt16: result = sysTypeFromName("uint16")
  53. of tyUInt32: result = sysTypeFromName("uint32")
  54. of tyUInt64: result = sysTypeFromName("uint64")
  55. of tyFloat: result = sysTypeFromName("float")
  56. of tyFloat32: result = sysTypeFromName("float32")
  57. of tyFloat64: result = sysTypeFromName("float64")
  58. of tyFloat128: result = sysTypeFromName("float128")
  59. of tyBool: result = sysTypeFromName("bool")
  60. of tyChar: result = sysTypeFromName("char")
  61. of tyString: result = sysTypeFromName("string")
  62. of tyCstring: result = sysTypeFromName("cstring")
  63. of tyPointer: result = sysTypeFromName("pointer")
  64. of tyNil: result = newSysType(g, tyNil, g.config.target.ptrSize)
  65. else: internalError(g.config, "request for typekind: " & $kind)
  66. g.sysTypes[kind] = result
  67. if result.kind != kind:
  68. if kind == tyFloat64 and result.kind == tyFloat: discard # because of aliasing
  69. else:
  70. internalError(g.config, "wanted: " & $kind & " got: " & $result.kind)
  71. if result == nil: internalError(g.config, "type not found: " & $kind)
  72. proc resetSysTypes*(g: ModuleGraph) =
  73. g.systemModule = nil
  74. g.compilerprocs = initStrTable()
  75. g.exposed = initStrTable()
  76. for i in low(g.sysTypes)..high(g.sysTypes):
  77. g.sysTypes[i] = nil
  78. proc getFloatLitType*(g: ModuleGraph; literal: PNode): PType =
  79. # for now we do not cache these:
  80. result = newSysType(g, tyFloat, size=8)
  81. result.n = literal
  82. proc skipIntLit*(t: PType; id: IdGenerator): PType {.inline.} =
  83. if t.n != nil and t.kind in {tyInt, tyFloat}:
  84. result = copyType(t, id, t.owner)
  85. result.n = nil
  86. else:
  87. result = t
  88. proc addSonSkipIntLit*(father, son: PType; id: IdGenerator) =
  89. let s = son.skipIntLit(id)
  90. father.add(s)
  91. propagateToOwner(father, s)
  92. proc makeVarType*(owner: PSym; baseType: PType; idgen: IdGenerator; kind = tyVar): PType =
  93. if baseType.kind == kind:
  94. result = baseType
  95. else:
  96. result = newType(kind, idgen, owner)
  97. addSonSkipIntLit(result, baseType, idgen)
  98. proc getCompilerProc*(g: ModuleGraph; name: string): PSym =
  99. let ident = getIdent(g.cache, name)
  100. result = strTableGet(g.compilerprocs, ident)
  101. if result == nil:
  102. result = loadCompilerProc(g, name)
  103. proc registerCompilerProc*(g: ModuleGraph; s: PSym) =
  104. strTableAdd(g.compilerprocs, s)
  105. proc registerNimScriptSymbol*(g: ModuleGraph; s: PSym) =
  106. # Nimscript symbols must be al unique:
  107. let conflict = strTableGet(g.exposed, s.name)
  108. if conflict == nil:
  109. strTableAdd(g.exposed, s)
  110. else:
  111. localError(g.config, s.info,
  112. "symbol conflicts with other .exportNims symbol at: " & g.config$conflict.info)
  113. proc getNimScriptSymbol*(g: ModuleGraph; name: string): PSym =
  114. strTableGet(g.exposed, getIdent(g.cache, name))
  115. proc resetNimScriptSymbols*(g: ModuleGraph) = g.exposed = initStrTable()
  116. proc getMagicEqSymForType*(g: ModuleGraph; t: PType; info: TLineInfo): PSym =
  117. case t.kind
  118. of tyInt, tyInt8, tyInt16, tyInt32, tyInt64,
  119. tyUInt, tyUInt8, tyUInt16, tyUInt32, tyUInt64:
  120. result = getSysMagic(g, info, "==", mEqI)
  121. of tyEnum:
  122. result = getSysMagic(g, info, "==", mEqEnum)
  123. of tyBool:
  124. result = getSysMagic(g, info, "==", mEqB)
  125. of tyRef, tyPtr, tyPointer:
  126. result = getSysMagic(g, info, "==", mEqRef)
  127. of tyString:
  128. result = getSysMagic(g, info, "==", mEqStr)
  129. of tyChar:
  130. result = getSysMagic(g, info, "==", mEqCh)
  131. of tySet:
  132. result = getSysMagic(g, info, "==", mEqSet)
  133. of tyProc:
  134. result = getSysMagic(g, info, "==", mEqProc)
  135. else:
  136. result = nil
  137. globalError(g.config, info,
  138. "can't find magic equals operator for type kind " & $t.kind)
  139. proc makePtrType*(baseType: PType; idgen: IdGenerator): PType =
  140. result = newType(tyPtr, idgen, baseType.owner)
  141. addSonSkipIntLit(result, baseType, idgen)
  142. proc makeAddr*(n: PNode; idgen: IdGenerator): PNode =
  143. if n.kind == nkHiddenAddr:
  144. result = n
  145. else:
  146. result = newTree(nkHiddenAddr, n)
  147. result.typ() = makePtrType(n.typ, idgen)