To: vim_dev@googlegroups.com Subject: Patch 8.2.0562 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.2.0562 Problem: Vim9: cannot split an expression into multiple lines. Solution: Continue in next line after an operator. Files: runtime/doc/vim9.txt, src/macros.h, src/vim9compile.c, src/testdir/test_vim9_expr.vim *** ../vim-8.2.0561/runtime/doc/vim9.txt 2020-04-12 20:19:12.639818982 +0200 --- runtime/doc/vim9.txt 2020-04-12 20:51:16.927419654 +0200 *************** *** 195,200 **** --- 195,212 ---- arg2 ) + For binary operators iin expressions not in [], {} or () a line break is + possible AFTER the operators. For example: > + let text = lead .. + middle .. + end + let total = start + + end - + correction + let result = positive ? + PosFunc(arg) : + NegFunc(arg) + Note that "enddef" cannot be used at the start of a continuation line, it ends the current function. *** ../vim-8.2.0561/src/macros.h 2020-03-11 14:19:53.480369957 +0100 --- src/macros.h 2020-04-12 20:24:15.323191994 +0200 *************** *** 37,46 **** #define LTOREQ_POS(a, b) (LT_POS(a, b) || EQUAL_POS(a, b)) /* ! * VIM_ISWHITE() is used for "^" and the like. It differs from isspace() ! * because it doesn't include and and the like. */ ! #define VIM_ISWHITE(x) ((x) == ' ' || (x) == '\t') /* * LINEEMPTY() - return TRUE if the line is empty --- 37,47 ---- #define LTOREQ_POS(a, b) (LT_POS(a, b) || EQUAL_POS(a, b)) /* ! * VIM_ISWHITE() differs from isspace() because it doesn't include and ! * and the like. */ ! #define VIM_ISWHITE(x) ((x) == ' ' || (x) == '\t') ! #define IS_WHITE_OR_NUL(x) ((x) == ' ' || (x) == '\t' || (x) == NUL) /* * LINEEMPTY() - return TRUE if the line is empty *** ../vim-8.2.0561/src/vim9compile.c 2020-04-12 20:19:12.639818982 +0200 --- src/vim9compile.c 2020-04-12 20:49:04.883743936 +0200 *************** *** 2070,2075 **** --- 2070,2093 ---- } /* + * If "*arg" is at the end of the line, advance to the next line. + * Return FAIL if beyond the last line, "*arg" is unmodified then. + */ + static int + may_get_next_line(char_u **arg, cctx_T *cctx) + { + if (**arg == NUL) + { + char_u *next = next_line_from_context(cctx); + + if (next == NULL) + return FAIL; + *arg = skipwhite(next); + } + return OK; + } + + /* * Generate an instruction to load script-local variable "name", without the * leading "s:". * Also finds imported variables. *************** *** 3394,3407 **** op = skipwhite(*arg); if (*op != '*' && *op != '/' && *op != '%') break; ! if (!VIM_ISWHITE(**arg) || !VIM_ISWHITE(op[1])) { char_u buf[3]; vim_strncpy(buf, op, 1); semsg(_(e_white_both), buf); } *arg = skipwhite(op + 1); // get the second variable if (compile_expr7(arg, cctx) == FAIL) --- 3412,3428 ---- op = skipwhite(*arg); if (*op != '*' && *op != '/' && *op != '%') break; ! if (!IS_WHITE_OR_NUL(**arg) || !IS_WHITE_OR_NUL(op[1])) { char_u buf[3]; vim_strncpy(buf, op, 1); semsg(_(e_white_both), buf); + return FAIL; } *arg = skipwhite(op + 1); + if (may_get_next_line(arg, cctx) == FAIL) + return FAIL; // get the second variable if (compile_expr7(arg, cctx) == FAIL) *************** *** 3438,3452 **** break; oplen = (*op == '.' ? 2 : 1); ! if (!VIM_ISWHITE(**arg) || !VIM_ISWHITE(op[oplen])) { char_u buf[3]; vim_strncpy(buf, op, oplen); semsg(_(e_white_both), buf); } *arg = skipwhite(op + oplen); // get the second variable if (compile_expr6(arg, cctx) == FAIL) --- 3459,3476 ---- break; oplen = (*op == '.' ? 2 : 1); ! if (!IS_WHITE_OR_NUL(**arg) || !IS_WHITE_OR_NUL(op[oplen])) { char_u buf[3]; vim_strncpy(buf, op, oplen); semsg(_(e_white_both), buf); + return FAIL; } *arg = skipwhite(op + oplen); + if (may_get_next_line(arg, cctx) == FAIL) + return FAIL; // get the second variable if (compile_expr6(arg, cctx) == FAIL) *************** *** 3572,3587 **** ++len; // nothing appended: match case ! if (!VIM_ISWHITE(**arg) || !VIM_ISWHITE(p[len])) { char_u buf[7]; vim_strncpy(buf, p, len); semsg(_(e_white_both), buf); } // get the second variable *arg = skipwhite(p + len); if (compile_expr5(arg, cctx) == FAIL) return FAIL; --- 3596,3615 ---- ++len; // nothing appended: match case ! if (!IS_WHITE_OR_NUL(**arg) || !IS_WHITE_OR_NUL(p[len])) { char_u buf[7]; vim_strncpy(buf, p, len); semsg(_(e_white_both), buf); + return FAIL; } // get the second variable *arg = skipwhite(p + len); + if (may_get_next_line(arg, cctx) == FAIL) + return FAIL; + if (compile_expr5(arg, cctx) == FAIL) return FAIL; *************** *** 3611,3618 **** ga_init2(&end_ga, sizeof(int), 10); while (p[0] == opchar && p[1] == opchar) { ! if (!VIM_ISWHITE(**arg) || !VIM_ISWHITE(p[2])) semsg(_(e_white_both), op); if (ga_grow(&end_ga, 1) == FAIL) { --- 3639,3649 ---- ga_init2(&end_ga, sizeof(int), 10); while (p[0] == opchar && p[1] == opchar) { ! if (!IS_WHITE_OR_NUL(**arg) || !IS_WHITE_OR_NUL(p[2])) ! { semsg(_(e_white_both), op); + return FAIL; + } if (ga_grow(&end_ga, 1) == FAIL) { *************** *** 3626,3631 **** --- 3657,3665 ---- // eval the next expression *arg = skipwhite(p + 2); + if (may_get_next_line(arg, cctx) == FAIL) + return FAIL; + if ((opchar == '|' ? compile_expr3(arg, cctx) : compile_expr4(arg, cctx)) == FAIL) { *************** *** 3726,3738 **** type_T *type1; type_T *type2; ! if (!VIM_ISWHITE(**arg) || !VIM_ISWHITE(p[1])) semsg(_(e_white_both), "?"); generate_JUMP(cctx, JUMP_IF_FALSE, 0); // evaluate the second expression; any type is accepted *arg = skipwhite(p + 1); if (compile_expr1(arg, cctx) == FAIL) return FAIL; --- 3760,3778 ---- type_T *type1; type_T *type2; ! if (!IS_WHITE_OR_NUL(**arg) || !IS_WHITE_OR_NUL(p[1])) ! { semsg(_(e_white_both), "?"); + return FAIL; + } generate_JUMP(cctx, JUMP_IF_FALSE, 0); // evaluate the second expression; any type is accepted *arg = skipwhite(p + 1); + if (may_get_next_line(arg, cctx) == FAIL) + return FAIL; + if (compile_expr1(arg, cctx) == FAIL) return FAIL; *************** *** 3754,3764 **** emsg(_(e_missing_colon)); return FAIL; } ! if (!VIM_ISWHITE(**arg) || !VIM_ISWHITE(p[1])) semsg(_(e_white_both), ":"); // evaluate the third expression *arg = skipwhite(p + 1); if (compile_expr1(arg, cctx) == FAIL) return FAIL; --- 3794,3810 ---- emsg(_(e_missing_colon)); return FAIL; } ! if (!IS_WHITE_OR_NUL(**arg) || !IS_WHITE_OR_NUL(p[1])) ! { semsg(_(e_white_both), ":"); + return FAIL; + } // evaluate the third expression *arg = skipwhite(p + 1); + if (may_get_next_line(arg, cctx) == FAIL) + return FAIL; + if (compile_expr1(arg, cctx) == FAIL) return FAIL; *** ../vim-8.2.0561/src/testdir/test_vim9_expr.vim 2020-04-12 18:02:02.031541127 +0200 --- src/testdir/test_vim9_expr.vim 2020-04-12 20:50:01.479605043 +0200 *************** *** 32,38 **** " test cond ? expr : expr def Test_expr1() assert_equal('one', true ? 'one' : 'two') ! assert_equal('one', 1 ? 'one' : 'two') if has('float') assert_equal('one', 0.1 ? 'one' : 'two') endif --- 32,40 ---- " test cond ? expr : expr def Test_expr1() assert_equal('one', true ? 'one' : 'two') ! assert_equal('one', 1 ? ! 'one' : ! 'two') if has('float') assert_equal('one', 0.1 ? 'one' : 'two') endif *************** *** 80,86 **** " test || def Test_expr2() assert_equal(2, 2 || 0) ! assert_equal(7, 0 || 0 || 7) assert_equal(0, 0 || 0) assert_equal('', 0 || '') --- 82,90 ---- " test || def Test_expr2() assert_equal(2, 2 || 0) ! assert_equal(7, 0 || ! 0 || ! 7) assert_equal(0, 0 || 0) assert_equal('', 0 || '') *************** *** 113,119 **** " test && def Test_expr3() assert_equal(0, 2 && 0) ! assert_equal(0, 0 && 0 && 7) assert_equal(7, 2 && 3 && 7) assert_equal(0, 0 && 0) assert_equal(0, 0 && '') --- 117,125 ---- " test && def Test_expr3() assert_equal(0, 2 && 0) ! assert_equal(0, 0 && ! 0 && ! 7) assert_equal(7, 2 && 3 && 7) assert_equal(0, 0 && 0) assert_equal(0, 0 && '') *************** *** 164,170 **** " test == comperator def Test_expr4_equal() assert_equal(true, true == true) ! assert_equal(false, true == false) assert_equal(true, true == g:atrue) assert_equal(false, g:atrue == false) --- 170,177 ---- " test == comperator def Test_expr4_equal() assert_equal(true, true == true) ! assert_equal(false, true == ! false) assert_equal(true, true == g:atrue) assert_equal(false, g:atrue == false) *************** *** 237,243 **** " test != comperator def Test_expr4_notequal() assert_equal(false, true != true) ! assert_equal(true, true != false) assert_equal(false, true != g:atrue) assert_equal(true, g:atrue != false) --- 244,251 ---- " test != comperator def Test_expr4_notequal() assert_equal(false, true != true) ! assert_equal(true, true != ! false) assert_equal(false, true != g:atrue) assert_equal(true, g:atrue != false) *************** *** 303,309 **** " test > comperator def Test_expr4_greater() assert_true(2 > 0) ! assert_true(2 > 1) assert_false(2 > 2) assert_false(2 > 3) if has('float') --- 311,318 ---- " test > comperator def Test_expr4_greater() assert_true(2 > 0) ! assert_true(2 > ! 1) assert_false(2 > 2) assert_false(2 > 3) if has('float') *************** *** 317,323 **** " test >= comperator def Test_expr4_greaterequal() assert_true(2 >= 0) ! assert_true(2 >= 2) assert_false(2 >= 3) if has('float') assert_true(2.0 >= 0.0) --- 326,333 ---- " test >= comperator def Test_expr4_greaterequal() assert_true(2 >= 0) ! assert_true(2 >= ! 2) assert_false(2 >= 3) if has('float') assert_true(2.0 >= 0.0) *************** *** 329,335 **** " test < comperator def Test_expr4_smaller() assert_false(2 < 0) ! assert_false(2 < 2) assert_true(2 < 3) if has('float') assert_false(2.0 < 0.0) --- 339,346 ---- " test < comperator def Test_expr4_smaller() assert_false(2 < 0) ! assert_false(2 < ! 2) assert_true(2 < 3) if has('float') assert_false(2.0 < 0.0) *************** *** 341,347 **** " test <= comperator def Test_expr4_smallerequal() assert_false(2 <= 0) ! assert_false(2 <= 1) assert_true(2 <= 2) assert_true(2 <= 3) if has('float') --- 352,359 ---- " test <= comperator def Test_expr4_smallerequal() assert_false(2 <= 0) ! assert_false(2 <= ! 1) assert_true(2 <= 2) assert_true(2 <= 3) if has('float') *************** *** 355,367 **** " test =~ comperator def Test_expr4_match() assert_equal(false, '2' =~ '0') ! assert_equal(true, '2' =~ '[0-9]') enddef " test !~ comperator def Test_expr4_nomatch() assert_equal(true, '2' !~ '0') ! assert_equal(false, '2' !~ '[0-9]') enddef " test is comperator --- 367,381 ---- " test =~ comperator def Test_expr4_match() assert_equal(false, '2' =~ '0') ! assert_equal(true, '2' =~ ! '[0-9]') enddef " test !~ comperator def Test_expr4_nomatch() assert_equal(true, '2' !~ '0') ! assert_equal(false, '2' !~ ! '[0-9]') enddef " test is comperator *************** *** 369,375 **** let mylist = [2] assert_false(mylist is [2]) let other = mylist ! assert_true(mylist is other) let myblob = 0z1234 assert_false(myblob is 0z1234) --- 383,390 ---- let mylist = [2] assert_false(mylist is [2]) let other = mylist ! assert_true(mylist is ! other) let myblob = 0z1234 assert_false(myblob is 0z1234) *************** *** 383,389 **** assert_true('2' isnot '0') assert_true(mylist isnot [2]) let other = mylist ! assert_false(mylist isnot other) let myblob = 0z1234 assert_true(myblob isnot 0z1234) --- 398,405 ---- assert_true('2' isnot '0') assert_true(mylist isnot [2]) let other = mylist ! assert_false(mylist isnot ! other) let myblob = 0z1234 assert_true(myblob isnot 0z1234) *************** *** 467,483 **** " test addition, subtraction, concatenation def Test_expr5() assert_equal(66, 60 + 6) ! assert_equal(70, 60 + g:anint) assert_equal(9, g:alsoint + 5) assert_equal(14, g:alsoint + g:anint) assert_equal(54, 60 - 6) ! assert_equal(50, 60 - g:anint) assert_equal(-1, g:alsoint - 5) assert_equal(-6, g:alsoint - g:anint) assert_equal('hello', 'hel' .. 'lo') ! assert_equal('hello 123', 'hello ' .. 123) assert_equal('123 hello', 123 .. ' hello') assert_equal('123456', 123 .. 456) --- 483,502 ---- " test addition, subtraction, concatenation def Test_expr5() assert_equal(66, 60 + 6) ! assert_equal(70, 60 + ! g:anint) assert_equal(9, g:alsoint + 5) assert_equal(14, g:alsoint + g:anint) assert_equal(54, 60 - 6) ! assert_equal(50, 60 - ! g:anint) assert_equal(-1, g:alsoint - 5) assert_equal(-6, g:alsoint - g:anint) assert_equal('hello', 'hel' .. 'lo') ! assert_equal('hello 123', 'hello ' .. ! 123) assert_equal('123 hello', 123 .. ' hello') assert_equal('123456', 123 .. 456) *************** *** 494,500 **** else assert_equal(66.0, 60.0 + 6.0) assert_equal(66.0, 60.0 + 6) ! assert_equal(66.0, 60 + 6.0) assert_equal(5.1, g:afloat + 5) assert_equal(8.1, 8 + g:afloat) assert_equal(10.1, g:anint + g:afloat) --- 513,520 ---- else assert_equal(66.0, 60.0 + 6.0) assert_equal(66.0, 60.0 + 6) ! assert_equal(66.0, 60 + ! 6.0) assert_equal(5.1, g:afloat + 5) assert_equal(8.1, 8 + g:afloat) assert_equal(10.1, g:anint + g:afloat) *************** *** 538,555 **** " test multiply, divide, modulo def Test_expr6() assert_equal(36, 6 * 6) ! assert_equal(24, 6 * g:alsoint) assert_equal(24, g:alsoint * 6) assert_equal(40, g:anint * g:alsoint) assert_equal(10, 60 / 6) ! assert_equal(6, 60 / g:anint) assert_equal(1, g:anint / 6) assert_equal(2, g:anint / g:alsoint) assert_equal(5, 11 % 6) assert_equal(4, g:anint % 6) ! assert_equal(3, 13 % g:anint) assert_equal(2, g:anint % g:alsoint) assert_equal(4, 6 * 4 / 6) --- 558,578 ---- " test multiply, divide, modulo def Test_expr6() assert_equal(36, 6 * 6) ! assert_equal(24, 6 * ! g:alsoint) assert_equal(24, g:alsoint * 6) assert_equal(40, g:anint * g:alsoint) assert_equal(10, 60 / 6) ! assert_equal(6, 60 / ! g:anint) assert_equal(1, g:anint / 6) assert_equal(2, g:anint / g:alsoint) assert_equal(5, 11 % 6) assert_equal(4, g:anint % 6) ! assert_equal(3, 13 % ! g:anint) assert_equal(2, g:anint % g:alsoint) assert_equal(4, 6 * 4 / 6) *************** *** 573,589 **** MissingFeature 'float' else assert_equal(36.0, 6.0 * 6) ! assert_equal(36.0, 6 * 6.0) assert_equal(36.0, 6.0 * 6.0) assert_equal(1.0, g:afloat * g:anint) assert_equal(10.0, 60 / 6.0) ! assert_equal(10.0, 60.0 / 6) assert_equal(10.0, 60.0 / 6.0) assert_equal(0.01, g:afloat / g:anint) assert_equal(4.0, 6.0 * 4 / 6) ! assert_equal(4.0, 6 * 4.0 / 6) assert_equal(4.0, 6 * 4 / 6.0) assert_equal(4.0, 6.0 * 4.0 / 6) assert_equal(4.0, 6 * 4.0 / 6.0) --- 596,616 ---- MissingFeature 'float' else assert_equal(36.0, 6.0 * 6) ! assert_equal(36.0, 6 * ! 6.0) assert_equal(36.0, 6.0 * 6.0) assert_equal(1.0, g:afloat * g:anint) assert_equal(10.0, 60 / 6.0) ! assert_equal(10.0, 60.0 / ! 6) assert_equal(10.0, 60.0 / 6.0) assert_equal(0.01, g:afloat / g:anint) assert_equal(4.0, 6.0 * 4 / 6) ! assert_equal(4.0, 6 * ! 4.0 / ! 6) assert_equal(4.0, 6 * 4 / 6.0) assert_equal(4.0, 6.0 * 4.0 / 6) assert_equal(4.0, 6 * 4.0 / 6.0) *** ../vim-8.2.0561/src/version.c 2020-04-12 20:19:12.643818971 +0200 --- src/version.c 2020-04-12 20:54:21.954964146 +0200 *************** *** 740,741 **** --- 740,743 ---- { /* Add new patch number below this line */ + /**/ + 562, /**/ -- We apologise again for the fault in the subtitles. Those responsible for sacking the people who have just been sacked have been sacked. "Monty Python and the Holy Grail" PYTHON (MONTY) PICTURES LTD /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ \\\ an exciting new programming language -- http://www.Zimbu.org /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///