]> git.immae.eu Git - github/fretlink/terraform-provider-statuscake.git/blob - vendor/github.com/hashicorp/hil/builtins.go
Initial transfer of provider code
[github/fretlink/terraform-provider-statuscake.git] / vendor / github.com / hashicorp / hil / builtins.go
1 package hil
2
3 import (
4 "errors"
5 "strconv"
6
7 "github.com/hashicorp/hil/ast"
8 )
9
10 // NOTE: All builtins are tested in engine_test.go
11
12 func registerBuiltins(scope *ast.BasicScope) *ast.BasicScope {
13 if scope == nil {
14 scope = new(ast.BasicScope)
15 }
16 if scope.FuncMap == nil {
17 scope.FuncMap = make(map[string]ast.Function)
18 }
19
20 // Implicit conversions
21 scope.FuncMap["__builtin_BoolToString"] = builtinBoolToString()
22 scope.FuncMap["__builtin_FloatToInt"] = builtinFloatToInt()
23 scope.FuncMap["__builtin_FloatToString"] = builtinFloatToString()
24 scope.FuncMap["__builtin_IntToFloat"] = builtinIntToFloat()
25 scope.FuncMap["__builtin_IntToString"] = builtinIntToString()
26 scope.FuncMap["__builtin_StringToInt"] = builtinStringToInt()
27 scope.FuncMap["__builtin_StringToFloat"] = builtinStringToFloat()
28 scope.FuncMap["__builtin_StringToBool"] = builtinStringToBool()
29
30 // Math operations
31 scope.FuncMap["__builtin_IntMath"] = builtinIntMath()
32 scope.FuncMap["__builtin_FloatMath"] = builtinFloatMath()
33 scope.FuncMap["__builtin_BoolCompare"] = builtinBoolCompare()
34 scope.FuncMap["__builtin_FloatCompare"] = builtinFloatCompare()
35 scope.FuncMap["__builtin_IntCompare"] = builtinIntCompare()
36 scope.FuncMap["__builtin_StringCompare"] = builtinStringCompare()
37 scope.FuncMap["__builtin_Logical"] = builtinLogical()
38 return scope
39 }
40
41 func builtinFloatMath() ast.Function {
42 return ast.Function{
43 ArgTypes: []ast.Type{ast.TypeInt},
44 Variadic: true,
45 VariadicType: ast.TypeFloat,
46 ReturnType: ast.TypeFloat,
47 Callback: func(args []interface{}) (interface{}, error) {
48 op := args[0].(ast.ArithmeticOp)
49 result := args[1].(float64)
50 for _, raw := range args[2:] {
51 arg := raw.(float64)
52 switch op {
53 case ast.ArithmeticOpAdd:
54 result += arg
55 case ast.ArithmeticOpSub:
56 result -= arg
57 case ast.ArithmeticOpMul:
58 result *= arg
59 case ast.ArithmeticOpDiv:
60 result /= arg
61 }
62 }
63
64 return result, nil
65 },
66 }
67 }
68
69 func builtinIntMath() ast.Function {
70 return ast.Function{
71 ArgTypes: []ast.Type{ast.TypeInt},
72 Variadic: true,
73 VariadicType: ast.TypeInt,
74 ReturnType: ast.TypeInt,
75 Callback: func(args []interface{}) (interface{}, error) {
76 op := args[0].(ast.ArithmeticOp)
77 result := args[1].(int)
78 for _, raw := range args[2:] {
79 arg := raw.(int)
80 switch op {
81 case ast.ArithmeticOpAdd:
82 result += arg
83 case ast.ArithmeticOpSub:
84 result -= arg
85 case ast.ArithmeticOpMul:
86 result *= arg
87 case ast.ArithmeticOpDiv:
88 if arg == 0 {
89 return nil, errors.New("divide by zero")
90 }
91
92 result /= arg
93 case ast.ArithmeticOpMod:
94 if arg == 0 {
95 return nil, errors.New("divide by zero")
96 }
97
98 result = result % arg
99 }
100 }
101
102 return result, nil
103 },
104 }
105 }
106
107 func builtinBoolCompare() ast.Function {
108 return ast.Function{
109 ArgTypes: []ast.Type{ast.TypeInt, ast.TypeBool, ast.TypeBool},
110 Variadic: false,
111 ReturnType: ast.TypeBool,
112 Callback: func(args []interface{}) (interface{}, error) {
113 op := args[0].(ast.ArithmeticOp)
114 lhs := args[1].(bool)
115 rhs := args[2].(bool)
116
117 switch op {
118 case ast.ArithmeticOpEqual:
119 return lhs == rhs, nil
120 case ast.ArithmeticOpNotEqual:
121 return lhs != rhs, nil
122 default:
123 return nil, errors.New("invalid comparison operation")
124 }
125 },
126 }
127 }
128
129 func builtinFloatCompare() ast.Function {
130 return ast.Function{
131 ArgTypes: []ast.Type{ast.TypeInt, ast.TypeFloat, ast.TypeFloat},
132 Variadic: false,
133 ReturnType: ast.TypeBool,
134 Callback: func(args []interface{}) (interface{}, error) {
135 op := args[0].(ast.ArithmeticOp)
136 lhs := args[1].(float64)
137 rhs := args[2].(float64)
138
139 switch op {
140 case ast.ArithmeticOpEqual:
141 return lhs == rhs, nil
142 case ast.ArithmeticOpNotEqual:
143 return lhs != rhs, nil
144 case ast.ArithmeticOpLessThan:
145 return lhs < rhs, nil
146 case ast.ArithmeticOpLessThanOrEqual:
147 return lhs <= rhs, nil
148 case ast.ArithmeticOpGreaterThan:
149 return lhs > rhs, nil
150 case ast.ArithmeticOpGreaterThanOrEqual:
151 return lhs >= rhs, nil
152 default:
153 return nil, errors.New("invalid comparison operation")
154 }
155 },
156 }
157 }
158
159 func builtinIntCompare() ast.Function {
160 return ast.Function{
161 ArgTypes: []ast.Type{ast.TypeInt, ast.TypeInt, ast.TypeInt},
162 Variadic: false,
163 ReturnType: ast.TypeBool,
164 Callback: func(args []interface{}) (interface{}, error) {
165 op := args[0].(ast.ArithmeticOp)
166 lhs := args[1].(int)
167 rhs := args[2].(int)
168
169 switch op {
170 case ast.ArithmeticOpEqual:
171 return lhs == rhs, nil
172 case ast.ArithmeticOpNotEqual:
173 return lhs != rhs, nil
174 case ast.ArithmeticOpLessThan:
175 return lhs < rhs, nil
176 case ast.ArithmeticOpLessThanOrEqual:
177 return lhs <= rhs, nil
178 case ast.ArithmeticOpGreaterThan:
179 return lhs > rhs, nil
180 case ast.ArithmeticOpGreaterThanOrEqual:
181 return lhs >= rhs, nil
182 default:
183 return nil, errors.New("invalid comparison operation")
184 }
185 },
186 }
187 }
188
189 func builtinStringCompare() ast.Function {
190 return ast.Function{
191 ArgTypes: []ast.Type{ast.TypeInt, ast.TypeString, ast.TypeString},
192 Variadic: false,
193 ReturnType: ast.TypeBool,
194 Callback: func(args []interface{}) (interface{}, error) {
195 op := args[0].(ast.ArithmeticOp)
196 lhs := args[1].(string)
197 rhs := args[2].(string)
198
199 switch op {
200 case ast.ArithmeticOpEqual:
201 return lhs == rhs, nil
202 case ast.ArithmeticOpNotEqual:
203 return lhs != rhs, nil
204 default:
205 return nil, errors.New("invalid comparison operation")
206 }
207 },
208 }
209 }
210
211 func builtinLogical() ast.Function {
212 return ast.Function{
213 ArgTypes: []ast.Type{ast.TypeInt},
214 Variadic: true,
215 VariadicType: ast.TypeBool,
216 ReturnType: ast.TypeBool,
217 Callback: func(args []interface{}) (interface{}, error) {
218 op := args[0].(ast.ArithmeticOp)
219 result := args[1].(bool)
220 for _, raw := range args[2:] {
221 arg := raw.(bool)
222 switch op {
223 case ast.ArithmeticOpLogicalOr:
224 result = result || arg
225 case ast.ArithmeticOpLogicalAnd:
226 result = result && arg
227 default:
228 return nil, errors.New("invalid logical operator")
229 }
230 }
231
232 return result, nil
233 },
234 }
235 }
236
237 func builtinFloatToInt() ast.Function {
238 return ast.Function{
239 ArgTypes: []ast.Type{ast.TypeFloat},
240 ReturnType: ast.TypeInt,
241 Callback: func(args []interface{}) (interface{}, error) {
242 return int(args[0].(float64)), nil
243 },
244 }
245 }
246
247 func builtinFloatToString() ast.Function {
248 return ast.Function{
249 ArgTypes: []ast.Type{ast.TypeFloat},
250 ReturnType: ast.TypeString,
251 Callback: func(args []interface{}) (interface{}, error) {
252 return strconv.FormatFloat(
253 args[0].(float64), 'g', -1, 64), nil
254 },
255 }
256 }
257
258 func builtinIntToFloat() ast.Function {
259 return ast.Function{
260 ArgTypes: []ast.Type{ast.TypeInt},
261 ReturnType: ast.TypeFloat,
262 Callback: func(args []interface{}) (interface{}, error) {
263 return float64(args[0].(int)), nil
264 },
265 }
266 }
267
268 func builtinIntToString() ast.Function {
269 return ast.Function{
270 ArgTypes: []ast.Type{ast.TypeInt},
271 ReturnType: ast.TypeString,
272 Callback: func(args []interface{}) (interface{}, error) {
273 return strconv.FormatInt(int64(args[0].(int)), 10), nil
274 },
275 }
276 }
277
278 func builtinStringToInt() ast.Function {
279 return ast.Function{
280 ArgTypes: []ast.Type{ast.TypeInt},
281 ReturnType: ast.TypeString,
282 Callback: func(args []interface{}) (interface{}, error) {
283 v, err := strconv.ParseInt(args[0].(string), 0, 0)
284 if err != nil {
285 return nil, err
286 }
287
288 return int(v), nil
289 },
290 }
291 }
292
293 func builtinStringToFloat() ast.Function {
294 return ast.Function{
295 ArgTypes: []ast.Type{ast.TypeString},
296 ReturnType: ast.TypeFloat,
297 Callback: func(args []interface{}) (interface{}, error) {
298 v, err := strconv.ParseFloat(args[0].(string), 64)
299 if err != nil {
300 return nil, err
301 }
302
303 return v, nil
304 },
305 }
306 }
307
308 func builtinBoolToString() ast.Function {
309 return ast.Function{
310 ArgTypes: []ast.Type{ast.TypeBool},
311 ReturnType: ast.TypeString,
312 Callback: func(args []interface{}) (interface{}, error) {
313 return strconv.FormatBool(args[0].(bool)), nil
314 },
315 }
316 }
317
318 func builtinStringToBool() ast.Function {
319 return ast.Function{
320 ArgTypes: []ast.Type{ast.TypeString},
321 ReturnType: ast.TypeBool,
322 Callback: func(args []interface{}) (interface{}, error) {
323 v, err := strconv.ParseBool(args[0].(string))
324 if err != nil {
325 return nil, err
326 }
327
328 return v, nil
329 },
330 }
331 }