Patch 8.2.2799

7 views
Skip to first unread message

Bram Moolenaar

unread,
Apr 21, 2021, 11:58:18 AM4/21/21
to vim...@googlegroups.com

Patch 8.2.2799
Problem: Vim9: type casts don't fully work at the script level.
Solution: Implement the missing piece.
Files: src/eval.c, src/testdir/test_vim9_expr.vim


*** ../vim-8.2.2798/src/eval.c 2021-04-18 16:08:49.416235259 +0200
--- src/eval.c 2021-04-21 17:27:36.336574801 +0200
***************
*** 51,56 ****
--- 51,57 ----
static int eval4(char_u **arg, typval_T *rettv, evalarg_T *evalarg);
static int eval5(char_u **arg, typval_T *rettv, evalarg_T *evalarg);
static int eval6(char_u **arg, typval_T *rettv, evalarg_T *evalarg, int want_string);
+ static int eval7t(char_u **arg, typval_T *rettv, evalarg_T *evalarg, int want_string);
static int eval7(char_u **arg, typval_T *rettv, evalarg_T *evalarg, int want_string);
static int eval7_leader(typval_T *rettv, int numeric_only, char_u *start_leader, char_u **end_leaderp);

***************
*** 3068,3074 ****
/*
* Get the first variable.
*/
! if (eval7(arg, rettv, evalarg, want_string) == FAIL)
return FAIL;

/*
--- 3069,3075 ----
/*
* Get the first variable.
*/
! if (eval7t(arg, rettv, evalarg, want_string) == FAIL)
return FAIL;

/*
***************
*** 3141,3147 ****
return FAIL;
}
*arg = skipwhite_and_linebreak(*arg + 1, evalarg);
! if (eval7(arg, &var2, evalarg, FALSE) == FAIL)
return FAIL;

if (evaluate)
--- 3142,3148 ----
return FAIL;
}
*arg = skipwhite_and_linebreak(*arg + 1, evalarg);
! if (eval7t(arg, &var2, evalarg, FALSE) == FAIL)
return FAIL;

if (evaluate)
***************
*** 3231,3236 ****
--- 3232,3317 ----
return OK;
}

+ /*
+ * Handle a type cast before a base level expression.
+ * "arg" must point to the first non-white of the expression.
+ * "arg" is advanced to just after the recognized expression.
+ * Return OK or FAIL.
+ */
+ static int
+ eval7t(
+ char_u **arg,
+ typval_T *rettv,
+ evalarg_T *evalarg,
+ int want_string) // after "." operator
+ {
+ type_T *want_type = NULL;
+ garray_T type_list; // list of pointers to allocated types
+ int res;
+ int evaluate = evalarg == NULL ? 0
+ : (evalarg->eval_flags & EVAL_EVALUATE);
+
+ // Recognize <type> in Vim9 script only.
+ if (in_vim9script() && **arg == '<' && eval_isnamec1((*arg)[1]))
+ {
+ ++*arg;
+ ga_init2(&type_list, sizeof(type_T *), 10);
+ want_type = parse_type(arg, &type_list, TRUE);
+ if (want_type == NULL && (evaluate || **arg != '>'))
+ {
+ clear_type_list(&type_list);
+ return FAIL;
+ }
+
+ if (**arg != '>')
+ {
+ if (*skipwhite(*arg) == '>')
+ semsg(_(e_no_white_space_allowed_before_str_str), ">", *arg);
+ else
+ emsg(_(e_missing_gt));
+ clear_type_list(&type_list);
+ return FAIL;
+ }
+ ++*arg;
+ *arg = skipwhite_and_linebreak(*arg, evalarg);
+ }
+
+ res = eval7(arg, rettv, evalarg, want_string);
+
+ if (want_type != NULL && evaluate)
+ {
+ if (res == OK)
+ {
+ type_T *actual = typval2type(rettv, get_copyID(), &type_list, TRUE);
+
+ if (!equal_type(want_type, actual))
+ {
+ if (want_type == &t_bool && actual != &t_bool
+ && (actual->tt_flags & TTFLAG_BOOL_OK))
+ {
+ int n = tv2bool(rettv);
+
+ // can use "0" and "1" for boolean in some places
+ clear_tv(rettv);
+ rettv->v_type = VAR_BOOL;
+ rettv->vval.v_number = n ? VVAL_TRUE : VVAL_FALSE;
+ }
+ else
+ {
+ where_T where;
+
+ where.wt_index = 0;
+ where.wt_variable = TRUE;
+ res = check_type(want_type, actual, TRUE, where);
+ }
+ }
+ }
+ clear_type_list(&type_list);
+ }
+
+ return res;
+ }
+
int
eval_leader(char_u **arg, int vim9)
{
*** ../vim-8.2.2798/src/testdir/test_vim9_expr.vim 2021-04-11 20:26:30.486312262 +0200
--- src/testdir/test_vim9_expr.vim 2021-04-21 17:30:22.140131199 +0200
***************
*** 1575,1590 ****

" type casts
def Test_expr7t()
! var ls: list<string> = ['a', <string>g:string_empty]
! var ln: list<number> = [<number>g:anint, <number>g:thefour]
! var nr = <number>234
! assert_equal(234, nr)

! CheckDefAndScriptFailure2(["var x = <nr>123"], 'E1010:', 'E15:', 1)
CheckDefFailure(["var x = <number>"], 'E1097:', 3)
CheckScriptFailure(['vim9script', "var x = <number>"], 'E15:', 2)
! CheckDefAndScriptFailure2(["var x = <number >123"], 'E1068:', 'E15:', 1)
! CheckDefAndScriptFailure2(["var x = <number 123"], 'E1104:', 'E15:', 1)
enddef

" test low level expression
--- 1575,1599 ----

" type casts
def Test_expr7t()
! var lines =<< trim END
! var ls: list<string> = ['a', <string>g:string_empty]
! var ln: list<number> = [<number>g:anint, <number>g:thefour]
! var nr = <number>234
! assert_equal(234, nr)
! var text =
! <string>
! 'text'
! if false
! text = <number>'xxx'
! endif
! END
! CheckDefAndScriptSuccess(lines)

! CheckDefAndScriptFailure(["var x = <nr>123"], 'E1010:', 1)
CheckDefFailure(["var x = <number>"], 'E1097:', 3)
CheckScriptFailure(['vim9script', "var x = <number>"], 'E15:', 2)
! CheckDefAndScriptFailure(["var x = <number >123"], 'E1068:', 1)
! CheckDefAndScriptFailure(["var x = <number 123"], 'E1104:', 1)
enddef

" test low level expression
*** ../vim-8.2.2798/src/version.c 2021-04-21 16:00:06.711976510 +0200
--- src/version.c 2021-04-21 17:03:07.137615346 +0200
***************
*** 752,753 ****
--- 752,755 ----
{ /* Add new patch number below this line */
+ /**/
+ 2799,
/**/

--
hundred-and-one symptoms of being an internet addict:
138. You develop a liking for cold coffee.

/// Bram Moolenaar -- Br...@Moolenaar.net -- http://www.Moolenaar.net \\\
/// \\\
\\\ sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ ///
\\\ help me help AIDS victims -- http://ICCF-Holland.org ///
Reply all
Reply to author
Forward
0 new messages