Patch 8.2.0321
Problem:    Vim9: ":execute" does not work yet.
Solution:   Add ISN_EXECUTE. (closes #5699) Also make :echo work with more
            than one argument.
Files:      src/vim9.h, src/vim9compile.c, src/vim9execute.c,
            src/testdir/test_vim9_disassemble.vim,
            src/testdir/test_vim9_script.vim


*** ../vim-8.2.0320/src/vim9.h  2020-02-06 21:27:05.158175180 +0100
--- src/vim9.h  2020-02-26 17:36:10.318495603 +0100
***************
*** 13,19 ****
  
  typedef enum {
      ISN_EXEC,     // execute Ex command line isn_arg.string
!     ISN_ECHO,     // echo isn_arg.number items on top of stack
  
      // get and set variables
      ISN_LOAD,     // push local variable isn_arg.number
--- 13,20 ----
  
  typedef enum {
      ISN_EXEC,     // execute Ex command line isn_arg.string
!     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
  
      // get and set variables
      ISN_LOAD,     // push local variable isn_arg.number
*** ../vim-8.2.0320/src/vim9compile.c   2020-02-25 22:58:25.607851771 +0100
--- src/vim9compile.c   2020-02-26 18:04:00.856556077 +0100
***************
*** 1116,1121 ****
--- 1116,1136 ----
      return OK;
  }
  
+ /*
+  * Generate an ISN_EXECUTE instruction.
+  */
+     static int
+ generate_EXECUTE(cctx_T *cctx, int count)
+ {
+     isn_T     *isn;
+ 
+     if ((isn = generate_instr_drop(cctx, ISN_EXECUTE, count)) == NULL)
+       return FAIL;
+     isn->isn_arg.number = count;
+ 
+     return OK;
+ }
+ 
      static int
  generate_EXEC(cctx_T *cctx, char_u *line)
  {
***************
*** 4671,4684 ****
      char_u    *p = arg;
      int               count = 0;
  
!     // for ()
      {
        if (compile_expr1(&p, cctx) == FAIL)
            return NULL;
        ++count;
      }
  
      generate_ECHO(cctx, with_white, count);
  
      return p;
  }
--- 4686,4725 ----
      char_u    *p = arg;
      int               count = 0;
  
!     for (;;)
      {
        if (compile_expr1(&p, cctx) == FAIL)
            return NULL;
        ++count;
+       p = skipwhite(p);
+       if (ends_excmd(*p))
+           break;
      }
  
      generate_ECHO(cctx, with_white, count);
+     return p;
+ }
+ 
+ /*
+  * compile "execute expr"
+  */
+     static char_u *
+ compile_execute(char_u *arg, cctx_T *cctx)
+ {
+     char_u    *p = arg;
+     int               count = 0;
+ 
+     for (;;)
+     {
+       if (compile_expr1(&p, cctx) == FAIL)
+           return NULL;
+       ++count;
+       p = skipwhite(p);
+       if (ends_excmd(*p))
+           break;
+     }
+ 
+     generate_EXECUTE(cctx, count);
  
      return p;
  }
***************
*** 5017,5028 ****
            case CMD_echon:
                    line = compile_echo(p, FALSE, &cctx);
                    break;
  
            default:
                    // Not recognized, execute with do_cmdline_cmd().
                    // TODO:
                    // CMD_echomsg
-                   // CMD_execute
                    // etc.
                    generate_EXEC(&cctx, line);
                    line = (char_u *)"";
--- 5058,5071 ----
            case CMD_echon:
                    line = compile_echo(p, FALSE, &cctx);
                    break;
+           case CMD_execute:
+                   line = compile_execute(p, &cctx);
+                   break;
  
            default:
                    // Not recognized, execute with do_cmdline_cmd().
                    // TODO:
                    // CMD_echomsg
                    // etc.
                    generate_EXEC(&cctx, line);
                    line = (char_u *)"";
***************
*** 5150,5155 ****
--- 5193,5199 ----
        case ISN_DCALL:
        case ISN_DROP:
        case ISN_ECHO:
+       case ISN_EXECUTE:
        case ISN_ENDTRY:
        case ISN_FOR:
        case ISN_FUNCREF:
*** ../vim-8.2.0320/src/vim9execute.c   2020-02-20 22:18:01.856405473 +0100
--- src/vim9execute.c   2020-02-26 18:00:26.425318481 +0100
***************
*** 533,538 ****
--- 533,580 ----
                }
                break;
  
+           // execute :execute {string} ...
+           case ISN_EXECUTE:
+               {
+                   int         count = iptr->isn_arg.number;
+                   garray_T    ga;
+                   char_u      buf[NUMBUFLEN];
+                   char_u      *p;
+                   int         len;
+                   int         failed = FALSE;
+ 
+                   ga_init2(&ga, 1, 80);
+                   for (idx = 0; idx < count; ++idx)
+                   {
+                       tv = STACK_TV_BOT(idx - count);
+                       if (tv->v_type == VAR_CHANNEL || tv->v_type == VAR_JOB)
+                       {
+                           emsg(_(e_inval_string));
+                           break;
+                       }
+                       else
+                           p = tv_get_string_buf(tv, buf);
+ 
+                       len = (int)STRLEN(p);
+                       if (ga_grow(&ga, len + 2) == FAIL)
+                           failed = TRUE;
+                       else
+                       {
+                           if (ga.ga_len > 0)
+                               ((char_u *)(ga.ga_data))[ga.ga_len++] = ' ';
+                           STRCPY((char_u *)(ga.ga_data) + ga.ga_len, p);
+                           ga.ga_len += len;
+                       }
+                       clear_tv(tv);
+                   }
+                   ectx.ec_stack.ga_len -= count;
+ 
+                   if (!failed && ga.ga_data != NULL)
+                       do_cmdline_cmd((char_u *)ga.ga_data);
+                   ga_clear(&ga);
+               }
+               break;
+ 
            // load local variable or argument
            case ISN_LOAD:
                if (ga_grow(&ectx.ec_stack, 1) == FAIL)
***************
*** 1666,1671 ****
--- 1708,1716 ----
                            echo->echo_count);
                }
                break;
+           case ISN_EXECUTE:
+               smsg("%4d EXECUTE %d", current, iptr->isn_arg.number);
+               break;
            case ISN_LOAD:
                if (iptr->isn_arg.number < 0)
                    smsg("%4d LOAD arg[%lld]", current,
*** ../vim-8.2.0320/src/testdir/test_vim9_disassemble.vim       2020-02-22 
19:07:24.393786830 +0100
--- src/testdir/test_vim9_disassemble.vim       2020-02-26 17:32:45.855222594 
+0100
***************
*** 690,693 ****
--- 690,726 ----
    " delete('Xdisassemble')
  enddef
  
+ def s:Execute()
+   execute 'help vim9.txt'
+   let cmd = 'help vim9.txt'
+   execute cmd
+   let tag = 'vim9.txt'
+   execute 'help ' .. tag
+ enddef
+ 
+ def Test_disassemble_execute()
+   let res = execute('disass s:Execute')
+   assert_match('\<SNR>\d*_Execute.*'
+         \ .. "execute 'help vim9.txt'.*"
+         \ .. '\d PUSHS "help vim9.txt".*'
+         \ .. '\d EXECUTE 1.*'
+         \ .. "let cmd = 'help vim9.txt'.*"
+         \ .. '\d PUSHS "help vim9.txt".*'
+         \ .. '\d STORE $0.*'
+         \ .. 'execute cmd.*'
+         \ .. '\d LOAD $0.*'
+         \ .. '\d EXECUTE 1.*'
+         \ .. "let tag = 'vim9.txt'.*"
+         \ .. '\d PUSHS "vim9.txt".*'
+         \ .. '\d STORE $1.*'
+         \ .. "execute 'help ' .. tag.*"
+         \ .. '\d PUSHS "help ".*'
+         \ .. '\d LOAD $1.*'
+         \ .. '\d CONCAT.*'
+         \ .. '\d EXECUTE 1.*'
+         \ .. '\d PUSHNR 0.*'
+         \ .. '\d RETURN'
+         \, res)
+ enddef
+ 
  " vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker
*** ../vim-8.2.0320/src/testdir/test_vim9_script.vim    2020-02-25 
22:58:25.607851771 +0100
--- src/testdir/test_vim9_script.vim    2020-02-26 18:10:39.768258187 +0100
***************
*** 1,6 ****
--- 1,7 ----
  " Test various aspects of the Vim9 script language.
  
  source check.vim
+ source view_util.vim
  
  " Check that "lines" inside ":def" results in an "error" message.
  func CheckDefFailure(lines, error)
***************
*** 692,696 ****
--- 693,725 ----
    delete('Xvim9lines')
  enddef
  
+ def Test_execute_cmd()
+   new
+   setline(1, 'default')
+   execute 'call setline(1, "execute-string")'
+   assert_equal('execute-string', getline(1))
+   let cmd1 = 'call setline(1,'
+   let cmd2 = '"execute-var")'
+   execute cmd1 cmd2
+   assert_equal('execute-var', getline(1))
+   execute cmd1 cmd2 '|call setline(1, "execute-var-string")'
+   assert_equal('execute-var-string', getline(1))
+   let cmd_first = 'call '
+   let cmd_last = 'setline(1, "execute-var-var")'
+   execute cmd_first .. cmd_last
+   assert_equal('execute-var-var', getline(1))
+   bwipe!
+ enddef
+ 
+ def Test_echo_cmd()
+   echo 'something'
+   assert_match('^something$', Screenline(&lines))
+ 
+   let str1 = 'some'
+   let str2 = 'more'
+   echo str1 str2
+   assert_match('^some more$', Screenline(&lines))
+ enddef
+ 
  
  " vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker
*** ../vim-8.2.0320/src/version.c       2020-02-26 16:15:31.076386941 +0100
--- src/version.c       2020-02-26 17:33:59.350961277 +0100
***************
*** 740,741 ****
--- 740,743 ----
  {   /* Add new patch number below this line */
+ /**/
+     321,
  /**/

-- 
hundred-and-one symptoms of being an internet addict:
124. You begin conversations with, "Who is your internet service provider?"

 /// 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/202002261725.01QHP85N020492%40masaka.moolenaar.net.

Raspunde prin e-mail lui