patch 8.2.1794: no falsy Coalescing operator
Problem: No falsy Coalescing operator.
Solution: Add the "??" operator. Fix mistake with function argument count.
diff --git a/src/testdir/test_expr.vim b/src/testdir/test_expr.vim
index cfae760..1086534 100644
--- a/src/testdir/test_expr.vim
+++ b/src/testdir/test_expr.vim
@@ -42,6 +42,28 @@
call assert_false(has('patch-9.9.1'))
endfunc
+func Test_op_falsy()
+ call assert_equal(v:true, v:true ?? 456)
+ call assert_equal(123, 123 ?? 456)
+ call assert_equal('yes', 'yes' ?? 456)
+ call assert_equal(0z00, 0z00 ?? 456)
+ call assert_equal([1], [1] ?? 456)
+ call assert_equal(#{one: 1}, #{one: 1} ?? 456)
+ if has('float')
+ call assert_equal(0.1, 0.1 ?? 456)
+ endif
+
+ call assert_equal(456, v:false ?? 456)
+ call assert_equal(456, 0 ?? 456)
+ call assert_equal(456, '' ?? 456)
+ call assert_equal(456, 0z ?? 456)
+ call assert_equal(456, [] ?? 456)
+ call assert_equal(456, {} ?? 456)
+ if has('float')
+ call assert_equal(456, 0.0 ?? 456)
+ endif
+endfunc
+
func Test_dict()
let d = {'': 'empty', 'a': 'a', 0: 'zero'}
call assert_equal('empty', d[''])
diff --git a/src/testdir/test_vim9_disassemble.vim b/src/testdir/test_vim9_disassemble.vim
index f1f358a..a8dbe1a 100644
--- a/src/testdir/test_vim9_disassemble.vim
+++ b/src/testdir/test_vim9_disassemble.vim
@@ -1326,6 +1326,33 @@
delete('Xdisassemble')
enddef
+def s:FalsyOp()
+ echo g:flag ?? "yes"
+ echo [] ?? "empty list"
+ echo "" ?? "empty string"
+enddef
+
+def Test_dsassemble_falsy_op()
+ var res = execute('disass s:FalsyOp')
+ assert_match('\<SNR>\d*_FalsyOp\_s*' ..
+ 'echo g:flag ?? "yes"\_s*' ..
+ '0 LOADG g:flag\_s*' ..
+ '1 JUMP_AND_KEEP_IF_TRUE -> 3\_s*' ..
+ '2 PUSHS "yes"\_s*' ..
+ '3 ECHO 1\_s*' ..
+ 'echo \[\] ?? "empty list"\_s*' ..
+ '4 NEWLIST size 0\_s*' ..
+ '5 JUMP_AND_KEEP_IF_TRUE -> 7\_s*' ..
+ '6 PUSHS "empty list"\_s*' ..
+ '7 ECHO 1\_s*' ..
+ 'echo "" ?? "empty string"\_s*' ..
+ '\d\+ PUSHS "empty string"\_s*' ..
+ '\d\+ ECHO 1\_s*' ..
+ '\d\+ PUSHNR 0\_s*' ..
+ '\d\+ RETURN',
+ res)
+enddef
+
def Test_disassemble_compare_const()
var cases = [
['"xx" == "yy"', false],
diff --git a/src/testdir/test_vim9_expr.vim b/src/testdir/test_vim9_expr.vim
index fa33089..253e469 100644
--- a/src/testdir/test_vim9_expr.vim
+++ b/src/testdir/test_vim9_expr.vim
@@ -12,7 +12,7 @@
enddef
" test cond ? expr : expr
-def Test_expr1()
+def Test_expr1_trinary()
assert_equal('one', true ? 'one' : 'two')
assert_equal('one', 1 ?
'one' :
@@ -61,7 +61,7 @@
assert_equal(123, Z(3))
enddef
-def Test_expr1_vimscript()
+def Test_expr1_trinary_vimscript()
# check line continuation
var lines =<< trim END
vim9script
@@ -139,7 +139,7 @@
CheckScriptSuccess(lines)
enddef
-func Test_expr1_fails()
+func Test_expr1_trinary_fails()
call CheckDefFailure(["var x = 1 ? 'one'"], "Missing ':' after '?'", 1)
let msg = "White space required before and after '?'"
@@ -160,6 +160,34 @@
\ 'Z()'], 'E119:', 4)
endfunc
+def Test_expr1_falsy()
+ var lines =<< trim END
+ assert_equal(v:true, v:true ?? 456)
+ assert_equal(123, 123 ?? 456)
+ assert_equal('yes', 'yes' ?? 456)
+ assert_equal([1], [1] ?? 456)
+ assert_equal(#{one: 1}, #{one: 1} ?? 456)
+ if has('float')
+ assert_equal(0.1, 0.1 ?? 456)
+ endif
+
+ assert_equal(456, v:false ?? 456)
+ assert_equal(456, 0 ?? 456)
+ assert_equal(456, '' ?? 456)
+ assert_equal(456, [] ?? 456)
+ assert_equal(456, {} ?? 456)
+ if has('float')
+ assert_equal(456, 0.0 ?? 456)
+ endif
+ END
+ CheckDefAndScriptSuccess(lines)
+
+ var msg = "White space required before and after '??'"
+ call CheckDefFailure(["var x = 1?? 'one' : 'two'"], msg, 1)
+ call CheckDefFailure(["var x = 1 ??'one' : 'two'"], msg, 1)
+ call CheckDefFailure(["var x = 1??'one' : 'two'"], msg, 1)
+enddef
+
" TODO: define inside test function
def Record(val: any): any
g:vals->add(val)