| 1 | type Any = f64 | int | string |
| 2 | |
| 3 | struct Test {} |
| 4 | |
| 5 | struct Test2 {} |
| 6 | |
| 7 | struct Test3 {} |
| 8 | |
| 9 | fn (t Test) test(args ...Any) { |
| 10 | println('called with ${args}') |
| 11 | } |
| 12 | |
| 13 | fn (t Test2) test_str(arg string) { |
| 14 | println('called with ${arg}') |
| 15 | } |
| 16 | |
| 17 | fn (t Test2) test_int(arg int, arg2 int) { |
| 18 | println('called with ${arg}, ${arg2}') |
| 19 | } |
| 20 | |
| 21 | fn (t Test3) test_int(arg int, arg2 int) { |
| 22 | println('called with ${arg}, ${arg2}') |
| 23 | } |
| 24 | |
| 25 | fn foo_any(i Any, k Any, j Any) string { |
| 26 | return '${i} : ${k} : ${j}' |
| 27 | } |
| 28 | |
| 29 | fn foo(i int, k int) string { |
| 30 | return '${i} : ${k}' |
| 31 | } |
| 32 | |
| 33 | fn bar(i f64, k f64, j f64) string { |
| 34 | return '${i} : ${k} : ${j}' |
| 35 | } |
| 36 | |
| 37 | fn baz(s string) string { |
| 38 | return s |
| 39 | } |
| 40 | |
| 41 | fn f_arr(i int, f f64) string { |
| 42 | return '${i} : ${f}' |
| 43 | } |
| 44 | |
| 45 | fn f_var(s string, args ...string) string { |
| 46 | return '${s} [ ${args.map(it).join(',')} ]' |
| 47 | } |
| 48 | |
| 49 | fn varargs[T](args ...T) string { |
| 50 | assert args.len > 0 |
| 51 | return args.map(it.str()).join(' : ') |
| 52 | } |
| 53 | |
| 54 | fn call[T](func_name string, args ...T) string { |
| 55 | return match func_name { |
| 56 | 'foo' { foo(...args) } |
| 57 | 'bar' { bar(...args) } |
| 58 | 'baz' { baz(...args) } |
| 59 | 'varargs' { varargs(...args) } |
| 60 | else { '' } |
| 61 | } |
| 62 | } |
| 63 | |
| 64 | fn call_any(func_name string, args ...Any) string { |
| 65 | return match func_name { |
| 66 | 'foo_any' { foo_any(...args) } |
| 67 | else { '' } |
| 68 | } |
| 69 | } |
| 70 | |
| 71 | fn comptime_call[T](instance T, method_name string, args ...Any) bool { |
| 72 | $for method in T.methods { |
| 73 | if method.name == method_name { |
| 74 | instance.$method(...args) |
| 75 | return true |
| 76 | } |
| 77 | } |
| 78 | return false |
| 79 | } |
| 80 | |
| 81 | fn comptime_call_vargs[T, R](instance T, method_name string, args ...R) bool { |
| 82 | $for method in T.methods { |
| 83 | if method.name == method_name { |
| 84 | instance.$method(...args) |
| 85 | return true |
| 86 | } |
| 87 | } |
| 88 | return false |
| 89 | } |
| 90 | |
| 91 | fn comptime_call_vargs2[T, R](instance T, method_name string, args ...R) bool { |
| 92 | $for method in T.methods { |
| 93 | if method.name == method_name { |
| 94 | instance.$method(200, ...args) |
| 95 | return true |
| 96 | } |
| 97 | } |
| 98 | return false |
| 99 | } |
| 100 | |
| 101 | fn test_main() { |
| 102 | assert call('foo', 10, 100) == '10 : 100' |
| 103 | assert call('bar', 1.1, 1.2, 1.3) == '1.1 : 1.2 : 1.3' |
| 104 | assert call('baz', 'test') == 'test' |
| 105 | assert call_any('foo_any', 10, 1.2, 'test') == "Any(10) : Any(1.2) : Any('test')" |
| 106 | assert call[Any]('varargs', 10, 1.2, 'test') == "Any(10) : Any(1.2) : Any('test')" |
| 107 | |
| 108 | a := []int{len: 2, init: 50} |
| 109 | assert foo(...a) == '50 : 50' |
| 110 | |
| 111 | b := []f64{len: 3, init: 1.2} |
| 112 | assert bar(...b) == '1.2 : 1.2 : 1.2' |
| 113 | |
| 114 | mut c := []Any{} |
| 115 | c << 10 |
| 116 | c << 1.2 |
| 117 | c << 'test' |
| 118 | assert varargs(...c) == "Any(10) : Any(1.2) : Any('test')" |
| 119 | |
| 120 | var := [0.0] |
| 121 | assert f_arr(1, ...var) == '1 : 0.0' |
| 122 | |
| 123 | var2 := ['a', 'b', 'c'] |
| 124 | assert f_var('foo', ...var2) == 'foo [ a,b,c ]' |
| 125 | } |
| 126 | |
| 127 | fn test_comptime() { |
| 128 | var := Test{} |
| 129 | assert comptime_call(var, 'test', 1, 2.3, '') |
| 130 | |
| 131 | var2 := Test2{} |
| 132 | assert comptime_call_vargs(var2, 'test_int', 1, 100) |
| 133 | assert comptime_call_vargs(var2, 'test_str', 'foo') |
| 134 | |
| 135 | var3 := Test3{} |
| 136 | assert comptime_call_vargs2(var3, 'test_int', 100) |
| 137 | } |
| 138 | |