mirror of
https://github.com/vim/vim.git
synced 2025-09-23 03:43:49 -04:00
patch 8.2.1329: Vim9: cannot define global function inside :def function
Problem: Vim9: cannot define global function inside :def function. Solution: Assign to global variable instead of local. (closes #6584)
This commit is contained in:
35
src/misc2.c
35
src/misc2.c
@@ -2027,6 +2027,41 @@ ga_clear_strings(garray_T *gap)
|
|||||||
ga_clear(gap);
|
ga_clear(gap);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copy a growing array that contains a list of strings.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
ga_copy_strings(garray_T *from, garray_T *to)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
ga_init2(to, sizeof(char_u *), 1);
|
||||||
|
if (ga_grow(to, from->ga_len) == FAIL)
|
||||||
|
return FAIL;
|
||||||
|
|
||||||
|
for (i = 0; i < from->ga_len; ++i)
|
||||||
|
{
|
||||||
|
char_u *orig = ((char_u **)from->ga_data)[i];
|
||||||
|
char_u *copy;
|
||||||
|
|
||||||
|
if (orig == NULL)
|
||||||
|
copy = NULL;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
copy = vim_strsave(orig);
|
||||||
|
if (copy == NULL)
|
||||||
|
{
|
||||||
|
to->ga_len = i;
|
||||||
|
ga_clear_strings(to);
|
||||||
|
return FAIL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
((char_u **)to->ga_data)[i] = copy;
|
||||||
|
}
|
||||||
|
to->ga_len = from->ga_len;
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initialize a growing array. Don't forget to set ga_itemsize and
|
* Initialize a growing array. Don't forget to set ga_itemsize and
|
||||||
* ga_growsize! Or use ga_init2().
|
* ga_growsize! Or use ga_init2().
|
||||||
|
@@ -56,6 +56,7 @@ char_u *vim_strrchr(char_u *string, int c);
|
|||||||
int vim_isspace(int x);
|
int vim_isspace(int x);
|
||||||
void ga_clear(garray_T *gap);
|
void ga_clear(garray_T *gap);
|
||||||
void ga_clear_strings(garray_T *gap);
|
void ga_clear_strings(garray_T *gap);
|
||||||
|
int ga_copy_strings(garray_T *from, garray_T *to);
|
||||||
void ga_init(garray_T *gap);
|
void ga_init(garray_T *gap);
|
||||||
void ga_init2(garray_T *gap, int itemsize, int growsize);
|
void ga_init2(garray_T *gap, int itemsize, int growsize);
|
||||||
int ga_grow(garray_T *gap, int n);
|
int ga_grow(garray_T *gap, int n);
|
||||||
|
@@ -5,6 +5,7 @@ int get_function_args(char_u **argp, char_u endchar, garray_T *newargs, garray_T
|
|||||||
char_u *get_lambda_name(void);
|
char_u *get_lambda_name(void);
|
||||||
char_u *register_cfunc(cfunc_T cb, cfunc_free_T cb_free, void *state);
|
char_u *register_cfunc(cfunc_T cb, cfunc_free_T cb_free, void *state);
|
||||||
int get_lambda_tv(char_u **arg, typval_T *rettv, evalarg_T *evalarg);
|
int get_lambda_tv(char_u **arg, typval_T *rettv, evalarg_T *evalarg);
|
||||||
|
void copy_func(char_u *lambda, char_u *global);
|
||||||
char_u *deref_func_name(char_u *name, int *lenp, partial_T **partialp, int no_autoload);
|
char_u *deref_func_name(char_u *name, int *lenp, partial_T **partialp, int no_autoload);
|
||||||
void emsg_funcname(char *ermsg, char_u *name);
|
void emsg_funcname(char *ermsg, char_u *name);
|
||||||
int get_func_tv(char_u *name, int len, typval_T *rettv, char_u **arg, evalarg_T *evalarg, funcexe_T *funcexe);
|
int get_func_tv(char_u *name, int len, typval_T *rettv, char_u **arg, evalarg_T *evalarg, funcexe_T *funcexe);
|
||||||
|
@@ -1546,6 +1546,7 @@ typedef enum {
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Structure to hold info for a user function.
|
* Structure to hold info for a user function.
|
||||||
|
* When adding a field check copy_func().
|
||||||
*/
|
*/
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
@@ -1618,6 +1619,7 @@ typedef struct
|
|||||||
#define FC_NOARGS 0x200 // no a: variables in lambda
|
#define FC_NOARGS 0x200 // no a: variables in lambda
|
||||||
#define FC_VIM9 0x400 // defined in vim9 script file
|
#define FC_VIM9 0x400 // defined in vim9 script file
|
||||||
#define FC_CFUNC 0x800 // defined as Lua C func
|
#define FC_CFUNC 0x800 // defined as Lua C func
|
||||||
|
#define FC_COPY 0x1000 // copy of another function by copy_func()
|
||||||
|
|
||||||
#define MAX_FUNC_ARGS 20 // maximum number of function arguments
|
#define MAX_FUNC_ARGS 20 // maximum number of function arguments
|
||||||
#define VAR_SHORT_LEN 20 // short variable name length
|
#define VAR_SHORT_LEN 20 // short variable name length
|
||||||
|
@@ -699,6 +699,24 @@ def Test_disassemble_lambda()
|
|||||||
instr)
|
instr)
|
||||||
enddef
|
enddef
|
||||||
|
|
||||||
|
def NestedOuter()
|
||||||
|
def g:Inner()
|
||||||
|
echomsg "inner"
|
||||||
|
enddef
|
||||||
|
enddef
|
||||||
|
|
||||||
|
def Test_nested_func()
|
||||||
|
let instr = execute('disassemble NestedOuter')
|
||||||
|
assert_match('NestedOuter\_s*' ..
|
||||||
|
'def g:Inner()\_s*' ..
|
||||||
|
'echomsg "inner"\_s*' ..
|
||||||
|
'enddef\_s*' ..
|
||||||
|
'\d NEWFUNC <lambda>\d\+ Inner\_s*' ..
|
||||||
|
'\d PUSHNR 0\_s*' ..
|
||||||
|
'\d RETURN',
|
||||||
|
instr)
|
||||||
|
enddef
|
||||||
|
|
||||||
def AndOr(arg: any): string
|
def AndOr(arg: any): string
|
||||||
if arg == 1 && arg != 2 || arg == 4
|
if arg == 1 && arg != 2 || arg == 4
|
||||||
return 'yes'
|
return 'yes'
|
||||||
|
@@ -133,6 +133,28 @@ def Test_nested_function()
|
|||||||
CheckDefFailure(['func Nested()', 'endfunc'], 'E1086:')
|
CheckDefFailure(['func Nested()', 'endfunc'], 'E1086:')
|
||||||
enddef
|
enddef
|
||||||
|
|
||||||
|
def Test_nested_global_function()
|
||||||
|
let lines =<< trim END
|
||||||
|
vim9script
|
||||||
|
def Outer()
|
||||||
|
def g:Inner(): string
|
||||||
|
return 'inner'
|
||||||
|
enddef
|
||||||
|
enddef
|
||||||
|
disass Outer
|
||||||
|
Outer()
|
||||||
|
assert_equal('inner', g:Inner())
|
||||||
|
delfunc g:Inner
|
||||||
|
Outer()
|
||||||
|
assert_equal('inner', g:Inner())
|
||||||
|
delfunc g:Inner
|
||||||
|
Outer()
|
||||||
|
assert_equal('inner', g:Inner())
|
||||||
|
delfunc g:Inner
|
||||||
|
END
|
||||||
|
CheckScriptSuccess(lines)
|
||||||
|
enddef
|
||||||
|
|
||||||
func Test_call_default_args_from_func()
|
func Test_call_default_args_from_func()
|
||||||
call assert_equal('string', MyDefaultArgs())
|
call assert_equal('string', MyDefaultArgs())
|
||||||
call assert_equal('one', MyDefaultArgs('one'))
|
call assert_equal('one', MyDefaultArgs('one'))
|
||||||
|
@@ -366,7 +366,7 @@ register_cfunc(cfunc_T cb, cfunc_free_T cb_free, void *state)
|
|||||||
if (fp == NULL)
|
if (fp == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
fp->uf_dfunc_idx = UF_NOT_COMPILED;
|
fp->uf_def_status = UF_NOT_COMPILED;
|
||||||
fp->uf_refcount = 1;
|
fp->uf_refcount = 1;
|
||||||
fp->uf_varargs = TRUE;
|
fp->uf_varargs = TRUE;
|
||||||
fp->uf_flags = FC_CFUNC;
|
fp->uf_flags = FC_CFUNC;
|
||||||
@@ -1069,7 +1069,8 @@ func_remove(ufunc_T *fp)
|
|||||||
{
|
{
|
||||||
// When there is a def-function index do not actually remove the
|
// When there is a def-function index do not actually remove the
|
||||||
// function, so we can find the index when defining the function again.
|
// function, so we can find the index when defining the function again.
|
||||||
if (fp->uf_def_status == UF_COMPILED)
|
// Do remove it when it's a copy.
|
||||||
|
if (fp->uf_def_status == UF_COMPILED && (fp->uf_flags & FC_COPY) == 0)
|
||||||
fp->uf_flags |= FC_DEAD;
|
fp->uf_flags |= FC_DEAD;
|
||||||
else
|
else
|
||||||
hash_remove(&func_hashtab, hi);
|
hash_remove(&func_hashtab, hi);
|
||||||
@@ -1122,7 +1123,8 @@ func_clear(ufunc_T *fp, int force)
|
|||||||
// clear this function
|
// clear this function
|
||||||
func_clear_items(fp);
|
func_clear_items(fp);
|
||||||
funccal_unref(fp->uf_scoped, fp, force);
|
funccal_unref(fp->uf_scoped, fp, force);
|
||||||
clear_def_function(fp);
|
if ((fp->uf_flags & FC_COPY) == 0)
|
||||||
|
clear_def_function(fp);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -1150,12 +1152,83 @@ func_free(ufunc_T *fp, int force)
|
|||||||
func_clear_free(ufunc_T *fp, int force)
|
func_clear_free(ufunc_T *fp, int force)
|
||||||
{
|
{
|
||||||
func_clear(fp, force);
|
func_clear(fp, force);
|
||||||
if (force || fp->uf_dfunc_idx == 0)
|
if (force || fp->uf_dfunc_idx == 0 || (fp->uf_flags & FC_COPY))
|
||||||
func_free(fp, force);
|
func_free(fp, force);
|
||||||
else
|
else
|
||||||
fp->uf_flags |= FC_DEAD;
|
fp->uf_flags |= FC_DEAD;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copy already defined function "lambda" to a new function with name "global".
|
||||||
|
* This is for when a compiled function defines a global function.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
copy_func(char_u *lambda, char_u *global)
|
||||||
|
{
|
||||||
|
ufunc_T *ufunc = find_func_even_dead(lambda, TRUE, NULL);
|
||||||
|
ufunc_T *fp;
|
||||||
|
|
||||||
|
if (ufunc == NULL)
|
||||||
|
semsg(_("E1102: lambda function not found: %s"), lambda);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// TODO: handle ! to overwrite
|
||||||
|
fp = find_func(global, TRUE, NULL);
|
||||||
|
if (fp != NULL)
|
||||||
|
{
|
||||||
|
semsg(_(e_funcexts), global);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
fp = alloc_clear(offsetof(ufunc_T, uf_name) + STRLEN(global) + 1);
|
||||||
|
if (fp == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
fp->uf_varargs = ufunc->uf_varargs;
|
||||||
|
fp->uf_flags = (ufunc->uf_flags & ~FC_VIM9) | FC_COPY;
|
||||||
|
fp->uf_def_status = ufunc->uf_def_status;
|
||||||
|
fp->uf_dfunc_idx = ufunc->uf_dfunc_idx;
|
||||||
|
if (ga_copy_strings(&fp->uf_args, &ufunc->uf_args) == FAIL
|
||||||
|
|| ga_copy_strings(&fp->uf_def_args, &ufunc->uf_def_args)
|
||||||
|
== FAIL
|
||||||
|
|| ga_copy_strings(&fp->uf_lines, &ufunc->uf_lines) == FAIL)
|
||||||
|
goto failed;
|
||||||
|
|
||||||
|
fp->uf_name_exp = ufunc->uf_name_exp == NULL ? NULL
|
||||||
|
: vim_strsave(ufunc->uf_name_exp);
|
||||||
|
if (ufunc->uf_arg_types != NULL)
|
||||||
|
{
|
||||||
|
fp->uf_arg_types = ALLOC_MULT(type_T *, fp->uf_args.ga_len);
|
||||||
|
if (fp->uf_arg_types == NULL)
|
||||||
|
goto failed;
|
||||||
|
mch_memmove(fp->uf_arg_types, ufunc->uf_arg_types,
|
||||||
|
sizeof(type_T *) * fp->uf_args.ga_len);
|
||||||
|
}
|
||||||
|
if (ufunc->uf_def_arg_idx != NULL)
|
||||||
|
{
|
||||||
|
fp->uf_def_arg_idx = ALLOC_MULT(int, fp->uf_def_args.ga_len + 1);
|
||||||
|
if (fp->uf_def_arg_idx == NULL)
|
||||||
|
goto failed;
|
||||||
|
mch_memmove(fp->uf_def_arg_idx, ufunc->uf_def_arg_idx,
|
||||||
|
sizeof(int) * fp->uf_def_args.ga_len + 1);
|
||||||
|
}
|
||||||
|
if (ufunc->uf_va_name != NULL)
|
||||||
|
{
|
||||||
|
fp->uf_va_name = vim_strsave(ufunc->uf_va_name);
|
||||||
|
if (fp->uf_va_name == NULL)
|
||||||
|
goto failed;
|
||||||
|
}
|
||||||
|
|
||||||
|
fp->uf_refcount = 1;
|
||||||
|
STRCPY(fp->uf_name, global);
|
||||||
|
hash_add(&func_hashtab, UF2HIKEY(fp));
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
|
||||||
|
failed:
|
||||||
|
func_clear_free(fp, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Call a user function.
|
* Call a user function.
|
||||||
@@ -2521,6 +2594,8 @@ list_functions(regmatch_T *regmatch)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* ":function" also supporting nested ":def".
|
* ":function" also supporting nested ":def".
|
||||||
|
* When "name_arg" is not NULL this is a nested function, using "name_arg" for
|
||||||
|
* the function name.
|
||||||
* Returns a pointer to the function or NULL if no function defined.
|
* Returns a pointer to the function or NULL if no function defined.
|
||||||
*/
|
*/
|
||||||
ufunc_T *
|
ufunc_T *
|
||||||
|
@@ -754,6 +754,8 @@ static char *(features[]) =
|
|||||||
|
|
||||||
static int included_patches[] =
|
static int included_patches[] =
|
||||||
{ /* Add new patch number below this line */
|
{ /* Add new patch number below this line */
|
||||||
|
/**/
|
||||||
|
1329,
|
||||||
/**/
|
/**/
|
||||||
1328,
|
1328,
|
||||||
/**/
|
/**/
|
||||||
|
@@ -79,6 +79,7 @@ typedef enum {
|
|||||||
ISN_PCALL_END, // cleanup after ISN_PCALL with cpf_top set
|
ISN_PCALL_END, // cleanup after ISN_PCALL with cpf_top set
|
||||||
ISN_RETURN, // return, result is on top of stack
|
ISN_RETURN, // return, result is on top of stack
|
||||||
ISN_FUNCREF, // push a function ref to dfunc isn_arg.funcref
|
ISN_FUNCREF, // push a function ref to dfunc isn_arg.funcref
|
||||||
|
ISN_NEWFUNC, // create a global function from a lambda function
|
||||||
|
|
||||||
// expression operations
|
// expression operations
|
||||||
ISN_JUMP, // jump if condition is matched isn_arg.jump
|
ISN_JUMP, // jump if condition is matched isn_arg.jump
|
||||||
@@ -237,6 +238,12 @@ typedef struct {
|
|||||||
int fr_var_idx; // variable to store partial
|
int fr_var_idx; // variable to store partial
|
||||||
} funcref_T;
|
} funcref_T;
|
||||||
|
|
||||||
|
// arguments to ISN_NEWFUNC
|
||||||
|
typedef struct {
|
||||||
|
char_u *nf_lambda; // name of the lambda already defined
|
||||||
|
char_u *nf_global; // name of the global function to be created
|
||||||
|
} newfunc_T;
|
||||||
|
|
||||||
// arguments to ISN_CHECKLEN
|
// arguments to ISN_CHECKLEN
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int cl_min_len; // minimum length
|
int cl_min_len; // minimum length
|
||||||
@@ -281,6 +288,7 @@ struct isn_S {
|
|||||||
script_T script;
|
script_T script;
|
||||||
unlet_T unlet;
|
unlet_T unlet;
|
||||||
funcref_T funcref;
|
funcref_T funcref;
|
||||||
|
newfunc_T newfunc;
|
||||||
checklen_T checklen;
|
checklen_T checklen;
|
||||||
shuffle_T shuffle;
|
shuffle_T shuffle;
|
||||||
} isn_arg;
|
} isn_arg;
|
||||||
|
@@ -1522,6 +1522,27 @@ generate_FUNCREF(cctx_T *cctx, int dfunc_idx)
|
|||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Generate an ISN_NEWFUNC instruction.
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
generate_NEWFUNC(cctx_T *cctx, char_u *lambda_name, char_u *func_name)
|
||||||
|
{
|
||||||
|
isn_T *isn;
|
||||||
|
char_u *name;
|
||||||
|
|
||||||
|
RETURN_OK_IF_SKIP(cctx);
|
||||||
|
name = vim_strsave(lambda_name);
|
||||||
|
if (name == NULL)
|
||||||
|
return FAIL;
|
||||||
|
if ((isn = generate_instr(cctx, ISN_NEWFUNC)) == NULL)
|
||||||
|
return FAIL;
|
||||||
|
isn->isn_arg.newfunc.nf_lambda = name;
|
||||||
|
isn->isn_arg.newfunc.nf_global = func_name;
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Generate an ISN_JUMP instruction.
|
* Generate an ISN_JUMP instruction.
|
||||||
*/
|
*/
|
||||||
@@ -4875,11 +4896,13 @@ exarg_getline(
|
|||||||
static char_u *
|
static char_u *
|
||||||
compile_nested_function(exarg_T *eap, cctx_T *cctx)
|
compile_nested_function(exarg_T *eap, cctx_T *cctx)
|
||||||
{
|
{
|
||||||
|
int is_global = *eap->arg == 'g' && eap->arg[1] == ':';
|
||||||
char_u *name_start = eap->arg;
|
char_u *name_start = eap->arg;
|
||||||
char_u *name_end = to_name_end(eap->arg, FALSE);
|
char_u *name_end = to_name_end(eap->arg, is_global);
|
||||||
char_u *name = get_lambda_name();
|
char_u *name = get_lambda_name();
|
||||||
lvar_T *lvar;
|
lvar_T *lvar;
|
||||||
ufunc_T *ufunc;
|
ufunc_T *ufunc;
|
||||||
|
int r;
|
||||||
|
|
||||||
eap->arg = name_end;
|
eap->arg = name_end;
|
||||||
eap->getline = exarg_getline;
|
eap->getline = exarg_getline;
|
||||||
@@ -4894,16 +4917,28 @@ compile_nested_function(exarg_T *eap, cctx_T *cctx)
|
|||||||
&& compile_def_function(ufunc, TRUE, cctx) == FAIL)
|
&& compile_def_function(ufunc, TRUE, cctx) == FAIL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
// Define a local variable for the function reference.
|
if (is_global)
|
||||||
lvar = reserve_local(cctx, name_start, name_end - name_start,
|
{
|
||||||
TRUE, ufunc->uf_func_type);
|
char_u *func_name = vim_strnsave(name_start + 2,
|
||||||
|
name_end - name_start - 2);
|
||||||
|
|
||||||
if (generate_FUNCREF(cctx, ufunc->uf_dfunc_idx) == FAIL
|
if (func_name == NULL)
|
||||||
|| generate_STORE(cctx, ISN_STORE, lvar->lv_idx, NULL) == FAIL)
|
r = FAIL;
|
||||||
return NULL;
|
else
|
||||||
|
r = generate_NEWFUNC(cctx, name, func_name);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Define a local variable for the function reference.
|
||||||
|
lvar = reserve_local(cctx, name_start, name_end - name_start,
|
||||||
|
TRUE, ufunc->uf_func_type);
|
||||||
|
if (generate_FUNCREF(cctx, ufunc->uf_dfunc_idx) == FAIL)
|
||||||
|
return NULL;
|
||||||
|
r = generate_STORE(cctx, ISN_STORE, lvar->lv_idx, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: warning for trailing text?
|
// TODO: warning for trailing text?
|
||||||
return (char_u *)"";
|
return r == FAIL ? NULL : (char_u *)"";
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -7641,6 +7676,11 @@ delete_instr(isn_T *isn)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case ISN_NEWFUNC:
|
||||||
|
vim_free(isn->isn_arg.newfunc.nf_lambda);
|
||||||
|
vim_free(isn->isn_arg.newfunc.nf_global);
|
||||||
|
break;
|
||||||
|
|
||||||
case ISN_2BOOL:
|
case ISN_2BOOL:
|
||||||
case ISN_2STRING:
|
case ISN_2STRING:
|
||||||
case ISN_ADDBLOB:
|
case ISN_ADDBLOB:
|
||||||
|
@@ -723,7 +723,10 @@ call_def_function(
|
|||||||
dfunc_T *dfunc = ((dfunc_T *)def_functions.ga_data)
|
dfunc_T *dfunc = ((dfunc_T *)def_functions.ga_data)
|
||||||
+ ufunc->uf_dfunc_idx;
|
+ ufunc->uf_dfunc_idx;
|
||||||
if (dfunc->df_instr == NULL)
|
if (dfunc->df_instr == NULL)
|
||||||
|
{
|
||||||
|
iemsg("using call_def_function() on not compiled function");
|
||||||
return FAIL;
|
return FAIL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CLEAR_FIELD(ectx);
|
CLEAR_FIELD(ectx);
|
||||||
@@ -1726,6 +1729,15 @@ call_def_function(
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
// Create a global function from a lambda.
|
||||||
|
case ISN_NEWFUNC:
|
||||||
|
{
|
||||||
|
newfunc_T *newfunc = &iptr->isn_arg.newfunc;
|
||||||
|
|
||||||
|
copy_func(newfunc->nf_lambda, newfunc->nf_global);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
// jump if a condition is met
|
// jump if a condition is met
|
||||||
case ISN_JUMP:
|
case ISN_JUMP:
|
||||||
{
|
{
|
||||||
@@ -2912,6 +2924,15 @@ ex_disassemble(exarg_T *eap)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case ISN_NEWFUNC:
|
||||||
|
{
|
||||||
|
newfunc_T *newfunc = &iptr->isn_arg.newfunc;
|
||||||
|
|
||||||
|
smsg("%4d NEWFUNC %s %s", current,
|
||||||
|
newfunc->nf_lambda, newfunc->nf_global);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case ISN_JUMP:
|
case ISN_JUMP:
|
||||||
{
|
{
|
||||||
char *when = "?";
|
char *when = "?";
|
||||||
|
Reference in New Issue
Block a user