Documentation ¶
Overview ¶
Package ast implements the nodes that form the abstract syntax tree once the lemur code has been parsed
This AST that results from the lemur code being successfully parsed is used as the input to the compiler to product the necessary byte code required for execution
Index ¶
- type ArrayLiteral
- type AssignmentExpression
- type BlockStatement
- type Boolean
- type CallExpression
- type CaseExpression
- type Expression
- type ExpressionStatement
- type ForExpression
- type ForInExpression
- type Function
- type FunctionLiteral
- type Identifier
- type IfExpression
- type IndexExpression
- type InfixExpression
- type IntegerLiteral
- type IteratorJumpStatement
- type MapLiteral
- type Node
- type PrefixExpression
- type Program
- type ReturnStatement
- type Statement
- type StringLiteral
- type SwitchExpression
- type ValStatement
- type WhileExpression
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type ArrayLiteral ¶
type ArrayLiteral struct { Token lexer.Token Elements []Expression }
ArrayLiteral simply represents a keyed data structure starting from an index of 0. The Elements can be made up of expressions and literals
func (*ArrayLiteral) String ¶
func (al *ArrayLiteral) String() string
func (*ArrayLiteral) TokenLiteral ¶
func (al *ArrayLiteral) TokenLiteral() string
type AssignmentExpression ¶
type AssignmentExpression struct { Token lexer.Token Left Expression Right Expression }
AssignmentExpression represents an expression when an existing symbol has it's value changed. Syntactically it is similar to an infix expression but has it's own node type because it's complication is closer to a ValStatement than an InfixExpression
func (*AssignmentExpression) String ¶
func (a *AssignmentExpression) String() string
func (*AssignmentExpression) TokenLiteral ¶
func (a *AssignmentExpression) TokenLiteral() string
type BlockStatement ¶
BlockStatement represents many statements as part of a block. A block is typically attach to something scoped like a Function and FunctionLiteral, or control flows like loops and conditionals
func (*BlockStatement) String ¶
func (bs *BlockStatement) String() string
func (*BlockStatement) TokenLiteral ¶
func (bs *BlockStatement) TokenLiteral() string
type Boolean ¶
IntegerLiteral simply represents a boolean primitive data type
func (*Boolean) TokenLiteral ¶
type CallExpression ¶
type CallExpression struct { Token lexer.Token Function Expression Arguments []Expression }
CallExpression represents an expression where a function is being called. The Arguments make up what should be passed to the Function if it has parameters defined
func (*CallExpression) String ¶
func (ce *CallExpression) String() string
func (*CallExpression) TokenLiteral ¶
func (ce *CallExpression) TokenLiteral() string
type CaseExpression ¶
type CaseExpression struct { Conditions []Expression Consequence *BlockStatement }
CaseExpression are part of SwitchExpression and represent the various condition that if one evaluates to true allow for the consequence block to be executed
type Expression ¶
type Expression interface { Node }
Expression represents a certain syntactical entity that will be evaluated
type ExpressionStatement ¶
type ExpressionStatement struct { Token lexer.Token Expression Expression }
ExpressionStatement acts as a default expression if the statment doesn't fall into other categories e.g a initialising statement like a ValStatement
func (*ExpressionStatement) String ¶
func (es *ExpressionStatement) String() string
func (*ExpressionStatement) TokenLiteral ¶
func (es *ExpressionStatement) TokenLiteral() string
type ForExpression ¶
type ForExpression struct { Token lexer.Token InitialiseStatement *ValStatement Condition Expression PostAssignmentStatement *AssignmentExpression Block *BlockStatement }
ForExpression represents one of the loop control flows available. ForExpression are made up of a initialising statement, a condition to evaluate that it's met or not, a post assignment statement to change the value of the symbol creating in the initialising statement, and a block to execute if the condition is met. The block should be executed as many times until the condition is not met
func (*ForExpression) String ¶
func (f *ForExpression) String() string
func (*ForExpression) TokenLiteral ¶
func (f *ForExpression) TokenLiteral() string
type ForInExpression ¶
type ForInExpression struct { Token lexer.Token KeyIdentifier *Identifier ValueIdentifier *Identifier Iterable Expression Block *BlockStatement }
ForInExpression represents one of the loop control flows available. It is made up of a iterable to be looped over, a key and value idenitifier to be assign values to based on the current position pointed to on the iterable, and a block to be executed for every item within the iterable
func (*ForInExpression) String ¶
func (fi *ForInExpression) String() string
func (*ForInExpression) TokenLiteral ¶
func (fi *ForInExpression) TokenLiteral() string
type Function ¶
type Function struct {
*FunctionLiteral
}
Function represents a normally define function which is always named
type FunctionLiteral ¶
type FunctionLiteral struct { Token lexer.Token Parameters []*Identifier Body *BlockStatement Name string }
FunctionLiteral represents a scoped block of code that can be called. It's made up of parameters that define what arguments can be passed, a block/body to execute, and optionally a name if define as a Function or attached to an identifier
func (*FunctionLiteral) String ¶
func (fl *FunctionLiteral) String() string
func (*FunctionLiteral) TokenLiteral ¶
func (fl *FunctionLiteral) TokenLiteral() string
type Identifier ¶
Identifier represents a token/symbol a user defines within their code
func (*Identifier) String ¶
func (i *Identifier) String() string
func (*Identifier) TokenLiteral ¶
func (i *Identifier) TokenLiteral() string
type IfExpression ¶
type IfExpression struct { Token lexer.Token Condition Expression Consequence *BlockStatement ElseIfs []*IfExpression Alternative *BlockStatement }
IfExpression represents one of the conditional branching control flows available. It encapsulates the condition of the if, it's consequence when evaluated to true, a set of other IfExpressions to represent else if when there are any, and finally an alternative representing the else block if defined
func (*IfExpression) String ¶
func (ie *IfExpression) String() string
func (*IfExpression) TokenLiteral ¶
func (ie *IfExpression) TokenLiteral() string
type IndexExpression ¶
type IndexExpression struct { Token lexer.Token Left Expression Index Expression }
IndexExpression represents an expression against an underlying ArrayLiteral or MapLiteral where a key is used to retrieve a value associated with it
func (*IndexExpression) String ¶
func (ie *IndexExpression) String() string
func (*IndexExpression) TokenLiteral ¶
func (ie *IndexExpression) TokenLiteral() string
type InfixExpression ¶
type InfixExpression struct { Token lexer.Token Left Expression Operator string Right Expression }
InfixExpression represents mostly but not exclusively arithmetic expressions. Exception to this would be for example using the + operator between two strings for concatenation purposes
func (*InfixExpression) String ¶
func (oe *InfixExpression) String() string
func (*InfixExpression) TokenLiteral ¶
func (oe *InfixExpression) TokenLiteral() string
type IntegerLiteral ¶
IntegerLiteral simply represents an integer primitive data type
func (*IntegerLiteral) String ¶
func (il *IntegerLiteral) String() string
func (*IntegerLiteral) TokenLiteral ¶
func (il *IntegerLiteral) TokenLiteral() string
type IteratorJumpStatement ¶
IteratorJumpStatement represents a call to stop/move to the next iteration early of loop control flows. These are done either via the keywords break (to stop) or continue (to move to the next iteration early)
func (*IteratorJumpStatement) String ¶
func (c *IteratorJumpStatement) String() string
func (*IteratorJumpStatement) TokenLiteral ¶
func (c *IteratorJumpStatement) TokenLiteral() string
type MapLiteral ¶
type MapLiteral struct { Token lexer.Token Pairs map[Expression]Expression }
MapLiteral simply represents a key value data structure. The key and value Pairs can be made up of expressions and literals
func (*MapLiteral) String ¶
func (hl *MapLiteral) String() string
func (*MapLiteral) TokenLiteral ¶
func (hl *MapLiteral) TokenLiteral() string
type Node ¶
type Node interface { // TokenLiteral is the pure string representation of the Node TokenLiteral() string // String is a formatted string version of the Node String() string }
Node represents a single part of the AST that is built by the parser
type PrefixExpression ¶
type PrefixExpression struct { Token lexer.Token Operator string Right Expression }
PrefixExpression represents expression where the operator is placed before the expression. There is no support for arithmetic operators (this is done via assignment expression like a += 1) and the only prefixes that are supported are ! and -
func (*PrefixExpression) String ¶
func (pe *PrefixExpression) String() string
func (*PrefixExpression) TokenLiteral ¶
func (pe *PrefixExpression) TokenLiteral() string
type Program ¶
type Program struct {
Statements []Statement
}
Program is the top level of the AST that represents the code that has been parsed
func (*Program) TokenLiteral ¶
type ReturnStatement ¶
type ReturnStatement struct { Token lexer.Token ReturnValue Expression }
ReturnStatement represents the execution to leave the function/current scope and resume the point where said function/current scope was called. This statement can have a value that is also returns back to the point at where it was called
func (*ReturnStatement) String ¶
func (r *ReturnStatement) String() string
func (*ReturnStatement) TokenLiteral ¶
func (r *ReturnStatement) TokenLiteral() string
type Statement ¶
type Statement interface { Node }
Statement represents the individual terminated code that becomes part of the overall Program or block
type StringLiteral ¶
StringLiteral simply represents a string primitive data type
func (*StringLiteral) String ¶
func (sl *StringLiteral) String() string
func (*StringLiteral) TokenLiteral ¶
func (sl *StringLiteral) TokenLiteral() string
type SwitchExpression ¶
type SwitchExpression struct { Token lexer.Token Expression Expression Cases []*CaseExpression Default *BlockStatement }
SwitchExpression represents one of the conditional branching control flows available. Unlike IfExpression where conditions can vary their comparisons, switch conditions are compare to the initial expression using an equality check before executing it's related consequence block. Similar to the else in IfExpression, there is an optional default block if none of the conditions are met
func (*SwitchExpression) String ¶
func (se *SwitchExpression) String() string
func (*SwitchExpression) TokenLiteral ¶
func (se *SwitchExpression) TokenLiteral() string
type ValStatement ¶
type ValStatement struct { Token lexer.Token Name *Identifier Value Expression Mutable bool }
ValStatement represents an initialising statement when a symbol is first attached to an expression. This initialising statement to a symbol typically allows the user to also define if the symbol is mutable or not
func (*ValStatement) String ¶
func (ls *ValStatement) String() string
func (*ValStatement) TokenLiteral ¶
func (ls *ValStatement) TokenLiteral() string
type WhileExpression ¶
type WhileExpression struct { Token lexer.Token Condition Expression Block *BlockStatement }
WhileExpression represents one of the loop control flows available. It is made up of a condition, and a block to execute in the condition is met. The block should be executed as many times until the condition is not met
func (*WhileExpression) String ¶
func (w *WhileExpression) String() string
func (*WhileExpression) TokenLiteral ¶
func (w *WhileExpression) TokenLiteral() string