1" Tests for Vim9 script expressions
2
3source check.vim
4source vim9.vim
5
6let g:cond = v:false
7def FuncOne(arg: number): string
8  return 'yes'
9enddef
10def FuncTwo(arg: number): number
11  return 123
12enddef
13
14" test cond ? expr : expr
15def Test_expr1_trinary()
16  assert_equal('one', true ? 'one' : 'two')
17  assert_equal('one', 1 ?
18			'one' :
19			'two')
20  if has('float')
21    assert_equal('one', !!0.1 ? 'one' : 'two')
22  endif
23  assert_equal('one', !!'x' ? 'one' : 'two')
24  assert_equal('one', !!'x'
25  			? 'one'
26			: 'two')
27  assert_equal('one', !!0z1234 ? 'one' : 'two')
28  assert_equal('one', !![0] ? 'one' : 'two')
29  assert_equal('one', !!#{x: 0} ? 'one' : 'two')
30  var name = 1
31  assert_equal('one', name ? 'one' : 'two')
32
33  assert_equal('two', false ? 'one' : 'two')
34  assert_equal('two', 0 ? 'one' : 'two')
35  if has('float')
36    assert_equal('two', !!0.0 ? 'one' : 'two')
37  endif
38  assert_equal('two', !!'' ? 'one' : 'two')
39  assert_equal('two', !!0z ? 'one' : 'two')
40  assert_equal('two', !![] ? 'one' : 'two')
41  assert_equal('two', !!{} ? 'one' : 'two')
42  name = 0
43  assert_equal('two', name ? 'one' : 'two')
44
45  # with constant condition expression is not evaluated
46  assert_equal('one', 1 ? 'one' : xxx)
47
48  var Some: func = function('len')
49  var Other: func = function('winnr')
50  var Res: func = g:atrue ? Some : Other
51  assert_equal(function('len'), Res)
52
53  var RetOne: func(string): number = function('len')
54  var RetTwo: func(string): number = function('winnr')
55  var RetThat: func = g:atrue ? RetOne : RetTwo
56  assert_equal(function('len'), RetThat)
57
58  var X = FuncOne
59  var Y = FuncTwo
60  var Z = g:cond ? FuncOne : FuncTwo
61  assert_equal(123, Z(3))
62enddef
63
64def Test_expr1_trinary_vimscript()
65  # check line continuation
66  var lines =<< trim END
67      vim9script
68      var name = 1
69      		? 'yes'
70		: 'no'
71      assert_equal('yes', name)
72  END
73  CheckScriptSuccess(lines)
74
75  lines =<< trim END
76      vim9script
77      var name = v:false
78      		? 'yes'
79		: 'no'
80      assert_equal('no', name)
81  END
82  CheckScriptSuccess(lines)
83
84  lines =<< trim END
85      vim9script
86      var name = v:false ?
87      		'yes' :
88		'no'
89      assert_equal('no', name)
90  END
91  CheckScriptSuccess(lines)
92
93  lines =<< trim END
94      vim9script
95      var name = v:false ?  # comment
96      		'yes' :
97                # comment
98		'no' # comment
99      assert_equal('no', name)
100  END
101  CheckScriptSuccess(lines)
102
103  # check white space
104  lines =<< trim END
105      vim9script
106      var name = v:true?1:2
107  END
108  CheckScriptFailure(lines, 'E1004:', 2)
109  lines =<< trim END
110      vim9script
111      var name = v:true? 1 : 2
112  END
113  CheckScriptFailure(lines, 'E1004:', 2)
114  lines =<< trim END
115      vim9script
116      var name = v:true ?1 : 2
117  END
118  CheckScriptFailure(lines, 'E1004:', 2)
119  lines =<< trim END
120      vim9script
121      var name = v:true ? 1: 2
122  END
123  CheckScriptFailure(lines, 'E1004:', 2)
124  lines =<< trim END
125      vim9script
126      var name = v:true ? 1 :2
127  END
128  CheckScriptFailure(lines, 'E1004:', 2)
129
130  lines =<< trim END
131      vim9script
132      var name = 'x' ? 1 : 2
133  END
134  CheckScriptFailure(lines, 'E1030:', 2)
135
136  lines =<< trim END
137      vim9script
138      var name = [] ? 1 : 2
139  END
140  CheckScriptFailure(lines, 'E745:', 2)
141
142  lines =<< trim END
143      vim9script
144      var name = {} ? 1 : 2
145  END
146  CheckScriptFailure(lines, 'E728:', 2)
147
148  # check after failure eval_flags is reset
149  lines =<< trim END
150      vim9script
151      try
152        eval('0 ? 1: 2')
153      catch
154      endtry
155      assert_equal(v:true, eval(string(v:true)))
156  END
157  CheckScriptSuccess(lines)
158
159  lines =<< trim END
160      vim9script
161      try
162        eval('0 ? 1 :2')
163      catch
164      endtry
165      assert_equal(v:true, eval(string(v:true)))
166  END
167  CheckScriptSuccess(lines)
168enddef
169
170func Test_expr1_trinary_fails()
171  call CheckDefFailure(["var x = 1 ? 'one'"], "Missing ':' after '?'", 1)
172
173  let msg = "White space required before and after '?'"
174  call CheckDefFailure(["var x = 1? 'one' : 'two'"], msg, 1)
175  call CheckDefFailure(["var x = 1 ?'one' : 'two'"], msg, 1)
176  call CheckDefFailure(["var x = 1?'one' : 'two'"], msg, 1)
177
178  let msg = "White space required before and after ':'"
179  call CheckDefFailure(["var x = 1 ? 'one': 'two'"], msg, 1)
180  call CheckDefFailure(["var x = 1 ? 'one' :'two'"], msg, 1)
181  call CheckDefFailure(["var x = 1 ? 'one':'two'"], msg, 1)
182
183  call CheckDefFailure(["var x = 'x' ? 'one' : 'two'"], 'E1030:', 1)
184  call CheckDefFailure(["var x = 0z1234 ? 'one' : 'two'"], 'E974:', 1)
185  call CheckDefExecFailure(["var x = [] ? 'one' : 'two'"], 'E745:', 1)
186  call CheckDefExecFailure(["var x = {} ? 'one' : 'two'"], 'E728:', 1)
187
188  if has('float')
189    call CheckDefFailure(["var x = 0.1 ? 'one' : 'two'"], 'E805:', 1)
190  endif
191
192  " missing argument detected even when common type is used
193  call CheckDefFailure([
194	\ 'var X = FuncOne',
195	\ 'var Y = FuncTwo',
196	\ 'var Z = g:cond ? FuncOne : FuncTwo',
197	\ 'Z()'], 'E119:', 4)
198endfunc
199
200def Test_expr1_falsy()
201  var lines =<< trim END
202      assert_equal(v:true, v:true ?? 456)
203      assert_equal(123, 123 ?? 456)
204      assert_equal('yes', 'yes' ?? 456)
205      assert_equal([1], [1] ?? 456)
206      assert_equal(#{one: 1}, #{one: 1} ?? 456)
207      if has('float')
208        assert_equal(0.1, 0.1 ?? 456)
209      endif
210
211      assert_equal(456, v:false ?? 456)
212      assert_equal(456, 0 ?? 456)
213      assert_equal(456, '' ?? 456)
214      assert_equal(456, [] ?? 456)
215      assert_equal(456, {} ?? 456)
216      if has('float')
217        assert_equal(456, 0.0 ?? 456)
218      endif
219  END
220  CheckDefAndScriptSuccess(lines)
221
222  var msg = "White space required before and after '??'"
223  call CheckDefFailure(["var x = 1?? 'one' : 'two'"], msg, 1)
224  call CheckDefFailure(["var x = 1 ??'one' : 'two'"], msg, 1)
225  call CheckDefFailure(["var x = 1??'one' : 'two'"], msg, 1)
226enddef
227
228" TODO: define inside test function
229def Record(val: any): any
230  g:vals->add(val)
231  return val
232enddef
233
234" test ||
235def Test_expr2()
236  assert_equal(true, 1 || 0)
237  assert_equal(true, 0 ||
238		    0 ||
239		    1)
240  assert_equal(false, 0 || 0)
241  assert_equal(false, 0
242  		    || 0)
243  assert_equal(false, 0 || false)
244
245  g:vals = []
246  assert_equal(true, Record(1) || Record(3))
247  assert_equal([1], g:vals)
248
249  g:vals = []
250  assert_equal(true, Record(0) || Record(1))
251  assert_equal([0, 1], g:vals)
252
253  g:vals = []
254  assert_equal(true, Record(0)
255		      || Record(1)
256		      || Record(0))
257  assert_equal([0, 1], g:vals)
258
259  g:vals = []
260  assert_equal(false, Record(0) || Record(false) || Record(0))
261  assert_equal([0, false, 0], g:vals)
262enddef
263
264def Test_expr2_vimscript()
265  # check line continuation
266  var lines =<< trim END
267      vim9script
268      var name = 0
269      		|| 1
270      assert_equal(true, name)
271  END
272  CheckScriptSuccess(lines)
273
274  lines =<< trim END
275      vim9script
276      var name = v:false
277      		|| v:true
278      		|| v:false
279      assert_equal(v:true, name)
280  END
281  CheckScriptSuccess(lines)
282
283  lines =<< trim END
284      vim9script
285      var name = v:false ||
286      		v:true ||
287		v:false
288      assert_equal(v:true, name)
289  END
290  CheckScriptSuccess(lines)
291
292  lines =<< trim END
293      vim9script
294      var name = v:false || # comment
295                # comment
296      		v:true ||
297                # comment
298		v:false # comment
299      assert_equal(v:true, name)
300  END
301  CheckScriptSuccess(lines)
302
303  # check white space
304  lines =<< trim END
305      vim9script
306      var name = v:true||v:true
307  END
308  CheckScriptFailure(lines, 'E1004:', 2)
309  lines =<< trim END
310      vim9script
311      var name = v:true ||v:true
312  END
313  CheckScriptFailure(lines, 'E1004:', 2)
314  lines =<< trim END
315      vim9script
316      var name = v:true|| v:true
317  END
318  CheckScriptFailure(lines, 'E1004:', 2)
319
320  # check evaluating to bool
321  lines =<< trim END
322      assert_equal(true, 1 || 0)
323      assert_equal(true, 0 ||
324			0 ||
325			!!7)
326      assert_equal(false, 0 || 0)
327      assert_equal(false, 0
328			|| 0)
329      assert_equal(false, 0 || false)
330
331      g:vals = []
332      assert_equal(true, Record(true) || Record(false))
333      assert_equal([true], g:vals)
334
335      g:vals = []
336      assert_equal(true, Record(0) || Record(true))
337      assert_equal([0, true], g:vals)
338
339      g:vals = []
340      assert_equal(true, Record(0)
341			  || Record(true)
342			  || Record(0))
343      assert_equal([0, true], g:vals)
344
345      g:vals = []
346      assert_equal(false, Record(0) || Record(false) || Record(0))
347      assert_equal([0, false, 0], g:vals)
348  END
349  CheckDefAndScriptSuccess(lines)
350enddef
351
352def Test_expr2_fails()
353  var msg = "White space required before and after '||'"
354  call CheckDefFailure(["var x = 1||2"], msg, 1)
355  call CheckDefFailure(["var x = 1 ||2"], msg, 1)
356  call CheckDefFailure(["var x = 1|| 2"], msg, 1)
357
358  call CheckDefFailure(["var x = 1 || xxx"], 'E1001:', 1)
359
360  # TODO: should fail at compile time
361  call CheckDefExecFailure(["var x = 3 || 7"], 'E1023:', 1)
362  call CheckScriptFailure(["vim9script", "var x = 3 || 7"], 'E1023:', 2)
363  call CheckDefExecFailure(["var x = [] || false"], 'E745:', 1)
364  call CheckScriptFailure(["vim9script", "var x = [] || false"], 'E745:', 2)
365enddef
366
367" test &&
368def Test_expr3()
369  assert_equal(false, 1 && 0)
370  assert_equal(false, 0 &&
371		0 &&
372		1)
373  assert_equal(true, 1
374  		    && true
375		    && 1)
376  assert_equal(false, 0 && 0)
377  assert_equal(false, 0 && false)
378  assert_equal(true, 1 && true)
379
380  g:vals = []
381  assert_equal(true, Record(true) && Record(1))
382  assert_equal([true, 1], g:vals)
383
384  g:vals = []
385  assert_equal(false, Record(0) && Record(1))
386  assert_equal([0], g:vals)
387
388  g:vals = []
389  assert_equal(false, Record(0) && Record(4) && Record(0))
390  assert_equal([0], g:vals)
391
392  g:vals = []
393  assert_equal(false, Record(1) && Record(true) && Record(0))
394  assert_equal([1, true, 0], g:vals)
395
396  g:vals = []
397  assert_equal(false, Record(1) && Record(true) && Record(0))
398  assert_equal([1, true, 0], g:vals)
399enddef
400
401def Test_expr3_vimscript()
402  # check line continuation
403  var lines =<< trim END
404      vim9script
405      var name = 0
406      		&& 1
407      assert_equal(false, name)
408  END
409  CheckScriptSuccess(lines)
410
411  lines =<< trim END
412      vim9script
413      var name = v:true
414      		&& v:true
415      		&& v:true
416      assert_equal(v:true, name)
417  END
418  CheckScriptSuccess(lines)
419
420  lines =<< trim END
421      vim9script
422      var name = v:true &&
423      		v:true &&
424      		v:true
425      assert_equal(v:true, name)
426  END
427  CheckScriptSuccess(lines)
428
429  lines =<< trim END
430      vim9script
431      var name = v:true &&  # comment
432                # comment
433      		v:true &&
434                # comment
435      		v:true
436      assert_equal(v:true, name)
437  END
438  CheckScriptSuccess(lines)
439
440  # check white space
441  lines =<< trim END
442      vim9script
443      var name = v:true&&v:true
444  END
445  CheckScriptFailure(lines, 'E1004:', 2)
446  lines =<< trim END
447      vim9script
448      var name = v:true &&v:true
449  END
450  CheckScriptFailure(lines, 'E1004:', 2)
451  lines =<< trim END
452      vim9script
453      var name = v:true&& v:true
454  END
455  CheckScriptFailure(lines, 'E1004:', 2)
456
457  # check keeping the value
458  lines =<< trim END
459      vim9script
460      assert_equal(false, 1 && 0)
461      assert_equal(false, 0 &&
462		    0 &&
463		    1)
464      assert_equal(true, 1
465			&& true
466			&& 1)
467      assert_equal(false, 0 && 0)
468      assert_equal(false, 0 && false)
469      assert_equal(false, 1 && 0)
470
471      g:vals = []
472      assert_equal(true, Record(1) && Record(true))
473      assert_equal([1, true], g:vals)
474
475      g:vals = []
476      assert_equal(false, Record(0) && Record(1))
477      assert_equal([0], g:vals)
478
479      g:vals = []
480      assert_equal(false, Record(0) && Record(1) && Record(0))
481      assert_equal([0], g:vals)
482
483      g:vals = []
484      assert_equal(false, Record(1) && Record(true) && Record(0))
485      assert_equal([1, true, 0], g:vals)
486  END
487  CheckScriptSuccess(lines)
488enddef
489
490func Test_expr3_fails()
491  let msg = "White space required before and after '&&'"
492  call CheckDefFailure(["var x = 1&&2"], msg, 1)
493  call CheckDefFailure(["var x = 1 &&2"], msg, 1)
494  call CheckDefFailure(["var x = 1&& 2"], msg, 1)
495endfunc
496
497" global variables to use for tests with the "any" type
498let atrue = v:true
499let afalse = v:false
500let anone = v:none
501let anull = v:null
502let anint = 10
503let theone = 1
504let thefour = 4
505if has('float')
506  let afloat = 0.1
507endif
508let astring = 'asdf'
509let ablob = 0z01ab
510let alist = [2, 3, 4]
511let adict = #{aaa: 2, bbb: 8}
512
513" test == comperator
514def Test_expr4_equal()
515  var trueVar = true
516  var falseVar = false
517  assert_equal(true, true == true)
518  assert_equal(false, true ==
519			false)
520  assert_equal(true, true
521			== trueVar)
522  assert_equal(false, true == falseVar)
523  assert_equal(true, true == g:atrue)
524  assert_equal(false, g:atrue == false)
525
526  assert_equal(true, v:none == v:none)
527  assert_equal(false, v:none == v:null)
528  assert_equal(true, g:anone == v:none)
529  assert_equal(false, v:none == g:anull)
530
531  var nr0 = 0
532  var nr61 = 61
533  assert_equal(false, 2 == 0)
534  assert_equal(false, 2 == nr0)
535  assert_equal(true, 61 == 61)
536  assert_equal(true, 61 == nr61)
537  assert_equal(true, g:anint == 10)
538  assert_equal(false, 61 == g:anint)
539
540  if has('float')
541    var ff = 0.3
542    assert_equal(true, ff == 0.3)
543    assert_equal(false, 0.4 == ff)
544    assert_equal(true, 0.1 == g:afloat)
545    assert_equal(false, g:afloat == 0.3)
546
547    ff = 3.0
548    assert_equal(true, ff == 3)
549    assert_equal(true, 3 == ff)
550    ff = 3.1
551    assert_equal(false, ff == 3)
552    assert_equal(false, 3 == ff)
553  endif
554
555  assert_equal(true, 'abc' == 'abc')
556  assert_equal(false, 'xyz' == 'abc')
557  assert_equal(true, g:astring == 'asdf')
558  assert_equal(false, 'xyz' == g:astring)
559
560  assert_equal(false, 'abc' == 'aBc')
561  assert_equal(false, 'abc' ==# 'aBc')
562  assert_equal(true, 'abc' ==? 'aBc')
563
564  assert_equal(false, 'abc' == 'ABC')
565  set ignorecase
566  assert_equal(false, 'abc' == 'ABC')
567  assert_equal(false, 'abc' ==# 'ABC')
568  set noignorecase
569
570  CheckDefFailure(["var x = 'a' == xxx"], 'E1001:', 1)
571  CheckDefExecFailure(['var items: any', 'eval 1', 'eval 2', 'if items == []', 'endif'], 'E691:', 4)
572
573  var bb = 0z3f
574  assert_equal(true, 0z3f == bb)
575  assert_equal(false, bb == 0z4f)
576  assert_equal(true, g:ablob == 0z01ab)
577  assert_equal(false, 0z3f == g:ablob)
578
579  assert_equal(true, [1, 2, 3] == [1, 2, 3])
580  assert_equal(false, [1, 2, 3] == [2, 3, 1])
581  assert_equal(true, [2, 3, 4] == g:alist)
582  assert_equal(false, g:alist == [2, 3, 1])
583  assert_equal(false, [1, 2, 3] == [])
584  assert_equal(false, [1, 2, 3] == ['1', '2', '3'])
585
586  assert_equal(true, #{one: 1, two: 2} == #{one: 1, two: 2})
587  assert_equal(false, #{one: 1, two: 2} == #{one: 2, two: 2})
588  assert_equal(false, #{one: 1, two: 2} == #{two: 2})
589  assert_equal(false, #{one: 1, two: 2} == #{})
590  assert_equal(true, g:adict == #{bbb: 8, aaa: 2})
591  assert_equal(false, #{ccc: 9, aaa: 2} == g:adict)
592
593  assert_equal(true, function('g:Test_expr4_equal') == function('g:Test_expr4_equal'))
594  assert_equal(false, function('g:Test_expr4_equal') == function('g:Test_expr4_is'))
595
596  assert_equal(true, function('g:Test_expr4_equal', [123]) == function('g:Test_expr4_equal', [123]))
597  assert_equal(false, function('g:Test_expr4_equal', [123]) == function('g:Test_expr4_is', [123]))
598  assert_equal(false, function('g:Test_expr4_equal', [123]) == function('g:Test_expr4_equal', [999]))
599
600  var OneFunc: func
601  var TwoFunc: func
602  OneFunc = function('len')
603  TwoFunc = function('len')
604  assert_equal(true, OneFunc('abc') == TwoFunc('123'))
605enddef
606
607" test != comperator
608def Test_expr4_notequal()
609  var trueVar = true
610  var falseVar = false
611  assert_equal(false, true != true)
612  assert_equal(true, true !=
613			false)
614  assert_equal(false, true
615  			!= trueVar)
616  assert_equal(true, true != falseVar)
617  assert_equal(false, true != g:atrue)
618  assert_equal(true, g:atrue != false)
619
620  assert_equal(false, v:none != v:none)
621  assert_equal(true, v:none != v:null)
622  assert_equal(false, g:anone != v:none)
623  assert_equal(true, v:none != g:anull)
624
625  var nr55 = 55
626  var nr0 = 55
627  assert_equal(true, 2 != 0)
628  assert_equal(true, 2 != nr0)
629  assert_equal(false, 55 != 55)
630  assert_equal(false, 55 != nr55)
631  assert_equal(false, g:anint != 10)
632  assert_equal(true, 61 != g:anint)
633
634  if has('float')
635    var ff = 0.3
636    assert_equal(false, 0.3 != ff)
637    assert_equal(true, 0.4 != ff)
638    assert_equal(false, 0.1 != g:afloat)
639    assert_equal(true, g:afloat != 0.3)
640
641    ff = 3.0
642    assert_equal(false, ff != 3)
643    assert_equal(false, 3 != ff)
644    ff = 3.1
645    assert_equal(true, ff != 3)
646    assert_equal(true, 3 != ff)
647  endif
648
649  assert_equal(false, 'abc' != 'abc')
650  assert_equal(true, 'xyz' != 'abc')
651  assert_equal(false, g:astring != 'asdf')
652  assert_equal(true, 'xyz' != g:astring)
653
654  assert_equal(true, 'abc' != 'ABC')
655  set ignorecase
656  assert_equal(true, 'abc' != 'ABC')
657  set noignorecase
658
659  var bb = 0z3f
660  assert_equal(false, 0z3f != bb)
661  assert_equal(true, bb != 0z4f)
662  assert_equal(false, g:ablob != 0z01ab)
663  assert_equal(true, 0z3f != g:ablob)
664
665  assert_equal(false, [1, 2, 3] != [1, 2, 3])
666  assert_equal(true, [1, 2, 3] != [2, 3, 1])
667  assert_equal(false, [2, 3, 4] != g:alist)
668  assert_equal(true, g:alist != [2, 3, 1])
669  assert_equal(true, [1, 2, 3] != [])
670  assert_equal(true, [1, 2, 3] != ['1', '2', '3'])
671
672  assert_equal(false, #{one: 1, two: 2} != #{one: 1, two: 2})
673  assert_equal(true, #{one: 1, two: 2} != #{one: 2, two: 2})
674  assert_equal(true, #{one: 1, two: 2} != #{two: 2})
675  assert_equal(true, #{one: 1, two: 2} != #{})
676  assert_equal(false, g:adict != #{bbb: 8, aaa: 2})
677  assert_equal(true, #{ccc: 9, aaa: 2} != g:adict)
678
679  assert_equal(false, function('g:Test_expr4_equal') != function('g:Test_expr4_equal'))
680  assert_equal(true, function('g:Test_expr4_equal') != function('g:Test_expr4_is'))
681
682  assert_equal(false, function('g:Test_expr4_equal', [123]) != function('g:Test_expr4_equal', [123]))
683  assert_equal(true, function('g:Test_expr4_equal', [123]) != function('g:Test_expr4_is', [123]))
684  assert_equal(true, function('g:Test_expr4_equal', [123]) != function('g:Test_expr4_equal', [999]))
685enddef
686
687" test > comperator
688def Test_expr4_greater()
689  assert_true(2 > 0)
690  assert_true(2 >
691		1)
692  assert_false(2 > 2)
693  assert_false(2 > 3)
694  var nr2 = 2
695  assert_true(nr2 > 0)
696  assert_true(nr2 >
697		1)
698  assert_false(nr2 > 2)
699  assert_false(nr2
700  		    > 3)
701  if has('float')
702    var ff = 2.0
703    assert_true(ff > 0.0)
704    assert_true(ff > 1.0)
705    assert_false(ff > 2.0)
706    assert_false(ff > 3.0)
707  endif
708enddef
709
710" test >= comperator
711def Test_expr4_greaterequal()
712  assert_true(2 >= 0)
713  assert_true(2 >=
714			2)
715  assert_false(2 >= 3)
716  var nr2 = 2
717  assert_true(nr2 >= 0)
718  assert_true(nr2 >= 2)
719  assert_false(nr2 >= 3)
720  if has('float')
721    var ff = 2.0
722    assert_true(ff >= 0.0)
723    assert_true(ff >= 2.0)
724    assert_false(ff >= 3.0)
725  endif
726enddef
727
728" test < comperator
729def Test_expr4_smaller()
730  assert_false(2 < 0)
731  assert_false(2 <
732			2)
733  assert_true(2
734  		< 3)
735  var nr2 = 2
736  assert_false(nr2 < 0)
737  assert_false(nr2 < 2)
738  assert_true(nr2 < 3)
739  if has('float')
740    var ff = 2.0
741    assert_false(ff < 0.0)
742    assert_false(ff < 2.0)
743    assert_true(ff < 3.0)
744  endif
745enddef
746
747" test <= comperator
748def Test_expr4_smallerequal()
749  assert_false(2 <= 0)
750  assert_false(2 <=
751			1)
752  assert_true(2
753  		<= 2)
754  assert_true(2 <= 3)
755  var nr2 = 2
756  assert_false(nr2 <= 0)
757  assert_false(nr2 <= 1)
758  assert_true(nr2 <= 2)
759  assert_true(nr2 <= 3)
760  if has('float')
761    var ff = 2.0
762    assert_false(ff <= 0.0)
763    assert_false(ff <= 1.0)
764    assert_true(ff <= 2.0)
765    assert_true(ff <= 3.0)
766  endif
767enddef
768
769" test =~ comperator
770def Test_expr4_match()
771  assert_equal(false, '2' =~ '0')
772  assert_equal(false, ''
773  			 =~ '0')
774  assert_equal(true, '2' =~
775			'[0-9]')
776enddef
777
778" test !~ comperator
779def Test_expr4_nomatch()
780  assert_equal(true, '2' !~ '0')
781  assert_equal(true, ''
782  			!~ '0')
783  assert_equal(false, '2' !~
784			'[0-9]')
785enddef
786
787" test is comperator
788def Test_expr4_is()
789  var mylist = [2]
790  assert_false(mylist is [2])
791  var other = mylist
792  assert_true(mylist is
793		other)
794
795  var myblob = 0z1234
796  assert_false(myblob
797  			is 0z1234)
798  var otherblob = myblob
799  assert_true(myblob is otherblob)
800enddef
801
802" test isnot comperator
803def Test_expr4_isnot()
804  var mylist = [2]
805  assert_true('2' isnot '0')
806  assert_true(mylist isnot [2])
807  var other = mylist
808  assert_false(mylist isnot
809			other)
810
811  var myblob = 0z1234
812  assert_true(myblob
813  		isnot 0z1234)
814  var otherblob = myblob
815  assert_false(myblob isnot otherblob)
816enddef
817
818def RetVoid()
819  var x = 1
820enddef
821
822def Test_expr4_vim9script()
823  # check line continuation
824  var lines =<< trim END
825      vim9script
826      var name = 0
827      		< 1
828      assert_equal(true, name)
829  END
830  CheckScriptSuccess(lines)
831
832  lines =<< trim END
833      vim9script
834      var name = 123
835                # comment
836      		!= 123
837      assert_equal(false, name)
838  END
839  CheckScriptSuccess(lines)
840
841  lines =<< trim END
842      vim9script
843      var name = 123 ==
844      			123
845      assert_equal(true, name)
846  END
847  CheckScriptSuccess(lines)
848
849  lines =<< trim END
850      vim9script
851      var list = [1, 2, 3]
852      var name = list
853      		is list
854      assert_equal(true, name)
855  END
856  CheckScriptSuccess(lines)
857
858  lines =<< trim END
859      vim9script
860      var list = [1, 2, 3]
861      var name = list # comment
862                 # comment
863      		is list
864      assert_equal(true, name)
865  END
866  CheckScriptSuccess(lines)
867
868  lines =<< trim END
869      vim9script
870      var myblob = 0z1234
871      var name = myblob
872      		isnot 0z11
873      assert_equal(true, name)
874  END
875  CheckScriptSuccess(lines)
876
877  # spot check mismatching types
878  lines =<< trim END
879      vim9script
880      echo '' == 0
881  END
882  CheckScriptFailure(lines, 'E1072:', 2)
883
884  lines =<< trim END
885      vim9script
886      echo v:true > v:false
887  END
888  CheckScriptFailure(lines, 'Cannot compare bool with bool', 2)
889
890  lines =<< trim END
891      vim9script
892      echo 123 is 123
893  END
894  CheckScriptFailure(lines, 'Cannot use "is" with number', 2)
895
896  # check 'ignorecase' not being used
897  lines =<< trim END
898    vim9script
899    set ignorecase
900    assert_equal(false, 'abc' == 'ABC')
901    assert_equal(false, 'abc' ==# 'ABC')
902    assert_equal(true, 'abc' ==? 'ABC')
903
904    assert_equal(true, 'abc' != 'ABC')
905    assert_equal(true, 'abc' !=# 'ABC')
906    assert_equal(false, 'abc' !=? 'ABC')
907
908    assert_equal(false, 'abc' =~ 'ABC')
909    assert_equal(false, 'abc' =~# 'ABC')
910    assert_equal(true, 'abc' =~? 'ABC')
911    set noignorecase
912  END
913  CheckScriptSuccess(lines)
914
915  # check missing white space
916  lines =<< trim END
917    vim9script
918    echo 2>3
919  END
920  CheckScriptFailure(lines, 'E1004:', 2)
921  lines =<< trim END
922    vim9script
923    echo 2 >3
924  END
925  CheckScriptFailure(lines, 'E1004:', 2)
926  lines =<< trim END
927    vim9script
928    echo 2> 3
929  END
930  CheckScriptFailure(lines, 'E1004:', 2)
931  lines =<< trim END
932    vim9script
933    echo 2!=3
934  END
935  CheckScriptFailure(lines, 'E1004:', 2)
936  lines =<< trim END
937    vim9script
938    echo 2 !=3
939  END
940  CheckScriptFailure(lines, 'E1004:', 2)
941  lines =<< trim END
942    vim9script
943    echo 2!= 3
944  END
945  CheckScriptFailure(lines, 'E1004:', 2)
946
947  lines =<< trim END
948    vim9script
949    echo len('xxx') == 3
950  END
951  CheckScriptSuccess(lines)
952
953  lines =<< trim END
954    vim9script
955    var line = 'abc'
956    echo line[1] =~ '\w'
957  END
958  CheckScriptSuccess(lines)
959enddef
960
961func Test_expr4_fails()
962  let msg = "White space required before and after '>'"
963  call CheckDefFailure(["var x = 1>2"], msg, 1)
964  call CheckDefFailure(["var x = 1 >2"], msg, 1)
965  call CheckDefFailure(["var x = 1> 2"], msg, 1)
966
967  let msg = "White space required before and after '=='"
968  call CheckDefFailure(["var x = 1==2"], msg, 1)
969  call CheckDefFailure(["var x = 1 ==2"], msg, 1)
970  call CheckDefFailure(["var x = 1== 2"], msg, 1)
971
972  let msg = "White space required before and after 'is'"
973  call CheckDefFailure(["var x = '1'is'2'"], msg, 1)
974  call CheckDefFailure(["var x = '1' is'2'"], msg, 1)
975  call CheckDefFailure(["var x = '1'is '2'"], msg, 1)
976
977  let msg = "White space required before and after 'isnot'"
978  call CheckDefFailure(["var x = '1'isnot'2'"], msg, 1)
979  call CheckDefFailure(["var x = '1' isnot'2'"], msg, 1)
980  call CheckDefFailure(["var x = '1'isnot '2'"], msg, 1)
981
982  call CheckDefFailure(["var x = 1 is# 2"], 'E15:', 1)
983  call CheckDefFailure(["var x = 1 is? 2"], 'E15:', 1)
984  call CheckDefFailure(["var x = 1 isnot# 2"], 'E15:', 1)
985  call CheckDefFailure(["var x = 1 isnot? 2"], 'E15:', 1)
986
987  call CheckDefFailure(["var x = 1 == '2'"], 'Cannot compare number with string', 1)
988  call CheckDefFailure(["var x = '1' == 2"], 'Cannot compare string with number', 1)
989  call CheckDefFailure(["var x = 1 == RetVoid()"], 'Cannot compare number with void', 1)
990  call CheckDefFailure(["var x = RetVoid() == 1"], 'Cannot compare void with number', 1)
991
992  call CheckDefFailure(["var x = true > false"], 'Cannot compare bool with bool', 1)
993  call CheckDefFailure(["var x = true >= false"], 'Cannot compare bool with bool', 1)
994  call CheckDefFailure(["var x = true < false"], 'Cannot compare bool with bool', 1)
995  call CheckDefFailure(["var x = true <= false"], 'Cannot compare bool with bool', 1)
996  call CheckDefFailure(["var x = true =~ false"], 'Cannot compare bool with bool', 1)
997  call CheckDefFailure(["var x = true !~ false"], 'Cannot compare bool with bool', 1)
998  call CheckDefFailure(["var x = true is false"], 'Cannot use "is" with bool', 1)
999  call CheckDefFailure(["var x = true isnot false"], 'Cannot use "isnot" with bool', 1)
1000
1001  call CheckDefFailure(["var x = v:none is v:null"], 'Cannot use "is" with special', 1)
1002  call CheckDefFailure(["var x = v:none isnot v:null"], 'Cannot use "isnot" with special', 1)
1003  call CheckDefFailure(["var x = 123 is 123"], 'Cannot use "is" with number', 1)
1004  call CheckDefFailure(["var x = 123 isnot 123"], 'Cannot use "isnot" with number', 1)
1005  if has('float')
1006    call CheckDefFailure(["var x = 1.3 is 1.3"], 'Cannot use "is" with float', 1)
1007    call CheckDefFailure(["var x = 1.3 isnot 1.3"], 'Cannot use "isnot" with float', 1)
1008  endif
1009
1010  call CheckDefFailure(["var x = 0za1 > 0z34"], 'Cannot compare blob with blob', 1)
1011  call CheckDefFailure(["var x = 0za1 >= 0z34"], 'Cannot compare blob with blob', 1)
1012  call CheckDefFailure(["var x = 0za1 < 0z34"], 'Cannot compare blob with blob', 1)
1013  call CheckDefFailure(["var x = 0za1 <= 0z34"], 'Cannot compare blob with blob', 1)
1014  call CheckDefFailure(["var x = 0za1 =~ 0z34"], 'Cannot compare blob with blob', 1)
1015  call CheckDefFailure(["var x = 0za1 !~ 0z34"], 'Cannot compare blob with blob', 1)
1016
1017  call CheckDefFailure(["var x = [13] > [88]"], 'Cannot compare list with list', 1)
1018  call CheckDefFailure(["var x = [13] >= [88]"], 'Cannot compare list with list', 1)
1019  call CheckDefFailure(["var x = [13] < [88]"], 'Cannot compare list with list', 1)
1020  call CheckDefFailure(["var x = [13] <= [88]"], 'Cannot compare list with list', 1)
1021  call CheckDefFailure(["var x = [13] =~ [88]"], 'Cannot compare list with list', 1)
1022  call CheckDefFailure(["var x = [13] !~ [88]"], 'Cannot compare list with list', 1)
1023
1024  call CheckDefFailure(['var j: job', 'var chan: channel', 'var r = j == chan'], 'Cannot compare job with channel', 3)
1025  call CheckDefFailure(['var j: job', 'var x: list<any>', 'var r = j == x'], 'Cannot compare job with list', 3)
1026  call CheckDefFailure(['var j: job', 'var Xx: func', 'var r = j == Xx'], 'Cannot compare job with func', 3)
1027  call CheckDefFailure(['var j: job', 'var Xx: func', 'var r = j == Xx'], 'Cannot compare job with func', 3)
1028endfunc
1029
1030" test addition, subtraction, concatenation
1031def Test_expr5()
1032  assert_equal(66, 60 + 6)
1033  assert_equal(70, 60 +
1034			g:anint)
1035  assert_equal(9, g:thefour
1036  			+ 5)
1037  assert_equal(14, g:thefour + g:anint)
1038  assert_equal([1, 2, 3, 4], [1] + g:alist)
1039
1040  assert_equal(54, 60 - 6)
1041  assert_equal(50, 60 -
1042		    g:anint)
1043  assert_equal(-1, g:thefour
1044  			- 5)
1045  assert_equal(-6, g:thefour - g:anint)
1046
1047  assert_equal('hello', 'hel' .. 'lo')
1048  assert_equal('hello 123', 'hello ' ..
1049					123)
1050  assert_equal('hello 123', 'hello '
1051  				..  123)
1052  assert_equal('123 hello', 123 .. ' hello')
1053  assert_equal('123456', 123 .. 456)
1054
1055  assert_equal('av:true', 'a' .. true)
1056  assert_equal('av:false', 'a' .. false)
1057  assert_equal('av:null', 'a' .. v:null)
1058  assert_equal('av:none', 'a' .. v:none)
1059  if has('float')
1060    assert_equal('a0.123', 'a' .. 0.123)
1061  endif
1062
1063  assert_equal([1, 2, 3, 4], [1, 2] + [3, 4])
1064  assert_equal(0z11223344, 0z1122 + 0z3344)
1065  assert_equal(0z112201ab, 0z1122
1066  				+ g:ablob)
1067  assert_equal(0z01ab3344, g:ablob + 0z3344)
1068  assert_equal(0z01ab01ab, g:ablob + g:ablob)
1069
1070  # concatenate non-constant to constant
1071  var save_path = &path
1072  &path = 'b'
1073  assert_equal('ab', 'a' .. &path)
1074  &path = save_path
1075
1076  @b = 'b'
1077  assert_equal('ab', 'a' .. @b)
1078
1079  $ENVVAR = 'env'
1080  assert_equal('aenv', 'a' .. $ENVVAR)
1081enddef
1082
1083def Test_expr5_vim9script()
1084  # check line continuation
1085  var lines =<< trim END
1086      vim9script
1087      var name = 11
1088      		+ 77
1089		- 22
1090      assert_equal(66, name)
1091  END
1092  CheckScriptSuccess(lines)
1093
1094  lines =<< trim END
1095      vim9script
1096      var name = 11 +
1097		  77 -
1098		  22
1099      assert_equal(66, name)
1100  END
1101  CheckScriptSuccess(lines)
1102
1103  lines =<< trim END
1104      vim9script
1105      var name = 11 +  # comment
1106		  77 -
1107                  # comment
1108		  22
1109      assert_equal(66, name)
1110  END
1111  CheckScriptSuccess(lines)
1112
1113  lines =<< trim END
1114      vim9script
1115      var name = 'one'
1116      		.. 'two'
1117      assert_equal('onetwo', name)
1118  END
1119  CheckScriptSuccess(lines)
1120
1121  lines =<< trim END
1122      vim9script
1123      echo 'abc' is# 'abc'
1124  END
1125  CheckScriptFailure(lines, 'E15:', 2)
1126
1127  lines =<< trim END
1128      vim9script
1129      echo 'abc' is? 'abc'
1130  END
1131  CheckScriptFailure(lines, 'E15:', 2)
1132
1133  lines =<< trim END
1134      vim9script
1135      echo 'abc' isnot# 'abc'
1136  END
1137  CheckScriptFailure(lines, 'E15:', 2)
1138
1139  lines =<< trim END
1140      vim9script
1141      echo 'abc' isnot? 'abc'
1142  END
1143  CheckScriptFailure(lines, 'E15:', 2)
1144
1145  # check white space
1146  lines =<< trim END
1147      vim9script
1148      echo 5+6
1149  END
1150  CheckScriptFailure(lines, 'E1004:', 2)
1151  lines =<< trim END
1152      vim9script
1153      echo 5 +6
1154  END
1155  CheckScriptFailure(lines, 'E1004:', 2)
1156  lines =<< trim END
1157      vim9script
1158      echo 5+ 6
1159  END
1160  CheckScriptFailure(lines, 'E1004:', 2)
1161
1162  lines =<< trim END
1163      vim9script
1164      echo 'a'..'b'
1165  END
1166  CheckScriptFailure(lines, 'E1004:', 2)
1167  lines =<< trim END
1168      vim9script
1169      echo 'a' ..'b'
1170  END
1171  CheckScriptFailure(lines, 'E1004:', 2)
1172  lines =<< trim END
1173      vim9script
1174      echo 'a'.. 'b'
1175  END
1176  CheckScriptFailure(lines, 'E1004:', 2)
1177
1178  # check valid string concatenation
1179  lines =<< trim END
1180      vim9script
1181      assert_equal('one123', 'one' .. 123)
1182      assert_equal('onev:true', 'one' .. true)
1183      assert_equal('onev:null', 'one' .. v:null)
1184      assert_equal('onev:none', 'one' .. v:none)
1185      if has('float')
1186        assert_equal('a0.123', 'a' .. 0.123)
1187      endif
1188  END
1189  CheckScriptSuccess(lines)
1190
1191  # check invalid string concatenation
1192  lines =<< trim END
1193      vim9script
1194      echo 'a' .. [1]
1195  END
1196  CheckScriptFailure(lines, 'E730:', 2)
1197  lines =<< trim END
1198      vim9script
1199      echo 'a' .. #{a: 1}
1200  END
1201  CheckScriptFailure(lines, 'E731:', 2)
1202  lines =<< trim END
1203      vim9script
1204      echo 'a' .. test_void()
1205  END
1206  CheckScriptFailure(lines, 'E908:', 2)
1207  lines =<< trim END
1208      vim9script
1209      echo 'a' .. 0z33
1210  END
1211  CheckScriptFailure(lines, 'E976:', 2)
1212  lines =<< trim END
1213      vim9script
1214      echo 'a' .. function('len')
1215  END
1216  CheckScriptFailure(lines, 'E729:', 2)
1217enddef
1218
1219def Test_expr5_vim9script_channel()
1220  if !has('channel')
1221    MissingFeature 'float'
1222  else
1223    var lines =<< trim END
1224        vim9script
1225        echo 'a' .. test_null_job()
1226    END
1227    CheckScriptFailure(lines, 'E908:', 2)
1228    lines =<< trim END
1229        vim9script
1230        echo 'a' .. test_null_channel()
1231    END
1232    CheckScriptFailure(lines, 'E908:', 2)
1233  endif
1234enddef
1235
1236def Test_expr5_float()
1237  if !has('float')
1238    MissingFeature 'float'
1239  else
1240    assert_equal(66.0, 60.0 + 6.0)
1241    assert_equal(66.0, 60.0 + 6)
1242    assert_equal(66.0, 60 +
1243			 6.0)
1244    assert_equal(5.1, g:afloat
1245    			+ 5)
1246    assert_equal(8.1, 8 + g:afloat)
1247    assert_equal(10.1, g:anint + g:afloat)
1248    assert_equal(10.1, g:afloat + g:anint)
1249
1250    assert_equal(54.0, 60.0 - 6.0)
1251    assert_equal(54.0, 60.0
1252    			    - 6)
1253    assert_equal(54.0, 60 - 6.0)
1254    assert_equal(-4.9, g:afloat - 5)
1255    assert_equal(7.9, 8 - g:afloat)
1256    assert_equal(9.9, g:anint - g:afloat)
1257    assert_equal(-9.9, g:afloat - g:anint)
1258  endif
1259enddef
1260
1261func Test_expr5_fails()
1262  let msg = "White space required before and after '+'"
1263  call CheckDefFailure(["var x = 1+2"], msg, 1)
1264  call CheckDefFailure(["var x = 1 +2"], msg, 1)
1265  call CheckDefFailure(["var x = 1+ 2"], msg, 1)
1266
1267  let msg = "White space required before and after '-'"
1268  call CheckDefFailure(["var x = 1-2"], msg, 1)
1269  call CheckDefFailure(["var x = 1 -2"], msg, 1)
1270  call CheckDefFailure(["var x = 1- 2"], msg, 1)
1271
1272  let msg = "White space required before and after '..'"
1273  call CheckDefFailure(["var x = '1'..'2'"], msg, 1)
1274  call CheckDefFailure(["var x = '1' ..'2'"], msg, 1)
1275  call CheckDefFailure(["var x = '1'.. '2'"], msg, 1)
1276
1277  call CheckDefFailure(["var x = 0z1122 + 33"], 'E1051', 1)
1278  call CheckDefFailure(["var x = 0z1122 + [3]"], 'E1051', 1)
1279  call CheckDefFailure(["var x = 0z1122 + 'asd'"], 'E1051', 1)
1280  call CheckDefFailure(["var x = 33 + 0z1122"], 'E1051', 1)
1281  call CheckDefFailure(["var x = [3] + 0z1122"], 'E1051', 1)
1282  call CheckDefFailure(["var x = 'asdf' + 0z1122"], 'E1051', 1)
1283  call CheckDefFailure(["var x = 6 + xxx"], 'E1001', 1)
1284
1285  call CheckDefFailure(["var x = 'a' .. [1]"], 'E1105', 1)
1286  call CheckDefFailure(["var x = 'a' .. #{a: 1}"], 'E1105', 1)
1287  call CheckDefFailure(["var x = 'a' .. test_void()"], 'E1105', 1)
1288  call CheckDefFailure(["var x = 'a' .. 0z32"], 'E1105', 1)
1289  call CheckDefFailure(["var x = 'a' .. function('len')"], 'E1105', 1)
1290  call CheckDefFailure(["var x = 'a' .. function('len', ['a'])"], 'E1105', 1)
1291endfunc
1292
1293func Test_expr5_fails_channel()
1294  CheckFeature channel
1295  call CheckDefFailure(["var x = 'a' .. test_null_job()"], 'E1105', 1)
1296  call CheckDefFailure(["var x = 'a' .. test_null_channel()"], 'E1105', 1)
1297endfunc
1298
1299" test multiply, divide, modulo
1300def Test_expr6()
1301  assert_equal(36, 6 * 6)
1302  assert_equal(24, 6 *
1303			g:thefour)
1304  assert_equal(24, g:thefour
1305  			* 6)
1306  assert_equal(40, g:anint * g:thefour)
1307
1308  assert_equal(10, 60 / 6)
1309  assert_equal(6, 60 /
1310			g:anint)
1311  assert_equal(1, g:anint / 6)
1312  assert_equal(2, g:anint
1313  			/ g:thefour)
1314
1315  assert_equal(5, 11 % 6)
1316  assert_equal(4, g:anint % 6)
1317  assert_equal(3, 13 %
1318			g:anint)
1319  assert_equal(2, g:anint
1320  			% g:thefour)
1321
1322  assert_equal(4, 6 * 4 / 6)
1323
1324  var x = [2]
1325  var y = [3]
1326  assert_equal(5, x[0] + y[0])
1327  assert_equal(6, x[0] * y[0])
1328  if has('float')
1329    var xf = [2.0]
1330    var yf = [3.0]
1331    assert_equal(5.0, xf[0]
1332    			+ yf[0])
1333    assert_equal(6.0, xf[0]
1334    			* yf[0])
1335  endif
1336
1337  CheckDefFailure(["var x = 6 * xxx"], 'E1001', 1)
1338enddef
1339
1340def Test_expr6_vim9script()
1341  # check line continuation
1342  var lines =<< trim END
1343      vim9script
1344      var name = 11
1345      		* 22
1346		/ 3
1347      assert_equal(80, name)
1348  END
1349  CheckScriptSuccess(lines)
1350
1351  lines =<< trim END
1352      vim9script
1353      var name = 25
1354      		% 10
1355      assert_equal(5, name)
1356  END
1357  CheckScriptSuccess(lines)
1358
1359  lines =<< trim END
1360      vim9script
1361      var name = 25
1362                # comment
1363
1364                # comment
1365      		% 10
1366      assert_equal(5, name)
1367  END
1368  CheckScriptSuccess(lines)
1369
1370  lines =<< trim END
1371      vim9script
1372      var name = 11 *
1373      		22 /
1374		3
1375      assert_equal(80, name)
1376  END
1377  CheckScriptSuccess(lines)
1378
1379  # check white space
1380  lines =<< trim END
1381      vim9script
1382      echo 5*6
1383  END
1384  CheckScriptFailure(lines, 'E1004:', 2)
1385  lines =<< trim END
1386      vim9script
1387      echo 5 *6
1388  END
1389  CheckScriptFailure(lines, 'E1004:', 2)
1390  lines =<< trim END
1391      vim9script
1392      echo 5* 6
1393  END
1394  CheckScriptFailure(lines, 'E1004:', 2)
1395enddef
1396
1397def Test_expr6_float()
1398  if !has('float')
1399    MissingFeature 'float'
1400  else
1401    assert_equal(36.0, 6.0 * 6)
1402    assert_equal(36.0, 6 *
1403			   6.0)
1404    assert_equal(36.0, 6.0 * 6.0)
1405    assert_equal(1.0, g:afloat * g:anint)
1406
1407    assert_equal(10.0, 60 / 6.0)
1408    assert_equal(10.0, 60.0 /
1409			6)
1410    assert_equal(10.0, 60.0 / 6.0)
1411    assert_equal(0.01, g:afloat / g:anint)
1412
1413    assert_equal(4.0, 6.0 * 4 / 6)
1414    assert_equal(4.0, 6 *
1415			4.0 /
1416			6)
1417    assert_equal(4.0, 6 * 4 / 6.0)
1418    assert_equal(4.0, 6.0 * 4.0 / 6)
1419    assert_equal(4.0, 6 * 4.0 / 6.0)
1420    assert_equal(4.0, 6.0 * 4 / 6.0)
1421    assert_equal(4.0, 6.0 * 4.0 / 6.0)
1422
1423    assert_equal(4.0, 6.0 * 4.0 / 6.0)
1424  endif
1425enddef
1426
1427func Test_expr6_fails()
1428  let msg = "White space required before and after '*'"
1429  call CheckDefFailure(["var x = 1*2"], msg, 1)
1430  call CheckDefFailure(["var x = 1 *2"], msg, 1)
1431  call CheckDefFailure(["var x = 1* 2"], msg, 1)
1432
1433  let msg = "White space required before and after '/'"
1434  call CheckDefFailure(["var x = 1/2"], msg, 1)
1435  call CheckDefFailure(["var x = 1 /2"], msg, 1)
1436  call CheckDefFailure(["var x = 1/ 2"], msg, 1)
1437
1438  let msg = "White space required before and after '%'"
1439  call CheckDefFailure(["var x = 1%2"], msg, 1)
1440  call CheckDefFailure(["var x = 1 %2"], msg, 1)
1441  call CheckDefFailure(["var x = 1% 2"], msg, 1)
1442
1443  call CheckDefFailure(["var x = '1' * '2'"], 'E1036:', 1)
1444  call CheckDefFailure(["var x = '1' / '2'"], 'E1036:', 1)
1445  call CheckDefFailure(["var x = '1' % '2'"], 'E1035:', 1)
1446
1447  call CheckDefFailure(["var x = 0z01 * 0z12"], 'E1036:', 1)
1448  call CheckDefFailure(["var x = 0z01 / 0z12"], 'E1036:', 1)
1449  call CheckDefFailure(["var x = 0z01 % 0z12"], 'E1035:', 1)
1450
1451  call CheckDefFailure(["var x = [1] * [2]"], 'E1036:', 1)
1452  call CheckDefFailure(["var x = [1] / [2]"], 'E1036:', 1)
1453  call CheckDefFailure(["var x = [1] % [2]"], 'E1035:', 1)
1454
1455  call CheckDefFailure(["var x = #{one: 1} * #{two: 2}"], 'E1036:', 1)
1456  call CheckDefFailure(["var x = #{one: 1} / #{two: 2}"], 'E1036:', 1)
1457  call CheckDefFailure(["var x = #{one: 1} % #{two: 2}"], 'E1035:', 1)
1458
1459  call CheckDefFailure(["var x = 0xff[1]"], 'E1107:', 1)
1460  if has('float')
1461    call CheckDefFailure(["var x = 0.7[1]"], 'E1107:', 1)
1462  endif
1463endfunc
1464
1465func Test_expr6_float_fails()
1466  CheckFeature float
1467  call CheckDefFailure(["var x = 1.0 % 2"], 'E1035:', 1)
1468endfunc
1469
1470" define here to use old style parsing
1471if has('float')
1472  let g:float_zero = 0.0
1473  let g:float_neg = -9.8
1474  let g:float_big = 9.9e99
1475endif
1476let g:blob_empty = 0z
1477let g:blob_one = 0z01
1478let g:blob_long = 0z0102.0304
1479
1480let g:string_empty = ''
1481let g:string_short = 'x'
1482let g:string_long = 'abcdefghijklm'
1483let g:string_special = "ab\ncd\ref\ekk"
1484
1485let g:special_true = v:true
1486let g:special_false = v:false
1487let g:special_null = v:null
1488let g:special_none = v:none
1489
1490let g:list_empty = []
1491let g:list_mixed = [1, 'b', v:false]
1492
1493let g:dict_empty = {}
1494let g:dict_one = #{one: 1}
1495
1496let $TESTVAR = 'testvar'
1497
1498" type casts
1499def Test_expr7t()
1500  var ls: list<string> = ['a', <string>g:string_empty]
1501  var ln: list<number> = [<number>g:anint, <number>g:thefour]
1502  var nr = <number>234
1503  assert_equal(234, nr)
1504
1505  CheckDefFailure(["var x = <nr>123"], 'E1010:', 1)
1506  CheckDefFailure(["var x = <number >123"], 'E1068:', 1)
1507  CheckDefFailure(["var x = <number 123"], 'E1104:', 1)
1508enddef
1509
1510" test low level expression
1511def Test_expr7_number()
1512  # number constant
1513  assert_equal(0, 0)
1514  assert_equal(654, 0654)
1515
1516  assert_equal(6, 0x6)
1517  assert_equal(15, 0xf)
1518  assert_equal(255, 0xff)
1519enddef
1520
1521def Test_expr7_float()
1522  # float constant
1523  if !has('float')
1524    MissingFeature 'float'
1525  else
1526    assert_equal(g:float_zero, .0)
1527    assert_equal(g:float_zero, 0.0)
1528    assert_equal(g:float_neg, -9.8)
1529    assert_equal(g:float_big, 9.9e99)
1530  endif
1531enddef
1532
1533def Test_expr7_blob()
1534  # blob constant
1535  assert_equal(g:blob_empty, 0z)
1536  assert_equal(g:blob_one, 0z01)
1537  assert_equal(g:blob_long, 0z0102.0304)
1538
1539  CheckDefFailure(["var x = 0z123"], 'E973:', 1)
1540enddef
1541
1542def Test_expr7_string()
1543  # string constant
1544  assert_equal(g:string_empty, '')
1545  assert_equal(g:string_empty, "")
1546  assert_equal(g:string_short, 'x')
1547  assert_equal(g:string_short, "x")
1548  assert_equal(g:string_long, 'abcdefghijklm')
1549  assert_equal(g:string_long, "abcdefghijklm")
1550  assert_equal(g:string_special, "ab\ncd\ref\ekk")
1551
1552  CheckDefFailure(['var x = "abc'], 'E114:', 1)
1553  CheckDefFailure(["var x = 'abc"], 'E115:', 1)
1554enddef
1555
1556def Test_expr7_vimvar()
1557  var old: list<string> = v:oldfiles
1558  var compl: dict<any> = v:completed_item
1559
1560  CheckDefFailure(["var old: list<number> = v:oldfiles"], 'E1012: Type mismatch; expected list<number> but got list<string>', 1)
1561  new
1562  exec "normal! afoo fo\<C-N>\<Esc>"
1563  CheckDefExecFailure(["var old: dict<number> = v:completed_item"], 'E1012: Type mismatch; expected dict<number> but got dict<string>', 1)
1564  bwipe!
1565enddef
1566
1567def Test_expr7_special()
1568  # special constant
1569  assert_equal(g:special_true, true)
1570  assert_equal(g:special_false, false)
1571  assert_equal(g:special_true, v:true)
1572  assert_equal(g:special_false, v:false)
1573
1574  assert_equal(true, !false)
1575  assert_equal(false, !true)
1576  assert_equal(true, !0)
1577  assert_equal(false, !1)
1578  assert_equal(false, !!false)
1579  assert_equal(true, !!true)
1580  assert_equal(false, !!0)
1581  assert_equal(true, !!1)
1582
1583  assert_equal(g:special_null, v:null)
1584  assert_equal(g:special_none, v:none)
1585
1586  CheckDefFailure(['v:true = true'], 'E46:', 1)
1587  CheckDefFailure(['v:true = false'], 'E46:', 1)
1588  CheckDefFailure(['v:false = true'], 'E46:', 1)
1589  CheckDefFailure(['v:null = 11'], 'E46:', 1)
1590  CheckDefFailure(['v:none = 22'], 'E46:', 1)
1591enddef
1592
1593def Test_expr7_special_vim9script()
1594  var lines =<< trim END
1595      vim9script
1596      var t = true
1597      var f = false
1598      assert_equal(v:true, true)
1599      assert_equal(true, t)
1600      assert_equal(v:false, false)
1601      assert_equal(false, f)
1602      assert_equal(true, !false)
1603      assert_equal(false, !true)
1604      assert_equal(true, !0)
1605      assert_equal(false, !1)
1606      assert_equal(false, !!false)
1607      assert_equal(true, !!true)
1608      assert_equal(false, !!0)
1609      assert_equal(true, !!1)
1610  END
1611  CheckScriptSuccess(lines)
1612enddef
1613
1614def Test_expr7_list()
1615  # list
1616  assert_equal(g:list_empty, [])
1617  assert_equal(g:list_empty, [  ])
1618
1619  var numbers: list<number> = [1, 2, 3]
1620  numbers = [1]
1621  numbers = []
1622
1623  var strings: list<string> = ['a', 'b', 'c']
1624  strings = ['x']
1625  strings = []
1626
1627  var mixed: list<any> = [1, 'b', false,]
1628  assert_equal(g:list_mixed, mixed)
1629  assert_equal('b', mixed[1])
1630
1631  echo [1,
1632  	2] [3,
1633		4]
1634
1635  var llstring: list<list<string>> = [['text'], []]
1636  llstring = [[], ['text']]
1637  llstring = [[], []]
1638
1639  var rangelist: list<number> = range(3)
1640  g:rangelist = range(3)
1641  CheckDefExecFailure(["var x: list<string> = g:rangelist"], 'E1012: Type mismatch; expected list<string> but got list<number>', 1)
1642
1643  CheckDefFailure(["var x = 1234[3]"], 'E1107:', 1)
1644  CheckDefExecFailure(["var x = g:anint[3]"], 'E1062:', 1)
1645
1646  CheckDefFailure(["var x = g:list_mixed[xxx]"], 'E1001:', 1)
1647
1648  CheckDefFailure(["var x = [1,2,3]"], 'E1069:', 1)
1649  CheckDefFailure(["var x = [1 ,2, 3]"], 'E1068:', 1)
1650
1651  CheckDefExecFailure(["echo 1", "var x = [][0]", "echo 3"], 'E684:', 2)
1652
1653  CheckDefExecFailure(["var x = g:list_mixed['xx']"], 'E1012:', 1)
1654  CheckDefFailure(["var x = g:list_mixed["], 'E1097:', 2)
1655  CheckDefFailure(["var x = g:list_mixed[0"], 'E1097:', 2)
1656  CheckDefExecFailure(["var x = g:list_empty[3]"], 'E684:', 1)
1657  CheckDefExecFailure(["var l: list<number> = [234, 'x']"], 'E1012:', 1)
1658  CheckDefExecFailure(["var l: list<number> = ['x', 234]"], 'E1012:', 1)
1659  CheckDefExecFailure(["var l: list<string> = [234, 'x']"], 'E1012:', 1)
1660  CheckDefExecFailure(["var l: list<string> = ['x', 123]"], 'E1012:', 1)
1661
1662  var lines =<< trim END
1663      vim9script
1664      var datalist: list<string>
1665      def Main()
1666        datalist += ['x'.
1667      enddef
1668      Main()
1669  END
1670  CheckScriptFailure(lines, 'E1127:')
1671enddef
1672
1673def Test_expr7_list_vim9script()
1674  var lines =<< trim END
1675      vim9script
1676      var l = [
1677		11,
1678		22,
1679		]
1680      assert_equal([11, 22], l)
1681
1682      echo [1,
1683	    2] [3,
1684		    4]
1685
1686      echo [1, # comment
1687            # comment
1688	    2] [3,
1689            # comment
1690		    4]
1691  END
1692  CheckScriptSuccess(lines)
1693
1694  lines =<< trim END
1695      vim9script
1696      var l = [11,
1697		22]
1698      assert_equal([11, 22], l)
1699  END
1700  CheckScriptSuccess(lines)
1701
1702  lines =<< trim END
1703      vim9script
1704      var l = [11,22]
1705  END
1706  CheckScriptFailure(lines, 'E1069:', 2)
1707
1708  lines =<< trim END
1709      vim9script
1710      var l = [11 , 22]
1711  END
1712  CheckScriptFailure(lines, 'E1068:', 2)
1713
1714  lines =<< trim END
1715    vim9script
1716    var l: list<number> = [234, 'x']
1717  END
1718  CheckScriptFailure(lines, 'E1012:', 2)
1719  lines =<< trim END
1720    vim9script
1721    var l: list<number> = ['x', 234]
1722  END
1723  CheckScriptFailure(lines, 'E1012:', 2)
1724  lines =<< trim END
1725    vim9script
1726    var l: list<string> = ['x', 234]
1727  END
1728  CheckScriptFailure(lines, 'E1012:', 2)
1729  lines =<< trim END
1730    vim9script
1731    var l: list<string> = [234, 'x']
1732  END
1733  CheckScriptFailure(lines, 'E1012:', 2)
1734enddef
1735
1736def LambdaWithComments(): func
1737  return {x ->
1738            # some comment
1739            x == 1
1740            # some comment
1741            ||
1742            x == 2
1743        }
1744enddef
1745
1746def LambdaUsingArg(x: number): func
1747  return {->
1748            # some comment
1749            x == 1
1750            # some comment
1751            ||
1752            x == 2
1753        }
1754enddef
1755
1756def Test_expr7_lambda()
1757  var La = { -> 'result'}
1758  assert_equal('result', La())
1759  assert_equal([1, 3, 5], [1, 2, 3]->map({key, val -> key + val}))
1760
1761  # line continuation inside lambda with "cond ? expr : expr" works
1762  var ll = range(3)
1763  map(ll, {k, v -> v % 2 ? {
1764	    '111': 111 } : {}
1765	})
1766  assert_equal([{}, {'111': 111}, {}], ll)
1767
1768  ll = range(3)
1769  map(ll, {k, v -> v == 8 || v
1770		== 9
1771		|| v % 2 ? 111 : 222
1772	})
1773  assert_equal([222, 111, 222], ll)
1774
1775  ll = range(3)
1776  map(ll, {k, v -> v != 8 && v
1777		!= 9
1778		&& v % 2 == 0 ? 111 : 222
1779	})
1780  assert_equal([111, 222, 111], ll)
1781
1782  var dl = [{'key': 0}, {'key': 22}]->filter({ _, v -> v['key'] })
1783  assert_equal([{'key': 22}], dl)
1784
1785  dl = [{'key': 12}, {'foo': 34}]
1786  assert_equal([{'key': 12}], filter(dl,
1787	{_, v -> has_key(v, 'key') ? v['key'] == 12 : 0}))
1788
1789  assert_equal(false, LambdaWithComments()(0))
1790  assert_equal(true, LambdaWithComments()(1))
1791  assert_equal(true, LambdaWithComments()(2))
1792  assert_equal(false, LambdaWithComments()(3))
1793
1794  assert_equal(false, LambdaUsingArg(0)())
1795  assert_equal(true, LambdaUsingArg(1)())
1796
1797  CheckDefFailure(["filter([1, 2], {k,v -> 1})"], 'E1069:', 1)
1798  # error is in first line of the lambda
1799  CheckDefFailure(["var L = {a -> a + b}"], 'E1001:', 0)
1800
1801  assert_equal('xxxyyy', 'xxx'->{a, b -> a .. b}('yyy'))
1802
1803  CheckDefExecFailure(["var s = 'asdf'->{a -> a}('x')"],
1804        'E1106: One argument too many')
1805  CheckDefExecFailure(["var s = 'asdf'->{a -> a}('x', 'y')"],
1806        'E1106: 2 arguments too many')
1807  CheckDefFailure(["echo 'asdf'->{a -> a}(x)"], 'E1001:', 1)
1808
1809  CheckDefSuccess(['var Fx = {a -> #{k1: 0,', ' k2: 1}}'])
1810  CheckDefFailure(['var Fx = {a -> #{k1: 0', ' k2: 1}}'], 'E722:', 2)
1811  CheckDefFailure(['var Fx = {a -> #{k1: 0,', ' k2 1}}'], 'E720:', 2)
1812
1813  CheckDefSuccess(['var Fx = {a -> [0,', ' 1]}'])
1814  CheckDefFailure(['var Fx = {a -> [0', ' 1]}'], 'E696:', 2)
1815enddef
1816
1817def Test_expr7_lambda_vim9script()
1818  var lines =<< trim END
1819      vim9script
1820      var v = 10->{a ->
1821	    a
1822	      + 2
1823	  }()
1824      assert_equal(12, v)
1825  END
1826  CheckScriptSuccess(lines)
1827
1828  # nested lambda with line breaks
1829  lines =<< trim END
1830      vim9script
1831      search('"', 'cW', 0, 0, {->
1832	synstack('.', col('.'))
1833	->map({_, v -> synIDattr(v, 'name')})->len()})
1834  END
1835  CheckScriptSuccess(lines)
1836enddef
1837
1838def Test_epxr7_funcref()
1839  var lines =<< trim END
1840    def RetNumber(): number
1841      return 123
1842    enddef
1843    var FuncRef = RetNumber
1844    assert_equal(123, FuncRef())
1845  END
1846  CheckDefAndScriptSuccess(lines)
1847enddef
1848
1849def Test_expr7_dict()
1850  # dictionary
1851  assert_equal(g:dict_empty, {})
1852  assert_equal(g:dict_empty, {  })
1853  assert_equal(g:dict_one, {'one': 1})
1854  var key = 'one'
1855  var val = 1
1856  assert_equal(g:dict_one, {key: val})
1857
1858  var numbers: dict<number> = #{a: 1, b: 2, c: 3}
1859  numbers = #{a: 1}
1860  numbers = #{}
1861
1862  var strings: dict<string> = #{a: 'a', b: 'b', c: 'c'}
1863  strings = #{a: 'x'}
1864  strings = #{}
1865
1866  var mixed: dict<any> = #{a: 'a', b: 42}
1867  mixed = #{a: 'x'}
1868  mixed = #{a: 234}
1869  mixed = #{}
1870
1871  var dictlist: dict<list<string>> = #{absent: [], present: ['hi']}
1872  dictlist = #{absent: ['hi'], present: []}
1873  dictlist = #{absent: [], present: []}
1874
1875  var dictdict: dict<dict<string>> = #{one: #{a: 'text'}, two: #{}}
1876  dictdict = #{one: #{}, two: #{a: 'text'}}
1877  dictdict = #{one: #{}, two: #{}}
1878
1879  CheckDefFailure(["var x = #{a:8}"], 'E1069:', 1)
1880  CheckDefFailure(["var x = #{a : 8}"], 'E1068:', 1)
1881  CheckDefFailure(["var x = #{a :8}"], 'E1068:', 1)
1882  CheckDefFailure(["var x = #{a: 8 , b: 9}"], 'E1068:', 1)
1883  CheckDefFailure(["var x = #{a: 1,b: 2}"], 'E1069:', 1)
1884
1885  CheckDefFailure(["var x = #{8: 8}"], 'E1014:', 1)
1886  CheckDefFailure(["var x = #{xxx}"], 'E720:', 1)
1887  CheckDefFailure(["var x = #{xxx: 1", "var y = 2"], 'E722:', 2)
1888  CheckDefFailure(["var x = #{xxx: 1,"], 'E723:', 2)
1889  CheckDefFailure(["var x = {'a': xxx}"], 'E1001:', 1)
1890  CheckDefFailure(["var x = {xxx: 8}"], 'E1001:', 1)
1891  CheckDefFailure(["var x = #{a: 1, a: 2}"], 'E721:', 1)
1892  CheckDefFailure(["var x = #"], 'E1015:', 1)
1893  CheckDefExecFailure(["var x = g:anint.member"], 'E715:', 1)
1894  CheckDefExecFailure(["var x = g:dict_empty.member"], 'E716:', 1)
1895
1896  CheckDefExecFailure(['var x: dict<number> = #{a: 234, b: "1"}'], 'E1012:', 1)
1897  CheckDefExecFailure(['var x: dict<number> = #{a: "x", b: 134}'], 'E1012:', 1)
1898  CheckDefExecFailure(['var x: dict<string> = #{a: 234, b: "1"}'], 'E1012:', 1)
1899  CheckDefExecFailure(['var x: dict<string> = #{a: "x", b: 134}'], 'E1012:', 1)
1900
1901  CheckDefFailure(['var x = ({'], 'E723:', 2)
1902enddef
1903
1904def Test_expr7_dict_vim9script()
1905  var lines =<< trim END
1906      vim9script
1907      var d = {
1908		'one':
1909		   1,
1910		'two': 2,
1911		   }
1912      assert_equal({'one': 1, 'two': 2}, d)
1913
1914      d = {  # comment
1915		'one':
1916                # comment
1917
1918		   1,
1919                # comment
1920                # comment
1921		'two': 2,
1922		   }
1923      assert_equal({'one': 1, 'two': 2}, d)
1924  END
1925  CheckScriptSuccess(lines)
1926
1927  lines =<< trim END
1928      vim9script
1929      var d = { "one": "one", "two": "two", }
1930      assert_equal({'one': 'one', 'two': 'two'}, d)
1931  END
1932  CheckScriptSuccess(lines)
1933
1934  lines =<< trim END
1935      vim9script
1936      var d = #{one: 1,
1937		two: 2,
1938	       }
1939      assert_equal({'one': 1, 'two': 2}, d)
1940  END
1941  CheckScriptSuccess(lines)
1942
1943  lines =<< trim END
1944      vim9script
1945      var d = #{one:1, two: 2}
1946  END
1947  CheckScriptFailure(lines, 'E1069:', 2)
1948
1949  lines =<< trim END
1950      vim9script
1951      var d = #{one: 1,two: 2}
1952  END
1953  CheckScriptFailure(lines, 'E1069:', 2)
1954
1955  lines =<< trim END
1956      vim9script
1957      var d = #{one : 1}
1958  END
1959  CheckScriptFailure(lines, 'E1068:', 2)
1960
1961  lines =<< trim END
1962      vim9script
1963      var d = #{one:1}
1964  END
1965  CheckScriptFailure(lines, 'E1069:', 2)
1966
1967  lines =<< trim END
1968      vim9script
1969      var d = #{one: 1 , two: 2}
1970  END
1971  CheckScriptFailure(lines, 'E1068:', 2)
1972
1973  lines =<< trim END
1974    vim9script
1975    var l: dict<number> = #{a: 234, b: 'x'}
1976  END
1977  CheckScriptFailure(lines, 'E1012:', 2)
1978  lines =<< trim END
1979    vim9script
1980    var l: dict<number> = #{a: 'x', b: 234}
1981  END
1982  CheckScriptFailure(lines, 'E1012:', 2)
1983  lines =<< trim END
1984    vim9script
1985    var l: dict<string> = #{a: 'x', b: 234}
1986  END
1987  CheckScriptFailure(lines, 'E1012:', 2)
1988  lines =<< trim END
1989    vim9script
1990    var l: dict<string> = #{a: 234, b: 'x'}
1991  END
1992  CheckScriptFailure(lines, 'E1012:', 2)
1993enddef
1994
1995let g:oneString = 'one'
1996
1997def Test_expr_member()
1998  assert_equal(1, g:dict_one.one)
1999  var d: dict<number> = g:dict_one
2000  assert_equal(1, d['one'])
2001  assert_equal(1, d[
2002		  'one'
2003		  ])
2004  assert_equal(1, d
2005  	.one)
2006  d = {'1': 1, '_': 2}
2007  assert_equal(1, d
2008  	.1)
2009  assert_equal(2, d
2010  	._)
2011
2012  # getting the one member should clear the dict after getting the item
2013  assert_equal('one', #{one: 'one'}.one)
2014  assert_equal('one', #{one: 'one'}[g:oneString])
2015
2016  CheckDefFailure(["var x = g:dict_one.#$!"], 'E1002:', 1)
2017  CheckDefExecFailure(["var d: dict<any>", "echo d['a']"], 'E716:', 2)
2018  CheckDefExecFailure(["var d: dict<number>", "d = g:list_empty"], 'E1012: Type mismatch; expected dict<number> but got list<unknown>', 2)
2019enddef
2020
2021def Test_expr7_any_index_slice()
2022  var lines =<< trim END
2023    # getting the one member should clear the list only after getting the item
2024    assert_equal('bbb', ['aaa', 'bbb', 'ccc'][1])
2025
2026    # string is permissive, index out of range accepted
2027    g:teststring = 'abcdef'
2028    assert_equal('b', g:teststring[1])
2029    assert_equal('', g:teststring[-1])
2030    assert_equal('', g:teststring[99])
2031
2032    assert_equal('b', g:teststring[1:1])
2033    assert_equal('bcdef', g:teststring[1:])
2034    assert_equal('abcd', g:teststring[:3])
2035    assert_equal('cdef', g:teststring[-4:])
2036    assert_equal('abcdef', g:teststring[-9:])
2037    assert_equal('abcd', g:teststring[:-3])
2038    assert_equal('', g:teststring[:-9])
2039
2040    # blob index cannot be out of range
2041    g:testblob = 0z01ab
2042    assert_equal(0x01, g:testblob[0])
2043    assert_equal(0xab, g:testblob[1])
2044    assert_equal(0xab, g:testblob[-1])
2045    assert_equal(0x01, g:testblob[-2])
2046
2047    # blob slice accepts out of range
2048    assert_equal(0z01ab, g:testblob[0:1])
2049    assert_equal(0z01, g:testblob[0:0])
2050    assert_equal(0z01, g:testblob[-2:-2])
2051    assert_equal(0zab, g:testblob[1:1])
2052    assert_equal(0zab, g:testblob[-1:-1])
2053    assert_equal(0z, g:testblob[2:2])
2054    assert_equal(0z, g:testblob[0:-3])
2055
2056    # list index cannot be out of range
2057    g:testlist = [0, 1, 2, 3]
2058    assert_equal(0, g:testlist[0])
2059    assert_equal(1, g:testlist[1])
2060    assert_equal(3, g:testlist[3])
2061    assert_equal(3, g:testlist[-1])
2062    assert_equal(0, g:testlist[-4])
2063    assert_equal(1, g:testlist[g:theone])
2064
2065    # list slice accepts out of range
2066    assert_equal([0], g:testlist[0:0])
2067    assert_equal([3], g:testlist[3:3])
2068    assert_equal([0, 1], g:testlist[0:1])
2069    assert_equal([0, 1, 2, 3], g:testlist[0:3])
2070    assert_equal([0, 1, 2, 3], g:testlist[0:9])
2071    assert_equal([], g:testlist[-1:1])
2072    assert_equal([1], g:testlist[-3:1])
2073    assert_equal([0, 1], g:testlist[-4:1])
2074    assert_equal([0, 1], g:testlist[-9:1])
2075    assert_equal([1, 2, 3], g:testlist[1:-1])
2076    assert_equal([1], g:testlist[1:-3])
2077    assert_equal([], g:testlist[1:-4])
2078    assert_equal([], g:testlist[1:-9])
2079
2080    g:testdict = #{a: 1, b: 2}
2081    assert_equal(1, g:testdict['a'])
2082    assert_equal(2, g:testdict['b'])
2083  END
2084
2085  CheckDefSuccess(lines)
2086  CheckScriptSuccess(['vim9script'] + lines)
2087
2088  CheckDefExecFailure(['echo g:testblob[2]'], 'E979:', 1)
2089  CheckScriptFailure(['vim9script', 'echo g:testblob[2]'], 'E979:', 2)
2090  CheckDefExecFailure(['echo g:testblob[-3]'], 'E979:', 1)
2091  CheckScriptFailure(['vim9script', 'echo g:testblob[-3]'], 'E979:', 2)
2092
2093  CheckDefExecFailure(['echo g:testlist[4]'], 'E684:', 1)
2094  CheckScriptFailure(['vim9script', 'echo g:testlist[4]'], 'E684:', 2)
2095  CheckDefExecFailure(['echo g:testlist[-5]'], 'E684:', 1)
2096  CheckScriptFailure(['vim9script', 'echo g:testlist[-5]'], 'E684:', 2)
2097
2098  CheckDefExecFailure(['echo g:testdict["a":"b"]'], 'E719:', 1)
2099  CheckScriptFailure(['vim9script', 'echo g:testdict["a":"b"]'], 'E719:', 2)
2100  CheckDefExecFailure(['echo g:testdict[1]'], 'E716:', 1)
2101  CheckScriptFailure(['vim9script', 'echo g:testdict[1]'], 'E716:', 2)
2102
2103  unlet g:teststring
2104  unlet g:testblob
2105  unlet g:testlist
2106enddef
2107
2108def Test_expr_member_vim9script()
2109  var lines =<< trim END
2110      vim9script
2111      var d = #{one:
2112      		'one',
2113		two: 'two',
2114		1: 1,
2115		_: 2}
2116      assert_equal('one', d.one)
2117      assert_equal('one', d
2118                            .one)
2119      assert_equal(1, d
2120                            .1)
2121      assert_equal(2, d
2122                            ._)
2123      assert_equal('one', d[
2124			    'one'
2125			    ])
2126  END
2127  CheckScriptSuccess(lines)
2128
2129  lines =<< trim END
2130      vim9script
2131      var l = [1,
2132		  2,
2133		  3, 4
2134		  ]
2135      assert_equal(2, l[
2136			    1
2137			    ])
2138      assert_equal([2, 3], l[1 : 2])
2139      assert_equal([1, 2, 3], l[
2140				:
2141				2
2142				])
2143      assert_equal([3, 4], l[
2144				2
2145				:
2146				])
2147  END
2148  CheckScriptSuccess(lines)
2149enddef
2150
2151def Test_expr7_option()
2152  # option
2153  set ts=11
2154  assert_equal(11, &ts)
2155  &ts = 9
2156  assert_equal(9, &ts)
2157  set ts=8
2158  set grepprg=some\ text
2159  assert_equal('some text', &grepprg)
2160  &grepprg = test_null_string()
2161  assert_equal('', &grepprg)
2162  set grepprg&
2163enddef
2164
2165def Test_expr7_environment()
2166  # environment variable
2167  assert_equal('testvar', $TESTVAR)
2168  assert_equal('', $ASDF_ASD_XXX)
2169
2170  CheckDefFailure(["var x = $$$"], 'E1002:', 1)
2171enddef
2172
2173def Test_expr7_register()
2174  @a = 'register a'
2175  assert_equal('register a', @a)
2176
2177  var fname = expand('%')
2178  assert_equal(fname, @%)
2179
2180  feedkeys(":echo 'some'\<CR>", "xt")
2181  assert_equal("echo 'some'", @:)
2182
2183  normal axyz
2184  assert_equal("xyz", @.)
2185  CheckDefFailure(["@. = 'yes'"], 'E354:', 1)
2186
2187  @/ = 'slash'
2188  assert_equal('slash', @/)
2189
2190  @= = 'equal'
2191  assert_equal('equal', @=)
2192enddef
2193
2194def Test_expr7_namespace()
2195  g:some_var = 'some'
2196  assert_equal('some', get(g:, 'some_var'))
2197  assert_equal('some', get(g:, 'some_var', 'xxx'))
2198  assert_equal('xxx', get(g:, 'no_var', 'xxx'))
2199  unlet g:some_var
2200
2201  b:some_var = 'some'
2202  assert_equal('some', get(b:, 'some_var'))
2203  assert_equal('some', get(b:, 'some_var', 'xxx'))
2204  assert_equal('xxx', get(b:, 'no_var', 'xxx'))
2205  unlet b:some_var
2206
2207  w:some_var = 'some'
2208  assert_equal('some', get(w:, 'some_var'))
2209  assert_equal('some', get(w:, 'some_var', 'xxx'))
2210  assert_equal('xxx', get(w:, 'no_var', 'xxx'))
2211  unlet w:some_var
2212
2213  t:some_var = 'some'
2214  assert_equal('some', get(t:, 'some_var'))
2215  assert_equal('some', get(t:, 'some_var', 'xxx'))
2216  assert_equal('xxx', get(t:, 'no_var', 'xxx'))
2217  unlet t:some_var
2218enddef
2219
2220def Test_expr7_parens()
2221  # (expr)
2222  assert_equal(4, (6 * 4) / 6)
2223  assert_equal(0, 6 * ( 4 / 6 ))
2224
2225  assert_equal(6, +6)
2226  assert_equal(-6, -6)
2227  assert_equal(6, --6)
2228  assert_equal(6, -+-6)
2229  assert_equal(-6, ---6)
2230  assert_equal(false, !-3)
2231  assert_equal(true, !+-+0)
2232enddef
2233
2234def Test_expr7_parens_vim9script()
2235  var lines =<< trim END
2236      vim9script
2237      var s = (
2238		'one'
2239		..
2240		'two'
2241		)
2242      assert_equal('onetwo', s)
2243  END
2244  CheckScriptSuccess(lines)
2245enddef
2246
2247def Test_expr7_negate()
2248  assert_equal(-99, -99)
2249  assert_equal(99, --99)
2250  var nr = 88
2251  assert_equal(-88, -nr)
2252  assert_equal(88, --nr)
2253enddef
2254
2255def Echo(arg: any): string
2256  return arg
2257enddef
2258
2259def s:Echo4Arg(arg: any): string
2260  return arg
2261enddef
2262
2263def Test_expr7_call()
2264  assert_equal('yes', 'yes'->Echo())
2265  assert_equal('yes', 'yes'
2266  			->s:Echo4Arg())
2267  assert_equal(true, !range(5)->empty())
2268  assert_equal([0, 1, 2], --3->range())
2269
2270  CheckDefFailure(["var x = 'yes'->Echo"], 'E107:', 1)
2271  CheckScriptFailure([
2272   "vim9script",
2273   "var x = substitute ('x', 'x', 'x', 'x')"
2274   ], 'E121:', 2)
2275  CheckDefFailure(["var Ref = function('len' [1, 2])"], 'E1123:', 1)
2276
2277  var auto_lines =<< trim END
2278      def g:some#func(): string
2279	return 'found'
2280      enddef
2281  END
2282  mkdir('Xruntime/autoload', 'p')
2283  writefile(auto_lines, 'Xruntime/autoload/some.vim')
2284  var save_rtp = &rtp
2285  &rtp = getcwd() .. '/Xruntime,' .. &rtp
2286  assert_equal('found', g:some#func())
2287  assert_equal('found', some#func())
2288
2289  &rtp = save_rtp
2290  delete('Xruntime', 'rf')
2291enddef
2292
2293
2294def Test_expr7_not()
2295  var lines =<< trim END
2296      assert_equal(true, !'')
2297      assert_equal(true, ![])
2298      assert_equal(false, !'asdf')
2299      assert_equal(false, ![2])
2300      assert_equal(true, !!'asdf')
2301      assert_equal(true, !![2])
2302
2303      assert_equal(true, ! false)
2304      assert_equal(true, !! true)
2305      assert_equal(true, ! ! true)
2306      assert_equal(true, !!! false)
2307      assert_equal(true, ! ! ! false)
2308
2309      g:true = true
2310      g:false = false
2311      assert_equal(true, ! g:false)
2312      assert_equal(true, !! g:true)
2313      assert_equal(true, ! ! g:true)
2314      assert_equal(true, !!! g:false)
2315      assert_equal(true, ! ! ! g:false)
2316      unlet g:true
2317      unlet g:false
2318
2319      assert_equal(true, !test_null_partial())
2320      assert_equal(false, !{-> 'yes'})
2321
2322      assert_equal(true, !test_null_dict())
2323      assert_equal(true, !{})
2324      assert_equal(false, !{'yes': 'no'})
2325
2326      if has('channel')
2327	assert_equal(true, !test_null_job())
2328	assert_equal(true, !test_null_channel())
2329      endif
2330
2331      assert_equal(true, !test_null_blob())
2332      assert_equal(true, !0z)
2333      assert_equal(false, !0z01)
2334
2335      assert_equal(true, !test_void())
2336      assert_equal(true, !test_unknown())
2337
2338      assert_equal(false, ![1, 2, 3]->reverse())
2339      assert_equal(true, ![]->reverse())
2340  END
2341  CheckDefAndScriptSuccess(lines)
2342enddef
2343
2344func Test_expr7_fails()
2345  call CheckDefFailure(["var x = (12"], "E110:", 1)
2346
2347  call CheckDefFailure(["var x = -'xx'"], "E1030:", 1)
2348  call CheckDefFailure(["var x = +'xx'"], "E1030:", 1)
2349  call CheckDefFailure(["var x = -0z12"], "E974:", 1)
2350  call CheckDefExecFailure(["var x = -[8]"], "E39:", 1)
2351  call CheckDefExecFailure(["var x = -{'a': 1}"], "E39:", 1)
2352
2353  call CheckDefFailure(["var x = @"], "E1002:", 1)
2354  call CheckDefFailure(["var x = @<"], "E354:", 1)
2355
2356  call CheckDefFailure(["var x = [1, 2"], "E697:", 2)
2357  call CheckDefFailure(["var x = [notfound]"], "E1001:", 1)
2358
2359  call CheckDefFailure(["var x = { -> 123) }"], "E451:", 1)
2360  call CheckDefFailure(["var x = 123->{x -> x + 5) }"], "E451:", 1)
2361
2362  call CheckDefFailure(["var x = &notexist"], 'E113:', 1)
2363  call CheckDefFailure(["&grepprg = [343]"], 'E1012:', 1)
2364
2365  call CheckDefExecFailure(["echo s:doesnt_exist"], 'E121:', 1)
2366  call CheckDefExecFailure(["echo g:doesnt_exist"], 'E121:', 1)
2367
2368  call CheckDefFailure(["echo a:somevar"], 'E1075:', 1)
2369  call CheckDefFailure(["echo l:somevar"], 'E1075:', 1)
2370  call CheckDefFailure(["echo x:somevar"], 'E1075:', 1)
2371
2372  call CheckDefExecFailure(["var x = +g:astring"], 'E1030:', 1)
2373  call CheckDefExecFailure(["var x = +g:ablob"], 'E974:', 1)
2374  call CheckDefExecFailure(["var x = +g:alist"], 'E745:', 1)
2375  call CheckDefExecFailure(["var x = +g:adict"], 'E728:', 1)
2376
2377  call CheckDefFailure(["var x = ''", "var y = x.memb"], 'E715:', 2)
2378
2379  call CheckDefFailure(["'yes'->", "Echo()"], 'E488: Trailing characters: ->', 1)
2380
2381  call CheckDefExecFailure(["[1, 2->len()"], 'E697:', 2)
2382  call CheckDefExecFailure(["#{a: 1->len()"], 'E722:', 1)
2383  call CheckDefExecFailure(["{'a': 1->len()"], 'E723:', 2)
2384endfunc
2385
2386let g:Funcrefs = [function('add')]
2387
2388func CallMe(arg)
2389  return a:arg
2390endfunc
2391
2392func CallMe2(one, two)
2393  return a:one .. a:two
2394endfunc
2395
2396def Test_expr7_trailing()
2397  # user function call
2398  assert_equal(123, g:CallMe(123))
2399  assert_equal(123, g:CallMe(  123))
2400  assert_equal(123, g:CallMe(123  ))
2401  assert_equal('yesno', g:CallMe2('yes', 'no'))
2402  assert_equal('yesno', g:CallMe2( 'yes', 'no' ))
2403  assert_equal('nothing', g:CallMe('nothing'))
2404
2405  # partial call
2406  var Part = function('g:CallMe')
2407  assert_equal('yes', Part('yes'))
2408
2409  # funcref call, using list index
2410  var l = []
2411  g:Funcrefs[0](l, 2)
2412  assert_equal([2], l)
2413
2414  # method call
2415  l = [2, 5, 6]
2416  l->map({k, v -> k + v})
2417  assert_equal([2, 6, 8], l)
2418
2419  # lambda method call
2420  l = [2, 5]
2421  l->{l -> add(l, 8)}()
2422  assert_equal([2, 5, 8], l)
2423
2424  # dict member
2425  var d = #{key: 123}
2426  assert_equal(123, d.key)
2427enddef
2428
2429def Test_expr7_string_subscript()
2430  var lines =<< trim END
2431    var text = 'abcdef'
2432    assert_equal('', text[-1])
2433    assert_equal('a', text[0])
2434    assert_equal('e', text[4])
2435    assert_equal('f', text[5])
2436    assert_equal('', text[6])
2437
2438    text = 'ábçdëf'
2439    assert_equal('', text[-999])
2440    assert_equal('', text[-1])
2441    assert_equal('á', text[0])
2442    assert_equal('b', text[1])
2443    assert_equal('ç', text[2])
2444    assert_equal('d', text[3])
2445    assert_equal('ë', text[4])
2446    assert_equal('f', text[5])
2447    assert_equal('', text[6])
2448    assert_equal('', text[999])
2449
2450    assert_equal('ábçdëf', text[0:-1])
2451    assert_equal('ábçdëf', text[0 :-1])
2452    assert_equal('ábçdëf', text[0: -1])
2453    assert_equal('ábçdëf', text[0 : -1])
2454    assert_equal('ábçdëf', text[0
2455                  :-1])
2456    assert_equal('ábçdëf', text[0:
2457                  -1])
2458    assert_equal('ábçdëf', text[0 : -1
2459                  ])
2460    assert_equal('bçdëf', text[1:-1])
2461    assert_equal('çdëf', text[2:-1])
2462    assert_equal('dëf', text[3:-1])
2463    assert_equal('ëf', text[4:-1])
2464    assert_equal('f', text[5:-1])
2465    assert_equal('', text[6:-1])
2466    assert_equal('', text[999:-1])
2467
2468    assert_equal('ábçd', text[:3])
2469    assert_equal('bçdëf', text[1:])
2470    assert_equal('ábçdëf', text[:])
2471  END
2472  CheckDefSuccess(lines)
2473  CheckScriptSuccess(['vim9script'] + lines)
2474enddef
2475
2476def Test_expr7_list_subscript()
2477  var lines =<< trim END
2478    var list = [0, 1, 2, 3, 4]
2479    assert_equal(0, list[0])
2480    assert_equal(4, list[4])
2481    assert_equal(4, list[-1])
2482    assert_equal(0, list[-5])
2483
2484    assert_equal([0, 1, 2, 3, 4], list[0:4])
2485    assert_equal([0, 1, 2, 3, 4], list[:])
2486    assert_equal([1, 2, 3, 4], list[1:])
2487    assert_equal([2, 3, 4], list[2:-1])
2488    assert_equal([4], list[4:-1])
2489    assert_equal([], list[5:-1])
2490    assert_equal([], list[999:-1])
2491    assert_equal([1, 2, 3, 4], list[g:theone:g:thefour])
2492
2493    assert_equal([0, 1, 2, 3], list[0:3])
2494    assert_equal([0], list[0:0])
2495    assert_equal([0, 1, 2, 3, 4], list[0:-1])
2496    assert_equal([0, 1, 2], list[0:-3])
2497    assert_equal([0], list[0:-5])
2498    assert_equal([], list[0:-6])
2499    assert_equal([], list[0:-99])
2500  END
2501  CheckDefSuccess(lines)
2502  CheckScriptSuccess(['vim9script'] + lines)
2503
2504  lines = ['var l = [0, 1, 2]', 'echo l[g:astring : g:theone]']
2505  CheckDefExecFailure(lines, 'E1012:')
2506  CheckScriptFailure(['vim9script'] + lines, 'E1030:', 3)
2507enddef
2508
2509def Test_expr7_dict_subscript()
2510  var lines =<< trim END
2511      vim9script
2512      var l = [#{lnum: 2}, #{lnum: 1}]
2513      var res = l[0].lnum > l[1].lnum
2514      assert_true(res)
2515  END
2516  CheckScriptSuccess(lines)
2517enddef
2518
2519def Test_expr7_subscript_linebreak()
2520  var range = range(
2521  		3)
2522  var l = range
2523	->map('string(v:key)')
2524  assert_equal(['0', '1', '2'], l)
2525
2526  l = range
2527  	->map('string(v:key)')
2528  assert_equal(['0', '1', '2'], l)
2529
2530  l = range # comment
2531  	->map('string(v:key)')
2532  assert_equal(['0', '1', '2'], l)
2533
2534  l = range
2535
2536  	->map('string(v:key)')
2537  assert_equal(['0', '1', '2'], l)
2538
2539  l = range
2540	# comment
2541  	->map('string(v:key)')
2542  assert_equal(['0', '1', '2'], l)
2543
2544  assert_equal('1', l[
2545	1])
2546
2547  var d = #{one: 33}
2548  assert_equal(33, d.
2549	one)
2550enddef
2551
2552def Test_expr7_method_call()
2553  new
2554  setline(1, ['first', 'last'])
2555  'second'->append(1)
2556  "third"->append(2)
2557  assert_equal(['first', 'second', 'third', 'last'], getline(1, '$'))
2558  bwipe!
2559
2560  var bufnr = bufnr()
2561  var loclist = [#{bufnr: bufnr, lnum: 42, col: 17, text: 'wrong'}]
2562  loclist->setloclist(0)
2563  assert_equal([#{bufnr: bufnr,
2564  		lnum: 42,
2565		col: 17,
2566		text: 'wrong',
2567		pattern: '',
2568		valid: 1,
2569		vcol: 0,
2570		nr: 0,
2571		type: '',
2572		module: ''}
2573		], getloclist(0))
2574
2575  var result: bool = get(#{n: 0}, 'n', 0)
2576  assert_equal(false, result)
2577enddef
2578
2579func Test_expr7_trailing_fails()
2580  call CheckDefFailure(['var l = [2]', 'l->{l -> add(l, 8)}'], 'E107:', 2)
2581  call CheckDefFailure(['var l = [2]', 'l->{l -> add(l, 8)} ()'], 'E274:', 2)
2582endfunc
2583
2584func Test_expr_fails()
2585  call CheckDefFailure(["var x = '1'is2"], 'E488:', 1)
2586  call CheckDefFailure(["var x = '1'isnot2"], 'E488:', 1)
2587
2588  call CheckDefFailure(["CallMe ('yes')"], 'E476:', 1)
2589  call CheckScriptFailure(["CallMe ('yes')"], 'E492:', 1)
2590  call CheckDefAndScriptFailure(["CallMe2('yes','no')"], 'E1069:', 1)
2591  call CheckDefFailure(["CallMe2('yes' , 'no')"], 'E1068:', 1)
2592
2593  call CheckDefFailure(["v:nosuch += 3"], 'E1001:', 1)
2594  call CheckDefFailure(["var v:statusmsg = ''"], 'E1016: Cannot declare a v: variable:', 1)
2595  call CheckDefFailure(["var asdf = v:nosuch"], 'E1001:', 1)
2596
2597  call CheckDefFailure(["echo len('asdf'"], 'E110:', 2)
2598  call CheckDefFailure(["echo Func0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789()"], 'E1011:', 1)
2599  call CheckDefFailure(["echo doesnotexist()"], 'E117:', 1)
2600endfunc
2601
2602" vim: shiftwidth=2 sts=2 expandtab
2603