1
2 #### command sub $(echo hi)
3 var x = $(echo hi)
4 var y = $(echo '')
5 # Make sure we can operate on these values
6 echo x=${x:-default} y=${y:-default}
7 ## STDOUT:
8 x=hi y=default
9 ## END
10
11
12 #### Set $HOME using 'var' (i.e. YSH string var in word evaluator)
13 var HOME = "foo"
14 echo $HOME
15 echo ~
16 ## STDOUT:
17 foo
18 foo
19 ## END
20
21 #### Use shell var in YSH expression
22 x='abc'
23 var length = len(x) # length in BYTES, unlike ${#x}
24 echo $length
25 ## STDOUT:
26 3
27 ## END
28
29 #### Length doesn't apply to BashArray
30 x=(a b c)
31 x[10]=A
32 x[20]=B
33
34 # shell style: length is 5
35 echo shell=${#x[@]}
36
37 shopt --set parse_ysh_expr_sub
38
39 # Length could be 20, but we may change the representation to Dict[int, str]
40 echo ysh=$[len(x)]
41
42 ## status: 3
43 ## STDOUT:
44 shell=5
45 ## END
46
47 #### $[len(x)] inside strings
48 var s = "abc"
49
50 shopt --set parse_ysh_expr_sub
51
52 echo -$[len(s)]-
53
54 # This already has a meaning ...
55 #echo "-$len(x)-"
56 #echo "-${len}(x)-"
57
58 ## STDOUT:
59 -3-
60 ## END
61
62 #### Func with multiple args in multiple contexts
63 shopt --set ysh:upgrade # needed for math.ysh
64
65 source $LIB_YSH/math.ysh
66
67 var x = max(1+2, 3+4)
68 echo $x $[max(1+2, 3+4)]
69
70 ## STDOUT:
71 7 7
72 ## END
73
74
75 #### Trailing Comma in Param list
76 shopt --set ysh:upgrade # needed for math.ysh
77
78 source $LIB_YSH/math.ysh
79
80 var x = max(1+2, 3+4,)
81 echo $x $[max(1+2, 3+4,)]
82
83 ## STDOUT:
84 7 7
85 ## END
86
87 #### nested expr contexts
88 var s = "123"
89
90 shopt --set parse_ysh_expr_sub
91 # lex_mode_e.ShCommand -> Expr -> ShCommand -> Expr
92 var x = $(echo $'len\n' $[len(s)])
93 echo $x
94 ## STDOUT:
95 len 3
96 ## END
97
98
99 # TODO:
100 # - test keyword args
101 # - test splatting *args, **kwargs
102 # - Multiline parsing
103 #
104 # var x = max(
105 # 1+2,
106 # 3+4,
107 # )
108 # echo $x $max(
109 # 1+2,
110 # 3+4,
111 # )
112
113 #### YSH var used with shell arithmetic
114 var w = "3"
115 echo lt=$(( w < 4 ))
116 echo gt=$(( w > 4 ))
117
118 var z = 3
119 echo lt=$(( z < 4 ))
120 echo gt=$(( z > 4 ))
121 ## STDOUT:
122 lt=1
123 gt=0
124 lt=1
125 gt=0
126 ## END
127
128 #### Parse { var x = 42 }
129 shopt -s ysh:upgrade
130 g() { var x = 42 }
131
132 var x = 1
133 f() { var x = 42; setvar x = 43 }
134 f
135 echo x=$x
136 ## STDOUT:
137 x=1
138 ## END
139
140 #### double quoted
141 var foo = "bar"
142 var x = "-$foo-${foo}-${undef:-default}-"
143 echo $x
144 ## STDOUT:
145 -bar-bar-default-
146 ## END
147
148 #### double quoted respects strict_array
149 shopt -s strict:all
150 declare -a a=(one two three)
151 var x = "-${a[@]}-"
152 echo $x
153 ## status: 1
154 ## stdout-json: ""
155
156 #### simple var sub $name $0 $1 $? etc.
157 ( exit 42 )
158 var status = $?
159 echo status=$status
160
161 set -- a b c
162 var one = $1
163 var two = $2
164 echo $one $two
165
166 var named = "$one" # equivalent to 'one'
167 echo named=$named
168
169 ## STDOUT:
170 status=42
171 a b
172 named=a
173 ## END
174
175 #### braced var sub ${x:-default}
176
177 # without double quotes
178
179 var b = ${foo:-default}
180 echo $b
181 var c = ${bar:-"-$b-"}
182 echo $c
183
184 var d = "${bar:-"-$c-"}" # another one
185 echo $d
186
187 ## STDOUT:
188 default
189 -default-
190 --default--
191 ## END
192
193 #### braced var sub respects strict_array
194 set -- a b c
195 var x = ${undef:-"$@"}
196 echo $x
197 shopt -s strict_array
198 setvar x = ${undef:-"$@"}
199 echo $x
200 ## status: 1
201 ## STDOUT:
202 a b c
203 ## END
204
205
206 #### null / true / false
207 shopt -s ysh:upgrade
208 var n = null
209 if (n) {
210 echo yes
211 } else {
212 echo no
213 }
214 var t = true
215 if (t) {
216 echo yes
217 } else {
218 echo no
219 }
220 var f = false
221 if (f) {
222 echo yes
223 } else {
224 echo no
225 }
226 ## STDOUT:
227 no
228 yes
229 no
230 ## END
231
232 #### multiline dict
233
234 # Note: a pair has to be all on one line. We could relax that but there isn't
235 # a strong reason to now.
236
237 var mydict = { a:1,
238 b: 2,
239 }
240
241 shopt --set parse_ysh_expr_sub
242
243 echo mydict=$[len(mydict)]
244 ## STDOUT:
245 mydict=2
246 ## END
247
248 #### multiline array and command sub (only here docs disallowed)
249 var array = %(
250 one
251 two
252 three
253 )
254
255 shopt --set parse_ysh_expr_sub
256
257 echo array=$[len(array)]
258
259 var comsub = $(
260 echo hi
261 echo bye
262 )
263 echo comsub=$[len(comsub)]
264
265 ## STDOUT:
266 array=3
267 comsub=6
268 ## END
269
270 #### obj=>method() - remove?
271 var s = 'hi'
272
273 # TODO: This does a bound method thing we probably don't want
274 var s2 = s=>upper()
275 echo $s2
276 ## STDOUT:
277 HI
278 ## END
279
280 #### s->upper does NOT work, should be s.upper() or =>
281 var s = 'hi'
282 var method = s->upper
283 echo $method
284 ## status: 3
285 ## stdout-json: ""
286
287 #### d.key
288 var d = {name: 'andy'}
289 var x = d.name
290 echo $x
291 ## STDOUT:
292 andy
293 ## END
294
295 #### a ++ b for string/list concatenation
296 shopt -s parse_brace parse_ysh_expr_sub
297
298 var i = 'abc'
299 var j = 'de'
300 var k = i ++ j
301 echo string $k
302
303
304 var a = [1, 2]
305 var b = [3]
306 var c = a ++ b
307 echo list len=$[len(c)]
308
309 echo ---
310
311 try {
312 = 'ab' ++ 3
313 }
314 echo Str Int $[_error.code]
315
316 try {
317 = [1, 2] ++ 3
318 }
319 echo List Int $[_error.code]
320
321 try {
322 = 3 ++ 'ab'
323 }
324 echo Int Str $[_error.code]
325
326 ## STDOUT:
327 string abcde
328 list len=3
329 ---
330 Str Int 3
331 List Int 3
332 Int Str 3
333 ## END
334
335 #### s ~~ glob and s !~~ glob
336 shopt -s ysh:all
337
338 if ('foo.py' ~~ '*.py') {
339 echo yes
340 }
341 if ('foo.py' !~~ '*.sh') {
342 echo no
343 }
344 ## STDOUT:
345 yes
346 no
347 ## END
348
349 #### Type Errors
350 shopt --set parse_brace
351
352 # TODO: It might be nice to get a message
353 try {
354 var x = {} + []
355 }
356 echo $[_error.code]
357
358 try {
359 setvar x = {} + 3
360 }
361 echo $[_error.code]
362
363 try {
364 = 'foo' ++ 3
365 }
366 echo $[_error.code]
367
368 try {
369 = 'foo' ++ 3
370 }
371 echo $[_error.code]
372
373 ## STDOUT:
374 3
375 3
376 3
377 3
378 ## END
379
380
381 #### can't use ++ on integers
382 var x = 12 ++ 3
383 echo $x
384 ## status: 3
385 ## STDOUT:
386 ## END
387
388 #### can't do mystr ++ mylist
389 = ["s"] + "t"
390 ## status: 3
391 ## STDOUT:
392 ## END
393
394
395 #### expression literals
396 var e = ^[1 + 2]
397
398 shopt --set parse_ysh_expr_sub
399
400 echo type=$[type(e)]
401 echo $[io->evalExpr(e)]
402
403 var e = ^[2 < 1]
404 echo $[io->evalExpr(e)]
405
406 var x = 42
407 var e = ^[42 === x and true]
408 echo $[io->evalExpr(e)]
409
410 var mylist = ^[3, 4]
411 pp test_ (io->evalExpr(mylist))
412
413 ## STDOUT:
414 type=Expr
415 3
416 false
417 true
418 (List) [3,4]
419 ## END
420
421 #### No list comprehension in ^[]
422
423 var mylist = ^[x for x in y]
424 pp test_ (io->evalExpr(mylist))
425
426 ## status: 2
427 ## STDOUT:
428 ## END
429
430
431 #### expression literals, evaluation failure
432 var e = ^[1 / 0]
433 call io->evalExpr(e)
434 ## status: 3
435 ## STDOUT:
436 ## END
437
438 #### expression literals, lazy evaluation
439 shopt --set parse_ysh_expr_sub
440
441 var x = 0
442 var e = ^[x]
443
444 setvar x = 1
445 echo result=$[io->evalExpr(e)]
446 ## STDOUT:
447 result=1
448 ## END
449
450 #### expression literals, sugar for strings
451 shopt --set parse_ysh_expr_sub
452
453 var x = 0
454 var e = ^"x is $x"
455
456 setvar x = 1
457 echo result=$[io->evalExpr(e)]
458 ## STDOUT:
459 result=x is 1
460 ## END