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 |
|