To: vim_dev@googlegroups.com Subject: Patch 8.2.0972 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.2.0972 Problem: Vim9 script variable declarations need a type. Solution: Make "let var: type" declare a script-local variable. Files: src/evalvars.c, src/vim9script.c, src/proto/vim9script.pro, src/globals.h, src/vim9compile.c, src/testdir/test_vim9_script.vim *** ../vim-8.2.0971/src/evalvars.c 2020-06-12 22:59:07.262097216 +0200 --- src/evalvars.c 2020-06-13 17:24:58.021863269 +0200 *************** *** 728,735 **** else if (expr[0] == '.') emsg(_("E985: .= is not supported with script version 2")); else if (!ends_excmd2(eap->cmd, arg)) ! // ":let var1 var2" ! arg = list_arg_vars(eap, arg, &first); else if (!eap->skip) { // ":let" --- 728,745 ---- else if (expr[0] == '.') emsg(_("E985: .= is not supported with script version 2")); else if (!ends_excmd2(eap->cmd, arg)) ! { ! if (current_sctx.sc_version == SCRIPT_VERSION_VIM9) ! { ! // Vim9 declaration ":let var: type" ! arg = vim9_declare_scriptvar(eap, arg); ! } ! else ! { ! // ":let var1 var2" - list values ! arg = list_arg_vars(eap, arg, &first); ! } ! } else if (!eap->skip) { // ":let" *** ../vim-8.2.0971/src/vim9script.c 2020-06-11 23:10:42.122363543 +0200 --- src/vim9script.c 2020-06-13 17:25:50.289676385 +0200 *************** *** 434,437 **** --- 434,492 ---- return cmd_end; } + /* + * Declare a script-local variable without init: "let var: type". + * "const" is an error since the value is missing. + * Returns a pointer to after the type. + */ + char_u * + vim9_declare_scriptvar(exarg_T *eap, char_u *arg) + { + char_u *p; + char_u *name; + scriptitem_T *si = SCRIPT_ITEM(current_sctx.sc_sid); + type_T *type; + int called_emsg_before = called_emsg; + typval_T init_tv; + + if (eap->cmdidx == CMD_const) + { + emsg(_(e_const_req_value)); + return arg + STRLEN(arg); + } + + // Check for valid starting character. + if (!eval_isnamec1(*arg)) + { + semsg(_(e_invarg2), arg); + return arg + STRLEN(arg); + } + + for (p = arg + 1; *p != NUL && *p != ':' && eval_isnamec(*p); + MB_PTR_ADV(p)) + ; + + if (*p != ':') + { + emsg(_(e_type_req)); + return arg + STRLEN(arg); + } + name = vim_strnsave(arg, p - arg); + + // parse type + p = skipwhite(p + 1); + type = parse_type(&p, &si->sn_type_list); + if (called_emsg != called_emsg_before) + return p; + + // Create the variable with 0/NULL value. + CLEAR_FIELD(init_tv); + init_tv.v_type = type->tt_type; + set_var_const(name, type, &init_tv, FALSE, 0); + + vim_free(name); + return p; + } + + #endif // FEAT_EVAL *** ../vim-8.2.0971/src/proto/vim9script.pro 2020-03-09 19:25:21.208186448 +0100 --- src/proto/vim9script.pro 2020-06-13 17:14:19.975875568 +0200 *************** *** 6,9 **** --- 6,10 ---- void ex_import(exarg_T *eap); int find_exported(int sid, char_u **argp, int *name_len, ufunc_T **ufunc, type_T **type); char_u *handle_import(char_u *arg_start, garray_T *gap, int import_sid, void *cctx); + char_u *vim9_declare_scriptvar(exarg_T *eap, char_u *arg); /* vim: set ft=c : */ *** ../vim-8.2.0971/src/globals.h 2020-06-13 15:47:21.070282268 +0200 --- src/globals.h 2020-06-13 16:56:31.851615118 +0200 *************** *** 1785,1790 **** --- 1785,1792 ---- EXTERN char e_no_white_before[] INIT(= N_("E1068: No white space allowed before '%s'")); EXTERN char e_lock_unlock[] INIT(= N_("E940: Cannot lock or unlock variable %s")); + EXTERN char e_const_req_value[] INIT(= N_("E1021: const requires a value")); + EXTERN char e_type_req[] INIT(= N_("E1022: type or initialization required")); #endif #if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS) EXTERN char e_alloc_color[] INIT(= N_("E254: Cannot allocate color %s")); *** ../vim-8.2.0971/src/vim9compile.c 2020-06-12 22:59:07.274097177 +0200 --- src/vim9compile.c 2020-06-13 17:01:27.590386002 +0200 *************** *** 2255,2261 **** } /* ! * Find "name" in imported items of the current script/ */ imported_T * find_imported(char_u *name, size_t len, cctx_T *cctx) --- 2255,2262 ---- } /* ! * Find "name" in imported items of the current script or in "cctx" if not ! * NULL. */ imported_T * find_imported(char_u *name, size_t len, cctx_T *cctx) *************** *** 5012,5023 **** } else if (cmdidx == CMD_const) { ! emsg(_("E1021: const requires a value")); goto theend; } else if (!has_type || dest == dest_option) { ! emsg(_("E1022: type or initialization required")); goto theend; } else --- 5013,5024 ---- } else if (cmdidx == CMD_const) { ! emsg(_(e_const_req_value)); goto theend; } else if (!has_type || dest == dest_option) { ! emsg(_(e_type_req)); goto theend; } else *** ../vim-8.2.0971/src/testdir/test_vim9_script.vim 2020-06-11 23:10:42.122363543 +0200 --- src/testdir/test_vim9_script.vim 2020-06-13 18:05:51.641187645 +0200 *************** *** 1815,1820 **** --- 1815,1836 ---- CheckScriptSuccess(lines) enddef + def Test_let_declaration() + let lines =<< trim END + vim9script + let var: string + g:var_uninit = var + var = 'text' + g:var_test = var + END + CheckScriptSuccess(lines) + assert_equal('', g:var_uninit) + assert_equal('text', g:var_test) + + unlet g:var_uninit + unlet g:var_test + enddef + def Test_forward_declaration() let lines =<< trim END vim9script *** ../vim-8.2.0971/src/version.c 2020-06-13 16:39:28.247393573 +0200 --- src/version.c 2020-06-13 18:07:08.660812649 +0200 *************** *** 756,757 **** --- 756,759 ---- { /* Add new patch number below this line */ + /**/ + 972, /**/ -- A computer programmer is a device for turning requirements into undocumented features. It runs on cola, pizza and Dilbert cartoons. Bram Moolenaar /// 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 ///