forked from influxdata/kapacitor
-
Notifications
You must be signed in to change notification settings - Fork 0
/
scope.go
92 lines (74 loc) · 2.14 KB
/
scope.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
package stateful
import (
"fmt"
"strings"
"github.com/influxdata/kapacitor/tick/ast"
)
type DynamicMethod func(self interface{}, args ...interface{}) (interface{}, error)
type DynamicFunc struct {
F func(args ...interface{}) (interface{}, error)
Sig map[Domain]ast.ValueType
}
func (df DynamicFunc) Call(args ...interface{}) (interface{}, error) {
return df.F(args...)
}
func (df DynamicFunc) Reset() {
}
func (df DynamicFunc) Signature() map[Domain]ast.ValueType {
return df.Sig
}
// Special marker that a value is empty
var empty = new(interface{})
// Contains a set of variables references and their values.
type Scope struct {
variables map[string]interface{}
dynamicMethods map[string]DynamicMethod
dynamicFuncs map[string]*DynamicFunc
}
//Initialize a new Scope object.
func NewScope() *Scope {
return &Scope{
variables: make(map[string]interface{}),
dynamicMethods: make(map[string]DynamicMethod),
dynamicFuncs: make(map[string]*DynamicFunc),
}
}
// Set defines a name -> value pairing in the scope.
func (s *Scope) Set(name string, value interface{}) {
s.variables[name] = value
}
// Whether a value has been set on the scope
func (s *Scope) Has(name string) bool {
v, ok := s.variables[name]
return ok && v != empty
}
// Get returns the value of 'name'.
func (s *Scope) Get(name string) (interface{}, error) {
if v, ok := s.variables[name]; ok && v != empty {
return v, nil
}
var possible []string
for k := range s.variables {
possible = append(possible, k)
}
return nil, fmt.Errorf("name %q is undefined. Names in scope: %s", name, strings.Join(possible, ","))
}
// Reset all scope values to an empty state.
func (s *Scope) Reset() {
// Scopes, are intended to be reused so do not free resources
for name := range s.variables {
s.Set(name, empty)
}
}
func (s *Scope) SetDynamicMethod(name string, m DynamicMethod) {
s.dynamicMethods[name] = m
}
func (s *Scope) DynamicMethod(name string) DynamicMethod {
return s.dynamicMethods[name]
}
func (s *Scope) SetDynamicFunc(name string, f *DynamicFunc) {
s.dynamicFuncs[name] = f
}
func (s *Scope) DynamicFunc(name string) *DynamicFunc {
return s.dynamicFuncs[name]
}