0
0
mirror of https://github.com/vim/vim.git synced 2025-09-23 03:43:49 -04:00

patch 8.2.0321: Vim9: ":execute" does not work yet

Problem:    Vim9: ":execute" does not work yet.
Solution:   Add ISN_EXECUTE. (closes #5699) Also make :echo work with more
            than one argument.
This commit is contained in:
Bram Moolenaar
2020-02-26 18:23:43 +01:00
parent b3f740695a
commit ad39c094d2
6 changed files with 157 additions and 3 deletions

View File

@@ -690,4 +690,37 @@ def Test_disassemble_compare()
" 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

View File

@@ -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,5 +693,33 @@ def Test_substitute_cmd()
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

View File

@@ -738,6 +738,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
321,
/**/
320,
/**/

View File

@@ -13,7 +13,8 @@
typedef enum {
ISN_EXEC, // execute Ex command line isn_arg.string
ISN_ECHO, // echo isn_arg.number items on top of stack
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

View File

@@ -1116,6 +1116,21 @@ generate_ECHO(cctx_T *cctx, int with_white, int count)
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,14 +4686,40 @@ compile_echo(char_u *arg, int with_white, cctx_T *cctx)
char_u *p = arg;
int count = 0;
// for ()
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,12 +5058,14 @@ compile_def_function(ufunc_T *ufunc, int set_return_type)
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
// CMD_execute
// etc.
generate_EXEC(&cctx, line);
line = (char_u *)"";
@@ -5150,6 +5193,7 @@ delete_instr(isn_T *isn)
case ISN_DCALL:
case ISN_DROP:
case ISN_ECHO:
case ISN_EXECUTE:
case ISN_ENDTRY:
case ISN_FOR:
case ISN_FUNCREF:

View File

@@ -533,6 +533,48 @@ call_def_function(
}
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,6 +1708,9 @@ ex_disassemble(exarg_T *eap)
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,