github.com/leeprovoost/terraform@v0.6.10-0.20160119085442-96f3f76118e7/config/lang/builtins.go (about) 1 package lang 2 3 import ( 4 "strconv" 5 6 "github.com/hashicorp/terraform/config/lang/ast" 7 ) 8 9 // NOTE: All builtins are tested in engine_test.go 10 11 func registerBuiltins(scope *ast.BasicScope) *ast.BasicScope { 12 if scope == nil { 13 scope = new(ast.BasicScope) 14 } 15 if scope.FuncMap == nil { 16 scope.FuncMap = make(map[string]ast.Function) 17 } 18 19 // Implicit conversions 20 scope.FuncMap["__builtin_FloatToInt"] = builtinFloatToInt() 21 scope.FuncMap["__builtin_FloatToString"] = builtinFloatToString() 22 scope.FuncMap["__builtin_IntToFloat"] = builtinIntToFloat() 23 scope.FuncMap["__builtin_IntToString"] = builtinIntToString() 24 scope.FuncMap["__builtin_StringToInt"] = builtinStringToInt() 25 26 // Math operations 27 scope.FuncMap["__builtin_UnaryIntMath"] = builtinUnaryIntMath() 28 scope.FuncMap["__builtin_UnaryFloatMath"] = builtinUnaryFloatMath() 29 scope.FuncMap["__builtin_IntMath"] = builtinIntMath() 30 scope.FuncMap["__builtin_FloatMath"] = builtinFloatMath() 31 return scope 32 } 33 34 func builtinUnaryIntMath() ast.Function { 35 return ast.Function{ 36 ArgTypes: []ast.Type{ast.TypeInt}, 37 Variadic: false, 38 ReturnType: ast.TypeInt, 39 Callback: func(args []interface{}) (interface{}, error) { 40 op := args[0].(ast.ArithmeticOp) 41 result := args[1].(int) 42 switch op { 43 case ast.ArithmeticOpAdd: 44 result = result 45 case ast.ArithmeticOpSub: 46 result = -result 47 } 48 49 return result, nil 50 }, 51 } 52 } 53 54 func builtinUnaryFloatMath() ast.Function { 55 return ast.Function{ 56 ArgTypes: []ast.Type{ast.TypeFloat}, 57 Variadic: false, 58 ReturnType: ast.TypeFloat, 59 Callback: func(args []interface{}) (interface{}, error) { 60 op := args[0].(ast.ArithmeticOp) 61 result := args[1].(float64) 62 switch op { 63 case ast.ArithmeticOpAdd: 64 result = result 65 case ast.ArithmeticOpSub: 66 result = -result 67 } 68 69 return result, nil 70 }, 71 } 72 } 73 74 func builtinFloatMath() ast.Function { 75 return ast.Function{ 76 ArgTypes: []ast.Type{ast.TypeInt}, 77 Variadic: true, 78 VariadicType: ast.TypeFloat, 79 ReturnType: ast.TypeFloat, 80 Callback: func(args []interface{}) (interface{}, error) { 81 op := args[0].(ast.ArithmeticOp) 82 result := args[1].(float64) 83 for _, raw := range args[2:] { 84 arg := raw.(float64) 85 switch op { 86 case ast.ArithmeticOpAdd: 87 result += arg 88 case ast.ArithmeticOpSub: 89 result -= arg 90 case ast.ArithmeticOpMul: 91 result *= arg 92 case ast.ArithmeticOpDiv: 93 result /= arg 94 } 95 } 96 97 return result, nil 98 }, 99 } 100 } 101 102 func builtinIntMath() ast.Function { 103 return ast.Function{ 104 ArgTypes: []ast.Type{ast.TypeInt}, 105 Variadic: true, 106 VariadicType: ast.TypeInt, 107 ReturnType: ast.TypeInt, 108 Callback: func(args []interface{}) (interface{}, error) { 109 op := args[0].(ast.ArithmeticOp) 110 result := args[1].(int) 111 for _, raw := range args[2:] { 112 arg := raw.(int) 113 switch op { 114 case ast.ArithmeticOpAdd: 115 result += arg 116 case ast.ArithmeticOpSub: 117 result -= arg 118 case ast.ArithmeticOpMul: 119 result *= arg 120 case ast.ArithmeticOpDiv: 121 result /= arg 122 case ast.ArithmeticOpMod: 123 result = result % arg 124 } 125 } 126 127 return result, nil 128 }, 129 } 130 } 131 132 func builtinFloatToInt() ast.Function { 133 return ast.Function{ 134 ArgTypes: []ast.Type{ast.TypeFloat}, 135 ReturnType: ast.TypeInt, 136 Callback: func(args []interface{}) (interface{}, error) { 137 return int(args[0].(float64)), nil 138 }, 139 } 140 } 141 142 func builtinFloatToString() ast.Function { 143 return ast.Function{ 144 ArgTypes: []ast.Type{ast.TypeFloat}, 145 ReturnType: ast.TypeString, 146 Callback: func(args []interface{}) (interface{}, error) { 147 return strconv.FormatFloat( 148 args[0].(float64), 'g', -1, 64), nil 149 }, 150 } 151 } 152 153 func builtinIntToFloat() ast.Function { 154 return ast.Function{ 155 ArgTypes: []ast.Type{ast.TypeInt}, 156 ReturnType: ast.TypeFloat, 157 Callback: func(args []interface{}) (interface{}, error) { 158 return float64(args[0].(int)), nil 159 }, 160 } 161 } 162 163 func builtinIntToString() ast.Function { 164 return ast.Function{ 165 ArgTypes: []ast.Type{ast.TypeInt}, 166 ReturnType: ast.TypeString, 167 Callback: func(args []interface{}) (interface{}, error) { 168 return strconv.FormatInt(int64(args[0].(int)), 10), nil 169 }, 170 } 171 } 172 173 func builtinStringToInt() ast.Function { 174 return ast.Function{ 175 ArgTypes: []ast.Type{ast.TypeInt}, 176 ReturnType: ast.TypeString, 177 Callback: func(args []interface{}) (interface{}, error) { 178 v, err := strconv.ParseInt(args[0].(string), 0, 0) 179 if err != nil { 180 return nil, err 181 } 182 183 return int(v), nil 184 }, 185 } 186 }