ast.nim 78 KB

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