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 -- [email protected] -- 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    ///

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/vim_dev/202011221716.0AMHGJBd1263993%40masaka.moolenaar.net.

Raspunde prin e-mail lui