-
Notifications
You must be signed in to change notification settings - Fork 3
/
expr.go
49 lines (45 loc) · 1.58 KB
/
expr.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
// Package mexpr provides a simple expression parser.
package mexpr
// Parse an expression and return the abstract syntax tree. If `types` is
// passed, it should be a set of representative example values for the input
// which will be used to type check the expression against.
func Parse(expression string, types any, options ...InterpreterOption) (*Node, Error) {
l := NewLexer(expression)
p := NewParser(l)
ast, err := p.Parse()
if err != nil {
return nil, err
}
if types != nil {
if err := TypeCheck(ast, types, options...); err != nil {
return ast, err
}
}
return ast, nil
}
// TypeCheck will take a parsed AST and type check against the given input
// structure with representative example values.
func TypeCheck(ast *Node, types any, options ...InterpreterOption) Error {
i := NewTypeChecker(ast, options...)
return i.Run(types)
}
// Run executes an AST with the given input and returns the output.
func Run(ast *Node, input any, options ...InterpreterOption) (any, Error) {
i := NewInterpreter(ast, options...)
return i.Run(input)
}
// Eval is a convenience function which lexes, parses, and executes an
// expression with the given input. If you plan to execute the expression
// multiple times consider caching the output of `Parse(...)` instead for a
// big speed improvement.
func Eval(expression string, input any, options ...InterpreterOption) (any, Error) {
// No need to type check because we are about to run with the input.
ast, err := Parse(expression, nil)
if err != nil {
return nil, err
}
if ast == nil {
return nil, nil
}
return Run(ast, input, options...)
}