Documentation ¶
Overview ¶
TICKscript is a simple invocation chaining DSL. See the examples for how its used and example syntax of the DSL.
A reflection based evaluation of an AST.
Index ¶
- Constants
- Variables
- func Evaluate(script string, scope *Scope) (err error)
- type BinaryNode
- type BoolNode
- type DurationNode
- type DynamicMethod
- type Func
- type Funcs
- type FunctionNode
- type IdentifierNode
- type LambdaNode
- type ListNode
- type Node
- type NumberNode
- type ReferenceNode
- type ReflectionDescriber
- func (r *ReflectionDescriber) CallMethod(name string, args ...interface{}) (interface{}, error)
- func (r *ReflectionDescriber) Desc() string
- func (r *ReflectionDescriber) HasMethod(name string) bool
- func (r *ReflectionDescriber) HasProperty(name string) bool
- func (r *ReflectionDescriber) Property(name string) interface{}
- func (r *ReflectionDescriber) SetProperty(name string, value interface{}) error
- type RegexNode
- type Scope
- type SelfDescriber
- type StarNode
- type StatefulExpr
- type StringNode
- type UnaryNode
Examples ¶
Constants ¶
const ( TokenError tokenType = iota TokenEOF TokenVar TokenAsgn TokenDot TokenIdent TokenReference TokenLambda TokenNumber TokenString TokenDuration TokenLParen TokenRParen TokenComma TokenNot TokenTrue TokenFalse TokenRegex TokenPlus TokenMinus TokenMult TokenDiv TokenMod TokenAnd TokenOr TokenEqual TokenNotEqual TokenLess TokenGreater TokenLessEqual TokenGreaterEqual TokenRegexEqual TokenRegexNotEqual )
Variables ¶
var ErrEmptyStack = errors.New("stack is empty")
var ErrInvalidExpr = errors.New("expression is invalid, could not evaluate")
var ErrNotFloat = errors.New("value is not a float")
Functions ¶
func Evaluate ¶
Parse and evaluate a given script for the scope. This evaluation method uses reflection to call methods on objects within the scope.
Example ¶
package main import ( "fmt" ) type Process struct { Name string Children []*Process } func (p *Process) Spawn() *Process { child := &Process{} p.Children = append(p.Children, child) return child } func (p *Process) String() string { return fmt.Sprintf("{%q %s}", p.Name, p.Children) } func main() { //Run a test that evaluates the DSL against the Process struct. script := ` //Name the parent parent.name('parent') // Spawn a first child var child1 = parent.spawn() // Name the first child child1.name('child1') //Spawn a grandchild and name it child1.spawn().name('grandchild') //Spawn a second child and name it parent.spawn().name('child2') ` scope := NewScope() parent := &Process{} scope.Set("parent", parent) err := Evaluate(script, scope) if err != nil { fmt.Println(err) } fmt.Println(parent) }
Output: {"parent" [{"child1" [{"grandchild" []}]} {"child2" []}]}
Types ¶
type BinaryNode ¶
type BinaryNode struct { Left Node Right Node Operator tokenType // contains filtered or unexported fields }
binaryNode holds two arguments and an operator.
func (*BinaryNode) String ¶
func (b *BinaryNode) String() string
type BoolNode ¶
type BoolNode struct { Bool bool // contains filtered or unexported fields }
boolNode holds one argument and an operator.
type DurationNode ¶
type DurationNode struct { Dur time.Duration //the duration // contains filtered or unexported fields }
durationNode holds a number: signed or unsigned integer or float. The value is parsed and stored under all the types that can represent the value. This simulates in a small amount of code the behavior of Go's ideal constants.
func (*DurationNode) String ¶
func (d *DurationNode) String() string
type DynamicMethod ¶ added in v0.10.0
type DynamicMethod func(self interface{}, args ...interface{}) (interface{}, error)
type Func ¶
type Func interface { Reset() Call(...interface{}) (interface{}, error) }
A callable function from within the expression
type FunctionNode ¶
type FunctionNode struct { Func string // The identifier Args []Node // contains filtered or unexported fields }
Holds the a function call with its args
func (*FunctionNode) String ¶
func (f *FunctionNode) String() string
type IdentifierNode ¶
type IdentifierNode struct { Ident string // The identifier // contains filtered or unexported fields }
Holds the textual representation of an identifier
func (*IdentifierNode) String ¶
func (i *IdentifierNode) String() string
type LambdaNode ¶
type LambdaNode struct { Node Node // contains filtered or unexported fields }
Represents the begining of a lambda expression
func (*LambdaNode) String ¶
func (l *LambdaNode) String() string
type ListNode ¶
type ListNode struct { Nodes []Node // contains filtered or unexported fields }
Holds a function call with its args
type NumberNode ¶
type NumberNode struct { IsInt bool // Number has an integral value. IsFloat bool // Number has a floating-point value. Int64 int64 // The integer value. Float64 float64 // The floating-point value. // contains filtered or unexported fields }
numberNode holds a number: signed or unsigned integer or float. The value is parsed and stored under all the types that can represent the value. This simulates in a small amount of code the behavior of Go's ideal constants.
func (*NumberNode) String ¶
func (n *NumberNode) String() string
type ReferenceNode ¶
type ReferenceNode struct { Reference string // The field reference // contains filtered or unexported fields }
Holds the textual representation of an identifier
func (*ReferenceNode) String ¶
func (r *ReferenceNode) String() string
type ReflectionDescriber ¶ added in v0.10.0
type ReflectionDescriber struct {
// contains filtered or unexported fields
}
Wraps any object as a SelfDescriber using reflection.
func NewReflectionDescriber ¶ added in v0.10.0
func NewReflectionDescriber(obj interface{}) *ReflectionDescriber
func (*ReflectionDescriber) CallMethod ¶ added in v0.10.0
func (r *ReflectionDescriber) CallMethod(name string, args ...interface{}) (interface{}, error)
func (*ReflectionDescriber) Desc ¶ added in v0.10.0
func (r *ReflectionDescriber) Desc() string
func (*ReflectionDescriber) HasMethod ¶ added in v0.10.0
func (r *ReflectionDescriber) HasMethod(name string) bool
Using reflection check if the object has the method or field. A field is a valid method because we can set it via reflection too.
func (*ReflectionDescriber) HasProperty ¶ added in v0.10.0
func (r *ReflectionDescriber) HasProperty(name string) bool
Using reflection check if the object has a field with the property name.
func (*ReflectionDescriber) Property ¶ added in v0.10.0
func (r *ReflectionDescriber) Property(name string) interface{}
func (*ReflectionDescriber) SetProperty ¶ added in v0.10.0
func (r *ReflectionDescriber) SetProperty(name string, value interface{}) error
type Scope ¶
type Scope struct {
// contains filtered or unexported fields
}
Contains a set of variables references and their values.
func (*Scope) DynamicMethod ¶ added in v0.10.0
func (s *Scope) DynamicMethod(name string) DynamicMethod
func (*Scope) SetDynamicMethod ¶ added in v0.10.0
func (s *Scope) SetDynamicMethod(name string, m DynamicMethod)
type SelfDescriber ¶ added in v0.10.0
type SelfDescriber interface { //A description the object Desc() string HasMethod(name string) bool CallMethod(name string, args ...interface{}) (interface{}, error) HasProperty(name string) bool Property(name string) interface{} SetProperty(name string, arg interface{}) error }
Interface for interacting with objects. If an object does not self describe via this interface than a reflection based implemenation will be used.
type StarNode ¶
type StarNode struct {
// contains filtered or unexported fields
}
Represents a standalone '*' token.
type StatefulExpr ¶
Expression functions are stateful. Their state is updated with each call to the function. A StatefulExpr is a Node and its associated function state.
func NewStatefulExpr ¶
func NewStatefulExpr(n Node) *StatefulExpr
type StringNode ¶
type StringNode struct { Literal string // The string literal // contains filtered or unexported fields }
Holds the textual representation of a string literal
func (*StringNode) String ¶
func (s *StringNode) String() string