ast.nim 79 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117
  1. #
  2. #
  3. # The Nim Compiler
  4. # (c) Copyright 2015 Andreas Rumpf
  5. #
  6. # See the file "copying.txt", included in this
  7. # distribution, for details about the copyright.
  8. #
  9. # abstract syntax tree + symbol table
  10. import
  11. lineinfos, hashes, options, ropes, idents, int128, tables
  12. from strutils import toLowerAscii
  13. export int128
  14. type
  15. TCallingConvention* = enum
  16. ccNimCall = "nimcall" # nimcall, also the default
  17. ccStdCall = "stdcall" # procedure is stdcall
  18. ccCDecl = "cdecl" # cdecl
  19. ccSafeCall = "safecall" # safecall
  20. ccSysCall = "syscall" # system call
  21. ccInline = "inline" # proc should be inlined
  22. ccNoInline = "noinline" # proc should not be inlined
  23. ccFastCall = "fastcall" # fastcall (pass parameters in registers)
  24. ccThisCall = "thiscall" # thiscall (parameters are pushed right-to-left)
  25. ccClosure = "closure" # proc has a closure
  26. ccNoConvention = "noconv" # needed for generating proper C procs sometimes
  27. type
  28. TNodeKind* = enum # order is extremely important, because ranges are used
  29. # to check whether a node belongs to a certain class
  30. nkNone, # unknown node kind: indicates an error
  31. # Expressions:
  32. # Atoms:
  33. nkEmpty, # the node is empty
  34. nkIdent, # node is an identifier
  35. nkSym, # node is a symbol
  36. nkType, # node is used for its typ field
  37. nkCharLit, # a character literal ''
  38. nkIntLit, # an integer literal
  39. nkInt8Lit,
  40. nkInt16Lit,
  41. nkInt32Lit,
  42. nkInt64Lit,
  43. nkUIntLit, # an unsigned integer literal
  44. nkUInt8Lit,
  45. nkUInt16Lit,
  46. nkUInt32Lit,
  47. nkUInt64Lit,
  48. nkFloatLit, # a floating point literal
  49. nkFloat32Lit,
  50. nkFloat64Lit,
  51. nkFloat128Lit,
  52. nkStrLit, # a string literal ""
  53. nkRStrLit, # a raw string literal r""
  54. nkTripleStrLit, # a triple string literal """
  55. nkNilLit, # the nil literal
  56. # end of atoms
  57. nkComesFrom, # "comes from" template/macro information for
  58. # better stack trace generation
  59. nkDotCall, # used to temporarily flag a nkCall node;
  60. # this is used
  61. # for transforming ``s.len`` to ``len(s)``
  62. nkCommand, # a call like ``p 2, 4`` without parenthesis
  63. nkCall, # a call like p(x, y) or an operation like +(a, b)
  64. nkCallStrLit, # a call with a string literal
  65. # x"abc" has two sons: nkIdent, nkRStrLit
  66. # x"""abc""" has two sons: nkIdent, nkTripleStrLit
  67. nkInfix, # a call like (a + b)
  68. nkPrefix, # a call like !a
  69. nkPostfix, # something like a! (also used for visibility)
  70. nkHiddenCallConv, # an implicit type conversion via a type converter
  71. nkExprEqExpr, # a named parameter with equals: ''expr = expr''
  72. nkExprColonExpr, # a named parameter with colon: ''expr: expr''
  73. nkIdentDefs, # a definition like `a, b: typeDesc = expr`
  74. # either typeDesc or expr may be nil; used in
  75. # formal parameters, var statements, etc.
  76. nkVarTuple, # a ``var (a, b) = expr`` construct
  77. nkPar, # syntactic (); may be a tuple constructor
  78. nkObjConstr, # object constructor: T(a: 1, b: 2)
  79. nkCurly, # syntactic {}
  80. nkCurlyExpr, # an expression like a{i}
  81. nkBracket, # syntactic []
  82. nkBracketExpr, # an expression like a[i..j, k]
  83. nkPragmaExpr, # an expression like a{.pragmas.}
  84. nkRange, # an expression like i..j
  85. nkDotExpr, # a.b
  86. nkCheckedFieldExpr, # a.b, but b is a field that needs to be checked
  87. nkDerefExpr, # a^
  88. nkIfExpr, # if as an expression
  89. nkElifExpr,
  90. nkElseExpr,
  91. nkLambda, # lambda expression
  92. nkDo, # lambda block appering as trailing proc param
  93. nkAccQuoted, # `a` as a node
  94. nkTableConstr, # a table constructor {expr: expr}
  95. nkBind, # ``bind expr`` node
  96. nkClosedSymChoice, # symbol choice node; a list of nkSyms (closed)
  97. nkOpenSymChoice, # symbol choice node; a list of nkSyms (open)
  98. nkHiddenStdConv, # an implicit standard type conversion
  99. nkHiddenSubConv, # an implicit type conversion from a subtype
  100. # to a supertype
  101. nkConv, # a type conversion
  102. nkCast, # a type cast
  103. nkStaticExpr, # a static expr
  104. nkAddr, # a addr expression
  105. nkHiddenAddr, # implicit address operator
  106. nkHiddenDeref, # implicit ^ operator
  107. nkObjDownConv, # down conversion between object types
  108. nkObjUpConv, # up conversion between object types
  109. nkChckRangeF, # range check for floats
  110. nkChckRange64, # range check for 64 bit ints
  111. nkChckRange, # range check for ints
  112. nkStringToCString, # string to cstring
  113. nkCStringToString, # cstring to string
  114. # end of expressions
  115. nkAsgn, # a = b
  116. nkFastAsgn, # internal node for a fast ``a = b``
  117. # (no string copy)
  118. nkGenericParams, # generic parameters
  119. nkFormalParams, # formal parameters
  120. nkOfInherit, # inherited from symbol
  121. nkImportAs, # a 'as' b in an import statement
  122. nkProcDef, # a proc
  123. nkMethodDef, # a method
  124. nkConverterDef, # a converter
  125. nkMacroDef, # a macro
  126. nkTemplateDef, # a template
  127. nkIteratorDef, # an iterator
  128. nkOfBranch, # used inside case statements
  129. # for (cond, action)-pairs
  130. nkElifBranch, # used in if statements
  131. nkExceptBranch, # an except section
  132. nkElse, # an else part
  133. nkAsmStmt, # an assembler block
  134. nkPragma, # a pragma statement
  135. nkPragmaBlock, # a pragma with a block
  136. nkIfStmt, # an if statement
  137. nkWhenStmt, # a when expression or statement
  138. nkForStmt, # a for statement
  139. nkParForStmt, # a parallel for statement
  140. nkWhileStmt, # a while statement
  141. nkCaseStmt, # a case statement
  142. nkTypeSection, # a type section (consists of type definitions)
  143. nkVarSection, # a var section
  144. nkLetSection, # a let section
  145. nkConstSection, # a const section
  146. nkConstDef, # a const definition
  147. nkTypeDef, # a type definition
  148. nkYieldStmt, # the yield statement as a tree
  149. nkDefer, # the 'defer' statement
  150. nkTryStmt, # a try statement
  151. nkFinally, # a finally section
  152. nkRaiseStmt, # a raise statement
  153. nkReturnStmt, # a return statement
  154. nkBreakStmt, # a break statement
  155. nkContinueStmt, # a continue statement
  156. nkBlockStmt, # a block statement
  157. nkStaticStmt, # a static statement
  158. nkDiscardStmt, # a discard statement
  159. nkStmtList, # a list of statements
  160. nkImportStmt, # an import statement
  161. nkImportExceptStmt, # an import x except a statement
  162. nkExportStmt, # an export statement
  163. nkExportExceptStmt, # an 'export except' statement
  164. nkFromStmt, # a from * import statement
  165. nkIncludeStmt, # an include statement
  166. nkBindStmt, # a bind statement
  167. nkMixinStmt, # a mixin statement
  168. nkUsingStmt, # an using statement
  169. nkCommentStmt, # a comment statement
  170. nkStmtListExpr, # a statement list followed by an expr; this is used
  171. # to allow powerful multi-line templates
  172. nkBlockExpr, # a statement block ending in an expr; this is used
  173. # to allow powerful multi-line templates that open a
  174. # temporary scope
  175. nkStmtListType, # a statement list ending in a type; for macros
  176. nkBlockType, # a statement block ending in a type; for macros
  177. # types as syntactic trees:
  178. nkWith, # distinct with `foo`
  179. nkWithout, # distinct without `foo`
  180. nkTypeOfExpr, # type(1+2)
  181. nkObjectTy, # object body
  182. nkTupleTy, # tuple body
  183. nkTupleClassTy, # tuple type class
  184. nkTypeClassTy, # user-defined type class
  185. nkStaticTy, # ``static[T]``
  186. nkRecList, # list of object parts
  187. nkRecCase, # case section of object
  188. nkRecWhen, # when section of object
  189. nkRefTy, # ``ref T``
  190. nkPtrTy, # ``ptr T``
  191. nkVarTy, # ``var T``
  192. nkConstTy, # ``const T``
  193. nkMutableTy, # ``mutable T``
  194. nkDistinctTy, # distinct type
  195. nkProcTy, # proc type
  196. nkIteratorTy, # iterator type
  197. nkSharedTy, # 'shared T'
  198. # we use 'nkPostFix' for the 'not nil' addition
  199. nkEnumTy, # enum body
  200. nkEnumFieldDef, # `ident = expr` in an enumeration
  201. nkArgList, # argument list
  202. nkPattern, # a special pattern; used for matching
  203. nkHiddenTryStmt, # a hidden try statement
  204. nkClosure, # (prc, env)-pair (internally used for code gen)
  205. nkGotoState, # used for the state machine (for iterators)
  206. nkState, # give a label to a code section (for iterators)
  207. nkBreakState, # special break statement for easier code generation
  208. nkFuncDef, # a func
  209. nkTupleConstr # a tuple constructor
  210. nkError # erroneous AST node
  211. nkModuleRef # for .rod file support: A (moduleId, itemId) pair
  212. nkReplayAction # for .rod file support: A replay action
  213. nkNilRodNode # for .rod file support: a 'nil' PNode
  214. TNodeKinds* = set[TNodeKind]
  215. type
  216. TSymFlag* = enum # 49 flags!
  217. sfUsed, # read access of sym (for warnings) or simply used
  218. sfExported, # symbol is exported from module
  219. sfFromGeneric, # symbol is instantiation of a generic; this is needed
  220. # for symbol file generation; such symbols should always
  221. # be written into the ROD file
  222. sfGlobal, # symbol is at global scope
  223. sfForward, # symbol is forward declared
  224. sfWasForwarded, # symbol had a forward declaration
  225. # (implies it's too dangerous to patch its type signature)
  226. sfImportc, # symbol is external; imported
  227. sfExportc, # symbol is exported (under a specified name)
  228. sfMangleCpp, # mangle as cpp (combines with `sfExportc`)
  229. sfVolatile, # variable is volatile
  230. sfRegister, # variable should be placed in a register
  231. sfPure, # object is "pure" that means it has no type-information
  232. # enum is "pure", its values need qualified access
  233. # variable is "pure"; it's an explicit "global"
  234. sfNoSideEffect, # proc has no side effects
  235. sfSideEffect, # proc may have side effects; cannot prove it has none
  236. sfMainModule, # module is the main module
  237. sfSystemModule, # module is the system module
  238. sfNoReturn, # proc never returns (an exit proc)
  239. sfAddrTaken, # the variable's address is taken (ex- or implicitly);
  240. # *OR*: a proc is indirectly called (used as first class)
  241. sfCompilerProc, # proc is a compiler proc, that is a C proc that is
  242. # needed for the code generator
  243. sfProcvar, # proc can be passed to a proc var
  244. sfDiscriminant, # field is a discriminant in a record/object
  245. sfRequiresInit, # field must be initialized during construction
  246. sfDeprecated, # symbol is deprecated
  247. sfExplain, # provide more diagnostics when this symbol is used
  248. sfError, # usage of symbol should trigger a compile-time error
  249. sfShadowed, # a symbol that was shadowed in some inner scope
  250. sfThread, # proc will run as a thread
  251. # variable is a thread variable
  252. sfCppNonPod, # tells compiler to treat such types as non-pod's, so that
  253. # `thread_local` is used instead of `__thread` for
  254. # {.threadvar.} + `--threads`. Only makes sense for importcpp types.
  255. # This has a performance impact so isn't set by default.
  256. sfCompileTime, # proc can be evaluated at compile time
  257. sfConstructor, # proc is a C++ constructor
  258. sfDispatcher, # copied method symbol is the dispatcher
  259. # deprecated and unused, except for the con
  260. sfBorrow, # proc is borrowed
  261. sfInfixCall, # symbol needs infix call syntax in target language;
  262. # for interfacing with C++, JS
  263. sfNamedParamCall, # symbol needs named parameter call syntax in target
  264. # language; for interfacing with Objective C
  265. sfDiscardable, # returned value may be discarded implicitly
  266. sfOverriden, # proc is overridden
  267. sfCallsite # A flag for template symbols to tell the
  268. # compiler it should use line information from
  269. # the calling side of the macro, not from the
  270. # implementation.
  271. sfGenSym # symbol is 'gensym'ed; do not add to symbol table
  272. sfNonReloadable # symbol will be left as-is when hot code reloading is on -
  273. # meaning that it won't be renamed and/or changed in any way
  274. sfGeneratedOp # proc is a generated '='; do not inject destructors in it
  275. # variable is generated closure environment; requires early
  276. # destruction for --newruntime.
  277. sfTemplateParam # symbol is a template parameter
  278. sfCursor # variable/field is a cursor, see RFC 177 for details
  279. sfInjectDestructors # whether the proc needs the 'injectdestructors' transformation
  280. sfNeverRaises # proc can never raise an exception, not even OverflowDefect
  281. # or out-of-memory
  282. sfUsedInFinallyOrExcept # symbol is used inside an 'except' or 'finally'
  283. sfSingleUsedTemp # For temporaries that we know will only be used once
  284. sfNoalias # 'noalias' annotation, means C's 'restrict'
  285. sfEffectsDelayed # an 'effectsDelayed' parameter
  286. sfGeneratedType # A anonymous generic type that is generated by the compiler for
  287. # objects that do not have generic parameters in case one of the
  288. # object fields has one.
  289. #
  290. # This is disallowed but can cause the typechecking to go into
  291. # an infinite loop, this flag is used as a sentinel to stop it.
  292. TSymFlags* = set[TSymFlag]
  293. const
  294. sfNoInit* = sfMainModule # don't generate code to init the variable
  295. sfAllUntyped* = sfVolatile # macro or template is immediately expanded \
  296. # in a generic context
  297. sfDirty* = sfPure
  298. # template is not hygienic (old styled template)
  299. # module, compiled from a dirty-buffer
  300. sfAnon* = sfDiscardable
  301. # symbol name that was generated by the compiler
  302. # the compiler will avoid printing such names
  303. # in user messages.
  304. sfNoForward* = sfRegister
  305. # forward declarations are not required (per module)
  306. sfReorder* = sfForward
  307. # reordering pass is enabled
  308. sfCompileToCpp* = sfInfixCall # compile the module as C++ code
  309. sfCompileToObjc* = sfNamedParamCall # compile the module as Objective-C code
  310. sfExperimental* = sfOverriden # module uses the .experimental switch
  311. sfGoto* = sfOverriden # var is used for 'goto' code generation
  312. sfWrittenTo* = sfBorrow # param is assigned to
  313. sfEscapes* = sfProcvar # param escapes
  314. sfBase* = sfDiscriminant
  315. sfIsSelf* = sfOverriden # param is 'self'
  316. sfCustomPragma* = sfRegister # symbol is custom pragma template
  317. const
  318. # getting ready for the future expr/stmt merge
  319. nkWhen* = nkWhenStmt
  320. nkWhenExpr* = nkWhenStmt
  321. nkEffectList* = nkArgList
  322. # hacks ahead: an nkEffectList is a node with 4 children:
  323. exceptionEffects* = 0 # exceptions at position 0
  324. requiresEffects* = 1 # 'requires' annotation
  325. ensuresEffects* = 2 # 'ensures' annotation
  326. tagEffects* = 3 # user defined tag ('gc', 'time' etc.)
  327. pragmasEffects* = 4 # not an effect, but a slot for pragmas in proc type
  328. effectListLen* = 5 # list of effects list
  329. nkLastBlockStmts* = {nkRaiseStmt, nkReturnStmt, nkBreakStmt, nkContinueStmt}
  330. # these must be last statements in a block
  331. type
  332. TTypeKind* = enum # order is important!
  333. # Don't forget to change hti.nim if you make a change here
  334. # XXX put this into an include file to avoid this issue!
  335. # several types are no longer used (guess which), but a
  336. # spot in the sequence is kept for backwards compatibility
  337. # (apparently something with bootstrapping)
  338. # if you need to add a type, they can apparently be reused
  339. tyNone, tyBool, tyChar,
  340. tyEmpty, tyAlias, tyNil, tyUntyped, tyTyped, tyTypeDesc,
  341. tyGenericInvocation, # ``T[a, b]`` for types to invoke
  342. tyGenericBody, # ``T[a, b, body]`` last parameter is the body
  343. tyGenericInst, # ``T[a, b, realInstance]`` instantiated generic type
  344. # realInstance will be a concrete type like tyObject
  345. # unless this is an instance of a generic alias type.
  346. # then realInstance will be the tyGenericInst of the
  347. # completely (recursively) resolved alias.
  348. tyGenericParam, # ``a`` in the above patterns
  349. tyDistinct,
  350. tyEnum,
  351. tyOrdinal, # integer types (including enums and boolean)
  352. tyArray,
  353. tyObject,
  354. tyTuple,
  355. tySet,
  356. tyRange,
  357. tyPtr, tyRef,
  358. tyVar,
  359. tySequence,
  360. tyProc,
  361. tyPointer, tyOpenArray,
  362. tyString, tyCstring, tyForward,
  363. tyInt, tyInt8, tyInt16, tyInt32, tyInt64, # signed integers
  364. tyFloat, tyFloat32, tyFloat64, tyFloat128,
  365. tyUInt, tyUInt8, tyUInt16, tyUInt32, tyUInt64,
  366. tyOwned, tySink, tyLent,
  367. tyVarargs,
  368. tyUncheckedArray
  369. # An array with boundaries [0,+∞]
  370. tyProxy # used as errornous type (for idetools)
  371. tyBuiltInTypeClass
  372. # Type such as the catch-all object, tuple, seq, etc
  373. tyUserTypeClass
  374. # the body of a user-defined type class
  375. tyUserTypeClassInst
  376. # Instance of a parametric user-defined type class.
  377. # Structured similarly to tyGenericInst.
  378. # tyGenericInst represents concrete types, while
  379. # this is still a "generic param" that will bind types
  380. # and resolves them during sigmatch and instantiation.
  381. tyCompositeTypeClass
  382. # Type such as seq[Number]
  383. # The notes for tyUserTypeClassInst apply here as well
  384. # sons[0]: the original expression used by the user.
  385. # sons[1]: fully expanded and instantiated meta type
  386. # (potentially following aliases)
  387. tyInferred
  388. # In the initial state `base` stores a type class constraining
  389. # the types that can be inferred. After a candidate type is
  390. # selected, it's stored in `lastSon`. Between `base` and `lastSon`
  391. # there may be 0, 2 or more types that were also considered as
  392. # possible candidates in the inference process (i.e. lastSon will
  393. # be updated to store a type best conforming to all candidates)
  394. tyAnd, tyOr, tyNot
  395. # boolean type classes such as `string|int`,`not seq`,
  396. # `Sortable and Enumable`, etc
  397. tyAnything
  398. # a type class matching any type
  399. tyStatic
  400. # a value known at compile type (the underlying type is .base)
  401. tyFromExpr
  402. # This is a type representing an expression that depends
  403. # on generic parameters (the expression is stored in t.n)
  404. # It will be converted to a real type only during generic
  405. # instantiation and prior to this it has the potential to
  406. # be any type.
  407. tyConcept
  408. # new style concept.
  409. tyVoid
  410. # now different from tyEmpty, hurray!
  411. tyIterable
  412. static:
  413. # remind us when TTypeKind stops to fit in a single 64-bit word
  414. # assert TTypeKind.high.ord <= 63
  415. discard
  416. const
  417. tyPureObject* = tyTuple
  418. GcTypeKinds* = {tyRef, tySequence, tyString}
  419. tyError* = tyProxy # as an errornous node should match everything
  420. tyUnknown* = tyFromExpr
  421. tyUnknownTypes* = {tyError, tyFromExpr}
  422. tyTypeClasses* = {tyBuiltInTypeClass, tyCompositeTypeClass,
  423. tyUserTypeClass, tyUserTypeClassInst,
  424. tyAnd, tyOr, tyNot, tyAnything}
  425. tyMetaTypes* = {tyGenericParam, tyTypeDesc, tyUntyped} + tyTypeClasses
  426. tyUserTypeClasses* = {tyUserTypeClass, tyUserTypeClassInst}
  427. # consider renaming as `tyAbstractVarRange`
  428. abstractVarRange* = {tyGenericInst, tyRange, tyVar, tyDistinct, tyOrdinal,
  429. tyTypeDesc, tyAlias, tyInferred, tySink, tyOwned}
  430. abstractInst* = {tyGenericInst, tyDistinct, tyOrdinal, tyTypeDesc, tyAlias,
  431. tyInferred, tySink, tyOwned} # xxx what about tyStatic?
  432. type
  433. TTypeKinds* = set[TTypeKind]
  434. TNodeFlag* = enum
  435. nfNone,
  436. nfBase2, # nfBase10 is default, so not needed
  437. nfBase8,
  438. nfBase16,
  439. nfAllConst, # used to mark complex expressions constant; easy to get rid of
  440. # but unfortunately it has measurable impact for compilation
  441. # efficiency
  442. nfTransf, # node has been transformed
  443. nfNoRewrite # node should not be transformed anymore
  444. nfSem # node has been checked for semantics
  445. nfLL # node has gone through lambda lifting
  446. nfDotField # the call can use a dot operator
  447. nfDotSetter # the call can use a setter dot operarator
  448. nfExplicitCall # x.y() was used instead of x.y
  449. nfExprCall # this is an attempt to call a regular expression
  450. nfIsRef # this node is a 'ref' node; used for the VM
  451. nfIsPtr # this node is a 'ptr' node; used for the VM
  452. nfPreventCg # this node should be ignored by the codegen
  453. nfBlockArg # this a stmtlist appearing in a call (e.g. a do block)
  454. nfFromTemplate # a top-level node returned from a template
  455. nfDefaultParam # an automatically inserter default parameter
  456. nfDefaultRefsParam # a default param value references another parameter
  457. # the flag is applied to proc default values and to calls
  458. nfExecuteOnReload # A top-level statement that will be executed during reloads
  459. nfLastRead # this node is a last read
  460. nfFirstWrite# this node is a first write
  461. nfHasComment # node has a comment
  462. nfSkipFieldChecking # node skips field visable checking
  463. TNodeFlags* = set[TNodeFlag]
  464. TTypeFlag* = enum # keep below 32 for efficiency reasons (now: 45)
  465. tfVarargs, # procedure has C styled varargs
  466. # tyArray type represeting a varargs list
  467. tfNoSideEffect, # procedure type does not allow side effects
  468. tfFinal, # is the object final?
  469. tfInheritable, # is the object inheritable?
  470. tfHasOwned, # type contains an 'owned' type and must be moved
  471. tfEnumHasHoles, # enum cannot be mapped into a range
  472. tfShallow, # type can be shallow copied on assignment
  473. tfThread, # proc type is marked as ``thread``; alias for ``gcsafe``
  474. tfFromGeneric, # type is an instantiation of a generic; this is needed
  475. # because for instantiations of objects, structural
  476. # type equality has to be used
  477. tfUnresolved, # marks unresolved typedesc/static params: e.g.
  478. # proc foo(T: typedesc, list: seq[T]): var T
  479. # proc foo(L: static[int]): array[L, int]
  480. # can be attached to ranges to indicate that the range
  481. # can be attached to generic procs with free standing
  482. # type parameters: e.g. proc foo[T]()
  483. # depends on unresolved static params.
  484. tfResolved # marks a user type class, after it has been bound to a
  485. # concrete type (lastSon becomes the concrete type)
  486. tfRetType, # marks return types in proc (used to detect type classes
  487. # used as return types for return type inference)
  488. tfCapturesEnv, # whether proc really captures some environment
  489. tfByCopy, # pass object/tuple by copy (C backend)
  490. tfByRef, # pass object/tuple by reference (C backend)
  491. tfIterator, # type is really an iterator, not a tyProc
  492. tfPartial, # type is declared as 'partial'
  493. tfNotNil, # type cannot be 'nil'
  494. tfRequiresInit, # type constains a "not nil" constraint somewhere or
  495. # a `requiresInit` field, so the default zero init
  496. # is not appropriate
  497. tfNeedsFullInit, # object type marked with {.requiresInit.}
  498. # all fields must be initialized
  499. tfVarIsPtr, # 'var' type is translated like 'ptr' even in C++ mode
  500. tfHasMeta, # type contains "wildcard" sub-types such as generic params
  501. # or other type classes
  502. tfHasGCedMem, # type contains GC'ed memory
  503. tfPacked
  504. tfHasStatic
  505. tfGenericTypeParam
  506. tfImplicitTypeParam
  507. tfInferrableStatic
  508. tfConceptMatchedTypeSym
  509. tfExplicit # for typedescs, marks types explicitly prefixed with the
  510. # `type` operator (e.g. type int)
  511. tfWildcard # consider a proc like foo[T, I](x: Type[T, I])
  512. # T and I here can bind to both typedesc and static types
  513. # before this is determined, we'll consider them to be a
  514. # wildcard type.
  515. tfHasAsgn # type has overloaded assignment operator
  516. tfBorrowDot # distinct type borrows '.'
  517. tfTriggersCompileTime # uses the NimNode type which make the proc
  518. # implicitly '.compiletime'
  519. tfRefsAnonObj # used for 'ref object' and 'ptr object'
  520. tfCovariant # covariant generic param mimicking a ptr type
  521. tfWeakCovariant # covariant generic param mimicking a seq/array type
  522. tfContravariant # contravariant generic param
  523. tfCheckedForDestructor # type was checked for having a destructor.
  524. # If it has one, t.destructor is not nil.
  525. tfAcyclic # object type was annotated as .acyclic
  526. tfIncompleteStruct # treat this type as if it had sizeof(pointer)
  527. tfCompleteStruct
  528. # (for importc types); type is fully specified, allowing to compute
  529. # sizeof, alignof, offsetof at CT
  530. tfExplicitCallConv
  531. tfIsConstructor
  532. tfEffectSystemWorkaround
  533. TTypeFlags* = set[TTypeFlag]
  534. TSymKind* = enum # the different symbols (start with the prefix sk);
  535. # order is important for the documentation generator!
  536. skUnknown, # unknown symbol: used for parsing assembler blocks
  537. # and first phase symbol lookup in generics
  538. skConditional, # symbol for the preprocessor (may become obsolete)
  539. skDynLib, # symbol represents a dynamic library; this is used
  540. # internally; it does not exist in Nim code
  541. skParam, # a parameter
  542. skGenericParam, # a generic parameter; eq in ``proc x[eq=`==`]()``
  543. skTemp, # a temporary variable (introduced by compiler)
  544. skModule, # module identifier
  545. skType, # a type
  546. skVar, # a variable
  547. skLet, # a 'let' symbol
  548. skConst, # a constant
  549. skResult, # special 'result' variable
  550. skProc, # a proc
  551. skFunc, # a func
  552. skMethod, # a method
  553. skIterator, # an iterator
  554. skConverter, # a type converter
  555. skMacro, # a macro
  556. skTemplate, # a template; currently also misused for user-defined
  557. # pragmas
  558. skField, # a field in a record or object
  559. skEnumField, # an identifier in an enum
  560. skForVar, # a for loop variable
  561. skLabel, # a label (for block statement)
  562. skStub, # symbol is a stub and not yet loaded from the ROD
  563. # file (it is loaded on demand, which may
  564. # mean: never)
  565. skPackage, # symbol is a package (used for canonicalization)
  566. skAlias # an alias (needs to be resolved immediately)
  567. TSymKinds* = set[TSymKind]
  568. const
  569. routineKinds* = {skProc, skFunc, skMethod, skIterator,
  570. skConverter, skMacro, skTemplate}
  571. ExportableSymKinds* = {skVar, skLet, skConst, skType, skEnumField, skStub, skAlias} + routineKinds
  572. tfUnion* = tfNoSideEffect
  573. tfGcSafe* = tfThread
  574. tfObjHasKids* = tfEnumHasHoles
  575. tfReturnsNew* = tfInheritable
  576. skError* = skUnknown
  577. var
  578. eqTypeFlags* = {tfIterator, tfNotNil, tfVarIsPtr, tfGcSafe, tfNoSideEffect}
  579. ## type flags that are essential for type equality.
  580. ## This is now a variable because for emulation of version:1.0 we
  581. ## might exclude {tfGcSafe, tfNoSideEffect}.
  582. type
  583. TMagic* = enum # symbols that require compiler magic:
  584. mNone,
  585. mDefined, mDeclared, mDeclaredInScope, mCompiles, mArrGet, mArrPut, mAsgn,
  586. mLow, mHigh, mSizeOf, mAlignOf, mOffsetOf, mTypeTrait,
  587. mIs, mOf, mAddr, mType, mTypeOf,
  588. mPlugin, mEcho, mShallowCopy, mSlurp, mStaticExec, mStatic,
  589. mParseExprToAst, mParseStmtToAst, mExpandToAst, mQuoteAst,
  590. mInc, mDec, mOrd,
  591. mNew, mNewFinalize, mNewSeq, mNewSeqOfCap,
  592. mLengthOpenArray, mLengthStr, mLengthArray, mLengthSeq,
  593. mIncl, mExcl, mCard, mChr,
  594. mGCref, mGCunref,
  595. mAddI, mSubI, mMulI, mDivI, mModI,
  596. mSucc, mPred,
  597. mAddF64, mSubF64, mMulF64, mDivF64,
  598. mShrI, mShlI, mAshrI, mBitandI, mBitorI, mBitxorI,
  599. mMinI, mMaxI,
  600. mAddU, mSubU, mMulU, mDivU, mModU,
  601. mEqI, mLeI, mLtI,
  602. mEqF64, mLeF64, mLtF64,
  603. mLeU, mLtU,
  604. mEqEnum, mLeEnum, mLtEnum,
  605. mEqCh, mLeCh, mLtCh,
  606. mEqB, mLeB, mLtB,
  607. mEqRef, mLePtr, mLtPtr,
  608. mXor, mEqCString, mEqProc,
  609. mUnaryMinusI, mUnaryMinusI64, mAbsI, mNot,
  610. mUnaryPlusI, mBitnotI,
  611. mUnaryPlusF64, mUnaryMinusF64,
  612. mCharToStr, mBoolToStr,
  613. mIntToStr, mInt64ToStr, mFloatToStr, # for compiling nimStdlibVersion < 1.5.1 (not bootstrapping)
  614. mCStrToStr,
  615. mStrToStr, mEnumToStr,
  616. mAnd, mOr,
  617. mImplies, mIff, mExists, mForall, mOld,
  618. mEqStr, mLeStr, mLtStr,
  619. mEqSet, mLeSet, mLtSet, mMulSet, mPlusSet, mMinusSet,
  620. mConStrStr, mSlice,
  621. mDotDot, # this one is only necessary to give nice compile time warnings
  622. mFields, mFieldPairs, mOmpParFor,
  623. mAppendStrCh, mAppendStrStr, mAppendSeqElem,
  624. mInSet, mRepr, mExit,
  625. mSetLengthStr, mSetLengthSeq,
  626. mIsPartOf, mAstToStr, mParallel,
  627. mSwap, mIsNil, mArrToSeq, mOpenArrayToSeq,
  628. mNewString, mNewStringOfCap, mParseBiggestFloat,
  629. mMove, mWasMoved, mDestroy, mTrace,
  630. mDefault, mUnown, mFinished, mIsolate, mAccessEnv, mAccessTypeField, mReset,
  631. mArray, mOpenArray, mRange, mSet, mSeq, mVarargs,
  632. mRef, mPtr, mVar, mDistinct, mVoid, mTuple,
  633. mOrdinal, mIterableType,
  634. mInt, mInt8, mInt16, mInt32, mInt64,
  635. mUInt, mUInt8, mUInt16, mUInt32, mUInt64,
  636. mFloat, mFloat32, mFloat64, mFloat128,
  637. mBool, mChar, mString, mCstring,
  638. mPointer, mNil, mExpr, mStmt, mTypeDesc,
  639. mVoidType, mPNimrodNode, mSpawn, mDeepCopy,
  640. mIsMainModule, mCompileDate, mCompileTime, mProcCall,
  641. mCpuEndian, mHostOS, mHostCPU, mBuildOS, mBuildCPU, mAppType,
  642. mCompileOption, mCompileOptionArg,
  643. mNLen, mNChild, mNSetChild, mNAdd, mNAddMultiple, mNDel,
  644. mNKind, mNSymKind,
  645. mNccValue, mNccInc, mNcsAdd, mNcsIncl, mNcsLen, mNcsAt,
  646. mNctPut, mNctLen, mNctGet, mNctHasNext, mNctNext,
  647. mNIntVal, mNFloatVal, mNSymbol, mNIdent, mNGetType, mNStrVal, mNSetIntVal,
  648. mNSetFloatVal, mNSetSymbol, mNSetIdent, mNSetType, mNSetStrVal, mNLineInfo,
  649. mNNewNimNode, mNCopyNimNode, mNCopyNimTree, mStrToIdent, mNSigHash, mNSizeOf,
  650. mNBindSym, mNCallSite,
  651. mEqIdent, mEqNimrodNode, mSameNodeType, mGetImpl, mNGenSym,
  652. mNHint, mNWarning, mNError,
  653. mInstantiationInfo, mGetTypeInfo, mGetTypeInfoV2,
  654. mNimvm, mIntDefine, mStrDefine, mBoolDefine, mRunnableExamples,
  655. mException, mBuiltinType, mSymOwner, mUncheckedArray, mGetImplTransf,
  656. mSymIsInstantiationOf, mNodeId, mPrivateAccess
  657. const
  658. # things that we can evaluate safely at compile time, even if not asked for it:
  659. ctfeWhitelist* = {mNone, mSucc,
  660. mPred, mInc, mDec, mOrd, mLengthOpenArray,
  661. mLengthStr, mLengthArray, mLengthSeq,
  662. mArrGet, mArrPut, mAsgn, mDestroy,
  663. mIncl, mExcl, mCard, mChr,
  664. mAddI, mSubI, mMulI, mDivI, mModI,
  665. mAddF64, mSubF64, mMulF64, mDivF64,
  666. mShrI, mShlI, mBitandI, mBitorI, mBitxorI,
  667. mMinI, mMaxI,
  668. mAddU, mSubU, mMulU, mDivU, mModU,
  669. mEqI, mLeI, mLtI,
  670. mEqF64, mLeF64, mLtF64,
  671. mLeU, mLtU,
  672. mEqEnum, mLeEnum, mLtEnum,
  673. mEqCh, mLeCh, mLtCh,
  674. mEqB, mLeB, mLtB,
  675. mEqRef, mEqProc, mLePtr, mLtPtr, mEqCString, mXor,
  676. mUnaryMinusI, mUnaryMinusI64, mAbsI, mNot, mUnaryPlusI, mBitnotI,
  677. mUnaryPlusF64, mUnaryMinusF64,
  678. mCharToStr, mBoolToStr,
  679. mIntToStr, mInt64ToStr, mFloatToStr,
  680. mCStrToStr,
  681. mStrToStr, mEnumToStr,
  682. mAnd, mOr,
  683. mEqStr, mLeStr, mLtStr,
  684. mEqSet, mLeSet, mLtSet, mMulSet, mPlusSet, mMinusSet,
  685. mConStrStr, mAppendStrCh, mAppendStrStr, mAppendSeqElem,
  686. mInSet, mRepr}
  687. generatedMagics* = {mNone, mIsolate, mFinished, mOpenArrayToSeq}
  688. ## magics that are generated as normal procs in the backend
  689. type
  690. ItemId* = object
  691. module*: int32
  692. item*: int32
  693. proc `==`*(a, b: ItemId): bool {.inline.} =
  694. a.item == b.item and a.module == b.module
  695. proc hash*(x: ItemId): Hash =
  696. var h: Hash = hash(x.module)
  697. h = h !& hash(x.item)
  698. result = !$h
  699. type
  700. TIdObj* {.acyclic.} = object of RootObj
  701. itemId*: ItemId
  702. PIdObj* = ref TIdObj
  703. PNode* = ref TNode
  704. TNodeSeq* = seq[PNode]
  705. PType* = ref TType
  706. PSym* = ref TSym
  707. TNode*{.final, acyclic.} = object # on a 32bit machine, this takes 32 bytes
  708. when defined(useNodeIds):
  709. id*: int
  710. typ*: PType
  711. info*: TLineInfo
  712. flags*: TNodeFlags
  713. case kind*: TNodeKind
  714. of nkCharLit..nkUInt64Lit:
  715. intVal*: BiggestInt
  716. of nkFloatLit..nkFloat128Lit:
  717. floatVal*: BiggestFloat
  718. of nkStrLit..nkTripleStrLit:
  719. strVal*: string
  720. of nkSym:
  721. sym*: PSym
  722. of nkIdent:
  723. ident*: PIdent
  724. else:
  725. sons*: TNodeSeq
  726. when defined(nimsuggest):
  727. endInfo*: TLineInfo
  728. TStrTable* = object # a table[PIdent] of PSym
  729. counter*: int
  730. data*: seq[PSym]
  731. # -------------- backend information -------------------------------
  732. TLocKind* = enum
  733. locNone, # no location
  734. locTemp, # temporary location
  735. locLocalVar, # location is a local variable
  736. locGlobalVar, # location is a global variable
  737. locParam, # location is a parameter
  738. locField, # location is a record field
  739. locExpr, # "location" is really an expression
  740. locProc, # location is a proc (an address of a procedure)
  741. locData, # location is a constant
  742. locCall, # location is a call expression
  743. locOther # location is something other
  744. TLocFlag* = enum
  745. lfIndirect, # backend introduced a pointer
  746. lfFullExternalName, # only used when 'conf.cmd == cmdNimfix': Indicates
  747. # that the symbol has been imported via 'importc: "fullname"' and
  748. # no format string.
  749. lfNoDeepCopy, # no need for a deep copy
  750. lfNoDecl, # do not declare it in C
  751. lfDynamicLib, # link symbol to dynamic library
  752. lfExportLib, # export symbol for dynamic library generation
  753. lfHeader, # include header file for symbol
  754. lfImportCompilerProc, # ``importc`` of a compilerproc
  755. lfSingleUse # no location yet and will only be used once
  756. lfEnforceDeref # a copyMem is required to dereference if this a
  757. # ptr array due to C array limitations.
  758. # See #1181, #6422, #11171
  759. lfPrepareForMutation # string location is about to be mutated (V2)
  760. TStorageLoc* = enum
  761. OnUnknown, # location is unknown (stack, heap or static)
  762. OnStatic, # in a static section
  763. OnStack, # location is on hardware stack
  764. OnHeap # location is on heap or global
  765. # (reference counting needed)
  766. TLocFlags* = set[TLocFlag]
  767. TLoc* = object
  768. k*: TLocKind # kind of location
  769. storage*: TStorageLoc
  770. flags*: TLocFlags # location's flags
  771. lode*: PNode # Node where the location came from; can be faked
  772. r*: Rope # rope value of location (code generators)
  773. # ---------------- end of backend information ------------------------------
  774. TLibKind* = enum
  775. libHeader, libDynamic
  776. TLib* = object # also misused for headers!
  777. # keep in sync with PackedLib
  778. kind*: TLibKind
  779. generated*: bool # needed for the backends:
  780. isOverriden*: bool
  781. name*: Rope
  782. path*: PNode # can be a string literal!
  783. CompilesId* = int ## id that is used for the caching logic within
  784. ## ``system.compiles``. See the seminst module.
  785. TInstantiation* = object
  786. sym*: PSym
  787. concreteTypes*: seq[PType]
  788. compilesId*: CompilesId
  789. PInstantiation* = ref TInstantiation
  790. TScope* {.acyclic.} = object
  791. depthLevel*: int
  792. symbols*: TStrTable
  793. parent*: PScope
  794. allowPrivateAccess*: seq[PSym] # # enable access to private fields
  795. PScope* = ref TScope
  796. PLib* = ref TLib
  797. TSym* {.acyclic.} = object of TIdObj # Keep in sync with PackedSym
  798. # proc and type instantiations are cached in the generic symbol
  799. case kind*: TSymKind
  800. of routineKinds:
  801. #procInstCache*: seq[PInstantiation]
  802. gcUnsafetyReason*: PSym # for better error messages regarding gcsafe
  803. transformedBody*: PNode # cached body after transf pass
  804. of skLet, skVar, skField, skForVar:
  805. guard*: PSym
  806. bitsize*: int
  807. alignment*: int # for alignment
  808. else: nil
  809. magic*: TMagic
  810. typ*: PType
  811. name*: PIdent
  812. info*: TLineInfo
  813. when defined(nimsuggest):
  814. endInfo*: TLineInfo
  815. hasUserSpecifiedType*: bool # used for determining whether to display inlay type hints
  816. owner*: PSym
  817. flags*: TSymFlags
  818. ast*: PNode # syntax tree of proc, iterator, etc.:
  819. # the whole proc including header; this is used
  820. # for easy generation of proper error messages
  821. # for variant record fields the discriminant
  822. # expression
  823. # for modules, it's a placeholder for compiler
  824. # generated code that will be appended to the
  825. # module after the sem pass (see appendToModule)
  826. options*: TOptions
  827. position*: int # used for many different things:
  828. # for enum fields its position;
  829. # for fields its offset
  830. # for parameters its position (starting with 0)
  831. # for a conditional:
  832. # 1 iff the symbol is defined, else 0
  833. # (or not in symbol table)
  834. # for modules, an unique index corresponding
  835. # to the module's fileIdx
  836. # for variables a slot index for the evaluator
  837. offset*: int # offset of record field
  838. loc*: TLoc
  839. annex*: PLib # additional fields (seldom used, so we use a
  840. # reference to another object to save space)
  841. when hasFFI:
  842. cname*: string # resolved C declaration name in importc decl, e.g.:
  843. # proc fun() {.importc: "$1aux".} => cname = funaux
  844. constraint*: PNode # additional constraints like 'lit|result'; also
  845. # misused for the codegenDecl pragma in the hope
  846. # it won't cause problems
  847. # for skModule the string literal to output for
  848. # deprecated modules.
  849. when defined(nimsuggest):
  850. allUsages*: seq[TLineInfo]
  851. TTypeSeq* = seq[PType]
  852. TLockLevel* = distinct int16
  853. TTypeAttachedOp* = enum ## as usual, order is important here
  854. attachedDestructor,
  855. attachedAsgn,
  856. attachedSink,
  857. attachedTrace,
  858. attachedDeepCopy
  859. TType* {.acyclic.} = object of TIdObj # \
  860. # types are identical iff they have the
  861. # same id; there may be multiple copies of a type
  862. # in memory!
  863. # Keep in sync with PackedType
  864. kind*: TTypeKind # kind of type
  865. callConv*: TCallingConvention # for procs
  866. flags*: TTypeFlags # flags of the type
  867. sons*: TTypeSeq # base types, etc.
  868. n*: PNode # node for types:
  869. # for range types a nkRange node
  870. # for record types a nkRecord node
  871. # for enum types a list of symbols
  872. # if kind == tyInt: it is an 'int literal(x)' type
  873. # for procs and tyGenericBody, it's the
  874. # formal param list
  875. # for concepts, the concept body
  876. # else: unused
  877. owner*: PSym # the 'owner' of the type
  878. sym*: PSym # types have the sym associated with them
  879. # it is used for converting types to strings
  880. size*: BiggestInt # the size of the type in bytes
  881. # -1 means that the size is unkwown
  882. align*: int16 # the type's alignment requirements
  883. paddingAtEnd*: int16 #
  884. lockLevel*: TLockLevel # lock level as required for deadlock checking
  885. loc*: TLoc
  886. typeInst*: PType # for generic instantiations the tyGenericInst that led to this
  887. # type.
  888. uniqueId*: ItemId # due to a design mistake, we need to keep the real ID here as it
  889. # is required by the --incremental:on mode.
  890. TPair* = object
  891. key*, val*: RootRef
  892. TPairSeq* = seq[TPair]
  893. TIdPair* = object
  894. key*: PIdObj
  895. val*: RootRef
  896. TIdPairSeq* = seq[TIdPair]
  897. TIdTable* = object # the same as table[PIdent] of PObject
  898. counter*: int
  899. data*: TIdPairSeq
  900. TIdNodePair* = object
  901. key*: PIdObj
  902. val*: PNode
  903. TIdNodePairSeq* = seq[TIdNodePair]
  904. TIdNodeTable* = object # the same as table[PIdObj] of PNode
  905. counter*: int
  906. data*: TIdNodePairSeq
  907. TNodePair* = object
  908. h*: Hash # because it is expensive to compute!
  909. key*: PNode
  910. val*: int
  911. TNodePairSeq* = seq[TNodePair]
  912. TNodeTable* = object # the same as table[PNode] of int;
  913. # nodes are compared by structure!
  914. counter*: int
  915. data*: TNodePairSeq
  916. TObjectSeq* = seq[RootRef]
  917. TObjectSet* = object
  918. counter*: int
  919. data*: TObjectSeq
  920. TImplication* = enum
  921. impUnknown, impNo, impYes
  922. template nodeId(n: PNode): int = cast[int](n)
  923. type Gconfig = object
  924. # we put comments in a side channel to avoid increasing `sizeof(TNode)`, which
  925. # reduces memory usage given that `PNode` is the most allocated type by far.
  926. comments: Table[int, string] # nodeId => comment
  927. useIc*: bool
  928. var gconfig {.threadvar.}: Gconfig
  929. proc setUseIc*(useIc: bool) = gconfig.useIc = useIc
  930. proc comment*(n: PNode): string =
  931. if nfHasComment in n.flags and not gconfig.useIc:
  932. # IC doesn't track comments, see `packed_ast`, so this could fail
  933. result = gconfig.comments[n.nodeId]
  934. proc `comment=`*(n: PNode, a: string) =
  935. let id = n.nodeId
  936. if a.len > 0:
  937. # if needed, we could periodically cleanup gconfig.comments when its size increases,
  938. # to ensure only live nodes (and with nfHasComment) have an entry in gconfig.comments;
  939. # for compiling compiler, the waste is very small:
  940. # num calls to newNodeImpl: 14984160 (num of PNode allocations)
  941. # size of gconfig.comments: 33585
  942. # num of nodes with comments that were deleted and hence wasted: 3081
  943. n.flags.incl nfHasComment
  944. gconfig.comments[id] = a
  945. elif nfHasComment in n.flags:
  946. n.flags.excl nfHasComment
  947. gconfig.comments.del(id)
  948. # BUGFIX: a module is overloadable so that a proc can have the
  949. # same name as an imported module. This is necessary because of
  950. # the poor naming choices in the standard library.
  951. const
  952. OverloadableSyms* = {skProc, skFunc, skMethod, skIterator,
  953. skConverter, skModule, skTemplate, skMacro, skEnumField}
  954. GenericTypes*: TTypeKinds = {tyGenericInvocation, tyGenericBody,
  955. tyGenericParam}
  956. StructuralEquivTypes*: TTypeKinds = {tyNil, tyTuple, tyArray,
  957. tySet, tyRange, tyPtr, tyRef, tyVar, tyLent, tySequence, tyProc, tyOpenArray,
  958. tyVarargs}
  959. ConcreteTypes*: TTypeKinds = { # types of the expr that may occur in::
  960. # var x = expr
  961. tyBool, tyChar, tyEnum, tyArray, tyObject,
  962. tySet, tyTuple, tyRange, tyPtr, tyRef, tyVar, tyLent, tySequence, tyProc,
  963. tyPointer,
  964. tyOpenArray, tyString, tyCstring, tyInt..tyInt64, tyFloat..tyFloat128,
  965. tyUInt..tyUInt64}
  966. IntegralTypes* = {tyBool, tyChar, tyEnum, tyInt..tyInt64,
  967. tyFloat..tyFloat128, tyUInt..tyUInt64} # weird name because it contains tyFloat
  968. ConstantDataTypes*: TTypeKinds = {tyArray, tySet,
  969. tyTuple, tySequence}
  970. NilableTypes*: TTypeKinds = {tyPointer, tyCstring, tyRef, tyPtr,
  971. tyProc, tyError} # TODO
  972. PtrLikeKinds*: TTypeKinds = {tyPointer, tyPtr} # for VM
  973. PersistentNodeFlags*: TNodeFlags = {nfBase2, nfBase8, nfBase16,
  974. nfDotSetter, nfDotField,
  975. nfIsRef, nfIsPtr, nfPreventCg, nfLL,
  976. nfFromTemplate, nfDefaultRefsParam,
  977. nfExecuteOnReload, nfLastRead,
  978. nfFirstWrite, nfSkipFieldChecking}
  979. namePos* = 0
  980. patternPos* = 1 # empty except for term rewriting macros
  981. genericParamsPos* = 2
  982. paramsPos* = 3
  983. pragmasPos* = 4
  984. miscPos* = 5 # used for undocumented and hacky stuff
  985. bodyPos* = 6 # position of body; use rodread.getBody() instead!
  986. resultPos* = 7
  987. dispatcherPos* = 8
  988. nfAllFieldsSet* = nfBase2
  989. nkCallKinds* = {nkCall, nkInfix, nkPrefix, nkPostfix,
  990. nkCommand, nkCallStrLit, nkHiddenCallConv}
  991. nkIdentKinds* = {nkIdent, nkSym, nkAccQuoted, nkOpenSymChoice,
  992. nkClosedSymChoice}
  993. nkPragmaCallKinds* = {nkExprColonExpr, nkCall, nkCallStrLit}
  994. nkLiterals* = {nkCharLit..nkTripleStrLit}
  995. nkFloatLiterals* = {nkFloatLit..nkFloat128Lit}
  996. nkLambdaKinds* = {nkLambda, nkDo}
  997. declarativeDefs* = {nkProcDef, nkFuncDef, nkMethodDef, nkIteratorDef, nkConverterDef}
  998. routineDefs* = declarativeDefs + {nkMacroDef, nkTemplateDef}
  999. procDefs* = nkLambdaKinds + declarativeDefs
  1000. callableDefs* = nkLambdaKinds + routineDefs
  1001. nkSymChoices* = {nkClosedSymChoice, nkOpenSymChoice}
  1002. nkStrKinds* = {nkStrLit..nkTripleStrLit}
  1003. skLocalVars* = {skVar, skLet, skForVar, skParam, skResult}
  1004. skProcKinds* = {skProc, skFunc, skTemplate, skMacro, skIterator,
  1005. skMethod, skConverter}
  1006. defaultSize = -1
  1007. defaultAlignment = -1
  1008. defaultOffset* = -1
  1009. proc getPIdent*(a: PNode): PIdent {.inline.} =
  1010. ## Returns underlying `PIdent` for `{nkSym, nkIdent}`, or `nil`.
  1011. case a.kind
  1012. of nkSym: a.sym.name
  1013. of nkIdent: a.ident
  1014. of nkOpenSymChoice, nkClosedSymChoice: a.sons[0].sym.name
  1015. else: nil
  1016. const
  1017. moduleShift = when defined(cpu32): 20 else: 24
  1018. template id*(a: PIdObj): int =
  1019. let x = a
  1020. (x.itemId.module.int shl moduleShift) + x.itemId.item.int
  1021. type
  1022. IdGenerator* = ref object # unfortunately, we really need the 'shared mutable' aspect here.
  1023. module*: int32
  1024. symId*: int32
  1025. typeId*: int32
  1026. sealed*: bool
  1027. const
  1028. PackageModuleId* = -3'i32
  1029. proc idGeneratorFromModule*(m: PSym): IdGenerator =
  1030. assert m.kind == skModule
  1031. result = IdGenerator(module: m.itemId.module, symId: m.itemId.item, typeId: 0)
  1032. proc nextSymId*(x: IdGenerator): ItemId {.inline.} =
  1033. assert(not x.sealed)
  1034. inc x.symId
  1035. result = ItemId(module: x.module, item: x.symId)
  1036. proc nextTypeId*(x: IdGenerator): ItemId {.inline.} =
  1037. assert(not x.sealed)
  1038. inc x.typeId
  1039. result = ItemId(module: x.module, item: x.typeId)
  1040. when false:
  1041. proc nextId*(x: IdGenerator): ItemId {.inline.} =
  1042. inc x.item
  1043. result = x[]
  1044. when false:
  1045. proc storeBack*(dest: var IdGenerator; src: IdGenerator) {.inline.} =
  1046. assert dest.ItemId.module == src.ItemId.module
  1047. if dest.ItemId.item > src.ItemId.item:
  1048. echo dest.ItemId.item, " ", src.ItemId.item, " ", src.ItemId.module
  1049. assert dest.ItemId.item <= src.ItemId.item
  1050. dest = src
  1051. var ggDebug* {.deprecated.}: bool ## convenience switch for trying out things
  1052. proc isCallExpr*(n: PNode): bool =
  1053. result = n.kind in nkCallKinds
  1054. proc discardSons*(father: PNode)
  1055. type Indexable = PNode | PType
  1056. proc len*(n: Indexable): int {.inline.} =
  1057. result = n.sons.len
  1058. proc safeLen*(n: PNode): int {.inline.} =
  1059. ## works even for leaves.
  1060. if n.kind in {nkNone..nkNilLit}: result = 0
  1061. else: result = n.len
  1062. proc safeArrLen*(n: PNode): int {.inline.} =
  1063. ## works for array-like objects (strings passed as openArray in VM).
  1064. if n.kind in {nkStrLit..nkTripleStrLit}: result = n.strVal.len
  1065. elif n.kind in {nkNone..nkFloat128Lit}: result = 0
  1066. else: result = n.len
  1067. proc add*(father, son: Indexable) =
  1068. assert son != nil
  1069. father.sons.add(son)
  1070. proc addAllowNil*(father, son: Indexable) {.inline.} =
  1071. father.sons.add(son)
  1072. template `[]`*(n: Indexable, i: int): Indexable = n.sons[i]
  1073. template `[]=`*(n: Indexable, i: int; x: Indexable) = n.sons[i] = x
  1074. template `[]`*(n: Indexable, i: BackwardsIndex): Indexable = n[n.len - i.int]
  1075. template `[]=`*(n: Indexable, i: BackwardsIndex; x: Indexable) = n[n.len - i.int] = x
  1076. proc getDeclPragma*(n: PNode): PNode =
  1077. ## return the `nkPragma` node for declaration `n`, or `nil` if no pragma was found.
  1078. ## Currently only supports routineDefs + {nkTypeDef}.
  1079. case n.kind
  1080. of routineDefs:
  1081. if n[pragmasPos].kind != nkEmpty: result = n[pragmasPos]
  1082. of nkTypeDef:
  1083. #[
  1084. type F3*{.deprecated: "x3".} = int
  1085. TypeSection
  1086. TypeDef
  1087. PragmaExpr
  1088. Postfix
  1089. Ident "*"
  1090. Ident "F3"
  1091. Pragma
  1092. ExprColonExpr
  1093. Ident "deprecated"
  1094. StrLit "x3"
  1095. Empty
  1096. Ident "int"
  1097. ]#
  1098. if n[0].kind == nkPragmaExpr:
  1099. result = n[0][1]
  1100. else:
  1101. # support as needed for `nkIdentDefs` etc.
  1102. result = nil
  1103. if result != nil:
  1104. assert result.kind == nkPragma, $(result.kind, n.kind)
  1105. when defined(useNodeIds):
  1106. const nodeIdToDebug* = -1 # 2322968
  1107. var gNodeId: int
  1108. template newNodeImpl(info2) =
  1109. result = PNode(kind: kind, info: info2)
  1110. when false:
  1111. # this would add overhead, so we skip it; it results in a small amount of leaked entries
  1112. # for old PNode that gets re-allocated at the same address as a PNode that
  1113. # has `nfHasComment` set (and an entry in that table). Only `nfHasComment`
  1114. # should be used to test whether a PNode has a comment; gconfig.comments
  1115. # can contain extra entries for deleted PNode's with comments.
  1116. gconfig.comments.del(cast[int](result))
  1117. template setIdMaybe() =
  1118. when defined(useNodeIds):
  1119. result.id = gNodeId
  1120. if result.id == nodeIdToDebug:
  1121. echo "KIND ", result.kind
  1122. writeStackTrace()
  1123. inc gNodeId
  1124. proc newNode*(kind: TNodeKind): PNode =
  1125. ## new node with unknown line info, no type, and no children
  1126. newNodeImpl(unknownLineInfo)
  1127. setIdMaybe()
  1128. proc newNodeI*(kind: TNodeKind, info: TLineInfo): PNode =
  1129. ## new node with line info, no type, and no children
  1130. newNodeImpl(info)
  1131. setIdMaybe()
  1132. proc newNodeI*(kind: TNodeKind, info: TLineInfo, children: int): PNode =
  1133. ## new node with line info, type, and children
  1134. newNodeImpl(info)
  1135. if children > 0:
  1136. newSeq(result.sons, children)
  1137. setIdMaybe()
  1138. proc newNodeIT*(kind: TNodeKind, info: TLineInfo, typ: PType): PNode =
  1139. ## new node with line info, type, and no children
  1140. result = newNode(kind)
  1141. result.info = info
  1142. result.typ = typ
  1143. proc newTree*(kind: TNodeKind; children: varargs[PNode]): PNode =
  1144. result = newNode(kind)
  1145. if children.len > 0:
  1146. result.info = children[0].info
  1147. result.sons = @children
  1148. proc newTreeI*(kind: TNodeKind; info: TLineInfo; children: varargs[PNode]): PNode =
  1149. result = newNodeI(kind, info)
  1150. if children.len > 0:
  1151. result.info = children[0].info
  1152. result.sons = @children
  1153. proc newTreeIT*(kind: TNodeKind; info: TLineInfo; typ: PType; children: varargs[PNode]): PNode =
  1154. result = newNodeIT(kind, info, typ)
  1155. if children.len > 0:
  1156. result.info = children[0].info
  1157. result.sons = @children
  1158. template previouslyInferred*(t: PType): PType =
  1159. if t.sons.len > 1: t.lastSon else: nil
  1160. when false:
  1161. import tables, strutils
  1162. var x: CountTable[string]
  1163. addQuitProc proc () {.noconv.} =
  1164. for k, v in pairs(x):
  1165. echo k
  1166. echo v
  1167. proc newSym*(symKind: TSymKind, name: PIdent, id: ItemId, owner: PSym,
  1168. info: TLineInfo; options: TOptions = {}): PSym =
  1169. # generates a symbol and initializes the hash field too
  1170. result = PSym(name: name, kind: symKind, flags: {}, info: info, itemId: id,
  1171. options: options, owner: owner, offset: defaultOffset)
  1172. when false:
  1173. if id.module == 48 and id.item == 39:
  1174. writeStackTrace()
  1175. echo "kind ", symKind, " ", name.s
  1176. if owner != nil: echo owner.name.s
  1177. proc astdef*(s: PSym): PNode =
  1178. # get only the definition (initializer) portion of the ast
  1179. if s.ast != nil and s.ast.kind == nkIdentDefs:
  1180. s.ast[2]
  1181. else:
  1182. s.ast
  1183. proc isMetaType*(t: PType): bool =
  1184. return t.kind in tyMetaTypes or
  1185. (t.kind == tyStatic and t.n == nil) or
  1186. tfHasMeta in t.flags
  1187. proc isUnresolvedStatic*(t: PType): bool =
  1188. return t.kind == tyStatic and t.n == nil
  1189. proc linkTo*(t: PType, s: PSym): PType {.discardable.} =
  1190. t.sym = s
  1191. s.typ = t
  1192. result = t
  1193. proc linkTo*(s: PSym, t: PType): PSym {.discardable.} =
  1194. t.sym = s
  1195. s.typ = t
  1196. result = s
  1197. template fileIdx*(c: PSym): FileIndex =
  1198. # XXX: this should be used only on module symbols
  1199. c.position.FileIndex
  1200. template filename*(c: PSym): string =
  1201. # XXX: this should be used only on module symbols
  1202. c.position.FileIndex.toFilename
  1203. proc appendToModule*(m: PSym, n: PNode) =
  1204. ## The compiler will use this internally to add nodes that will be
  1205. ## appended to the module after the sem pass
  1206. if m.ast == nil:
  1207. m.ast = newNode(nkStmtList)
  1208. m.ast.sons = @[n]
  1209. else:
  1210. assert m.ast.kind == nkStmtList
  1211. m.ast.sons.add(n)
  1212. const # for all kind of hash tables:
  1213. GrowthFactor* = 2 # must be power of 2, > 0
  1214. StartSize* = 8 # must be power of 2, > 0
  1215. proc copyStrTable*(dest: var TStrTable, src: TStrTable) =
  1216. dest.counter = src.counter
  1217. setLen(dest.data, src.data.len)
  1218. for i in 0..high(src.data): dest.data[i] = src.data[i]
  1219. proc copyIdTable*(dest: var TIdTable, src: TIdTable) =
  1220. dest.counter = src.counter
  1221. newSeq(dest.data, src.data.len)
  1222. for i in 0..high(src.data): dest.data[i] = src.data[i]
  1223. proc copyObjectSet*(dest: var TObjectSet, src: TObjectSet) =
  1224. dest.counter = src.counter
  1225. setLen(dest.data, src.data.len)
  1226. for i in 0..high(src.data): dest.data[i] = src.data[i]
  1227. proc discardSons*(father: PNode) =
  1228. father.sons = @[]
  1229. proc withInfo*(n: PNode, info: TLineInfo): PNode =
  1230. n.info = info
  1231. return n
  1232. proc newIdentNode*(ident: PIdent, info: TLineInfo): PNode =
  1233. result = newNode(nkIdent)
  1234. result.ident = ident
  1235. result.info = info
  1236. proc newSymNode*(sym: PSym): PNode =
  1237. result = newNode(nkSym)
  1238. result.sym = sym
  1239. result.typ = sym.typ
  1240. result.info = sym.info
  1241. proc newSymNode*(sym: PSym, info: TLineInfo): PNode =
  1242. result = newNode(nkSym)
  1243. result.sym = sym
  1244. result.typ = sym.typ
  1245. result.info = info
  1246. proc newIntNode*(kind: TNodeKind, intVal: BiggestInt): PNode =
  1247. result = newNode(kind)
  1248. result.intVal = intVal
  1249. proc newIntNode*(kind: TNodeKind, intVal: Int128): PNode =
  1250. result = newNode(kind)
  1251. result.intVal = castToInt64(intVal)
  1252. proc lastSon*(n: Indexable): Indexable = n.sons[^1]
  1253. proc skipTypes*(t: PType, kinds: TTypeKinds): PType =
  1254. ## Used throughout the compiler code to test whether a type tree contains or
  1255. ## doesn't contain a specific type/types - it is often the case that only the
  1256. ## last child nodes of a type tree need to be searched. This is a really hot
  1257. ## path within the compiler!
  1258. result = t
  1259. while result.kind in kinds: result = lastSon(result)
  1260. proc newIntTypeNode*(intVal: BiggestInt, typ: PType): PNode =
  1261. let kind = skipTypes(typ, abstractVarRange).kind
  1262. case kind
  1263. of tyInt: result = newNode(nkIntLit)
  1264. of tyInt8: result = newNode(nkInt8Lit)
  1265. of tyInt16: result = newNode(nkInt16Lit)
  1266. of tyInt32: result = newNode(nkInt32Lit)
  1267. of tyInt64: result = newNode(nkInt64Lit)
  1268. of tyChar: result = newNode(nkCharLit)
  1269. of tyUInt: result = newNode(nkUIntLit)
  1270. of tyUInt8: result = newNode(nkUInt8Lit)
  1271. of tyUInt16: result = newNode(nkUInt16Lit)
  1272. of tyUInt32: result = newNode(nkUInt32Lit)
  1273. of tyUInt64: result = newNode(nkUInt64Lit)
  1274. of tyBool, tyEnum:
  1275. # XXX: does this really need to be the kind nkIntLit?
  1276. result = newNode(nkIntLit)
  1277. of tyStatic: # that's a pre-existing bug, will fix in another PR
  1278. result = newNode(nkIntLit)
  1279. else: doAssert false, $kind
  1280. result.intVal = intVal
  1281. result.typ = typ
  1282. proc newIntTypeNode*(intVal: Int128, typ: PType): PNode =
  1283. # XXX: introduce range check
  1284. newIntTypeNode(castToInt64(intVal), typ)
  1285. proc newFloatNode*(kind: TNodeKind, floatVal: BiggestFloat): PNode =
  1286. result = newNode(kind)
  1287. result.floatVal = floatVal
  1288. proc newStrNode*(kind: TNodeKind, strVal: string): PNode =
  1289. result = newNode(kind)
  1290. result.strVal = strVal
  1291. proc newStrNode*(strVal: string; info: TLineInfo): PNode =
  1292. result = newNodeI(nkStrLit, info)
  1293. result.strVal = strVal
  1294. proc newProcNode*(kind: TNodeKind, info: TLineInfo, body: PNode,
  1295. params,
  1296. name, pattern, genericParams,
  1297. pragmas, exceptions: PNode): PNode =
  1298. result = newNodeI(kind, info)
  1299. result.sons = @[name, pattern, genericParams, params,
  1300. pragmas, exceptions, body]
  1301. const
  1302. UnspecifiedLockLevel* = TLockLevel(-1'i16)
  1303. MaxLockLevel* = 1000'i16
  1304. UnknownLockLevel* = TLockLevel(1001'i16)
  1305. AttachedOpToStr*: array[TTypeAttachedOp, string] = [
  1306. "=destroy", "=copy", "=sink", "=trace", "=deepcopy"]
  1307. proc `$`*(x: TLockLevel): string =
  1308. if x.ord == UnspecifiedLockLevel.ord: result = "<unspecified>"
  1309. elif x.ord == UnknownLockLevel.ord: result = "<unknown>"
  1310. else: result = $int16(x)
  1311. proc `$`*(s: PSym): string =
  1312. if s != nil:
  1313. result = s.name.s & "@" & $s.id
  1314. else:
  1315. result = "<nil>"
  1316. proc newType*(kind: TTypeKind, id: ItemId; owner: PSym): PType =
  1317. result = PType(kind: kind, owner: owner, size: defaultSize,
  1318. align: defaultAlignment, itemId: id,
  1319. lockLevel: UnspecifiedLockLevel,
  1320. uniqueId: id)
  1321. when false:
  1322. if result.itemId.module == 55 and result.itemId.item == 2:
  1323. echo "KNID ", kind
  1324. writeStackTrace()
  1325. proc mergeLoc(a: var TLoc, b: TLoc) =
  1326. if a.k == low(typeof(a.k)): a.k = b.k
  1327. if a.storage == low(typeof(a.storage)): a.storage = b.storage
  1328. a.flags.incl b.flags
  1329. if a.lode == nil: a.lode = b.lode
  1330. if a.r == nil: a.r = b.r
  1331. proc newSons*(father: Indexable, length: int) =
  1332. setLen(father.sons, length)
  1333. proc assignType*(dest, src: PType) =
  1334. dest.kind = src.kind
  1335. dest.flags = src.flags
  1336. dest.callConv = src.callConv
  1337. dest.n = src.n
  1338. dest.size = src.size
  1339. dest.align = src.align
  1340. dest.lockLevel = src.lockLevel
  1341. # this fixes 'type TLock = TSysLock':
  1342. if src.sym != nil:
  1343. if dest.sym != nil:
  1344. dest.sym.flags.incl src.sym.flags-{sfUsed, sfExported}
  1345. if dest.sym.annex == nil: dest.sym.annex = src.sym.annex
  1346. mergeLoc(dest.sym.loc, src.sym.loc)
  1347. else:
  1348. dest.sym = src.sym
  1349. newSons(dest, src.len)
  1350. for i in 0..<src.len: dest[i] = src[i]
  1351. proc copyType*(t: PType, id: ItemId, owner: PSym): PType =
  1352. result = newType(t.kind, id, owner)
  1353. assignType(result, t)
  1354. result.sym = t.sym # backend-info should not be copied
  1355. proc exactReplica*(t: PType): PType =
  1356. result = copyType(t, t.itemId, t.owner)
  1357. proc copySym*(s: PSym; id: ItemId): PSym =
  1358. result = newSym(s.kind, s.name, id, s.owner, s.info, s.options)
  1359. #result.ast = nil # BUGFIX; was: s.ast which made problems
  1360. result.typ = s.typ
  1361. result.flags = s.flags
  1362. result.magic = s.magic
  1363. result.options = s.options
  1364. result.position = s.position
  1365. result.loc = s.loc
  1366. result.annex = s.annex # BUGFIX
  1367. result.constraint = s.constraint
  1368. if result.kind in {skVar, skLet, skField}:
  1369. result.guard = s.guard
  1370. result.bitsize = s.bitsize
  1371. result.alignment = s.alignment
  1372. proc createModuleAlias*(s: PSym, id: ItemId, newIdent: PIdent, info: TLineInfo;
  1373. options: TOptions): PSym =
  1374. result = newSym(s.kind, newIdent, id, s.owner, info, options)
  1375. # keep ID!
  1376. result.ast = s.ast
  1377. #result.id = s.id # XXX figure out what to do with the ID.
  1378. result.flags = s.flags
  1379. result.options = s.options
  1380. result.position = s.position
  1381. result.loc = s.loc
  1382. result.annex = s.annex
  1383. proc initStrTable*(x: var TStrTable) =
  1384. x.counter = 0
  1385. newSeq(x.data, StartSize)
  1386. proc newStrTable*: TStrTable =
  1387. initStrTable(result)
  1388. proc initIdTable*(x: var TIdTable) =
  1389. x.counter = 0
  1390. newSeq(x.data, StartSize)
  1391. proc newIdTable*: TIdTable =
  1392. initIdTable(result)
  1393. proc resetIdTable*(x: var TIdTable) =
  1394. x.counter = 0
  1395. # clear and set to old initial size:
  1396. setLen(x.data, 0)
  1397. setLen(x.data, StartSize)
  1398. proc initObjectSet*(x: var TObjectSet) =
  1399. x.counter = 0
  1400. newSeq(x.data, StartSize)
  1401. proc initIdNodeTable*(x: var TIdNodeTable) =
  1402. x.counter = 0
  1403. newSeq(x.data, StartSize)
  1404. proc initNodeTable*(x: var TNodeTable) =
  1405. x.counter = 0
  1406. newSeq(x.data, StartSize)
  1407. proc skipTypes*(t: PType, kinds: TTypeKinds; maxIters: int): PType =
  1408. result = t
  1409. var i = maxIters
  1410. while result.kind in kinds:
  1411. result = lastSon(result)
  1412. dec i
  1413. if i == 0: return nil
  1414. proc skipTypesOrNil*(t: PType, kinds: TTypeKinds): PType =
  1415. ## same as skipTypes but handles 'nil'
  1416. result = t
  1417. while result != nil and result.kind in kinds:
  1418. if result.len == 0: return nil
  1419. result = lastSon(result)
  1420. proc isGCedMem*(t: PType): bool {.inline.} =
  1421. result = t.kind in {tyString, tyRef, tySequence} or
  1422. t.kind == tyProc and t.callConv == ccClosure
  1423. proc propagateToOwner*(owner, elem: PType; propagateHasAsgn = true) =
  1424. owner.flags.incl elem.flags * {tfHasMeta, tfTriggersCompileTime}
  1425. if tfNotNil in elem.flags:
  1426. if owner.kind in {tyGenericInst, tyGenericBody, tyGenericInvocation}:
  1427. owner.flags.incl tfNotNil
  1428. if elem.isMetaType:
  1429. owner.flags.incl tfHasMeta
  1430. let mask = elem.flags * {tfHasAsgn, tfHasOwned}
  1431. if mask != {} and propagateHasAsgn:
  1432. let o2 = owner.skipTypes({tyGenericInst, tyAlias, tySink})
  1433. if o2.kind in {tyTuple, tyObject, tyArray,
  1434. tySequence, tySet, tyDistinct}:
  1435. o2.flags.incl mask
  1436. owner.flags.incl mask
  1437. if owner.kind notin {tyProc, tyGenericInst, tyGenericBody,
  1438. tyGenericInvocation, tyPtr}:
  1439. let elemB = elem.skipTypes({tyGenericInst, tyAlias, tySink})
  1440. if elemB.isGCedMem or tfHasGCedMem in elemB.flags:
  1441. # for simplicity, we propagate this flag even to generics. We then
  1442. # ensure this doesn't bite us in sempass2.
  1443. owner.flags.incl tfHasGCedMem
  1444. proc rawAddSon*(father, son: PType; propagateHasAsgn = true) =
  1445. father.sons.add(son)
  1446. if not son.isNil: propagateToOwner(father, son, propagateHasAsgn)
  1447. proc rawAddSonNoPropagationOfTypeFlags*(father, son: PType) =
  1448. father.sons.add(son)
  1449. proc addSonNilAllowed*(father, son: PNode) =
  1450. father.sons.add(son)
  1451. proc delSon*(father: PNode, idx: int) =
  1452. if father.len == 0: return
  1453. for i in idx..<father.len - 1: father[i] = father[i + 1]
  1454. father.sons.setLen(father.len - 1)
  1455. proc copyNode*(src: PNode): PNode =
  1456. # does not copy its sons!
  1457. if src == nil:
  1458. return nil
  1459. result = newNode(src.kind)
  1460. result.info = src.info
  1461. result.typ = src.typ
  1462. result.flags = src.flags * PersistentNodeFlags
  1463. result.comment = src.comment
  1464. when defined(useNodeIds):
  1465. if result.id == nodeIdToDebug:
  1466. echo "COMES FROM ", src.id
  1467. case src.kind
  1468. of nkCharLit..nkUInt64Lit: result.intVal = src.intVal
  1469. of nkFloatLiterals: result.floatVal = src.floatVal
  1470. of nkSym: result.sym = src.sym
  1471. of nkIdent: result.ident = src.ident
  1472. of nkStrLit..nkTripleStrLit: result.strVal = src.strVal
  1473. else: discard
  1474. when defined(nimsuggest):
  1475. result.endInfo = src.endInfo
  1476. template transitionNodeKindCommon(k: TNodeKind) =
  1477. let obj {.inject.} = n[]
  1478. n[] = TNode(kind: k, typ: obj.typ, info: obj.info, flags: obj.flags)
  1479. # n.comment = obj.comment # shouldn't be needed, the address doesnt' change
  1480. when defined(useNodeIds):
  1481. n.id = obj.id
  1482. proc transitionSonsKind*(n: PNode, kind: range[nkComesFrom..nkTupleConstr]) =
  1483. transitionNodeKindCommon(kind)
  1484. n.sons = obj.sons
  1485. proc transitionIntKind*(n: PNode, kind: range[nkCharLit..nkUInt64Lit]) =
  1486. transitionNodeKindCommon(kind)
  1487. n.intVal = obj.intVal
  1488. proc transitionIntToFloatKind*(n: PNode, kind: range[nkFloatLit..nkFloat128Lit]) =
  1489. transitionNodeKindCommon(kind)
  1490. n.floatVal = BiggestFloat(obj.intVal)
  1491. proc transitionNoneToSym*(n: PNode) =
  1492. transitionNodeKindCommon(nkSym)
  1493. template transitionSymKindCommon*(k: TSymKind) =
  1494. let obj {.inject.} = s[]
  1495. s[] = TSym(kind: k, itemId: obj.itemId, magic: obj.magic, typ: obj.typ, name: obj.name,
  1496. info: obj.info, owner: obj.owner, flags: obj.flags, ast: obj.ast,
  1497. options: obj.options, position: obj.position, offset: obj.offset,
  1498. loc: obj.loc, annex: obj.annex, constraint: obj.constraint)
  1499. when hasFFI:
  1500. s.cname = obj.cname
  1501. when defined(nimsuggest):
  1502. s.allUsages = obj.allUsages
  1503. proc transitionGenericParamToType*(s: PSym) =
  1504. transitionSymKindCommon(skType)
  1505. proc transitionRoutineSymKind*(s: PSym, kind: range[skProc..skTemplate]) =
  1506. transitionSymKindCommon(kind)
  1507. s.gcUnsafetyReason = obj.gcUnsafetyReason
  1508. s.transformedBody = obj.transformedBody
  1509. proc transitionToLet*(s: PSym) =
  1510. transitionSymKindCommon(skLet)
  1511. s.guard = obj.guard
  1512. s.bitsize = obj.bitsize
  1513. s.alignment = obj.alignment
  1514. template copyNodeImpl(dst, src, processSonsStmt) =
  1515. if src == nil: return
  1516. dst = newNode(src.kind)
  1517. dst.info = src.info
  1518. when defined(nimsuggest):
  1519. result.endInfo = src.endInfo
  1520. dst.typ = src.typ
  1521. dst.flags = src.flags * PersistentNodeFlags
  1522. dst.comment = src.comment
  1523. when defined(useNodeIds):
  1524. if dst.id == nodeIdToDebug:
  1525. echo "COMES FROM ", src.id
  1526. case src.kind
  1527. of nkCharLit..nkUInt64Lit: dst.intVal = src.intVal
  1528. of nkFloatLiterals: dst.floatVal = src.floatVal
  1529. of nkSym: dst.sym = src.sym
  1530. of nkIdent: dst.ident = src.ident
  1531. of nkStrLit..nkTripleStrLit: dst.strVal = src.strVal
  1532. else: processSonsStmt
  1533. proc shallowCopy*(src: PNode): PNode =
  1534. # does not copy its sons, but provides space for them:
  1535. copyNodeImpl(result, src):
  1536. newSeq(result.sons, src.len)
  1537. proc copyTree*(src: PNode): PNode =
  1538. # copy a whole syntax tree; performs deep copying
  1539. copyNodeImpl(result, src):
  1540. newSeq(result.sons, src.len)
  1541. for i in 0..<src.len:
  1542. result[i] = copyTree(src[i])
  1543. proc copyTreeWithoutNode*(src, skippedNode: PNode): PNode =
  1544. copyNodeImpl(result, src):
  1545. result.sons = newSeqOfCap[PNode](src.len)
  1546. for n in src.sons:
  1547. if n != skippedNode:
  1548. result.sons.add copyTreeWithoutNode(n, skippedNode)
  1549. proc hasSonWith*(n: PNode, kind: TNodeKind): bool =
  1550. for i in 0..<n.len:
  1551. if n[i].kind == kind:
  1552. return true
  1553. result = false
  1554. proc hasNilSon*(n: PNode): bool =
  1555. for i in 0..<n.safeLen:
  1556. if n[i] == nil:
  1557. return true
  1558. elif hasNilSon(n[i]):
  1559. return true
  1560. result = false
  1561. proc containsNode*(n: PNode, kinds: TNodeKinds): bool =
  1562. if n == nil: return
  1563. case n.kind
  1564. of nkEmpty..nkNilLit: result = n.kind in kinds
  1565. else:
  1566. for i in 0..<n.len:
  1567. if n.kind in kinds or containsNode(n[i], kinds): return true
  1568. proc hasSubnodeWith*(n: PNode, kind: TNodeKind): bool =
  1569. case n.kind
  1570. of nkEmpty..nkNilLit, nkFormalParams: result = n.kind == kind
  1571. else:
  1572. for i in 0..<n.len:
  1573. if (n[i].kind == kind) or hasSubnodeWith(n[i], kind):
  1574. return true
  1575. result = false
  1576. proc getInt*(a: PNode): Int128 =
  1577. case a.kind
  1578. of nkCharLit, nkUIntLit..nkUInt64Lit:
  1579. result = toInt128(cast[uint64](a.intVal))
  1580. of nkInt8Lit..nkInt64Lit:
  1581. result = toInt128(a.intVal)
  1582. of nkIntLit:
  1583. # XXX: enable this assert
  1584. # assert a.typ.kind notin {tyChar, tyUint..tyUInt64}
  1585. result = toInt128(a.intVal)
  1586. else:
  1587. raiseRecoverableError("cannot extract number from invalid AST node")
  1588. proc getInt64*(a: PNode): int64 {.deprecated: "use getInt".} =
  1589. case a.kind
  1590. of nkCharLit, nkUIntLit..nkUInt64Lit, nkIntLit..nkInt64Lit:
  1591. result = a.intVal
  1592. else:
  1593. raiseRecoverableError("cannot extract number from invalid AST node")
  1594. proc getFloat*(a: PNode): BiggestFloat =
  1595. case a.kind
  1596. of nkFloatLiterals: result = a.floatVal
  1597. of nkCharLit, nkUIntLit..nkUInt64Lit, nkIntLit..nkInt64Lit:
  1598. result = BiggestFloat a.intVal
  1599. else:
  1600. raiseRecoverableError("cannot extract number from invalid AST node")
  1601. #doAssert false, "getFloat"
  1602. #internalError(a.info, "getFloat")
  1603. #result = 0.0
  1604. proc getStr*(a: PNode): string =
  1605. case a.kind
  1606. of nkStrLit..nkTripleStrLit: result = a.strVal
  1607. of nkNilLit:
  1608. # let's hope this fixes more problems than it creates:
  1609. result = ""
  1610. else:
  1611. raiseRecoverableError("cannot extract string from invalid AST node")
  1612. #doAssert false, "getStr"
  1613. #internalError(a.info, "getStr")
  1614. #result = ""
  1615. proc getStrOrChar*(a: PNode): string =
  1616. case a.kind
  1617. of nkStrLit..nkTripleStrLit: result = a.strVal
  1618. of nkCharLit..nkUInt64Lit: result = $chr(int(a.intVal))
  1619. else:
  1620. raiseRecoverableError("cannot extract string from invalid AST node")
  1621. #doAssert false, "getStrOrChar"
  1622. #internalError(a.info, "getStrOrChar")
  1623. #result = ""
  1624. proc isGenericParams*(n: PNode): bool {.inline.} =
  1625. ## used to judge whether a node is generic params.
  1626. n != nil and n.kind == nkGenericParams
  1627. proc isGenericRoutine*(n: PNode): bool {.inline.} =
  1628. n != nil and n.kind in callableDefs and n[genericParamsPos].isGenericParams
  1629. proc isGenericRoutineStrict*(s: PSym): bool {.inline.} =
  1630. ## determines if this symbol represents a generic routine
  1631. ## the unusual name is so it doesn't collide and eventually replaces
  1632. ## `isGenericRoutine`
  1633. s.kind in skProcKinds and s.ast.isGenericRoutine
  1634. proc isGenericRoutine*(s: PSym): bool {.inline.} =
  1635. ## determines if this symbol represents a generic routine or an instance of
  1636. ## one. This should be renamed accordingly and `isGenericRoutineStrict`
  1637. ## should take this name instead.
  1638. ##
  1639. ## Warning/XXX: Unfortunately, it considers a proc kind symbol flagged with
  1640. ## sfFromGeneric as a generic routine. Instead this should likely not be the
  1641. ## case and the concepts should be teased apart:
  1642. ## - generic definition
  1643. ## - generic instance
  1644. ## - either generic definition or instance
  1645. s.kind in skProcKinds and (sfFromGeneric in s.flags or
  1646. s.ast.isGenericRoutine)
  1647. proc skipGenericOwner*(s: PSym): PSym =
  1648. ## Generic instantiations are owned by their originating generic
  1649. ## symbol. This proc skips such owners and goes straight to the owner
  1650. ## of the generic itself (the module or the enclosing proc).
  1651. result = if s.kind in skProcKinds and sfFromGeneric in s.flags:
  1652. s.owner.owner
  1653. else:
  1654. s.owner
  1655. proc originatingModule*(s: PSym): PSym =
  1656. result = s.owner
  1657. while result.kind != skModule: result = result.owner
  1658. proc isRoutine*(s: PSym): bool {.inline.} =
  1659. result = s.kind in skProcKinds
  1660. proc isCompileTimeProc*(s: PSym): bool {.inline.} =
  1661. result = s.kind == skMacro or
  1662. s.kind in {skProc, skFunc} and sfCompileTime in s.flags
  1663. proc isRunnableExamples*(n: PNode): bool =
  1664. # Templates and generics don't perform symbol lookups.
  1665. result = n.kind == nkSym and n.sym.magic == mRunnableExamples or
  1666. n.kind == nkIdent and n.ident.s == "runnableExamples"
  1667. proc requiredParams*(s: PSym): int =
  1668. # Returns the number of required params (without default values)
  1669. # XXX: Perhaps we can store this in the `offset` field of the
  1670. # symbol instead?
  1671. for i in 1..<s.typ.len:
  1672. if s.typ.n[i].sym.ast != nil:
  1673. return i - 1
  1674. return s.typ.len - 1
  1675. proc hasPattern*(s: PSym): bool {.inline.} =
  1676. result = isRoutine(s) and s.ast[patternPos].kind != nkEmpty
  1677. iterator items*(n: PNode): PNode =
  1678. for i in 0..<n.safeLen: yield n[i]
  1679. iterator pairs*(n: PNode): tuple[i: int, n: PNode] =
  1680. for i in 0..<n.safeLen: yield (i, n[i])
  1681. proc isAtom*(n: PNode): bool {.inline.} =
  1682. result = n.kind >= nkNone and n.kind <= nkNilLit
  1683. proc isEmptyType*(t: PType): bool {.inline.} =
  1684. ## 'void' and 'typed' types are often equivalent to 'nil' these days:
  1685. result = t == nil or t.kind in {tyVoid, tyTyped}
  1686. proc makeStmtList*(n: PNode): PNode =
  1687. if n.kind == nkStmtList:
  1688. result = n
  1689. else:
  1690. result = newNodeI(nkStmtList, n.info)
  1691. result.add n
  1692. proc skipStmtList*(n: PNode): PNode =
  1693. if n.kind in {nkStmtList, nkStmtListExpr}:
  1694. for i in 0..<n.len-1:
  1695. if n[i].kind notin {nkEmpty, nkCommentStmt}: return n
  1696. result = n.lastSon
  1697. else:
  1698. result = n
  1699. proc toVar*(typ: PType; kind: TTypeKind; idgen: IdGenerator): PType =
  1700. ## If ``typ`` is not a tyVar then it is converted into a `var <typ>` and
  1701. ## returned. Otherwise ``typ`` is simply returned as-is.
  1702. result = typ
  1703. if typ.kind != kind:
  1704. result = newType(kind, nextTypeId(idgen), typ.owner)
  1705. rawAddSon(result, typ)
  1706. proc toRef*(typ: PType; idgen: IdGenerator): PType =
  1707. ## If ``typ`` is a tyObject then it is converted into a `ref <typ>` and
  1708. ## returned. Otherwise ``typ`` is simply returned as-is.
  1709. result = typ
  1710. if typ.skipTypes({tyAlias, tyGenericInst}).kind == tyObject:
  1711. result = newType(tyRef, nextTypeId(idgen), typ.owner)
  1712. rawAddSon(result, typ)
  1713. proc toObject*(typ: PType): PType =
  1714. ## If ``typ`` is a tyRef then its immediate son is returned (which in many
  1715. ## cases should be a ``tyObject``).
  1716. ## Otherwise ``typ`` is simply returned as-is.
  1717. let t = typ.skipTypes({tyAlias, tyGenericInst})
  1718. if t.kind == tyRef: t.lastSon
  1719. else: typ
  1720. proc toObjectFromRefPtrGeneric*(typ: PType): PType =
  1721. #[
  1722. See also `toObject`.
  1723. Finds the underlying `object`, even in cases like these:
  1724. type
  1725. B[T] = object f0: int
  1726. A1[T] = ref B[T]
  1727. A2[T] = ref object f1: int
  1728. A3 = ref object f2: int
  1729. A4 = object f3: int
  1730. ]#
  1731. result = typ
  1732. while true:
  1733. case result.kind
  1734. of tyGenericBody: result = result.lastSon
  1735. of tyRef, tyPtr, tyGenericInst, tyGenericInvocation, tyAlias: result = result[0]
  1736. # automatic dereferencing is deep, refs #18298.
  1737. else: break
  1738. assert result.sym != nil
  1739. proc isImportedException*(t: PType; conf: ConfigRef): bool =
  1740. assert t != nil
  1741. if conf.exc != excCpp:
  1742. return false
  1743. let base = t.skipTypes({tyAlias, tyPtr, tyDistinct, tyGenericInst})
  1744. if base.sym != nil and {sfCompileToCpp, sfImportc} * base.sym.flags != {}:
  1745. result = true
  1746. proc isInfixAs*(n: PNode): bool =
  1747. return n.kind == nkInfix and n[0].kind == nkIdent and n[0].ident.s == "as"
  1748. proc skipColon*(n: PNode): PNode =
  1749. result = n
  1750. if n.kind == nkExprColonExpr:
  1751. result = n[1]
  1752. proc findUnresolvedStatic*(n: PNode): PNode =
  1753. # n.typ == nil: see issue #14802
  1754. if n.kind == nkSym and n.typ != nil and n.typ.kind == tyStatic and n.typ.n == nil:
  1755. return n
  1756. for son in n:
  1757. let n = son.findUnresolvedStatic
  1758. if n != nil: return n
  1759. return nil
  1760. when false:
  1761. proc containsNil*(n: PNode): bool =
  1762. # only for debugging
  1763. if n.isNil: return true
  1764. for i in 0..<n.safeLen:
  1765. if n[i].containsNil: return true
  1766. template hasDestructor*(t: PType): bool = {tfHasAsgn, tfHasOwned} * t.flags != {}
  1767. template incompleteType*(t: PType): bool =
  1768. t.sym != nil and {sfForward, sfNoForward} * t.sym.flags == {sfForward}
  1769. template typeCompleted*(s: PSym) =
  1770. incl s.flags, sfNoForward
  1771. template detailedInfo*(sym: PSym): string =
  1772. sym.name.s
  1773. proc isInlineIterator*(typ: PType): bool {.inline.} =
  1774. typ.kind == tyProc and tfIterator in typ.flags and typ.callConv != ccClosure
  1775. proc isIterator*(typ: PType): bool {.inline.} =
  1776. typ.kind == tyProc and tfIterator in typ.flags
  1777. proc isClosureIterator*(typ: PType): bool {.inline.} =
  1778. typ.kind == tyProc and tfIterator in typ.flags and typ.callConv == ccClosure
  1779. proc isClosure*(typ: PType): bool {.inline.} =
  1780. typ.kind == tyProc and typ.callConv == ccClosure
  1781. proc isSinkParam*(s: PSym): bool {.inline.} =
  1782. s.kind == skParam and (s.typ.kind == tySink or tfHasOwned in s.typ.flags)
  1783. proc isSinkType*(t: PType): bool {.inline.} =
  1784. t.kind == tySink or tfHasOwned in t.flags
  1785. proc newProcType*(info: TLineInfo; id: ItemId; owner: PSym): PType =
  1786. result = newType(tyProc, id, owner)
  1787. result.n = newNodeI(nkFormalParams, info)
  1788. rawAddSon(result, nil) # return type
  1789. # result.n[0] used to be `nkType`, but now it's `nkEffectList` because
  1790. # the effects are now stored in there too ... this is a bit hacky, but as
  1791. # usual we desperately try to save memory:
  1792. result.n.add newNodeI(nkEffectList, info)
  1793. proc addParam*(procType: PType; param: PSym) =
  1794. param.position = procType.len-1
  1795. procType.n.add newSymNode(param)
  1796. rawAddSon(procType, param.typ)
  1797. const magicsThatCanRaise = {
  1798. mNone, mSlurp, mStaticExec, mParseExprToAst, mParseStmtToAst, mEcho}
  1799. proc canRaiseConservative*(fn: PNode): bool =
  1800. if fn.kind == nkSym and fn.sym.magic notin magicsThatCanRaise:
  1801. result = false
  1802. else:
  1803. result = true
  1804. proc canRaise*(fn: PNode): bool =
  1805. if fn.kind == nkSym and (fn.sym.magic notin magicsThatCanRaise or
  1806. {sfImportc, sfInfixCall} * fn.sym.flags == {sfImportc} or
  1807. sfGeneratedOp in fn.sym.flags):
  1808. result = false
  1809. elif fn.kind == nkSym and fn.sym.magic == mEcho:
  1810. result = true
  1811. else:
  1812. # TODO check for n having sons? or just return false for now if not
  1813. if fn.typ != nil and fn.typ.n != nil and fn.typ.n[0].kind == nkSym:
  1814. result = false
  1815. else:
  1816. result = fn.typ != nil and fn.typ.n != nil and ((fn.typ.n[0].len < effectListLen) or
  1817. (fn.typ.n[0][exceptionEffects] != nil and
  1818. fn.typ.n[0][exceptionEffects].safeLen > 0))
  1819. proc toHumanStrImpl[T](kind: T, num: static int): string =
  1820. result = $kind
  1821. result = result[num..^1]
  1822. result[0] = result[0].toLowerAscii
  1823. proc toHumanStr*(kind: TSymKind): string =
  1824. ## strips leading `sk`
  1825. result = toHumanStrImpl(kind, 2)
  1826. proc toHumanStr*(kind: TTypeKind): string =
  1827. ## strips leading `tk`
  1828. result = toHumanStrImpl(kind, 2)
  1829. proc skipAddr*(n: PNode): PNode {.inline.} =
  1830. (if n.kind == nkHiddenAddr: n[0] else: n)
  1831. proc isNewStyleConcept*(n: PNode): bool {.inline.} =
  1832. assert n.kind == nkTypeClassTy
  1833. result = n[0].kind == nkEmpty
  1834. const
  1835. nodesToIgnoreSet* = {nkNone..pred(nkSym), succ(nkSym)..nkNilLit,
  1836. nkTypeSection, nkProcDef, nkConverterDef,
  1837. nkMethodDef, nkIteratorDef, nkMacroDef, nkTemplateDef, nkLambda, nkDo,
  1838. nkFuncDef, nkConstSection, nkConstDef, nkIncludeStmt, nkImportStmt,
  1839. nkExportStmt, nkPragma, nkCommentStmt, nkBreakState,
  1840. nkTypeOfExpr, nkMixinStmt, nkBindStmt}