github.com/turtlemonvh/terraform@v0.6.9-0.20151204001754-8e40b6b855e8/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_IntMath"] = builtinIntMath()
    28  	scope.FuncMap["__builtin_FloatMath"] = builtinFloatMath()
    29  	return scope
    30  }
    31  
    32  func builtinFloatMath() ast.Function {
    33  	return ast.Function{
    34  		ArgTypes:     []ast.Type{ast.TypeInt},
    35  		Variadic:     true,
    36  		VariadicType: ast.TypeFloat,
    37  		ReturnType:   ast.TypeFloat,
    38  		Callback: func(args []interface{}) (interface{}, error) {
    39  			op := args[0].(ast.ArithmeticOp)
    40  			result := args[1].(float64)
    41  			for _, raw := range args[2:] {
    42  				arg := raw.(float64)
    43  				switch op {
    44  				case ast.ArithmeticOpAdd:
    45  					result += arg
    46  				case ast.ArithmeticOpSub:
    47  					result -= arg
    48  				case ast.ArithmeticOpMul:
    49  					result *= arg
    50  				case ast.ArithmeticOpDiv:
    51  					result /= arg
    52  				}
    53  			}
    54  
    55  			return result, nil
    56  		},
    57  	}
    58  }
    59  
    60  func builtinIntMath() ast.Function {
    61  	return ast.Function{
    62  		ArgTypes:     []ast.Type{ast.TypeInt},
    63  		Variadic:     true,
    64  		VariadicType: ast.TypeInt,
    65  		ReturnType:   ast.TypeInt,
    66  		Callback: func(args []interface{}) (interface{}, error) {
    67  			op := args[0].(ast.ArithmeticOp)
    68  			result := args[1].(int)
    69  			for _, raw := range args[2:] {
    70  				arg := raw.(int)
    71  				switch op {
    72  				case ast.ArithmeticOpAdd:
    73  					result += arg
    74  				case ast.ArithmeticOpSub:
    75  					result -= arg
    76  				case ast.ArithmeticOpMul:
    77  					result *= arg
    78  				case ast.ArithmeticOpDiv:
    79  					result /= arg
    80  				case ast.ArithmeticOpMod:
    81  					result = result % arg
    82  				}
    83  			}
    84  
    85  			return result, nil
    86  		},
    87  	}
    88  }
    89  
    90  func builtinFloatToInt() ast.Function {
    91  	return ast.Function{
    92  		ArgTypes:   []ast.Type{ast.TypeFloat},
    93  		ReturnType: ast.TypeInt,
    94  		Callback: func(args []interface{}) (interface{}, error) {
    95  			return int(args[0].(float64)), nil
    96  		},
    97  	}
    98  }
    99  
   100  func builtinFloatToString() ast.Function {
   101  	return ast.Function{
   102  		ArgTypes:   []ast.Type{ast.TypeFloat},
   103  		ReturnType: ast.TypeString,
   104  		Callback: func(args []interface{}) (interface{}, error) {
   105  			return strconv.FormatFloat(
   106  				args[0].(float64), 'g', -1, 64), nil
   107  		},
   108  	}
   109  }
   110  
   111  func builtinIntToFloat() ast.Function {
   112  	return ast.Function{
   113  		ArgTypes:   []ast.Type{ast.TypeInt},
   114  		ReturnType: ast.TypeFloat,
   115  		Callback: func(args []interface{}) (interface{}, error) {
   116  			return float64(args[0].(int)), nil
   117  		},
   118  	}
   119  }
   120  
   121  func builtinIntToString() ast.Function {
   122  	return ast.Function{
   123  		ArgTypes:   []ast.Type{ast.TypeInt},
   124  		ReturnType: ast.TypeString,
   125  		Callback: func(args []interface{}) (interface{}, error) {
   126  			return strconv.FormatInt(int64(args[0].(int)), 10), nil
   127  		},
   128  	}
   129  }
   130  
   131  func builtinStringToInt() ast.Function {
   132  	return ast.Function{
   133  		ArgTypes:   []ast.Type{ast.TypeInt},
   134  		ReturnType: ast.TypeString,
   135  		Callback: func(args []interface{}) (interface{}, error) {
   136  			v, err := strconv.ParseInt(args[0].(string), 0, 0)
   137  			if err != nil {
   138  				return nil, err
   139  			}
   140  
   141  			return int(v), nil
   142  		},
   143  	}
   144  }