summaryrefslogtreecommitdiff
path: root/vendor/github.com/hashicorp/hil/builtins.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/hashicorp/hil/builtins.go')
-rw-r--r--vendor/github.com/hashicorp/hil/builtins.go331
1 files changed, 331 insertions, 0 deletions
diff --git a/vendor/github.com/hashicorp/hil/builtins.go b/vendor/github.com/hashicorp/hil/builtins.go
new file mode 100644
index 00000000..909c788a
--- /dev/null
+++ b/vendor/github.com/hashicorp/hil/builtins.go
@@ -0,0 +1,331 @@
+package hil
+
+import (
+ "errors"
+ "strconv"
+
+ "github.com/hashicorp/hil/ast"
+)
+
+// NOTE: All builtins are tested in engine_test.go
+
+func registerBuiltins(scope *ast.BasicScope) *ast.BasicScope {
+ if scope == nil {
+ scope = new(ast.BasicScope)
+ }
+ if scope.FuncMap == nil {
+ scope.FuncMap = make(map[string]ast.Function)
+ }
+
+ // Implicit conversions
+ scope.FuncMap["__builtin_BoolToString"] = builtinBoolToString()
+ scope.FuncMap["__builtin_FloatToInt"] = builtinFloatToInt()
+ scope.FuncMap["__builtin_FloatToString"] = builtinFloatToString()
+ scope.FuncMap["__builtin_IntToFloat"] = builtinIntToFloat()
+ scope.FuncMap["__builtin_IntToString"] = builtinIntToString()
+ scope.FuncMap["__builtin_StringToInt"] = builtinStringToInt()
+ scope.FuncMap["__builtin_StringToFloat"] = builtinStringToFloat()
+ scope.FuncMap["__builtin_StringToBool"] = builtinStringToBool()
+
+ // Math operations
+ scope.FuncMap["__builtin_IntMath"] = builtinIntMath()
+ scope.FuncMap["__builtin_FloatMath"] = builtinFloatMath()
+ scope.FuncMap["__builtin_BoolCompare"] = builtinBoolCompare()
+ scope.FuncMap["__builtin_FloatCompare"] = builtinFloatCompare()
+ scope.FuncMap["__builtin_IntCompare"] = builtinIntCompare()
+ scope.FuncMap["__builtin_StringCompare"] = builtinStringCompare()
+ scope.FuncMap["__builtin_Logical"] = builtinLogical()
+ return scope
+}
+
+func builtinFloatMath() ast.Function {
+ return ast.Function{
+ ArgTypes: []ast.Type{ast.TypeInt},
+ Variadic: true,
+ VariadicType: ast.TypeFloat,
+ ReturnType: ast.TypeFloat,
+ Callback: func(args []interface{}) (interface{}, error) {
+ op := args[0].(ast.ArithmeticOp)
+ result := args[1].(float64)
+ for _, raw := range args[2:] {
+ arg := raw.(float64)
+ switch op {
+ case ast.ArithmeticOpAdd:
+ result += arg
+ case ast.ArithmeticOpSub:
+ result -= arg
+ case ast.ArithmeticOpMul:
+ result *= arg
+ case ast.ArithmeticOpDiv:
+ result /= arg
+ }
+ }
+
+ return result, nil
+ },
+ }
+}
+
+func builtinIntMath() ast.Function {
+ return ast.Function{
+ ArgTypes: []ast.Type{ast.TypeInt},
+ Variadic: true,
+ VariadicType: ast.TypeInt,
+ ReturnType: ast.TypeInt,
+ Callback: func(args []interface{}) (interface{}, error) {
+ op := args[0].(ast.ArithmeticOp)
+ result := args[1].(int)
+ for _, raw := range args[2:] {
+ arg := raw.(int)
+ switch op {
+ case ast.ArithmeticOpAdd:
+ result += arg
+ case ast.ArithmeticOpSub:
+ result -= arg
+ case ast.ArithmeticOpMul:
+ result *= arg
+ case ast.ArithmeticOpDiv:
+ if arg == 0 {
+ return nil, errors.New("divide by zero")
+ }
+
+ result /= arg
+ case ast.ArithmeticOpMod:
+ if arg == 0 {
+ return nil, errors.New("divide by zero")
+ }
+
+ result = result % arg
+ }
+ }
+
+ return result, nil
+ },
+ }
+}
+
+func builtinBoolCompare() ast.Function {
+ return ast.Function{
+ ArgTypes: []ast.Type{ast.TypeInt, ast.TypeBool, ast.TypeBool},
+ Variadic: false,
+ ReturnType: ast.TypeBool,
+ Callback: func(args []interface{}) (interface{}, error) {
+ op := args[0].(ast.ArithmeticOp)
+ lhs := args[1].(bool)
+ rhs := args[2].(bool)
+
+ switch op {
+ case ast.ArithmeticOpEqual:
+ return lhs == rhs, nil
+ case ast.ArithmeticOpNotEqual:
+ return lhs != rhs, nil
+ default:
+ return nil, errors.New("invalid comparison operation")
+ }
+ },
+ }
+}
+
+func builtinFloatCompare() ast.Function {
+ return ast.Function{
+ ArgTypes: []ast.Type{ast.TypeInt, ast.TypeFloat, ast.TypeFloat},
+ Variadic: false,
+ ReturnType: ast.TypeBool,
+ Callback: func(args []interface{}) (interface{}, error) {
+ op := args[0].(ast.ArithmeticOp)
+ lhs := args[1].(float64)
+ rhs := args[2].(float64)
+
+ switch op {
+ case ast.ArithmeticOpEqual:
+ return lhs == rhs, nil
+ case ast.ArithmeticOpNotEqual:
+ return lhs != rhs, nil
+ case ast.ArithmeticOpLessThan:
+ return lhs < rhs, nil
+ case ast.ArithmeticOpLessThanOrEqual:
+ return lhs <= rhs, nil
+ case ast.ArithmeticOpGreaterThan:
+ return lhs > rhs, nil
+ case ast.ArithmeticOpGreaterThanOrEqual:
+ return lhs >= rhs, nil
+ default:
+ return nil, errors.New("invalid comparison operation")
+ }
+ },
+ }
+}
+
+func builtinIntCompare() ast.Function {
+ return ast.Function{
+ ArgTypes: []ast.Type{ast.TypeInt, ast.TypeInt, ast.TypeInt},
+ Variadic: false,
+ ReturnType: ast.TypeBool,
+ Callback: func(args []interface{}) (interface{}, error) {
+ op := args[0].(ast.ArithmeticOp)
+ lhs := args[1].(int)
+ rhs := args[2].(int)
+
+ switch op {
+ case ast.ArithmeticOpEqual:
+ return lhs == rhs, nil
+ case ast.ArithmeticOpNotEqual:
+ return lhs != rhs, nil
+ case ast.ArithmeticOpLessThan:
+ return lhs < rhs, nil
+ case ast.ArithmeticOpLessThanOrEqual:
+ return lhs <= rhs, nil
+ case ast.ArithmeticOpGreaterThan:
+ return lhs > rhs, nil
+ case ast.ArithmeticOpGreaterThanOrEqual:
+ return lhs >= rhs, nil
+ default:
+ return nil, errors.New("invalid comparison operation")
+ }
+ },
+ }
+}
+
+func builtinStringCompare() ast.Function {
+ return ast.Function{
+ ArgTypes: []ast.Type{ast.TypeInt, ast.TypeString, ast.TypeString},
+ Variadic: false,
+ ReturnType: ast.TypeBool,
+ Callback: func(args []interface{}) (interface{}, error) {
+ op := args[0].(ast.ArithmeticOp)
+ lhs := args[1].(string)
+ rhs := args[2].(string)
+
+ switch op {
+ case ast.ArithmeticOpEqual:
+ return lhs == rhs, nil
+ case ast.ArithmeticOpNotEqual:
+ return lhs != rhs, nil
+ default:
+ return nil, errors.New("invalid comparison operation")
+ }
+ },
+ }
+}
+
+func builtinLogical() ast.Function {
+ return ast.Function{
+ ArgTypes: []ast.Type{ast.TypeInt},
+ Variadic: true,
+ VariadicType: ast.TypeBool,
+ ReturnType: ast.TypeBool,
+ Callback: func(args []interface{}) (interface{}, error) {
+ op := args[0].(ast.ArithmeticOp)
+ result := args[1].(bool)
+ for _, raw := range args[2:] {
+ arg := raw.(bool)
+ switch op {
+ case ast.ArithmeticOpLogicalOr:
+ result = result || arg
+ case ast.ArithmeticOpLogicalAnd:
+ result = result && arg
+ default:
+ return nil, errors.New("invalid logical operator")
+ }
+ }
+
+ return result, nil
+ },
+ }
+}
+
+func builtinFloatToInt() ast.Function {
+ return ast.Function{
+ ArgTypes: []ast.Type{ast.TypeFloat},
+ ReturnType: ast.TypeInt,
+ Callback: func(args []interface{}) (interface{}, error) {
+ return int(args[0].(float64)), nil
+ },
+ }
+}
+
+func builtinFloatToString() ast.Function {
+ return ast.Function{
+ ArgTypes: []ast.Type{ast.TypeFloat},
+ ReturnType: ast.TypeString,
+ Callback: func(args []interface{}) (interface{}, error) {
+ return strconv.FormatFloat(
+ args[0].(float64), 'g', -1, 64), nil
+ },
+ }
+}
+
+func builtinIntToFloat() ast.Function {
+ return ast.Function{
+ ArgTypes: []ast.Type{ast.TypeInt},
+ ReturnType: ast.TypeFloat,
+ Callback: func(args []interface{}) (interface{}, error) {
+ return float64(args[0].(int)), nil
+ },
+ }
+}
+
+func builtinIntToString() ast.Function {
+ return ast.Function{
+ ArgTypes: []ast.Type{ast.TypeInt},
+ ReturnType: ast.TypeString,
+ Callback: func(args []interface{}) (interface{}, error) {
+ return strconv.FormatInt(int64(args[0].(int)), 10), nil
+ },
+ }
+}
+
+func builtinStringToInt() ast.Function {
+ return ast.Function{
+ ArgTypes: []ast.Type{ast.TypeInt},
+ ReturnType: ast.TypeString,
+ Callback: func(args []interface{}) (interface{}, error) {
+ v, err := strconv.ParseInt(args[0].(string), 0, 0)
+ if err != nil {
+ return nil, err
+ }
+
+ return int(v), nil
+ },
+ }
+}
+
+func builtinStringToFloat() ast.Function {
+ return ast.Function{
+ ArgTypes: []ast.Type{ast.TypeString},
+ ReturnType: ast.TypeFloat,
+ Callback: func(args []interface{}) (interface{}, error) {
+ v, err := strconv.ParseFloat(args[0].(string), 64)
+ if err != nil {
+ return nil, err
+ }
+
+ return v, nil
+ },
+ }
+}
+
+func builtinBoolToString() ast.Function {
+ return ast.Function{
+ ArgTypes: []ast.Type{ast.TypeBool},
+ ReturnType: ast.TypeString,
+ Callback: func(args []interface{}) (interface{}, error) {
+ return strconv.FormatBool(args[0].(bool)), nil
+ },
+ }
+}
+
+func builtinStringToBool() ast.Function {
+ return ast.Function{
+ ArgTypes: []ast.Type{ast.TypeString},
+ ReturnType: ast.TypeBool,
+ Callback: func(args []interface{}) (interface{}, error) {
+ v, err := strconv.ParseBool(args[0].(string))
+ if err != nil {
+ return nil, err
+ }
+
+ return v, nil
+ },
+ }
+}