1// helper
2fn sqr(x int) int {
3	return x * x
4}
5
6fn high_fn(f fn(int) int) {
7	x := f(111)
8	println('x == $x')
9}
10
11fn high_fn_no_ret(f fn(int)) {
12	f(111)
13}
14
15fn high_fn_array(f fn(a []int) []int) {
16
17}
18
19fn high_fn_multi_return(a int, b fn (c []int, d []string) ([]int, []string)) {
20
21}
22
23fn high_fn_return_single_anon() (fn(int)f32) {
24	_ = 1
25	correct := fn(n int)f32 {
26		return f32(n * n)
27	}
28	return correct
29}
30fn high_fn_return_multi_anons() (fn(int)f32, fn(int)string) {
31	// parsing trap
32	_ = fn(n int)byte {
33		return 0x00
34	}
35	correct_second := fn(n int)string {
36		return '$n'
37	}
38	correct_first := fn(n int)f32 {
39		return f32(n * n)
40	}
41	// parsing trap
42	_ = fn(n int)[]int {
43		return [n]
44	}
45	return correct_first, correct_second
46}
47fn high_fn_return_named_fn() (fn(int)int) {
48	return sqr
49}
50fn test_high_fn_ret_anons() {
51	param := 13
52	func_sqr1 := high_fn_return_single_anon()
53	assert func_sqr1(param) == param * param
54
55	func_sqr2, func_repr := high_fn_return_multi_anons()
56	assert func_sqr2(param) == (param * param)
57	assert func_repr(param) == '$param'
58
59	top_lvl_sqr := high_fn_return_named_fn()
60	assert top_lvl_sqr(param) == param * param
61}
62
63fn high_fn_applier(arg int, func fn(a int)string) string {
64	return func(arg)
65}
66fn test_high_fn_applier() {
67	arg := 13
68	expect := '$arg $arg'
69	func := fn (arg int) string {
70		return '$arg $arg'
71	}
72	assert expect == high_fn_applier(arg, func)
73}
74
75fn test_fns() {
76	// no asserts for now, just test function declarations above
77	high_fn(sqr)
78}
79
80fn test_anon_fn() {
81	f1 := fn(a int){
82		println('hello from f1')
83	}
84	f1(1)
85
86	f2 := fn(a int) int {
87		println('hello from f2')
88		return 10
89	}
90	f2res := f2(1)
91	println('f2res == $f2res')
92	// TODO/FIXME: assert bug? uncomment to see
93	// assert f2res == 10
94
95	high_fn(fn (x int) int {
96		return x + 1
97	})
98
99	high_fn_no_ret(fn (x int) {
100		println('hello $x')
101	})
102}
103
104fn test_anon_fn_direct_call() {
105	fn(name string) {
106		println('hello $name')
107	}('from anon')
108
109	b := fn(n int) int {
110		return 11+n
111	}(100)
112	assert b == 111
113}
114
115//
116// Test assigning functions (IdentFn)
117//
118
119fn simple_fn1() int {
120	return 1
121}
122
123fn simple_fn2(n f32) (int, string) {
124	return int(1 + n), "fish"
125}
126
127fn test_assigning_fns() {
128	func1 := simple_fn1
129	assert func1() == 1
130
131	func2 := simple_fn2
132	res2_1, res2_2 := func2(13.0)
133	assert res2_1 == 14.0
134	assert res2_2 == "fish"
135
136	anon_func1 := fn(s string)int {
137		return s.len
138	}
139	func3 := anon_func1
140	res3 := func3("fish")
141	assert res3 == 4
142}
143
144//
145// End assigning functions (IdentFn)
146//
147