Implements an IR for representing code in the code-generators. It's currently a slightly adjusted version of PNode, but the idea is to simplify and evolve it, meaning that everything here is subject to change.
Types
BlockId = distinct uint32
- Identifies a block within another block -- the IDs are not unique within a Body. An outermost block has ID 0, a block within the block ID 1, etc. Source Edit
Body = object locals*: Store[LocalId, Local] ## all locals belonging to the body code*: CgNode
- A self-contained CG IR fragment. This is usually the full body of a procedure. Source Edit
CgNode {.acyclic.} = ref object info*: TLineInfo typ*: PType case kind*: CgNodeKind of cnkInvalid, cnkEmpty, cnkType, cnkNilLit, cnkResume: nil of cnkIntLit, cnkUIntLit: intVal*: BiggestInt of cnkFloatLit: floatVal*: BiggestFloat of cnkStrLit: strVal*: StringId of cnkAstLit: astLit*: PNode of cnkField: field*: PSym of cnkProc: prc*: ProcedureId of cnkConst: cnst*: ConstId of cnkGlobal: global*: GlobalId of cnkMagic: magic*: TMagic of cnkLabel: label*: BlockId of cnkLocal: local*: LocalId of cnkWithOperand: operand*: CgNode of cnkWithItems: kids*: seq[CgNode]
- A node in the tree structure representing code during the code generation stage. The "CG" prefix is short for "code generation". Source Edit
CgNodeKind = enum cnkInvalid, ## the node is uninitialized cnkEmpty, ## represents the absence of something. The meaning depends ## on the context cnkType, ## a literal type cnkIntLit, cnkUIntLit, cnkFloatLit, cnkStrLit, cnkNilLit, ## the nil literal cnkAstLit, ## a ``NimNode`` literal cnkField, ## reference to an object field's symbol cnkLabel, ## name of a block cnkProc, ## name of a procedure cnkConst, ## reference to a named, global constant cnkGlobal, ## reference to a global location cnkLocal, ## reference to a local cnkMagic, ## name of a magic procedure. Only valid in the callee ## slot of ``cnkCall`` and ``cnkCheckedCall`` nodes cnkResume, ## leave the current procedure as part of exceptional ## control-flow cnkCall, ## a procedure call. The first operand is the procedure, ## the following operands the arguments cnkCheckedCall, ## like ``cnkCall``, but the call might raise an exception cnkNeg, cnkAdd, cnkSub, cnkMul, cnkDiv, cnkModI, cnkTupleConstr, ## tuple constructor cnkObjConstr, ## object constructor cnkSetConstr, ## set constructor cnkArrayConstr, ## array constructor cnkClosureConstr, ## closure constructor cnkRange, ## a range expression in a ``case``-branch or cnkBinding, ## special node used in ``cnkObjConstr`` to associate a ## field with a value cnkFieldAccess, cnkArrayAccess, cnkTupleAccess, cnkDeref, ## dereference 'x' cnkAddr, ## address of 'x' cnkHiddenAddr, ## create an internal reference of the operand cnkDerefView, ## dereference for a view cnkConv, ## a type conversion cnkLvalueConv, ## an lvalue-preserving conversion. The ones reaching ## into the code generators are usually discarded, but ## they're still required for proper typing cnkHiddenConv, cnkToSlice, ## slice creation. Works the same as the corresponding ## MIR operation cnkObjDownConv, ## down conversion between `object` or `ref` types cnkObjUpConv, ## up conversion between `object` or `ref` types cnkCast, ## reinterpret the bit-pattern of the operand as a ## different type cnkStmtList, cnkVoidStmt, ## discard the operand value (i.e., do nothing with it) cnkEmitStmt, ## an ``emit`` statement cnkAsmStmt, ## an ``asm`` statement cnkIfStmt, ## only execute the body when the condition expression ## evaluates to 'true' cnkCaseStmt, ## a ``case`` statement cnkBranch, ## the branch of a ``case`` statement cnkGotoStmt, cnkLoopStmt, ## jump back to a loop join point cnkRaiseStmt, ## raise(x) -- set the `x` as the current exception and start ## exceptional control-flow. `x` can be ``cnkEmpty`` in which ## case "set current exception" part is skipped cnkContinueStmt, ## jump to the next target in the active jump list cnkJoinStmt, ## join point for gotos cnkLoopJoinStmt, ## join point for loops cnkEnd, ## marks the end of a structured control-flow block ## (identified by the label) cnkExcept, ## special join point, representing an exception handler cnkFinally, cnkDef, ## starts the lifetime of a local and optionally assigns an ## initial value cnkAsgn, ## a = b cnkFastAsgn ## fast assign b to a
- Source Edit
Consts
cnkLiterals = {cnkIntLit, cnkUIntLit, cnkFloatLit, cnkStrLit}
- Source Edit
cnkWithItems = {cnkCall..cnkTupleAccess, cnkToSlice, cnkStmtList..cnkFastAsgn}
- node kinds for which the items iterator is available Source Edit
cnkWithOperand = {cnkConv, cnkHiddenConv, cnkDeref, cnkAddr, cnkHiddenAddr, cnkDerefView, cnkObjDownConv, cnkObjUpConv, cnkCast, cnkLvalueConv}
- Source Edit
Procs
proc merge(dest: var Body; source: Body): CgNode {....raises: [], tags: [].}
- Merges source into dest by appending the former to the latter. Returns the node representing the code from source after it was merged. Source Edit
proc newExpr(kind: CgNodeKind; info: TLineInfo; typ: PType; kids: varargs[CgNode]): CgNode {....raises: [], tags: [].}
- Source Edit
func newLocalRef(id: LocalId; info: TLineInfo; typ: PType): CgNode {....raises: [], tags: [].}
- Source Edit
proc newNode(kind: CgNodeKind; info = unknownLineInfo; typ = PType(nil)): CgNode {. ...raises: [], tags: [].}
- Source Edit