tim/engine/ast

Search:
Group by:

Types

Ast {.acyclic.} = ref object
  src*: string               ## the source path of the ast
  nodes*: seq[Node]          ## a seq containing tree nodes 
  partials*: TimPartialsTable ## AST trees from included partials 
  modules*: TimModulesTable  ## AST trees from imported modules
  jit*: bool                 ## whether the current AST requires JIT compliation or not
  
CommandType = enum
  cmdEcho = "echo", cmdReturn = "return", cmdDiscard = "discard",
  cmdBreak = "break"
ConditionBranch = tuple[expr: Node, body: seq[Node]]
FnParam = tuple[pName: string, pType: NodeType, pImplVal: Node, meta: Meta]
FunctionType = enum
  fnImportLocal, fnImportSystem, fnImportModule
HtmlAttributes = TableRef[string, seq[Node]]
InfixOp {.pure.} = enum
  None, EQ = "==", NE = "!=", GT = ">", GTE = ">=", LT = "<", LTE = "<=",
  AND = "and", OR = "or", AMP = "&"
MathOp {.pure.} = enum
  invalidCalcOp, mPlus = "+", mMinus = "-", mMulti = "*", mDiv = "/", mMod = "%"
Meta = array[3, int]
Node {.acyclic.} = ref object
  case nt*: NodeType
  of ntHtmlElement:
      tag*: HtmlTag
      stag*: string
      attrs*: HtmlAttributes
      attrNodes*: seq[Node]
      nodes*: seq[Node]

  of ntVariableDef:
      varName*: string       ## variable identifier
      varValue*: Node        ## the value of a variable
      varType*: NodeType     ## type of a variable, any of `string`, `int`, `float`, `array`, `object`
      varUsed*: bool
      varImmutable*: bool    ## enabled when a variable is defined as `const`
    
  of ntAssignExpr:
      asgnIdent*: string     ## identifier name
      asgnVal*: Node         ## a Node value assigned to `asgnIdent`
    
  of ntInfixExpr:
      infixOp*: InfixOp      ## the infix operator 
      infixLeft*, infixRight*: Node ## lhs, rhs nodes
    
  of ntMathInfixExpr:
      infixMathOp*: MathOp   ## the infix operator for math operations
      infixMathLeft*, infixMathRight*: Node ## lhs, rhs nodes for math operations
    
  of ntConditionStmt:
      condIfBranch*: ConditionBranch ## the `if` branch of a conditional statement
      condElifBranch*: seq[ConditionBranch] ## a sequence of `elif` branches
      condElseBranch*: seq[Node] ## the body of an `else` branch
    
  of ntCaseStmt:
      caseExpr*: Node
      caseBranch*: seq[ConditionBranch]
      caseElse*: seq[Node]

  of ntLoopStmt:
      loopItem*: Node        ## a node type of `ntIdent` or `ntIdentPair`
      loopItems*: Node       ## a node type represeting an iterable storage
      loopBody*: seq[Node]   ## a sequence of Node elements in `for` body
    
  of ntIdentPair:
      identPairs*: tuple[a, b: Node]

  of ntLitString:
      sVal*: string
      sVals*: seq[Node]

  of ntLitInt:
      iVal*: int

  of ntLitFloat:
      fVal*: float

  of ntLitBool:
      bVal*: bool

  of ntLitArray:
      arrayType*: NodeType
      arrayItems*: seq[Node] ## a sequence of nodes representing an array
    
  of ntLitObject:
      objectItems*: OrderedTableRef[string, Node] ## Ordered table of Nodes for object storage
    
  of ntCommandStmt:
      cmdType*: CommandType  ## type of given command, either `echo` or `return`
      cmdValue*: Node        ## the node value of the command 
    
  of ntIdent:
      identName*: string
      identSafe*: bool
      identArgs*: seq[Node]

  of ntDotExpr:
      storageType*: StorageType ## holds the storage type of a dot expression
      lhs*, rhs*: Node       ## lhs, rhs nodes of dot expression node
    
  of ntBracketExpr:
      bracketStorageType*: StorageType ## holds the storage type of a bracket expression
      bracketLHS*, bracketIndex*: Node ## lhs, rhs nodes of a bracket expression
    
  of ntIndexRange:
      rangeNodes*: array[2, Node]
      rangeLastIndex*: bool

  of ntFunction:
      fnIdent*: string       ## function identifier name
      fnParams*: OrderedTable[string, FnParam] ## an ordered table containing the function parameters
      fnBody*: seq[Node]     ## the function body
      fnReturnType*: NodeType ## the return type of a function
                              ## if a function has no return type, then `ntUnknown`
                              ## is used as default (void)
      fnReturnHtmlElement*: HtmlTag
      fnFwdDecl*, fnExport*: bool
      fnType*: FunctionType
      fnSource*: string

  of ntJavaScriptSnippet, ntYamlSnippet, ntJsonSnippet:
      snippetCode*: string   ## string-based snipept code for either
                             ## `yaml`, `json` or `js`
    
  of ntInclude:
      includes*: seq[string] ## a sequence of files to be included
    
  of ntImport:
      modules*: seq[string]  ## a sequence containing imported modules
    
  of ntPlaceholder:
      placeholderName*: string ## placeholder target name
    
  of ntStream:
      streamContent*: JsonNode

  of ntClientBlock:
      clientTargetElement*: string ## an existing HTML selector to used
                                   ## to insert generated JavaScript snippet
                                   ## using `insertAdjacentElement()`
      clientStmt*: seq[Node] ## nodes to interpret/transpile to JavaScript
                             ## for client-side rendering. Note that only HTML
                             ## elements will be transformed to JS code, while
                             ## other statements (such `if`, `for`, `var`) are getting
                             ## interpreted at compile-time (for static templates) or 
                             ## on the fly for templates marked as jit.
    
  of ntStmtList:
      stmtList*: seq[Node]

  of ntRuntimeCode:
      runtimeCode*: string

  else:
    nil
  meta*: Meta
Part of the compiler's abstract syntax tree Important do not initialize this object directly
NodeType = enum
  ntUnknown = "void", ntLitInt = "int", ntLitString = "string",
  ntLitFloat = "float", ntLitBool = "bool", ntLitArray = "array",
  ntLitObject = "object", ntFunction = "function", ntLitVoid = "void",
  ntVariableDef = "Variable", ntAssignExpr = "Assignment",
  ntHtmlElement = "HtmlElement", ntInfixExpr = "InfixExpression",
  ntMathInfixExpr = "MathExpression", ntCommandStmt = "CommandStatement",
  ntIdent = "Identifier", ntCall = "FunctionCall", ntIdentPair,
  ntDotExpr = "DotExpression", ntBracketExpr = "BracketExpression",
  ntIndexRange = "IndexRange", ntConditionStmt = "ConditionStatement",
  ntCaseStmt = "CaseExpression", ntLoopStmt = "LoopStmt",
  ntViewLoader = "ViewLoader", ntInclude = "Include", ntImport = "Import",
  ntPlaceholder = "Placeholder", ntStream = "Stream",
  ntJavaScriptSnippet = "JavaScriptSnippet", ntYamlSnippet = "YAMLSnippet",
  ntJsonSnippet = "JsonSnippet", ntClientBlock = "ClientSideStatement",
  ntStmtList = "StatementList", ntRuntimeCode = "Runtime"
ScopeTable = TableRef[string, Node]
StorageType = enum
  scopeStorage,             ## Data created inside a `timl` template.
                             ## Scope data can be accessed by identifier name
                             ## ```
                             ## var say = "Hello"
                             ## echo $say
                             ## ```
  globalStorage,            ## Data exposed globally using a `JsonNode` object
                             ## when initializing Tim Engine. Global data
                             ## can be accessed from any layout, view or partial
                             ## using the `$app` prefix
  localStorage ## Data exposed from a Controller using a `JsonNode` object is stored
               ## in a local storage.  Can be accessed from the current view, layout and its partials
               ## using the `$this` prefix.
TimModulesTable = TableRef[string, Ast]
TimPartialsTable = TableRef[string, (Ast, seq[cli.Row])]
Value = object
  case kind*: ValueKind
  of jsonValue:
      jVal*: JsonNode

  of nimValue:
      nVal*: Node

  
ValueKind = enum
  jsonValue, nimValue

Consts

ntAssignableSet = {ntLitString, ntLitInt, ntLitFloat, ntLitBool, ntLitObject,
                   ntLitArray}

Procs

proc `$`(x: Ast): string {....raises: [Exception], tags: [RootEffect], forbids: [].}
proc getInfixMathOp(kind: TokenKind; isInfixInfix: bool): MathOp {....raises: [],
    tags: [], forbids: [].}
proc getInfixOp(kind: TokenKind; isInfixInfix: bool): InfixOp {....raises: [],
    tags: [], forbids: [].}
proc getTag(x: Node): string {....raises: [], tags: [], forbids: [].}
proc getType(x: NimNode): NodeType {.compileTime, ...raises: [], tags: [],
                                     forbids: [].}
proc getVoidNode(): Node {....raises: [], tags: [], forbids: [].}
proc newArray(items: seq[Node] = @[]): Node {....raises: [], tags: [], forbids: [].}
Creates a new Array node
proc newAssignment(tk: TokenTuple; varValue: Node): Node {....raises: [], tags: [],
    forbids: [].}
Create a new assignment Node
proc newBool(v: bool): Node {....raises: [], tags: [], forbids: [].}
Create a new bool value Node
proc newBool(v: bool; tk: TokenTuple): Node {....raises: [], tags: [], forbids: [].}
Create a new bool value Node
proc newCall(tk: TokenTuple): Node {....raises: [], tags: [], forbids: [].}
Create a new function call Node
proc newCommand(cmdType: CommandType; node: Node; tk: TokenTuple): Node {.
    ...raises: [], tags: [], forbids: [].}
Create a new command for cmdType
proc newCondition(condIfBranch: ConditionBranch; tk: TokenTuple): Node {.
    ...raises: [], tags: [], forbids: [].}
proc newFloat(v: float): Node {....raises: [], tags: [], forbids: [].}
Create a new float value node
proc newFloat(v: float; tk: TokenTuple): Node {....raises: [], tags: [],
    forbids: [].}
Create a new float value node
proc newFunction(tk: TokenTuple; ident: string): Node {....raises: [], tags: [],
    forbids: [].}
Create a new Function definition Node
proc newHtmlElement(tag: HtmlTag; tk: TokenTuple): Node {....raises: [], tags: [],
    forbids: [].}
proc newIdent(tk: TokenTuple): Node {....raises: [], tags: [], forbids: [].}
proc newInfix(lhs, rhs: Node; infixOp: InfixOp; tk: TokenTuple): Node {.
    ...raises: [], tags: [], forbids: [].}
proc newInteger(v: int): Node {....raises: [], tags: [], forbids: [].}
proc newInteger(v: int; tk: TokenTuple): Node {....raises: [], tags: [],
    forbids: [].}
proc newNode(nt: static NodeType): Node
proc newNode(nt: static NodeType; tk: TokenTuple): Node
proc newStream(node: JsonNode): Node {....raises: [], tags: [], forbids: [].}
Create a new Stream from node
proc newString(tk: TokenTuple): Node {....raises: [], tags: [], forbids: [].}
Create a new string value node
proc newString(v: string): Node {....raises: [], tags: [], forbids: [].}
Create a new string value node
proc newVariable(varName: string; varValue: Node; meta: Meta): Node {.
    ...raises: [], tags: [], forbids: [].}
Create a new variable definition Node
proc newVariable(varName: string; varValue: Node; tk: TokenTuple): Node {.
    ...raises: [], tags: [], forbids: [].}
Create a new variable definition Node
proc toTimNode(x: JsonNode): Node {....raises: [], tags: [], forbids: [].}