To: vim_dev@googlegroups.com Subject: Patch 8.2.2033 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.2.2033 Problem: Vim9: :def without argument gives compilation error. Solution: Add the DEF instruction. (closes #7344) Files: src/ex_docmd.c, src/vim9.h, src/vim9compile.c, src/vim9execute.c, src/userfunc.c, src/proto/userfunc.pro, src/testdir/test_vim9_disassemble.vim, src/testdir/test_vim9_func.vim *** ../vim-8.2.2032/src/ex_docmd.c 2020-11-20 21:06:56.699112617 +0100 --- src/ex_docmd.c 2020-11-22 17:22:21.295685336 +0100 *************** *** 274,280 **** # define ex_continue ex_ni # define ex_debug ex_ni # define ex_debuggreedy ex_ni - # define ex_def ex_ni # define ex_defcompile ex_ni # define ex_delfunction ex_ni # define ex_disassemble ex_ni --- 274,279 ---- *** ../vim-8.2.2032/src/vim9.h 2020-10-24 23:08:34.707491630 +0200 --- src/vim9.h 2020-11-22 17:34:48.868463208 +0100 *************** *** 82,87 **** --- 82,88 ---- ISN_RETURN, // return, result is on top of stack ISN_FUNCREF, // push a function ref to dfunc isn_arg.funcref ISN_NEWFUNC, // create a global function from a lambda function + ISN_DEF, // list functions // expression operations ISN_JUMP, // jump if condition is matched isn_arg.jump *** ../vim-8.2.2032/src/vim9compile.c 2020-11-20 18:59:14.466192941 +0100 --- src/vim9compile.c 2020-11-22 17:57:52.554574982 +0100 *************** *** 1433,1438 **** --- 1433,1458 ---- } /* + * Generate an ISN_DEF instruction: list functions + */ + static int + generate_DEF(cctx_T *cctx, char_u *name, size_t len) + { + isn_T *isn; + + RETURN_OK_IF_SKIP(cctx); + if ((isn = generate_instr(cctx, ISN_DEF)) == NULL) + return FAIL; + if (len > 0) + { + isn->isn_arg.string = vim_strnsave(name, len); + if (isn->isn_arg.string == NULL) + return FAIL; + } + return OK; + } + + /* * Generate an ISN_JUMP instruction. */ static int *************** *** 4801,4806 **** --- 4821,4847 ---- return NULL; } + if (*name_start == '/') + { + name_end = skip_regexp(name_start + 1, '/', TRUE); + if (*name_end == '/') + ++name_end; + eap->nextcmd = check_nextcmd(name_end); + } + if (name_end == name_start || *skipwhite(name_end) != '(') + { + if (!ends_excmd2(name_start, name_end)) + { + semsg(_(e_invalid_command_str), eap->cmd); + return NULL; + } + + // "def" or "def Name": list functions + if (generate_DEF(cctx, name_start, name_end - name_start) == FAIL) + return NULL; + return eap->nextcmd == NULL ? (char_u *)"" : eap->nextcmd; + } + // Only g:Func() can use a namespace. if (name_start[1] == ':' && !is_global) { *************** *** 7736,7757 **** { switch (isn->isn_type) { case ISN_EXEC: case ISN_LOADENV: case ISN_LOADG: - case ISN_LOADB: - case ISN_LOADW: - case ISN_LOADT: case ISN_LOADOPT: ! case ISN_STRINGMEMBER: case ISN_PUSHEXC: case ISN_PUSHS: case ISN_STOREENV: case ISN_STOREG: - case ISN_STOREB: - case ISN_STOREW: case ISN_STORET: ! case ISN_PUSHFUNC: vim_free(isn->isn_arg.string); break; --- 7777,7799 ---- { switch (isn->isn_type) { + case ISN_DEF: case ISN_EXEC: + case ISN_LOADB: case ISN_LOADENV: case ISN_LOADG: case ISN_LOADOPT: ! case ISN_LOADT: ! case ISN_LOADW: case ISN_PUSHEXC: + case ISN_PUSHFUNC: case ISN_PUSHS: + case ISN_STOREB: case ISN_STOREENV: case ISN_STOREG: case ISN_STORET: ! case ISN_STOREW: ! case ISN_STRINGMEMBER: vim_free(isn->isn_arg.string); break; *** ../vim-8.2.2032/src/vim9execute.c 2020-11-21 11:45:46.221834425 +0100 --- src/vim9execute.c 2020-11-22 17:49:04.560651329 +0100 *************** *** 1970,1975 **** --- 1970,1989 ---- } break; + // List functions + case ISN_DEF: + if (iptr->isn_arg.string == NULL) + list_functions(NULL); + else + { + exarg_T ea; + + CLEAR_FIELD(ea); + ea.cmd = ea.arg = iptr->isn_arg.string; + define_function(&ea, NULL); + } + break; + // jump if a condition is met case ISN_JUMP: { *************** *** 3371,3376 **** --- 3385,3399 ---- } break; + case ISN_DEF: + { + char_u *name = iptr->isn_arg.string; + + smsg("%4d DEF %s", current, + name == NULL ? (char_u *)"" : name); + } + break; + case ISN_JUMP: { char *when = "?"; *** ../vim-8.2.2032/src/userfunc.c 2020-11-17 18:23:15.519278866 +0100 --- src/userfunc.c 2020-11-22 17:47:40.632991699 +0100 *************** *** 2748,2754 **** * List functions. When "regmatch" is NULL all of then. * Otherwise functions matching "regmatch". */ ! static void list_functions(regmatch_T *regmatch) { int changed = func_hashtab.ht_changed; --- 2748,2754 ---- * List functions. When "regmatch" is NULL all of then. * Otherwise functions matching "regmatch". */ ! void list_functions(regmatch_T *regmatch) { int changed = func_hashtab.ht_changed; *** ../vim-8.2.2032/src/proto/userfunc.pro 2020-11-17 18:23:15.519278866 +0100 --- src/proto/userfunc.pro 2020-11-22 17:48:00.492910766 +0100 *************** *** 33,38 **** --- 33,39 ---- char_u *printable_func_name(ufunc_T *fp); char_u *trans_function_name(char_u **pp, int *is_global, int skip, int flags, funcdict_T *fdp, partial_T **partial); char_u *untrans_function_name(char_u *name); + void list_functions(regmatch_T *regmatch); ufunc_T *define_function(exarg_T *eap, char_u *name_arg); void ex_function(exarg_T *eap); void ex_defcompile(exarg_T *eap); *** ../vim-8.2.2032/src/testdir/test_vim9_disassemble.vim 2020-11-18 16:34:59.266884583 +0100 --- src/testdir/test_vim9_disassemble.vim 2020-11-22 17:55:44.411071334 +0100 *************** *** 905,910 **** --- 905,933 ---- instr) enddef + def NestedDefList() + def + def Info + def /Info + def /Info/ + enddef + + def Test_nested_def_list() + var instr = execute('disassemble NestedDefList') + assert_match('NestedDefList\_s*' .. + 'def\_s*' .. + '\d DEF \_s*' .. + 'def Info\_s*' .. + '\d DEF Info\_s*' .. + 'def /Info\_s*' .. + '\d DEF /Info\_s*' .. + 'def /Info/\_s*' .. + '\d DEF /Info/\_s*' .. + '\d PUSHNR 0\_s*' .. + '\d RETURN', + instr) + enddef + def AndOr(arg: any): string if arg == 1 && arg != 2 || arg == 4 return 'yes' *** ../vim-8.2.2032/src/testdir/test_vim9_func.vim 2020-11-22 14:23:57.059233488 +0100 --- src/testdir/test_vim9_func.vim 2020-11-22 18:10:44.452167419 +0100 *************** *** 288,293 **** --- 288,320 ---- CheckScriptFailure(lines, "E1073:") enddef + def DefListAll() + def + enddef + + def DefListOne() + def DefListOne + enddef + + def DefListMatches() + def /DefList + enddef + + def Test_nested_def_list() + var funcs = split(execute('call DefListAll()'), "\n") + assert_true(len(funcs) > 10) + assert_true(funcs->index('def DefListAll()') >= 0) + + funcs = split(execute('call DefListOne()'), "\n") + assert_equal([' def DefListOne()', '1 def DefListOne', ' enddef'], funcs) + + funcs = split(execute('call DefListMatches()'), "\n") + assert_true(len(funcs) >= 3) + assert_true(funcs->index('def DefListAll()') >= 0) + assert_true(funcs->index('def DefListOne()') >= 0) + assert_true(funcs->index('def DefListMatches()') >= 0) + enddef + def Test_global_local_function() var lines =<< trim END vim9script *** ../vim-8.2.2032/src/version.c 2020-11-22 15:51:18.257265193 +0100 --- src/version.c 2020-11-22 17:35:17.144317706 +0100 *************** *** 752,753 **** --- 752,755 ---- { /* Add new patch number below this line */ + /**/ + 2033, /**/ -- "To whoever finds this note - I have been imprisoned by my father who wishes me to marry against my will. Please please please please come and rescue me. I am in the tall tower of Swamp Castle." SIR LAUNCELOT's eyes light up with holy inspiration. "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 ///