ast.nim 79 KB

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