-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathexpr.go
143 lines (137 loc) · 3.57 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
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
// Package expr provides a framework for parsing and evaluating mathematical expressions.
package expr
import (
"errors"
"github.com/regel/expr/ast"
)
type EvaluateError struct {
Message string
}
func (e *EvaluateError) Error() string {
return e.Message
}
// Compile parses and compiles a given input expression.
// The input expression is parsed into an AST (Abstract Syntax Tree) node, which
// is then returned along with any errors that occurred during the parsing process.
//
// Parameters:
// - input (string): The input expression to be compiled.
//
// Returns:
// - node (*ast.AST): The root node of the compiled AST.
// - err (error): Any error that occurred during parsing, or nil if no errors occurred.
//
// If a panic occurs during parsing, it is caught and an error is returned with a message describing the cause of the panic.
// If the panic is not a string or an error, an "unknown panic" error is returned.
//
// Example usage:
//
// node, err := ast.Compile("1 + 2 * 3")
func Compile(input string) (node *ast.AST, err error) {
node = nil
defer func() {
if r := recover(); r != nil {
switch x := r.(type) {
case string:
err = errors.New(x)
case error:
err = x
default:
err = errors.New("unknown panic")
}
}
}()
node, err = ast.ParseExpr(input)
return node, err
}
// Run executes the given AST in the provided environment.
//
// Parameters:
// - node (*ast.AST): the AST to be executed.
// - env (*ast.Env): the environment to be used for execution.
//
// Return values:
// - v (interface{}): the result of executing the AST.
// - err (error): an error, if one occurred during execution.
//
// If a panic occurs during execution, it is caught and an error is returned with a message describing the cause of the panic. If the panic is not a string or an error, an "unknown panic" error is returned.
//
// Example:
//
// package main
// import (
// "fmt"
// "github.com/regel/expr/ast"
// )
// func main() {
// env := ast.NewEnv()
// env.Set("x", 2.0)
// env.Set("y", 3.0)
// input := "x + y"
// node, err := ast.ParseExpr(input)
// if err != nil {
// fmt.Println(err)
// } else {
// result, err := expr.Run(node, env)
// if err != nil {
// fmt.Println(err)
// } else {
// fmt.Println(result)
// }
// }
// }
func Run(node *ast.AST, env *ast.Env) (v interface{}, err error) {
err = nil
v = 0
defer func() {
if r := recover(); r != nil {
switch x := r.(type) {
case string:
err = &EvaluateError{
Message: x,
}
case error:
err = x
default:
err = errors.New("unknown panic")
}
}
}()
v = ast.Evaluate(node, env)
return v, err
}
// Evaluate parses and evaluates a given input string using the provided environment.
//
// Parameters:
// - input (string): the input string to be evaluated.
// - env (*ast.Env): the environment to be used for evaluating the input string.
//
// Return values:
// - v (interface{}): the result of evaluating the input string.
// - err (error): an error, if one occurred during evaluation.
//
// If a panic occurs during evaluation, it is caught and an error is returned with a message describing the cause of the panic.
func Evaluate(input string, env *ast.Env) (v interface{}, err error) {
err = nil
v = 0
defer func() {
if r := recover(); r != nil {
switch x := r.(type) {
case string:
err = &EvaluateError{
Message: x,
}
case error:
err = x
default:
err = errors.New("unknown panic")
}
}
}()
node, err := ast.ParseExpr(input)
if err != nil {
return v, err
}
v = ast.Evaluate(node, env)
return v, err
}