ast.nim 82 KB

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