abstract syntax tree + symbol table querying operations
A companion module to ast_types containing things related to querying the AST and Symbol Table. Not all reads are here as some base level reading is required for manipulation, which are contained in ast itself.
Types
NodePosName = enum PosLastIdent, ## Last item in the identifier PosType, ## Type position for variable declaration or a procedure. For ## procedure returns it's formal parameters (signature) PosInit, ## Initialization expression PosProcBody, ## Procedure body PosProcReturn, ## Return value of the procedure in formal parameters PosProcArgs, ## Formal parmeters in the procedure PosTypeBody, ## Type definition body PosName, ## Procedure name PosBody, ## Generic statement body PosPragma ## Pragma position in the node body
- Named node position accessor Source Edit
NodeSliceName = enum SliceAllIdents, ## All identifiers in the ident defs SliceAllArguments, ## All arguments in the formal parammeters SliceAllBranches, ## All case statement branches SliceBranchExpressions ## All expressions in the `of` branch
- Named node slice accessor Source Edit
Consts
AttachedOpToMagic: array[TTypeAttachedOp, TMagic] = [mDestroy, mAsgn, mAsgn, mTrace, mDeepCopy]
- Source Edit
AttachedOpToStr: array[TTypeAttachedOp, string] = ["=destroy", "=copy", "=sink", "=trace", "=deepcopy"]
- Source Edit
callableDefs = {nkLambda..nkDo, nkProcDef..nkIteratorDef, nkFuncDef}
- Source Edit
compilerInfoPos = 2
- Error compiler source file as strlit, line & col on info Source Edit
ConcreteTypes: TTypeKinds = {tyBool, tyChar, tyEnum, tyArray, tyObject, tySet, tyTuple, tyRange, tyPtr, tyRef, tyVar, tyLent, tySequence, tyProc, tyPointer, tyOpenArray, tyString, tyCstring, tyInt..tyInt64, tyFloat..tyFloat64, tyUInt..tyUInt64}
- Source Edit
ConstantDataTypes: TTypeKinds = {tyArray, tySet, tyTuple, tySequence}
- Source Edit
declarativeDefs = {nkProcDef, nkFuncDef, nkMethodDef, nkIteratorDef, nkConverterDef}
- Source Edit
defaultAlignment = -1
- Source Edit
defaultOffset = -1
- Source Edit
defaultSize = -1
- Source Edit
dispatcherPos = 8
- Source Edit
entityDefs = {nkIdentDefs..nkVarTuple, nkLambda..nkDo, nkProcDef..nkIteratorDef, nkForStmt, nkConstDef, nkFuncDef}
- all nodes that have definition slots. In other words, semantic analysis of these can introduce new symbols Source Edit
errorKindPos = 1
- Error kind enum as an intlit Source Edit
FakeVarParams = {mInc, mDec, mIncl, mExcl, mSetLengthStr, mSetLengthSeq, mAppendStrCh, mAppendStrStr, mSwap, mAppendSeqElem, mNewSeq, mReset, mShallowCopy, mDeepCopy, mMove, mWasMoved}
- An arguments to these magics never uses nkHiddenAddr, even if the corresponding parameter is a 'var' parameter. The reason for this is that these magics are lowered into code that, because it gets inlined directly, doesn't mutate the arguments through indirection. This also implies that the "is address taken" analysis (see sfAddrTaken) must not be performed for arguments to these magics. Source Edit
firstArgPos = 3
- Error first 0..n additional nodes depends on error kind Source Edit
genericParamsPos = 2
- Generic parametesr in the procedure-like nodes Source Edit
GenericTypes: TTypeKinds = {tyGenericInvocation, tyGenericBody, tyGenericParam}
- Source Edit
IntegralTypes = {tyBool, tyChar, tyEnum, tyInt..tyInt64, tyFloat..tyFloat64, tyUInt..tyUInt64}
- Source Edit
magicsThatCanRaise = {mNone, mParseExprToAst, mParseStmtToAst, mEcho, mChckRange}
- Source Edit
MaxLockLevel = 1000'i16
- Source Edit
NilableTypes: TTypeKinds = {tyPointer, tyCstring, tyRef, tyPtr, tyProc, tyProxy}
- Source Edit
nkAllNodeKinds = {nkError..nkNilRodNode}
- Source Edit
nkCallKinds = {nkCall, nkInfix, nkPrefix, nkPostfix, nkCommand, nkCallStrLit, nkHiddenCallConv}
- Source Edit
nkFloatKinds = {nkFloatLit..nkFloat64Lit}
- Source Edit
nkIdentKinds = {nkIdent, nkSym, nkAccQuoted, nkOpenSymChoice, nkClosedSymChoice}
- Source Edit
nkIntKinds = {nkCharLit..nkUInt64Lit}
- Source Edit
nkLambdaKinds = {nkLambda, nkDo}
- Source Edit
nkPragmaCallKinds = {nkExprColonExpr, nkCall, nkCallStrLit}
- Source Edit
nkStrKinds = {nkStrLit..nkTripleStrLit}
- Source Edit
nkSymChoices = {nkClosedSymChoice, nkOpenSymChoice}
- Source Edit
nkTypeExprs = {nkTypeOfExpr, nkObjectTy, nkTupleTy, nkTupleClassTy, nkTypeClassTy, nkStaticTy, nkRefTy, nkPtrTy, nkVarTy, nkConstTy, nkMutableTy, nkDistinctTy, nkProcTy, nkIteratorTy, nkSharedTy, nkEnumTy}
- Source Edit
OverloadableSyms = {skProc, skFunc, skMethod, skIterator, skConverter, skTemplate, skMacro, skEnumField, skModule}
- Source Edit
patternPos = 1
- empty except for term rewriting macros Source Edit
PersistentNodeFlags: TNodeFlags = {nfDotSetter, nfDotField, nfLL, nfFromTemplate, nfDefaultRefsParam, nfWasGensym}
- Source Edit
pragmasPos = 4
- Position of the pragma in the procedure-like nodes Source Edit
PtrLikeKinds: TTypeKinds = {tyPointer, tyPtr}
- Source Edit
routineDefs = {nkProcDef..nkIteratorDef, nkFuncDef}
- Source Edit
skipForDiscardable = {nkIfStmt, nkIfExpr, nkCaseStmt, nkOfBranch, nkElse, nkStmtListExpr, nkTryStmt, nkFinally, nkExceptBranch, nkElifBranch, nkElifExpr, nkElseExpr, nkBlockStmt, nkBlockExpr, nkHiddenStdConv, nkHiddenDeref}
- Source Edit
skLocalVars = {skVar, skLet, skForVar, skParam, skResult}
- Source Edit
skProcKinds = {skProc, skFunc, skTemplate, skMacro, skIterator, skMethod, skConverter}
- Source Edit
StructuralEquivTypes: TTypeKinds = {tyNil, tyTuple, tyArray, tySet, tyRange, tyPtr, tyRef, tyVar, tyLent, tySequence, tyProc, tyOpenArray, tyVarargs}
- Source Edit
UnknownLockLevel = 1001'i16
- Source Edit
UnspecifiedLockLevel = -1'i16
- Source Edit
wrongNodePos = 0
- Error the ast node we swapped Source Edit
Procs
proc `$`(x: TLockLevel): string {....raises: [], tags: [].}
- Source Edit
proc `[]`(node: PNode; pos: NodePosName): PNode {....raises: [], tags: [].}
- Get subnode by named position Source Edit
proc `[]`(node: PNode; slice: NodeSliceName): seq[PNode] {....raises: [], tags: [].}
- Access named node slice Source Edit
proc astdef(s: PSym): PNode {....raises: [], tags: [].}
- get only the definition (initializer) portion of the ast Source Edit
proc canRaise(panicsEnabled: bool; n: PNode): bool {....raises: [], tags: [].}
- 'true' if a call with n as the callee can exit via exceptional control- flow, otherwise 'false'. If panics are not enabled, this also includes all routines that are not certain magics, compiler procs, or imported. Source Edit
proc canRaiseConservative(fn: PNode): bool {....raises: [], tags: [].}
- Source Edit
proc containsNode(n: PNode; kinds: TNodeKinds): bool {....raises: [], tags: [].}
- Source Edit
proc endsInNoReturn(n: PNode): bool {....raises: [], tags: [].}
- Checks if expression n ends in an unstructured exit (raise, return, etc.) or a call of a noreturn proc. This is meant to be called on a semmed n. Source Edit
proc findUnresolvedStatic(n: PNode): PNode {....raises: [], tags: [].}
- Source Edit
proc getDeclPragma(n: PNode): PNode {....raises: [], tags: [].}
- return the nkPragma node for declaration n, or nil if no pragma was found. Currently only supports routineDefs + {nkTypeDef}. Source Edit
proc getIdentLineInfo(n: PNode): TLineInfo {....raises: [], tags: [].}
- Returns the line information of the identifier-like node in the (semantically valid) AST n appearing in a name slot. Source Edit
proc getInt64(a: PNode): int64 {....deprecated: "use getInt", raises: [ERecoverableError], tags: [].}
- Source Edit
proc getnimblePkg(a: PSym): PSym {....raises: [], tags: [].}
- Source Edit
proc getnimblePkgId(a: PSym): int {....raises: [], tags: [].}
- Source Edit
proc getPIdent(a: PNode): PIdent {.inline, ...raises: [], tags: [].}
- Returns underlying PIdent for {nkSym, nkIdent}, or nil. Source Edit
proc getStrOrChar(a: PNode): string {....raises: [ERecoverableError], tags: [].}
- Source Edit
func hasDestructor(t: PType): bool {.inline, ...raises: [], tags: [].}
- Returns whether the underlying concrete type of t has attached lifetime tracking hooks (that is, is resource-like). Source Edit
proc hasPattern(s: PSym): bool {.inline, ...raises: [], tags: [].}
- Source Edit
proc hasSonWith(n: PNode; kind: TNodeKind): bool {....raises: [], tags: [].}
- Source Edit
proc hasSubnodeWith(n: PNode; kind: TNodeKind): bool {....raises: [], tags: [].}
- Source Edit
proc isCallExpr(n: PNode): bool {....raises: [], tags: [].}
- Source Edit
proc isClosureIterator(typ: PType): bool {.inline, ...raises: [], tags: [].}
- Source Edit
proc isCompileTimeProc(s: PSym): bool {.inline, ...raises: [], tags: [].}
- Source Edit
proc isEmptyType(t: PType): bool {.inline, ...raises: [], tags: [].}
- 'void' and 'typed' types are often equivalent to 'nil' these days: Source Edit
proc isError(n: PNode): bool {.inline, ...raises: [], tags: [].}
- whether the node is an error, strictly checks nkError and is nil safe Source Edit
proc isError(s: PSym): bool {.inline, ...raises: [], tags: [].}
- whether the symbol is an error, strictly checks skError, an error node exists, and is nil safe. Source Edit
proc isError(t: PType): bool {.inline, ...raises: [], tags: [].}
-
whether the type is an error. useful because of compiler legacy, as tyError isn't an enum field rather a const refering to tyProxy.
xxx: currently we have no way to disambiguate between legacy and new
Source Edit proc isErrorLike(n: PNode): bool {.inline, ...raises: [], tags: [].}
-
whether the node is an error, including error symbol, or error type
- xxx: longer term we should probably not produce nodes like these in the
- first place and mark them as nkErrors with an appropriate error kind.
proc isErrorLike(s: PSym): bool {.inline, ...raises: [], tags: [].}
- whether the symbol is an error. useful because of compiler legacy, as skError isn't an enum field rather a const refering to skUnkonwn. we disambiguate via the presence of the ast field being non-nil and of kind nkError Source Edit
proc isErrorLike(t: PType): bool {.inline, ...raises: [], tags: [].}
-
whether the type is an error. useful because of compiler legacy, as tyError isn't an enum field rather a const refering to tyProxy.
xxx: currently we have no way to disambiguate between legacy and new
Source Edit proc isGenericParams(n: PNode): bool {.inline, ...raises: [], tags: [].}
- used to judge whether a node is generic params. Source Edit
proc isGenericRoutine(n: PNode): bool {.inline, ...raises: [], tags: [].}
- Source Edit
proc isGenericRoutine(s: PSym): bool {.inline, ...raises: [], tags: [].}
-
determines if this symbol represents a generic routine or an instance of one. This should be renamed accordingly and isGenericRoutineStrict should take this name instead.
Warning/XXX: Unfortunately, it considers a proc kind symbol flagged with sfFromGeneric as a generic routine. Instead this should likely not be the case and the concepts should be teased apart:
- generic definition
- generic instance
- either generic definition or instance
proc isGenericRoutineStrict(s: PSym): bool {.inline, ...raises: [], tags: [].}
- determines if this symbol represents a generic routine the unusual name is so it doesn't collide and eventually replaces isGenericRoutine Source Edit
proc isInlineIterator(typ: PType): bool {.inline, ...raises: [], tags: [].}
- Source Edit
proc isMetaType(t: PType): bool {....raises: [], tags: [].}
- Source Edit
func isOwnedBy(a, b: PSym): bool {....raises: [], tags: [].}
- Tests if b is the transitive owner of a, returns true if a got owned! :) Source Edit
proc isRunnableExamples(n: PNode): bool {....raises: [], tags: [].}
- Source Edit
proc isSinkParam(s: PSym): bool {.inline, ...raises: [], tags: [].}
- Source Edit
proc isSinkType(t: PType): bool {.inline, ...raises: [], tags: [].}
- Source Edit
proc isUnresolvedStatic(t: PType): bool {....raises: [], tags: [].}
- Source Edit
proc isUnresolvedSym(s: PSym): bool {....raises: [], tags: [].}
- Source Edit
proc originatingModule(s: PSym): PSym {....raises: [], tags: [].}
- Source Edit
proc requiredGenericParams(s: PSym): int {....raises: [], tags: [].}
- Source Edit
proc requiredParams(s: PSym): int {....raises: [], tags: [].}
- Source Edit
proc skipDistincts(t: PType): PType {.inline, ...raises: [], tags: [].}
- Skips over all possible distinct instantiations, getting base. Source Edit
proc skipGenericOwner(s: PSym): PSym {....raises: [], tags: [].}
- Generic instantiations are owned by their originating generic symbol. This proc skips such owners and goes straight to the owner of the generic itself (the module or the enclosing proc). Source Edit
proc skipStmtList(n: PNode): PNode {....raises: [], tags: [].}
- Source Edit
proc skipTypes(t: PType; kinds: TTypeKinds): PType {....raises: [], tags: [].}
- Used throughout the compiler code to test whether a type tree contains or doesn't contain a specific type/types - it is often the case that only the last child nodes of a type tree need to be searched. This is a really hot path within the compiler! Source Edit
proc skipTypes(t: PType; kinds: TTypeKinds; maxIters: int): PType {....raises: [], tags: [].}
- Source Edit
proc skipTypesOrNil(t: PType; kinds: TTypeKinds): PType {....raises: [], tags: [].}
- same as skipTypes but handles 'nil' Source Edit
Iterators
iterator branches(node: PNode): tuple[position: int, n: PNode] {....raises: [], tags: [].}
- Returns all branches of the case statement or expression node in order of occurrence. position is the 0-based position of the branch, not the index of the sub-node Source Edit
iterator branchLabels(node: PNode): (int, PNode) {....raises: [], tags: [].}
- Returns all labels of the branch-like constructs (i.e. of, if, elif) that node represents, together with their position. For convenience, else branches are also allowed: they're treated as having no labels Source Edit
iterator forLoopDefs(forStmt: PNode): PNode {....raises: [], tags: [].}
- Returns the nodes appearing in the name slots (including nested ones) of the provided nkForStmt node. Source Edit
iterator genericParamsInMacroCall(macroSym: PSym; call: PNode): (PSym, PNode) {. ...raises: [], tags: [].}
- For a macro call, yields the symbol for each generic parameter toghether with the argument provided to it Source Edit
Templates
template detailedInfo(sym: PSym): string
- Source Edit
template incompleteType(t: PType): bool
- Source Edit
template previouslyInferred(t: PType): PType
- Source Edit
template typeCompleted(s: PSym)
- Source Edit