Skip to content

Commit 6abdcf8

Browse files
committed
patch 8.2.2033: Vim9: :def without argument gives compilation error
Problem: Vim9: :def without argument gives compilation error. Solution: Add the DEF instruction. (closes #7344)
1 parent dcbab75 commit 6abdcf8

9 files changed

Lines changed: 127 additions & 9 deletions

File tree

src/ex_docmd.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -274,7 +274,6 @@ static void ex_tag_cmd(exarg_T *eap, char_u *name);
274274
# define ex_continue ex_ni
275275
# define ex_debug ex_ni
276276
# define ex_debuggreedy ex_ni
277-
# define ex_def ex_ni
278277
# define ex_defcompile ex_ni
279278
# define ex_delfunction ex_ni
280279
# define ex_disassemble ex_ni

src/proto/userfunc.pro

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ int call_func(char_u *funcname, int len, typval_T *rettv, int argcount_in, typva
3333
char_u *printable_func_name(ufunc_T *fp);
3434
char_u *trans_function_name(char_u **pp, int *is_global, int skip, int flags, funcdict_T *fdp, partial_T **partial);
3535
char_u *untrans_function_name(char_u *name);
36+
void list_functions(regmatch_T *regmatch);
3637
ufunc_T *define_function(exarg_T *eap, char_u *name_arg);
3738
void ex_function(exarg_T *eap);
3839
void ex_defcompile(exarg_T *eap);

src/testdir/test_vim9_disassemble.vim

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -905,6 +905,29 @@ def Test_nested_func()
905905
instr)
906906
enddef
907907

908+
def NestedDefList()
909+
def
910+
def Info
911+
def /Info
912+
def /Info/
913+
enddef
914+
915+
def Test_nested_def_list()
916+
var instr = execute('disassemble NestedDefList')
917+
assert_match('NestedDefList\_s*' ..
918+
'def\_s*' ..
919+
'\d DEF \_s*' ..
920+
'def Info\_s*' ..
921+
'\d DEF Info\_s*' ..
922+
'def /Info\_s*' ..
923+
'\d DEF /Info\_s*' ..
924+
'def /Info/\_s*' ..
925+
'\d DEF /Info/\_s*' ..
926+
'\d PUSHNR 0\_s*' ..
927+
'\d RETURN',
928+
instr)
929+
enddef
930+
908931
def AndOr(arg: any): string
909932
if arg == 1 && arg != 2 || arg == 4
910933
return 'yes'

src/testdir/test_vim9_func.vim

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,33 @@ def Test_nested_global_function()
288288
CheckScriptFailure(lines, "E1073:")
289289
enddef
290290

291+
def DefListAll()
292+
def
293+
enddef
294+
295+
def DefListOne()
296+
def DefListOne
297+
enddef
298+
299+
def DefListMatches()
300+
def /DefList
301+
enddef
302+
303+
def Test_nested_def_list()
304+
var funcs = split(execute('call DefListAll()'), "\n")
305+
assert_true(len(funcs) > 10)
306+
assert_true(funcs->index('def DefListAll()') >= 0)
307+
308+
funcs = split(execute('call DefListOne()'), "\n")
309+
assert_equal([' def DefListOne()', '1 def DefListOne', ' enddef'], funcs)
310+
311+
funcs = split(execute('call DefListMatches()'), "\n")
312+
assert_true(len(funcs) >= 3)
313+
assert_true(funcs->index('def DefListAll()') >= 0)
314+
assert_true(funcs->index('def DefListOne()') >= 0)
315+
assert_true(funcs->index('def DefListMatches()') >= 0)
316+
enddef
317+
291318
def Test_global_local_function()
292319
var lines =<< trim END
293320
vim9script

src/userfunc.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2748,7 +2748,7 @@ untrans_function_name(char_u *name)
27482748
* List functions. When "regmatch" is NULL all of then.
27492749
* Otherwise functions matching "regmatch".
27502750
*/
2751-
static void
2751+
void
27522752
list_functions(regmatch_T *regmatch)
27532753
{
27542754
int changed = func_hashtab.ht_changed;

src/version.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -750,6 +750,8 @@ static char *(features[]) =
750750

751751
static int included_patches[] =
752752
{ /* Add new patch number below this line */
753+
/**/
754+
2033,
753755
/**/
754756
2032,
755757
/**/

src/vim9.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ typedef enum {
8282
ISN_RETURN, // return, result is on top of stack
8383
ISN_FUNCREF, // push a function ref to dfunc isn_arg.funcref
8484
ISN_NEWFUNC, // create a global function from a lambda function
85+
ISN_DEF, // list functions
8586

8687
// expression operations
8788
ISN_JUMP, // jump if condition is matched isn_arg.jump

src/vim9compile.c

Lines changed: 49 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1432,6 +1432,26 @@ generate_NEWFUNC(cctx_T *cctx, char_u *lambda_name, char_u *func_name)
14321432
return OK;
14331433
}
14341434

1435+
/*
1436+
* Generate an ISN_DEF instruction: list functions
1437+
*/
1438+
static int
1439+
generate_DEF(cctx_T *cctx, char_u *name, size_t len)
1440+
{
1441+
isn_T *isn;
1442+
1443+
RETURN_OK_IF_SKIP(cctx);
1444+
if ((isn = generate_instr(cctx, ISN_DEF)) == NULL)
1445+
return FAIL;
1446+
if (len > 0)
1447+
{
1448+
isn->isn_arg.string = vim_strnsave(name, len);
1449+
if (isn->isn_arg.string == NULL)
1450+
return FAIL;
1451+
}
1452+
return OK;
1453+
}
1454+
14351455
/*
14361456
* Generate an ISN_JUMP instruction.
14371457
*/
@@ -4801,6 +4821,27 @@ compile_nested_function(exarg_T *eap, cctx_T *cctx)
48014821
return NULL;
48024822
}
48034823

4824+
if (*name_start == '/')
4825+
{
4826+
name_end = skip_regexp(name_start + 1, '/', TRUE);
4827+
if (*name_end == '/')
4828+
++name_end;
4829+
eap->nextcmd = check_nextcmd(name_end);
4830+
}
4831+
if (name_end == name_start || *skipwhite(name_end) != '(')
4832+
{
4833+
if (!ends_excmd2(name_start, name_end))
4834+
{
4835+
semsg(_(e_invalid_command_str), eap->cmd);
4836+
return NULL;
4837+
}
4838+
4839+
// "def" or "def Name": list functions
4840+
if (generate_DEF(cctx, name_start, name_end - name_start) == FAIL)
4841+
return NULL;
4842+
return eap->nextcmd == NULL ? (char_u *)"" : eap->nextcmd;
4843+
}
4844+
48044845
// Only g:Func() can use a namespace.
48054846
if (name_start[1] == ':' && !is_global)
48064847
{
@@ -7736,22 +7777,23 @@ delete_instr(isn_T *isn)
77367777
{
77377778
switch (isn->isn_type)
77387779
{
7780+
case ISN_DEF:
77397781
case ISN_EXEC:
7782+
case ISN_LOADB:
77407783
case ISN_LOADENV:
77417784
case ISN_LOADG:
7742-
case ISN_LOADB:
7743-
case ISN_LOADW:
7744-
case ISN_LOADT:
77457785
case ISN_LOADOPT:
7746-
case ISN_STRINGMEMBER:
7786+
case ISN_LOADT:
7787+
case ISN_LOADW:
77477788
case ISN_PUSHEXC:
7789+
case ISN_PUSHFUNC:
77487790
case ISN_PUSHS:
7791+
case ISN_STOREB:
77497792
case ISN_STOREENV:
77507793
case ISN_STOREG:
7751-
case ISN_STOREB:
7752-
case ISN_STOREW:
77537794
case ISN_STORET:
7754-
case ISN_PUSHFUNC:
7795+
case ISN_STOREW:
7796+
case ISN_STRINGMEMBER:
77557797
vim_free(isn->isn_arg.string);
77567798
break;
77577799

src/vim9execute.c

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1970,6 +1970,20 @@ call_def_function(
19701970
}
19711971
break;
19721972

1973+
// List functions
1974+
case ISN_DEF:
1975+
if (iptr->isn_arg.string == NULL)
1976+
list_functions(NULL);
1977+
else
1978+
{
1979+
exarg_T ea;
1980+
1981+
CLEAR_FIELD(ea);
1982+
ea.cmd = ea.arg = iptr->isn_arg.string;
1983+
define_function(&ea, NULL);
1984+
}
1985+
break;
1986+
19731987
// jump if a condition is met
19741988
case ISN_JUMP:
19751989
{
@@ -3371,6 +3385,15 @@ ex_disassemble(exarg_T *eap)
33713385
}
33723386
break;
33733387

3388+
case ISN_DEF:
3389+
{
3390+
char_u *name = iptr->isn_arg.string;
3391+
3392+
smsg("%4d DEF %s", current,
3393+
name == NULL ? (char_u *)"" : name);
3394+
}
3395+
break;
3396+
33743397
case ISN_JUMP:
33753398
{
33763399
char *when = "?";

0 commit comments

Comments
 (0)