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