OILS / spec / ysh-expr-arith.test.sh View on Github | oils.pub

663 lines, 361 significant
1## oils_failures_allowed: 0
2
3#### Minus operator is left associative
4
5var a = 1 - 0 - 1
6var b = (1 - 0) - 1
7echo a=$a b=$b
8
9var a = 3 - 1 - 2
10var b = (3 - 1) - 2
11echo a=$a b=$b
12
13## STDOUT:
14a=0 b=0
15a=0 b=0
16## END
17
18#### Division operators are left associative
19
20var a = 10 / 4 / 2
21var b = 10 / 4 / 2
22echo a=$a b=$b
23
24var a = 9 // 3 // 3
25var b = (9 // 3) // 3
26echo a=$a b=$b
27
28var a = 11 % 6 % 3
29var b = (11 % 6) % 3
30echo a=$a b=$b
31
32## STDOUT:
33a=1.25 b=1.25
34a=1 b=1
35a=2 b=2
36## END
37
38#### Exponentiation is right associative
39
40var a = 3 ** 2 ** 2
41var b = 3 ** (2 ** 2)
42echo a=$a b=$b
43
44## STDOUT:
45a=81 b=81
46## END
47
48#### Binary operators, with conversions from string
49shopt --set parse_ysh_expr_sub
50
51echo ' i i' $[1 + 2]
52echo 'si i' $['1' + 2]
53echo ' i si' $[1 + '2']
54echo ---
55
56echo ' f f' $[2.5 - 1.5]
57echo 'sf f' $['2.5' - 1.5]
58echo ' f sf' $[2.5 - '1.5']
59echo ---
60
61echo ' i f' $[4 * 1.5]
62echo 'si f' $['4' * 1.5]
63echo ' i sf' $[4 * '1.5']
64echo ---
65
66echo ' f i' $[5.0 / 2]
67echo 'sf i' $['5.0' / 2]
68echo ' f si' $[5.0 / '2']
69
70## STDOUT:
71 i i 3
72si i 3
73 i si 3
74---
75 f f 1.0
76sf f 1.0
77 f sf 1.0
78---
79 i f 6.0
80si f 6.0
81 i sf 6.0
82---
83 f i 2.5
84sf i 2.5
85 f si 2.5
86## END
87
88#### Floating Point Division with /
89
90var i = '1.0' / '0.05'
91
92echo $i
93
94## STDOUT:
9520.0
96## END
97
98
99#### Operations That Convert to Integer: // % **
100shopt -s parse_brace
101
102var m = ' 5 ' // 2
103
104var n = ' 5 ' % 2
105
106var p = ' 5 ' ** 2
107
108write -- $m $n $p
109
110try {
111 var z = 'a' // 3
112}
113echo _status $_status
114
115try {
116 var z = 'z' % 3
117}
118echo _status $_status
119
120## STDOUT:
1212
1221
12325
124_status 3
125_status 3
126## END
127
128#### Division by zero
129shopt -s parse_brace
130
131try {
132 = 42 / 0
133}
134echo "status / is $_status"
135
136try {
137 = 42 // 0
138}
139echo "status // is $_status"
140
141try {
142 = 42 % 0
143}
144echo "status % is $_status"
145
146## STDOUT:
147status / is 3
148status // is 3
149status % is 3
150## END
151
152#### Unary Operations
153
154var a = ~1
155
156var b = -1
157var c = -2.3
158
159var d = not true
160
161
162write -- $a $b $c $d
163
164## STDOUT:
165-2
166-1
167-2.3
168false
169## END
170
171#### Unary plus on integers and floats
172
173var a = +1
174var b = +42
175var c = +2.5
176
177var d = -10
178var e = +d
179
180write -- $a $b $c $e
181
182## STDOUT:
1831
18442
1852.5
186-10
187## END
188
189#### unary plus and minus combined
190
191var a = +-5
192var b = -+5
193var c = +(-3)
194
195write -- $a $b $c
196
197## STDOUT:
198-5
199-5
200-3
201## END
202
203#### unary minus on strings
204json write (-3)
205json write (-'4')
206json write (-'5.5')
207
208# Not accepted
209json write (-'abc')
210
211## status: 3
212## STDOUT:
213-3
214-4
215-5.5
216## END
217
218#### unary plus on strings
219json write (+3)
220json write (+'4')
221json write (+'5.5')
222
223# Not accepted
224json write (+'abc')
225
226## status: 3
227## STDOUT:
2283
2294
2305.5
231## END
232
233#### unary ~ complement on strings
234json write (~0)
235json write (~'1')
236json write (~' 2 ')
237# Not accepted
238json write (~'3.5')
239
240## status: 3
241## STDOUT:
242-1
243-2
244-3
245## END
246
247#### unary ~ doesn't work on bool
248= ~false
249## status: 3
250## STDOUT:
251## END
252
253#### unary ~ doesn't work on float
254= ~1.0
255## status: 3
256## STDOUT:
257## END
258
259#### unary - applied to bool is not allowed
260= ~false
261## status: 3
262## STDOUT:
263## END
264
265#### Big float constants becomes inf and -inf, tiny become 0.0 and -0.0
266
267$SH -c '
268var x = 0.12345
269pp test_ (x)
270'
271echo float=$?
272
273$SH -c '
274# Becomes infinity
275var x = 0.123456789e1234567
276pp test_ (x)
277
278var x = -0.123456789e1234567
279pp test_ (x)
280'
281echo float=$?
282
283$SH -c '
284# Becomes infinity
285var x = 0.123456789e-1234567
286pp test_ (x)
287
288var x = -0.123456789e-1234567
289pp test_ (x)
290'
291echo float=$?
292
293## STDOUT:
294(Float) 0.12345
295float=0
296(Float) INFINITY
297(Float) -INFINITY
298float=0
299(Float) 0.0
300(Float) -0.0
301float=0
302## END
303
304#### Int constants bigger than 64 bits
305
306# Decimal
307$SH -c '
308var x = 1111
309pp test_ (x)
310'
311echo dec=$?
312
313$SH -c '
314var x = 1111_2222_3333_4444_5555_6666
315pp test_ (x)
316'
317echo dec=$?
318
319# Binary
320$SH -c '
321var x = 0b11
322pp test_ (x)
323'
324echo bin=$?
325
326$SH -c '
327var x = 0b1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111
328pp test_ (x)
329'
330echo bin=$?
331
332# Octal
333$SH -c '
334var x = 0o77
335pp test_ (x)
336'
337echo oct=$?
338
339$SH -c '
340var x = 0o1111_2222_3333_4444_5555_6666
341pp test_ (x)
342'
343echo oct=$?
344
345# Hex
346$SH -c '
347var x = 0xff
348pp test_ (x)
349'
350echo hex=$?
351
352$SH -c '
353var x = 0xaaaa_bbbb_cccc_dddd_eeee_ffff
354pp test_ (x)
355'
356echo hex=$?
357
358## STDOUT:
359(Int) 1111
360dec=0
361dec=2
362(Int) 3
363bin=0
364bin=2
365(Int) 63
366oct=0
367oct=2
368(Int) 255
369hex=0
370hex=2
371## END
372
373#### Bit shift by negative number is not allowed
374
375shopt -s ysh:upgrade
376
377pp test_ (1 << 1)
378pp test_ (1 << 0)
379try {
380 pp test_ (1 << -1)
381}
382echo failed $[_error.code]
383echo
384
385pp test_ (16 >> 2)
386pp test_ (16 >> 1)
387pp test_ (16 >> 0)
388try {
389 pp test_ (16 >> -1)
390}
391echo failed $[_error.code]
392
393## STDOUT:
394(Int) 2
395(Int) 1
396failed 3
397
398(Int) 4
399(Int) 8
400(Int) 16
401failed 3
402## END
403
404#### 64-bit operations
405
406shopt -s ysh:upgrade
407
408var i = 1 << 32
409var s = str(i)
410
411echo "i = $i, s = $s"
412
413if (s ~== i) {
414 echo equal
415}
416
417## STDOUT:
418i = 4294967296, s = 4294967296
419equal
420## END
421
422#### 64-bit integer doesn't overflow
423
424# same as spec/arith.test.sh case 38
425
426var a= 1 << 31
427echo $a
428
429var b = a + a
430echo $b
431
432var c = b + a
433echo $c
434
435var x = 1 << 62
436var y = x - 1
437echo "max positive = $[ x + y ]"
438
439#echo "overflow $[ x + x ]"
440
441## STDOUT:
4422147483648
4434294967296
4446442450944
445max positive = 9223372036854775807
446## END
447
448#### Integer literals
449var d = 123
450var b = 0b11
451var o = 0o123
452var h = 0xff
453echo $d $b $o $h
454## STDOUT:
455123 3 83 255
456## END
457
458#### Integer literals with underscores
459const dec = 65_536
460const bin = 0b0001_0101
461const oct = 0o001_755
462const hex = 0x0001_000f
463
464echo SHELL
465echo $dec
466echo $bin
467echo $oct
468echo $hex
469const x = 1_1 + 0b1_1 + 0o1_1 + 0x1_1
470echo sum $x
471
472# This works under Python 3.6, but the continuous build has earlier versions
473if false; then
474 echo ---
475 echo PYTHON
476
477 python3 -c '
478 print(65_536)
479 print(0b0001_0101)
480 print(0o001_755)
481 print(0x0001_000f)
482
483 # Weird syntax
484 print("sum", 1_1 + 0b1_1 + 0o1_1 + 0x1_1)
485 '
486fi
487
488## STDOUT:
489SHELL
49065536
49121
4921005
49365551
494sum 40
495## END
496
497#### Exponentiation with **
498var x = 2**3
499echo $x
500
501var y = 2.0 ** 3.0 # NOT SUPPORTED
502echo 'should not get here'
503
504## status: 3
505## STDOUT:
5068
507## END
508
509#### Float Division
510pp test_ (5/2)
511pp test_ (-5/2)
512pp test_ (5/-2)
513pp test_ (-5/-2)
514
515echo ---
516
517var x = 9
518setvar x /= 2
519pp test_ (x)
520
521var x = -9
522setvar x /= 2
523pp test_ (x)
524
525var x = 9
526setvar x /= -2
527pp test_ (x)
528
529var x = -9
530setvar x /= -2
531pp test_ (x)
532
533
534## STDOUT:
535(Float) 2.5
536(Float) -2.5
537(Float) -2.5
538(Float) 2.5
539---
540(Float) 4.5
541(Float) -4.5
542(Float) -4.5
543(Float) 4.5
544## END
545
546#### Integer Division (rounds toward zero)
547pp test_ (5//2)
548pp test_ (-5//2)
549pp test_ (5//-2)
550pp test_ (-5//-2)
551
552echo ---
553
554var x = 9
555setvar x //= 2
556pp test_ (x)
557
558var x = -9
559setvar x //= 2
560pp test_ (x)
561
562var x = 9
563setvar x //= -2
564pp test_ (x)
565
566var x = -9
567setvar x //= -2
568pp test_ (x)
569
570## STDOUT:
571(Int) 2
572(Int) -2
573(Int) -2
574(Int) 2
575---
576(Int) 4
577(Int) -4
578(Int) -4
579(Int) 4
580## END
581
582#### % operator is remainder
583pp test_ ( 5 % 3)
584pp test_ (-5 % 3)
585
586# negative divisor illegal (tested in test/ysh-runtime-errors.sh)
587#pp test_ ( 5 % -3)
588#pp test_ (-5 % -3)
589
590var z = 10
591setvar z %= 3
592pp test_ (z)
593
594var z = -10
595setvar z %= 3
596pp test_ (z)
597
598## STDOUT:
599(Int) 2
600(Int) -2
601(Int) 1
602(Int) -1
603## END
604
605#### Bitwise logical
606var a = 0b0101 & 0b0011
607echo $a
608var b = 0b0101 | 0b0011
609echo $b
610var c = 0b0101 ^ 0b0011
611echo $c
612var d = ~b
613echo $d
614## STDOUT:
6151
6167
6176
618-8
619## END
620
621#### Shift operators
622var a = 1 << 4
623echo $a
624var b = 16 >> 4
625echo $b
626## STDOUT:
62716
6281
629## END
630
631#### multiline strings, list, tuple syntax for list, etc.
632shopt --set parse_ysh_expr_sub
633
634var dq = "
635dq
6362
637"
638echo dq=$[len(dq)]
639
640var sq = '
641sq
6422
643'
644echo sq=$[len(sq)]
645
646var mylist = [
647 1,
648 2,
649 3,
650]
651echo mylist=$[len(mylist)]
652
653var mytuple = (1,
654 2, 3)
655echo mytuple=$[len(mytuple)]
656
657## STDOUT:
658dq=6
659sq=6
660mylist=3
661mytuple=3
662## END
663