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