1 # Oil Functions
2
3 #### Untyped func
4 shopt -s oil:all # parse_tea
5
6 func add(x, y) Int {
7 echo hi
8 return x + y
9 }
10 var result = add(42, 1)
11 echo $result
12 ## STDOUT:
13 hi
14 43
15 ## END
16
17 #### Typed func
18 shopt -s oil:all
19
20 func add(x Int, y Int) Int {
21 echo hi
22 return x+y
23 }
24 var result = add(42, 1)
25 echo $result
26 ## STDOUT:
27 hi
28 43
29 ## END
30
31 #### func: default values for positional params
32 shopt -s oil:all
33 func add(x Int, y=1, z=1+2*3) {
34 return x + y + z
35 }
36 echo $add(3)
37 echo $add(3,4)
38 ## STDOUT:
39 11
40 14
41 ## END
42
43 #### pass too many positional params to func (without spread)
44 shopt -s oil:all
45 func add(x, y) {
46 return x + y
47 }
48 var f = add(1,2)
49 echo f=$f
50 var f = add(1,2,3)
51 echo $f
52 ## status: 1
53 ## STDOUT:
54 f=3
55 ## END
56
57 #### Positional Spread
58 shopt -s oil:all
59 func add(x, y, ...args) {
60 write @args
61 return x + y
62 }
63 var args = @[5 6 7 8]
64 var y = add(...args)
65 echo y=$y
66 ## STDOUT:
67 7
68 8
69 y=11
70 ## END
71
72 #### pass named arg to func
73 shopt -s oil:all
74
75 func f(; x=42) {
76 echo $x
77 }
78 pass f()
79 pass f(x=99)
80 ## STDOUT:
81 42
82 99
83 ## END
84
85 #### Func with missing named param with no default
86 shopt -s oil:all
87 func add(x Int, y Int ; verbose Bool) {
88 if (verbose) {
89 echo 'verbose'
90 }
91 return x + y
92 }
93 var a = add(3, 2, verbose=true)
94 echo $a
95
96 # crashes
97 var a = add(3, 2)
98 echo "shouldn't get here"
99 ## status: 1
100 ## STDOUT:
101 verbose
102 5
103 ## END
104
105 #### Func passed wrong named param
106 shopt -s oil:all
107 func add(x, y) {
108 return x + y
109 }
110 var x = add(2, 3)
111 echo x=$x
112 var y = add(2, 3, verbose=true)
113
114 ## status: 1
115 ## STDOUT:
116 x=5
117 ## END
118
119
120 #### Named Spread
121 shopt -s oil:all
122 func add(x, y; verbose=true, ...named) {
123 if (verbose) { echo 'verbose' }
124 write @named | sort
125 return x + y
126 }
127 var args = {verbose: false, a: 1, b: 2}
128 var args2 = {f: 3}
129 var ret = add(2, 3; ...args, ...args2)
130 echo ret=$ret
131 ## STDOUT:
132 a
133 b
134 f
135 ret=5
136 ## END
137
138 #### Func with varargs
139 shopt -s oil:all
140 func printf(fmt, ...args) {
141 = fmt
142 # Should be a LIST
143 = args
144 }
145 pass printf('foo', 'a', 42, null)
146
147 ## STDOUT:
148 (Str) 'foo'
149 (Tuple) ('a', 42, None)
150 ## END
151
152 #### return expression then return builtin
153 shopt -s parse_tea
154
155 func f(x) {
156 return x + 2*3
157 }
158 # this goes in proc
159 f() {
160 local x=42
161 return $x
162 }
163 var x = f(36)
164 echo x=$x
165 f
166 echo status=$?
167 ## STDOUT:
168 x=42
169 status=42
170 ## END
171
172 #### Open proc (any number of args)
173 proc f {
174 var x = 42
175 return x
176 }
177 # this gets called with 3 args then?
178 f a b c
179 echo status=$?
180 ## STDOUT:
181 status=42
182 ## END
183
184 #### Closed proc with no args, passed too many
185 proc f() {
186 return 42
187 }
188 f
189 echo status=$?
190
191 # TODO: This should abort, or have status 1
192 f a b
193 echo status=$?
194
195 ## status: 1
196 ## STDOUT:
197 status=42
198 ## END
199
200 #### Open proc has "$@"
201 shopt -s oil:all
202 proc foo {
203 write ARGV "$@"
204 }
205 builtin set -- a b c
206 foo x y z
207 ## STDOUT:
208 ARGV
209 x
210 y
211 z
212 ## END
213
214 #### Closed proc doesn't have "$@"
215 shopt -s oil:all
216 proc foo(d, e, f) {
217 write params $d $e $f
218 write ARGV "$@"
219 }
220 builtin set -- a b c
221 foo x y z
222 ## STDOUT:
223 params
224 x
225 y
226 z
227 ARGV
228 ## END
229
230
231 #### Proc with default args
232 proc f(x='foo') {
233 echo x=$x
234 }
235 f
236 ## STDOUT:
237 x=foo
238 ## END
239
240 #### Proc with explicit args
241
242 # doesn't require oil:all
243 proc f(x, y, z) {
244 echo $x $y $z
245 var ret = 42
246 return ret # expression mode
247 }
248 # this gets called with 3 args then?
249 f a b c
250 echo status=$?
251 ## STDOUT:
252 a b c
253 status=42
254 ## END
255
256 #### Proc with varargs
257
258 # TODO: opts goes with this
259 # var opt = grep_opts.parse(ARGV)
260 #
261 # func(**opt) # Assumes keyword args match?
262 # parse :grep_opts :opt @ARGV
263
264 shopt -s oil:all
265
266 proc f(@names) {
267 write names: @names
268 }
269 # this gets called with 3 args then?
270 f a b c
271 echo status=$?
272 ## STDOUT:
273 names:
274 a
275 b
276 c
277 status=0
278 ## END
279
280 #### Proc name-with-hyphen
281 proc name-with-hyphen {
282 echo "$@"
283 }
284 name-with-hyphen x y z
285 ## STDOUT:
286 x y z
287 ## END
288
289 #### Proc with block arg
290
291 # TODO: Test more of this
292 proc f(x, y, &block) {
293 echo hi
294 }
295 f a b
296 ## STDOUT:
297 hi
298 ## END
299
300 #### inline function calls with spread, named args, etc.
301 shopt -s oil:all
302
303 func f(a, b=0, ...args; c, d=0, ...named) {
304 write __ args: @args
305 write __ named:
306 write @named | sort
307 if (named) {
308 return [a, b, c, d]
309 } else {
310 return a + b + c + d
311 }
312 }
313 var a = [42, 43]
314 var n = {x: 99, y: 100}
315
316 echo ____
317 write string $f(0, 1, ...a, c=2, d=3)
318
319 # Now get a list back
320 echo ____
321 write array @f(5, 6, ...a, c=7, d=8; ...n)
322
323 ## STDOUT:
324 ____
325 __
326 args:
327 42
328 43
329 __
330 named:
331
332 string
333 6
334 ____
335 __
336 args:
337 42
338 43
339 __
340 named:
341 x
342 y
343 array
344 5
345 6
346 7
347 8
348 ## END
349
350 #### basic lambda
351 var f = |x| x+1
352 var y = f(0)
353 echo $y
354 echo $f(42)
355 ## STDOUT:
356 1
357 43
358 ## END
359
360 #### proc returning wrong type
361
362 # this should print an error message
363 proc f {
364 var a = @(one two)
365 return a
366 }
367 f
368 ## STDOUT:
369 ## END
370
371 #### proc returning invalid string
372
373 # this should print an error message
374 proc f {
375 var s = 'not an integer status'
376 return s
377 }
378 f
379 ## STDOUT:
380 ## END