vancode/interpreter/ast

This module defines the AST (Abstract Syntax Tree) data structures used by the VanCode interpreter. The AST is fully extensible, allowing for easy addition of new node kinds and fields without modifying existing code

The AST is designed to be simple and flexible, with a focus on ease of use and extensibility. It supports a wide range of node kinds, including literals, expressions, statements, and declarations.

Each node can have an arbitrary number of child nodes, which are stored in a sequence. Leaf nodes (such as literals and identifiers) have specific fields to store their values, while branch nodes use the children sequence to store their child nodes.

Types

Ast {.acyclic.} = ref object
  sourcePath*: string        ## The source path of the AST (e.g., the file path of the template)
  otherPaths*: seq[string]   ## Other paths that this AST is associated with (imported/included templates)
  nodes*: seq[Node]          ## The top-level nodes of the AST
HtmlAttributeType = enum
  htmlAttrClass, htmlAttrId, htmlAttrIdent, htmlAttr
Node {.acyclic.} = ref object
  ln*, col*: int             ## Line information used for compile errors
  case kind* {.extensibleCase.}: NodeKind
  of nkEmpty, nkNil:
    nil
  of nkBool:
    boolVal*: bool           ## The boolean value
  of nkInt:
    intVal*: int64           ## The integer value
  of nkFloat:
    floatVal*: float64       ## The float value
  of nkString:
    stringVal*: string       ## The string value
  of nkIdent:
    ident*: string           ## The identifier name
  of nkVarTy:
    varType*: Node           ## The variable type node
  of nkDocComment:
    comment*: string         ## The doc comment content
  else:
    children*: seq[Node]     ## Child nodes used to build the AST tree
                             ## Used for all other node kinds not listed above
An AST node.
NodeKind {..} = enum
  nkEmpty, nkBool, nkInt, nkFloat, nkString, nkIdent, nkVarTy, nkNil, nkScript,
  nkIdentDefs, nkFormalParams, nkGenericParams, nkRecFields, nkPrefix,
  nkPostfix, nkInfix, nkDot, nkBracket, nkColon, nkIndex, nkCall, nkIf,
  nkProcTy, nkTypeDef, nkVar = "var", nkLet = "let", nkConst = "const", nkWhile,
  nkFor, nkBreak, nkContinue, nkReturn, nkYield, nkImport, nkInclude, nkStatic,
  nkObject, nkArray, nkProc, nkIterator, nkBlock, nkDocComment, nkObjectStorage

Lets

defaultNil = newIdent("nil")

Procs

proc `$`(node: Node): string {....raises: [], tags: [], forbids: [].}
Stringify a node. This only supports leaf nodes, for trees, use treeRepr.
proc `[]`(node: Node; index: int | BackwardsIndex): Node
proc `[]`(node: Node; slice: HSlice): seq[Node]
proc `[]=`(node: Node; index: int | BackwardsIndex; child: Node)
proc add(node, child: Node): Node {.discardable, ...raises: [], tags: [],
                                    forbids: [].}
proc add(node: Node; children: openArray[Node]): Node {.discardable, ...raises: [],
    tags: [], forbids: [].}
proc debugEcho(node: Node) {....gcsafe, raises: [OpenParserJsonError, ValueError,
    Exception], tags: [RootEffect], forbids: [].}
proc debugEcho(nodes: seq[Node]) {....gcsafe, raises: [OpenParserJsonError,
    ValueError, Exception], tags: [RootEffect], forbids: [].}
proc hash(node: Node): Hash {....raises: [Exception], tags: [RootEffect],
                              forbids: [].}
proc len(node: Node): int {....raises: [], tags: [], forbids: [].}
proc newBoolLit(val: bool): Node {....raises: [], tags: [], forbids: [].}
Construct a new bool literal.
proc newCall(ident: Node; args: varargs[Node]): Node {....raises: [], tags: [],
    forbids: [].}
Construct a new call node.
proc newEmpty(): Node {....raises: [], tags: [], forbids: [].}
Construct a new empty node.
proc newFloatLit(val: float64): Node {....raises: [], tags: [], forbids: [].}
Construct a new float literal.
proc newFunction(ident, body: Node;
                 genericParams, formalParams: Node = newEmpty()): Node {.
    ...raises: [], tags: [], forbids: [].}
Construct a new function declaration node.
proc newIdent(ident: string): Node {....raises: [], tags: [], forbids: [].}
Construct a new ident node.
proc newIdentDefs(names: openArray[Node]; ty: Node; value = newEmpty()): Node {.
    ...raises: [], tags: [], forbids: [].}
Construct a new nkIdentDefs node.
proc newInfix(op, left, right: Node): Node {....raises: [], tags: [], forbids: [].}
Construct a new infix node.
proc newIntLit(val: int64): Node {....raises: [], tags: [], forbids: [].}
Construct a new integer literal.
proc newNil(): Node {....raises: [], tags: [], forbids: [].}
Construct a new nil node.
proc newNode(kind: NodeKind): Node {....raises: [], tags: [], forbids: [].}
Construct a new node.
proc newStringLit(val: string): Node {....raises: [], tags: [], forbids: [].}
Construct a new string literal.
proc newTree(kind: NodeKind; children: varargs[Node]): Node {....raises: [],
    tags: [], forbids: [].}
Construct a new branch node with the given kind.
proc nkBlock(children: varargs[Node]): Node {....raises: [], tags: [], forbids: [].}
Construct a new block.
proc render(node: Node): string {....raises: [Exception], tags: [RootEffect],
                                  forbids: [].}
Renders the node's AST representation into a string. Note that this is imperfect and can't fully reproduce the actual user input (this, for instance, omits parentheses, as they are ignored by the parser).
proc treeRepr(node: Node): string {....raises: [], tags: [], forbids: [].}
Stringify a node into a tree representation.

Iterators

iterator items(node: Node): Node {....raises: [], tags: [], forbids: [].}
iterator pairs(node: Node): tuple[i: int, n: Node] {....raises: [], tags: [],
    forbids: [].}