1
2 #### Open proc (any number of args)
3 shopt --set parse_proc
4
5 proc f {
6 var x = 42
7 return $x
8 }
9 # this gets called with 3 args then?
10 f a b c
11 echo status=$?
12 ## STDOUT:
13 status=42
14 ## END
15
16 #### Closed proc with no args, passed too many
17 shopt --set parse_proc
18
19 proc f() {
20 return 42
21 }
22 f
23 echo status=$?
24
25 f a b # status 2
26
27 ## status: 3
28 ## STDOUT:
29 status=42
30 ## END
31
32 #### Open proc has "$@"
33 shopt -s oil:all
34 proc foo {
35 write ARGV "$@"
36 }
37 builtin set -- a b c
38 foo x y z
39 ## STDOUT:
40 ARGV
41 x
42 y
43 z
44 ## END
45
46 #### Closed proc doesn't have "$@"
47 shopt -s oil:all
48 proc foo(d, e, f) {
49 write params $d $e $f
50 write ARGV "$@"
51 }
52 builtin set -- a b c
53 foo x y z
54 ## STDOUT:
55 params
56 x
57 y
58 z
59 ARGV
60 ## END
61
62
63 #### Proc with default args
64 shopt --set parse_proc
65
66 proc f(x='foo') {
67 echo x=$x
68 }
69 f
70 ## STDOUT:
71 x=foo
72 ## END
73
74 #### Proc with word params
75 shopt --set parse_proc
76
77 # doesn't require oil:all
78 proc f(x, y, z) {
79 echo $x $y $z
80 var ret = 42
81 return $ret
82 }
83 # this gets called with 3 args then?
84 f a b c
85 echo status=$?
86 ## STDOUT:
87 a b c
88 status=42
89 ## END
90
91 #### Proc with ... "rest" word params
92
93 # TODO: opts goes with this
94 # var opt = grep_opts.parse(ARGV)
95 #
96 # func(**opt) # Assumes keyword args match?
97 # parse :grep_opts :opt @ARGV
98
99 shopt -s oil:all
100
101 proc f(...names) {
102 write names: @names
103 }
104 # this gets called with 3 args then?
105 f a b c
106 echo status=$?
107 ## STDOUT:
108 names:
109 a
110 b
111 c
112 status=0
113 ## END
114
115 #### word rest params 2
116 shopt --set ysh:all
117
118 proc f(first, ...rest) { # @ means "the rest of the arguments"
119 write --sep ' ' -- $first
120 write --sep ' ' -- @rest # @ means "splice this array"
121 }
122 f a b c
123 ## STDOUT:
124 a
125 b c
126 ## END
127
128 #### proc with typed args
129 shopt --set ysh:upgrade
130
131 # TODO: duplicate param names aren't allowed
132 proc p (a; mylist, mydict; opt Int = 42) {
133 json write --pretty=F (a)
134 json write --pretty=F (mylist)
135 json write --pretty=F (mydict)
136 #json write --pretty=F (opt)
137 }
138
139 p WORD ([1,2,3], {name: 'bob'})
140
141 echo ---
142
143 p x (:| a b |, {bob: 42}, a = 5)
144
145 ## STDOUT:
146 "WORD"
147 [1,2,3]
148 {"name":"bob"}
149 ---
150 "x"
151 ["a","b"]
152 {"bob":42}
153 ## END
154
155 #### Proc name-with-hyphen
156 shopt --set parse_proc
157
158 proc name-with-hyphen {
159 echo "$@"
160 }
161 name-with-hyphen x y z
162 ## STDOUT:
163 x y z
164 ## END
165
166 #### Proc with block arg
167 shopt --set ysh:upgrade
168
169 # TODO: Test more of this
170 proc f(x, y ; ; ; block) {
171 echo f word $x $y
172
173 if (block) {
174 eval (block)
175 }
176 }
177 f a b { echo FFF }
178
179 # With varargs and block
180 shopt --set parse_proc
181
182 proc g(x, y, ...rest ; ; ; block) {
183 echo g word $x $y
184 echo g rest @rest
185
186 if (block) {
187 eval (block)
188 }
189 }
190 g a b c d {
191 echo GGG
192 }
193
194 ## STDOUT:
195 f word a b
196 FFF
197 g word a b
198 g rest c d
199 GGG
200 ## END
201
202 #### proc returning wrong type
203 shopt --set parse_proc
204
205 # this should print an error message
206 proc f {
207 var a = %(one two)
208 return $a
209 }
210 f
211 ## status: 3
212 ## STDOUT:
213 ## END
214
215 #### proc returning invalid string
216 shopt --set parse_proc
217
218 # this should print an error message
219 proc f {
220 var s = 'not an integer status'
221 return $s
222 }
223 f
224 ## status: 1
225 ## STDOUT:
226 ## END
227
228 #### 'return' doesn't accept expressions
229 proc p {
230 return 1 + 2
231 }
232 p
233 ## status: 2
234 ## STDOUT:
235 ## END
236
237 #### procs are in same namespace as shell functions
238 shopt --set parse_proc
239
240 myfunc() {
241 echo hi
242 }
243
244 proc myproc {
245 echo hi
246 }
247
248 declare -F
249 ## STDOUT:
250 declare -f myfunc
251 declare -f myproc
252 ## END
253
254
255 #### Nested proc is disallowed at parse time
256 shopt --set parse_proc
257
258 # NOTE: we can disallow this in Oil statically ...
259 proc f {
260 proc g {
261 echo 'G'
262 }
263 g
264 }
265 f
266 g
267 ## status: 2
268 ## stdout-json: ""
269
270 #### Procs defined inside compound statements (with redefine_proc)
271
272 shopt --set oil:upgrade
273 shopt --set redefine_proc_func
274
275 for x in 1 2 {
276 proc p {
277 echo 'loop'
278 }
279 }
280 p
281
282 {
283 proc p {
284 echo 'brace'
285 }
286 }
287 p
288
289 ## STDOUT:
290 loop
291 brace
292 ## END
293