github.com/mattn/anko@v0.1.10/vm/vmFunctions_test.go (about)

     1  package vm
     2  
     3  import (
     4  	"bytes"
     5  	"fmt"
     6  	"reflect"
     7  	"sync"
     8  	"testing"
     9  	"time"
    10  
    11  	"github.com/mattn/anko/env"
    12  )
    13  
    14  func TestReturns(t *testing.T) {
    15  	t.Parallel()
    16  
    17  	tests := []Test{
    18  		{Script: `return 1++`, RunError: fmt.Errorf("invalid operation")},
    19  		{Script: `return 1, 1++`, RunError: fmt.Errorf("invalid operation")},
    20  		{Script: `return 1, 2, 1++`, RunError: fmt.Errorf("invalid operation")},
    21  
    22  		{Script: `return`, RunOutput: nil},
    23  		{Script: `return nil`, RunOutput: nil},
    24  		{Script: `return true`, RunOutput: true},
    25  		{Script: `return 1`, RunOutput: int64(1)},
    26  		{Script: `return 1.1`, RunOutput: float64(1.1)},
    27  		{Script: `return "a"`, RunOutput: "a"},
    28  
    29  		{Script: `b()`, Input: map[string]interface{}{"b": func() {}}, RunOutput: nil},
    30  		{Script: `b()`, Input: map[string]interface{}{"b": func() reflect.Value { return reflect.Value{} }}, RunOutput: reflect.Value{}},
    31  		{Script: `b()`, Input: map[string]interface{}{"b": func() interface{} { return nil }}, RunOutput: nil},
    32  		{Script: `b()`, Input: map[string]interface{}{"b": func() bool { return true }}, RunOutput: true},
    33  		{Script: `b()`, Input: map[string]interface{}{"b": func() int32 { return int32(1) }}, RunOutput: int32(1)},
    34  		{Script: `b()`, Input: map[string]interface{}{"b": func() int64 { return int64(1) }}, RunOutput: int64(1)},
    35  		{Script: `b()`, Input: map[string]interface{}{"b": func() float32 { return float32(1.1) }}, RunOutput: float32(1.1)},
    36  		{Script: `b()`, Input: map[string]interface{}{"b": func() float64 { return float64(1.1) }}, RunOutput: float64(1.1)},
    37  		{Script: `b()`, Input: map[string]interface{}{"b": func() string { return "a" }}, RunOutput: "a"},
    38  
    39  		{Script: `b(a)`, Input: map[string]interface{}{"a": reflect.Value{}, "b": func(c reflect.Value) reflect.Value { return c }}, RunOutput: reflect.Value{}, Output: map[string]interface{}{"a": reflect.Value{}}},
    40  		{Script: `b(a)`, Input: map[string]interface{}{"a": nil, "b": func(c interface{}) interface{} { return c }}, RunOutput: nil, Output: map[string]interface{}{"a": nil}},
    41  		{Script: `b(a)`, Input: map[string]interface{}{"a": true, "b": func(c bool) bool { return c }}, RunOutput: true, Output: map[string]interface{}{"a": true}},
    42  		{Script: `b(a)`, Input: map[string]interface{}{"a": int32(1), "b": func(c int32) int32 { return c }}, RunOutput: int32(1), Output: map[string]interface{}{"a": int32(1)}},
    43  		{Script: `b(a)`, Input: map[string]interface{}{"a": int64(1), "b": func(c int64) int64 { return c }}, RunOutput: int64(1), Output: map[string]interface{}{"a": int64(1)}},
    44  		{Script: `b(a)`, Input: map[string]interface{}{"a": float32(1.1), "b": func(c float32) float32 { return c }}, RunOutput: float32(1.1), Output: map[string]interface{}{"a": float32(1.1)}},
    45  		{Script: `b(a)`, Input: map[string]interface{}{"a": float64(1.1), "b": func(c float64) float64 { return c }}, RunOutput: float64(1.1), Output: map[string]interface{}{"a": float64(1.1)}},
    46  		{Script: `b(a)`, Input: map[string]interface{}{"a": "a", "b": func(c string) string { return c }}, RunOutput: "a", Output: map[string]interface{}{"a": "a"}},
    47  
    48  		{Script: `b(a)`, Input: map[string]interface{}{"a": "a", "b": func(c bool) bool { return c }}, RunError: fmt.Errorf("function wants argument type bool but received type string"), Output: map[string]interface{}{"a": "a"}},
    49  		{Script: `b(a)`, Input: map[string]interface{}{"a": int64(1), "b": func(c int32) int32 { return c }}, RunOutput: int32(1), Output: map[string]interface{}{"a": int64(1)}},
    50  		{Script: `b(a)`, Input: map[string]interface{}{"a": int32(1), "b": func(c int64) int64 { return c }}, RunOutput: int64(1), Output: map[string]interface{}{"a": int32(1)}},
    51  		{Script: `b(a)`, Input: map[string]interface{}{"a": float64(1.25), "b": func(c float32) float32 { return c }}, RunOutput: float32(1.25), Output: map[string]interface{}{"a": float64(1.25)}},
    52  		{Script: `b(a)`, Input: map[string]interface{}{"a": float32(1.25), "b": func(c float64) float64 { return c }}, RunOutput: float64(1.25), Output: map[string]interface{}{"a": float32(1.25)}},
    53  		{Script: `b(a)`, Input: map[string]interface{}{"a": true, "b": func(c string) string { return c }}, RunError: fmt.Errorf("function wants argument type string but received type bool"), Output: map[string]interface{}{"a": true}},
    54  
    55  		{Script: `b(a)`, Input: map[string]interface{}{"a": testVarValueBool, "b": func(c interface{}) interface{} { return c }}, RunOutput: testVarValueBool, Output: map[string]interface{}{"a": testVarValueBool}},
    56  		{Script: `b(a)`, Input: map[string]interface{}{"a": testVarValueInt32, "b": func(c interface{}) interface{} { return c }}, RunOutput: testVarValueInt32, Output: map[string]interface{}{"a": testVarValueInt32}},
    57  		{Script: `b(a)`, Input: map[string]interface{}{"a": testVarValueInt64, "b": func(c interface{}) interface{} { return c }}, RunOutput: testVarValueInt64, Output: map[string]interface{}{"a": testVarValueInt64}},
    58  		{Script: `b(a)`, Input: map[string]interface{}{"a": testVarValueFloat32, "b": func(c interface{}) interface{} { return c }}, RunOutput: testVarValueFloat32, Output: map[string]interface{}{"a": testVarValueFloat32}},
    59  		{Script: `b(a)`, Input: map[string]interface{}{"a": testVarValueFloat64, "b": func(c interface{}) interface{} { return c }}, RunOutput: testVarValueFloat64, Output: map[string]interface{}{"a": testVarValueFloat64}},
    60  		{Script: `b(a)`, Input: map[string]interface{}{"a": testVarValueString, "b": func(c interface{}) interface{} { return c }}, RunOutput: testVarValueString, Output: map[string]interface{}{"a": testVarValueString}},
    61  
    62  		{Script: `func aFunc() {}; aFunc()`, RunOutput: nil},
    63  		{Script: `func aFunc() { return }; aFunc()`, RunOutput: nil},
    64  		{Script: `func aFunc() { return }; a = aFunc()`, RunOutput: nil, Output: map[string]interface{}{"a": nil}},
    65  		{Script: `func aFunc() { return 1 }; aFunc()`, RunOutput: int64(1)},
    66  		{Script: `func aFunc() { return 1 }; a = aFunc()`, RunOutput: int64(1), Output: map[string]interface{}{"a": int64(1)}},
    67  
    68  		{Script: `func aFunc() {return nil}; aFunc()`, RunOutput: nil},
    69  		{Script: `func aFunc() {return true}; aFunc()`, RunOutput: true},
    70  		{Script: `func aFunc() {return 1}; aFunc()`, RunOutput: int64(1)},
    71  		{Script: `func aFunc() {return 1.1}; aFunc()`, RunOutput: float64(1.1)},
    72  		{Script: `func aFunc() {return "a"}; aFunc()`, RunOutput: "a"},
    73  
    74  		{Script: `func aFunc() {return 1 + 2}; aFunc()`, RunOutput: int64(3)},
    75  		{Script: `func aFunc() {return 1.25 + 2.25}; aFunc()`, RunOutput: float64(3.5)},
    76  		{Script: `func aFunc() {return "a" + "b"}; aFunc()`, RunOutput: "ab"},
    77  
    78  		{Script: `func aFunc() {return 1 + 2, 3 + 4}; aFunc()`, RunOutput: []interface{}{int64(3), int64(7)}},
    79  		{Script: `func aFunc() {return 1.25 + 2.25, 3.25 + 4.25}; aFunc()`, RunOutput: []interface{}{float64(3.5), float64(7.5)}},
    80  		{Script: `func aFunc() {return "a" + "b", "c" + "d"}; aFunc()`, RunOutput: []interface{}{"ab", "cd"}},
    81  
    82  		{Script: `func aFunc() {return nil, nil}; aFunc()`, RunOutput: []interface{}{nil, nil}},
    83  		{Script: `func aFunc() {return true, false}; aFunc()`, RunOutput: []interface{}{true, false}},
    84  		{Script: `func aFunc() {return 1, 2}; aFunc()`, RunOutput: []interface{}{int64(1), int64(2)}},
    85  		{Script: `func aFunc() {return 1.1, 2.2}; aFunc()`, RunOutput: []interface{}{float64(1.1), float64(2.2)}},
    86  		{Script: `func aFunc() {return "a", "b"}; aFunc()`, RunOutput: []interface{}{"a", "b"}},
    87  
    88  		{Script: `func aFunc() {return [nil]}; aFunc()`, RunOutput: []interface{}{nil}},
    89  		{Script: `func aFunc() {return [nil, nil]}; aFunc()`, RunOutput: []interface{}{nil, nil}},
    90  		{Script: `func aFunc() {return [nil, nil, nil]}; aFunc()`, RunOutput: []interface{}{nil, nil, nil}},
    91  		{Script: `func aFunc() {return [nil, nil], [nil, nil]}; aFunc()`, RunOutput: []interface{}{[]interface{}{nil, nil}, []interface{}{nil, nil}}},
    92  
    93  		{Script: `func aFunc() {return [true]}; aFunc()`, RunOutput: []interface{}{true}},
    94  		{Script: `func aFunc() {return [true, false]}; aFunc()`, RunOutput: []interface{}{true, false}},
    95  		{Script: `func aFunc() {return [true, false, true]}; aFunc()`, RunOutput: []interface{}{true, false, true}},
    96  		{Script: `func aFunc() {return [true, false], [false, true]}; aFunc()`, RunOutput: []interface{}{[]interface{}{true, false}, []interface{}{false, true}}},
    97  
    98  		{Script: `func aFunc() {return []}; aFunc()`, RunOutput: []interface{}{}},
    99  		{Script: `func aFunc() {return [1]}; aFunc()`, RunOutput: []interface{}{int64(1)}},
   100  		{Script: `func aFunc() {return [1, 2]}; aFunc()`, RunOutput: []interface{}{int64(1), int64(2)}},
   101  		{Script: `func aFunc() {return [1, 2, 3]}; aFunc()`, RunOutput: []interface{}{int64(1), int64(2), int64(3)}},
   102  		{Script: `func aFunc() {return [1, 2], [3, 4]}; aFunc()`, RunOutput: []interface{}{[]interface{}{int64(1), int64(2)}, []interface{}{int64(3), int64(4)}}},
   103  
   104  		{Script: `func aFunc() {return [1.1]}; aFunc()`, RunOutput: []interface{}{float64(1.1)}},
   105  		{Script: `func aFunc() {return [1.1, 2.2]}; aFunc()`, RunOutput: []interface{}{float64(1.1), float64(2.2)}},
   106  		{Script: `func aFunc() {return [1.1, 2.2, 3.3]}; aFunc()`, RunOutput: []interface{}{float64(1.1), float64(2.2), float64(3.3)}},
   107  		{Script: `func aFunc() {return [1.1, 2.2], [3.3, 4.4]}; aFunc()`, RunOutput: []interface{}{[]interface{}{float64(1.1), float64(2.2)}, []interface{}{float64(3.3), float64(4.4)}}},
   108  
   109  		{Script: `func aFunc() {return ["a"]}; aFunc()`, RunOutput: []interface{}{"a"}},
   110  		{Script: `func aFunc() {return ["a", "b"]}; aFunc()`, RunOutput: []interface{}{"a", "b"}},
   111  		{Script: `func aFunc() {return ["a", "b", "c"]}; aFunc()`, RunOutput: []interface{}{"a", "b", "c"}},
   112  		{Script: `func aFunc() {return ["a", "b"], ["c", "d"]}; aFunc()`, RunOutput: []interface{}{[]interface{}{"a", "b"}, []interface{}{"c", "d"}}},
   113  
   114  		{Script: `func aFunc() {return nil, nil}; aFunc()`, RunOutput: []interface{}{interface{}(nil), interface{}(nil)}},
   115  		{Script: `func aFunc() {return true, false}; aFunc()`, RunOutput: []interface{}{true, false}},
   116  		{Script: `func aFunc() {return 1, 2}; aFunc()`, RunOutput: []interface{}{int64(1), int64(2)}},
   117  		{Script: `func aFunc() {return 1.1, 2.2}; aFunc()`, RunOutput: []interface{}{float64(1.1), float64(2.2)}},
   118  		{Script: `func aFunc() {return "a", "b"}; aFunc()`, RunOutput: []interface{}{"a", "b"}},
   119  
   120  		{Script: `func aFunc() {return a}; aFunc()`, Input: map[string]interface{}{"a": reflect.Value{}}, RunOutput: reflect.Value{}, Output: map[string]interface{}{"a": reflect.Value{}}},
   121  
   122  		{Script: `func aFunc() {return a}; aFunc()`, Input: map[string]interface{}{"a": nil}, RunOutput: nil, Output: map[string]interface{}{"a": nil}},
   123  		{Script: `func aFunc() {return a}; aFunc()`, Input: map[string]interface{}{"a": true}, RunOutput: true, Output: map[string]interface{}{"a": true}},
   124  		{Script: `func aFunc() {return a}; aFunc()`, Input: map[string]interface{}{"a": int64(1)}, RunOutput: int64(1), Output: map[string]interface{}{"a": int64(1)}},
   125  		{Script: `func aFunc() {return a}; aFunc()`, Input: map[string]interface{}{"a": float64(1.1)}, RunOutput: float64(1.1), Output: map[string]interface{}{"a": float64(1.1)}},
   126  		{Script: `func aFunc() {return a}; aFunc()`, Input: map[string]interface{}{"a": "a"}, RunOutput: "a", Output: map[string]interface{}{"a": "a"}},
   127  
   128  		{Script: `func aFunc() {return a, a}; aFunc()`, Input: map[string]interface{}{"a": reflect.Value{}}, RunOutput: []interface{}{reflect.Value{}, reflect.Value{}}, Output: map[string]interface{}{"a": reflect.Value{}}},
   129  		{Script: `func aFunc() {return a, a}; aFunc()`, Input: map[string]interface{}{"a": nil}, RunOutput: []interface{}{nil, nil}, Output: map[string]interface{}{"a": nil}},
   130  		{Script: `func aFunc() {return a, a}; aFunc()`, Input: map[string]interface{}{"a": true}, RunOutput: []interface{}{true, true}, Output: map[string]interface{}{"a": true}},
   131  		{Script: `func aFunc() {return a, a}; aFunc()`, Input: map[string]interface{}{"a": int32(1)}, RunOutput: []interface{}{int32(1), int32(1)}, Output: map[string]interface{}{"a": int32(1)}},
   132  		{Script: `func aFunc() {return a, a}; aFunc()`, Input: map[string]interface{}{"a": int64(1)}, RunOutput: []interface{}{int64(1), int64(1)}, Output: map[string]interface{}{"a": int64(1)}},
   133  		{Script: `func aFunc() {return a, a}; aFunc()`, Input: map[string]interface{}{"a": float32(1.1)}, RunOutput: []interface{}{float32(1.1), float32(1.1)}, Output: map[string]interface{}{"a": float32(1.1)}},
   134  		{Script: `func aFunc() {return a, a}; aFunc()`, Input: map[string]interface{}{"a": float64(1.1)}, RunOutput: []interface{}{float64(1.1), float64(1.1)}, Output: map[string]interface{}{"a": float64(1.1)}},
   135  		{Script: `func aFunc() {return a, a}; aFunc()`, Input: map[string]interface{}{"a": "a"}, RunOutput: []interface{}{"a", "a"}, Output: map[string]interface{}{"a": "a"}},
   136  
   137  		{Script: `func a(x) { return x}; a(nil)`, RunOutput: nil},
   138  		{Script: `func a(x) { return x}; a(true)`, RunOutput: true},
   139  		{Script: `func a(x) { return x}; a(1)`, RunOutput: int64(1)},
   140  		{Script: `func a(x) { return x}; a(1.1)`, RunOutput: float64(1.1)},
   141  		{Script: `func a(x) { return x}; a("a")`, RunOutput: "a"},
   142  
   143  		{Script: `func aFunc() {return a}; for {aFunc(); break}`, Input: map[string]interface{}{"a": nil}, RunOutput: nil, Output: map[string]interface{}{"a": nil}},
   144  		{Script: `func aFunc() {return a}; for {aFunc(); break}`, Input: map[string]interface{}{"a": true}, RunOutput: nil, Output: map[string]interface{}{"a": true}},
   145  		{Script: `func aFunc() {return a}; for {aFunc(); break}`, Input: map[string]interface{}{"a": int64(1)}, RunOutput: nil, Output: map[string]interface{}{"a": int64(1)}},
   146  		{Script: `func aFunc() {return a}; for {aFunc(); break}`, Input: map[string]interface{}{"a": float64(1.1)}, RunOutput: nil, Output: map[string]interface{}{"a": float64(1.1)}},
   147  		{Script: `func aFunc() {return a}; for {aFunc(); break}`, Input: map[string]interface{}{"a": "a"}, RunOutput: nil, Output: map[string]interface{}{"a": "a"}},
   148  
   149  		{Script: `func aFunc() {for {return a}}; aFunc()`, Input: map[string]interface{}{"a": nil}, RunOutput: nil, Output: map[string]interface{}{"a": nil}},
   150  		{Script: `func aFunc() {for {return a}}; aFunc()`, Input: map[string]interface{}{"a": true}, RunOutput: true, Output: map[string]interface{}{"a": true}},
   151  		{Script: `func aFunc() {for {return a}}; aFunc()`, Input: map[string]interface{}{"a": int64(1)}, RunOutput: int64(1), Output: map[string]interface{}{"a": int64(1)}},
   152  		{Script: `func aFunc() {for {return a}}; aFunc()`, Input: map[string]interface{}{"a": float64(1.1)}, RunOutput: float64(1.1), Output: map[string]interface{}{"a": float64(1.1)}},
   153  		{Script: `func aFunc() {for {return a}}; aFunc()`, Input: map[string]interface{}{"a": "a"}, RunOutput: "a", Output: map[string]interface{}{"a": "a"}},
   154  
   155  		{Script: `func aFunc() {for {if true {return a}}}; aFunc()`, Input: map[string]interface{}{"a": nil}, RunOutput: nil, Output: map[string]interface{}{"a": nil}},
   156  		{Script: `func aFunc() {for {if true {return a}}}; aFunc()`, Input: map[string]interface{}{"a": true}, RunOutput: true, Output: map[string]interface{}{"a": true}},
   157  		{Script: `func aFunc() {for {if true {return a}}}; aFunc()`, Input: map[string]interface{}{"a": int64(1)}, RunOutput: int64(1), Output: map[string]interface{}{"a": int64(1)}},
   158  		{Script: `func aFunc() {for {if true {return a}}}; aFunc()`, Input: map[string]interface{}{"a": float64(1.1)}, RunOutput: float64(1.1), Output: map[string]interface{}{"a": float64(1.1)}},
   159  		{Script: `func aFunc() {for {if true {return a}}}; aFunc()`, Input: map[string]interface{}{"a": "a"}, RunOutput: "a", Output: map[string]interface{}{"a": "a"}},
   160  
   161  		{Script: `func aFunc() {return nil, nil}; a, b = aFunc()`, RunOutput: nil, Output: map[string]interface{}{"a": nil, "b": nil}},
   162  		{Script: `func aFunc() {return true, false}; a, b = aFunc()`, RunOutput: false, Output: map[string]interface{}{"a": true, "b": false}},
   163  		{Script: `func aFunc() {return 1, 2}; a, b = aFunc()`, RunOutput: int64(2), Output: map[string]interface{}{"a": int64(1), "b": int64(2)}},
   164  		{Script: `func aFunc() {return 1.1, 2.2}; a, b = aFunc()`, RunOutput: float64(2.2), Output: map[string]interface{}{"a": float64(1.1), "b": float64(2.2)}},
   165  		{Script: `func aFunc() {return "a", "b"}; a, b = aFunc()`, RunOutput: "b", Output: map[string]interface{}{"a": "a", "b": "b"}},
   166  	}
   167  	runTests(t, tests, nil, &Options{Debug: true})
   168  }
   169  
   170  func TestFunctions(t *testing.T) {
   171  	t.Parallel()
   172  
   173  	tests := []Test{
   174  		{Script: `a()`, Input: map[string]interface{}{"a": reflect.Value{}}, RunError: fmt.Errorf("cannot call type struct")},
   175  		{Script: `a = nil; a()`, RunError: fmt.Errorf("cannot call type interface"), Output: map[string]interface{}{"a": nil}},
   176  		{Script: `a = true; a()`, RunError: fmt.Errorf("cannot call type bool"), Output: map[string]interface{}{"a": true}},
   177  		{Script: `a = nil; b = func c(d) { return d == nil }; c = nil; c(a)`, RunError: fmt.Errorf("cannot call type interface"), Output: map[string]interface{}{"a": nil}},
   178  		{Script: `a = [true]; a()`, RunError: fmt.Errorf("cannot call type slice")},
   179  		{Script: `a = [true]; func b(c) { return c() }; b(a)`, RunError: fmt.Errorf("cannot call type slice")},
   180  		{Script: `a = {}; a.missing()`, RunError: fmt.Errorf("cannot call type interface"), Output: map[string]interface{}{"a": map[interface{}]interface{}{}}},
   181  		{Script: `a = 1; b = func(,a){}; a`, ParseError: fmt.Errorf("syntax error: unexpected ','"), RunOutput: int64(1)},
   182  
   183  		{Script: `func a(b) { }; a()`, RunError: fmt.Errorf("function wants 1 arguments but received 0")},
   184  		{Script: `func a(b) { }; a(true, true)`, RunError: fmt.Errorf("function wants 1 arguments but received 2")},
   185  		{Script: `func a(b, c) { }; a()`, RunError: fmt.Errorf("function wants 2 arguments but received 0")},
   186  		{Script: `func a(b, c) { }; a(true)`, RunError: fmt.Errorf("function wants 2 arguments but received 1")},
   187  		{Script: `func a(b, c) { }; a(true, true, true)`, RunError: fmt.Errorf("function wants 2 arguments but received 3")},
   188  
   189  		{Script: `func a() { return "a" }; a.b()`, RunError: fmt.Errorf("type func does not support member operation")},
   190  		{Script: `a = [func () { return nil}]; func b(c) { return c() }; b(a[1])`, RunError: fmt.Errorf("index out of range")},
   191  		{Script: `func a() { return "a" }; b()`, RunError: fmt.Errorf("undefined symbol 'b'")},
   192  		{Script: ` func a() { return "a" }; 1++()`, RunError: fmt.Errorf("invalid operation")},
   193  		{Script: ` func a(b) { return b }; a(1++)`, RunError: fmt.Errorf("invalid operation")},
   194  
   195  		{Script: `a`, Input: map[string]interface{}{"a": testVarFunc}, RunOutput: testVarFunc, Output: map[string]interface{}{"a": testVarFunc}},
   196  		{Script: `a()`, Input: map[string]interface{}{"a": testVarFunc}, RunOutput: int64(1), Output: map[string]interface{}{"a": testVarFunc}},
   197  		{Script: `a`, Input: map[string]interface{}{"a": testVarFuncP}, RunOutput: testVarFuncP, Output: map[string]interface{}{"a": testVarFuncP}},
   198  		// TOFIX:
   199  		// {Script: `a()`, Input: map[string]interface{}{"a": testVarFuncP}, RunOutput: int64(1), Output: map[string]interface{}{"a": testVarFuncP}},
   200  
   201  		{Script: `module a { func b() { return } }; a.b()`, RunOutput: nil},
   202  		{Script: `module a { func b() { return nil} }; a.b()`, RunOutput: nil},
   203  		{Script: `module a { func b() { return true} }; a.b()`, RunOutput: true},
   204  		{Script: `module a { func b() { return 1} }; a.b()`, RunOutput: int64(1)},
   205  		{Script: `module a { func b() { return 1.1} }; a.b()`, RunOutput: float64(1.1)},
   206  		{Script: `module a { func b() { return "a"} }; a.b()`, RunOutput: "a"},
   207  
   208  		{Script: `if true { module a { func b() { return } } }; a.b()`, RunError: fmt.Errorf("undefined symbol 'a'")},
   209  
   210  		{Script: `a = 1; func b() { a = 2 }; b()`, RunOutput: int64(2), Output: map[string]interface{}{"a": int64(2)}},
   211  		{Script: `b(a); a`, Input: map[string]interface{}{"a": int64(1), "b": func(c interface{}) { c = int64(2); _ = c }}, RunOutput: int64(1), Output: map[string]interface{}{"a": int64(1)}},
   212  		{Script: `func b() { }; go b()`, RunOutput: nil},
   213  
   214  		{Script: `b(a)`, Input: map[string]interface{}{"a": nil, "b": func(c interface{}) bool { return c == nil }}, RunOutput: true, Output: map[string]interface{}{"a": nil}},
   215  		{Script: `b(a)`, Input: map[string]interface{}{"a": true, "b": func(c bool) bool { return c == true }}, RunOutput: true, Output: map[string]interface{}{"a": true}},
   216  		{Script: `b(a)`, Input: map[string]interface{}{"a": int32(1), "b": func(c int32) bool { return c == 1 }}, RunOutput: true, Output: map[string]interface{}{"a": int32(1)}},
   217  		{Script: `b(a)`, Input: map[string]interface{}{"a": int64(1), "b": func(c int64) bool { return c == 1 }}, RunOutput: true, Output: map[string]interface{}{"a": int64(1)}},
   218  		{Script: `b(a)`, Input: map[string]interface{}{"a": float32(1.1), "b": func(c float32) bool { return c == 1.1 }}, RunOutput: true, Output: map[string]interface{}{"a": float32(1.1)}},
   219  		{Script: `b(a)`, Input: map[string]interface{}{"a": float64(1.1), "b": func(c float64) bool { return c == 1.1 }}, RunOutput: true, Output: map[string]interface{}{"a": float64(1.1)}},
   220  		{Script: `b(a)`, Input: map[string]interface{}{"a": "a", "b": func(c string) bool { return c == "a" }}, RunOutput: true, Output: map[string]interface{}{"a": "a"}},
   221  
   222  		{Script: `b(a)`, Input: map[string]interface{}{"a": testVarValueBool, "b": func(c reflect.Value) bool { return c == testVarValueBool }}, RunOutput: true, Output: map[string]interface{}{"a": testVarValueBool}},
   223  		{Script: `b(a)`, Input: map[string]interface{}{"a": testVarValueInt32, "b": func(c reflect.Value) bool { return c == testVarValueInt32 }}, RunOutput: true, Output: map[string]interface{}{"a": testVarValueInt32}},
   224  		{Script: `b(a)`, Input: map[string]interface{}{"a": testVarValueInt64, "b": func(c reflect.Value) bool { return c == testVarValueInt64 }}, RunOutput: true, Output: map[string]interface{}{"a": testVarValueInt64}},
   225  		{Script: `b(a)`, Input: map[string]interface{}{"a": testVarValueFloat32, "b": func(c reflect.Value) bool { return c == testVarValueFloat32 }}, RunOutput: true, Output: map[string]interface{}{"a": testVarValueFloat32}},
   226  		{Script: `b(a)`, Input: map[string]interface{}{"a": testVarValueFloat64, "b": func(c reflect.Value) bool { return c == testVarValueFloat64 }}, RunOutput: true, Output: map[string]interface{}{"a": testVarValueFloat64}},
   227  		{Script: `b(a)`, Input: map[string]interface{}{"a": testVarValueString, "b": func(c reflect.Value) bool { return c == testVarValueString }}, RunOutput: true, Output: map[string]interface{}{"a": testVarValueString}},
   228  
   229  		{Script: `x(a, b, c, d, e, f, g)`, Input: map[string]interface{}{"a": nil, "b": true, "c": int32(1), "d": int64(2), "e": float32(1.1), "f": float64(2.2), "g": "g",
   230  			"x": func(a interface{}, b bool, c int32, d int64, e float32, f float64, g string) bool {
   231  				return a == nil && b == true && c == 1 && d == 2 && e == 1.1 && f == 2.2 && g == "g"
   232  			}}, RunOutput: true, Output: map[string]interface{}{"a": nil, "b": true, "c": int32(1), "d": int64(2), "e": float32(1.1), "f": float64(2.2), "g": "g"}},
   233  		{Script: `x(a, b, c, d, e, f, g)`, Input: map[string]interface{}{"a": nil, "b": true, "c": int32(1), "d": int64(2), "e": float32(1.1), "f": float64(2.2), "g": "g",
   234  			"x": func(a interface{}, b bool, c int32, d int64, e float32, f float64, g string) (interface{}, bool, int32, int64, float32, float64, string) {
   235  				return a, b, c, d, e, f, g
   236  			}}, RunOutput: []interface{}{nil, true, int32(1), int64(2), float32(1.1), float64(2.2), "g"}, Output: map[string]interface{}{"a": nil, "b": true, "c": int32(1), "d": int64(2), "e": float32(1.1), "f": float64(2.2), "g": "g"}},
   237  
   238  		{Script: `b = a()`, Input: map[string]interface{}{"a": func() (bool, int32, int64, float32, float64, string) { return true, 1, 2, 3.3, 4.4, "5" }}, RunOutput: []interface{}{true, int32(1), int64(2), float32(3.3), float64(4.4), "5"}, Output: map[string]interface{}{"b": []interface{}{true, int32(1), int64(2), float32(3.3), float64(4.4), "5"}}},
   239  		{Script: `b = a(); b`, Input: map[string]interface{}{"a": func() (bool, int32, int64, float32, float64, string) { return true, 1, 2, 3.3, 4.4, "5" }}, RunOutput: []interface{}{true, int32(1), int64(2), float32(3.3), float64(4.4), "5"}, Output: map[string]interface{}{"b": []interface{}{true, int32(1), int64(2), float32(3.3), float64(4.4), "5"}}},
   240  		{Script: `b, c = a(); b`, Input: map[string]interface{}{"a": func() (bool, int32, int64, float32, float64, string) { return true, 1, 2, 3.3, 4.4, "5" }}, RunOutput: true, Output: map[string]interface{}{"b": true, "c": int32(1)}},
   241  		{Script: `b, c, d = a(); b`, Input: map[string]interface{}{"a": func() (bool, int32, int64, float32, float64, string) { return true, 1, 2, 3.3, 4.4, "5" }}, RunOutput: true, Output: map[string]interface{}{"b": true, "c": int32(1), "d": int64(2)}},
   242  		{Script: `b, c, d, e = a(); b`, Input: map[string]interface{}{"a": func() (bool, int32, int64, float32, float64, string) { return true, 1, 2, 3.3, 4.4, "5" }}, RunOutput: true, Output: map[string]interface{}{"b": true, "c": int32(1), "d": int64(2), "e": float32(3.3)}},
   243  		{Script: `b, c, d, e, f = a(); b`, Input: map[string]interface{}{"a": func() (bool, int32, int64, float32, float64, string) { return true, 1, 2, 3.3, 4.4, "5" }}, RunOutput: true, Output: map[string]interface{}{"b": true, "c": int32(1), "d": int64(2), "e": float32(3.3), "f": float64(4.4)}},
   244  		{Script: `b, c, d, e, f, g = a(); b`, Input: map[string]interface{}{"a": func() (bool, int32, int64, float32, float64, string) { return true, 1, 2, 3.3, 4.4, "5" }}, RunOutput: true, Output: map[string]interface{}{"b": true, "c": int32(1), "d": int64(2), "e": float32(3.3), "f": float64(4.4), "g": "5"}},
   245  
   246  		{Script: `a = nil; b(a)`, Input: map[string]interface{}{"b": func(c interface{}) bool { return c == nil }}, RunOutput: true, Output: map[string]interface{}{"a": nil}},
   247  		{Script: `a = true; b(a)`, Input: map[string]interface{}{"b": func(c bool) bool { return c == true }}, RunOutput: true, Output: map[string]interface{}{"a": true}},
   248  		{Script: `a = 1; b(a)`, Input: map[string]interface{}{"b": func(c int64) bool { return c == 1 }}, RunOutput: true, Output: map[string]interface{}{"a": int64(1)}},
   249  		{Script: `a = 1.1; b(a)`, Input: map[string]interface{}{"b": func(c float64) bool { return c == 1.1 }}, RunOutput: true, Output: map[string]interface{}{"a": float64(1.1)}},
   250  		{Script: `a = "a"; b(a)`, Input: map[string]interface{}{"b": func(c string) bool { return c == "a" }}, RunOutput: true, Output: map[string]interface{}{"a": "a"}},
   251  
   252  		{Script: `func b(c) { return c == nil }; b(a)`, Input: map[string]interface{}{"a": nil}, RunOutput: true, Output: map[string]interface{}{"a": nil}},
   253  		{Script: `func b(c) { return c == true }; b(a)`, Input: map[string]interface{}{"a": true}, RunOutput: true, Output: map[string]interface{}{"a": true}},
   254  		{Script: `func b(c) { return c == 1 }; b(a)`, Input: map[string]interface{}{"a": int32(1)}, RunOutput: true, Output: map[string]interface{}{"a": int32(1)}},
   255  		{Script: `func b(c) { return c == 1 }; b(a)`, Input: map[string]interface{}{"a": int64(1)}, RunOutput: true, Output: map[string]interface{}{"a": int64(1)}},
   256  		{Script: `func b(c) { return c == 1.1 }; b(a)`, Input: map[string]interface{}{"a": float32(1.1)}, RunOutput: true, Output: map[string]interface{}{"a": float32(1.1)}},
   257  		{Script: `func b(c) { return c == 1.1 }; b(a)`, Input: map[string]interface{}{"a": float64(1.1)}, RunOutput: true, Output: map[string]interface{}{"a": float64(1.1)}},
   258  		{Script: `func b(c) { return c == "a" }; b(a)`, Input: map[string]interface{}{"a": "a"}, RunOutput: true, Output: map[string]interface{}{"a": "a"}},
   259  
   260  		{Script: `a = nil; func b(c) { return c == nil }; b(a)`, RunOutput: true, Output: map[string]interface{}{"a": nil}},
   261  		{Script: `a = true; func b(c) { return c == true }; b(a)`, RunOutput: true, Output: map[string]interface{}{"a": true}},
   262  		{Script: `a = 1; func b(c) { return c == 1 }; b(a)`, Input: map[string]interface{}{"a": int64(1)}, RunOutput: true, Output: map[string]interface{}{"a": int64(1)}},
   263  		{Script: `a = 1.1; func b(c) { return c == 1.1 }; b(a)`, Input: map[string]interface{}{"a": float64(1.1)}, RunOutput: true, Output: map[string]interface{}{"a": float64(1.1)}},
   264  		{Script: `a = "a"; func b(c) { return c == "a" }; b(a)`, Input: map[string]interface{}{"a": "a"}, RunOutput: true, Output: map[string]interface{}{"a": "a"}},
   265  
   266  		{Script: `b(a[0])`, Input: map[string]interface{}{"a": []interface{}{nil}, "b": func(c interface{}) bool { return c == nil }}, RunOutput: true, Output: map[string]interface{}{"a": []interface{}{nil}}},
   267  		{Script: `b(a[0])`, Input: map[string]interface{}{"a": []interface{}{true}, "b": func(c interface{}) bool { return c == true }}, RunOutput: true, Output: map[string]interface{}{"a": []interface{}{true}}},
   268  		{Script: `b(a[0])`, Input: map[string]interface{}{"a": []interface{}{int32(1)}, "b": func(c interface{}) bool { return c == int32(1) }}, RunOutput: true, Output: map[string]interface{}{"a": []interface{}{int32(1)}}},
   269  		{Script: `b(a[0])`, Input: map[string]interface{}{"a": []interface{}{int64(1)}, "b": func(c interface{}) bool { return c == int64(1) }}, RunOutput: true, Output: map[string]interface{}{"a": []interface{}{int64(1)}}},
   270  		{Script: `b(a[0])`, Input: map[string]interface{}{"a": []interface{}{float32(1.1)}, "b": func(c interface{}) bool { return c == float32(1.1) }}, RunOutput: true, Output: map[string]interface{}{"a": []interface{}{float32(1.1)}}},
   271  		{Script: `b(a[0])`, Input: map[string]interface{}{"a": []interface{}{float64(1.1)}, "b": func(c interface{}) bool { return c == float64(1.1) }}, RunOutput: true, Output: map[string]interface{}{"a": []interface{}{float64(1.1)}}},
   272  		{Script: `b(a[0])`, Input: map[string]interface{}{"a": []interface{}{"a"}, "b": func(c interface{}) bool { return c == "a" }}, RunOutput: true, Output: map[string]interface{}{"a": []interface{}{"a"}}},
   273  
   274  		// TOFIX:
   275  		//		{Script: `b(a)`,
   276  		//			Input:     map[string]interface{}{"a": []bool{true, false, true}, "b": func(c ...bool) bool { return c[len(c)-1] }},
   277  		//			RunOutput: true, Output: map[string]interface{}{"a": true}},
   278  
   279  		{Script: `b(a[0])`, Input: map[string]interface{}{"a": []interface{}{true}, "b": func(c bool) bool { return c == true }}, RunOutput: true, Output: map[string]interface{}{"a": []interface{}{true}}},
   280  		{Script: `b(a[0])`, Input: map[string]interface{}{"a": []interface{}{int32(1)}, "b": func(c int32) bool { return c == int32(1) }}, RunOutput: true, Output: map[string]interface{}{"a": []interface{}{int32(1)}}},
   281  		{Script: `b(a[0])`, Input: map[string]interface{}{"a": []interface{}{int64(1)}, "b": func(c int64) bool { return c == int64(1) }}, RunOutput: true, Output: map[string]interface{}{"a": []interface{}{int64(1)}}},
   282  		{Script: `b(a[0])`, Input: map[string]interface{}{"a": []interface{}{float32(1.1)}, "b": func(c float32) bool { return c == float32(1.1) }}, RunOutput: true, Output: map[string]interface{}{"a": []interface{}{float32(1.1)}}},
   283  		{Script: `b(a[0])`, Input: map[string]interface{}{"a": []interface{}{float64(1.1)}, "b": func(c float64) bool { return c == float64(1.1) }}, RunOutput: true, Output: map[string]interface{}{"a": []interface{}{float64(1.1)}}},
   284  		{Script: `b(a[0])`, Input: map[string]interface{}{"a": []interface{}{"a"}, "b": func(c string) bool { return c == "a" }}, RunOutput: true, Output: map[string]interface{}{"a": []interface{}{"a"}}},
   285  
   286  		{Script: `a = [nil]; b(a[0])`, Input: map[string]interface{}{"b": func(c interface{}) bool { return c == nil }}, RunOutput: true, Output: map[string]interface{}{"a": []interface{}{nil}}},
   287  		{Script: `a = [true]; b(a[0])`, Input: map[string]interface{}{"b": func(c bool) bool { return c == true }}, RunOutput: true, Output: map[string]interface{}{"a": []interface{}{true}}},
   288  		{Script: `a = [1]; b(a[0])`, Input: map[string]interface{}{"b": func(c int64) bool { return c == int64(1) }}, RunOutput: true, Output: map[string]interface{}{"a": []interface{}{int64(1)}}},
   289  		{Script: `a = [1.1]; b(a[0])`, Input: map[string]interface{}{"b": func(c float64) bool { return c == float64(1.1) }}, RunOutput: true, Output: map[string]interface{}{"a": []interface{}{float64(1.1)}}},
   290  		{Script: `a = ["a"]; b(a[0])`, Input: map[string]interface{}{"b": func(c string) bool { return c == "a" }}, RunOutput: true, Output: map[string]interface{}{"a": []interface{}{"a"}}},
   291  
   292  		{Script: `a = [nil]; func b(c) { c == nil }; b(a[0])`, RunOutput: true, Output: map[string]interface{}{"a": []interface{}{nil}}},
   293  		{Script: `a = [true]; func b(c) { c == true }; b(a[0])`, RunOutput: true, Output: map[string]interface{}{"a": []interface{}{true}}},
   294  		{Script: `a = [1]; func b(c) { c == 1 }; b(a[0])`, RunOutput: true, Output: map[string]interface{}{"a": []interface{}{int64(1)}}},
   295  		{Script: `a = [1.1]; func b(c) { c == 1.1 }; b(a[0])`, RunOutput: true, Output: map[string]interface{}{"a": []interface{}{float64(1.1)}}},
   296  		{Script: `a = ["a"]; func b(c) { c == "a" }; b(a[0])`, RunOutput: true, Output: map[string]interface{}{"a": []interface{}{"a"}}},
   297  
   298  		{Script: `a = nil; b = func (d) { return d == nil }; b(a)`, RunOutput: true, Output: map[string]interface{}{"a": nil}},
   299  		{Script: `a = true; b = func (d) { return d == true }; b(a)`, RunOutput: true, Output: map[string]interface{}{"a": true}},
   300  		{Script: `a = 1; b = func (d) { return d == 1 }; b(a)`, RunOutput: true, Output: map[string]interface{}{"a": int64(1)}},
   301  		{Script: `a = 1.1; b = func (d) { return d == 1.1 }; b(a)`, RunOutput: true, Output: map[string]interface{}{"a": float64(1.1)}},
   302  		{Script: `a = "a"; b = func (d) { return d == "a" }; b(a)`, RunOutput: true, Output: map[string]interface{}{"a": "a"}},
   303  
   304  		{Script: `a = nil; b = func c(d) { return d == nil }; b(a)`, RunOutput: true, Output: map[string]interface{}{"a": nil}},
   305  		{Script: `a = true; b = func c(d) { return d == true }; b(a)`, RunOutput: true, Output: map[string]interface{}{"a": true}},
   306  		{Script: `a = 1; b = func c(d) { return d == 1 }; b(a)`, RunOutput: true, Output: map[string]interface{}{"a": int64(1)}},
   307  		{Script: `a = 1.1; b = func c(d) { return d == 1.1 }; b(a)`, RunOutput: true, Output: map[string]interface{}{"a": float64(1.1)}},
   308  		{Script: `a = "a"; b = func c(d) { return d == "a" }; b(a)`, RunOutput: true, Output: map[string]interface{}{"a": "a"}},
   309  
   310  		{Script: `a = nil; b = func c(d) { return d == nil }; c(a)`, RunOutput: true, Output: map[string]interface{}{"a": nil}},
   311  		{Script: `a = true; b = func c(d) { return d == true }; c(a)`, RunOutput: true, Output: map[string]interface{}{"a": true}},
   312  		{Script: `a = 1; b = func c(d) { return d == 1 }; c(a)`, RunOutput: true, Output: map[string]interface{}{"a": int64(1)}},
   313  		{Script: `a = 1.1; b = func c(d) { return d == 1.1 }; c(a)`, RunOutput: true, Output: map[string]interface{}{"a": float64(1.1)}},
   314  		{Script: `a = "a"; b = func c(d) { return d == "a" }; c(a)`, RunOutput: true, Output: map[string]interface{}{"a": "a"}},
   315  
   316  		{Script: `a = nil; func b() { return func c(d) { d == nil } }; e = b(); e(a)`, RunOutput: true, Output: map[string]interface{}{"a": nil}},
   317  		{Script: `a = true; func b() { return func c(d) { d == true } }; e = b(); e(a)`, RunOutput: true, Output: map[string]interface{}{"a": true}},
   318  		{Script: `a = 1; func b() { return func c(d) { d == 1 } }; e = b(); e(a)`, RunOutput: true, Output: map[string]interface{}{"a": int64(1)}},
   319  		{Script: `a = 1.1; func b() { return func c(d) { d == 1.1 } }; e = b(); e(a)`, RunOutput: true, Output: map[string]interface{}{"a": float64(1.1)}},
   320  		{Script: `a = "a"; func b() { return func c(d) { d == "a" } }; e = b(); e(a)`, RunOutput: true, Output: map[string]interface{}{"a": "a"}},
   321  
   322  		{Script: `a = func () { return nil }; func b(c) { return c() }; b(a)`, RunOutput: nil},
   323  		{Script: `a = func () { return true }; func b(c) { return c() }; b(a)`, RunOutput: true},
   324  		{Script: `a = func () { return 1 }; func b(c) { return c() }; b(a)`, RunOutput: int64(1)},
   325  		{Script: `a = func () { return 1.1 }; func b(c) { return c() }; b(a)`, RunOutput: float64(1.1)},
   326  		{Script: `a = func () { return "a" }; func b(c) { return c() }; b(a)`, RunOutput: "a"},
   327  
   328  		{Script: `a = [nil]; func c(d) { return d[0] }; c(a)`, RunOutput: nil},
   329  		{Script: `a = [true]; func c(d) { return d[0] }; c(a)`, RunOutput: true},
   330  		{Script: `a = [1]; func c(d) { return d[0] }; c(a)`, RunOutput: int64(1)},
   331  		{Script: `a = [1.1]; func c(d) { return d[0] }; c(a)`, RunOutput: float64(1.1)},
   332  		{Script: `a = ["a"]; func c(d) { return d[0] }; c(a)`, RunOutput: "a"},
   333  
   334  		{Script: `a = {"b": nil}; func c(d) { return d.b }; c(a)`, RunOutput: nil},
   335  		{Script: `a = {"b": true}; func c(d) { return d.b }; c(a)`, RunOutput: true},
   336  		{Script: `a = {"b": 1}; func c(d) { return d.b }; c(a)`, RunOutput: int64(1)},
   337  		{Script: `a = {"b": 1.1}; func c(d) { return d.b }; c(a)`, RunOutput: float64(1.1)},
   338  		{Script: `a = {"b": "a"}; func c(d) { return d.b }; c(a)`, RunOutput: "a"},
   339  
   340  		{Script: `a = func() { return func(c) { return c + "c"} }; a()("a")`, RunOutput: "ac"},
   341  		{Script: `a = func() { return func(c) { return c + "c"} }(); a("a")`, RunOutput: "ac"},
   342  		{Script: `a = func() { return func(c) { return c + "c"} }()("a")`, RunOutput: "ac"},
   343  		{Script: `func() { return func(c) { return c + "c"} }()("a")`, RunOutput: "ac"},
   344  
   345  		{Script: `a = func(b) { return func() { return b + "c"} }; b = a("a"); b()`, RunOutput: "ac"},
   346  		{Script: `a = func(b) { return func() { return b + "c"} }("a"); a()`, RunOutput: "ac"},
   347  		{Script: `a = func(b) { return func() { return b + "c"} }("a")()`, RunOutput: "ac"},
   348  		{Script: `func(b) { return func() { return b + "c"} }("a")()`, RunOutput: "ac"},
   349  
   350  		{Script: `a = func(b) { return func(c) { return b[c] } }; b = a({"x": "x"}); b("x")`, RunOutput: "x"},
   351  		{Script: `a = func(b) { return func(c) { return b[c] } }({"x": "x"}); a("x")`, RunOutput: "x"},
   352  		{Script: `a = func(b) { return func(c) { return b[c] } }({"x": "x"})("x")`, RunOutput: "x"},
   353  		{Script: `func(b) { return func(c) { return b[c] } }({"x": "x"})("x")`, RunOutput: "x"},
   354  
   355  		{Script: `a = func(b) { return func(c) { return b[c] } }; x = {"y": "y"}; b = a(x); x = {"y": "y"}; b("y")`, RunOutput: "y"},
   356  		{Script: `a = func(b) { return func(c) { return b[c] } }; x = {"y": "y"}; b = a(x); x.y = "z"; b("y")`, RunOutput: "z"},
   357  
   358  		{Script: ` func a() { return "a" }; a()`, RunOutput: "a"},
   359  		{Script: `a = func a() { return "a" }; a = func() { return "b" }; a()`, RunOutput: "b"},
   360  		{Script: `a = "a.b"; func a() { return "a" }; a()`, RunOutput: "a"},
   361  
   362  		{Script: `a = func() { b = "b"; return func() { b += "c" } }(); a()`, RunOutput: "bc"},
   363  		{Script: `a = func() { b = "b"; return func() { b += "c"; return b} }(); a()`, RunOutput: "bc"},
   364  		{Script: `a = func(b) { return func(c) { return func(d) { return d + "d" }(c) + "c" }(b) + "b" }("a")`, RunOutput: "adcb"},
   365  		{Script: `a = func(b) { return "b" + func(c) { return "c" + func(d) { return "d" + d  }(c) }(b) }("a")`, RunOutput: "bcda"},
   366  		{Script: `a = func(b) { return b + "b" }; a( func(c) { return c + "c" }("a") )`, RunOutput: "acb"},
   367  
   368  		{Script: `a = func(x, y) { return func() { x(y) } }; b = a(func (z) { return z + "z" }, "b"); b()`, RunOutput: "bz"},
   369  
   370  		{Script: `a = make(Time); a.IsZero()`, Types: map[string]interface{}{"Time": time.Time{}}, RunOutput: true},
   371  
   372  		{Script: `a = make(Buffer); n, err = a.WriteString("a"); if err != nil { return err }; n`, Types: map[string]interface{}{"Buffer": bytes.Buffer{}}, RunOutput: 1},
   373  		{Script: `a = make(Buffer); n, err = a.WriteString("a"); if err != nil { return err }; a.String()`, Types: map[string]interface{}{"Buffer": bytes.Buffer{}}, RunOutput: "a"},
   374  
   375  		{Script: `b = {}; c = a(b.c); c`, Input: map[string]interface{}{"a": func(b string) bool {
   376  			if b == "" {
   377  				return true
   378  			}
   379  			return false
   380  		}}, RunOutput: true},
   381  	}
   382  	runTests(t, tests, nil, &Options{Debug: true})
   383  }
   384  
   385  func TestPointerFunctions(t *testing.T) {
   386  	t.Parallel()
   387  
   388  	testFunctionPointer := func(b interface{}) string {
   389  		rv := reflect.ValueOf(b)
   390  		if !rv.IsValid() {
   391  			return "invalid"
   392  		}
   393  		if rv.Kind() != reflect.Ptr {
   394  			return fmt.Sprintf("not ptr: " + rv.Kind().String())
   395  		}
   396  		if rv.IsNil() {
   397  			return "IsNil"
   398  		}
   399  		if !rv.Elem().CanInterface() {
   400  			return "cannot interface"
   401  		}
   402  		if rv.Elem().Interface() != int64(1) {
   403  			return fmt.Sprintf("not 1: %v", rv.Elem().Interface())
   404  		}
   405  		if !rv.Elem().CanSet() {
   406  			return "cannot set"
   407  		}
   408  		slice := reflect.MakeSlice(interfaceSliceType, 0, 1)
   409  		value, _ := makeValue(stringType)
   410  		value.SetString("b")
   411  		slice = reflect.Append(slice, value)
   412  		rv.Elem().Set(slice)
   413  		return "good"
   414  	}
   415  	tests := []Test{
   416  		{Script: `b = 1; a(&b)`, Input: map[string]interface{}{"a": testFunctionPointer}, RunOutput: "good", Output: map[string]interface{}{"b": []interface{}{"b"}}},
   417  	}
   418  	runTests(t, tests, nil, &Options{Debug: true})
   419  }
   420  
   421  func TestVariadicFunctions(t *testing.T) {
   422  	t.Parallel()
   423  
   424  	tests := []Test{
   425  		// params Variadic arg !Variadic
   426  		{Script: `func a(b...) { return b }; a()`, RunOutput: []interface{}{}},
   427  		{Script: `func a(b...) { return b }; a(true)`, RunOutput: []interface{}{true}},
   428  		{Script: `func a(b...) { return b }; a(true, true)`, RunOutput: []interface{}{true, true}},
   429  		{Script: `func a(b...) { return b }; a([true])`, RunOutput: []interface{}{[]interface{}{true}}},
   430  		{Script: `func a(b...) { return b }; a([true, true])`, RunOutput: []interface{}{[]interface{}{true, true}}},
   431  		{Script: `func a(b...) { return b }; a([true, true], [true, true])`, RunOutput: []interface{}{[]interface{}{true, true}, []interface{}{true, true}}},
   432  
   433  		// params Variadic arg !Variadic
   434  		{Script: `func a(b, c...) { return c }; a()`, RunError: fmt.Errorf("function wants 2 arguments but received 0")},
   435  		{Script: `func a(b, c...) { return c }; a(true)`, RunOutput: []interface{}{}},
   436  		{Script: `func a(b, c...) { return c }; a(true, true)`, RunOutput: []interface{}{true}},
   437  		{Script: `func a(b, c...) { return c }; a(true, true, true)`, RunOutput: []interface{}{true, true}},
   438  		{Script: `func a(b, c...) { return c }; a([true])`, RunOutput: []interface{}{}},
   439  		{Script: `func a(b, c...) { return c }; a([true], [true])`, RunOutput: []interface{}{[]interface{}{true}}},
   440  		{Script: `func a(b, c...) { return c }; a([true], [true], [true])`, RunOutput: []interface{}{[]interface{}{true}, []interface{}{true}}},
   441  		{Script: `func a(b, c...) { return c }; a([true], [true, true], [true, true])`, RunOutput: []interface{}{[]interface{}{true, true}, []interface{}{true, true}}},
   442  
   443  		// params Variadic arg Variadic
   444  		{Script: `func a(b...) { return b }; a([true]...)`, RunOutput: []interface{}{true}},
   445  		{Script: `func a(b...) { return b }; a([true, true]...)`, RunOutput: []interface{}{true, true}},
   446  		{Script: `func a(b...) { return b }; a(true, [true]...)`, RunError: fmt.Errorf("function wants 1 arguments but received 2")},
   447  
   448  		// params Variadic arg Variadic
   449  		{Script: `func a(b, c...) { return c }; a([true]...)`, RunOutput: []interface{}{}},
   450  		{Script: `func a(b, c...) { return c }; a([true, true]...)`, RunOutput: []interface{}{}},
   451  		{Script: `func a(b, c...) { return c }; a(true, [true]...)`, RunOutput: []interface{}{true}},
   452  		{Script: `func a(b, c...) { return c }; a(true, [true, true]...)`, RunOutput: []interface{}{true, true}},
   453  
   454  		// params !Variadic arg Variadic
   455  		{Script: `func a() { return "a" }; a([true]...)`, RunOutput: "a"},
   456  		{Script: `func a() { return "a" }; a(true, [true]...)`, RunOutput: "a"},
   457  		{Script: `func a() { return "a" }; a(true, [true, true]...)`, RunOutput: "a"},
   458  
   459  		// params !Variadic arg Variadic
   460  		{Script: `func a(b) { return b }; a(true...)`, RunError: fmt.Errorf("call is variadic but last parameter is of type bool")},
   461  		{Script: `func a(b) { return b }; a([true]...)`, RunOutput: true},
   462  		{Script: `func a(b) { return b }; a(true, false...)`, RunError: fmt.Errorf("function wants 1 arguments but received 2")},
   463  		{Script: `func a(b) { return b }; a(true, [1]...)`, RunError: fmt.Errorf("function wants 1 arguments but received 2")},
   464  		{Script: `func a(b) { return b }; a(true, [1, 2]...)`, RunError: fmt.Errorf("function wants 1 arguments but received 2")},
   465  		{Script: `func a(b) { return b }; a([true, 1]...)`, RunOutput: true},
   466  		{Script: `func a(b) { return b }; a([true, 1, 2]...)`, RunOutput: true},
   467  
   468  		// params !Variadic arg Variadi
   469  		{Script: `func a(b, c) { return c }; a(false...)`, RunError: fmt.Errorf("call is variadic but last parameter is of type bool")},
   470  		{Script: `func a(b, c) { return c }; a([1]...)`, RunError: fmt.Errorf("function wants 2 arguments but received 1")},
   471  		{Script: `func a(b, c) { return c }; a(1, true...)`, RunError: fmt.Errorf("call is variadic but last parameter is of type bool")},
   472  		{Script: `func a(b, c) { return c }; a(1, [true]...)`, RunOutput: true},
   473  		{Script: `func a(b, c) { return c }; a([1, true]...)`, RunOutput: true},
   474  		{Script: `func a(b, c) { return c }; a(1, true...)`, RunError: fmt.Errorf("call is variadic but last parameter is of type bool")},
   475  		{Script: `func a(b, c) { return c }; a(1, [true]...)`, RunOutput: true},
   476  		{Script: `func a(b, c) { return c }; a(1, true, false...)`, RunError: fmt.Errorf("function wants 2 arguments but received 3")},
   477  		{Script: `func a(b, c) { return c }; a(1, true, [2]...)`, RunError: fmt.Errorf("function wants 2 arguments but received 3")},
   478  		{Script: `func a(b, c) { return c }; a(1, [true, 2]...)`, RunOutput: true},
   479  		{Script: `func a(b, c) { return c }; a([1, true, 2]...)`, RunOutput: true},
   480  	}
   481  	runTests(t, tests, nil, &Options{Debug: true})
   482  }
   483  
   484  func TestFunctionsInArraysAndMaps(t *testing.T) {
   485  	t.Parallel()
   486  
   487  	tests := []Test{
   488  		{Script: `a = [func () { return nil }]; a[0]()`, RunOutput: nil},
   489  		{Script: `a = [func () { return true }]; a[0]()`, RunOutput: true},
   490  		{Script: `a = [func () { return 1 }]; a[0]()`, RunOutput: int64(1)},
   491  		{Script: `a = [func () { return 1.1 }]; a[0]()`, RunOutput: float64(1.1)},
   492  		{Script: `a = [func () { return "a" }]; a[0]()`, RunOutput: "a"},
   493  
   494  		{Script: `a = [func () { return nil }]; b = a[0]; b()`, RunOutput: nil},
   495  		{Script: `a = [func () { return true }]; b = a[0]; b()`, RunOutput: true},
   496  		{Script: `a = [func () { return 1 }]; b = a[0]; b()`, RunOutput: int64(1)},
   497  		{Script: `a = [func () { return 1.1 }]; b = a[0]; b()`, RunOutput: float64(1.1)},
   498  		{Script: `a = [func () { return "a" }]; b = a[0]; b()`, RunOutput: "a"},
   499  
   500  		{Script: `a = [func () { return nil}]; func b(c) { return c() }; b(a[0])`, RunOutput: nil},
   501  		{Script: `a = [func () { return true}]; func b(c) { return c() }; b(a[0])`, RunOutput: true},
   502  		{Script: `a = [func () { return 1}]; func b(c) { return c() }; b(a[0])`, RunOutput: int64(1)},
   503  		{Script: `a = [func () { return 1.1}]; func b(c) { return c() }; b(a[0])`, RunOutput: float64(1.1)},
   504  		{Script: `a = [func () { return "a"}]; func b(c) { return c() }; b(a[0])`, RunOutput: "a"},
   505  
   506  		{Script: `a = {"b": func () { return nil }}; a["b"]()`, RunOutput: nil},
   507  		{Script: `a = {"b": func () { return true }}; a["b"]()`, RunOutput: true},
   508  		{Script: `a = {"b": func () { return 1 }}; a["b"]()`, RunOutput: int64(1)},
   509  		{Script: `a = {"b": func () { return 1.1 }}; a["b"]()`, RunOutput: float64(1.1)},
   510  		{Script: `a = {"b": func () { return "a" }}; a["b"]()`, RunOutput: "a"},
   511  
   512  		{Script: `a = {"b": func () { return nil }}; a.b()`, RunOutput: nil},
   513  		{Script: `a = {"b": func () { return true }}; a.b()`, RunOutput: true},
   514  		{Script: `a = {"b": func () { return 1 }}; a.b()`, RunOutput: int64(1)},
   515  		{Script: `a = {"b": func () { return 1.1 }}; a.b()`, RunOutput: float64(1.1)},
   516  		{Script: `a = {"b": func () { return "a" }}; a.b()`, RunOutput: "a"},
   517  
   518  		{Script: `a = {"b": func () { return nil }}; func c(d) { return d() }; c(a.b)`, RunOutput: nil},
   519  		{Script: `a = {"b": func () { return true }}; func c(d) { return d() }; c(a.b)`, RunOutput: true},
   520  		{Script: `a = {"b": func () { return 1 }}; func c(d) { return d() }; c(a.b)`, RunOutput: int64(1)},
   521  		{Script: `a = {"b": func () { return 1.1 }}; func c(d) { return d() }; c(a.b)`, RunOutput: float64(1.1)},
   522  		{Script: `a = {"b": func () { return "a" }}; func c(d) { return d() }; c(a.b)`, RunOutput: "a"},
   523  	}
   524  	runTests(t, tests, nil, &Options{Debug: true})
   525  }
   526  
   527  func TestFunctionConversions(t *testing.T) {
   528  	t.Parallel()
   529  
   530  	tests := []Test{
   531  		{Script: `b = func(c){ return c }; a("x", b)`, Input: map[string]interface{}{"a": func(b string, c func(string) string) string { return c(b) }}, RunOutput: "x"},
   532  		{Script: `b = make(struct1); b.A = func (c, d) { return c == d }; b.A(2, 2)`, Types: map[string]interface{}{"struct1": &struct {
   533  			A func(int, int) bool
   534  		}{}},
   535  			RunOutput: true},
   536  		{Script: `b = 1; a(&b)`, Input: map[string]interface{}{"a": func(b *int64) { *b = int64(2) }}, Output: map[string]interface{}{"b": int64(2)}},
   537  		{Script: `b = func(){ return true, 1, 2, 3.3, 4.4, "5" }; c, d, e, f, g, h = a(b); c`, Input: map[string]interface{}{"a": func(b func() (bool, int32, int64, float32, float64, string)) (bool, int32, int64, float32, float64, string) {
   538  			return b()
   539  		}}, RunOutput: true, Output: map[string]interface{}{"c": true, "d": int32(1), "e": int64(2), "f": float32(3.3), "g": float64(4.4), "h": "5"}},
   540  
   541  		// string to byte
   542  		{Script: `b = a("yz"); b`, Input: map[string]interface{}{"a": func(b byte) string { return string(b) }}, RunError: fmt.Errorf("function wants argument type uint8 but received type string")},
   543  		{Script: `b = a("x"); b`, Input: map[string]interface{}{"a": func(b byte) string { return string(b) }}, RunOutput: "x"},
   544  		{Script: `b = a(""); b`, Input: map[string]interface{}{"a": func(b byte) string { return string(b) }}, RunOutput: "\x00"},
   545  		// string to rune
   546  		{Script: `b = a("yz"); b`, Input: map[string]interface{}{"a": func(b rune) string { return string(b) }}, RunError: fmt.Errorf("function wants argument type int32 but received type string")},
   547  		{Script: `b = a("x"); b`, Input: map[string]interface{}{"a": func(b rune) string { return string(b) }}, RunOutput: "x"},
   548  		{Script: `b = a(""); b`, Input: map[string]interface{}{"a": func(b rune) string { return string(b) }}, RunOutput: "\x00"},
   549  
   550  		// slice inteface unable to convert to int
   551  		{Script: `b = [1, 2.2, "3"]; a(b)`, Input: map[string]interface{}{"a": func(b []int) int { return len(b) }}, RunError: fmt.Errorf("function wants argument type []int but received type []interface {}"), Output: map[string]interface{}{"b": []interface{}{int64(1), float64(2.2), "3"}}},
   552  		// slice no sub convertible conversion
   553  		{Script: `a(b)`, Input: map[string]interface{}{"a": func(b []int) int { return len(b) }, "b": []int64{1}}, RunOutput: int(1), Output: map[string]interface{}{"b": []int64{1}}},
   554  		// array no sub convertible conversion
   555  		{Script: `a(b)`, Input: map[string]interface{}{"a": func(b [2]int) int { return len(b) }, "b": [2]int64{1, 2}}, RunOutput: int(2), Output: map[string]interface{}{"b": [2]int64{1, 2}}},
   556  		// slice no sub to interface conversion
   557  		{Script: `a(b)`, Input: map[string]interface{}{"a": func(b []interface{}) int { return len(b) }, "b": []int64{1}}, RunOutput: int(1), Output: map[string]interface{}{"b": []int64{1}}},
   558  		// array no sub to interface conversion
   559  		{Script: `a(b)`, Input: map[string]interface{}{"a": func(b [2]interface{}) int { return len(b) }, "b": [2]int64{1, 2}}, RunOutput: int(2), Output: map[string]interface{}{"b": [2]int64{1, 2}}},
   560  		// slice no sub from interface conversion
   561  		{Script: `b = [1]; a(b)`, Input: map[string]interface{}{"a": func(b []int) int { return len(b) }}, RunOutput: int(1), Output: map[string]interface{}{"b": []interface{}{int64(1)}}},
   562  		// array no sub from interface conversion
   563  		{Script: `a(b)`, Input: map[string]interface{}{"a": func(b [2]int) int { return len(b) }, "b": [2]interface{}{1, 2}}, RunOutput: int(2), Output: map[string]interface{}{"b": [2]interface{}{1, 2}}},
   564  
   565  		// slice sub mismatch
   566  		{Script: `a(b)`, Input: map[string]interface{}{"a": func(b []int) int { return len(b) }, "b": [][]int64{{1, 2}}}, RunError: fmt.Errorf("function wants argument type []int but received type [][]int64"), Output: map[string]interface{}{"b": [][]int64{{1, 2}}}},
   567  		// array sub mismatch
   568  		{Script: `a(b)`, Input: map[string]interface{}{"a": func(b [2]int) int { return len(b) }, "b": [1][2]int64{{1, 2}}}, RunError: fmt.Errorf("function wants argument type [2]int but received type [1][2]int64"), Output: map[string]interface{}{"b": [1][2]int64{{1, 2}}}},
   569  
   570  		// slice with sub int64 to int conversion
   571  		{Script: `a(b)`, Input: map[string]interface{}{"a": func(b [][]int) int { return len(b) }, "b": [][]int64{{1, 2}, {3, 4}}}, RunOutput: int(2), Output: map[string]interface{}{"b": [][]int64{{1, 2}, {3, 4}}}},
   572  		// array with sub int64 to int conversion
   573  		{Script: `a(b)`, Input: map[string]interface{}{"a": func(b [][]int) int { return len(b) }, "b": [2][2]int64{{1, 2}, {3, 4}}}, RunOutput: int(2), Output: map[string]interface{}{"b": [2][2]int64{{1, 2}, {3, 4}}}},
   574  		// slice with sub interface to int conversion
   575  		{Script: `b = [[1, 2], [3, 4]]; a(b)`, Input: map[string]interface{}{"a": func(b [][]int) int { return len(b) }}, RunOutput: int(2), Output: map[string]interface{}{"b": []interface{}{[]interface{}{int64(1), int64(2)}, []interface{}{int64(3), int64(4)}}}},
   576  		// slice with sub interface to int conversion
   577  		{Script: `a(b)`, Input: map[string]interface{}{"a": func(b [][]int) int { return len(b) }, "b": [][]interface{}{{int64(1), int32(2)}, {float64(3.3), float32(4.4)}}}, RunOutput: int(2), Output: map[string]interface{}{"b": [][]interface{}{{int64(1), int32(2)}, {float64(3.3), float32(4.4)}}}},
   578  		// array with sub interface to int conversion
   579  		{Script: `a(b)`, Input: map[string]interface{}{"a": func(b [][]int) int { return len(b) }, "b": [2][2]interface{}{{1, 2}, {3, 4}}}, RunOutput: int(2), Output: map[string]interface{}{"b": [2][2]interface{}{{1, 2}, {3, 4}}}},
   580  		// slice with single interface to double interface
   581  		{Script: `b = [[1, 2], [3, 4]]; a(b)`, Input: map[string]interface{}{"a": func(b [][]interface{}) int { return len(b) }}, RunOutput: int(2), Output: map[string]interface{}{"b": []interface{}{[]interface{}{int64(1), int64(2)}, []interface{}{int64(3), int64(4)}}}},
   582  		// slice with sub int64 to double interface conversion
   583  		{Script: `a(b)`, Input: map[string]interface{}{"a": func(b [][]interface{}) int { return len(b) }, "b": [][]int64{{1, 2}, {3, 4}}}, RunOutput: int(2), Output: map[string]interface{}{"b": [][]int64{{1, 2}, {3, 4}}}},
   584  		// array with sub int64 to double interface conversion
   585  		{Script: `a(b)`, Input: map[string]interface{}{"a": func(b [][]interface{}) int { return len(b) }, "b": [2][2]int64{{1, 2}, {3, 4}}}, RunOutput: int(2), Output: map[string]interface{}{"b": [2][2]int64{{1, 2}, {3, 4}}}},
   586  
   587  		// TOFIX: not able to change pointer value
   588  		// {Script: `b = 1; c = &b; a(c); *c`, Input: map[string]interface{}{"a": func(b *int64) { *b = int64(2) }}, RunOutput: int64(2), Output: map[string]interface{}{"b": int64(2)}},
   589  
   590  		// map [interface]interface to [interface]interface
   591  		{Script: `b = {nil:nil}; c = nil; d = a(b, c)`, Input: map[string]interface{}{"a": func(b map[interface{}]interface{}, c interface{}) interface{} { return b[c] }}, RunOutput: nil, Output: map[string]interface{}{"b": map[interface{}]interface{}{nil: nil}, "c": nil}},
   592  		{Script: `b = {true:true}; c = true; d = a(b, c)`, Input: map[string]interface{}{"a": func(b map[interface{}]interface{}, c interface{}) interface{} { return b[c] }}, RunOutput: true, Output: map[string]interface{}{"b": map[interface{}]interface{}{true: true}, "c": true}},
   593  		{Script: `b = {1:2}; c = 1; d = a(b, c)`, Input: map[string]interface{}{"a": func(b map[interface{}]interface{}, c interface{}) interface{} { return b[c] }}, RunOutput: int64(2), Output: map[string]interface{}{"b": map[interface{}]interface{}{int64(1): int64(2)}, "c": int64(1)}},
   594  		{Script: `b = {1.1:2.2}; c = 1.1; d = a(b, c)`, Input: map[string]interface{}{"a": func(b map[interface{}]interface{}, c interface{}) interface{} { return b[c] }}, RunOutput: float64(2.2), Output: map[string]interface{}{"b": map[interface{}]interface{}{float64(1.1): float64(2.2)}, "c": float64(1.1)}},
   595  		{Script: `b = {"a":"b"}; c = "a"; d = a(b, c)`, Input: map[string]interface{}{"a": func(b map[interface{}]interface{}, c interface{}) interface{} { return b[c] }}, RunOutput: "b", Output: map[string]interface{}{"b": map[interface{}]interface{}{"a": "b"}, "c": "a"}},
   596  
   597  		// map [interface]interface to [bool]interface
   598  		{Script: `b = {"a":"b"}; c = true; d = a(b, c)`, Input: map[string]interface{}{"a": func(b map[bool]interface{}, c bool) interface{} { return b[c] }}, RunError: fmt.Errorf("function wants argument type map[bool]interface {} but received type map[interface {}]interface {}"), Output: map[string]interface{}{"b": map[interface{}]interface{}{"a": "b"}, "c": true}},
   599  		{Script: `b = {"a":"b"}; c = "a"; d = a(b, c)`, Input: map[string]interface{}{"a": func(b map[bool]interface{}, c bool) interface{} { return b[c] }}, RunError: fmt.Errorf("function wants argument type map[bool]interface {} but received type map[interface {}]interface {}"), Output: map[string]interface{}{"b": map[interface{}]interface{}{"a": "b"}, "c": "a"}},
   600  		{Script: `b = {true:"b"}; c = "a"; d = a(b, c)`, Input: map[string]interface{}{"a": func(b map[bool]interface{}, c bool) interface{} { return b[c] }}, RunError: fmt.Errorf("function wants argument type bool but received type string"), Output: map[string]interface{}{"b": map[interface{}]interface{}{true: "b"}, "c": "a"}},
   601  		{Script: `b = {true:nil}; c = true; d = a(b, c)`, Input: map[string]interface{}{"a": func(b map[bool]interface{}, c bool) interface{} { return b[c] }}, RunOutput: nil, Output: map[string]interface{}{"b": map[interface{}]interface{}{true: nil}, "c": true}},
   602  		{Script: `b = {true:true}; c = true; d = a(b, c)`, Input: map[string]interface{}{"a": func(b map[bool]interface{}, c bool) interface{} { return b[c] }}, RunOutput: true, Output: map[string]interface{}{"b": map[interface{}]interface{}{true: true}, "c": true}},
   603  		{Script: `b = {true:2}; c = true; d = a(b, c)`, Input: map[string]interface{}{"a": func(b map[bool]interface{}, c bool) interface{} { return b[c] }}, RunOutput: int64(2), Output: map[string]interface{}{"b": map[interface{}]interface{}{true: int64(2)}, "c": true}},
   604  		{Script: `b = {true:2.2}; c = true; d = a(b, c)`, Input: map[string]interface{}{"a": func(b map[bool]interface{}, c bool) interface{} { return b[c] }}, RunOutput: float64(2.2), Output: map[string]interface{}{"b": map[interface{}]interface{}{true: float64(2.2)}, "c": true}},
   605  		{Script: `b = {true:"b"}; c = true; d = a(b, c)`, Input: map[string]interface{}{"a": func(b map[bool]interface{}, c bool) interface{} { return b[c] }}, RunOutput: "b", Output: map[string]interface{}{"b": map[interface{}]interface{}{true: "b"}, "c": true}},
   606  
   607  		// map [interface]interface to [int32]interface
   608  		{Script: `b = {1:nil}; c = 1; d = a(b, c)`, Input: map[string]interface{}{"a": func(b map[int32]interface{}, c int32) interface{} { return b[c] }}, RunOutput: nil, Output: map[string]interface{}{"b": map[interface{}]interface{}{int64(1): nil}, "c": int64(1)}},
   609  		{Script: `b = {1:true}; c = 1; d = a(b, c)`, Input: map[string]interface{}{"a": func(b map[int32]interface{}, c int32) interface{} { return b[c] }}, RunOutput: true, Output: map[string]interface{}{"b": map[interface{}]interface{}{int64(1): true}, "c": int64(1)}},
   610  		{Script: `b = {1:2}; c = 1; d = a(b, c)`, Input: map[string]interface{}{"a": func(b map[int32]interface{}, c int32) interface{} { return b[c] }}, RunOutput: int64(2), Output: map[string]interface{}{"b": map[interface{}]interface{}{int64(1): int64(2)}, "c": int64(1)}},
   611  		{Script: `b = {1:2.2}; c = 1; d = a(b, c)`, Input: map[string]interface{}{"a": func(b map[int32]interface{}, c int32) interface{} { return b[c] }}, RunOutput: float64(2.2), Output: map[string]interface{}{"b": map[interface{}]interface{}{int64(1): float64(2.2)}, "c": int64(1)}},
   612  		{Script: `b = {1:"b"}; c = 1; d = a(b, c)`, Input: map[string]interface{}{"a": func(b map[int32]interface{}, c int32) interface{} { return b[c] }}, RunOutput: "b", Output: map[string]interface{}{"b": map[interface{}]interface{}{int64(1): "b"}, "c": int64(1)}},
   613  
   614  		// map [interface]interface to [int64]interface
   615  		{Script: `b = {1:nil}; c = 1; d = a(b, c)`, Input: map[string]interface{}{"a": func(b map[int64]interface{}, c int64) interface{} { return b[c] }}, RunOutput: nil, Output: map[string]interface{}{"b": map[interface{}]interface{}{int64(1): nil}, "c": int64(1)}},
   616  		{Script: `b = {1:true}; c = 1; d = a(b, c)`, Input: map[string]interface{}{"a": func(b map[int64]interface{}, c int64) interface{} { return b[c] }}, RunOutput: true, Output: map[string]interface{}{"b": map[interface{}]interface{}{int64(1): true}, "c": int64(1)}},
   617  		{Script: `b = {1:2}; c = 1; d = a(b, c)`, Input: map[string]interface{}{"a": func(b map[int64]interface{}, c int64) interface{} { return b[c] }}, RunOutput: int64(2), Output: map[string]interface{}{"b": map[interface{}]interface{}{int64(1): int64(2)}, "c": int64(1)}},
   618  		{Script: `b = {1:2.2}; c = 1; d = a(b, c)`, Input: map[string]interface{}{"a": func(b map[int64]interface{}, c int64) interface{} { return b[c] }}, RunOutput: float64(2.2), Output: map[string]interface{}{"b": map[interface{}]interface{}{int64(1): float64(2.2)}, "c": int64(1)}},
   619  		{Script: `b = {1:"b"}; c = 1; d = a(b, c)`, Input: map[string]interface{}{"a": func(b map[int64]interface{}, c int64) interface{} { return b[c] }}, RunOutput: "b", Output: map[string]interface{}{"b": map[interface{}]interface{}{int64(1): "b"}, "c": int64(1)}},
   620  
   621  		// map [interface]interface to [float32]interface
   622  		{Script: `b = {1.1:nil}; c = 1.1; d = a(b, c)`, Input: map[string]interface{}{"a": func(b map[float32]interface{}, c float32) interface{} { return b[c] }}, RunOutput: nil, Output: map[string]interface{}{"b": map[interface{}]interface{}{float64(1.1): nil}, "c": float64(1.1)}},
   623  		{Script: `b = {1.1:true}; c = 1.1; d = a(b, c)`, Input: map[string]interface{}{"a": func(b map[float32]interface{}, c float32) interface{} { return b[c] }}, RunOutput: true, Output: map[string]interface{}{"b": map[interface{}]interface{}{float64(1.1): true}, "c": float64(1.1)}},
   624  		{Script: `b = {1.1:2}; c = 1.1; d = a(b, c)`, Input: map[string]interface{}{"a": func(b map[float32]interface{}, c float32) interface{} { return b[c] }}, RunOutput: int64(2), Output: map[string]interface{}{"b": map[interface{}]interface{}{float64(1.1): int64(2)}, "c": float64(1.1)}},
   625  		{Script: `b = {1.1:2.2}; c = 1.1; d = a(b, c)`, Input: map[string]interface{}{"a": func(b map[float32]interface{}, c float32) interface{} { return b[c] }}, RunOutput: float64(2.2), Output: map[string]interface{}{"b": map[interface{}]interface{}{float64(1.1): float64(2.2)}, "c": float64(1.1)}},
   626  		{Script: `b = {1.1:"b"}; c = 1.1; d = a(b, c)`, Input: map[string]interface{}{"a": func(b map[float32]interface{}, c float32) interface{} { return b[c] }}, RunOutput: "b", Output: map[string]interface{}{"b": map[interface{}]interface{}{float64(1.1): "b"}, "c": float64(1.1)}},
   627  
   628  		// map [interface]interface to [float64]interface
   629  		{Script: `b = {1.1:nil}; c = 1.1; d = a(b, c)`, Input: map[string]interface{}{"a": func(b map[float64]interface{}, c float64) interface{} { return b[c] }}, RunOutput: nil, Output: map[string]interface{}{"b": map[interface{}]interface{}{float64(1.1): nil}, "c": float64(1.1)}},
   630  		{Script: `b = {1.1:true}; c = 1.1; d = a(b, c)`, Input: map[string]interface{}{"a": func(b map[float64]interface{}, c float64) interface{} { return b[c] }}, RunOutput: true, Output: map[string]interface{}{"b": map[interface{}]interface{}{float64(1.1): true}, "c": float64(1.1)}},
   631  		{Script: `b = {1.1:2}; c = 1.1; d = a(b, c)`, Input: map[string]interface{}{"a": func(b map[float64]interface{}, c float64) interface{} { return b[c] }}, RunOutput: int64(2), Output: map[string]interface{}{"b": map[interface{}]interface{}{float64(1.1): int64(2)}, "c": float64(1.1)}},
   632  		{Script: `b = {1.1:2.2}; c = 1.1; d = a(b, c)`, Input: map[string]interface{}{"a": func(b map[float64]interface{}, c float64) interface{} { return b[c] }}, RunOutput: float64(2.2), Output: map[string]interface{}{"b": map[interface{}]interface{}{float64(1.1): float64(2.2)}, "c": float64(1.1)}},
   633  		{Script: `b = {1.1:"b"}; c = 1.1; d = a(b, c)`, Input: map[string]interface{}{"a": func(b map[float64]interface{}, c float64) interface{} { return b[c] }}, RunOutput: "b", Output: map[string]interface{}{"b": map[interface{}]interface{}{float64(1.1): "b"}, "c": float64(1.1)}},
   634  
   635  		// map [interface]interface to [string]interface
   636  		{Script: `b = {"a":nil}; c = "a"; d = a(b, c)`, Input: map[string]interface{}{"a": func(b map[string]interface{}, c string) interface{} { return b[c] }}, RunOutput: nil, Output: map[string]interface{}{"b": map[interface{}]interface{}{"a": nil}, "c": "a"}},
   637  		{Script: `b = {"a":true}; c = "a"; d = a(b, c)`, Input: map[string]interface{}{"a": func(b map[string]interface{}, c string) interface{} { return b[c] }}, RunOutput: true, Output: map[string]interface{}{"b": map[interface{}]interface{}{"a": true}, "c": "a"}},
   638  		{Script: `b = {"a":2}; c = "a"; d = a(b, c)`, Input: map[string]interface{}{"a": func(b map[string]interface{}, c string) interface{} { return b[c] }}, RunOutput: int64(2), Output: map[string]interface{}{"b": map[interface{}]interface{}{"a": int64(2)}, "c": "a"}},
   639  		{Script: `b = {"a":2.2}; c = "a"; d = a(b, c)`, Input: map[string]interface{}{"a": func(b map[string]interface{}, c string) interface{} { return b[c] }}, RunOutput: float64(2.2), Output: map[string]interface{}{"b": map[interface{}]interface{}{"a": float64(2.2)}, "c": "a"}},
   640  		{Script: `b = {"a":"b"}; c = "a"; d = a(b, c)`, Input: map[string]interface{}{"a": func(b map[string]interface{}, c string) interface{} { return b[c] }}, RunOutput: "b", Output: map[string]interface{}{"b": map[interface{}]interface{}{"a": "b"}, "c": "a"}},
   641  
   642  		// map [interface]interface to [string]X
   643  		{Script: `b = {"a":"b"}; c = "a"; d = a(b, c)`, Input: map[string]interface{}{"a": func(b map[string]bool, c string) bool { return b[c] }}, RunError: fmt.Errorf("function wants argument type map[string]bool but received type map[interface {}]interface {}"), Output: map[string]interface{}{"b": map[interface{}]interface{}{"a": "b"}, "c": "a"}},
   644  		{Script: `b = {"a":true}; c = "a"; d = a(b, c)`, Input: map[string]interface{}{"a": func(b map[string]bool, c string) bool { return b[c] }}, RunOutput: true, Output: map[string]interface{}{"b": map[interface{}]interface{}{"a": true}, "c": "a"}},
   645  		{Script: `b = {"a":1}; c = "a"; d = a(b, c)`, Input: map[string]interface{}{"a": func(b map[string]int32, c string) int32 { return b[c] }}, RunOutput: int32(1), Output: map[string]interface{}{"b": map[interface{}]interface{}{"a": int64(1)}, "c": "a"}},
   646  		{Script: `b = {"a":1}; c = "a"; d = a(b, c)`, Input: map[string]interface{}{"a": func(b map[string]int64, c string) int64 { return b[c] }}, RunOutput: int64(1), Output: map[string]interface{}{"b": map[interface{}]interface{}{"a": int64(1)}, "c": "a"}},
   647  		{Script: `b = {"a":1.1}; c = "a"; d = a(b, c)`, Input: map[string]interface{}{"a": func(b map[string]float32, c string) float32 { return b[c] }}, RunOutput: float32(1.1), Output: map[string]interface{}{"b": map[interface{}]interface{}{"a": float64(1.1)}, "c": "a"}},
   648  		{Script: `b = {"a":1.1}; c = "a"; d = a(b, c)`, Input: map[string]interface{}{"a": func(b map[string]float64, c string) float64 { return b[c] }}, RunOutput: float64(1.1), Output: map[string]interface{}{"b": map[interface{}]interface{}{"a": float64(1.1)}, "c": "a"}},
   649  		{Script: `b = {"a":"b"}; c = "a"; d = a(b, c)`, Input: map[string]interface{}{"a": func(b map[string]string, c string) string { return b[c] }}, RunOutput: "b", Output: map[string]interface{}{"b": map[interface{}]interface{}{"a": "b"}, "c": "a"}},
   650  	}
   651  	runTests(t, tests, nil, &Options{Debug: true})
   652  
   653  	tests = []Test{
   654  		{Script: `c = a(b)`,
   655  			Input: map[string]interface{}{"a": func(b func() bool) bool {
   656  				return b()
   657  			}, "b": func(c func(bool)) { c(true) }}, RunError: fmt.Errorf("function wants argument type func() bool but received type func(func(bool))")},
   658  		{Script: `b = func(){ return 1++ }; c = a(b)`,
   659  			Input: map[string]interface{}{"a": func(b func() bool) bool {
   660  				return b()
   661  			}}, RunError: fmt.Errorf("invalid operation")},
   662  		{Script: `b = func(){ return true }; c = a(b)`,
   663  			Input: map[string]interface{}{"a": func(b func() string) string {
   664  				return b()
   665  			}}, RunError: fmt.Errorf("function wants return type string but received type bool")},
   666  		{Script: `b = func(){ return true }; c = a(b)`,
   667  			Input: map[string]interface{}{"a": func(b func() (bool, string)) (bool, string) {
   668  				return b()
   669  			}}, RunError: fmt.Errorf("function wants 2 return values but received bool")},
   670  		{Script: `b = func(){ return true, 1 }; c = a(b)`,
   671  			Input: map[string]interface{}{"a": func(b func() (bool, int64, string)) (bool, int64, string) {
   672  				return b()
   673  			}}, RunError: fmt.Errorf("function wants 3 return values but received 2 values")},
   674  		{Script: `b = func(){ return "1", true }; c = a(b)`,
   675  			Input: map[string]interface{}{"a": func(b func() (bool, string)) (bool, string) {
   676  				return b()
   677  			}}, RunError: fmt.Errorf("function wants return type bool but received type string")},
   678  	}
   679  	runTests(t, tests, nil, &Options{Debug: false})
   680  }
   681  
   682  func TestVariadicFunctionConversions(t *testing.T) {
   683  	t.Parallel()
   684  
   685  	testSumFunc := func(nums ...int64) int64 {
   686  		var total int64
   687  		for _, num := range nums {
   688  			total += num
   689  		}
   690  		return total
   691  	}
   692  	tests := []Test{
   693  		// params Variadic arg !Variadic
   694  		{Script: `a(true)`, Input: map[string]interface{}{"a": func(b ...interface{}) []interface{} { return b }}, RunOutput: []interface{}{true}},
   695  
   696  		{Script: `a()`, Input: map[string]interface{}{"a": testSumFunc}, RunOutput: int64(0)},
   697  		{Script: `a(1)`, Input: map[string]interface{}{"a": testSumFunc}, RunOutput: int64(1)},
   698  		{Script: `a(1, 2)`, Input: map[string]interface{}{"a": testSumFunc}, RunOutput: int64(3)},
   699  		{Script: `a(1, 2, 3)`, Input: map[string]interface{}{"a": testSumFunc}, RunOutput: int64(6)},
   700  
   701  		// TODO: add more tests
   702  	}
   703  	runTests(t, tests, nil, &Options{Debug: true})
   704  }
   705  
   706  func TestLen(t *testing.T) {
   707  	t.Parallel()
   708  
   709  	tests := []Test{
   710  		{Script: `len(1++)`, RunError: fmt.Errorf("invalid operation")},
   711  		{Script: `len(true)`, RunError: fmt.Errorf("type bool does not support len operation")},
   712  
   713  		{Script: `a = ""; len(a)`, RunOutput: int64(0)},
   714  		{Script: `a = "test"; len(a)`, RunOutput: int64(4)},
   715  		{Script: `a = []; len(a)`, RunOutput: int64(0)},
   716  		{Script: `a = [nil]; len(a)`, RunOutput: int64(1)},
   717  		{Script: `a = [true]; len(a)`, RunOutput: int64(1)},
   718  		{Script: `a = ["test"]; len(a)`, RunOutput: int64(1)},
   719  		{Script: `a = [1]; len(a)`, RunOutput: int64(1)},
   720  		{Script: `a = [1.1]; len(a)`, RunOutput: int64(1)},
   721  
   722  		{Script: `a = [[]]; len(a)`, RunOutput: int64(1)},
   723  		{Script: `a = [[nil]]; len(a)`, RunOutput: int64(1)},
   724  		{Script: `a = [[true]]; len(a)`, RunOutput: int64(1)},
   725  		{Script: `a = [["test"]]; len(a)`, RunOutput: int64(1)},
   726  		{Script: `a = [[1]]; len(a)`, RunOutput: int64(1)},
   727  		{Script: `a = [[1.1]]; len(a)`, RunOutput: int64(1)},
   728  
   729  		{Script: `a = [[]]; len(a[0])`, RunOutput: int64(0)},
   730  		{Script: `a = [[nil]]; len(a[0])`, RunOutput: int64(1)},
   731  		{Script: `a = [[true]]; len(a[0])`, RunOutput: int64(1)},
   732  		{Script: `a = [["test"]]; len(a[0])`, RunOutput: int64(1)},
   733  		{Script: `a = [[1]]; len(a[0])`, RunOutput: int64(1)},
   734  		{Script: `a = [[1.1]]; len(a[0])`, RunOutput: int64(1)},
   735  
   736  		{Script: `len(a)`, Input: map[string]interface{}{"a": "a"}, RunOutput: int64(1), Output: map[string]interface{}{"a": "a"}},
   737  		{Script: `len(a)`, Input: map[string]interface{}{"a": map[string]interface{}{}}, RunOutput: int64(0), Output: map[string]interface{}{"a": map[string]interface{}{}}},
   738  		{Script: `len(a)`, Input: map[string]interface{}{"a": map[string]interface{}{"test": "test"}}, RunOutput: int64(1), Output: map[string]interface{}{"a": map[string]interface{}{"test": "test"}}},
   739  		{Script: `len(a["test"])`, Input: map[string]interface{}{"a": map[string]interface{}{"test": "test"}}, RunOutput: int64(4), Output: map[string]interface{}{"a": map[string]interface{}{"test": "test"}}},
   740  
   741  		{Script: `len(a)`, Input: map[string]interface{}{"a": []interface{}{}}, RunOutput: int64(0), Output: map[string]interface{}{"a": []interface{}{}}},
   742  		{Script: `len(a)`, Input: map[string]interface{}{"a": []interface{}{nil}}, RunOutput: int64(1), Output: map[string]interface{}{"a": []interface{}{nil}}},
   743  		{Script: `len(a)`, Input: map[string]interface{}{"a": []interface{}{true}}, RunOutput: int64(1), Output: map[string]interface{}{"a": []interface{}{true}}},
   744  		{Script: `len(a)`, Input: map[string]interface{}{"a": []interface{}{int32(1)}}, RunOutput: int64(1), Output: map[string]interface{}{"a": []interface{}{int32(1)}}},
   745  		{Script: `len(a)`, Input: map[string]interface{}{"a": []interface{}{int64(1)}}, RunOutput: int64(1), Output: map[string]interface{}{"a": []interface{}{int64(1)}}},
   746  		{Script: `len(a)`, Input: map[string]interface{}{"a": []interface{}{float32(1.1)}}, RunOutput: int64(1), Output: map[string]interface{}{"a": []interface{}{float32(1.1)}}},
   747  		{Script: `len(a)`, Input: map[string]interface{}{"a": []interface{}{float64(1.1)}}, RunOutput: int64(1), Output: map[string]interface{}{"a": []interface{}{float64(1.1)}}},
   748  		{Script: `len(a)`, Input: map[string]interface{}{"a": []interface{}{"a"}}, RunOutput: int64(1), Output: map[string]interface{}{"a": []interface{}{"a"}}},
   749  
   750  		{Script: `len(a[0])`, Input: map[string]interface{}{"a": []interface{}{"test"}}, RunOutput: int64(4), Output: map[string]interface{}{"a": []interface{}{"test"}}},
   751  
   752  		{Script: `len(a)`, Input: map[string]interface{}{"a": [][]interface{}{}}, RunOutput: int64(0), Output: map[string]interface{}{"a": [][]interface{}{}}},
   753  		{Script: `len(a)`, Input: map[string]interface{}{"a": [][]interface{}{nil}}, RunOutput: int64(1), Output: map[string]interface{}{"a": [][]interface{}{nil}}},
   754  		{Script: `len(a)`, Input: map[string]interface{}{"a": [][]interface{}{{nil}}}, RunOutput: int64(1), Output: map[string]interface{}{"a": [][]interface{}{{nil}}}},
   755  		{Script: `len(a)`, Input: map[string]interface{}{"a": [][]interface{}{{true}}}, RunOutput: int64(1), Output: map[string]interface{}{"a": [][]interface{}{{true}}}},
   756  		{Script: `len(a)`, Input: map[string]interface{}{"a": [][]interface{}{{int32(1)}}}, RunOutput: int64(1), Output: map[string]interface{}{"a": [][]interface{}{{int32(1)}}}},
   757  		{Script: `len(a)`, Input: map[string]interface{}{"a": [][]interface{}{{int64(1)}}}, RunOutput: int64(1), Output: map[string]interface{}{"a": [][]interface{}{{int64(1)}}}},
   758  		{Script: `len(a)`, Input: map[string]interface{}{"a": [][]interface{}{{float32(1.1)}}}, RunOutput: int64(1), Output: map[string]interface{}{"a": [][]interface{}{{float32(1.1)}}}},
   759  		{Script: `len(a)`, Input: map[string]interface{}{"a": [][]interface{}{{float64(1.1)}}}, RunOutput: int64(1), Output: map[string]interface{}{"a": [][]interface{}{{float64(1.1)}}}},
   760  		{Script: `len(a)`, Input: map[string]interface{}{"a": [][]interface{}{{"a"}}}, RunOutput: int64(1), Output: map[string]interface{}{"a": [][]interface{}{{"a"}}}},
   761  
   762  		{Script: `len(a[0])`, Input: map[string]interface{}{"a": [][]interface{}{nil}}, RunOutput: int64(0), Output: map[string]interface{}{"a": [][]interface{}{nil}}},
   763  		{Script: `len(a[0])`, Input: map[string]interface{}{"a": [][]interface{}{{nil}}}, RunOutput: int64(1), Output: map[string]interface{}{"a": [][]interface{}{{nil}}}},
   764  		{Script: `len(a[0])`, Input: map[string]interface{}{"a": [][]interface{}{{true}}}, RunOutput: int64(1), Output: map[string]interface{}{"a": [][]interface{}{{true}}}},
   765  		{Script: `len(a[0])`, Input: map[string]interface{}{"a": [][]interface{}{{int32(1)}}}, RunOutput: int64(1), Output: map[string]interface{}{"a": [][]interface{}{{int32(1)}}}},
   766  		{Script: `len(a[0])`, Input: map[string]interface{}{"a": [][]interface{}{{int64(1)}}}, RunOutput: int64(1), Output: map[string]interface{}{"a": [][]interface{}{{int64(1)}}}},
   767  		{Script: `len(a[0])`, Input: map[string]interface{}{"a": [][]interface{}{{float32(1.1)}}}, RunOutput: int64(1), Output: map[string]interface{}{"a": [][]interface{}{{float32(1.1)}}}},
   768  		{Script: `len(a[0])`, Input: map[string]interface{}{"a": [][]interface{}{{float64(1.1)}}}, RunOutput: int64(1), Output: map[string]interface{}{"a": [][]interface{}{{float64(1.1)}}}},
   769  		{Script: `len(a[0])`, Input: map[string]interface{}{"a": [][]interface{}{{"a"}}}, RunOutput: int64(1), Output: map[string]interface{}{"a": [][]interface{}{{"a"}}}},
   770  
   771  		{Script: `len(a[0][0])`, Input: map[string]interface{}{"a": [][]interface{}{{"test"}}}, RunOutput: int64(4), Output: map[string]interface{}{"a": [][]interface{}{{"test"}}}},
   772  	}
   773  	runTests(t, tests, nil, &Options{Debug: true})
   774  }
   775  
   776  func TestCallFunctionWithVararg(t *testing.T) {
   777  	t.Parallel()
   778  
   779  	e := env.NewEnv()
   780  	err := e.Define("X", func(args ...string) []string {
   781  		return args
   782  	})
   783  	if err != nil {
   784  		t.Errorf("Define error: %v", err)
   785  	}
   786  	want := []string{"foo", "bar", "baz"}
   787  	err = e.Define("a", want)
   788  	if err != nil {
   789  		t.Errorf("Define error: %v", err)
   790  	}
   791  	got, err := Execute(e, nil, "X(a...)")
   792  	if err != nil {
   793  		t.Errorf("execute error - received %#v - expected: %#v", err, nil)
   794  	}
   795  	if !reflect.DeepEqual(got, want) {
   796  		t.Errorf("execute error - received %#v - expected: %#v", got, want)
   797  	}
   798  }
   799  
   800  func TestGoFunctionConcurrency(t *testing.T) {
   801  	t.Parallel()
   802  
   803  	tests := []Test{
   804  		{Script: `
   805  waitGroup.Add(5);
   806  a = []; b = []; c = []; d = []; e = []
   807  fa = func() { for i = 0; i < 100; i++ { a += 1 }; waitGroup.Done() }
   808  fb = func() { for i = 0; i < 100; i++ { b += 2 }; waitGroup.Done() }
   809  fc = func() { for i = 0; i < 100; i++ { c += 3 }; waitGroup.Done() }
   810  fd = func() { for i = 0; i < 100; i++ { d += 4 }; waitGroup.Done() }
   811  fe = func() { for i = 0; i < 100; i++ { e += 5 }; waitGroup.Done() }
   812  go fa(); go fb(); go fc(); go fd(); go fe()
   813  waitGroup.Wait()`,
   814  			Input: map[string]interface{}{"waitGroup": &sync.WaitGroup{}},
   815  			Output: map[string]interface{}{
   816  				"a": []interface{}{int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1)},
   817  				"b": []interface{}{int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2)},
   818  				"c": []interface{}{int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3)},
   819  				"d": []interface{}{int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4)},
   820  				"e": []interface{}{int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5)},
   821  			}},
   822  		{Script: `
   823  waitGroup.Add(5);
   824  x = [1, 2, 3, 4, 5]
   825  a = []; b = []; c = []; d = []; e = []
   826  fa = func() { for i = 0; i < 100; i++ { a += x[0] }; waitGroup.Done() }
   827  fb = func() { for i = 0; i < 100; i++ { b += x[1] }; waitGroup.Done() }
   828  fc = func() { for i = 0; i < 100; i++ { c += x[2] }; waitGroup.Done() }
   829  fd = func() { for i = 0; i < 100; i++ { d += x[3] }; waitGroup.Done() }
   830  fe = func() { for i = 0; i < 100; i++ { e += x[4] }; waitGroup.Done() }
   831  go fa(); go fb(); go fc(); go fd(); go fe()
   832  waitGroup.Wait()`,
   833  			Input: map[string]interface{}{"waitGroup": &sync.WaitGroup{}},
   834  			Output: map[string]interface{}{
   835  				"a": []interface{}{int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1)},
   836  				"b": []interface{}{int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2)},
   837  				"c": []interface{}{int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3)},
   838  				"d": []interface{}{int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4)},
   839  				"e": []interface{}{int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5)},
   840  			}},
   841  		{Script: `
   842  waitGroup.Add(5);
   843  x = func(y) { return y }
   844  a = []; b = []; c = []; d = []; e = []
   845  fa = func() { for i = 0; i < 100; i++ { a += x(1) }; waitGroup.Done() }
   846  fb = func() { for i = 0; i < 100; i++ { b += x(2) }; waitGroup.Done() }
   847  fc = func() { for i = 0; i < 100; i++ { c += x(3) }; waitGroup.Done() }
   848  fd = func() { for i = 0; i < 100; i++ { d += x(4) }; waitGroup.Done() }
   849  fe = func() { for i = 0; i < 100; i++ { e += x(5) }; waitGroup.Done() }
   850  go fa(); go fb(); go fc(); go fd(); go fe()
   851  waitGroup.Wait()`,
   852  			Input: map[string]interface{}{"waitGroup": &sync.WaitGroup{}},
   853  			Output: map[string]interface{}{
   854  				"a": []interface{}{int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1), int64(1)},
   855  				"b": []interface{}{int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2), int64(2)},
   856  				"c": []interface{}{int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3), int64(3)},
   857  				"d": []interface{}{int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4), int64(4)},
   858  				"e": []interface{}{int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5), int64(5)},
   859  			}},
   860  	}
   861  
   862  	runTests(t, tests, nil, &Options{Debug: true})
   863  }