To: vim_dev@googlegroups.com Subject: Patch 8.2.2861 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.2.2861 Problem: Vim9: "legacy return" is not recognized as a return statement. Solution: Specifically check for a return command. (closes #8213) Files: src/vim9compile.c, src/vim9execute.c, src/vim9.h, src/testdir/test_vim9_expr.vim *** ../vim-8.2.2860/src/vim9compile.c 2021-05-16 15:24:45.654704709 +0200 --- src/vim9compile.c 2021-05-16 23:38:53.693003933 +0200 *************** *** 2174,2179 **** --- 2174,2198 ---- } static int + generate_LEGACY_EVAL(cctx_T *cctx, char_u *line) + { + isn_T *isn; + garray_T *stack = &cctx->ctx_type_stack; + + RETURN_OK_IF_SKIP(cctx); + if ((isn = generate_instr(cctx, ISN_LEGACY_EVAL)) == NULL) + return FAIL; + isn->isn_arg.string = vim_strsave(line); + + if (ga_grow(stack, 1) == FAIL) + return FAIL; + ((type_T **)stack->ga_data)[stack->ga_len] = &t_any; + ++stack->ga_len; + + return OK; + } + + static int generate_EXECCONCAT(cctx_T *cctx, int count) { isn_T *isn; *************** *** 5321,5330 **** } /* ! * compile "return [expr]" */ static char_u * ! compile_return(char_u *arg, int check_return_type, cctx_T *cctx) { char_u *p = arg; garray_T *stack = &cctx->ctx_type_stack; --- 5340,5350 ---- } /* ! * Compile "return [expr]". ! * When "legacy" is TRUE evaluate [expr] with legacy syntax */ static char_u * ! compile_return(char_u *arg, int check_return_type, int legacy, cctx_T *cctx) { char_u *p = arg; garray_T *stack = &cctx->ctx_type_stack; *************** *** 5332,5340 **** if (*p != NUL && *p != '|' && *p != '\n') { ! // compile return argument into instructions ! if (compile_expr0(&p, cctx) == FAIL) ! return NULL; if (cctx->ctx_skip != SKIP_YES) { --- 5352,5375 ---- if (*p != NUL && *p != '|' && *p != '\n') { ! if (legacy) ! { ! int save_flags = cmdmod.cmod_flags; ! ! generate_LEGACY_EVAL(cctx, p); ! if (need_type(&t_any, cctx->ctx_ufunc->uf_ret_type, -1, ! 0, cctx, FALSE, FALSE) == FAIL) ! return NULL; ! cmdmod.cmod_flags |= CMOD_LEGACY; ! (void)skip_expr(&p, NULL); ! cmdmod.cmod_flags = save_flags; ! } ! else ! { ! // compile return argument into instructions ! if (compile_expr0(&p, cctx) == FAIL) ! return NULL; ! } if (cctx->ctx_skip != SKIP_YES) { *************** *** 9193,9199 **** // When using ":legacy cmd" always use compile_exec(). if (local_cmdmod.cmod_flags & CMOD_LEGACY) ! ea.cmdidx = CMD_legacy; if (p == ea.cmd && ea.cmdidx != CMD_SIZE) { --- 9228,9242 ---- // When using ":legacy cmd" always use compile_exec(). if (local_cmdmod.cmod_flags & CMOD_LEGACY) ! { ! char_u *start = ea.cmd; ! ! // ":legacy return expr" needs to be handled differently. ! if (checkforcmd(&start, "return", 4)) ! ea.cmdidx = CMD_return; ! else ! ea.cmdidx = CMD_legacy; ! } if (p == ea.cmd && ea.cmdidx != CMD_SIZE) { *************** *** 9254,9260 **** goto erret; case CMD_return: ! line = compile_return(p, check_return_type, &cctx); cctx.ctx_had_return = TRUE; break; --- 9297,9304 ---- goto erret; case CMD_return: ! line = compile_return(p, check_return_type, ! local_cmdmod.cmod_flags & CMOD_LEGACY, &cctx); cctx.ctx_had_return = TRUE; break; *************** *** 9605,9610 **** --- 9649,9655 ---- { case ISN_DEF: case ISN_EXEC: + case ISN_LEGACY_EVAL: case ISN_LOADAUTO: case ISN_LOADB: case ISN_LOADENV: *** ../vim-8.2.2860/src/vim9execute.c 2021-05-16 15:24:45.654704709 +0200 --- src/vim9execute.c 2021-05-16 23:28:15.207783649 +0200 *************** *** 1388,1393 **** --- 1388,1414 ---- } break; + // Evaluate an expression with legacy syntax, push it onto the + // stack. + case ISN_LEGACY_EVAL: + { + char_u *arg = iptr->isn_arg.string; + int res; + int save_flags = cmdmod.cmod_flags; + + if (GA_GROW(&ectx->ec_stack, 1) == FAIL) + return FAIL; + tv = STACK_TV_BOT(0); + init_tv(tv); + cmdmod.cmod_flags |= CMOD_LEGACY; + res = eval0(arg, tv, NULL, &EVALARG_EVALUATE); + cmdmod.cmod_flags = save_flags; + if (res == FAIL) + goto on_error; + ++ectx->ec_stack.ga_len; + } + break; + // push typeval VAR_INSTR with instructions to be executed case ISN_INSTR: { *************** *** 4464,4469 **** --- 4485,4494 ---- case ISN_EXEC: smsg("%s%4d EXEC %s", pfx, current, iptr->isn_arg.string); break; + case ISN_LEGACY_EVAL: + smsg("%s%4d EVAL legacy %s", pfx, current, + iptr->isn_arg.string); + break; case ISN_REDIRSTART: smsg("%s%4d REDIR", pfx, current); break; *** ../vim-8.2.2860/src/vim9.h 2021-05-07 17:55:51.963584417 +0200 --- src/vim9.h 2021-05-16 23:23:48.392946482 +0200 *************** *** 14,19 **** --- 14,20 ---- typedef enum { ISN_EXEC, // execute Ex command line isn_arg.string ISN_EXECCONCAT, // execute Ex command from isn_arg.number items on stack + ISN_LEGACY_EVAL, // evaluate expression isn_arg.string with legacy syntax. ISN_ECHO, // echo isn_arg.echo.echo_count items on top of stack ISN_EXECUTE, // execute Ex commands isn_arg.number items on top of stack ISN_ECHOMSG, // echo Ex commands isn_arg.number items on top of stack *** ../vim-8.2.2860/src/testdir/test_vim9_expr.vim 2021-05-06 21:04:51.518534023 +0200 --- src/testdir/test_vim9_expr.vim 2021-05-16 23:58:35.191821216 +0200 *************** *** 2777,2782 **** --- 2777,2786 ---- CheckDefAndScriptFailure(lines, 'E15:') enddef + def LegacyReturn(): string + legacy return #{key: 'ok'}.key + enddef + def Test_expr7_legacy_script() var lines =<< trim END let s:legacy = 'legacy' *************** *** 2790,2795 **** --- 2794,2810 ---- call assert_equal('legacy', GetLocalPrefix()) END CheckScriptSuccess(lines) + + assert_equal('ok', LegacyReturn()) + + lines =<< trim END + vim9script + def GetNumber(): number + legacy return range(3)->map('v:val + 1') + enddef + echo GetNumber() + END + CheckScriptFailure(lines, 'E1012: Type mismatch; expected number but got list') enddef def Echo(arg: any): string *** ../vim-8.2.2860/src/version.c 2021-05-16 20:18:51.029536617 +0200 --- src/version.c 2021-05-16 21:55:54.315716622 +0200 *************** *** 752,753 **** --- 752,755 ---- { /* Add new patch number below this line */ + /**/ + 2861, /**/ -- If I tell you "you have a beautiful body", would you hold it against me? /// Bram Moolenaar -- Bram@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 ///