diff --git a/src/vim9compile.c b/src/vim9compile.c
index 4bce997..50fe7e2 100644
--- a/src/vim9compile.c
+++ b/src/vim9compile.c
@@ -8,7 +8,7 @@
  */
 
 /*
- * vim9compile.c: :def and dealing with instructions
+ * vim9compile.c: compiling a :def function
  */
 
 #define USING_FLOAT_STUFF
@@ -16,194 +16,15 @@
 
 #if defined(FEAT_EVAL) || defined(PROTO)
 
-#ifdef VMS
-# include <float.h>
+// When not generating protos this is included in proto.h
+#ifdef PROTO
+# include "vim9.h"
 #endif
 
-#define DEFINE_VIM9_GLOBALS
-#include "vim9.h"
-
-// values for ctx_skip
-typedef enum {
-    SKIP_NOT,		// condition is a constant, produce code
-    SKIP_YES,		// condition is a constant, do NOT produce code
-    SKIP_UNKNOWN	// condition is not a constant, produce code
-} skip_T;
-
-/*
- * Chain of jump instructions where the end label needs to be set.
- */
-typedef struct endlabel_S endlabel_T;
-struct endlabel_S {
-    endlabel_T	*el_next;	    // chain end_label locations
-    int		el_end_label;	    // instruction idx where to set end
-};
-
-/*
- * info specific for the scope of :if / elseif / else
- */
-typedef struct {
-    int		is_seen_else;
-    int		is_seen_skip_not;   // a block was unconditionally executed
-    int		is_had_return;	    // every block ends in :return
-    int		is_if_label;	    // instruction idx at IF or ELSEIF
-    endlabel_T	*is_end_label;	    // instructions to set end label
-} ifscope_T;
-
-/*
- * info specific for the scope of :while
- */
-typedef struct {
-    int		ws_top_label;	    // instruction idx at WHILE
-    endlabel_T	*ws_end_label;	    // instructions to set end
-} whilescope_T;
-
-/*
- * info specific for the scope of :for
- */
-typedef struct {
-    int		fs_top_label;	    // instruction idx at FOR
-    endlabel_T	*fs_end_label;	    // break instructions
-} forscope_T;
-
-/*
- * info specific for the scope of :try
- */
-typedef struct {
-    int		ts_try_label;	    // instruction idx at TRY
-    endlabel_T	*ts_end_label;	    // jump to :finally or :endtry
-    int		ts_catch_label;	    // instruction idx of last CATCH
-    int		ts_caught_all;	    // "catch" without argument encountered
-} tryscope_T;
-
-typedef enum {
-    NO_SCOPE,
-    IF_SCOPE,
-    WHILE_SCOPE,
-    FOR_SCOPE,
-    TRY_SCOPE,
-    BLOCK_SCOPE
-} scopetype_T;
-
-/*
- * Info for one scope, pointed to by "ctx_scope".
- */
-typedef struct scope_S scope_T;
-struct scope_S {
-    scope_T	*se_outer;	    // scope containing this one
-    scopetype_T se_type;
-    int		se_local_count;	    // ctx_locals.ga_len before scope
-    skip_T	se_skip_save;	    // ctx_skip before the block
-    union {
-	ifscope_T	se_if;
-	whilescope_T	se_while;
-	forscope_T	se_for;
-	tryscope_T	se_try;
-    } se_u;
-};
-
-/*
- * Entry for "ctx_locals".  Used for arguments and local variables.
- */
-typedef struct {
-    char_u	*lv_name;
-    type_T	*lv_type;
-    int		lv_idx;		// index of the variable on the stack
-    int		lv_from_outer;	// nesting level, using ctx_outer scope
-    int		lv_const;	// when TRUE cannot be assigned to
-    int		lv_arg;		// when TRUE this is an argument
-} lvar_T;
-
-// Destination for an assignment or ":unlet" with an index.
-typedef enum {
-    dest_local,
-    dest_option,
-    dest_func_option,
-    dest_env,
-    dest_global,
-    dest_buffer,
-    dest_window,
-    dest_tab,
-    dest_vimvar,
-    dest_script,
-    dest_reg,
-    dest_expr,
-} assign_dest_T;
-
-// Used by compile_lhs() to store information about the LHS of an assignment
-// and one argument of ":unlet" with an index.
-typedef struct {
-    assign_dest_T   lhs_dest;	    // type of destination
-
-    char_u	    *lhs_name;	    // allocated name excluding the last
-				    // "[expr]" or ".name".
-    size_t	    lhs_varlen;	    // length of the variable without
-				    // "[expr]" or ".name"
-    char_u	    *lhs_whole;	    // allocated name including the last
-				    // "[expr]" or ".name" for :redir
-    size_t	    lhs_varlen_total; // length of the variable including
-				      // any "[expr]" or ".name"
-    char_u	    *lhs_dest_end;  // end of the destination, including
-				    // "[expr]" or ".name".
-    char_u	    *lhs_end;	    // end including any type
-
-    int		    lhs_has_index;  // has "[expr]" or ".name"
-
-    int		    lhs_new_local;  // create new local variable
-    int		    lhs_opt_flags;  // for when destination is an option
-    int		    lhs_vimvaridx;  // for when destination is a v:var
-
-    lvar_T	    lhs_local_lvar; // used for existing local destination
-    lvar_T	    lhs_arg_lvar;   // used for argument destination
-    lvar_T	    *lhs_lvar;	    // points to destination lvar
-    int		    lhs_scriptvar_sid;
-    int		    lhs_scriptvar_idx;
-
-    int		    lhs_has_type;   // type was specified
-    type_T	    *lhs_type;
-    type_T	    *lhs_member_type;
-
-    int		    lhs_append;	    // used by ISN_REDIREND
-} lhs_T;
-
-/*
- * Context for compiling lines of Vim script.
- * Stores info about the local variables and condition stack.
- */
-struct cctx_S {
-    ufunc_T	*ctx_ufunc;	    // current function
-    int		ctx_lnum;	    // line number in current function
-    char_u	*ctx_line_start;    // start of current line or NULL
-    garray_T	ctx_instr;	    // generated instructions
-
-    int		ctx_prev_lnum;	    // line number below previous command, for
-				    // debugging
-
-    compiletype_T ctx_compile_type;
-
-    garray_T	ctx_locals;	    // currently visible local variables
-
-    int		ctx_has_closure;    // set to one if a closures was created in
-				    // the function
-
-    garray_T	ctx_imports;	    // imported items
-
-    skip_T	ctx_skip;
-    scope_T	*ctx_scope;	    // current scope, NULL at toplevel
-    int		ctx_had_return;	    // last seen statement was "return"
-
-    cctx_T	*ctx_outer;	    // outer scope for lambda or nested
-				    // function
-    int		ctx_outer_used;	    // var in ctx_outer was used
-
-    garray_T	ctx_type_stack;	    // type of each item on the stack
-    garray_T	*ctx_type_list;	    // list of pointers to allocated types
-
-    int		ctx_has_cmdmod;	    // ISN_CMDMOD was generated
-
-    lhs_T	ctx_redir_lhs;	    // LHS for ":redir => var", valid when
-				    // lhs_name is not NULL
-};
+// Functions defined with :def are stored in this growarray.
+// They are never removed, so that they can be found by index.
+// Deleted functions have the df_deleted flag set.
+garray_T def_functions = {0, 0, sizeof(dfunc_T), 50, NULL};
 
 static void delete_def_function_contents(dfunc_T *dfunc, int mark_deleted);
 
@@ -213,7 +34,7 @@
  * If "lvar" is NULL only check if the variable can be found.
  * Return FAIL if not found.
  */
-    static int
+    int
 lookup_local(char_u *name, size_t len, lvar_T *lvar, cctx_T *cctx)
 {
     int	    idx;
@@ -262,7 +83,7 @@
  * Sets "gen_load_outer" to TRUE if found in outer scope.
  * Returns OK when found, FAIL otherwise.
  */
-    static int
+    int
 arg_exists(
 	char_u	*name,
 	size_t	len,
@@ -397,7 +218,7 @@
 /*
  * Return TRUE if the script context is Vim9 script.
  */
-    static int
+    int
 script_is_vim9()
 {
     return SCRIPT_ITEM(current_sctx.sc_sid)->sn_version == SCRIPT_VERSION_VIM9;
@@ -408,7 +229,7 @@
  * "cctx" is NULL at the script level.
  * Returns OK or FAIL.
  */
-    static int
+    int
 script_var_exists(char_u *name, size_t len, cctx_T *cctx)
 {
     if (current_sctx.sc_sid <= 0)
@@ -533,493 +354,6 @@
 }
 
 
-/////////////////////////////////////////////////////////////////////
-// Following generate_ functions expect the caller to call ga_grow().
-
-#define RETURN_NULL_IF_SKIP(cctx) if (cctx->ctx_skip == SKIP_YES) return NULL
-#define RETURN_OK_IF_SKIP(cctx) if (cctx->ctx_skip == SKIP_YES) return OK
-
-/*
- * Generate an instruction without arguments.
- * Returns a pointer to the new instruction, NULL if failed.
- */
-    static isn_T *
-generate_instr(cctx_T *cctx, isntype_T isn_type)
-{
-    garray_T	*instr = &cctx->ctx_instr;
-    isn_T	*isn;
-
-    RETURN_NULL_IF_SKIP(cctx);
-    if (GA_GROW_FAILS(instr, 1))
-	return NULL;
-    isn = ((isn_T *)instr->ga_data) + instr->ga_len;
-    isn->isn_type = isn_type;
-    isn->isn_lnum = cctx->ctx_lnum + 1;
-    ++instr->ga_len;
-
-    return isn;
-}
-
-/*
- * Generate an instruction without arguments.
- * "drop" will be removed from the stack.
- * Returns a pointer to the new instruction, NULL if failed.
- */
-    static isn_T *
-generate_instr_drop(cctx_T *cctx, isntype_T isn_type, int drop)
-{
-    garray_T	*stack = &cctx->ctx_type_stack;
-
-    RETURN_NULL_IF_SKIP(cctx);
-    stack->ga_len -= drop;
-    return generate_instr(cctx, isn_type);
-}
-
-/*
- * Generate instruction "isn_type" and put "type" on the type stack.
- */
-    static isn_T *
-generate_instr_type(cctx_T *cctx, isntype_T isn_type, type_T *type)
-{
-    isn_T	*isn;
-    garray_T	*stack = &cctx->ctx_type_stack;
-
-    if ((isn = generate_instr(cctx, isn_type)) == NULL)
-	return NULL;
-
-    if (GA_GROW_FAILS(stack, 1))
-	return NULL;
-    ((type_T **)stack->ga_data)[stack->ga_len] = type == NULL ? &t_any : type;
-    ++stack->ga_len;
-
-    return isn;
-}
-
-/*
- * Generate an ISN_DEBUG instruction.
- */
-    static isn_T *
-generate_instr_debug(cctx_T *cctx)
-{
-    isn_T	*isn;
-    dfunc_T	*dfunc = ((dfunc_T *)def_functions.ga_data)
-					       + cctx->ctx_ufunc->uf_dfunc_idx;
-
-    if ((isn = generate_instr(cctx, ISN_DEBUG)) == NULL)
-	return NULL;
-    isn->isn_arg.debug.dbg_var_names_len = dfunc->df_var_names.ga_len;
-    isn->isn_arg.debug.dbg_break_lnum = cctx->ctx_prev_lnum;
-    return isn;
-}
-
-/*
- * If type at "offset" isn't already VAR_STRING then generate ISN_2STRING.
- * But only for simple types.
- * When "tolerant" is TRUE convert most types to string, e.g. a List.
- */
-    static int
-may_generate_2STRING(int offset, int tolerant, cctx_T *cctx)
-{
-    isn_T	*isn;
-    isntype_T	isntype = ISN_2STRING;
-    garray_T	*stack = &cctx->ctx_type_stack;
-    type_T	**type;
-
-    RETURN_OK_IF_SKIP(cctx);
-    type = ((type_T **)stack->ga_data) + stack->ga_len + offset;
-    switch ((*type)->tt_type)
-    {
-	// nothing to be done
-	case VAR_STRING: return OK;
-
-	// conversion possible
-	case VAR_SPECIAL:
-	case VAR_BOOL:
-	case VAR_NUMBER:
-	case VAR_FLOAT:
-			 break;
-
-	// conversion possible (with runtime check)
-	case VAR_ANY:
-	case VAR_UNKNOWN:
-			 isntype = ISN_2STRING_ANY;
-			 break;
-
-	// conversion possible when tolerant
-	case VAR_LIST:
-			 if (tolerant)
-			 {
-			     isntype = ISN_2STRING_ANY;
-			     break;
-			 }
-			 // FALLTHROUGH
-
-	// conversion not possible
-	case VAR_VOID:
-	case VAR_BLOB:
-	case VAR_FUNC:
-	case VAR_PARTIAL:
-	case VAR_DICT:
-	case VAR_JOB:
-	case VAR_CHANNEL:
-	case VAR_INSTR:
-			 to_string_error((*type)->tt_type);
-			 return FAIL;
-    }
-
-    *type = &t_string;
-    if ((isn = generate_instr(cctx, isntype)) == NULL)
-	return FAIL;
-    isn->isn_arg.tostring.offset = offset;
-    isn->isn_arg.tostring.tolerant = tolerant;
-
-    return OK;
-}
-
-    static int
-check_number_or_float(vartype_T type1, vartype_T type2, char_u *op)
-{
-    if (!((type1 == VAR_NUMBER || type1 == VAR_FLOAT || type1 == VAR_ANY)
-	    && (type2 == VAR_NUMBER || type2 == VAR_FLOAT
-							 || type2 == VAR_ANY)))
-    {
-	if (*op == '+')
-	    emsg(_(e_wrong_argument_type_for_plus));
-	else
-	    semsg(_(e_char_requires_number_or_float_arguments), *op);
-	return FAIL;
-    }
-    return OK;
-}
-
-/*
- * Generate instruction for "+".  For a list this creates a new list.
- */
-    static int
-generate_add_instr(
-	cctx_T *cctx,
-	vartype_T vartype,
-	type_T *type1,
-	type_T *type2,
-	exprtype_T expr_type)
-{
-    garray_T	*stack = &cctx->ctx_type_stack;
-    isn_T	*isn = generate_instr_drop(cctx,
-		      vartype == VAR_NUMBER ? ISN_OPNR
-		    : vartype == VAR_LIST ? ISN_ADDLIST
-		    : vartype == VAR_BLOB ? ISN_ADDBLOB
-#ifdef FEAT_FLOAT
-		    : vartype == VAR_FLOAT ? ISN_OPFLOAT
-#endif
-		    : ISN_OPANY, 1);
-
-    if (vartype != VAR_LIST && vartype != VAR_BLOB
-	    && type1->tt_type != VAR_ANY
-	    && type2->tt_type != VAR_ANY
-	    && check_number_or_float(
-			type1->tt_type, type2->tt_type, (char_u *)"+") == FAIL)
-	return FAIL;
-
-    if (isn != NULL)
-    {
-	if (isn->isn_type == ISN_ADDLIST)
-	    isn->isn_arg.op.op_type = expr_type;
-	else
-	    isn->isn_arg.op.op_type = EXPR_ADD;
-    }
-
-    // When concatenating two lists with different member types the member type
-    // becomes "any".
-    if (vartype == VAR_LIST
-	    && type1->tt_type == VAR_LIST && type2->tt_type == VAR_LIST
-	    && type1->tt_member != type2->tt_member)
-	(((type_T **)stack->ga_data)[stack->ga_len - 1]) = &t_list_any;
-
-    return isn == NULL ? FAIL : OK;
-}
-
-/*
- * Get the type to use for an instruction for an operation on "type1" and
- * "type2".  If they are matching use a type-specific instruction. Otherwise
- * fall back to runtime type checking.
- */
-    static vartype_T
-operator_type(type_T *type1, type_T *type2)
-{
-    if (type1->tt_type == type2->tt_type
-	    && (type1->tt_type == VAR_NUMBER
-		|| type1->tt_type == VAR_LIST
-#ifdef FEAT_FLOAT
-		|| type1->tt_type == VAR_FLOAT
-#endif
-		|| type1->tt_type == VAR_BLOB))
-	return type1->tt_type;
-    return VAR_ANY;
-}
-
-/*
- * Generate an instruction with two arguments.  The instruction depends on the
- * type of the arguments.
- */
-    static int
-generate_two_op(cctx_T *cctx, char_u *op)
-{
-    garray_T	*stack = &cctx->ctx_type_stack;
-    type_T	*type1;
-    type_T	*type2;
-    vartype_T	vartype;
-    isn_T	*isn;
-
-    RETURN_OK_IF_SKIP(cctx);
-
-    // Get the known type of the two items on the stack.
-    type1 = ((type_T **)stack->ga_data)[stack->ga_len - 2];
-    type2 = ((type_T **)stack->ga_data)[stack->ga_len - 1];
-    vartype = operator_type(type1, type2);
-
-    switch (*op)
-    {
-	case '+':
-		  if (generate_add_instr(cctx, vartype, type1, type2,
-							    EXPR_COPY) == FAIL)
-		      return FAIL;
-		  break;
-
-	case '-':
-	case '*':
-	case '/': if (check_number_or_float(type1->tt_type, type2->tt_type,
-								   op) == FAIL)
-		      return FAIL;
-		  if (vartype == VAR_NUMBER)
-		      isn = generate_instr_drop(cctx, ISN_OPNR, 1);
-#ifdef FEAT_FLOAT
-		  else if (vartype == VAR_FLOAT)
-		      isn = generate_instr_drop(cctx, ISN_OPFLOAT, 1);
-#endif
-		  else
-		      isn = generate_instr_drop(cctx, ISN_OPANY, 1);
-		  if (isn != NULL)
-		      isn->isn_arg.op.op_type = *op == '*'
-				 ? EXPR_MULT : *op == '/'? EXPR_DIV : EXPR_SUB;
-		  break;
-
-	case '%': if ((type1->tt_type != VAR_ANY
-					       && type1->tt_type != VAR_NUMBER)
-			  || (type2->tt_type != VAR_ANY
-					      && type2->tt_type != VAR_NUMBER))
-		  {
-		      emsg(_(e_percent_requires_number_arguments));
-		      return FAIL;
-		  }
-		  isn = generate_instr_drop(cctx,
-			      vartype == VAR_NUMBER ? ISN_OPNR : ISN_OPANY, 1);
-		  if (isn != NULL)
-		      isn->isn_arg.op.op_type = EXPR_REM;
-		  break;
-    }
-
-    // correct type of result
-    if (vartype == VAR_ANY)
-    {
-	type_T *type = &t_any;
-
-#ifdef FEAT_FLOAT
-	// float+number and number+float results in float
-	if ((type1->tt_type == VAR_NUMBER || type1->tt_type == VAR_FLOAT)
-		&& (type2->tt_type == VAR_NUMBER || type2->tt_type == VAR_FLOAT))
-	    type = &t_float;
-#endif
-	((type_T **)stack->ga_data)[stack->ga_len - 1] = type;
-    }
-
-    return OK;
-}
-
-/*
- * Get the instruction to use for comparing "type1" with "type2"
- * Return ISN_DROP when failed.
- */
-    static isntype_T
-get_compare_isn(exprtype_T exprtype, vartype_T type1, vartype_T type2)
-{
-    isntype_T	isntype = ISN_DROP;
-
-    if (type1 == VAR_UNKNOWN)
-	type1 = VAR_ANY;
-    if (type2 == VAR_UNKNOWN)
-	type2 = VAR_ANY;
-
-    if (type1 == type2)
-    {
-	switch (type1)
-	{
-	    case VAR_BOOL: isntype = ISN_COMPAREBOOL; break;
-	    case VAR_SPECIAL: isntype = ISN_COMPARESPECIAL; break;
-	    case VAR_NUMBER: isntype = ISN_COMPARENR; break;
-	    case VAR_FLOAT: isntype = ISN_COMPAREFLOAT; break;
-	    case VAR_STRING: isntype = ISN_COMPARESTRING; break;
-	    case VAR_BLOB: isntype = ISN_COMPAREBLOB; break;
-	    case VAR_LIST: isntype = ISN_COMPARELIST; break;
-	    case VAR_DICT: isntype = ISN_COMPAREDICT; break;
-	    case VAR_FUNC: isntype = ISN_COMPAREFUNC; break;
-	    default: isntype = ISN_COMPAREANY; break;
-	}
-    }
-    else if (type1 == VAR_ANY || type2 == VAR_ANY
-	    || ((type1 == VAR_NUMBER || type1 == VAR_FLOAT)
-	      && (type2 == VAR_NUMBER || type2 == VAR_FLOAT)))
-	isntype = ISN_COMPAREANY;
-
-    if ((exprtype == EXPR_IS || exprtype == EXPR_ISNOT)
-	    && (isntype == ISN_COMPAREBOOL
-	    || isntype == ISN_COMPARESPECIAL
-	    || isntype == ISN_COMPARENR
-	    || isntype == ISN_COMPAREFLOAT))
-    {
-	semsg(_(e_cannot_use_str_with_str),
-		exprtype == EXPR_IS ? "is" : "isnot" , vartype_name(type1));
-	return ISN_DROP;
-    }
-    if (isntype == ISN_DROP
-	    || ((exprtype != EXPR_EQUAL && exprtype != EXPR_NEQUAL
-		    && (type1 == VAR_BOOL || type1 == VAR_SPECIAL
-		       || type2 == VAR_BOOL || type2 == VAR_SPECIAL)))
-	    || ((exprtype != EXPR_EQUAL && exprtype != EXPR_NEQUAL
-				 && exprtype != EXPR_IS && exprtype != EXPR_ISNOT
-		    && (type1 == VAR_BLOB || type2 == VAR_BLOB
-			|| type1 == VAR_LIST || type2 == VAR_LIST))))
-    {
-	semsg(_(e_cannot_compare_str_with_str),
-		vartype_name(type1), vartype_name(type2));
-	return ISN_DROP;
-    }
-    return isntype;
-}
-
-    int
-check_compare_types(exprtype_T type, typval_T *tv1, typval_T *tv2)
-{
-    if (get_compare_isn(type, tv1->v_type, tv2->v_type) == ISN_DROP)
-	return FAIL;
-    return OK;
-}
-
-/*
- * Generate an ISN_COMPARE* instruction with a boolean result.
- */
-    static int
-generate_COMPARE(cctx_T *cctx, exprtype_T exprtype, int ic)
-{
-    isntype_T	isntype;
-    isn_T	*isn;
-    garray_T	*stack = &cctx->ctx_type_stack;
-    vartype_T	type1;
-    vartype_T	type2;
-
-    RETURN_OK_IF_SKIP(cctx);
-
-    // Get the known type of the two items on the stack.  If they are matching
-    // use a type-specific instruction. Otherwise fall back to runtime type
-    // checking.
-    type1 = ((type_T **)stack->ga_data)[stack->ga_len - 2]->tt_type;
-    type2 = ((type_T **)stack->ga_data)[stack->ga_len - 1]->tt_type;
-    isntype = get_compare_isn(exprtype, type1, type2);
-    if (isntype == ISN_DROP)
-	return FAIL;
-
-    if ((isn = generate_instr(cctx, isntype)) == NULL)
-	return FAIL;
-    isn->isn_arg.op.op_type = exprtype;
-    isn->isn_arg.op.op_ic = ic;
-
-    // takes two arguments, puts one bool back
-    if (stack->ga_len >= 2)
-    {
-	--stack->ga_len;
-	((type_T **)stack->ga_data)[stack->ga_len - 1] = &t_bool;
-    }
-
-    return OK;
-}
-
-/*
- * Generate an ISN_2BOOL instruction.
- * "offset" is the offset in the type stack.
- */
-    static int
-generate_2BOOL(cctx_T *cctx, int invert, int offset)
-{
-    isn_T	*isn;
-    garray_T	*stack = &cctx->ctx_type_stack;
-
-    RETURN_OK_IF_SKIP(cctx);
-    if ((isn = generate_instr(cctx, ISN_2BOOL)) == NULL)
-	return FAIL;
-    isn->isn_arg.tobool.invert = invert;
-    isn->isn_arg.tobool.offset = offset;
-
-    // type becomes bool
-    ((type_T **)stack->ga_data)[stack->ga_len + offset] = &t_bool;
-
-    return OK;
-}
-
-/*
- * Generate an ISN_COND2BOOL instruction.
- */
-    static int
-generate_COND2BOOL(cctx_T *cctx)
-{
-    isn_T	*isn;
-    garray_T	*stack = &cctx->ctx_type_stack;
-
-    RETURN_OK_IF_SKIP(cctx);
-    if ((isn = generate_instr(cctx, ISN_COND2BOOL)) == NULL)
-	return FAIL;
-
-    // type becomes bool
-    ((type_T **)stack->ga_data)[stack->ga_len - 1] = &t_bool;
-
-    return OK;
-}
-
-    static int
-generate_TYPECHECK(
-	cctx_T	    *cctx,
-	type_T	    *expected,
-	int	    offset,
-	int	    argidx)
-{
-    isn_T	*isn;
-    garray_T	*stack = &cctx->ctx_type_stack;
-
-    RETURN_OK_IF_SKIP(cctx);
-    if ((isn = generate_instr(cctx, ISN_CHECKTYPE)) == NULL)
-	return FAIL;
-    isn->isn_arg.type.ct_type = alloc_type(expected);
-    isn->isn_arg.type.ct_off = (int8_T)offset;
-    isn->isn_arg.type.ct_arg_idx = (int8_T)argidx;
-
-    // type becomes expected
-    ((type_T **)stack->ga_data)[stack->ga_len + offset] = expected;
-
-    return OK;
-}
-
-    static int
-generate_SETTYPE(
-	cctx_T	    *cctx,
-	type_T	    *expected)
-{
-    isn_T	*isn;
-
-    RETURN_OK_IF_SKIP(cctx);
-    if ((isn = generate_instr(cctx, ISN_SETTYPE)) == NULL)
-	return FAIL;
-    isn->isn_arg.type.ct_type = alloc_type(expected);
-    return OK;
-}
-
 /*
  * Return TRUE if "actual" could be "expected" and a runtime typecheck is to be
  * used.  Return FALSE if the types will never match.
@@ -1108,1397 +442,10 @@
 }
 
 /*
- * Check that the top of the type stack has a type that can be used as a
- * condition.  Give an error and return FAIL if not.
- */
-    static int
-bool_on_stack(cctx_T *cctx)
-{
-    garray_T	*stack = &cctx->ctx_type_stack;
-    type_T	*type;
-
-    type = ((type_T **)stack->ga_data)[stack->ga_len - 1];
-    if (type == &t_bool)
-	return OK;
-
-    if (type == &t_any || type == &t_number || type == &t_number_bool)
-	// Number 0 and 1 are OK to use as a bool.  "any" could also be a bool.
-	// This requires a runtime type check.
-	return generate_COND2BOOL(cctx);
-
-    return need_type(type, &t_bool, -1, 0, cctx, FALSE, FALSE);
-}
-
-/*
- * Generate an ISN_PUSHNR instruction.
- */
-    static int
-generate_PUSHNR(cctx_T *cctx, varnumber_T number)
-{
-    isn_T	*isn;
-    garray_T	*stack = &cctx->ctx_type_stack;
-
-    RETURN_OK_IF_SKIP(cctx);
-    if ((isn = generate_instr_type(cctx, ISN_PUSHNR, &t_number)) == NULL)
-	return FAIL;
-    isn->isn_arg.number = number;
-
-    if (number == 0 || number == 1)
-	// A 0 or 1 number can also be used as a bool.
-	((type_T **)stack->ga_data)[stack->ga_len - 1] = &t_number_bool;
-    return OK;
-}
-
-/*
- * Generate an ISN_PUSHBOOL instruction.
- */
-    static int
-generate_PUSHBOOL(cctx_T *cctx, varnumber_T number)
-{
-    isn_T	*isn;
-
-    RETURN_OK_IF_SKIP(cctx);
-    if ((isn = generate_instr_type(cctx, ISN_PUSHBOOL, &t_bool)) == NULL)
-	return FAIL;
-    isn->isn_arg.number = number;
-
-    return OK;
-}
-
-/*
- * Generate an ISN_PUSHSPEC instruction.
- */
-    static int
-generate_PUSHSPEC(cctx_T *cctx, varnumber_T number)
-{
-    isn_T	*isn;
-
-    RETURN_OK_IF_SKIP(cctx);
-    if ((isn = generate_instr_type(cctx, ISN_PUSHSPEC, &t_special)) == NULL)
-	return FAIL;
-    isn->isn_arg.number = number;
-
-    return OK;
-}
-
-#ifdef FEAT_FLOAT
-/*
- * Generate an ISN_PUSHF instruction.
- */
-    static int
-generate_PUSHF(cctx_T *cctx, float_T fnumber)
-{
-    isn_T	*isn;
-
-    RETURN_OK_IF_SKIP(cctx);
-    if ((isn = generate_instr_type(cctx, ISN_PUSHF, &t_float)) == NULL)
-	return FAIL;
-    isn->isn_arg.fnumber = fnumber;
-
-    return OK;
-}
-#endif
-
-/*
- * Generate an ISN_PUSHS instruction.
- * Consumes "*str".  When freed *str is set to NULL, unless "str" is NULL.
- */
-    static int
-generate_PUSHS(cctx_T *cctx, char_u **str)
-{
-    isn_T	*isn;
-
-    if (cctx->ctx_skip == SKIP_YES)
-    {
-	if (str != NULL)
-	    VIM_CLEAR(*str);
-	return OK;
-    }
-    if ((isn = generate_instr_type(cctx, ISN_PUSHS, &t_string)) == NULL)
-    {
-	if (str != NULL)
-	    VIM_CLEAR(*str);
-	return FAIL;
-    }
-    isn->isn_arg.string = str == NULL ? NULL : *str;
-
-    return OK;
-}
-
-/*
- * Generate an ISN_PUSHCHANNEL instruction.
- * Consumes "channel".
- */
-    static int
-generate_PUSHCHANNEL(cctx_T *cctx, channel_T *channel)
-{
-    isn_T	*isn;
-
-    RETURN_OK_IF_SKIP(cctx);
-    if ((isn = generate_instr_type(cctx, ISN_PUSHCHANNEL, &t_channel)) == NULL)
-	return FAIL;
-    isn->isn_arg.channel = channel;
-
-    return OK;
-}
-
-/*
- * Generate an ISN_PUSHJOB instruction.
- * Consumes "job".
- */
-    static int
-generate_PUSHJOB(cctx_T *cctx, job_T *job)
-{
-    isn_T	*isn;
-
-    RETURN_OK_IF_SKIP(cctx);
-    if ((isn = generate_instr_type(cctx, ISN_PUSHJOB, &t_channel)) == NULL)
-	return FAIL;
-    isn->isn_arg.job = job;
-
-    return OK;
-}
-
-/*
- * Generate an ISN_PUSHBLOB instruction.
- * Consumes "blob".
- */
-    static int
-generate_PUSHBLOB(cctx_T *cctx, blob_T *blob)
-{
-    isn_T	*isn;
-
-    RETURN_OK_IF_SKIP(cctx);
-    if ((isn = generate_instr_type(cctx, ISN_PUSHBLOB, &t_blob)) == NULL)
-	return FAIL;
-    isn->isn_arg.blob = blob;
-
-    return OK;
-}
-
-/*
- * Generate an ISN_PUSHFUNC instruction with name "name".
- * Consumes "name".
- */
-    static int
-generate_PUSHFUNC(cctx_T *cctx, char_u *name, type_T *type)
-{
-    isn_T	*isn;
-    char_u	*funcname;
-
-    RETURN_OK_IF_SKIP(cctx);
-    if ((isn = generate_instr_type(cctx, ISN_PUSHFUNC, type)) == NULL)
-	return FAIL;
-    if (name == NULL)
-	funcname = NULL;
-    else if (*name == K_SPECIAL)  // script-local
-	funcname = vim_strsave(name);
-    else
-    {
-	funcname = alloc(STRLEN(name) + 3);
-	if (funcname != NULL)
-	{
-	    STRCPY(funcname, "g:");
-	    STRCPY(funcname + 2, name);
-	}
-    }
-
-    isn->isn_arg.string = funcname;
-    return OK;
-}
-
-/*
- * Generate an ISN_GETITEM instruction with "index".
- * "with_op" is TRUE for "+=" and other operators, the stack has the current
- * value below the list with values.
- */
-    static int
-generate_GETITEM(cctx_T *cctx, int index, int with_op)
-{
-    isn_T	*isn;
-    garray_T	*stack = &cctx->ctx_type_stack;
-    type_T	*type = ((type_T **)stack->ga_data)[stack->ga_len
-							  - (with_op ? 2 : 1)];
-    type_T	*item_type = &t_any;
-
-    RETURN_OK_IF_SKIP(cctx);
-
-    if (type->tt_type != VAR_LIST)
-    {
-	// cannot happen, caller has checked the type
-	emsg(_(e_listreq));
-	return FAIL;
-    }
-    item_type = type->tt_member;
-    if ((isn = generate_instr(cctx, ISN_GETITEM)) == NULL)
-	return FAIL;
-    isn->isn_arg.getitem.gi_index = index;
-    isn->isn_arg.getitem.gi_with_op = with_op;
-
-    // add the item type to the type stack
-    if (GA_GROW_FAILS(stack, 1))
-	return FAIL;
-    ((type_T **)stack->ga_data)[stack->ga_len] = item_type;
-    ++stack->ga_len;
-    return OK;
-}
-
-/*
- * Generate an ISN_SLICE instruction with "count".
- */
-    static int
-generate_SLICE(cctx_T *cctx, int count)
-{
-    isn_T	*isn;
-
-    RETURN_OK_IF_SKIP(cctx);
-    if ((isn = generate_instr(cctx, ISN_SLICE)) == NULL)
-	return FAIL;
-    isn->isn_arg.number = count;
-    return OK;
-}
-
-/*
- * Generate an ISN_CHECKLEN instruction with "min_len".
- */
-    static int
-generate_CHECKLEN(cctx_T *cctx, int min_len, int more_OK)
-{
-    isn_T	*isn;
-
-    RETURN_OK_IF_SKIP(cctx);
-
-    if ((isn = generate_instr(cctx, ISN_CHECKLEN)) == NULL)
-	return FAIL;
-    isn->isn_arg.checklen.cl_min_len = min_len;
-    isn->isn_arg.checklen.cl_more_OK = more_OK;
-
-    return OK;
-}
-
-/*
- * Generate an ISN_STORE instruction.
- */
-    static int
-generate_STORE(cctx_T *cctx, isntype_T isn_type, int idx, char_u *name)
-{
-    isn_T	*isn;
-
-    RETURN_OK_IF_SKIP(cctx);
-    if ((isn = generate_instr_drop(cctx, isn_type, 1)) == NULL)
-	return FAIL;
-    if (name != NULL)
-	isn->isn_arg.string = vim_strsave(name);
-    else
-	isn->isn_arg.number = idx;
-
-    return OK;
-}
-
-/*
- * Generate an ISN_STOREOUTER instruction.
- */
-    static int
-generate_STOREOUTER(cctx_T *cctx, int idx, int level)
-{
-    isn_T	*isn;
-
-    RETURN_OK_IF_SKIP(cctx);
-    if ((isn = generate_instr_drop(cctx, ISN_STOREOUTER, 1)) == NULL)
-	return FAIL;
-    isn->isn_arg.outer.outer_idx = idx;
-    isn->isn_arg.outer.outer_depth = level;
-
-    return OK;
-}
-
-/*
- * Generate an ISN_STORENR instruction (short for ISN_PUSHNR + ISN_STORE)
- */
-    static int
-generate_STORENR(cctx_T *cctx, int idx, varnumber_T value)
-{
-    isn_T	*isn;
-
-    RETURN_OK_IF_SKIP(cctx);
-    if ((isn = generate_instr(cctx, ISN_STORENR)) == NULL)
-	return FAIL;
-    isn->isn_arg.storenr.stnr_idx = idx;
-    isn->isn_arg.storenr.stnr_val = value;
-
-    return OK;
-}
-
-/*
- * Generate an ISN_STOREOPT or ISN_STOREFUNCOPT instruction
- */
-    static int
-generate_STOREOPT(
-	cctx_T	    *cctx,
-	isntype_T   isn_type,
-	char_u	    *name,
-	int	    opt_flags)
-{
-    isn_T	*isn;
-
-    RETURN_OK_IF_SKIP(cctx);
-    if ((isn = generate_instr_drop(cctx, isn_type, 1)) == NULL)
-	return FAIL;
-    isn->isn_arg.storeopt.so_name = vim_strsave(name);
-    isn->isn_arg.storeopt.so_flags = opt_flags;
-
-    return OK;
-}
-
-/*
- * Generate an ISN_LOAD or similar instruction.
- */
-    static int
-generate_LOAD(
-	cctx_T	    *cctx,
-	isntype_T   isn_type,
-	int	    idx,
-	char_u	    *name,
-	type_T	    *type)
-{
-    isn_T	*isn;
-
-    RETURN_OK_IF_SKIP(cctx);
-    if ((isn = generate_instr_type(cctx, isn_type, type)) == NULL)
-	return FAIL;
-    if (name != NULL)
-	isn->isn_arg.string = vim_strsave(name);
-    else
-	isn->isn_arg.number = idx;
-
-    return OK;
-}
-
-/*
- * Generate an ISN_LOADOUTER instruction
- */
-    static int
-generate_LOADOUTER(
-	cctx_T	    *cctx,
-	int	    idx,
-	int	    nesting,
-	type_T	    *type)
-{
-    isn_T	*isn;
-
-    RETURN_OK_IF_SKIP(cctx);
-    if ((isn = generate_instr_type(cctx, ISN_LOADOUTER, type)) == NULL)
-	return FAIL;
-    isn->isn_arg.outer.outer_idx = idx;
-    isn->isn_arg.outer.outer_depth = nesting;
-
-    return OK;
-}
-
-/*
- * Generate an ISN_LOADV instruction for v:var.
- */
-    static int
-generate_LOADV(
-	cctx_T	    *cctx,
-	char_u	    *name,
-	int	    error)
-{
-    int	    di_flags;
-    int	    vidx = find_vim_var(name, &di_flags);
-    type_T  *type;
-
-    RETURN_OK_IF_SKIP(cctx);
-    if (vidx < 0)
-    {
-	if (error)
-	    semsg(_(e_variable_not_found_str), name);
-	return FAIL;
-    }
-    type = typval2type_vimvar(get_vim_var_tv(vidx), cctx->ctx_type_list);
-
-    return generate_LOAD(cctx, ISN_LOADV, vidx, NULL, type);
-}
-
-/*
- * Generate an ISN_UNLET instruction.
- */
-    static int
-generate_UNLET(cctx_T *cctx, isntype_T isn_type, char_u *name, int forceit)
-{
-    isn_T	*isn;
-
-    RETURN_OK_IF_SKIP(cctx);
-    if ((isn = generate_instr(cctx, isn_type)) == NULL)
-	return FAIL;
-    isn->isn_arg.unlet.ul_name = vim_strsave(name);
-    isn->isn_arg.unlet.ul_forceit = forceit;
-
-    return OK;
-}
-
-/*
- * Generate an ISN_LOCKCONST instruction.
- */
-    static int
-generate_LOCKCONST(cctx_T *cctx)
-{
-    isn_T	*isn;
-
-    RETURN_OK_IF_SKIP(cctx);
-    if ((isn = generate_instr(cctx, ISN_LOCKCONST)) == NULL)
-	return FAIL;
-    return OK;
-}
-
-/*
- * Generate an ISN_LOADS instruction.
- */
-    static int
-generate_OLDSCRIPT(
-	cctx_T	    *cctx,
-	isntype_T   isn_type,
-	char_u	    *name,
-	int	    sid,
-	type_T	    *type)
-{
-    isn_T	*isn;
-
-    RETURN_OK_IF_SKIP(cctx);
-    if (isn_type == ISN_LOADS)
-	isn = generate_instr_type(cctx, isn_type, type);
-    else
-	isn = generate_instr_drop(cctx, isn_type, 1);
-    if (isn == NULL)
-	return FAIL;
-    isn->isn_arg.loadstore.ls_name = vim_strsave(name);
-    isn->isn_arg.loadstore.ls_sid = sid;
-
-    return OK;
-}
-
-/*
- * Generate an ISN_LOADSCRIPT or ISN_STORESCRIPT instruction.
- */
-    static int
-generate_VIM9SCRIPT(
-	cctx_T	    *cctx,
-	isntype_T   isn_type,
-	int	    sid,
-	int	    idx,
-	type_T	    *type)
-{
-    isn_T	*isn;
-    scriptref_T	*sref;
-    scriptitem_T *si = SCRIPT_ITEM(sid);
-
-    RETURN_OK_IF_SKIP(cctx);
-    if (isn_type == ISN_LOADSCRIPT)
-	isn = generate_instr_type(cctx, isn_type, type);
-    else
-	isn = generate_instr_drop(cctx, isn_type, 1);
-    if (isn == NULL)
-	return FAIL;
-
-    // This requires three arguments, which doesn't fit in an instruction, thus
-    // we need to allocate a struct for this.
-    sref = ALLOC_ONE(scriptref_T);
-    if (sref == NULL)
-	return FAIL;
-    isn->isn_arg.script.scriptref = sref;
-    sref->sref_sid = sid;
-    sref->sref_idx = idx;
-    sref->sref_seq = si->sn_script_seq;
-    sref->sref_type = type;
-    return OK;
-}
-
-/*
- * Generate an ISN_NEWLIST instruction.
- */
-    static int
-generate_NEWLIST(cctx_T *cctx, int count)
-{
-    isn_T	*isn;
-    garray_T	*stack = &cctx->ctx_type_stack;
-    type_T	*type;
-    type_T	*member;
-
-    RETURN_OK_IF_SKIP(cctx);
-    if ((isn = generate_instr(cctx, ISN_NEWLIST)) == NULL)
-	return FAIL;
-    isn->isn_arg.number = count;
-
-    // get the member type from all the items on the stack.
-    if (count == 0)
-	member = &t_unknown;
-    else
-	member = get_member_type_from_stack(
-	    ((type_T **)stack->ga_data) + stack->ga_len, count, 1,
-							  cctx->ctx_type_list);
-    type = get_list_type(member, cctx->ctx_type_list);
-
-    // drop the value types
-    stack->ga_len -= count;
-
-    // add the list type to the type stack
-    if (GA_GROW_FAILS(stack, 1))
-	return FAIL;
-    ((type_T **)stack->ga_data)[stack->ga_len] = type;
-    ++stack->ga_len;
-
-    return OK;
-}
-
-/*
- * Generate an ISN_NEWDICT instruction.
- */
-    static int
-generate_NEWDICT(cctx_T *cctx, int count)
-{
-    isn_T	*isn;
-    garray_T	*stack = &cctx->ctx_type_stack;
-    type_T	*type;
-    type_T	*member;
-
-    RETURN_OK_IF_SKIP(cctx);
-    if ((isn = generate_instr(cctx, ISN_NEWDICT)) == NULL)
-	return FAIL;
-    isn->isn_arg.number = count;
-
-    if (count == 0)
-	member = &t_void;
-    else
-	member = get_member_type_from_stack(
-	    ((type_T **)stack->ga_data) + stack->ga_len, count, 2,
-							  cctx->ctx_type_list);
-    type = get_dict_type(member, cctx->ctx_type_list);
-
-    // drop the key and value types
-    stack->ga_len -= 2 * count;
-
-    // add the dict type to the type stack
-    if (GA_GROW_FAILS(stack, 1))
-	return FAIL;
-    ((type_T **)stack->ga_data)[stack->ga_len] = type;
-    ++stack->ga_len;
-
-    return OK;
-}
-
-/*
- * Generate an ISN_FUNCREF instruction.
- */
-    static int
-generate_FUNCREF(cctx_T *cctx, ufunc_T *ufunc)
-{
-    isn_T	*isn;
-    garray_T	*stack = &cctx->ctx_type_stack;
-
-    RETURN_OK_IF_SKIP(cctx);
-    if ((isn = generate_instr(cctx, ISN_FUNCREF)) == NULL)
-	return FAIL;
-    if (ufunc->uf_def_status == UF_NOT_COMPILED)
-	isn->isn_arg.funcref.fr_func_name = vim_strsave(ufunc->uf_name);
-    else
-	isn->isn_arg.funcref.fr_dfunc_idx = ufunc->uf_dfunc_idx;
-    cctx->ctx_has_closure = 1;
-
-    // If the referenced function is a closure, it may use items further up in
-    // the nested context, including this one.
-    if (ufunc->uf_flags & FC_CLOSURE)
-	cctx->ctx_ufunc->uf_flags |= FC_CLOSURE;
-
-    if (GA_GROW_FAILS(stack, 1))
-	return FAIL;
-    ((type_T **)stack->ga_data)[stack->ga_len] =
-	       ufunc->uf_func_type == NULL ? &t_func_any : ufunc->uf_func_type;
-    ++stack->ga_len;
-
-    return OK;
-}
-
-/*
- * Generate an ISN_NEWFUNC instruction.
- * "lambda_name" and "func_name" must be in allocated memory and will be
- * consumed.
- */
-    static int
-generate_NEWFUNC(cctx_T *cctx, char_u *lambda_name, char_u *func_name)
-{
-    isn_T	*isn;
-
-    if (cctx->ctx_skip == SKIP_YES)
-    {
-	vim_free(lambda_name);
-	vim_free(func_name);
-	return OK;
-    }
-    if ((isn = generate_instr(cctx, ISN_NEWFUNC)) == NULL)
-    {
-	vim_free(lambda_name);
-	vim_free(func_name);
-	return FAIL;
-    }
-    isn->isn_arg.newfunc.nf_lambda = lambda_name;
-    isn->isn_arg.newfunc.nf_global = func_name;
-
-    return OK;
-}
-
-/*
- * 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
-generate_JUMP(cctx_T *cctx, jumpwhen_T when, int where)
-{
-    isn_T	*isn;
-    garray_T	*stack = &cctx->ctx_type_stack;
-
-    RETURN_OK_IF_SKIP(cctx);
-    if ((isn = generate_instr(cctx, ISN_JUMP)) == NULL)
-	return FAIL;
-    isn->isn_arg.jump.jump_when = when;
-    isn->isn_arg.jump.jump_where = where;
-
-    if (when != JUMP_ALWAYS && stack->ga_len > 0)
-	--stack->ga_len;
-
-    return OK;
-}
-
-/*
- * Generate an ISN_JUMP_IF_ARG_SET instruction.
- */
-    static int
-generate_JUMP_IF_ARG_SET(cctx_T *cctx, int arg_off)
-{
-    isn_T	*isn;
-
-    RETURN_OK_IF_SKIP(cctx);
-    if ((isn = generate_instr(cctx, ISN_JUMP_IF_ARG_SET)) == NULL)
-	return FAIL;
-    isn->isn_arg.jumparg.jump_arg_off = arg_off;
-    // jump_where is set later
-    return OK;
-}
-
-    static int
-generate_FOR(cctx_T *cctx, int loop_idx)
-{
-    isn_T	*isn;
-    garray_T	*stack = &cctx->ctx_type_stack;
-
-    RETURN_OK_IF_SKIP(cctx);
-    if ((isn = generate_instr(cctx, ISN_FOR)) == NULL)
-	return FAIL;
-    isn->isn_arg.forloop.for_idx = loop_idx;
-
-    if (GA_GROW_FAILS(stack, 1))
-	return FAIL;
-    // type doesn't matter, will be stored next
-    ((type_T **)stack->ga_data)[stack->ga_len] = &t_any;
-    ++stack->ga_len;
-
-    return OK;
-}
-/*
- * Generate an ISN_TRYCONT instruction.
- */
-    static int
-generate_TRYCONT(cctx_T *cctx, int levels, int where)
-{
-    isn_T	*isn;
-
-    RETURN_OK_IF_SKIP(cctx);
-    if ((isn = generate_instr(cctx, ISN_TRYCONT)) == NULL)
-	return FAIL;
-    isn->isn_arg.trycont.tct_levels = levels;
-    isn->isn_arg.trycont.tct_where = where;
-
-    return OK;
-}
-
-
-/*
- * Generate an ISN_BCALL instruction.
- * "method_call" is TRUE for "value->method()"
- * Return FAIL if the number of arguments is wrong.
- */
-    static int
-generate_BCALL(cctx_T *cctx, int func_idx, int argcount, int method_call)
-{
-    isn_T	*isn;
-    garray_T	*stack = &cctx->ctx_type_stack;
-    int		argoff;
-    type_T	**argtypes = NULL;
-    type_T	*shuffled_argtypes[MAX_FUNC_ARGS];
-    type_T	*maptype = NULL;
-
-    RETURN_OK_IF_SKIP(cctx);
-    argoff = check_internal_func(func_idx, argcount);
-    if (argoff < 0)
-	return FAIL;
-
-    if (method_call && argoff > 1)
-    {
-	if ((isn = generate_instr(cctx, ISN_SHUFFLE)) == NULL)
-	    return FAIL;
-	isn->isn_arg.shuffle.shfl_item = argcount;
-	isn->isn_arg.shuffle.shfl_up = argoff - 1;
-    }
-
-    if (argcount > 0)
-    {
-	// Check the types of the arguments.
-	argtypes = ((type_T **)stack->ga_data) + stack->ga_len - argcount;
-	if (method_call && argoff > 1)
-	{
-	    int i;
-
-	    for (i = 0; i < argcount; ++i)
-		shuffled_argtypes[i] = (i < argoff - 1)
-			    ? argtypes[i + 1]
-			    : (i == argoff - 1) ? argtypes[0] : argtypes[i];
-	    argtypes = shuffled_argtypes;
-	}
-	if (internal_func_check_arg_types(argtypes, func_idx, argcount,
-								 cctx) == FAIL)
-	    return FAIL;
-	if (internal_func_is_map(func_idx))
-	    maptype = *argtypes;
-    }
-
-    if ((isn = generate_instr(cctx, ISN_BCALL)) == NULL)
-	return FAIL;
-    isn->isn_arg.bfunc.cbf_idx = func_idx;
-    isn->isn_arg.bfunc.cbf_argcount = argcount;
-
-    // Drop the argument types and push the return type.
-    stack->ga_len -= argcount;
-    if (GA_GROW_FAILS(stack, 1))
-	return FAIL;
-    ((type_T **)stack->ga_data)[stack->ga_len] =
-			  internal_func_ret_type(func_idx, argcount, argtypes);
-    ++stack->ga_len;
-
-    if (maptype != NULL && maptype->tt_member != NULL
-					       && maptype->tt_member != &t_any)
-	// Check that map() didn't change the item types.
-	generate_TYPECHECK(cctx, maptype, -1, 1);
-
-    return OK;
-}
-
-/*
- * Generate an ISN_LISTAPPEND instruction.  Works like add().
- * Argument count is already checked.
- */
-    static int
-generate_LISTAPPEND(cctx_T *cctx)
-{
-    garray_T	*stack = &cctx->ctx_type_stack;
-    type_T	*list_type;
-    type_T	*item_type;
-    type_T	*expected;
-
-    // Caller already checked that list_type is a list.
-    list_type = ((type_T **)stack->ga_data)[stack->ga_len - 2];
-    item_type = ((type_T **)stack->ga_data)[stack->ga_len - 1];
-    expected = list_type->tt_member;
-    if (need_type(item_type, expected, -1, 0, cctx, FALSE, FALSE) == FAIL)
-	return FAIL;
-
-    if (generate_instr(cctx, ISN_LISTAPPEND) == NULL)
-	return FAIL;
-
-    --stack->ga_len;	    // drop the argument
-    return OK;
-}
-
-/*
- * Generate an ISN_BLOBAPPEND instruction.  Works like add().
- * Argument count is already checked.
- */
-    static int
-generate_BLOBAPPEND(cctx_T *cctx)
-{
-    garray_T	*stack = &cctx->ctx_type_stack;
-    type_T	*item_type;
-
-    // Caller already checked that blob_type is a blob.
-    item_type = ((type_T **)stack->ga_data)[stack->ga_len - 1];
-    if (need_type(item_type, &t_number, -1, 0, cctx, FALSE, FALSE) == FAIL)
-	return FAIL;
-
-    if (generate_instr(cctx, ISN_BLOBAPPEND) == NULL)
-	return FAIL;
-
-    --stack->ga_len;	    // drop the argument
-    return OK;
-}
-
-/*
- * Return TRUE if "ufunc" should be compiled, taking into account whether
- * "profile" indicates profiling is to be done.
- */
-    int
-func_needs_compiling(ufunc_T *ufunc, compiletype_T compile_type)
-{
-    switch (ufunc->uf_def_status)
-    {
-	case UF_TO_BE_COMPILED:
-	    return TRUE;
-
-	case UF_COMPILED:
-	{
-	    dfunc_T *dfunc = ((dfunc_T *)def_functions.ga_data)
-							 + ufunc->uf_dfunc_idx;
-
-	    switch (compile_type)
-	    {
-		case CT_PROFILE:
-#ifdef FEAT_PROFILE
-		    return dfunc->df_instr_prof == NULL;
-#endif
-		case CT_NONE:
-		    return dfunc->df_instr == NULL;
-		case CT_DEBUG:
-		    return dfunc->df_instr_debug == NULL;
-	    }
-	}
-
-	case UF_NOT_COMPILED:
-	case UF_COMPILE_ERROR:
-	case UF_COMPILING:
-	    break;
-    }
-    return FALSE;
-}
-
-/*
- * Generate an ISN_DCALL or ISN_UCALL instruction.
- * Return FAIL if the number of arguments is wrong.
- */
-    static int
-generate_CALL(cctx_T *cctx, ufunc_T *ufunc, int pushed_argcount)
-{
-    isn_T	*isn;
-    garray_T	*stack = &cctx->ctx_type_stack;
-    int		regular_args = ufunc->uf_args.ga_len;
-    int		argcount = pushed_argcount;
-
-    RETURN_OK_IF_SKIP(cctx);
-    if (argcount > regular_args && !has_varargs(ufunc))
-    {
-	semsg(_(e_too_many_arguments_for_function_str),
-						   printable_func_name(ufunc));
-	return FAIL;
-    }
-    if (argcount < regular_args - ufunc->uf_def_args.ga_len)
-    {
-	semsg(_(e_not_enough_arguments_for_function_str),
-						   printable_func_name(ufunc));
-	return FAIL;
-    }
-
-    if (ufunc->uf_def_status != UF_NOT_COMPILED
-	    && ufunc->uf_def_status != UF_COMPILE_ERROR)
-    {
-	int		i;
-
-	for (i = 0; i < argcount; ++i)
-	{
-	    type_T *expected;
-	    type_T *actual;
-
-	    actual = ((type_T **)stack->ga_data)[stack->ga_len - argcount + i];
-	    if (actual == &t_special
-			      && i >= regular_args - ufunc->uf_def_args.ga_len)
-	    {
-		// assume v:none used for default argument value
-		continue;
-	    }
-	    if (i < regular_args)
-	    {
-		if (ufunc->uf_arg_types == NULL)
-		    continue;
-		expected = ufunc->uf_arg_types[i];
-	    }
-	    else if (ufunc->uf_va_type == NULL
-					   || ufunc->uf_va_type == &t_list_any)
-		// possibly a lambda or "...: any"
-		expected = &t_any;
-	    else
-		expected = ufunc->uf_va_type->tt_member;
-	    if (need_type(actual, expected, -argcount + i, i + 1, cctx,
-							  TRUE, FALSE) == FAIL)
-	    {
-		arg_type_mismatch(expected, actual, i + 1);
-		return FAIL;
-	    }
-	}
-	if (func_needs_compiling(ufunc, COMPILE_TYPE(ufunc))
-		&& compile_def_function(ufunc, ufunc->uf_ret_type == NULL,
-					    COMPILE_TYPE(ufunc), NULL) == FAIL)
-	    return FAIL;
-    }
-    if (ufunc->uf_def_status == UF_COMPILE_ERROR)
-    {
-	emsg_funcname(_(e_call_to_function_that_failed_to_compile_str),
-							       ufunc->uf_name);
-	return FAIL;
-    }
-
-    if ((isn = generate_instr(cctx,
-		    ufunc->uf_def_status != UF_NOT_COMPILED ? ISN_DCALL
-							 : ISN_UCALL)) == NULL)
-	return FAIL;
-    if (isn->isn_type == ISN_DCALL)
-    {
-	isn->isn_arg.dfunc.cdf_idx = ufunc->uf_dfunc_idx;
-	isn->isn_arg.dfunc.cdf_argcount = argcount;
-    }
-    else
-    {
-	// A user function may be deleted and redefined later, can't use the
-	// ufunc pointer, need to look it up again at runtime.
-	isn->isn_arg.ufunc.cuf_name = vim_strsave(ufunc->uf_name);
-	isn->isn_arg.ufunc.cuf_argcount = argcount;
-    }
-
-    stack->ga_len -= argcount; // drop the arguments
-    if (GA_GROW_FAILS(stack, 1))
-	return FAIL;
-    // add return value
-    ((type_T **)stack->ga_data)[stack->ga_len] = ufunc->uf_ret_type;
-    ++stack->ga_len;
-
-    return OK;
-}
-
-/*
- * Generate an ISN_UCALL instruction when the function isn't defined yet.
- */
-    static int
-generate_UCALL(cctx_T *cctx, char_u *name, int argcount)
-{
-    isn_T	*isn;
-    garray_T	*stack = &cctx->ctx_type_stack;
-
-    RETURN_OK_IF_SKIP(cctx);
-    if ((isn = generate_instr(cctx, ISN_UCALL)) == NULL)
-	return FAIL;
-    isn->isn_arg.ufunc.cuf_name = vim_strsave(name);
-    isn->isn_arg.ufunc.cuf_argcount = argcount;
-
-    stack->ga_len -= argcount; // drop the arguments
-    if (GA_GROW_FAILS(stack, 1))
-	return FAIL;
-    // add return value
-    ((type_T **)stack->ga_data)[stack->ga_len] = &t_any;
-    ++stack->ga_len;
-
-    return OK;
-}
-
-/*
- * Generate an ISN_PCALL instruction.
- * "type" is the type of the FuncRef.
- */
-    static int
-generate_PCALL(
-	cctx_T	*cctx,
-	int	argcount,
-	char_u	*name,
-	type_T	*type,
-	int	at_top)
-{
-    isn_T	*isn;
-    garray_T	*stack = &cctx->ctx_type_stack;
-    type_T	*ret_type;
-
-    RETURN_OK_IF_SKIP(cctx);
-
-    if (type->tt_type == VAR_ANY)
-	ret_type = &t_any;
-    else if (type->tt_type == VAR_FUNC || type->tt_type == VAR_PARTIAL)
-    {
-	if (type->tt_argcount != -1)
-	{
-	    int	    varargs = (type->tt_flags & TTFLAG_VARARGS) ? 1 : 0;
-
-	    if (argcount < type->tt_min_argcount - varargs)
-	    {
-		semsg(_(e_not_enough_arguments_for_function_str), name);
-		return FAIL;
-	    }
-	    if (!varargs && argcount > type->tt_argcount)
-	    {
-		semsg(_(e_too_many_arguments_for_function_str), name);
-		return FAIL;
-	    }
-	    if (type->tt_args != NULL)
-	    {
-		int i;
-
-		for (i = 0; i < argcount; ++i)
-		{
-		    int	    offset = -argcount + i - (at_top ? 0 : 1);
-		    type_T *actual = ((type_T **)stack->ga_data)[
-						       stack->ga_len + offset];
-		    type_T *expected;
-
-		    if (varargs && i >= type->tt_argcount - 1)
-			expected = type->tt_args[
-					     type->tt_argcount - 1]->tt_member;
-		    else if (i >= type->tt_min_argcount
-						       && actual == &t_special)
-			expected = &t_any;
-		    else
-			expected = type->tt_args[i];
-		    if (need_type(actual, expected, offset, i + 1,
-						    cctx, TRUE, FALSE) == FAIL)
-		    {
-			arg_type_mismatch(expected, actual, i + 1);
-			return FAIL;
-		    }
-		}
-	    }
-	}
-	ret_type = type->tt_member;
-	if (ret_type == &t_unknown)
-	    // return type not known yet, use a runtime check
-	    ret_type = &t_any;
-    }
-    else
-    {
-	semsg(_(e_not_callable_type_str), name);
-	return FAIL;
-    }
-
-    if ((isn = generate_instr(cctx, ISN_PCALL)) == NULL)
-	return FAIL;
-    isn->isn_arg.pfunc.cpf_top = at_top;
-    isn->isn_arg.pfunc.cpf_argcount = argcount;
-
-    stack->ga_len -= argcount; // drop the arguments
-
-    // drop the funcref/partial, get back the return value
-    ((type_T **)stack->ga_data)[stack->ga_len - 1] = ret_type;
-
-    // If partial is above the arguments it must be cleared and replaced with
-    // the return value.
-    if (at_top && generate_instr(cctx, ISN_PCALL_END) == NULL)
-	return FAIL;
-
-    return OK;
-}
-
-/*
- * Generate an ISN_STRINGMEMBER instruction.
- */
-    static int
-generate_STRINGMEMBER(cctx_T *cctx, char_u *name, size_t len)
-{
-    isn_T	*isn;
-    garray_T	*stack = &cctx->ctx_type_stack;
-    type_T	*type;
-
-    RETURN_OK_IF_SKIP(cctx);
-    if ((isn = generate_instr(cctx, ISN_STRINGMEMBER)) == NULL)
-	return FAIL;
-    isn->isn_arg.string = vim_strnsave(name, len);
-
-    // check for dict type
-    type = ((type_T **)stack->ga_data)[stack->ga_len - 1];
-    if (type->tt_type != VAR_DICT && type != &t_any)
-    {
-	char *tofree;
-
-	semsg(_(e_expected_dictionary_for_using_key_str_but_got_str),
-					       name, type_name(type, &tofree));
-	vim_free(tofree);
-	return FAIL;
-    }
-    // change dict type to dict member type
-    if (type->tt_type == VAR_DICT)
-    {
-	((type_T **)stack->ga_data)[stack->ga_len - 1] =
-		      type->tt_member == &t_unknown ? &t_any : type->tt_member;
-    }
-
-    return OK;
-}
-
-/*
- * Generate an ISN_ECHO instruction.
- */
-    static int
-generate_ECHO(cctx_T *cctx, int with_white, int count)
-{
-    isn_T	*isn;
-
-    RETURN_OK_IF_SKIP(cctx);
-    if ((isn = generate_instr_drop(cctx, ISN_ECHO, count)) == NULL)
-	return FAIL;
-    isn->isn_arg.echo.echo_with_white = with_white;
-    isn->isn_arg.echo.echo_count = count;
-
-    return OK;
-}
-
-/*
- * Generate an ISN_EXECUTE/ISN_ECHOMSG/ISN_ECHOERR instruction.
- */
-    static int
-generate_MULT_EXPR(cctx_T *cctx, isntype_T isn_type, int count)
-{
-    isn_T	*isn;
-
-    if ((isn = generate_instr_drop(cctx, isn_type, count)) == NULL)
-	return FAIL;
-    isn->isn_arg.number = count;
-
-    return OK;
-}
-
-/*
- * Generate an ISN_PUT instruction.
- */
-    static int
-generate_PUT(cctx_T *cctx, int regname, linenr_T lnum)
-{
-    isn_T	*isn;
-
-    RETURN_OK_IF_SKIP(cctx);
-    if ((isn = generate_instr(cctx, ISN_PUT)) == NULL)
-	return FAIL;
-    isn->isn_arg.put.put_regname = regname;
-    isn->isn_arg.put.put_lnum = lnum;
-    return OK;
-}
-
-/*
- * Generate an EXEC instruction that takes a string argument.
- * A copy is made of "line".
- */
-    static int
-generate_EXEC_copy(cctx_T *cctx, isntype_T isntype, char_u *line)
-{
-    isn_T	*isn;
-
-    RETURN_OK_IF_SKIP(cctx);
-    if ((isn = generate_instr(cctx, isntype)) == NULL)
-	return FAIL;
-    isn->isn_arg.string = vim_strsave(line);
-    return OK;
-}
-
-/*
- * Generate an EXEC instruction that takes a string argument.
- * "str" must be allocated, it is consumed.
- */
-    static int
-generate_EXEC(cctx_T *cctx, isntype_T isntype, char_u *str)
-{
-    isn_T	*isn;
-
-    if (cctx->ctx_skip == SKIP_YES)
-    {
-	vim_free(str);
-	return OK;
-    }
-    if ((isn = generate_instr(cctx, isntype)) == NULL)
-    {
-	vim_free(str);
-	return FAIL;
-    }
-    isn->isn_arg.string = str;
-    return OK;
-}
-
-    static int
-generate_LEGACY_EVAL(cctx_T *cctx, char_u *line)
-{
-    isn_T	*isn;
-    garray_T	*stack = &cctx->ctx_type_stack;
-
-    RETURN_OK_IF_SKIP(cctx);
-    if ((isn = generate_instr(cctx, ISN_LEGACY_EVAL)) == NULL)
-	return FAIL;
-    isn->isn_arg.string = vim_strsave(line);
-
-    if (GA_GROW_FAILS(stack, 1))
-	return FAIL;
-    ((type_T **)stack->ga_data)[stack->ga_len] = &t_any;
-    ++stack->ga_len;
-
-    return OK;
-}
-
-    static int
-generate_EXECCONCAT(cctx_T *cctx, int count)
-{
-    isn_T	*isn;
-
-    if ((isn = generate_instr_drop(cctx, ISN_EXECCONCAT, count)) == NULL)
-	return FAIL;
-    isn->isn_arg.number = count;
-    return OK;
-}
-
-/*
- * Generate ISN_RANGE.  Consumes "range".  Return OK/FAIL.
- */
-    static int
-generate_RANGE(cctx_T *cctx, char_u *range)
-{
-    isn_T	*isn;
-    garray_T	*stack = &cctx->ctx_type_stack;
-
-    if ((isn = generate_instr(cctx, ISN_RANGE)) == NULL)
-	return FAIL;
-    isn->isn_arg.string = range;
-
-    if (GA_GROW_FAILS(stack, 1))
-	return FAIL;
-    ((type_T **)stack->ga_data)[stack->ga_len] = &t_number;
-    ++stack->ga_len;
-    return OK;
-}
-
-    static int
-generate_UNPACK(cctx_T *cctx, int var_count, int semicolon)
-{
-    isn_T	*isn;
-
-    RETURN_OK_IF_SKIP(cctx);
-    if ((isn = generate_instr(cctx, ISN_UNPACK)) == NULL)
-	return FAIL;
-    isn->isn_arg.unpack.unp_count = var_count;
-    isn->isn_arg.unpack.unp_semicolon = semicolon;
-    return OK;
-}
-
-/*
- * Generate an instruction for any command modifiers.
- */
-    static int
-generate_cmdmods(cctx_T *cctx, cmdmod_T *cmod)
-{
-    isn_T	*isn;
-
-    if (has_cmdmod(cmod, FALSE))
-    {
-	cctx->ctx_has_cmdmod = TRUE;
-
-	if ((isn = generate_instr(cctx, ISN_CMDMOD)) == NULL)
-	    return FAIL;
-	isn->isn_arg.cmdmod.cf_cmdmod = ALLOC_ONE(cmdmod_T);
-	if (isn->isn_arg.cmdmod.cf_cmdmod == NULL)
-	    return FAIL;
-	mch_memmove(isn->isn_arg.cmdmod.cf_cmdmod, cmod, sizeof(cmdmod_T));
-	// filter program now belongs to the instruction
-	cmod->cmod_filter_regmatch.regprog = NULL;
-    }
-
-    return OK;
-}
-
-    static int
-generate_undo_cmdmods(cctx_T *cctx)
-{
-    if (cctx->ctx_has_cmdmod && generate_instr(cctx, ISN_CMDMOD_REV) == NULL)
-	return FAIL;
-    cctx->ctx_has_cmdmod = FALSE;
-    return OK;
-}
-
-    static int
-misplaced_cmdmod(cctx_T *cctx)
-{
-    garray_T	*instr = &cctx->ctx_instr;
-
-    if (cctx->ctx_has_cmdmod
-	    && ((isn_T *)instr->ga_data)[instr->ga_len - 1].isn_type
-								 == ISN_CMDMOD)
-    {
-	emsg(_(e_misplaced_command_modifier));
-	return TRUE;
-    }
-    return FALSE;
-}
-
-/*
- * Get the index of the current instruction.
- * This compensates for a preceding ISN_CMDMOD and ISN_PROF_START.
- */
-    static int
-current_instr_idx(cctx_T *cctx)
-{
-    garray_T	*instr = &cctx->ctx_instr;
-    int		idx = instr->ga_len;
-
-    while (idx > 0)
-    {
-	if (cctx->ctx_has_cmdmod && ((isn_T *)instr->ga_data)[idx - 1]
-						       .isn_type == ISN_CMDMOD)
-	{
-	    --idx;
-	    continue;
-	}
-#ifdef FEAT_PROFILE
-	if (((isn_T *)instr->ga_data)[idx - 1].isn_type == ISN_PROF_START)
-	{
-	    --idx;
-	    continue;
-	}
-#endif
-	if (((isn_T *)instr->ga_data)[idx - 1].isn_type == ISN_DEBUG)
-	{
-	    --idx;
-	    continue;
-	}
-	break;
-    }
-    return idx;
-}
-
-#ifdef FEAT_PROFILE
-    static void
-may_generate_prof_end(cctx_T *cctx, int prof_lnum)
-{
-    if (cctx->ctx_compile_type == CT_PROFILE && prof_lnum >= 0)
-	generate_instr(cctx, ISN_PROF_END);
-}
-#endif
-
-/*
  * Reserve space for a local variable.
  * Return the variable or NULL if it failed.
  */
-    static lvar_T *
+    lvar_T *
 reserve_local(
 	cctx_T	*cctx,
 	char_u	*name,
@@ -2542,36 +489,6 @@
 }
 
 /*
- * Remove local variables above "new_top".
- */
-    static void
-unwind_locals(cctx_T *cctx, int new_top)
-{
-    if (cctx->ctx_locals.ga_len > new_top)
-    {
-	int	idx;
-	lvar_T	*lvar;
-
-	for (idx = new_top; idx < cctx->ctx_locals.ga_len; ++idx)
-	{
-	    lvar = ((lvar_T *)cctx->ctx_locals.ga_data) + idx;
-	    vim_free(lvar->lv_name);
-	}
-    }
-    cctx->ctx_locals.ga_len = new_top;
-}
-
-/*
- * Free all local variables.
- */
-    static void
-free_locals(cctx_T *cctx)
-{
-    unwind_locals(cctx, 0);
-    ga_clear(&cctx->ctx_locals);
-}
-
-/*
  * If "check_writable" is ASSIGN_CONST give an error if the variable was
  * defined with :final or :const, if "check_writable" is ASSIGN_FINAL give an
  * error if the variable was defined with :const.
@@ -2705,6 +622,27 @@
 }
 
 /*
+ * Called when checking for a following operator at "arg".  When the rest of
+ * the line is empty or only a comment, peek the next line.  If there is a next
+ * line return a pointer to it and set "nextp".
+ * Otherwise skip over white space.
+ */
+    char_u *
+may_peek_next_line(cctx_T *cctx, char_u *arg, char_u **nextp)
+{
+    char_u *p = skipwhite(arg);
+
+    *nextp = NULL;
+    if (*p == NUL || (VIM_ISWHITE(*arg) && vim9_comment_start(p)))
+    {
+	*nextp = peek_next_line_from_context(cctx);
+	if (*nextp != NULL)
+	    return *nextp;
+    }
+    return p;
+}
+
+/*
  * Return a pointer to the next line that isn't empty or only contains a
  * comment. Skips over white space.
  * Returns NULL if there is none.
@@ -2733,27 +671,6 @@
 }
 
 /*
- * Called when checking for a following operator at "arg".  When the rest of
- * the line is empty or only a comment, peek the next line.  If there is a next
- * line return a pointer to it and set "nextp".
- * Otherwise skip over white space.
- */
-    static char_u *
-may_peek_next_line(cctx_T *cctx, char_u *arg, char_u **nextp)
-{
-    char_u *p = skipwhite(arg);
-
-    *nextp = NULL;
-    if (*p == NUL || (VIM_ISWHITE(*arg) && vim9_comment_start(p)))
-    {
-	*nextp = peek_next_line_from_context(cctx);
-	if (*nextp != NULL)
-	    return *nextp;
-    }
-    return p;
-}
-
-/*
  * Get the next line of the function from "cctx".
  * Skips over empty lines.  Skips over comment lines if "skip_comment" is TRUE.
  * Returns NULL when at the end.
@@ -2785,7 +702,7 @@
  * Also when "whitep" points to white space and "*arg" is on a "#".
  * Return FAIL if beyond the last line, "*arg" is unmodified then.
  */
-    static int
+    int
 may_get_next_line(char_u *whitep, char_u **arg, cctx_T *cctx)
 {
     *arg = skipwhite(whitep);
@@ -2805,7 +722,7 @@
 /*
  * Idem, and give an error when failed.
  */
-    static int
+    int
 may_get_next_line_error(char_u *whitep, char_u **arg, cctx_T *cctx)
 {
     if (may_get_next_line(whitep, arg, cctx) == FAIL)
@@ -2817,3013 +734,6 @@
     return OK;
 }
 
-
-// Structure passed between the compile_expr* functions to keep track of
-// constants that have been parsed but for which no code was produced yet.  If
-// possible expressions on these constants are applied at compile time.  If
-// that is not possible, the code to push the constants needs to be generated
-// before other instructions.
-// Using 50 should be more than enough of 5 levels of ().
-#define PPSIZE 50
-typedef struct {
-    typval_T	pp_tv[PPSIZE];	// stack of ppconst constants
-    int		pp_used;	// active entries in pp_tv[]
-    int		pp_is_const;	// all generated code was constants, used for a
-				// list or dict with constant members
-} ppconst_T;
-
-static int compile_expr0_ext(char_u **arg,  cctx_T *cctx, int *is_const);
-static int compile_expr0(char_u **arg,  cctx_T *cctx);
-static int compile_expr1(char_u **arg,  cctx_T *cctx, ppconst_T *ppconst);
-
-/*
- * Generate a PUSH instruction for "tv".
- * "tv" will be consumed or cleared.
- * Nothing happens if "tv" is NULL or of type VAR_UNKNOWN;
- */
-    static int
-generate_tv_PUSH(cctx_T *cctx, typval_T *tv)
-{
-    if (tv != NULL)
-    {
-	switch (tv->v_type)
-	{
-	    case VAR_UNKNOWN:
-		break;
-	    case VAR_BOOL:
-		generate_PUSHBOOL(cctx, tv->vval.v_number);
-		break;
-	    case VAR_SPECIAL:
-		generate_PUSHSPEC(cctx, tv->vval.v_number);
-		break;
-	    case VAR_NUMBER:
-		generate_PUSHNR(cctx, tv->vval.v_number);
-		break;
-#ifdef FEAT_FLOAT
-	    case VAR_FLOAT:
-		generate_PUSHF(cctx, tv->vval.v_float);
-		break;
-#endif
-	    case VAR_BLOB:
-		generate_PUSHBLOB(cctx, tv->vval.v_blob);
-		tv->vval.v_blob = NULL;
-		break;
-	    case VAR_STRING:
-		generate_PUSHS(cctx, &tv->vval.v_string);
-		tv->vval.v_string = NULL;
-		break;
-	    default:
-		iemsg("constant type not supported");
-		clear_tv(tv);
-		return FAIL;
-	}
-	tv->v_type = VAR_UNKNOWN;
-    }
-    return OK;
-}
-
-/*
- * Generate code for any ppconst entries.
- */
-    static int
-generate_ppconst(cctx_T *cctx, ppconst_T *ppconst)
-{
-    int	    i;
-    int	    ret = OK;
-    int	    save_skip = cctx->ctx_skip;
-
-    cctx->ctx_skip = SKIP_NOT;
-    for (i = 0; i < ppconst->pp_used; ++i)
-	if (generate_tv_PUSH(cctx, &ppconst->pp_tv[i]) == FAIL)
-	    ret = FAIL;
-    ppconst->pp_used = 0;
-    cctx->ctx_skip = save_skip;
-    return ret;
-}
-
-/*
- * Check that the last item of "ppconst" is a bool, if there is an item.
- */
-    static int
-check_ppconst_bool(ppconst_T *ppconst)
-{
-    if (ppconst->pp_used > 0)
-    {
-	typval_T    *tv = &ppconst->pp_tv[ppconst->pp_used - 1];
-	where_T	    where = WHERE_INIT;
-
-	return check_typval_type(&t_bool, tv, where);
-    }
-    return OK;
-}
-
-/*
- * Clear ppconst constants.  Used when failing.
- */
-    static void
-clear_ppconst(ppconst_T *ppconst)
-{
-    int	    i;
-
-    for (i = 0; i < ppconst->pp_used; ++i)
-	clear_tv(&ppconst->pp_tv[i]);
-    ppconst->pp_used = 0;
-}
-
-/*
- * Compile getting a member from a list/dict/string/blob.  Stack has the
- * indexable value and the index or the two indexes of a slice.
- * "keeping_dict" is used for dict[func](arg) to pass dict to func.
- */
-    static int
-compile_member(int is_slice, int *keeping_dict, cctx_T *cctx)
-{
-    type_T	**typep;
-    garray_T	*stack = &cctx->ctx_type_stack;
-    vartype_T	vartype;
-    type_T	*idxtype;
-
-    // We can index a list, dict and blob.  If we don't know the type
-    // we can use the index value type.  If we still don't know use an "ANY"
-    // instruction.
-    typep = ((type_T **)stack->ga_data) + stack->ga_len
-						  - (is_slice ? 3 : 2);
-    vartype = (*typep)->tt_type;
-    idxtype = ((type_T **)stack->ga_data)[stack->ga_len - 1];
-    // If the index is a string, the variable must be a Dict.
-    if (*typep == &t_any && idxtype == &t_string)
-	vartype = VAR_DICT;
-    if (vartype == VAR_STRING || vartype == VAR_LIST || vartype == VAR_BLOB)
-    {
-	if (need_type(idxtype, &t_number, -1, 0, cctx, FALSE, FALSE) == FAIL)
-	    return FAIL;
-	if (is_slice)
-	{
-	    idxtype = ((type_T **)stack->ga_data)[stack->ga_len - 2];
-	    if (need_type(idxtype, &t_number, -2, 0, cctx,
-							 FALSE, FALSE) == FAIL)
-		return FAIL;
-	}
-    }
-
-    if (vartype == VAR_DICT)
-    {
-	if (is_slice)
-	{
-	    emsg(_(e_cannot_slice_dictionary));
-	    return FAIL;
-	}
-	if ((*typep)->tt_type == VAR_DICT)
-	{
-	    *typep = (*typep)->tt_member;
-	    if (*typep == &t_unknown)
-		// empty dict was used
-		*typep = &t_any;
-	}
-	else
-	{
-	    if (need_type(*typep, &t_dict_any, -2, 0, cctx,
-							 FALSE, FALSE) == FAIL)
-		return FAIL;
-	    *typep = &t_any;
-	}
-	if (may_generate_2STRING(-1, FALSE, cctx) == FAIL)
-	    return FAIL;
-	if (generate_instr_drop(cctx, ISN_MEMBER, 1) == FAIL)
-	    return FAIL;
-	if (keeping_dict != NULL)
-	    *keeping_dict = TRUE;
-    }
-    else if (vartype == VAR_STRING)
-    {
-	*typep = &t_string;
-	if ((is_slice
-		? generate_instr_drop(cctx, ISN_STRSLICE, 2)
-		: generate_instr_drop(cctx, ISN_STRINDEX, 1)) == FAIL)
-	    return FAIL;
-    }
-    else if (vartype == VAR_BLOB)
-    {
-	if (is_slice)
-	{
-	    *typep = &t_blob;
-	    if (generate_instr_drop(cctx, ISN_BLOBSLICE, 2) == FAIL)
-		return FAIL;
-	}
-	else
-	{
-	    *typep = &t_number;
-	    if (generate_instr_drop(cctx, ISN_BLOBINDEX, 1) == FAIL)
-		return FAIL;
-	}
-    }
-    else if (vartype == VAR_LIST || *typep == &t_any)
-    {
-	if (is_slice)
-	{
-	    if (generate_instr_drop(cctx,
-		     vartype == VAR_LIST ?  ISN_LISTSLICE : ISN_ANYSLICE,
-							    2) == FAIL)
-		return FAIL;
-	}
-	else
-	{
-	    if ((*typep)->tt_type == VAR_LIST)
-	    {
-		*typep = (*typep)->tt_member;
-		if (*typep == &t_unknown)
-		    // empty list was used
-		    *typep = &t_any;
-	    }
-	    if (generate_instr_drop(cctx,
-			vartype == VAR_LIST ?  ISN_LISTINDEX : ISN_ANYINDEX, 1)
-								       == FAIL)
-		return FAIL;
-	}
-    }
-    else
-    {
-	switch (vartype)
-	{
-	    case VAR_FUNC:
-	    case VAR_PARTIAL:
-		emsg(_(e_cannot_index_a_funcref));
-		break;
-	    case VAR_BOOL:
-	    case VAR_SPECIAL:
-	    case VAR_JOB:
-	    case VAR_CHANNEL:
-	    case VAR_INSTR:
-	    case VAR_UNKNOWN:
-	    case VAR_ANY:
-	    case VAR_VOID:
-		emsg(_(e_cannot_index_special_variable));
-		break;
-	    default:
-		emsg(_(e_string_list_dict_or_blob_required));
-	}
-	return FAIL;
-    }
-    return OK;
-}
-
-/*
- * Generate an instruction to load script-local variable "name", without the
- * leading "s:".
- * Also finds imported variables.
- */
-    static int
-compile_load_scriptvar(
-	cctx_T *cctx,
-	char_u *name,	    // variable NUL terminated
-	char_u *start,	    // start of variable
-	char_u **end,	    // end of variable
-	int    error)	    // when TRUE may give error
-{
-    scriptitem_T    *si;
-    int		    idx;
-    imported_T	    *import;
-
-    if (!SCRIPT_ID_VALID(current_sctx.sc_sid))
-	return FAIL;
-    si = SCRIPT_ITEM(current_sctx.sc_sid);
-    idx = get_script_item_idx(current_sctx.sc_sid, name, 0, cctx);
-    if (idx == -1 || si->sn_version != SCRIPT_VERSION_VIM9)
-    {
-	// variable is not in sn_var_vals: old style script.
-	return generate_OLDSCRIPT(cctx, ISN_LOADS, name, current_sctx.sc_sid,
-								       &t_any);
-    }
-    if (idx >= 0)
-    {
-	svar_T		*sv = ((svar_T *)si->sn_var_vals.ga_data) + idx;
-
-	generate_VIM9SCRIPT(cctx, ISN_LOADSCRIPT,
-					current_sctx.sc_sid, idx, sv->sv_type);
-	return OK;
-    }
-
-    import = find_imported(name, 0, cctx);
-    if (import != NULL)
-    {
-	if (import->imp_flags & IMP_FLAGS_STAR)
-	{
-	    char_u	*p = skipwhite(*end);
-	    char_u	*exp_name;
-	    int		cc;
-	    ufunc_T	*ufunc;
-	    type_T	*type;
-
-	    // Used "import * as Name", need to lookup the member.
-	    if (*p != '.')
-	    {
-		semsg(_(e_expected_dot_after_name_str), start);
-		return FAIL;
-	    }
-	    ++p;
-	    if (VIM_ISWHITE(*p))
-	    {
-		emsg(_(e_no_white_space_allowed_after_dot));
-		return FAIL;
-	    }
-
-	    // isolate one name
-	    exp_name = p;
-	    while (eval_isnamec(*p))
-		++p;
-	    cc = *p;
-	    *p = NUL;
-
-	    idx = find_exported(import->imp_sid, exp_name, &ufunc, &type,
-								   cctx, TRUE);
-	    *p = cc;
-	    p = skipwhite(p);
-	    *end = p;
-
-	    if (idx < 0)
-	    {
-		if (*p == '(' && ufunc != NULL)
-		{
-		    generate_PUSHFUNC(cctx, ufunc->uf_name, import->imp_type);
-		    return OK;
-		}
-		return FAIL;
-	    }
-
-	    generate_VIM9SCRIPT(cctx, ISN_LOADSCRIPT,
-		    import->imp_sid,
-		    idx,
-		    type);
-	}
-	else if (import->imp_funcname != NULL)
-	    generate_PUSHFUNC(cctx, import->imp_funcname, import->imp_type);
-	else
-	    generate_VIM9SCRIPT(cctx, ISN_LOADSCRIPT,
-		    import->imp_sid,
-		    import->imp_var_vals_idx,
-		    import->imp_type);
-	return OK;
-    }
-
-    if (error)
-	semsg(_(e_item_not_found_str), name);
-    return FAIL;
-}
-
-    static int
-generate_funcref(cctx_T *cctx, char_u *name)
-{
-    ufunc_T *ufunc = find_func(name, FALSE, cctx);
-
-    if (ufunc == NULL)
-	return FAIL;
-
-    // Need to compile any default values to get the argument types.
-    if (func_needs_compiling(ufunc, COMPILE_TYPE(ufunc))
-	    && compile_def_function(ufunc, TRUE, COMPILE_TYPE(ufunc), NULL)
-								       == FAIL)
-	return FAIL;
-    return generate_PUSHFUNC(cctx, ufunc->uf_name, ufunc->uf_func_type);
-}
-
-/*
- * Compile a variable name into a load instruction.
- * "end" points to just after the name.
- * "is_expr" is TRUE when evaluating an expression, might be a funcref.
- * When "error" is FALSE do not give an error when not found.
- */
-    static int
-compile_load(
-	char_u **arg,
-	char_u *end_arg,
-	cctx_T	*cctx,
-	int	is_expr,
-	int	error)
-{
-    type_T	*type;
-    char_u	*name = NULL;
-    char_u	*end = end_arg;
-    int		res = FAIL;
-    int		prev_called_emsg = called_emsg;
-
-    if (*(*arg + 1) == ':')
-    {
-	if (end <= *arg + 2)
-	{
-	    isntype_T  isn_type;
-
-	    // load dictionary of namespace
-	    switch (**arg)
-	    {
-		case 'g': isn_type = ISN_LOADGDICT; break;
-		case 'w': isn_type = ISN_LOADWDICT; break;
-		case 't': isn_type = ISN_LOADTDICT; break;
-		case 'b': isn_type = ISN_LOADBDICT; break;
-		default:
-		    semsg(_(e_namespace_not_supported_str), *arg);
-		    goto theend;
-	    }
-	    if (generate_instr_type(cctx, isn_type, &t_dict_any) == NULL)
-		goto theend;
-	    res = OK;
-	}
-	else
-	{
-	    isntype_T  isn_type = ISN_DROP;
-
-	    // load namespaced variable
-	    name = vim_strnsave(*arg + 2, end - (*arg + 2));
-	    if (name == NULL)
-		return FAIL;
-
-	    switch (**arg)
-	    {
-		case 'v': res = generate_LOADV(cctx, name, error);
-			  break;
-		case 's': if (is_expr && ASCII_ISUPPER(*name)
-				       && find_func(name, FALSE, cctx) != NULL)
-			      res = generate_funcref(cctx, name);
-			  else
-			      res = compile_load_scriptvar(cctx, name,
-							    NULL, &end, error);
-			  break;
-		case 'g': if (vim_strchr(name, AUTOLOAD_CHAR) == NULL)
-			  {
-			      if (is_expr && ASCII_ISUPPER(*name)
-				       && find_func(name, FALSE, cctx) != NULL)
-				  res = generate_funcref(cctx, name);
-			      else
-				  isn_type = ISN_LOADG;
-			  }
-			  else
-			  {
-			      isn_type = ISN_LOADAUTO;
-			      vim_free(name);
-			      name = vim_strnsave(*arg, end - *arg);
-			      if (name == NULL)
-				  return FAIL;
-			  }
-			  break;
-		case 'w': isn_type = ISN_LOADW; break;
-		case 't': isn_type = ISN_LOADT; break;
-		case 'b': isn_type = ISN_LOADB; break;
-		default:  // cannot happen, just in case
-			  semsg(_(e_namespace_not_supported_str), *arg);
-			  goto theend;
-	    }
-	    if (isn_type != ISN_DROP)
-	    {
-		// Global, Buffer-local, Window-local and Tabpage-local
-		// variables can be defined later, thus we don't check if it
-		// exists, give an error at runtime.
-		res = generate_LOAD(cctx, isn_type, 0, name, &t_any);
-	    }
-	}
-    }
-    else
-    {
-	size_t	    len = end - *arg;
-	int	    idx;
-	int	    gen_load = FALSE;
-	int	    gen_load_outer = 0;
-
-	name = vim_strnsave(*arg, end - *arg);
-	if (name == NULL)
-	    return FAIL;
-
-	if (vim_strchr(name, AUTOLOAD_CHAR) != NULL)
-	{
-	    script_autoload(name, FALSE);
-	    res = generate_LOAD(cctx, ISN_LOADAUTO, 0, name, &t_any);
-	}
-	else if (arg_exists(*arg, len, &idx, &type, &gen_load_outer, cctx)
-									 == OK)
-	{
-	    if (gen_load_outer == 0)
-		gen_load = TRUE;
-	}
-	else
-	{
-	    lvar_T lvar;
-
-	    if (lookup_local(*arg, len, &lvar, cctx) == OK)
-	    {
-		type = lvar.lv_type;
-		idx = lvar.lv_idx;
-		if (lvar.lv_from_outer != 0)
-		    gen_load_outer = lvar.lv_from_outer;
-		else
-		    gen_load = TRUE;
-	    }
-	    else
-	    {
-		// "var" can be script-local even without using "s:" if it
-		// already exists in a Vim9 script or when it's imported.
-		if (script_var_exists(*arg, len, cctx) == OK
-			|| find_imported(name, 0, cctx) != NULL)
-		   res = compile_load_scriptvar(cctx, name, *arg, &end, FALSE);
-
-		// When evaluating an expression and the name starts with an
-		// uppercase letter it can be a user defined function.
-		// generate_funcref() will fail if the function can't be found.
-		if (res == FAIL && is_expr && ASCII_ISUPPER(*name))
-		    res = generate_funcref(cctx, name);
-	    }
-	}
-	if (gen_load)
-	    res = generate_LOAD(cctx, ISN_LOAD, idx, NULL, type);
-	if (gen_load_outer > 0)
-	{
-	    res = generate_LOADOUTER(cctx, idx, gen_load_outer, type);
-	    cctx->ctx_outer_used = TRUE;
-	}
-    }
-
-    *arg = end;
-
-theend:
-    if (res == FAIL && error && called_emsg == prev_called_emsg)
-	semsg(_(e_variable_not_found_str), name);
-    vim_free(name);
-    return res;
-}
-
-    static void
-clear_instr_ga(garray_T *gap)
-{
-    int idx;
-
-    for (idx = 0; idx < gap->ga_len; ++idx)
-	delete_instr(((isn_T *)gap->ga_data) + idx);
-    ga_clear(gap);
-}
-
-/*
- * Compile a string in a ISN_PUSHS instruction into an ISN_INSTR.
- * Returns FAIL if compilation fails.
- */
-    static int
-compile_string(isn_T *isn, cctx_T *cctx)
-{
-    char_u	*s = isn->isn_arg.string;
-    garray_T	save_ga = cctx->ctx_instr;
-    int		expr_res;
-    int		trailing_error;
-    int		instr_count;
-    isn_T	*instr = NULL;
-
-    // Remove the string type from the stack.
-    --cctx->ctx_type_stack.ga_len;
-
-    // Temporarily reset the list of instructions so that the jump labels are
-    // correct.
-    cctx->ctx_instr.ga_len = 0;
-    cctx->ctx_instr.ga_maxlen = 0;
-    cctx->ctx_instr.ga_data = NULL;
-    expr_res = compile_expr0(&s, cctx);
-    s = skipwhite(s);
-    trailing_error = *s != NUL;
-
-    if (expr_res == FAIL || trailing_error
-				       || GA_GROW_FAILS(&cctx->ctx_instr, 1))
-    {
-	if (trailing_error)
-	    semsg(_(e_trailing_arg), s);
-	clear_instr_ga(&cctx->ctx_instr);
-	cctx->ctx_instr = save_ga;
-	++cctx->ctx_type_stack.ga_len;
-	return FAIL;
-    }
-
-    // Move the generated instructions into the ISN_INSTR instruction, then
-    // restore the list of instructions.
-    instr_count = cctx->ctx_instr.ga_len;
-    instr = cctx->ctx_instr.ga_data;
-    instr[instr_count].isn_type = ISN_FINISH;
-
-    cctx->ctx_instr = save_ga;
-    vim_free(isn->isn_arg.string);
-    isn->isn_type = ISN_INSTR;
-    isn->isn_arg.instr = instr;
-    return OK;
-}
-
-/*
- * Compile the argument expressions.
- * "arg" points to just after the "(" and is advanced to after the ")"
- */
-    static int
-compile_arguments(char_u **arg, cctx_T *cctx, int *argcount, int is_searchpair)
-{
-    char_u  *p = *arg;
-    char_u  *whitep = *arg;
-    int	    must_end = FALSE;
-    int	    instr_count;
-
-    for (;;)
-    {
-	if (may_get_next_line(whitep, &p, cctx) == FAIL)
-	    goto failret;
-	if (*p == ')')
-	{
-	    *arg = p + 1;
-	    return OK;
-	}
-	if (must_end)
-	{
-	    semsg(_(e_missing_comma_before_argument_str), p);
-	    return FAIL;
-	}
-
-	instr_count = cctx->ctx_instr.ga_len;
-	if (compile_expr0(&p, cctx) == FAIL)
-	    return FAIL;
-	++*argcount;
-
-	if (is_searchpair && *argcount == 5
-		&& cctx->ctx_instr.ga_len == instr_count + 1)
-	{
-	    isn_T *isn = ((isn_T *)cctx->ctx_instr.ga_data) + instr_count;
-
-	    // {skip} argument of searchpair() can be compiled if not empty
-	    if (isn->isn_type == ISN_PUSHS && *isn->isn_arg.string != NUL)
-		compile_string(isn, cctx);
-	}
-
-	if (*p != ',' && *skipwhite(p) == ',')
-	{
-	    semsg(_(e_no_white_space_allowed_before_str_str), ",", p);
-	    p = skipwhite(p);
-	}
-	if (*p == ',')
-	{
-	    ++p;
-	    if (*p != NUL && !VIM_ISWHITE(*p))
-		semsg(_(e_white_space_required_after_str_str), ",", p - 1);
-	}
-	else
-	    must_end = TRUE;
-	whitep = p;
-	p = skipwhite(p);
-    }
-failret:
-    emsg(_(e_missing_closing_paren));
-    return FAIL;
-}
-
-/*
- * Compile a function call:  name(arg1, arg2)
- * "arg" points to "name", "arg + varlen" to the "(".
- * "argcount_init" is 1 for "value->method()"
- * Instructions:
- *	EVAL arg1
- *	EVAL arg2
- *	BCALL / DCALL / UCALL
- */
-    static int
-compile_call(
-	char_u	    **arg,
-	size_t	    varlen,
-	cctx_T	    *cctx,
-	ppconst_T   *ppconst,
-	int	    argcount_init)
-{
-    char_u	*name = *arg;
-    char_u	*p;
-    int		argcount = argcount_init;
-    char_u	namebuf[100];
-    char_u	fname_buf[FLEN_FIXED + 1];
-    char_u	*tofree = NULL;
-    int		error = FCERR_NONE;
-    ufunc_T	*ufunc = NULL;
-    int		res = FAIL;
-    int		is_autoload;
-    int		is_searchpair;
-
-    // We can evaluate "has('name')" at compile time.
-    // We always evaluate "exists_compiled()" at compile time.
-    if ((varlen == 3 && STRNCMP(*arg, "has", 3) == 0)
-	    || (varlen == 15 && STRNCMP(*arg, "exists_compiled", 6) == 0))
-    {
-	char_u	    *s = skipwhite(*arg + varlen + 1);
-	typval_T    argvars[2];
-	int	    is_has = **arg == 'h';
-
-	argvars[0].v_type = VAR_UNKNOWN;
-	if (*s == '"')
-	    (void)eval_string(&s, &argvars[0], TRUE);
-	else if (*s == '\'')
-	    (void)eval_lit_string(&s, &argvars[0], TRUE);
-	s = skipwhite(s);
-	if (*s == ')' && argvars[0].v_type == VAR_STRING
-	       && ((is_has && !dynamic_feature(argvars[0].vval.v_string))
-		    || !is_has))
-	{
-	    typval_T	*tv = &ppconst->pp_tv[ppconst->pp_used];
-
-	    *arg = s + 1;
-	    argvars[1].v_type = VAR_UNKNOWN;
-	    tv->v_type = VAR_NUMBER;
-	    tv->vval.v_number = 0;
-	    if (is_has)
-		f_has(argvars, tv);
-	    else
-		f_exists(argvars, tv);
-	    clear_tv(&argvars[0]);
-	    ++ppconst->pp_used;
-	    return OK;
-	}
-	clear_tv(&argvars[0]);
-	if (!is_has)
-	{
-	    emsg(_(e_argument_of_exists_compiled_must_be_literal_string));
-	    return FAIL;
-	}
-    }
-
-    if (generate_ppconst(cctx, ppconst) == FAIL)
-	return FAIL;
-
-    if (varlen >= sizeof(namebuf))
-    {
-	semsg(_(e_name_too_long_str), name);
-	return FAIL;
-    }
-    vim_strncpy(namebuf, *arg, varlen);
-    name = fname_trans_sid(namebuf, fname_buf, &tofree, &error);
-
-    // We handle the "skip" argument of searchpair() and searchpairpos()
-    // differently.
-    is_searchpair = (varlen == 6 && STRNCMP(*arg, "search", 6) == 0)
-	         || (varlen == 9 && STRNCMP(*arg, "searchpos", 9) == 0)
-	        || (varlen == 10 && STRNCMP(*arg, "searchpair", 10) == 0)
-	        || (varlen == 13 && STRNCMP(*arg, "searchpairpos", 13) == 0);
-
-    *arg = skipwhite(*arg + varlen + 1);
-    if (compile_arguments(arg, cctx, &argcount, is_searchpair) == FAIL)
-	goto theend;
-
-    is_autoload = vim_strchr(name, AUTOLOAD_CHAR) != NULL;
-    if (ASCII_ISLOWER(*name) && name[1] != ':' && !is_autoload)
-    {
-	int	    idx;
-
-	// builtin function
-	idx = find_internal_func(name);
-	if (idx >= 0)
-	{
-	    if (STRCMP(name, "flatten") == 0)
-	    {
-		emsg(_(e_cannot_use_flatten_in_vim9_script));
-		goto theend;
-	    }
-
-	    if (STRCMP(name, "add") == 0 && argcount == 2)
-	    {
-		garray_T    *stack = &cctx->ctx_type_stack;
-		type_T	    *type = ((type_T **)stack->ga_data)[
-							    stack->ga_len - 2];
-
-		// add() can be compiled to instructions if we know the type
-		if (type->tt_type == VAR_LIST)
-		{
-		    // inline "add(list, item)" so that the type can be checked
-		    res = generate_LISTAPPEND(cctx);
-		    idx = -1;
-		}
-		else if (type->tt_type == VAR_BLOB)
-		{
-		    // inline "add(blob, nr)" so that the type can be checked
-		    res = generate_BLOBAPPEND(cctx);
-		    idx = -1;
-		}
-	    }
-
-	    if (idx >= 0)
-		res = generate_BCALL(cctx, idx, argcount, argcount_init == 1);
-	}
-	else
-	    semsg(_(e_unknown_function_str), namebuf);
-	goto theend;
-    }
-
-    // An argument or local variable can be a function reference, this
-    // overrules a function name.
-    if (lookup_local(namebuf, varlen, NULL, cctx) == FAIL
-	    && arg_exists(namebuf, varlen, NULL, NULL, NULL, cctx) != OK)
-    {
-	// If we can find the function by name generate the right call.
-	// Skip global functions here, a local funcref takes precedence.
-	ufunc = find_func(name, FALSE, cctx);
-	if (ufunc != NULL && !func_is_global(ufunc))
-	{
-	    res = generate_CALL(cctx, ufunc, argcount);
-	    goto theend;
-	}
-    }
-
-    // If the name is a variable, load it and use PCALL.
-    // Not for g:Func(), we don't know if it is a variable or not.
-    // Not for eome#Func(), it will be loaded later.
-    p = namebuf;
-    if (STRNCMP(namebuf, "g:", 2) != 0 && !is_autoload
-	    && compile_load(&p, namebuf + varlen, cctx, FALSE, FALSE) == OK)
-    {
-	garray_T    *stack = &cctx->ctx_type_stack;
-	type_T	    *type = ((type_T **)stack->ga_data)[stack->ga_len - 1];
-
-	res = generate_PCALL(cctx, argcount, namebuf, type, FALSE);
-	goto theend;
-    }
-
-    // If we can find a global function by name generate the right call.
-    if (ufunc != NULL)
-    {
-	res = generate_CALL(cctx, ufunc, argcount);
-	goto theend;
-    }
-
-    // A global function may be defined only later.  Need to figure out at
-    // runtime.  Also handles a FuncRef at runtime.
-    if (STRNCMP(namebuf, "g:", 2) == 0 || is_autoload)
-	res = generate_UCALL(cctx, name, argcount);
-    else
-	semsg(_(e_unknown_function_str), namebuf);
-
-theend:
-    vim_free(tofree);
-    return res;
-}
-
-// like NAMESPACE_CHAR but with 'a' and 'l'.
-#define VIM9_NAMESPACE_CHAR	(char_u *)"bgstvw"
-
-/*
- * Find the end of a variable or function name.  Unlike find_name_end() this
- * does not recognize magic braces.
- * When "use_namespace" is TRUE recognize "b:", "s:", etc.
- * Return a pointer to just after the name.  Equal to "arg" if there is no
- * valid name.
- */
-    char_u *
-to_name_end(char_u *arg, int use_namespace)
-{
-    char_u	*p;
-
-    // Quick check for valid starting character.
-    if (!eval_isnamec1(*arg))
-	return arg;
-
-    for (p = arg + 1; *p != NUL && eval_isnamec(*p); MB_PTR_ADV(p))
-	// Include a namespace such as "s:var" and "v:var".  But "n:" is not
-	// and can be used in slice "[n:]".
-	if (*p == ':' && (p != arg + 1
-			     || !use_namespace
-			     || vim_strchr(VIM9_NAMESPACE_CHAR, *arg) == NULL))
-	    break;
-    return p;
-}
-
-/*
- * Like to_name_end() but also skip over a list or dict constant.
- * Also accept "<SNR>123_Func".
- * This intentionally does not handle line continuation.
- */
-    char_u *
-to_name_const_end(char_u *arg)
-{
-    char_u	*p = arg;
-    typval_T	rettv;
-
-    if (STRNCMP(p, "<SNR>", 5) == 0)
-	p = skipdigits(p + 5);
-    p = to_name_end(p, TRUE);
-    if (p == arg && *arg == '[')
-    {
-
-	// Can be "[1, 2, 3]->Func()".
-	if (eval_list(&p, &rettv, NULL, FALSE) == FAIL)
-	    p = arg;
-    }
-    return p;
-}
-
-/*
- * parse a list: [expr, expr]
- * "*arg" points to the '['.
- * ppconst->pp_is_const is set if all items are a constant.
- */
-    static int
-compile_list(char_u **arg, cctx_T *cctx, ppconst_T *ppconst)
-{
-    char_u	*p = skipwhite(*arg + 1);
-    char_u	*whitep = *arg + 1;
-    int		count = 0;
-    int		is_const;
-    int		is_all_const = TRUE;	// reset when non-const encountered
-
-    for (;;)
-    {
-	if (may_get_next_line(whitep, &p, cctx) == FAIL)
-	{
-	    semsg(_(e_list_end), *arg);
-	    return FAIL;
-	}
-	if (*p == ',')
-	{
-	    semsg(_(e_no_white_space_allowed_before_str_str), ",", p);
-	    return FAIL;
-	}
-	if (*p == ']')
-	{
-	    ++p;
-	    break;
-	}
-	if (compile_expr0_ext(&p, cctx, &is_const) == FAIL)
-	    return FAIL;
-	if (!is_const)
-	    is_all_const = FALSE;
-	++count;
-	if (*p == ',')
-	{
-	    ++p;
-	    if (*p != ']' && !IS_WHITE_OR_NUL(*p))
-	    {
-		semsg(_(e_white_space_required_after_str_str), ",", p - 1);
-		return FAIL;
-	    }
-	}
-	whitep = p;
-	p = skipwhite(p);
-    }
-    *arg = p;
-
-    ppconst->pp_is_const = is_all_const;
-    return generate_NEWLIST(cctx, count);
-}
-
-/*
- * Parse a lambda: "(arg, arg) => expr"
- * "*arg" points to the '('.
- * Returns OK/FAIL when a lambda is recognized, NOTDONE if it's not a lambda.
- */
-    static int
-compile_lambda(char_u **arg, cctx_T *cctx)
-{
-    int		r;
-    typval_T	rettv;
-    ufunc_T	*ufunc;
-    evalarg_T	evalarg;
-
-    init_evalarg(&evalarg);
-    evalarg.eval_flags = EVAL_EVALUATE;
-    evalarg.eval_cctx = cctx;
-
-    // Get the funcref in "rettv".
-    r = get_lambda_tv(arg, &rettv, TRUE, &evalarg);
-    if (r != OK)
-    {
-	clear_evalarg(&evalarg, NULL);
-	return r;
-    }
-
-    // "rettv" will now be a partial referencing the function.
-    ufunc = rettv.vval.v_partial->pt_func;
-    ++ufunc->uf_refcount;
-    clear_tv(&rettv);
-
-    // Compile it here to get the return type.  The return type is optional,
-    // when it's missing use t_unknown.  This is recognized in
-    // compile_return().
-    if (ufunc->uf_ret_type->tt_type == VAR_VOID)
-	ufunc->uf_ret_type = &t_unknown;
-    compile_def_function(ufunc, FALSE, cctx->ctx_compile_type, cctx);
-
-    // When the outer function is compiled for profiling or debugging, the
-    // lambda may be called without profiling or debugging.  Compile it here in
-    // the right context.
-    if (cctx->ctx_compile_type == CT_DEBUG
-#ifdef FEAT_PROFILE
-	    || cctx->ctx_compile_type == CT_PROFILE
-#endif
-       )
-	compile_def_function(ufunc, FALSE, CT_NONE, cctx);
-
-    // The last entry in evalarg.eval_tofree_ga is a copy of the last line and
-    // "*arg" may point into it.  Point into the original line to avoid a
-    // dangling pointer.
-    if (evalarg.eval_using_cmdline)
-    {
-	garray_T    *gap = &evalarg.eval_tofree_ga;
-	size_t	    off = *arg - ((char_u **)gap->ga_data)[gap->ga_len - 1];
-
-	*arg = ((char_u **)cctx->ctx_ufunc->uf_lines.ga_data)[cctx->ctx_lnum]
-									 + off;
-    }
-
-    clear_evalarg(&evalarg, NULL);
-
-    if (ufunc->uf_def_status == UF_COMPILED)
-    {
-	// The return type will now be known.
-	set_function_type(ufunc);
-
-	// The function reference count will be 1.  When the ISN_FUNCREF
-	// instruction is deleted the reference count is decremented and the
-	// function is freed.
-	return generate_FUNCREF(cctx, ufunc);
-    }
-
-    func_ptr_unref(ufunc);
-    return FAIL;
-}
-
-/*
- * Get a lambda and compile it.  Uses Vim9 syntax.
- */
-    int
-get_lambda_tv_and_compile(
-	char_u	    **arg,
-	typval_T    *rettv,
-	int	    types_optional,
-	evalarg_T   *evalarg)
-{
-    int		r;
-    ufunc_T	*ufunc;
-    int		save_sc_version = current_sctx.sc_version;
-
-    // Get the funcref in "rettv".
-    current_sctx.sc_version = SCRIPT_VERSION_VIM9;
-    r = get_lambda_tv(arg, rettv, types_optional, evalarg);
-    current_sctx.sc_version = save_sc_version;
-    if (r != OK)
-	return r;
-
-    // "rettv" will now be a partial referencing the function.
-    ufunc = rettv->vval.v_partial->pt_func;
-
-    // Compile it here to get the return type.  The return type is optional,
-    // when it's missing use t_unknown.  This is recognized in
-    // compile_return().
-    if (ufunc->uf_ret_type == NULL || ufunc->uf_ret_type->tt_type == VAR_VOID)
-	ufunc->uf_ret_type = &t_unknown;
-    compile_def_function(ufunc, FALSE, CT_NONE, NULL);
-
-    if (ufunc->uf_def_status == UF_COMPILED)
-    {
-	// The return type will now be known.
-	set_function_type(ufunc);
-	return OK;
-    }
-    clear_tv(rettv);
-    return FAIL;
-}
-
-/*
- * parse a dict: {key: val, [key]: val}
- * "*arg" points to the '{'.
- * ppconst->pp_is_const is set if all item values are a constant.
- */
-    static int
-compile_dict(char_u **arg, cctx_T *cctx, ppconst_T *ppconst)
-{
-    garray_T	*instr = &cctx->ctx_instr;
-    int		count = 0;
-    dict_T	*d = dict_alloc();
-    dictitem_T	*item;
-    char_u	*whitep = *arg + 1;
-    char_u	*p;
-    int		is_const;
-    int		is_all_const = TRUE;	// reset when non-const encountered
-
-    if (d == NULL)
-	return FAIL;
-    if (generate_ppconst(cctx, ppconst) == FAIL)
-	return FAIL;
-    for (;;)
-    {
-	char_u	    *key = NULL;
-
-	if (may_get_next_line(whitep, arg, cctx) == FAIL)
-	{
-	    *arg = NULL;
-	    goto failret;
-	}
-
-	if (**arg == '}')
-	    break;
-
-	if (**arg == '[')
-	{
-	    isn_T	*isn;
-
-	    // {[expr]: value} uses an evaluated key.
-	    *arg = skipwhite(*arg + 1);
-	    if (compile_expr0(arg, cctx) == FAIL)
-		return FAIL;
-	    isn = ((isn_T *)instr->ga_data) + instr->ga_len - 1;
-	    if (isn->isn_type == ISN_PUSHNR)
-	    {
-		char buf[NUMBUFLEN];
-
-		// Convert to string at compile time.
-		vim_snprintf(buf, NUMBUFLEN, "%lld", isn->isn_arg.number);
-		isn->isn_type = ISN_PUSHS;
-		isn->isn_arg.string = vim_strsave((char_u *)buf);
-	    }
-	    if (isn->isn_type == ISN_PUSHS)
-		key = isn->isn_arg.string;
-	    else if (may_generate_2STRING(-1, FALSE, cctx) == FAIL)
-		return FAIL;
-	    *arg = skipwhite(*arg);
-	    if (**arg != ']')
-	    {
-		emsg(_(e_missing_matching_bracket_after_dict_key));
-		return FAIL;
-	    }
-	    ++*arg;
-	}
-	else
-	{
-	    // {"name": value},
-	    // {'name': value},
-	    // {name: value} use "name" as a literal key
-	    key = get_literal_key(arg);
-	    if (key == NULL)
-		return FAIL;
-	    if (generate_PUSHS(cctx, &key) == FAIL)
-		return FAIL;
-	}
-
-	// Check for duplicate keys, if using string keys.
-	if (key != NULL)
-	{
-	    item = dict_find(d, key, -1);
-	    if (item != NULL)
-	    {
-		semsg(_(e_duplicate_key), key);
-		goto failret;
-	    }
-	    item = dictitem_alloc(key);
-	    if (item != NULL)
-	    {
-		item->di_tv.v_type = VAR_UNKNOWN;
-		item->di_tv.v_lock = 0;
-		if (dict_add(d, item) == FAIL)
-		    dictitem_free(item);
-	    }
-	}
-
-	if (**arg != ':')
-	{
-	    if (*skipwhite(*arg) == ':')
-		semsg(_(e_no_white_space_allowed_before_str_str), ":", *arg);
-	    else
-		semsg(_(e_missing_dict_colon), *arg);
-	    return FAIL;
-	}
-	whitep = *arg + 1;
-	if (!IS_WHITE_OR_NUL(*whitep))
-	{
-	    semsg(_(e_white_space_required_after_str_str), ":", *arg);
-	    return FAIL;
-	}
-
-	if (may_get_next_line(whitep, arg, cctx) == FAIL)
-	{
-	    *arg = NULL;
-	    goto failret;
-	}
-
-	if (compile_expr0_ext(arg, cctx, &is_const) == FAIL)
-	    return FAIL;
-	if (!is_const)
-	    is_all_const = FALSE;
-	++count;
-
-	whitep = *arg;
-	if (may_get_next_line(whitep, arg, cctx) == FAIL)
-	{
-	    *arg = NULL;
-	    goto failret;
-	}
-	if (**arg == '}')
-	    break;
-	if (**arg != ',')
-	{
-	    semsg(_(e_missing_dict_comma), *arg);
-	    goto failret;
-	}
-	if (IS_WHITE_OR_NUL(*whitep))
-	{
-	    semsg(_(e_no_white_space_allowed_before_str_str), ",", whitep);
-	    return FAIL;
-	}
-	whitep = *arg + 1;
-	if (!IS_WHITE_OR_NUL(*whitep))
-	{
-	    semsg(_(e_white_space_required_after_str_str), ",", *arg);
-	    return FAIL;
-	}
-	*arg = skipwhite(whitep);
-    }
-
-    *arg = *arg + 1;
-
-    // Allow for following comment, after at least one space.
-    p = skipwhite(*arg);
-    if (VIM_ISWHITE(**arg) && vim9_comment_start(p))
-	*arg += STRLEN(*arg);
-
-    dict_unref(d);
-    ppconst->pp_is_const = is_all_const;
-    return generate_NEWDICT(cctx, count);
-
-failret:
-    if (*arg == NULL)
-    {
-	semsg(_(e_missing_dict_end), _("[end of lines]"));
-	*arg = (char_u *)"";
-    }
-    dict_unref(d);
-    return FAIL;
-}
-
-/*
- * Compile "&option".
- */
-    static int
-compile_get_option(char_u **arg, cctx_T *cctx)
-{
-    typval_T	rettv;
-    char_u	*start = *arg;
-    int		ret;
-
-    // parse the option and get the current value to get the type.
-    rettv.v_type = VAR_UNKNOWN;
-    ret = eval_option(arg, &rettv, TRUE);
-    if (ret == OK)
-    {
-	// include the '&' in the name, eval_option() expects it.
-	char_u	*name = vim_strnsave(start, *arg - start);
-	type_T	*type = rettv.v_type == VAR_BOOL ? &t_bool
-			  : rettv.v_type == VAR_NUMBER ? &t_number : &t_string;
-
-	ret = generate_LOAD(cctx, ISN_LOADOPT, 0, name, type);
-	vim_free(name);
-    }
-    clear_tv(&rettv);
-
-    return ret;
-}
-
-/*
- * Compile "$VAR".
- */
-    static int
-compile_get_env(char_u **arg, cctx_T *cctx)
-{
-    char_u	*start = *arg;
-    int		len;
-    int		ret;
-    char_u	*name;
-
-    ++*arg;
-    len = get_env_len(arg);
-    if (len == 0)
-    {
-	semsg(_(e_syntax_error_at_str), start - 1);
-	return FAIL;
-    }
-
-    // include the '$' in the name, eval_env_var() expects it.
-    name = vim_strnsave(start, len + 1);
-    ret = generate_LOAD(cctx, ISN_LOADENV, 0, name, &t_string);
-    vim_free(name);
-    return ret;
-}
-
-/*
- * Compile "@r".
- */
-    static int
-compile_get_register(char_u **arg, cctx_T *cctx)
-{
-    int		ret;
-
-    ++*arg;
-    if (**arg == NUL)
-    {
-	semsg(_(e_syntax_error_at_str), *arg - 1);
-	return FAIL;
-    }
-    if (!valid_yank_reg(**arg, FALSE))
-    {
-	emsg_invreg(**arg);
-	return FAIL;
-    }
-    ret = generate_LOAD(cctx, ISN_LOADREG, **arg, NULL, &t_string);
-    ++*arg;
-    return ret;
-}
-
-/*
- * Apply leading '!', '-' and '+' to constant "rettv".
- * When "numeric_only" is TRUE do not apply '!'.
- */
-    static int
-apply_leader(typval_T *rettv, int numeric_only, char_u *start, char_u **end)
-{
-    char_u *p = *end;
-
-    // this works from end to start
-    while (p > start)
-    {
-	--p;
-	if (*p == '-' || *p == '+')
-	{
-	    // only '-' has an effect, for '+' we only check the type
-#ifdef FEAT_FLOAT
-	    if (rettv->v_type == VAR_FLOAT)
-	    {
-		if (*p == '-')
-		    rettv->vval.v_float = -rettv->vval.v_float;
-	    }
-	    else
-#endif
-	    {
-		varnumber_T	val;
-		int		error = FALSE;
-
-		// tv_get_number_chk() accepts a string, but we don't want that
-		// here
-		if (check_not_string(rettv) == FAIL)
-		    return FAIL;
-		val = tv_get_number_chk(rettv, &error);
-		clear_tv(rettv);
-		if (error)
-		    return FAIL;
-		if (*p == '-')
-		    val = -val;
-		rettv->v_type = VAR_NUMBER;
-		rettv->vval.v_number = val;
-	    }
-	}
-	else if (numeric_only)
-	{
-	    ++p;
-	    break;
-	}
-	else if (*p == '!')
-	{
-	    int v = tv2bool(rettv);
-
-	    // '!' is permissive in the type.
-	    clear_tv(rettv);
-	    rettv->v_type = VAR_BOOL;
-	    rettv->vval.v_number = v ? VVAL_FALSE : VVAL_TRUE;
-	}
-    }
-    *end = p;
-    return OK;
-}
-
-/*
- * Recognize v: variables that are constants and set "rettv".
- */
-    static void
-get_vim_constant(char_u **arg, typval_T *rettv)
-{
-    if (STRNCMP(*arg, "v:true", 6) == 0)
-    {
-	rettv->v_type = VAR_BOOL;
-	rettv->vval.v_number = VVAL_TRUE;
-	*arg += 6;
-    }
-    else if (STRNCMP(*arg, "v:false", 7) == 0)
-    {
-	rettv->v_type = VAR_BOOL;
-	rettv->vval.v_number = VVAL_FALSE;
-	*arg += 7;
-    }
-    else if (STRNCMP(*arg, "v:null", 6) == 0)
-    {
-	rettv->v_type = VAR_SPECIAL;
-	rettv->vval.v_number = VVAL_NULL;
-	*arg += 6;
-    }
-    else if (STRNCMP(*arg, "v:none", 6) == 0)
-    {
-	rettv->v_type = VAR_SPECIAL;
-	rettv->vval.v_number = VVAL_NONE;
-	*arg += 6;
-    }
-}
-
-    exprtype_T
-get_compare_type(char_u *p, int *len, int *type_is)
-{
-    exprtype_T	type = EXPR_UNKNOWN;
-    int		i;
-
-    switch (p[0])
-    {
-	case '=':   if (p[1] == '=')
-			type = EXPR_EQUAL;
-		    else if (p[1] == '~')
-			type = EXPR_MATCH;
-		    break;
-	case '!':   if (p[1] == '=')
-			type = EXPR_NEQUAL;
-		    else if (p[1] == '~')
-			type = EXPR_NOMATCH;
-		    break;
-	case '>':   if (p[1] != '=')
-		    {
-			type = EXPR_GREATER;
-			*len = 1;
-		    }
-		    else
-			type = EXPR_GEQUAL;
-		    break;
-	case '<':   if (p[1] != '=')
-		    {
-			type = EXPR_SMALLER;
-			*len = 1;
-		    }
-		    else
-			type = EXPR_SEQUAL;
-		    break;
-	case 'i':   if (p[1] == 's')
-		    {
-			// "is" and "isnot"; but not a prefix of a name
-			if (p[2] == 'n' && p[3] == 'o' && p[4] == 't')
-			    *len = 5;
-			i = p[*len];
-			if (!isalnum(i) && i != '_')
-			{
-			    type = *len == 2 ? EXPR_IS : EXPR_ISNOT;
-			    *type_is = TRUE;
-			}
-		    }
-		    break;
-    }
-    return type;
-}
-
-/*
- * Skip over an expression, ignoring most errors.
- */
-    static void
-skip_expr_cctx(char_u **arg, cctx_T *cctx)
-{
-    evalarg_T	evalarg;
-
-    init_evalarg(&evalarg);
-    evalarg.eval_cctx = cctx;
-    skip_expr(arg, &evalarg);
-    clear_evalarg(&evalarg, NULL);
-}
-
-/*
- * Compile code to apply '-', '+' and '!'.
- * When "numeric_only" is TRUE do not apply '!'.
- */
-    static int
-compile_leader(cctx_T *cctx, int numeric_only, char_u *start, char_u **end)
-{
-    char_u	*p = *end;
-
-    // this works from end to start
-    while (p > start)
-    {
-	--p;
-	while (VIM_ISWHITE(*p))
-	    --p;
-	if (*p == '-' || *p == '+')
-	{
-	    int		negate = *p == '-';
-	    isn_T	*isn;
-	    garray_T    *stack = &cctx->ctx_type_stack;
-	    type_T	*type;
-
-	    type = ((type_T **)stack->ga_data)[stack->ga_len - 1];
-	    if (type != &t_float && need_type(type, &t_number,
-					    -1, 0, cctx, FALSE, FALSE) == FAIL)
-		return FAIL;
-
-	    while (p > start && (p[-1] == '-' || p[-1] == '+'))
-	    {
-		--p;
-		if (*p == '-')
-		    negate = !negate;
-	    }
-	    // only '-' has an effect, for '+' we only check the type
-	    if (negate)
-	    {
-		isn = generate_instr(cctx, ISN_NEGATENR);
-		if (isn == NULL)
-		    return FAIL;
-	    }
-	}
-	else if (numeric_only)
-	{
-	    ++p;
-	    break;
-	}
-	else
-	{
-	    int  invert = *p == '!';
-
-	    while (p > start && (p[-1] == '!' || VIM_ISWHITE(p[-1])))
-	    {
-		if (p[-1] == '!')
-		    invert = !invert;
-		--p;
-	    }
-	    if (generate_2BOOL(cctx, invert, -1) == FAIL)
-		return FAIL;
-	}
-    }
-    *end = p;
-    return OK;
-}
-
-/*
- * Compile "(expression)": recursive!
- * Return FAIL/OK.
- */
-    static int
-compile_parenthesis(char_u **arg, cctx_T *cctx, ppconst_T *ppconst)
-{
-    int	    ret;
-    char_u  *p = *arg + 1;
-
-    if (may_get_next_line_error(p, arg, cctx) == FAIL)
-	return FAIL;
-    if (ppconst->pp_used <= PPSIZE - 10)
-    {
-	ret = compile_expr1(arg, cctx, ppconst);
-    }
-    else
-    {
-	// Not enough space in ppconst, flush constants.
-	if (generate_ppconst(cctx, ppconst) == FAIL)
-	    return FAIL;
-	ret = compile_expr0(arg, cctx);
-    }
-    if (may_get_next_line_error(*arg, arg, cctx) == FAIL)
-	return FAIL;
-    if (**arg == ')')
-	++*arg;
-    else if (ret == OK)
-    {
-	emsg(_(e_missing_closing_paren));
-	ret = FAIL;
-    }
-    return ret;
-}
-
-/*
- * Compile whatever comes after "name" or "name()".
- * Advances "*arg" only when something was recognized.
- */
-    static int
-compile_subscript(
-	char_u **arg,
-	cctx_T *cctx,
-	char_u *start_leader,
-	char_u **end_leader,
-	ppconst_T *ppconst)
-{
-    char_u	*name_start = *end_leader;
-    int		keeping_dict = FALSE;
-
-    for (;;)
-    {
-	char_u *p = skipwhite(*arg);
-
-	if (*p == NUL || (VIM_ISWHITE(**arg) && vim9_comment_start(p)))
-	{
-	    char_u *next = peek_next_line_from_context(cctx);
-
-	    // If a following line starts with "->{" or "->X" advance to that
-	    // line, so that a line break before "->" is allowed.
-	    // Also if a following line starts with ".x".
-	    if (next != NULL &&
-		    ((next[0] == '-' && next[1] == '>'
-				 && (next[2] == '{'
-				       || ASCII_ISALPHA(*skipwhite(next + 2))))
-		    || (next[0] == '.' && eval_isdictc(next[1]))))
-	    {
-		next = next_line_from_context(cctx, TRUE);
-		if (next == NULL)
-		    return FAIL;
-		*arg = next;
-		p = skipwhite(*arg);
-	    }
-	}
-
-	// Do not skip over white space to find the "(", "execute 'x' (expr)"
-	// is not a function call.
-	if (**arg == '(')
-	{
-	    garray_T    *stack = &cctx->ctx_type_stack;
-	    type_T	*type;
-	    int		argcount = 0;
-
-	    if (generate_ppconst(cctx, ppconst) == FAIL)
-		return FAIL;
-	    ppconst->pp_is_const = FALSE;
-
-	    // funcref(arg)
-	    type = ((type_T **)stack->ga_data)[stack->ga_len - 1];
-
-	    *arg = skipwhite(p + 1);
-	    if (compile_arguments(arg, cctx, &argcount, FALSE) == FAIL)
-		return FAIL;
-	    if (generate_PCALL(cctx, argcount, name_start, type, TRUE) == FAIL)
-		return FAIL;
-	    if (keeping_dict)
-	    {
-		keeping_dict = FALSE;
-		if (generate_instr(cctx, ISN_CLEARDICT) == NULL)
-		    return FAIL;
-	    }
-	}
-	else if (*p == '-' && p[1] == '>')
-	{
-	    char_u *pstart = p;
-
-	    if (generate_ppconst(cctx, ppconst) == FAIL)
-		return FAIL;
-	    ppconst->pp_is_const = FALSE;
-
-	    // something->method()
-	    // Apply the '!', '-' and '+' first:
-	    //   -1.0->func() works like (-1.0)->func()
-	    if (compile_leader(cctx, TRUE, start_leader, end_leader) == FAIL)
-		return FAIL;
-
-	    p += 2;
-	    *arg = skipwhite(p);
-	    // No line break supported right after "->".
-	    if (**arg == '(')
-	    {
-		int	    argcount = 1;
-		garray_T    *stack = &cctx->ctx_type_stack;
-		int	    type_idx_start = stack->ga_len;
-		type_T	    *type;
-		int	    expr_isn_start = cctx->ctx_instr.ga_len;
-		int	    expr_isn_end;
-		int	    arg_isn_count;
-
-		// Funcref call:  list->(Refs[2])(arg)
-		// or lambda:	  list->((arg) => expr)(arg)
-		//
-		// Fist compile the function expression.
-		if (compile_parenthesis(arg, cctx, ppconst) == FAIL)
-		    return FAIL;
-
-		// Remember the next instruction index, where the instructions
-		// for arguments are being written.
-		expr_isn_end = cctx->ctx_instr.ga_len;
-
-		// Compile the arguments.
-		if (**arg != '(')
-		{
-		    if (*skipwhite(*arg) == '(')
-			emsg(_(e_nowhitespace));
-		    else
-			semsg(_(e_missing_parenthesis_str), *arg);
-		    return FAIL;
-		}
-		*arg = skipwhite(*arg + 1);
-		if (compile_arguments(arg, cctx, &argcount, FALSE) == FAIL)
-		    return FAIL;
-
-		// Move the instructions for the arguments to before the
-		// instructions of the expression and move the type of the
-		// expression after the argument types.  This is what ISN_PCALL
-		// expects.
-		stack = &cctx->ctx_type_stack;
-		arg_isn_count = cctx->ctx_instr.ga_len - expr_isn_end;
-		if (arg_isn_count > 0)
-		{
-		    int	    expr_isn_count = expr_isn_end - expr_isn_start;
-		    isn_T   *isn = ALLOC_MULT(isn_T, expr_isn_count);
-
-		    if (isn == NULL)
-			return FAIL;
-		    mch_memmove(isn, ((isn_T *)cctx->ctx_instr.ga_data)
-							      + expr_isn_start,
-					       sizeof(isn_T) * expr_isn_count);
-		    mch_memmove(((isn_T *)cctx->ctx_instr.ga_data)
-							      + expr_isn_start,
-			     ((isn_T *)cctx->ctx_instr.ga_data) + expr_isn_end,
-						sizeof(isn_T) * arg_isn_count);
-		    mch_memmove(((isn_T *)cctx->ctx_instr.ga_data)
-					      + expr_isn_start + arg_isn_count,
-					  isn, sizeof(isn_T) * expr_isn_count);
-		    vim_free(isn);
-
-		    type = ((type_T **)stack->ga_data)[type_idx_start];
-		    mch_memmove(((type_T **)stack->ga_data) + type_idx_start,
-			      ((type_T **)stack->ga_data) + type_idx_start + 1,
-			      sizeof(type_T *)
-				       * (stack->ga_len - type_idx_start - 1));
-		    ((type_T **)stack->ga_data)[stack->ga_len - 1] = type;
-		}
-
-		type = ((type_T **)stack->ga_data)[stack->ga_len - 1];
-		if (generate_PCALL(cctx, argcount, p - 2, type, FALSE) == FAIL)
-		    return FAIL;
-	    }
-	    else
-	    {
-		// method call:  list->method()
-		p = *arg;
-		if (!eval_isnamec1(*p))
-		{
-		    semsg(_(e_trailing_arg), pstart);
-		    return FAIL;
-		}
-		if (ASCII_ISALPHA(*p) && p[1] == ':')
-		    p += 2;
-		for ( ; eval_isnamec(*p); ++p)
-		    ;
-		if (*p != '(')
-		{
-		    semsg(_(e_missing_parenthesis_str), *arg);
-		    return FAIL;
-		}
-		if (compile_call(arg, p - *arg, cctx, ppconst, 1) == FAIL)
-		    return FAIL;
-	    }
-	    if (keeping_dict)
-	    {
-		keeping_dict = FALSE;
-		if (generate_instr(cctx, ISN_CLEARDICT) == NULL)
-		    return FAIL;
-	    }
-	}
-	else if (**arg == '[')
-	{
-	    int		is_slice = FALSE;
-
-	    // list index: list[123]
-	    // dict member: dict[key]
-	    // string index: text[123]
-	    // blob index: blob[123]
-	    if (generate_ppconst(cctx, ppconst) == FAIL)
-		return FAIL;
-	    ppconst->pp_is_const = FALSE;
-
-	    ++p;
-	    if (may_get_next_line_error(p, arg, cctx) == FAIL)
-		return FAIL;
-	    if (**arg == ':')
-	    {
-		// missing first index is equal to zero
-		generate_PUSHNR(cctx, 0);
-	    }
-	    else
-	    {
-		if (compile_expr0(arg, cctx) == FAIL)
-		    return FAIL;
-		if (**arg == ':')
-		{
-		    semsg(_(e_white_space_required_before_and_after_str_at_str),
-								    ":", *arg);
-		    return FAIL;
-		}
-		if (may_get_next_line_error(*arg, arg, cctx) == FAIL)
-		    return FAIL;
-		*arg = skipwhite(*arg);
-	    }
-	    if (**arg == ':')
-	    {
-		is_slice = TRUE;
-		++*arg;
-		if (!IS_WHITE_OR_NUL(**arg) && **arg != ']')
-		{
-		    semsg(_(e_white_space_required_before_and_after_str_at_str),
-								    ":", *arg);
-		    return FAIL;
-		}
-		if (may_get_next_line_error(*arg, arg, cctx) == FAIL)
-		    return FAIL;
-		if (**arg == ']')
-		    // missing second index is equal to end of string
-		    generate_PUSHNR(cctx, -1);
-		else
-		{
-		    if (compile_expr0(arg, cctx) == FAIL)
-			return FAIL;
-		    if (may_get_next_line_error(*arg, arg, cctx) == FAIL)
-			return FAIL;
-		    *arg = skipwhite(*arg);
-		}
-	    }
-
-	    if (**arg != ']')
-	    {
-		emsg(_(e_missing_closing_square_brace));
-		return FAIL;
-	    }
-	    *arg = *arg + 1;
-
-	    if (keeping_dict)
-	    {
-		keeping_dict = FALSE;
-		if (generate_instr(cctx, ISN_CLEARDICT) == NULL)
-		    return FAIL;
-	    }
-	    if (compile_member(is_slice, &keeping_dict, cctx) == FAIL)
-		return FAIL;
-	}
-	else if (*p == '.' && p[1] != '.')
-	{
-	    // dictionary member: dict.name
-	    if (generate_ppconst(cctx, ppconst) == FAIL)
-		return FAIL;
-	    ppconst->pp_is_const = FALSE;
-
-	    *arg = p + 1;
-	    if (IS_WHITE_OR_NUL(**arg))
-	    {
-		emsg(_(e_missing_name_after_dot));
-		return FAIL;
-	    }
-	    p = *arg;
-	    if (eval_isdictc(*p))
-		while (eval_isnamec(*p))
-		    MB_PTR_ADV(p);
-	    if (p == *arg)
-	    {
-		semsg(_(e_syntax_error_at_str), *arg);
-		return FAIL;
-	    }
-	    if (keeping_dict && generate_instr(cctx, ISN_CLEARDICT) == NULL)
-		return FAIL;
-	    if (generate_STRINGMEMBER(cctx, *arg, p - *arg) == FAIL)
-		return FAIL;
-	    keeping_dict = TRUE;
-	    *arg = p;
-	}
-	else
-	    break;
-    }
-
-    // Turn "dict.Func" into a partial for "Func" bound to "dict".
-    // This needs to be done at runtime to be able to check the type.
-    if (keeping_dict && generate_instr(cctx, ISN_USEDICT) == NULL)
-	return FAIL;
-
-    return OK;
-}
-
-/*
- * Compile an expression at "*arg" and add instructions to "cctx->ctx_instr".
- * "arg" is advanced until after the expression, skipping white space.
- *
- * If the value is a constant "ppconst->pp_used" will be non-zero.
- * Before instructions are generated, any values in "ppconst" will generated.
- *
- * This is the compiling equivalent of eval1(), eval2(), etc.
- */
-
-/*
- *  number		number constant
- *  0zFFFFFFFF		Blob constant
- *  "string"		string constant
- *  'string'		literal string constant
- *  &option-name	option value
- *  @r			register contents
- *  identifier		variable value
- *  function()		function call
- *  $VAR		environment variable
- *  (expression)	nested expression
- *  [expr, expr]	List
- *  {key: val, [key]: val}   Dictionary
- *
- *  Also handle:
- *  ! in front		logical NOT
- *  - in front		unary minus
- *  + in front		unary plus (ignored)
- *  trailing (arg)	funcref/partial call
- *  trailing []		subscript in String or List
- *  trailing .name	entry in Dictionary
- *  trailing ->name()	method call
- */
-    static int
-compile_expr7(
-	char_u **arg,
-	cctx_T *cctx,
-	ppconst_T *ppconst)
-{
-    char_u	*start_leader, *end_leader;
-    int		ret = OK;
-    typval_T	*rettv = &ppconst->pp_tv[ppconst->pp_used];
-    int		used_before = ppconst->pp_used;
-
-    ppconst->pp_is_const = FALSE;
-
-    /*
-     * Skip '!', '-' and '+' characters.  They are handled later.
-     */
-    start_leader = *arg;
-    if (eval_leader(arg, TRUE) == FAIL)
-	return FAIL;
-    end_leader = *arg;
-
-    rettv->v_type = VAR_UNKNOWN;
-    switch (**arg)
-    {
-	/*
-	 * Number constant.
-	 */
-	case '0':	// also for blob starting with 0z
-	case '1':
-	case '2':
-	case '3':
-	case '4':
-	case '5':
-	case '6':
-	case '7':
-	case '8':
-	case '9':
-	case '.':   if (eval_number(arg, rettv, TRUE, FALSE) == FAIL)
-			return FAIL;
-		    // Apply "-" and "+" just before the number now, right to
-		    // left.  Matters especially when "->" follows.  Stops at
-		    // '!'.
-		    if (apply_leader(rettv, TRUE,
-					    start_leader, &end_leader) == FAIL)
-		    {
-			clear_tv(rettv);
-			return FAIL;
-		    }
-		    break;
-
-	/*
-	 * String constant: "string".
-	 */
-	case '"':   if (eval_string(arg, rettv, TRUE) == FAIL)
-			return FAIL;
-		    break;
-
-	/*
-	 * Literal string constant: 'str''ing'.
-	 */
-	case '\'':  if (eval_lit_string(arg, rettv, TRUE) == FAIL)
-			return FAIL;
-		    break;
-
-	/*
-	 * Constant Vim variable.
-	 */
-	case 'v':   get_vim_constant(arg, rettv);
-		    ret = NOTDONE;
-		    break;
-
-	/*
-	 * "true" constant
-	 */
-	case 't':   if (STRNCMP(*arg, "true", 4) == 0
-						   && !eval_isnamec((*arg)[4]))
-		    {
-			*arg += 4;
-			rettv->v_type = VAR_BOOL;
-			rettv->vval.v_number = VVAL_TRUE;
-		    }
-		    else
-			ret = NOTDONE;
-		    break;
-
-	/*
-	 * "false" constant
-	 */
-	case 'f':   if (STRNCMP(*arg, "false", 5) == 0
-						   && !eval_isnamec((*arg)[5]))
-		    {
-			*arg += 5;
-			rettv->v_type = VAR_BOOL;
-			rettv->vval.v_number = VVAL_FALSE;
-		    }
-		    else
-			ret = NOTDONE;
-		    break;
-
-	/*
-	 * "null" constant
-	 */
-	case 'n':   if (STRNCMP(*arg, "null", 4) == 0
-						   && !eval_isnamec((*arg)[4]))
-		    {
-			*arg += 4;
-			rettv->v_type = VAR_SPECIAL;
-			rettv->vval.v_number = VVAL_NULL;
-		    }
-		    else
-			ret = NOTDONE;
-		    break;
-
-	/*
-	 * List: [expr, expr]
-	 */
-	case '[':   if (generate_ppconst(cctx, ppconst) == FAIL)
-			return FAIL;
-		    ret = compile_list(arg, cctx, ppconst);
-		    break;
-
-	/*
-	 * Dictionary: {'key': val, 'key': val}
-	 */
-	case '{':   if (generate_ppconst(cctx, ppconst) == FAIL)
-			return FAIL;
-		    ret = compile_dict(arg, cctx, ppconst);
-		    break;
-
-	/*
-	 * Option value: &name
-	 */
-	case '&':	if (generate_ppconst(cctx, ppconst) == FAIL)
-			    return FAIL;
-			ret = compile_get_option(arg, cctx);
-			break;
-
-	/*
-	 * Environment variable: $VAR.
-	 */
-	case '$':	if (generate_ppconst(cctx, ppconst) == FAIL)
-			    return FAIL;
-			ret = compile_get_env(arg, cctx);
-			break;
-
-	/*
-	 * Register contents: @r.
-	 */
-	case '@':	if (generate_ppconst(cctx, ppconst) == FAIL)
-			    return FAIL;
-			ret = compile_get_register(arg, cctx);
-			break;
-	/*
-	 * nested expression: (expression).
-	 * lambda: (arg, arg) => expr
-	 * funcref: (arg, arg) => { statement }
-	 */
-	case '(':   // if compile_lambda returns NOTDONE then it must be (expr)
-		    ret = compile_lambda(arg, cctx);
-		    if (ret == NOTDONE)
-			ret = compile_parenthesis(arg, cctx, ppconst);
-		    break;
-
-	default:    ret = NOTDONE;
-		    break;
-    }
-    if (ret == FAIL)
-	return FAIL;
-
-    if (rettv->v_type != VAR_UNKNOWN && used_before == ppconst->pp_used)
-    {
-	if (cctx->ctx_skip == SKIP_YES)
-	    clear_tv(rettv);
-	else
-	    // A constant expression can possibly be handled compile time,
-	    // return the value instead of generating code.
-	    ++ppconst->pp_used;
-    }
-    else if (ret == NOTDONE)
-    {
-	char_u	    *p;
-	int	    r;
-
-	if (!eval_isnamec1(**arg))
-	{
-	    if (!vim9_bad_comment(*arg))
-	    {
-		if (ends_excmd(*skipwhite(*arg)))
-		    semsg(_(e_empty_expression_str), *arg);
-		else
-		    semsg(_(e_name_expected_str), *arg);
-	    }
-	    return FAIL;
-	}
-
-	// "name" or "name()"
-	p = to_name_end(*arg, TRUE);
-	if (p - *arg == (size_t)1 && **arg == '_')
-	{
-	    emsg(_(e_cannot_use_underscore_here));
-	    return FAIL;
-	}
-
-	if (*p == '(')
-	{
-	    r = compile_call(arg, p - *arg, cctx, ppconst, 0);
-	}
-	else
-	{
-	    if (cctx->ctx_skip != SKIP_YES
-				    && generate_ppconst(cctx, ppconst) == FAIL)
-		return FAIL;
-	    r = compile_load(arg, p, cctx, TRUE, TRUE);
-	}
-	if (r == FAIL)
-	    return FAIL;
-    }
-
-    // Handle following "[]", ".member", etc.
-    // Then deal with prefixed '-', '+' and '!', if not done already.
-    if (compile_subscript(arg, cctx, start_leader, &end_leader,
-							     ppconst) == FAIL)
-	return FAIL;
-    if (ppconst->pp_used > 0)
-    {
-	// apply the '!', '-' and '+' before the constant
-	rettv = &ppconst->pp_tv[ppconst->pp_used - 1];
-	if (apply_leader(rettv, FALSE, start_leader, &end_leader) == FAIL)
-	    return FAIL;
-	return OK;
-    }
-    if (compile_leader(cctx, FALSE, start_leader, &end_leader) == FAIL)
-	return FAIL;
-    return OK;
-}
-
-/*
- * Give the "white on both sides" error, taking the operator from "p[len]".
- */
-    void
-error_white_both(char_u *op, int len)
-{
-    char_u	buf[10];
-
-    vim_strncpy(buf, op, len);
-    semsg(_(e_white_space_required_before_and_after_str_at_str), buf, op);
-}
-
-/*
- * <type>expr7: runtime type check / conversion
- */
-    static int
-compile_expr7t(char_u **arg, cctx_T *cctx, ppconst_T *ppconst)
-{
-    type_T *want_type = NULL;
-
-    // Recognize <type>
-    if (**arg == '<' && eval_isnamec1((*arg)[1]))
-    {
-	++*arg;
-	want_type = parse_type(arg, cctx->ctx_type_list, TRUE);
-	if (want_type == NULL)
-	    return FAIL;
-
-	if (**arg != '>')
-	{
-	    if (*skipwhite(*arg) == '>')
-		semsg(_(e_no_white_space_allowed_before_str_str), ">", *arg);
-	    else
-		emsg(_(e_missing_gt));
-	    return FAIL;
-	}
-	++*arg;
-	if (may_get_next_line_error(*arg, arg, cctx) == FAIL)
-	    return FAIL;
-    }
-
-    if (compile_expr7(arg, cctx, ppconst) == FAIL)
-	return FAIL;
-
-    if (want_type != NULL)
-    {
-	garray_T    *stack = &cctx->ctx_type_stack;
-	type_T	    *actual;
-	where_T	    where = WHERE_INIT;
-
-	generate_ppconst(cctx, ppconst);
-	actual = ((type_T **)stack->ga_data)[stack->ga_len - 1];
-	if (check_type(want_type, actual, FALSE, where) == FAIL)
-	{
-	    if (need_type(actual, want_type, -1, 0, cctx, FALSE, FALSE) == FAIL)
-		return FAIL;
-	}
-    }
-
-    return OK;
-}
-
-/*
- *	*	number multiplication
- *	/	number division
- *	%	number modulo
- */
-    static int
-compile_expr6(char_u **arg, cctx_T *cctx, ppconst_T *ppconst)
-{
-    char_u	*op;
-    char_u	*next;
-    int		ppconst_used = ppconst->pp_used;
-
-    // get the first expression
-    if (compile_expr7t(arg, cctx, ppconst) == FAIL)
-	return FAIL;
-
-    /*
-     * Repeat computing, until no "*", "/" or "%" is following.
-     */
-    for (;;)
-    {
-	op = may_peek_next_line(cctx, *arg, &next);
-	if (*op != '*' && *op != '/' && *op != '%')
-	    break;
-	if (next != NULL)
-	{
-	    *arg = next_line_from_context(cctx, TRUE);
-	    op = skipwhite(*arg);
-	}
-
-	if (!IS_WHITE_OR_NUL(**arg) || !IS_WHITE_OR_NUL(op[1]))
-	{
-	    error_white_both(op, 1);
-	    return FAIL;
-	}
-	if (may_get_next_line_error(op + 1, arg, cctx) == FAIL)
-	    return FAIL;
-
-	// get the second expression
-	if (compile_expr7t(arg, cctx, ppconst) == FAIL)
-	    return FAIL;
-
-	if (ppconst->pp_used == ppconst_used + 2
-		&& ppconst->pp_tv[ppconst_used].v_type == VAR_NUMBER
-		&& ppconst->pp_tv[ppconst_used + 1].v_type == VAR_NUMBER)
-	{
-	    typval_T	    *tv1 = &ppconst->pp_tv[ppconst_used];
-	    typval_T	    *tv2 = &ppconst->pp_tv[ppconst_used + 1];
-	    varnumber_T	    res = 0;
-	    int		    failed = FALSE;
-
-	    // both are numbers: compute the result
-	    switch (*op)
-	    {
-		case '*': res = tv1->vval.v_number * tv2->vval.v_number;
-			  break;
-		case '/': res = num_divide(tv1->vval.v_number,
-						  tv2->vval.v_number, &failed);
-			  break;
-		case '%': res = num_modulus(tv1->vval.v_number,
-						  tv2->vval.v_number, &failed);
-			  break;
-	    }
-	    if (failed)
-		return FAIL;
-	    tv1->vval.v_number = res;
-	    --ppconst->pp_used;
-	}
-	else
-	{
-	    generate_ppconst(cctx, ppconst);
-	    generate_two_op(cctx, op);
-	}
-    }
-
-    return OK;
-}
-
-/*
- *      +	number addition or list/blobl concatenation
- *      -	number subtraction
- *      ..	string concatenation
- */
-    static int
-compile_expr5(char_u **arg, cctx_T *cctx, ppconst_T *ppconst)
-{
-    char_u	*op;
-    char_u	*next;
-    int		oplen;
-    int		ppconst_used = ppconst->pp_used;
-
-    // get the first variable
-    if (compile_expr6(arg, cctx, ppconst) == FAIL)
-	return FAIL;
-
-    /*
-     * Repeat computing, until no "+", "-" or ".." is following.
-     */
-    for (;;)
-    {
-	op = may_peek_next_line(cctx, *arg, &next);
-	if (*op != '+' && *op != '-' && !(*op == '.' && *(op + 1) == '.'))
-	    break;
-	if (op[0] == op[1] && *op != '.' && next)
-	    // Finding "++" or "--" on the next line is a separate command.
-	    // But ".." is concatenation.
-	    break;
-	oplen = (*op == '.' ? 2 : 1);
-	if (next != NULL)
-	{
-	    *arg = next_line_from_context(cctx, TRUE);
-	    op = skipwhite(*arg);
-	}
-
-	if (!IS_WHITE_OR_NUL(**arg) || !IS_WHITE_OR_NUL(op[oplen]))
-	{
-	    error_white_both(op, oplen);
-	    return FAIL;
-	}
-
-	if (may_get_next_line_error(op + oplen, arg, cctx) == FAIL)
-	    return FAIL;
-
-	// get the second expression
-	if (compile_expr6(arg, cctx, ppconst) == FAIL)
-	    return FAIL;
-
-	if (ppconst->pp_used == ppconst_used + 2
-		&& (*op == '.'
-		    ? (ppconst->pp_tv[ppconst_used].v_type == VAR_STRING
-		    && ppconst->pp_tv[ppconst_used + 1].v_type == VAR_STRING)
-		    : (ppconst->pp_tv[ppconst_used].v_type == VAR_NUMBER
-		    && ppconst->pp_tv[ppconst_used + 1].v_type == VAR_NUMBER)))
-	{
-	    typval_T *tv1 = &ppconst->pp_tv[ppconst_used];
-	    typval_T *tv2 = &ppconst->pp_tv[ppconst_used + 1];
-
-	    // concat/subtract/add constant numbers
-	    if (*op == '+')
-		tv1->vval.v_number = tv1->vval.v_number + tv2->vval.v_number;
-	    else if (*op == '-')
-		tv1->vval.v_number = tv1->vval.v_number - tv2->vval.v_number;
-	    else
-	    {
-		// concatenate constant strings
-		char_u *s1 = tv1->vval.v_string;
-		char_u *s2 = tv2->vval.v_string;
-		size_t len1 = STRLEN(s1);
-
-		tv1->vval.v_string = alloc((int)(len1 + STRLEN(s2) + 1));
-		if (tv1->vval.v_string == NULL)
-		{
-		    clear_ppconst(ppconst);
-		    return FAIL;
-		}
-		mch_memmove(tv1->vval.v_string, s1, len1);
-		STRCPY(tv1->vval.v_string + len1, s2);
-		vim_free(s1);
-		vim_free(s2);
-	    }
-	    --ppconst->pp_used;
-	}
-	else
-	{
-	    generate_ppconst(cctx, ppconst);
-	    ppconst->pp_is_const = FALSE;
-	    if (*op == '.')
-	    {
-		if (may_generate_2STRING(-2, FALSE, cctx) == FAIL
-			|| may_generate_2STRING(-1, FALSE, cctx) == FAIL)
-		    return FAIL;
-		generate_instr_drop(cctx, ISN_CONCAT, 1);
-	    }
-	    else
-		generate_two_op(cctx, op);
-	}
-    }
-
-    return OK;
-}
-
-/*
- * expr5a == expr5b
- * expr5a =~ expr5b
- * expr5a != expr5b
- * expr5a !~ expr5b
- * expr5a > expr5b
- * expr5a >= expr5b
- * expr5a < expr5b
- * expr5a <= expr5b
- * expr5a is expr5b
- * expr5a isnot expr5b
- *
- * Produces instructions:
- *	EVAL expr5a		Push result of "expr5a"
- *	EVAL expr5b		Push result of "expr5b"
- *	COMPARE			one of the compare instructions
- */
-    static int
-compile_expr4(char_u **arg, cctx_T *cctx, ppconst_T *ppconst)
-{
-    exprtype_T	type = EXPR_UNKNOWN;
-    char_u	*p;
-    char_u	*next;
-    int		len = 2;
-    int		type_is = FALSE;
-    int		ppconst_used = ppconst->pp_used;
-
-    // get the first variable
-    if (compile_expr5(arg, cctx, ppconst) == FAIL)
-	return FAIL;
-
-    p = may_peek_next_line(cctx, *arg, &next);
-    type = get_compare_type(p, &len, &type_is);
-
-    /*
-     * If there is a comparative operator, use it.
-     */
-    if (type != EXPR_UNKNOWN)
-    {
-	int ic = FALSE;  // Default: do not ignore case
-
-	if (next != NULL)
-	{
-	    *arg = next_line_from_context(cctx, TRUE);
-	    p = skipwhite(*arg);
-	}
-	if (type_is && (p[len] == '?' || p[len] == '#'))
-	{
-	    semsg(_(e_invalid_expression_str), *arg);
-	    return FAIL;
-	}
-	// extra question mark appended: ignore case
-	if (p[len] == '?')
-	{
-	    ic = TRUE;
-	    ++len;
-	}
-	// extra '#' appended: match case (ignored)
-	else if (p[len] == '#')
-	    ++len;
-	// nothing appended: match case
-
-	if (!IS_WHITE_OR_NUL(**arg) || !IS_WHITE_OR_NUL(p[len]))
-	{
-	    error_white_both(p, len);
-	    return FAIL;
-	}
-
-	// get the second variable
-	if (may_get_next_line_error(p + len, arg, cctx) == FAIL)
-	    return FAIL;
-
-	if (compile_expr5(arg, cctx, ppconst) == FAIL)
-	    return FAIL;
-
-	if (ppconst->pp_used == ppconst_used + 2)
-	{
-	    typval_T *	tv1 = &ppconst->pp_tv[ppconst->pp_used - 2];
-	    typval_T	*tv2 = &ppconst->pp_tv[ppconst->pp_used - 1];
-	    int		ret;
-
-	    // Both sides are a constant, compute the result now.
-	    // First check for a valid combination of types, this is more
-	    // strict than typval_compare().
-	    if (check_compare_types(type, tv1, tv2) == FAIL)
-		ret = FAIL;
-	    else
-	    {
-		ret = typval_compare(tv1, tv2, type, ic);
-		tv1->v_type = VAR_BOOL;
-		tv1->vval.v_number = tv1->vval.v_number
-						      ? VVAL_TRUE : VVAL_FALSE;
-		clear_tv(tv2);
-		--ppconst->pp_used;
-	    }
-	    return ret;
-	}
-
-	generate_ppconst(cctx, ppconst);
-	return generate_COMPARE(cctx, type, ic);
-    }
-
-    return OK;
-}
-
-static int compile_expr3(char_u **arg,  cctx_T *cctx, ppconst_T *ppconst);
-
-/*
- * Compile || or &&.
- */
-    static int
-compile_and_or(
-	char_u **arg,
-	cctx_T	*cctx,
-	char	*op,
-	ppconst_T *ppconst,
-	int	ppconst_used UNUSED)
-{
-    char_u	*next;
-    char_u	*p = may_peek_next_line(cctx, *arg, &next);
-    int		opchar = *op;
-
-    if (p[0] == opchar && p[1] == opchar)
-    {
-	garray_T	*instr = &cctx->ctx_instr;
-	garray_T	end_ga;
-	int		save_skip = cctx->ctx_skip;
-
-	/*
-	 * Repeat until there is no following "||" or "&&"
-	 */
-	ga_init2(&end_ga, sizeof(int), 10);
-	while (p[0] == opchar && p[1] == opchar)
-	{
-	    long	start_lnum = SOURCING_LNUM;
-	    long	save_sourcing_lnum;
-	    int		start_ctx_lnum = cctx->ctx_lnum;
-	    int		save_lnum;
-	    int		const_used;
-	    int		status;
-	    jumpwhen_T	jump_when = opchar == '|'
-				      ? JUMP_IF_COND_TRUE : JUMP_IF_COND_FALSE;
-
-	    if (next != NULL)
-	    {
-		*arg = next_line_from_context(cctx, TRUE);
-		p = skipwhite(*arg);
-	    }
-
-	    if (!IS_WHITE_OR_NUL(**arg) || !IS_WHITE_OR_NUL(p[2]))
-	    {
-		semsg(_(e_white_space_required_before_and_after_str_at_str),
-									op, p);
-		ga_clear(&end_ga);
-		return FAIL;
-	    }
-
-	    save_sourcing_lnum = SOURCING_LNUM;
-	    SOURCING_LNUM = start_lnum;
-	    save_lnum = cctx->ctx_lnum;
-	    cctx->ctx_lnum = start_ctx_lnum;
-
-	    status = check_ppconst_bool(ppconst);
-	    if (status != FAIL)
-	    {
-		// Use the last ppconst if possible.
-		if (ppconst->pp_used > 0)
-		{
-		    typval_T	*tv = &ppconst->pp_tv[ppconst->pp_used - 1];
-		    int		is_true = tv2bool(tv);
-
-		    if ((is_true && opchar == '|')
-						|| (!is_true && opchar == '&'))
-		    {
-			// For "false && expr" and "true || expr" the "expr"
-			// does not need to be evaluated.
-			cctx->ctx_skip = SKIP_YES;
-			clear_tv(tv);
-			tv->v_type = VAR_BOOL;
-			tv->vval.v_number = is_true ? VVAL_TRUE : VVAL_FALSE;
-		    }
-		    else
-		    {
-			// For "true && expr" and "false || expr" only "expr"
-			// needs to be evaluated.
-			--ppconst->pp_used;
-			jump_when = JUMP_NEVER;
-		    }
-		}
-		else
-		{
-		    // Every part must evaluate to a bool.
-		    status = bool_on_stack(cctx);
-		}
-	    }
-	    if (status != FAIL)
-		status = ga_grow(&end_ga, 1);
-	    cctx->ctx_lnum = save_lnum;
-	    if (status == FAIL)
-	    {
-		ga_clear(&end_ga);
-		return FAIL;
-	    }
-
-	    if (jump_when != JUMP_NEVER)
-	    {
-		if (cctx->ctx_skip != SKIP_YES)
-		{
-		    *(((int *)end_ga.ga_data) + end_ga.ga_len) = instr->ga_len;
-		    ++end_ga.ga_len;
-		}
-		generate_JUMP(cctx, jump_when, 0);
-	    }
-
-	    // eval the next expression
-	    SOURCING_LNUM = save_sourcing_lnum;
-	    if (may_get_next_line_error(p + 2, arg, cctx) == FAIL)
-	    {
-		ga_clear(&end_ga);
-		return FAIL;
-	    }
-
-	    const_used = ppconst->pp_used;
-	    if ((opchar == '|' ? compile_expr3(arg, cctx, ppconst)
-				  : compile_expr4(arg, cctx, ppconst)) == FAIL)
-	    {
-		ga_clear(&end_ga);
-		return FAIL;
-	    }
-
-	    // "0 || 1" results in true, "1 && 0" results in false.
-	    if (ppconst->pp_used == const_used + 1)
-	    {
-		typval_T	*tv = &ppconst->pp_tv[ppconst->pp_used - 1];
-
-		if (tv->v_type == VAR_NUMBER
-			 && (tv->vval.v_number == 1 || tv->vval.v_number == 0))
-		{
-		    tv->vval.v_number = tv->vval.v_number == 1
-						      ? VVAL_TRUE : VVAL_FALSE;
-		    tv->v_type = VAR_BOOL;
-		}
-	    }
-
-	    p = may_peek_next_line(cctx, *arg, &next);
-	}
-
-	if (check_ppconst_bool(ppconst) == FAIL)
-	{
-	    ga_clear(&end_ga);
-	    return FAIL;
-	}
-
-	if (cctx->ctx_skip != SKIP_YES && ppconst->pp_used == 0)
-	    // Every part must evaluate to a bool.
-	    if (bool_on_stack(cctx) == FAIL)
-	    {
-		ga_clear(&end_ga);
-		return FAIL;
-	    }
-
-	if (end_ga.ga_len > 0)
-	{
-	    // Fill in the end label in all jumps.
-	    generate_ppconst(cctx, ppconst);
-	    while (end_ga.ga_len > 0)
-	    {
-		isn_T	*isn;
-
-		--end_ga.ga_len;
-		isn = ((isn_T *)instr->ga_data)
-				  + *(((int *)end_ga.ga_data) + end_ga.ga_len);
-		isn->isn_arg.jump.jump_where = instr->ga_len;
-	    }
-	}
-	ga_clear(&end_ga);
-
-	cctx->ctx_skip = save_skip;
-    }
-
-    return OK;
-}
-
-/*
- * expr4a && expr4a && expr4a	    logical AND
- *
- * Produces instructions:
- *	EVAL expr4a		Push result of "expr4a"
- *	COND2BOOL		convert to bool if needed
- *	JUMP_IF_COND_FALSE end
- *	EVAL expr4b		Push result of "expr4b"
- *	JUMP_IF_COND_FALSE end
- *	EVAL expr4c		Push result of "expr4c"
- * end:
- */
-    static int
-compile_expr3(char_u **arg, cctx_T *cctx, ppconst_T *ppconst)
-{
-    int		ppconst_used = ppconst->pp_used;
-
-    // get the first variable
-    if (compile_expr4(arg, cctx, ppconst) == FAIL)
-	return FAIL;
-
-    // || and && work almost the same
-    return compile_and_or(arg, cctx, "&&", ppconst, ppconst_used);
-}
-
-/*
- * expr3a || expr3b || expr3c	    logical OR
- *
- * Produces instructions:
- *	EVAL expr3a		Push result of "expr3a"
- *	COND2BOOL		convert to bool if needed
- *	JUMP_IF_COND_TRUE end
- *	EVAL expr3b		Push result of "expr3b"
- *	JUMP_IF_COND_TRUE end
- *	EVAL expr3c		Push result of "expr3c"
- * end:
- */
-    static int
-compile_expr2(char_u **arg, cctx_T *cctx, ppconst_T *ppconst)
-{
-    int		ppconst_used = ppconst->pp_used;
-
-    // eval the first expression
-    if (compile_expr3(arg, cctx, ppconst) == FAIL)
-	return FAIL;
-
-    // || and && work almost the same
-    return compile_and_or(arg, cctx, "||", ppconst, ppconst_used);
-}
-
-/*
- * Toplevel expression: expr2 ? expr1a : expr1b
- * Produces instructions:
- *	EVAL expr2		Push result of "expr2"
- *      JUMP_IF_FALSE alt	jump if false
- *      EVAL expr1a
- *      JUMP_ALWAYS end
- * alt:	EVAL expr1b
- * end:
- *
- * Toplevel expression: expr2 ?? expr1
- * Produces instructions:
- *	EVAL expr2		    Push result of "expr2"
- *      JUMP_AND_KEEP_IF_TRUE end   jump if true
- *      EVAL expr1
- * end:
- */
-    static int
-compile_expr1(char_u **arg, cctx_T *cctx, ppconst_T *ppconst)
-{
-    char_u	*p;
-    int		ppconst_used = ppconst->pp_used;
-    char_u	*next;
-
-    // Ignore all kinds of errors when not producing code.
-    if (cctx->ctx_skip == SKIP_YES)
-    {
-	skip_expr_cctx(arg, cctx);
-	return OK;
-    }
-
-    // Evaluate the first expression.
-    if (compile_expr2(arg, cctx, ppconst) == FAIL)
-	return FAIL;
-
-    p = may_peek_next_line(cctx, *arg, &next);
-    if (*p == '?')
-    {
-	int		op_falsy = p[1] == '?';
-	garray_T	*instr = &cctx->ctx_instr;
-	garray_T	*stack = &cctx->ctx_type_stack;
-	int		alt_idx = instr->ga_len;
-	int		end_idx = 0;
-	isn_T		*isn;
-	type_T		*type1 = NULL;
-	int		has_const_expr = FALSE;
-	int		const_value = FALSE;
-	int		save_skip = cctx->ctx_skip;
-
-	if (next != NULL)
-	{
-	    *arg = next_line_from_context(cctx, TRUE);
-	    p = skipwhite(*arg);
-	}
-
-	if (!IS_WHITE_OR_NUL(**arg) || !IS_WHITE_OR_NUL(p[1 + op_falsy]))
-	{
-	    semsg(_(e_white_space_required_before_and_after_str_at_str),
-						     op_falsy ? "??" : "?", p);
-	    return FAIL;
-	}
-
-	if (ppconst->pp_used == ppconst_used + 1)
-	{
-	    // the condition is a constant, we know whether the ? or the :
-	    // expression is to be evaluated.
-	    has_const_expr = TRUE;
-	    if (op_falsy)
-		const_value = tv2bool(&ppconst->pp_tv[ppconst_used]);
-	    else
-	    {
-		int error = FALSE;
-
-		const_value = tv_get_bool_chk(&ppconst->pp_tv[ppconst_used],
-								       &error);
-		if (error)
-		    return FAIL;
-	    }
-	    cctx->ctx_skip = save_skip == SKIP_YES ||
-		 (op_falsy ? const_value : !const_value) ? SKIP_YES : SKIP_NOT;
-
-	    if (op_falsy && cctx->ctx_skip == SKIP_YES)
-		// "left ?? right" and "left" is truthy: produce "left"
-		generate_ppconst(cctx, ppconst);
-	    else
-	    {
-		clear_tv(&ppconst->pp_tv[ppconst_used]);
-		--ppconst->pp_used;
-	    }
-	}
-	else
-	{
-	    generate_ppconst(cctx, ppconst);
-	    if (op_falsy)
-		end_idx = instr->ga_len;
-	    generate_JUMP(cctx, op_falsy
-				   ? JUMP_AND_KEEP_IF_TRUE : JUMP_IF_FALSE, 0);
-	    if (op_falsy)
-		type1 = ((type_T **)stack->ga_data)[stack->ga_len];
-	}
-
-	// evaluate the second expression; any type is accepted
-	if (may_get_next_line_error(p + 1 + op_falsy, arg, cctx) == FAIL)
-	    return FAIL;
-	if (compile_expr1(arg, cctx, ppconst) == FAIL)
-	    return FAIL;
-
-	if (!has_const_expr)
-	{
-	    generate_ppconst(cctx, ppconst);
-
-	    if (!op_falsy)
-	    {
-		// remember the type and drop it
-		--stack->ga_len;
-		type1 = ((type_T **)stack->ga_data)[stack->ga_len];
-
-		end_idx = instr->ga_len;
-		generate_JUMP(cctx, JUMP_ALWAYS, 0);
-
-		// jump here from JUMP_IF_FALSE
-		isn = ((isn_T *)instr->ga_data) + alt_idx;
-		isn->isn_arg.jump.jump_where = instr->ga_len;
-	    }
-	}
-
-	if (!op_falsy)
-	{
-	    // Check for the ":".
-	    p = may_peek_next_line(cctx, *arg, &next);
-	    if (*p != ':')
-	    {
-		emsg(_(e_missing_colon_after_questionmark));
-		return FAIL;
-	    }
-	    if (next != NULL)
-	    {
-		*arg = next_line_from_context(cctx, TRUE);
-		p = skipwhite(*arg);
-	    }
-
-	    if (!IS_WHITE_OR_NUL(**arg) || !IS_WHITE_OR_NUL(p[1]))
-	    {
-		semsg(_(e_white_space_required_before_and_after_str_at_str),
-								       ":", p);
-		return FAIL;
-	    }
-
-	    // evaluate the third expression
-	    if (has_const_expr)
-		cctx->ctx_skip = save_skip == SKIP_YES || const_value
-							 ? SKIP_YES : SKIP_NOT;
-	    if (may_get_next_line_error(p + 1, arg, cctx) == FAIL)
-		return FAIL;
-	    if (compile_expr1(arg, cctx, ppconst) == FAIL)
-		return FAIL;
-	}
-
-	if (!has_const_expr)
-	{
-	    type_T	**typep;
-
-	    generate_ppconst(cctx, ppconst);
-
-	    // If the types differ, the result has a more generic type.
-	    typep = ((type_T **)stack->ga_data) + stack->ga_len - 1;
-	    common_type(type1, *typep, typep, cctx->ctx_type_list);
-
-	    // jump here from JUMP_ALWAYS or JUMP_AND_KEEP_IF_TRUE
-	    isn = ((isn_T *)instr->ga_data) + end_idx;
-	    isn->isn_arg.jump.jump_where = instr->ga_len;
-	}
-
-	cctx->ctx_skip = save_skip;
-    }
-    return OK;
-}
-
-/*
- * Toplevel expression.
- * Sets "is_const" (if not NULL) to indicate the value is a constant.
- * Returns OK or FAIL.
- */
-    static int
-compile_expr0_ext(char_u **arg,  cctx_T *cctx, int *is_const)
-{
-    ppconst_T	ppconst;
-
-    CLEAR_FIELD(ppconst);
-    if (compile_expr1(arg, cctx, &ppconst) == FAIL)
-    {
-	clear_ppconst(&ppconst);
-	return FAIL;
-    }
-    if (is_const != NULL)
-	*is_const = ppconst.pp_used > 0 || ppconst.pp_is_const;
-    if (generate_ppconst(cctx, &ppconst) == FAIL)
-	return FAIL;
-    return OK;
-}
-
-/*
- * Toplevel expression.
- */
-    static int
-compile_expr0(char_u **arg,  cctx_T *cctx)
-{
-    return compile_expr0_ext(arg, cctx, NULL);
-}
-
-/*
- * Compile "return [expr]".
- * When "legacy" is TRUE evaluate [expr] with legacy syntax
- */
-    static char_u *
-compile_return(char_u *arg, int check_return_type, int legacy, cctx_T *cctx)
-{
-    char_u	*p = arg;
-    garray_T	*stack = &cctx->ctx_type_stack;
-    type_T	*stack_type;
-
-    if (*p != NUL && *p != '|' && *p != '\n')
-    {
-	if (legacy)
-	{
-	    int save_flags = cmdmod.cmod_flags;
-
-	    generate_LEGACY_EVAL(cctx, p);
-	    if (need_type(&t_any, cctx->ctx_ufunc->uf_ret_type, -1,
-						0, cctx, FALSE, FALSE) == FAIL)
-		return NULL;
-	    cmdmod.cmod_flags |= CMOD_LEGACY;
-	    (void)skip_expr(&p, NULL);
-	    cmdmod.cmod_flags = save_flags;
-	}
-	else
-	{
-	    // compile return argument into instructions
-	    if (compile_expr0(&p, cctx) == FAIL)
-		return NULL;
-	}
-
-	if (cctx->ctx_skip != SKIP_YES)
-	{
-	    // "check_return_type" with uf_ret_type set to &t_unknown is used
-	    // for an inline function without a specified return type.  Set the
-	    // return type here.
-	    stack_type = ((type_T **)stack->ga_data)[stack->ga_len - 1];
-	    if ((check_return_type && (cctx->ctx_ufunc->uf_ret_type == NULL
-				|| cctx->ctx_ufunc->uf_ret_type == &t_unknown
-				|| cctx->ctx_ufunc->uf_ret_type == &t_any))
-		    || (!check_return_type
-				&& cctx->ctx_ufunc->uf_ret_type == &t_unknown))
-	    {
-		cctx->ctx_ufunc->uf_ret_type = stack_type;
-	    }
-	    else
-	    {
-		if (cctx->ctx_ufunc->uf_ret_type->tt_type == VAR_VOID
-			&& stack_type->tt_type != VAR_VOID
-			&& stack_type->tt_type != VAR_UNKNOWN)
-		{
-		    emsg(_(e_returning_value_in_function_without_return_type));
-		    return NULL;
-		}
-		if (need_type(stack_type, cctx->ctx_ufunc->uf_ret_type, -1,
-						0, cctx, FALSE, FALSE) == FAIL)
-		    return NULL;
-	    }
-	}
-    }
-    else
-    {
-	// "check_return_type" cannot be TRUE, only used for a lambda which
-	// always has an argument.
-	if (cctx->ctx_ufunc->uf_ret_type->tt_type != VAR_VOID
-		&& cctx->ctx_ufunc->uf_ret_type->tt_type != VAR_UNKNOWN)
-	{
-	    emsg(_(e_missing_return_value));
-	    return NULL;
-	}
-
-	// No argument, return zero.
-	generate_PUSHNR(cctx, 0);
-    }
-
-    // Undo any command modifiers.
-    generate_undo_cmdmods(cctx);
-
-    if (cctx->ctx_skip != SKIP_YES && generate_instr(cctx, ISN_RETURN) == NULL)
-	return NULL;
-
-    // "return val | endif" is possible
-    return skipwhite(p);
-}
-
 /*
  * Get a line from the compilation context, compatible with exarg_T getline().
  * Return a pointer to the line in allocated memory.
@@ -5859,6 +769,44 @@
 }
 
 /*
+ * Return TRUE if "ufunc" should be compiled, taking into account whether
+ * "profile" indicates profiling is to be done.
+ */
+    int
+func_needs_compiling(ufunc_T *ufunc, compiletype_T compile_type)
+{
+    switch (ufunc->uf_def_status)
+    {
+	case UF_TO_BE_COMPILED:
+	    return TRUE;
+
+	case UF_COMPILED:
+	{
+	    dfunc_T *dfunc = ((dfunc_T *)def_functions.ga_data)
+							 + ufunc->uf_dfunc_idx;
+
+	    switch (compile_type)
+	    {
+		case CT_PROFILE:
+#ifdef FEAT_PROFILE
+		    return dfunc->df_instr_prof == NULL;
+#endif
+		case CT_NONE:
+		    return dfunc->df_instr == NULL;
+		case CT_DEBUG:
+		    return dfunc->df_instr_debug == NULL;
+	    }
+	}
+
+	case UF_NOT_COMPILED:
+	case UF_COMPILE_ERROR:
+	case UF_COMPILING:
+	    break;
+    }
+    return FALSE;
+}
+
+/*
  * Compile a nested :def command.
  */
     static char_u *
@@ -6124,7 +1072,7 @@
  * "type" is set to the destination type if known, unchanted otherwise.
  * Return FAIL if an error message was given.
  */
-    static int
+    int
 get_var_dest(
 	char_u		*name,
 	assign_dest_T	*dest,
@@ -6243,102 +1191,6 @@
     return OK;
 }
 
-/*
- * Generate a STORE instruction for "dest", not being "dest_local".
- * Return FAIL when out of memory.
- */
-    static int
-generate_store_var(
-	cctx_T		*cctx,
-	assign_dest_T	dest,
-	int		opt_flags,
-	int		vimvaridx,
-	int		scriptvar_idx,
-	int		scriptvar_sid,
-	type_T		*type,
-	char_u		*name)
-{
-    switch (dest)
-    {
-	case dest_option:
-	    return generate_STOREOPT(cctx, ISN_STOREOPT,
-					skip_option_env_lead(name), opt_flags);
-	case dest_func_option:
-	    return generate_STOREOPT(cctx, ISN_STOREFUNCOPT,
-					skip_option_env_lead(name), opt_flags);
-	case dest_global:
-	    // include g: with the name, easier to execute that way
-	    return generate_STORE(cctx, vim_strchr(name, AUTOLOAD_CHAR) == NULL
-					? ISN_STOREG : ISN_STOREAUTO, 0, name);
-	case dest_buffer:
-	    // include b: with the name, easier to execute that way
-	    return generate_STORE(cctx, ISN_STOREB, 0, name);
-	case dest_window:
-	    // include w: with the name, easier to execute that way
-	    return generate_STORE(cctx, ISN_STOREW, 0, name);
-	case dest_tab:
-	    // include t: with the name, easier to execute that way
-	    return generate_STORE(cctx, ISN_STORET, 0, name);
-	case dest_env:
-	    return generate_STORE(cctx, ISN_STOREENV, 0, name + 1);
-	case dest_reg:
-	    return generate_STORE(cctx, ISN_STOREREG,
-					 name[1] == '@' ? '"' : name[1], NULL);
-	case dest_vimvar:
-	    return generate_STORE(cctx, ISN_STOREV, vimvaridx, NULL);
-	case dest_script:
-	    if (scriptvar_idx < 0)
-		// "s:" may be included in the name.
-		return generate_OLDSCRIPT(cctx, ISN_STORES, name,
-							  scriptvar_sid, type);
-	    return generate_VIM9SCRIPT(cctx, ISN_STORESCRIPT,
-					   scriptvar_sid, scriptvar_idx, type);
-	case dest_local:
-	case dest_expr:
-	    // cannot happen
-	    break;
-    }
-    return FAIL;
-}
-
-    static int
-generate_store_lhs(cctx_T *cctx, lhs_T *lhs, int instr_count)
-{
-    if (lhs->lhs_dest != dest_local)
-	return generate_store_var(cctx, lhs->lhs_dest,
-			    lhs->lhs_opt_flags, lhs->lhs_vimvaridx,
-			    lhs->lhs_scriptvar_idx, lhs->lhs_scriptvar_sid,
-			    lhs->lhs_type, lhs->lhs_name);
-
-    if (lhs->lhs_lvar != NULL)
-    {
-	garray_T	*instr = &cctx->ctx_instr;
-	isn_T		*isn = ((isn_T *)instr->ga_data) + instr->ga_len - 1;
-
-	// optimization: turn "var = 123" from ISN_PUSHNR + ISN_STORE into
-	// ISN_STORENR
-	if (lhs->lhs_lvar->lv_from_outer == 0
-		&& instr->ga_len == instr_count + 1
-		&& isn->isn_type == ISN_PUSHNR)
-	{
-	    varnumber_T val = isn->isn_arg.number;
-	    garray_T    *stack = &cctx->ctx_type_stack;
-
-	    isn->isn_type = ISN_STORENR;
-	    isn->isn_arg.storenr.stnr_idx = lhs->lhs_lvar->lv_idx;
-	    isn->isn_arg.storenr.stnr_val = val;
-	    if (stack->ga_len > 0)
-		--stack->ga_len;
-	}
-	else if (lhs->lhs_lvar->lv_from_outer > 0)
-	    generate_STOREOUTER(cctx, lhs->lhs_lvar->lv_idx,
-						 lhs->lhs_lvar->lv_from_outer);
-	else
-	    generate_STORE(cctx, ISN_STORE, lhs->lhs_lvar->lv_idx, NULL);
-    }
-    return OK;
-}
-
     static int
 is_decl_command(int cmdidx)
 {
@@ -6351,7 +1203,7 @@
  * of ":unlet" with an index.
  * Returns OK or FAIL.
  */
-    static int
+    int
 compile_lhs(
 	char_u	*var_start,
 	lhs_T	*lhs,
@@ -6637,7 +1489,7 @@
 /*
  * Figure out the LHS and check a few errors.
  */
-    static int
+    int
 compile_assign_lhs(
 	char_u	*var_start,
 	lhs_T	*lhs,
@@ -6809,7 +1661,7 @@
  * Produce code for loading "lhs" and also take care of an index.
  * Return OK/FAIL.
  */
-    static int
+    int
 compile_load_lhs_with_index(lhs_T *lhs, char_u *var_start, cctx_T *cctx)
 {
     compile_load_lhs(lhs, var_start, NULL, cctx);
@@ -6841,7 +1693,7 @@
  * information in "lhs".
  * Returns OK or FAIL.
  */
-    static int
+    int
 compile_assign_unlet(
 	char_u	*var_start,
 	lhs_T	*lhs,
@@ -7519,2089 +2371,6 @@
     return NOTDONE;
 }
 
-/*
- * Check if "name" can be "unlet".
- */
-    int
-check_vim9_unlet(char_u *name)
-{
-    if (name[1] != ':' || vim_strchr((char_u *)"gwtb", *name) == NULL)
-    {
-	// "unlet s:var" is allowed in legacy script.
-	if (*name == 's' && !script_is_vim9())
-	    return OK;
-	semsg(_(e_cannot_unlet_str), name);
-	return FAIL;
-    }
-    return OK;
-}
-
-/*
- * Callback passed to ex_unletlock().
- */
-    static int
-compile_unlet(
-    lval_T  *lvp,
-    char_u  *name_end,
-    exarg_T *eap,
-    int	    deep UNUSED,
-    void    *coookie)
-{
-    cctx_T	*cctx = coookie;
-    char_u	*p = lvp->ll_name;
-    int		cc = *name_end;
-    int		ret = OK;
-
-    if (cctx->ctx_skip == SKIP_YES)
-	return OK;
-
-    *name_end = NUL;
-    if (*p == '$')
-    {
-	// :unlet $ENV_VAR
-	ret = generate_UNLET(cctx, ISN_UNLETENV, p + 1, eap->forceit);
-    }
-    else if (vim_strchr(p, '.') != NULL || vim_strchr(p, '[') != NULL)
-    {
-	lhs_T	    lhs;
-
-	// This is similar to assigning: lookup the list/dict, compile the
-	// idx/key.  Then instead of storing the value unlet the item.
-	// unlet {list}[idx]
-	// unlet {dict}[key]  dict.key
-	//
-	// Figure out the LHS type and other properties.
-	//
-	ret = compile_lhs(p, &lhs, CMD_unlet, FALSE, 0, cctx);
-
-	// : unlet an indexed item
-	if (!lhs.lhs_has_index)
-	{
-	    iemsg("called compile_lhs() without an index");
-	    ret = FAIL;
-	}
-	else
-	{
-	    // Use the info in "lhs" to unlet the item at the index in the
-	    // list or dict.
-	    ret = compile_assign_unlet(p, &lhs, FALSE, &t_void, cctx);
-	}
-
-	vim_free(lhs.lhs_name);
-    }
-    else if (check_vim9_unlet(p) == FAIL)
-    {
-	ret = FAIL;
-    }
-    else
-    {
-	// Normal name.  Only supports g:, w:, t: and b: namespaces.
-	ret = generate_UNLET(cctx, ISN_UNLET, p, eap->forceit);
-    }
-
-    *name_end = cc;
-    return ret;
-}
-
-/*
- * Callback passed to ex_unletlock().
- */
-    static int
-compile_lock_unlock(
-    lval_T  *lvp,
-    char_u  *name_end,
-    exarg_T *eap,
-    int	    deep UNUSED,
-    void    *coookie)
-{
-    cctx_T	*cctx = coookie;
-    int		cc = *name_end;
-    char_u	*p = lvp->ll_name;
-    int		ret = OK;
-    size_t	len;
-    char_u	*buf;
-    isntype_T	isn = ISN_EXEC;
-
-    if (cctx->ctx_skip == SKIP_YES)
-	return OK;
-
-    // Cannot use :lockvar and :unlockvar on local variables.
-    if (p[1] != ':')
-    {
-	char_u *end = find_name_end(p, NULL, NULL, FNE_CHECK_START);
-
-	if (lookup_local(p, end - p, NULL, cctx) == OK)
-	{
-	    char_u *s = p;
-
-	    if (*end != '.' && *end != '[')
-	    {
-		emsg(_(e_cannot_lock_unlock_local_variable));
-		return FAIL;
-	    }
-
-	    // For "d.member" put the local variable on the stack, it will be
-	    // passed to ex_lockvar() indirectly.
-	    if (compile_load(&s, end, cctx, FALSE, FALSE) == FAIL)
-		return FAIL;
-	    isn = ISN_LOCKUNLOCK;
-	}
-    }
-
-    // Checking is done at runtime.
-    *name_end = NUL;
-    len = name_end - p + 20;
-    buf = alloc(len);
-    if (buf == NULL)
-	ret = FAIL;
-    else
-    {
-	vim_snprintf((char *)buf, len, "%s %s",
-		eap->cmdidx == CMD_lockvar ? "lockvar" : "unlockvar",
-		p);
-	ret = generate_EXEC_copy(cctx, isn, buf);
-
-	vim_free(buf);
-	*name_end = cc;
-    }
-    return ret;
-}
-
-/*
- * compile "unlet var", "lock var" and "unlock var"
- * "arg" points to "var".
- */
-    static char_u *
-compile_unletlock(char_u *arg, exarg_T *eap, cctx_T *cctx)
-{
-    ex_unletlock(eap, arg, 0, GLV_NO_AUTOLOAD | GLV_COMPILING,
-	    eap->cmdidx == CMD_unlet ? compile_unlet : compile_lock_unlock,
-	    cctx);
-    return eap->nextcmd == NULL ? (char_u *)"" : eap->nextcmd;
-}
-
-/*
- * generate a jump to the ":endif"/":endfor"/":endwhile"/":finally"/":endtry".
- */
-    static int
-compile_jump_to_end(endlabel_T **el, jumpwhen_T when, cctx_T *cctx)
-{
-    garray_T	*instr = &cctx->ctx_instr;
-    endlabel_T  *endlabel = ALLOC_CLEAR_ONE(endlabel_T);
-
-    if (endlabel == NULL)
-	return FAIL;
-    endlabel->el_next = *el;
-    *el = endlabel;
-    endlabel->el_end_label = instr->ga_len;
-
-    generate_JUMP(cctx, when, 0);
-    return OK;
-}
-
-    static void
-compile_fill_jump_to_end(endlabel_T **el, int jump_where, cctx_T *cctx)
-{
-    garray_T	*instr = &cctx->ctx_instr;
-
-    while (*el != NULL)
-    {
-	endlabel_T  *cur = (*el);
-	isn_T	    *isn;
-
-	isn = ((isn_T *)instr->ga_data) + cur->el_end_label;
-	isn->isn_arg.jump.jump_where = jump_where;
-	*el = cur->el_next;
-	vim_free(cur);
-    }
-}
-
-    static void
-compile_free_jump_to_end(endlabel_T **el)
-{
-    while (*el != NULL)
-    {
-	endlabel_T  *cur = (*el);
-
-	*el = cur->el_next;
-	vim_free(cur);
-    }
-}
-
-/*
- * Create a new scope and set up the generic items.
- */
-    static scope_T *
-new_scope(cctx_T *cctx, scopetype_T type)
-{
-    scope_T *scope = ALLOC_CLEAR_ONE(scope_T);
-
-    if (scope == NULL)
-	return NULL;
-    scope->se_outer = cctx->ctx_scope;
-    cctx->ctx_scope = scope;
-    scope->se_type = type;
-    scope->se_local_count = cctx->ctx_locals.ga_len;
-    return scope;
-}
-
-/*
- * Free the current scope and go back to the outer scope.
- */
-    static void
-drop_scope(cctx_T *cctx)
-{
-    scope_T *scope = cctx->ctx_scope;
-
-    if (scope == NULL)
-    {
-	iemsg("calling drop_scope() without a scope");
-	return;
-    }
-    cctx->ctx_scope = scope->se_outer;
-    switch (scope->se_type)
-    {
-	case IF_SCOPE:
-	    compile_free_jump_to_end(&scope->se_u.se_if.is_end_label); break;
-	case FOR_SCOPE:
-	    compile_free_jump_to_end(&scope->se_u.se_for.fs_end_label); break;
-	case WHILE_SCOPE:
-	    compile_free_jump_to_end(&scope->se_u.se_while.ws_end_label); break;
-	case TRY_SCOPE:
-	    compile_free_jump_to_end(&scope->se_u.se_try.ts_end_label); break;
-	case NO_SCOPE:
-	case BLOCK_SCOPE:
-	    break;
-    }
-    vim_free(scope);
-}
-
-/*
- * compile "if expr"
- *
- * "if expr" Produces instructions:
- *	EVAL expr		Push result of "expr"
- *	JUMP_IF_FALSE end
- *	... body ...
- * end:
- *
- * "if expr | else" Produces instructions:
- *	EVAL expr		Push result of "expr"
- *	JUMP_IF_FALSE else
- *	... body ...
- *	JUMP_ALWAYS end
- * else:
- *	... body ...
- * end:
- *
- * "if expr1 | elseif expr2 | else" Produces instructions:
- *	EVAL expr		Push result of "expr"
- *	JUMP_IF_FALSE elseif
- *	... body ...
- *	JUMP_ALWAYS end
- * elseif:
- *	EVAL expr		Push result of "expr"
- *	JUMP_IF_FALSE else
- *	... body ...
- *	JUMP_ALWAYS end
- * else:
- *	... body ...
- * end:
- */
-    static char_u *
-compile_if(char_u *arg, cctx_T *cctx)
-{
-    char_u	*p = arg;
-    garray_T	*instr = &cctx->ctx_instr;
-    int		instr_count = instr->ga_len;
-    scope_T	*scope;
-    skip_T	skip_save = cctx->ctx_skip;
-    ppconst_T	ppconst;
-
-    CLEAR_FIELD(ppconst);
-    if (compile_expr1(&p, cctx, &ppconst) == FAIL)
-    {
-	clear_ppconst(&ppconst);
-	return NULL;
-    }
-    if (!ends_excmd2(arg, skipwhite(p)))
-    {
-	semsg(_(e_trailing_arg), p);
-	return NULL;
-    }
-    if (cctx->ctx_skip == SKIP_YES)
-	clear_ppconst(&ppconst);
-    else if (instr->ga_len == instr_count && ppconst.pp_used == 1)
-    {
-	int error = FALSE;
-	int v;
-
-	// The expression results in a constant.
-	v = tv_get_bool_chk(&ppconst.pp_tv[0], &error);
-	clear_ppconst(&ppconst);
-	if (error)
-	    return NULL;
-	cctx->ctx_skip = v ? SKIP_NOT : SKIP_YES;
-    }
-    else
-    {
-	// Not a constant, generate instructions for the expression.
-	cctx->ctx_skip = SKIP_UNKNOWN;
-	if (generate_ppconst(cctx, &ppconst) == FAIL)
-	    return NULL;
-	if (bool_on_stack(cctx) == FAIL)
-	    return NULL;
-    }
-
-    // CMDMOD_REV must come before the jump
-    generate_undo_cmdmods(cctx);
-
-    scope = new_scope(cctx, IF_SCOPE);
-    if (scope == NULL)
-	return NULL;
-    scope->se_skip_save = skip_save;
-    // "is_had_return" will be reset if any block does not end in :return
-    scope->se_u.se_if.is_had_return = TRUE;
-
-    if (cctx->ctx_skip == SKIP_UNKNOWN)
-    {
-	// "where" is set when ":elseif", "else" or ":endif" is found
-	scope->se_u.se_if.is_if_label = instr->ga_len;
-	generate_JUMP(cctx, JUMP_IF_FALSE, 0);
-    }
-    else
-	scope->se_u.se_if.is_if_label = -1;
-
-#ifdef FEAT_PROFILE
-    if (cctx->ctx_compile_type == CT_PROFILE && cctx->ctx_skip == SKIP_YES
-						      && skip_save != SKIP_YES)
-    {
-	// generated a profile start, need to generate a profile end, since it
-	// won't be done after returning
-	cctx->ctx_skip = SKIP_NOT;
-	generate_instr(cctx, ISN_PROF_END);
-	cctx->ctx_skip = SKIP_YES;
-    }
-#endif
-
-    return p;
-}
-
-    static char_u *
-compile_elseif(char_u *arg, cctx_T *cctx)
-{
-    char_u	*p = arg;
-    garray_T	*instr = &cctx->ctx_instr;
-    int		instr_count;
-    isn_T	*isn;
-    scope_T	*scope = cctx->ctx_scope;
-    ppconst_T	ppconst;
-    skip_T	save_skip = cctx->ctx_skip;
-
-    if (scope == NULL || scope->se_type != IF_SCOPE)
-    {
-	emsg(_(e_elseif_without_if));
-	return NULL;
-    }
-    unwind_locals(cctx, scope->se_local_count);
-    if (!cctx->ctx_had_return)
-	scope->se_u.se_if.is_had_return = FALSE;
-
-    if (cctx->ctx_skip == SKIP_NOT)
-    {
-	// previous block was executed, this one and following will not
-	cctx->ctx_skip = SKIP_YES;
-	scope->se_u.se_if.is_seen_skip_not = TRUE;
-    }
-    if (scope->se_u.se_if.is_seen_skip_not)
-    {
-	// A previous block was executed, skip over expression and bail out.
-	// Do not count the "elseif" for profiling and cmdmod
-	instr->ga_len = current_instr_idx(cctx);
-
-	skip_expr_cctx(&p, cctx);
-	return p;
-    }
-
-    if (cctx->ctx_skip == SKIP_UNKNOWN)
-    {
-	int	    moved_cmdmod = FALSE;
-	int	    saved_debug = FALSE;
-	isn_T	    debug_isn;
-
-	// Move any CMDMOD instruction to after the jump
-	if (((isn_T *)instr->ga_data)[instr->ga_len - 1].isn_type == ISN_CMDMOD)
-	{
-	    if (GA_GROW_FAILS(instr, 1))
-		return NULL;
-	    ((isn_T *)instr->ga_data)[instr->ga_len] =
-				  ((isn_T *)instr->ga_data)[instr->ga_len - 1];
-	    --instr->ga_len;
-	    moved_cmdmod = TRUE;
-	}
-
-	// Remove the already generated ISN_DEBUG, it is written below the
-	// ISN_FOR instruction.
-	if (cctx->ctx_compile_type == CT_DEBUG && instr->ga_len > 0
-		&& ((isn_T *)instr->ga_data)[instr->ga_len - 1]
-							.isn_type == ISN_DEBUG)
-	{
-	    --instr->ga_len;
-	    debug_isn = ((isn_T *)instr->ga_data)[instr->ga_len];
-	    saved_debug = TRUE;
-	}
-
-	if (compile_jump_to_end(&scope->se_u.se_if.is_end_label,
-						    JUMP_ALWAYS, cctx) == FAIL)
-	    return NULL;
-	// previous "if" or "elseif" jumps here
-	isn = ((isn_T *)instr->ga_data) + scope->se_u.se_if.is_if_label;
-	isn->isn_arg.jump.jump_where = instr->ga_len;
-
-	if (moved_cmdmod)
-	    ++instr->ga_len;
-
-	if (saved_debug)
-	{
-	    // move the debug instruction here
-	    if (GA_GROW_FAILS(instr, 1))
-		return NULL;
-	    ((isn_T *)instr->ga_data)[instr->ga_len] = debug_isn;
-	    ++instr->ga_len;
-	}
-    }
-
-    // compile "expr"; if we know it evaluates to FALSE skip the block
-    CLEAR_FIELD(ppconst);
-    if (cctx->ctx_skip == SKIP_YES)
-    {
-	cctx->ctx_skip = SKIP_UNKNOWN;
-#ifdef FEAT_PROFILE
-	if (cctx->ctx_compile_type == CT_PROFILE)
-	    // the previous block was skipped, need to profile this line
-	    generate_instr(cctx, ISN_PROF_START);
-#endif
-	if (cctx->ctx_compile_type == CT_DEBUG)
-	    // the previous block was skipped, may want to debug this line
-	    generate_instr_debug(cctx);
-    }
-
-    instr_count = instr->ga_len;
-    if (compile_expr1(&p, cctx, &ppconst) == FAIL)
-    {
-	clear_ppconst(&ppconst);
-	return NULL;
-    }
-    cctx->ctx_skip = save_skip;
-    if (!ends_excmd2(arg, skipwhite(p)))
-    {
-	clear_ppconst(&ppconst);
-	semsg(_(e_trailing_arg), p);
-	return NULL;
-    }
-    if (scope->se_skip_save == SKIP_YES)
-	clear_ppconst(&ppconst);
-    else if (instr->ga_len == instr_count && ppconst.pp_used == 1)
-    {
-	int error = FALSE;
-	int v;
-
-	// The expression result is a constant.
-	v = tv_get_bool_chk(&ppconst.pp_tv[0], &error);
-	if (error)
-	{
-	    clear_ppconst(&ppconst);
-	    return NULL;
-	}
-	cctx->ctx_skip = v ? SKIP_NOT : SKIP_YES;
-	clear_ppconst(&ppconst);
-	scope->se_u.se_if.is_if_label = -1;
-    }
-    else
-    {
-	// Not a constant, generate instructions for the expression.
-	cctx->ctx_skip = SKIP_UNKNOWN;
-	if (generate_ppconst(cctx, &ppconst) == FAIL)
-	    return NULL;
-	if (bool_on_stack(cctx) == FAIL)
-	    return NULL;
-
-	// CMDMOD_REV must come before the jump
-	generate_undo_cmdmods(cctx);
-
-	// "where" is set when ":elseif", "else" or ":endif" is found
-	scope->se_u.se_if.is_if_label = instr->ga_len;
-	generate_JUMP(cctx, JUMP_IF_FALSE, 0);
-    }
-
-    return p;
-}
-
-    static char_u *
-compile_else(char_u *arg, cctx_T *cctx)
-{
-    char_u	*p = arg;
-    garray_T	*instr = &cctx->ctx_instr;
-    isn_T	*isn;
-    scope_T	*scope = cctx->ctx_scope;
-
-    if (scope == NULL || scope->se_type != IF_SCOPE)
-    {
-	emsg(_(e_else_without_if));
-	return NULL;
-    }
-    unwind_locals(cctx, scope->se_local_count);
-    if (!cctx->ctx_had_return)
-	scope->se_u.se_if.is_had_return = FALSE;
-    scope->se_u.se_if.is_seen_else = TRUE;
-
-#ifdef FEAT_PROFILE
-    if (cctx->ctx_compile_type == CT_PROFILE)
-    {
-	if (cctx->ctx_skip == SKIP_NOT
-		&& ((isn_T *)instr->ga_data)[instr->ga_len - 1]
-						   .isn_type == ISN_PROF_START)
-	    // the previous block was executed, do not count "else" for
-	    // profiling
-	    --instr->ga_len;
-	if (cctx->ctx_skip == SKIP_YES && !scope->se_u.se_if.is_seen_skip_not)
-	{
-	    // the previous block was not executed, this one will, do count the
-	    // "else" for profiling
-	    cctx->ctx_skip = SKIP_NOT;
-	    generate_instr(cctx, ISN_PROF_END);
-	    generate_instr(cctx, ISN_PROF_START);
-	    cctx->ctx_skip = SKIP_YES;
-	}
-    }
-#endif
-
-    if (!scope->se_u.se_if.is_seen_skip_not && scope->se_skip_save != SKIP_YES)
-    {
-	// jump from previous block to the end, unless the else block is empty
-	if (cctx->ctx_skip == SKIP_UNKNOWN)
-	{
-	    if (!cctx->ctx_had_return
-		    && compile_jump_to_end(&scope->se_u.se_if.is_end_label,
-						    JUMP_ALWAYS, cctx) == FAIL)
-		return NULL;
-	}
-
-	if (cctx->ctx_skip == SKIP_UNKNOWN)
-	{
-	    if (scope->se_u.se_if.is_if_label >= 0)
-	    {
-		// previous "if" or "elseif" jumps here
-		isn = ((isn_T *)instr->ga_data) + scope->se_u.se_if.is_if_label;
-		isn->isn_arg.jump.jump_where = instr->ga_len;
-		scope->se_u.se_if.is_if_label = -1;
-	    }
-	}
-
-	if (cctx->ctx_skip != SKIP_UNKNOWN)
-	    cctx->ctx_skip = cctx->ctx_skip == SKIP_YES ? SKIP_NOT : SKIP_YES;
-    }
-
-    return p;
-}
-
-    static char_u *
-compile_endif(char_u *arg, cctx_T *cctx)
-{
-    scope_T	*scope = cctx->ctx_scope;
-    ifscope_T	*ifscope;
-    garray_T	*instr = &cctx->ctx_instr;
-    isn_T	*isn;
-
-    if (misplaced_cmdmod(cctx))
-	return NULL;
-
-    if (scope == NULL || scope->se_type != IF_SCOPE)
-    {
-	emsg(_(e_endif_without_if));
-	return NULL;
-    }
-    ifscope = &scope->se_u.se_if;
-    unwind_locals(cctx, scope->se_local_count);
-    if (!cctx->ctx_had_return)
-	ifscope->is_had_return = FALSE;
-
-    if (scope->se_u.se_if.is_if_label >= 0)
-    {
-	// previous "if" or "elseif" jumps here
-	isn = ((isn_T *)instr->ga_data) + scope->se_u.se_if.is_if_label;
-	isn->isn_arg.jump.jump_where = instr->ga_len;
-    }
-    // Fill in the "end" label in jumps at the end of the blocks.
-    compile_fill_jump_to_end(&ifscope->is_end_label, instr->ga_len, cctx);
-
-#ifdef FEAT_PROFILE
-    // even when skipping we count the endif as executed, unless the block it's
-    // in is skipped
-    if (cctx->ctx_compile_type == CT_PROFILE && cctx->ctx_skip == SKIP_YES
-					    && scope->se_skip_save != SKIP_YES)
-    {
-	cctx->ctx_skip = SKIP_NOT;
-	generate_instr(cctx, ISN_PROF_START);
-    }
-#endif
-    cctx->ctx_skip = scope->se_skip_save;
-
-    // If all the blocks end in :return and there is an :else then the
-    // had_return flag is set.
-    cctx->ctx_had_return = ifscope->is_had_return && ifscope->is_seen_else;
-
-    drop_scope(cctx);
-    return arg;
-}
-
-/*
- * Compile "for var in expr":
- *
- * Produces instructions:
- *       PUSHNR -1
- *       STORE loop-idx		Set index to -1
- *       EVAL expr		result of "expr" on top of stack
- * top:  FOR loop-idx, end	Increment index, use list on bottom of stack
- *				- if beyond end, jump to "end"
- *				- otherwise get item from list and push it
- *       STORE var		Store item in "var"
- *       ... body ...
- *       JUMP top		Jump back to repeat
- * end:	 DROP			Drop the result of "expr"
- *
- * Compile "for [var1, var2] in expr" - as above, but instead of "STORE var":
- *	 UNPACK 2		Split item in 2
- *       STORE var1		Store item in "var1"
- *       STORE var2		Store item in "var2"
- */
-    static char_u *
-compile_for(char_u *arg_start, cctx_T *cctx)
-{
-    char_u	*arg;
-    char_u	*arg_end;
-    char_u	*name = NULL;
-    char_u	*p;
-    char_u	*wp;
-    int		var_count = 0;
-    int		var_list = FALSE;
-    int		semicolon = FALSE;
-    size_t	varlen;
-    garray_T	*stack = &cctx->ctx_type_stack;
-    garray_T	*instr = &cctx->ctx_instr;
-    scope_T	*scope;
-    lvar_T	*loop_lvar;	// loop iteration variable
-    lvar_T	*var_lvar;	// variable for "var"
-    type_T	*vartype;
-    type_T	*item_type = &t_any;
-    int		idx;
-    int		prev_lnum = cctx->ctx_prev_lnum;
-
-    p = skip_var_list(arg_start, TRUE, &var_count, &semicolon, FALSE);
-    if (p == NULL)
-	return NULL;
-    if (var_count == 0)
-	var_count = 1;
-    else
-	var_list = TRUE;  // can also be a list of one variable
-
-    // consume "in"
-    wp = p;
-    if (may_get_next_line_error(wp, &p, cctx) == FAIL)
-	return NULL;
-    if (STRNCMP(p, "in", 2) != 0 || !IS_WHITE_OR_NUL(p[2]))
-    {
-	if (*p == ':' && wp != p)
-	    semsg(_(e_no_white_space_allowed_before_colon_str), p);
-	else
-	    emsg(_(e_missing_in));
-	return NULL;
-    }
-    wp = p + 2;
-    if (may_get_next_line_error(wp, &p, cctx) == FAIL)
-	return NULL;
-
-    // Remove the already generated ISN_DEBUG, it is written below the ISN_FOR
-    // instruction.
-    if (cctx->ctx_compile_type == CT_DEBUG && instr->ga_len > 0
-	    && ((isn_T *)instr->ga_data)[instr->ga_len - 1]
-							.isn_type == ISN_DEBUG)
-    {
-	--instr->ga_len;
-	prev_lnum = ((isn_T *)instr->ga_data)[instr->ga_len]
-						 .isn_arg.debug.dbg_break_lnum;
-    }
-
-    scope = new_scope(cctx, FOR_SCOPE);
-    if (scope == NULL)
-	return NULL;
-
-    // Reserve a variable to store the loop iteration counter and initialize it
-    // to -1.
-    loop_lvar = reserve_local(cctx, (char_u *)"", 0, FALSE, &t_number);
-    if (loop_lvar == NULL)
-    {
-	// out of memory
-	drop_scope(cctx);
-	return NULL;
-    }
-    generate_STORENR(cctx, loop_lvar->lv_idx, -1);
-
-    // compile "expr", it remains on the stack until "endfor"
-    arg = p;
-    if (compile_expr0(&arg, cctx) == FAIL)
-    {
-	drop_scope(cctx);
-	return NULL;
-    }
-    arg_end = arg;
-
-    if (cctx->ctx_skip != SKIP_YES)
-    {
-	// If we know the type of "var" and it is a not a supported type we can
-	// give an error now.
-	vartype = ((type_T **)stack->ga_data)[stack->ga_len - 1];
-	if (vartype->tt_type != VAR_LIST && vartype->tt_type != VAR_STRING
-		&& vartype->tt_type != VAR_BLOB && vartype->tt_type != VAR_ANY)
-	{
-	    semsg(_(e_for_loop_on_str_not_supported),
-					       vartype_name(vartype->tt_type));
-	    drop_scope(cctx);
-	    return NULL;
-	}
-
-	if (vartype->tt_type == VAR_STRING)
-	    item_type = &t_string;
-	else if (vartype->tt_type == VAR_BLOB)
-	    item_type = &t_number;
-	else if (vartype->tt_type == VAR_LIST
-				     && vartype->tt_member->tt_type != VAR_ANY)
-	{
-	    if (!var_list)
-		item_type = vartype->tt_member;
-	    else if (vartype->tt_member->tt_type == VAR_LIST
-			  && vartype->tt_member->tt_member->tt_type != VAR_ANY)
-		item_type = vartype->tt_member->tt_member;
-	}
-
-	// CMDMOD_REV must come before the FOR instruction.
-	generate_undo_cmdmods(cctx);
-
-	// "for_end" is set when ":endfor" is found
-	scope->se_u.se_for.fs_top_label = current_instr_idx(cctx);
-
-	generate_FOR(cctx, loop_lvar->lv_idx);
-
-	arg = arg_start;
-	if (var_list)
-	{
-	    generate_UNPACK(cctx, var_count, semicolon);
-	    arg = skipwhite(arg + 1);	// skip white after '['
-
-	    // the list item is replaced by a number of items
-	    if (GA_GROW_FAILS(stack, var_count - 1))
-	    {
-		drop_scope(cctx);
-		return NULL;
-	    }
-	    --stack->ga_len;
-	    for (idx = 0; idx < var_count; ++idx)
-	    {
-		((type_T **)stack->ga_data)[stack->ga_len] =
-				 (semicolon && idx == 0) ? vartype : item_type;
-		++stack->ga_len;
-	    }
-	}
-
-	for (idx = 0; idx < var_count; ++idx)
-	{
-	    assign_dest_T	dest = dest_local;
-	    int			opt_flags = 0;
-	    int			vimvaridx = -1;
-	    type_T		*type = &t_any;
-	    type_T		*lhs_type = &t_any;
-	    where_T		where = WHERE_INIT;
-
-	    p = skip_var_one(arg, FALSE);
-	    varlen = p - arg;
-	    name = vim_strnsave(arg, varlen);
-	    if (name == NULL)
-		goto failed;
-	    if (*p == ':')
-	    {
-		p = skipwhite(p + 1);
-		lhs_type = parse_type(&p, cctx->ctx_type_list, TRUE);
-	    }
-
-	    if (get_var_dest(name, &dest, CMD_for, &opt_flags,
-					      &vimvaridx, &type, cctx) == FAIL)
-		goto failed;
-	    if (dest != dest_local)
-	    {
-		if (generate_store_var(cctx, dest, opt_flags, vimvaridx,
-						     0, 0, type, name) == FAIL)
-		    goto failed;
-	    }
-	    else if (varlen == 1 && *arg == '_')
-	    {
-		// Assigning to "_": drop the value.
-		if (generate_instr_drop(cctx, ISN_DROP, 1) == NULL)
-		    goto failed;
-	    }
-	    else
-	    {
-		// Script var is not supported.
-		if (STRNCMP(name, "s:", 2) == 0)
-		{
-		    emsg(_(e_cannot_use_script_variable_in_for_loop));
-		    goto failed;
-		}
-
-		if (!valid_varname(arg, (int)varlen, FALSE))
-		    goto failed;
-		if (lookup_local(arg, varlen, NULL, cctx) == OK)
-		{
-		    semsg(_(e_variable_already_declared), arg);
-		    goto failed;
-		}
-
-		// Reserve a variable to store "var".
-		where.wt_index = var_list ? idx + 1 : 0;
-		where.wt_variable = TRUE;
-		if (lhs_type == &t_any)
-		    lhs_type = item_type;
-		else if (item_type != &t_unknown
-			    && (item_type == &t_any
-			      ? need_type(item_type, lhs_type,
-						     -1, 0, cctx, FALSE, FALSE)
-			      : check_type(lhs_type, item_type, TRUE, where))
-			    == FAIL)
-		    goto failed;
-		var_lvar = reserve_local(cctx, arg, varlen, TRUE, lhs_type);
-		if (var_lvar == NULL)
-		    // out of memory or used as an argument
-		    goto failed;
-
-		if (semicolon && idx == var_count - 1)
-		    var_lvar->lv_type = vartype;
-		else
-		    var_lvar->lv_type = item_type;
-		generate_STORE(cctx, ISN_STORE, var_lvar->lv_idx, NULL);
-	    }
-
-	    if (*p == ',' || *p == ';')
-		++p;
-	    arg = skipwhite(p);
-	    vim_free(name);
-	}
-
-	if (cctx->ctx_compile_type == CT_DEBUG)
-	{
-	    int save_prev_lnum = cctx->ctx_prev_lnum;
-
-	    // Add ISN_DEBUG here, so that the loop variables can be inspected.
-	    // Use the prev_lnum from the ISN_DEBUG instruction removed above.
-	    cctx->ctx_prev_lnum = prev_lnum;
-	    generate_instr_debug(cctx);
-	    cctx->ctx_prev_lnum = save_prev_lnum;
-	}
-    }
-
-    return arg_end;
-
-failed:
-    vim_free(name);
-    drop_scope(cctx);
-    return NULL;
-}
-
-/*
- * compile "endfor"
- */
-    static char_u *
-compile_endfor(char_u *arg, cctx_T *cctx)
-{
-    garray_T	*instr = &cctx->ctx_instr;
-    scope_T	*scope = cctx->ctx_scope;
-    forscope_T	*forscope;
-    isn_T	*isn;
-
-    if (misplaced_cmdmod(cctx))
-	return NULL;
-
-    if (scope == NULL || scope->se_type != FOR_SCOPE)
-    {
-	emsg(_(e_for));
-	return NULL;
-    }
-    forscope = &scope->se_u.se_for;
-    cctx->ctx_scope = scope->se_outer;
-    if (cctx->ctx_skip != SKIP_YES)
-    {
-	unwind_locals(cctx, scope->se_local_count);
-
-	// At end of ":for" scope jump back to the FOR instruction.
-	generate_JUMP(cctx, JUMP_ALWAYS, forscope->fs_top_label);
-
-	// Fill in the "end" label in the FOR statement so it can jump here.
-	isn = ((isn_T *)instr->ga_data) + forscope->fs_top_label;
-	isn->isn_arg.forloop.for_end = instr->ga_len;
-
-	// Fill in the "end" label any BREAK statements
-	compile_fill_jump_to_end(&forscope->fs_end_label, instr->ga_len, cctx);
-
-	// Below the ":for" scope drop the "expr" list from the stack.
-	if (generate_instr_drop(cctx, ISN_DROP, 1) == NULL)
-	    return NULL;
-    }
-
-    vim_free(scope);
-
-    return arg;
-}
-
-/*
- * compile "while expr"
- *
- * Produces instructions:
- * top:  EVAL expr		Push result of "expr"
- *       JUMP_IF_FALSE end	jump if false
- *       ... body ...
- *       JUMP top		Jump back to repeat
- * end:
- *
- */
-    static char_u *
-compile_while(char_u *arg, cctx_T *cctx)
-{
-    char_u	*p = arg;
-    scope_T	*scope;
-
-    scope = new_scope(cctx, WHILE_SCOPE);
-    if (scope == NULL)
-	return NULL;
-
-    // "endwhile" jumps back here, one before when profiling or using cmdmods
-    scope->se_u.se_while.ws_top_label = current_instr_idx(cctx);
-
-    // compile "expr"
-    if (compile_expr0(&p, cctx) == FAIL)
-	return NULL;
-
-    if (!ends_excmd2(arg, skipwhite(p)))
-    {
-	semsg(_(e_trailing_arg), p);
-	return NULL;
-    }
-
-    if (cctx->ctx_skip != SKIP_YES)
-    {
-	if (bool_on_stack(cctx) == FAIL)
-	    return FAIL;
-
-	// CMDMOD_REV must come before the jump
-	generate_undo_cmdmods(cctx);
-
-	// "while_end" is set when ":endwhile" is found
-	if (compile_jump_to_end(&scope->se_u.se_while.ws_end_label,
-						  JUMP_IF_FALSE, cctx) == FAIL)
-	    return FAIL;
-    }
-
-    return p;
-}
-
-/*
- * compile "endwhile"
- */
-    static char_u *
-compile_endwhile(char_u *arg, cctx_T *cctx)
-{
-    scope_T	*scope = cctx->ctx_scope;
-    garray_T	*instr = &cctx->ctx_instr;
-
-    if (misplaced_cmdmod(cctx))
-	return NULL;
-    if (scope == NULL || scope->se_type != WHILE_SCOPE)
-    {
-	emsg(_(e_while));
-	return NULL;
-    }
-    cctx->ctx_scope = scope->se_outer;
-    if (cctx->ctx_skip != SKIP_YES)
-    {
-	unwind_locals(cctx, scope->se_local_count);
-
-#ifdef FEAT_PROFILE
-	// count the endwhile before jumping
-	may_generate_prof_end(cctx, cctx->ctx_lnum);
-#endif
-
-	// At end of ":for" scope jump back to the FOR instruction.
-	generate_JUMP(cctx, JUMP_ALWAYS, scope->se_u.se_while.ws_top_label);
-
-	// Fill in the "end" label in the WHILE statement so it can jump here.
-	// And in any jumps for ":break"
-	compile_fill_jump_to_end(&scope->se_u.se_while.ws_end_label,
-							  instr->ga_len, cctx);
-    }
-
-    vim_free(scope);
-
-    return arg;
-}
-
-/*
- * compile "continue"
- */
-    static char_u *
-compile_continue(char_u *arg, cctx_T *cctx)
-{
-    scope_T	*scope = cctx->ctx_scope;
-    int		try_scopes = 0;
-    int		loop_label;
-
-    for (;;)
-    {
-	if (scope == NULL)
-	{
-	    emsg(_(e_continue));
-	    return NULL;
-	}
-	if (scope->se_type == FOR_SCOPE)
-	{
-	    loop_label = scope->se_u.se_for.fs_top_label;
-	    break;
-	}
-	if (scope->se_type == WHILE_SCOPE)
-	{
-	    loop_label = scope->se_u.se_while.ws_top_label;
-	    break;
-	}
-	if (scope->se_type == TRY_SCOPE)
-	    ++try_scopes;
-	scope = scope->se_outer;
-    }
-
-    if (try_scopes > 0)
-	// Inside one or more try/catch blocks we first need to jump to the
-	// "finally" or "endtry" to cleanup.
-	generate_TRYCONT(cctx, try_scopes, loop_label);
-    else
-	// Jump back to the FOR or WHILE instruction.
-	generate_JUMP(cctx, JUMP_ALWAYS, loop_label);
-
-    return arg;
-}
-
-/*
- * compile "break"
- */
-    static char_u *
-compile_break(char_u *arg, cctx_T *cctx)
-{
-    scope_T	*scope = cctx->ctx_scope;
-    endlabel_T	**el;
-
-    for (;;)
-    {
-	if (scope == NULL)
-	{
-	    emsg(_(e_break));
-	    return NULL;
-	}
-	if (scope->se_type == FOR_SCOPE || scope->se_type == WHILE_SCOPE)
-	    break;
-	scope = scope->se_outer;
-    }
-
-    // Jump to the end of the FOR or WHILE loop.
-    if (scope->se_type == FOR_SCOPE)
-	el = &scope->se_u.se_for.fs_end_label;
-    else
-	el = &scope->se_u.se_while.ws_end_label;
-    if (compile_jump_to_end(el, JUMP_ALWAYS, cctx) == FAIL)
-	return FAIL;
-
-    return arg;
-}
-
-/*
- * compile "{" start of block
- */
-    static char_u *
-compile_block(char_u *arg, cctx_T *cctx)
-{
-    if (new_scope(cctx, BLOCK_SCOPE) == NULL)
-	return NULL;
-    return skipwhite(arg + 1);
-}
-
-/*
- * compile end of block: drop one scope
- */
-    static void
-compile_endblock(cctx_T *cctx)
-{
-    scope_T	*scope = cctx->ctx_scope;
-
-    cctx->ctx_scope = scope->se_outer;
-    unwind_locals(cctx, scope->se_local_count);
-    vim_free(scope);
-}
-
-/*
- * Compile "try".
- * Creates a new scope for the try-endtry, pointing to the first catch and
- * finally.
- * Creates another scope for the "try" block itself.
- * TRY instruction sets up exception handling at runtime.
- *
- *	"try"
- *	    TRY -> catch1, -> finally  push trystack entry
- *	    ... try block
- *	"throw {exception}"
- *	    EVAL {exception}
- *	    THROW		create exception
- *	    ... try block
- *	" catch {expr}"
- *	    JUMP -> finally
- * catch1:  PUSH exception
- *	    EVAL {expr}
- *	    MATCH
- *	    JUMP nomatch -> catch2
- *	    CATCH   remove exception
- *	    ... catch block
- *	" catch"
- *	    JUMP -> finally
- * catch2:  CATCH   remove exception
- *	    ... catch block
- *	" finally"
- * finally:
- *	    ... finally block
- *	" endtry"
- *	    ENDTRY  pop trystack entry, may rethrow
- */
-    static char_u *
-compile_try(char_u *arg, cctx_T *cctx)
-{
-    garray_T	*instr = &cctx->ctx_instr;
-    scope_T	*try_scope;
-    scope_T	*scope;
-
-    if (misplaced_cmdmod(cctx))
-	return NULL;
-
-    // scope that holds the jumps that go to catch/finally/endtry
-    try_scope = new_scope(cctx, TRY_SCOPE);
-    if (try_scope == NULL)
-	return NULL;
-
-    if (cctx->ctx_skip != SKIP_YES)
-    {
-	isn_T	*isn;
-
-	// "try_catch" is set when the first ":catch" is found or when no catch
-	// is found and ":finally" is found.
-	// "try_finally" is set when ":finally" is found
-	// "try_endtry" is set when ":endtry" is found
-	try_scope->se_u.se_try.ts_try_label = instr->ga_len;
-	if ((isn = generate_instr(cctx, ISN_TRY)) == NULL)
-	    return NULL;
-	isn->isn_arg.try.try_ref = ALLOC_CLEAR_ONE(tryref_T);
-	if (isn->isn_arg.try.try_ref == NULL)
-	    return NULL;
-    }
-
-    // scope for the try block itself
-    scope = new_scope(cctx, BLOCK_SCOPE);
-    if (scope == NULL)
-	return NULL;
-
-    return arg;
-}
-
-/*
- * Compile "catch {expr}".
- */
-    static char_u *
-compile_catch(char_u *arg, cctx_T *cctx UNUSED)
-{
-    scope_T	*scope = cctx->ctx_scope;
-    garray_T	*instr = &cctx->ctx_instr;
-    char_u	*p;
-    isn_T	*isn;
-
-    if (misplaced_cmdmod(cctx))
-	return NULL;
-
-    // end block scope from :try or :catch
-    if (scope != NULL && scope->se_type == BLOCK_SCOPE)
-	compile_endblock(cctx);
-    scope = cctx->ctx_scope;
-
-    // Error if not in a :try scope
-    if (scope == NULL || scope->se_type != TRY_SCOPE)
-    {
-	emsg(_(e_catch));
-	return NULL;
-    }
-
-    if (scope->se_u.se_try.ts_caught_all)
-    {
-	emsg(_(e_catch_unreachable_after_catch_all));
-	return NULL;
-    }
-
-    if (cctx->ctx_skip != SKIP_YES)
-    {
-#ifdef FEAT_PROFILE
-	// the profile-start should be after the jump
-	if (cctx->ctx_compile_type == CT_PROFILE
-		&& instr->ga_len > 0
-		&& ((isn_T *)instr->ga_data)[instr->ga_len - 1]
-						   .isn_type == ISN_PROF_START)
-	    --instr->ga_len;
-#endif
-	// Jump from end of previous block to :finally or :endtry
-	if (compile_jump_to_end(&scope->se_u.se_try.ts_end_label,
-						    JUMP_ALWAYS, cctx) == FAIL)
-	    return NULL;
-
-	// End :try or :catch scope: set value in ISN_TRY instruction
-	isn = ((isn_T *)instr->ga_data) + scope->se_u.se_try.ts_try_label;
-	if (isn->isn_arg.try.try_ref->try_catch == 0)
-	    isn->isn_arg.try.try_ref->try_catch = instr->ga_len;
-	if (scope->se_u.se_try.ts_catch_label != 0)
-	{
-	    // Previous catch without match jumps here
-	    isn = ((isn_T *)instr->ga_data) + scope->se_u.se_try.ts_catch_label;
-	    isn->isn_arg.jump.jump_where = instr->ga_len;
-	}
-#ifdef FEAT_PROFILE
-	if (cctx->ctx_compile_type == CT_PROFILE)
-	{
-	    // a "throw" that jumps here needs to be counted
-	    generate_instr(cctx, ISN_PROF_END);
-	    // the "catch" is also counted
-	    generate_instr(cctx, ISN_PROF_START);
-	}
-#endif
-	if (cctx->ctx_compile_type == CT_DEBUG)
-	    generate_instr_debug(cctx);
-    }
-
-    p = skipwhite(arg);
-    if (ends_excmd2(arg, p))
-    {
-	scope->se_u.se_try.ts_caught_all = TRUE;
-	scope->se_u.se_try.ts_catch_label = 0;
-    }
-    else
-    {
-	char_u *end;
-	char_u *pat;
-	char_u *tofree = NULL;
-	int	dropped = 0;
-	int	len;
-
-	// Push v:exception, push {expr} and MATCH
-	generate_instr_type(cctx, ISN_PUSHEXC, &t_string);
-
-	end = skip_regexp_ex(p + 1, *p, TRUE, &tofree, &dropped, NULL);
-	if (*end != *p)
-	{
-	    semsg(_(e_separator_mismatch_str), p);
-	    vim_free(tofree);
-	    return FAIL;
-	}
-	if (tofree == NULL)
-	    len = (int)(end - (p + 1));
-	else
-	    len = (int)(end - tofree);
-	pat = vim_strnsave(tofree == NULL ? p + 1 : tofree, len);
-	vim_free(tofree);
-	p += len + 2 + dropped;
-	if (pat == NULL)
-	    return FAIL;
-	if (generate_PUSHS(cctx, &pat) == FAIL)
-	    return FAIL;
-
-	if (generate_COMPARE(cctx, EXPR_MATCH, FALSE) == FAIL)
-	    return NULL;
-
-	scope->se_u.se_try.ts_catch_label = instr->ga_len;
-	if (generate_JUMP(cctx, JUMP_IF_FALSE, 0) == FAIL)
-	    return NULL;
-    }
-
-    if (cctx->ctx_skip != SKIP_YES && generate_instr(cctx, ISN_CATCH) == NULL)
-	return NULL;
-
-    if (new_scope(cctx, BLOCK_SCOPE) == NULL)
-	return NULL;
-    return p;
-}
-
-    static char_u *
-compile_finally(char_u *arg, cctx_T *cctx)
-{
-    scope_T	*scope = cctx->ctx_scope;
-    garray_T	*instr = &cctx->ctx_instr;
-    isn_T	*isn;
-    int		this_instr;
-
-    if (misplaced_cmdmod(cctx))
-	return NULL;
-
-    // end block scope from :try or :catch
-    if (scope != NULL && scope->se_type == BLOCK_SCOPE)
-	compile_endblock(cctx);
-    scope = cctx->ctx_scope;
-
-    // Error if not in a :try scope
-    if (scope == NULL || scope->se_type != TRY_SCOPE)
-    {
-	emsg(_(e_finally));
-	return NULL;
-    }
-
-    if (cctx->ctx_skip != SKIP_YES)
-    {
-	// End :catch or :finally scope: set value in ISN_TRY instruction
-	isn = ((isn_T *)instr->ga_data) + scope->se_u.se_try.ts_try_label;
-	if (isn->isn_arg.try.try_ref->try_finally != 0)
-	{
-	    emsg(_(e_finally_dup));
-	    return NULL;
-	}
-
-	this_instr = instr->ga_len;
-#ifdef FEAT_PROFILE
-	if (cctx->ctx_compile_type == CT_PROFILE
-		&& ((isn_T *)instr->ga_data)[this_instr - 1]
-						   .isn_type == ISN_PROF_START)
-	{
-	    // jump to the profile start of the "finally"
-	    --this_instr;
-
-	    // jump to the profile end above it
-	    if (this_instr > 0 && ((isn_T *)instr->ga_data)[this_instr - 1]
-						     .isn_type == ISN_PROF_END)
-		--this_instr;
-	}
-#endif
-
-	// Fill in the "end" label in jumps at the end of the blocks.
-	compile_fill_jump_to_end(&scope->se_u.se_try.ts_end_label,
-							     this_instr, cctx);
-
-	// If there is no :catch then an exception jumps to :finally.
-	if (isn->isn_arg.try.try_ref->try_catch == 0)
-	    isn->isn_arg.try.try_ref->try_catch = this_instr;
-	isn->isn_arg.try.try_ref->try_finally = this_instr;
-	if (scope->se_u.se_try.ts_catch_label != 0)
-	{
-	    // Previous catch without match jumps here
-	    isn = ((isn_T *)instr->ga_data) + scope->se_u.se_try.ts_catch_label;
-	    isn->isn_arg.jump.jump_where = this_instr;
-	    scope->se_u.se_try.ts_catch_label = 0;
-	}
-	if (generate_instr(cctx, ISN_FINALLY) == NULL)
-	    return NULL;
-    }
-
-    return arg;
-}
-
-    static char_u *
-compile_endtry(char_u *arg, cctx_T *cctx)
-{
-    scope_T	*scope = cctx->ctx_scope;
-    garray_T	*instr = &cctx->ctx_instr;
-    isn_T	*try_isn;
-
-    if (misplaced_cmdmod(cctx))
-	return NULL;
-
-    // end block scope from :catch or :finally
-    if (scope != NULL && scope->se_type == BLOCK_SCOPE)
-	compile_endblock(cctx);
-    scope = cctx->ctx_scope;
-
-    // Error if not in a :try scope
-    if (scope == NULL || scope->se_type != TRY_SCOPE)
-    {
-	if (scope == NULL)
-	    emsg(_(e_no_endtry));
-	else if (scope->se_type == WHILE_SCOPE)
-	    emsg(_(e_endwhile));
-	else if (scope->se_type == FOR_SCOPE)
-	    emsg(_(e_endfor));
-	else
-	    emsg(_(e_endif));
-	return NULL;
-    }
-
-    try_isn = ((isn_T *)instr->ga_data) + scope->se_u.se_try.ts_try_label;
-    if (cctx->ctx_skip != SKIP_YES)
-    {
-	if (try_isn->isn_arg.try.try_ref->try_catch == 0
-				      && try_isn->isn_arg.try.try_ref->try_finally == 0)
-	{
-	    emsg(_(e_missing_catch_or_finally));
-	    return NULL;
-	}
-
-#ifdef FEAT_PROFILE
-	if (cctx->ctx_compile_type == CT_PROFILE
-		&& ((isn_T *)instr->ga_data)[instr->ga_len - 1]
-						.isn_type == ISN_PROF_START)
-	    // move the profile start after "endtry" so that it's not counted when
-	    // the exception is rethrown.
-	    --instr->ga_len;
-#endif
-
-	// Fill in the "end" label in jumps at the end of the blocks, if not
-	// done by ":finally".
-	compile_fill_jump_to_end(&scope->se_u.se_try.ts_end_label,
-							  instr->ga_len, cctx);
-
-	if (scope->se_u.se_try.ts_catch_label != 0)
-	{
-	    // Last catch without match jumps here
-	    isn_T *isn = ((isn_T *)instr->ga_data)
-					   + scope->se_u.se_try.ts_catch_label;
-	    isn->isn_arg.jump.jump_where = instr->ga_len;
-	}
-    }
-
-    compile_endblock(cctx);
-
-    if (cctx->ctx_skip != SKIP_YES)
-    {
-	// End :catch or :finally scope: set instruction index in ISN_TRY
-	// instruction
-	try_isn->isn_arg.try.try_ref->try_endtry = instr->ga_len;
-	if (cctx->ctx_skip != SKIP_YES
-				   && generate_instr(cctx, ISN_ENDTRY) == NULL)
-	    return NULL;
-#ifdef FEAT_PROFILE
-	if (cctx->ctx_compile_type == CT_PROFILE)
-	    generate_instr(cctx, ISN_PROF_START);
-#endif
-    }
-    return arg;
-}
-
-/*
- * compile "throw {expr}"
- */
-    static char_u *
-compile_throw(char_u *arg, cctx_T *cctx UNUSED)
-{
-    char_u *p = skipwhite(arg);
-
-    if (compile_expr0(&p, cctx) == FAIL)
-	return NULL;
-    if (cctx->ctx_skip == SKIP_YES)
-	return p;
-    if (may_generate_2STRING(-1, FALSE, cctx) == FAIL)
-	return NULL;
-    if (generate_instr_drop(cctx, ISN_THROW, 1) == NULL)
-	return NULL;
-
-    return p;
-}
-
-    static char_u *
-compile_eval(char_u *arg, cctx_T *cctx)
-{
-    char_u	*p = arg;
-    int		name_only;
-    long	lnum = SOURCING_LNUM;
-
-    // find_ex_command() will consider a variable name an expression, assuming
-    // that something follows on the next line.  Check that something actually
-    // follows, otherwise it's probably a misplaced command.
-    name_only = cmd_is_name_only(arg);
-
-    if (compile_expr0(&p, cctx) == FAIL)
-	return NULL;
-
-    if (name_only && lnum == SOURCING_LNUM)
-    {
-	semsg(_(e_expression_without_effect_str), arg);
-	return NULL;
-    }
-
-    // drop the result
-    generate_instr_drop(cctx, ISN_DROP, 1);
-
-    return skipwhite(p);
-}
-
-/*
- * compile "echo expr"
- * compile "echomsg expr"
- * compile "echoerr expr"
- * compile "echoconsole expr"
- * compile "execute expr"
- */
-    static char_u *
-compile_mult_expr(char_u *arg, int cmdidx, cctx_T *cctx)
-{
-    char_u	*p = arg;
-    char_u	*prev = arg;
-    char_u	*expr_start;
-    int		count = 0;
-    int		start_ctx_lnum = cctx->ctx_lnum;
-    garray_T	*stack = &cctx->ctx_type_stack;
-    type_T	*type;
-
-    for (;;)
-    {
-	if (ends_excmd2(prev, p))
-	    break;
-	expr_start = p;
-	if (compile_expr0(&p, cctx) == FAIL)
-	    return NULL;
-
-	if (cctx->ctx_skip != SKIP_YES)
-	{
-	    // check for non-void type
-	    type = ((type_T **)stack->ga_data)[stack->ga_len - 1];
-	    if (type->tt_type == VAR_VOID)
-	    {
-		semsg(_(e_expression_does_not_result_in_value_str), expr_start);
-		return NULL;
-	    }
-	}
-
-	++count;
-	prev = p;
-	p = skipwhite(p);
-    }
-
-    if (count > 0)
-    {
-	long save_lnum = cctx->ctx_lnum;
-
-	// Use the line number where the command started.
-	cctx->ctx_lnum = start_ctx_lnum;
-
-	if (cmdidx == CMD_echo || cmdidx == CMD_echon)
-	    generate_ECHO(cctx, cmdidx == CMD_echo, count);
-	else if (cmdidx == CMD_execute)
-	    generate_MULT_EXPR(cctx, ISN_EXECUTE, count);
-	else if (cmdidx == CMD_echomsg)
-	    generate_MULT_EXPR(cctx, ISN_ECHOMSG, count);
-	else if (cmdidx == CMD_echoconsole)
-	    generate_MULT_EXPR(cctx, ISN_ECHOCONSOLE, count);
-	else
-	    generate_MULT_EXPR(cctx, ISN_ECHOERR, count);
-
-	cctx->ctx_lnum = save_lnum;
-    }
-    return p;
-}
-
-/*
- * If "eap" has a range that is not a constant generate an ISN_RANGE
- * instruction to compute it and return OK.
- * Otherwise return FAIL, the caller must deal with any range.
- */
-    static int
-compile_variable_range(exarg_T *eap, cctx_T *cctx)
-{
-    char_u *range_end = skip_range(eap->cmd, TRUE, NULL);
-    char_u *p = skipdigits(eap->cmd);
-
-    if (p == range_end)
-	return FAIL;
-    return generate_RANGE(cctx, vim_strnsave(eap->cmd, range_end - eap->cmd));
-}
-
-/*
- * :put r
- * :put ={expr}
- */
-    static char_u *
-compile_put(char_u *arg, exarg_T *eap, cctx_T *cctx)
-{
-    char_u	*line = arg;
-    linenr_T	lnum;
-    char	*errormsg;
-    int		above = eap->forceit;
-
-    eap->regname = *line;
-
-    if (eap->regname == '=')
-    {
-	char_u *p = line + 1;
-
-	if (compile_expr0(&p, cctx) == FAIL)
-	    return NULL;
-	line = p;
-    }
-    else if (eap->regname != NUL)
-	++line;
-
-    if (compile_variable_range(eap, cctx) == OK)
-    {
-	lnum = above ? LNUM_VARIABLE_RANGE_ABOVE : LNUM_VARIABLE_RANGE;
-    }
-    else
-    {
-	// Either no range or a number.
-	// "errormsg" will not be set because the range is ADDR_LINES.
-	if (parse_cmd_address(eap, &errormsg, FALSE) == FAIL)
-	    // cannot happen
-	    return NULL;
-	if (eap->addr_count == 0)
-	    lnum = -1;
-	else
-	    lnum = eap->line2;
-	if (above)
-	    --lnum;
-    }
-
-    generate_PUT(cctx, eap->regname, lnum);
-    return line;
-}
-
-/*
- * A command that is not compiled, execute with legacy code.
- */
-    static char_u *
-compile_exec(char_u *line_arg, exarg_T *eap, cctx_T *cctx)
-{
-    char_u	*line = line_arg;
-    char_u	*p;
-    int		has_expr = FALSE;
-    char_u	*nextcmd = (char_u *)"";
-    char_u	*tofree = NULL;
-    char_u	*cmd_arg = NULL;
-
-    if (cctx->ctx_skip == SKIP_YES)
-	goto theend;
-
-    // If there was a prececing command modifier, drop it and include it in the
-    // EXEC command.
-    if (cctx->ctx_has_cmdmod)
-    {
-	garray_T	*instr = &cctx->ctx_instr;
-	isn_T		*isn = ((isn_T *)instr->ga_data) + instr->ga_len - 1;
-
-	if (isn->isn_type == ISN_CMDMOD)
-	{
-	    vim_regfree(isn->isn_arg.cmdmod.cf_cmdmod
-					       ->cmod_filter_regmatch.regprog);
-	    vim_free(isn->isn_arg.cmdmod.cf_cmdmod);
-	    --instr->ga_len;
-	    cctx->ctx_has_cmdmod = FALSE;
-	}
-    }
-
-    if (eap->cmdidx >= 0 && eap->cmdidx < CMD_SIZE)
-    {
-	long	argt = eap->argt;
-	int	usefilter = FALSE;
-
-	has_expr = argt & (EX_XFILE | EX_EXPAND);
-
-	// If the command can be followed by a bar, find the bar and truncate
-	// it, so that the following command can be compiled.
-	// The '|' is overwritten with a NUL, it is put back below.
-	if ((eap->cmdidx == CMD_write || eap->cmdidx == CMD_read)
-							   && *eap->arg == '!')
-	    // :w !filter or :r !filter or :r! filter
-	    usefilter = TRUE;
-	if ((argt & EX_TRLBAR) && !usefilter)
-	{
-	    eap->argt = argt;
-	    separate_nextcmd(eap);
-	    if (eap->nextcmd != NULL)
-		nextcmd = eap->nextcmd;
-	}
-	else if (eap->cmdidx == CMD_wincmd)
-	{
-	    p = eap->arg;
-	    if (*p != NUL)
-		++p;
-	    if (*p == 'g' || *p == Ctrl_G)
-		++p;
-	    p = skipwhite(p);
-	    if (*p == '|')
-	    {
-		*p = NUL;
-		nextcmd = p + 1;
-	    }
-	}
-	else if (eap->cmdidx == CMD_command || eap->cmdidx == CMD_autocmd)
-	{
-	    // If there is a trailing '{' read lines until the '}'
-	    p = eap->arg + STRLEN(eap->arg) - 1;
-	    while (p > eap->arg && VIM_ISWHITE(*p))
-		--p;
-	    if (*p == '{')
-	    {
-		exarg_T ea;
-		int	flags;  // unused
-		int	start_lnum = SOURCING_LNUM;
-
-		CLEAR_FIELD(ea);
-		ea.arg = eap->arg;
-		fill_exarg_from_cctx(&ea, cctx);
-		(void)may_get_cmd_block(&ea, p, &tofree, &flags);
-		if (tofree != NULL)
-		{
-		    *p = NUL;
-		    line = concat_str(line, tofree);
-		    if (line == NULL)
-			goto theend;
-		    vim_free(tofree);
-		    tofree = line;
-		    SOURCING_LNUM = start_lnum;
-		}
-	    }
-	}
-    }
-
-    if (eap->cmdidx == CMD_syntax && STRNCMP(eap->arg, "include ", 8) == 0)
-    {
-	// expand filename in "syntax include [@group] filename"
-	has_expr = TRUE;
-	eap->arg = skipwhite(eap->arg + 7);
-	if (*eap->arg == '@')
-	    eap->arg = skiptowhite(eap->arg);
-    }
-
-    if ((eap->cmdidx == CMD_global || eap->cmdidx == CMD_vglobal)
-						       && STRLEN(eap->arg) > 4)
-    {
-	int delim = *eap->arg;
-
-	p = skip_regexp_ex(eap->arg + 1, delim, TRUE, NULL, NULL, NULL);
-	if (*p == delim)
-	    cmd_arg = p + 1;
-    }
-
-    if (eap->cmdidx == CMD_folddoopen || eap->cmdidx == CMD_folddoclosed)
-	cmd_arg = eap->arg;
-
-    if (cmd_arg != NULL)
-    {
-	exarg_T nea;
-
-	CLEAR_FIELD(nea);
-	nea.cmd = cmd_arg;
-	p = find_ex_command(&nea, NULL, lookup_scriptitem, NULL);
-	if (nea.cmdidx < CMD_SIZE)
-	{
-	    has_expr = excmd_get_argt(nea.cmdidx) & (EX_XFILE | EX_EXPAND);
-	    if (has_expr)
-		eap->arg = skiptowhite(eap->arg);
-	}
-    }
-
-    if (has_expr && (p = (char_u *)strstr((char *)eap->arg, "`=")) != NULL)
-    {
-	int	count = 0;
-	char_u	*start = skipwhite(line);
-
-	// :cmd xxx`=expr1`yyy`=expr2`zzz
-	// PUSHS ":cmd xxx"
-	// eval expr1
-	// PUSHS "yyy"
-	// eval expr2
-	// PUSHS "zzz"
-	// EXECCONCAT 5
-	for (;;)
-	{
-	    if (p > start)
-	    {
-		char_u *val = vim_strnsave(start, p - start);
-
-		generate_PUSHS(cctx, &val);
-		++count;
-	    }
-	    p += 2;
-	    if (compile_expr0(&p, cctx) == FAIL)
-		return NULL;
-	    may_generate_2STRING(-1, TRUE, cctx);
-	    ++count;
-	    p = skipwhite(p);
-	    if (*p != '`')
-	    {
-		emsg(_(e_missing_backtick));
-		return NULL;
-	    }
-	    start = p + 1;
-
-	    p = (char_u *)strstr((char *)start, "`=");
-	    if (p == NULL)
-	    {
-		if (*skipwhite(start) != NUL)
-		{
-		    char_u *val = vim_strsave(start);
-
-		    generate_PUSHS(cctx, &val);
-		    ++count;
-		}
-		break;
-	    }
-	}
-	generate_EXECCONCAT(cctx, count);
-    }
-    else
-	generate_EXEC_copy(cctx, ISN_EXEC, line);
-
-theend:
-    if (*nextcmd != NUL)
-    {
-	// the parser expects a pointer to the bar, put it back
-	--nextcmd;
-	*nextcmd = '|';
-    }
-    vim_free(tofree);
-
-    return nextcmd;
-}
-
-/*
- * A script command with heredoc, e.g.
- *	ruby << EOF
- *	   command
- *	EOF
- * Has been turned into one long line with NL characters by
- * get_function_body():
- *	ruby << EOF<NL>   command<NL>EOF
- */
-    static char_u *
-compile_script(char_u *line, cctx_T *cctx)
-{
-    if (cctx->ctx_skip != SKIP_YES)
-    {
-	isn_T	*isn;
-
-	if ((isn = generate_instr(cctx, ISN_EXEC_SPLIT)) == NULL)
-	    return NULL;
-	isn->isn_arg.string = vim_strsave(line);
-    }
-    return (char_u *)"";
-}
-
-
-/*
- * :s/pat/repl/
- */
-    static char_u *
-compile_substitute(char_u *arg, exarg_T *eap, cctx_T *cctx)
-{
-    char_u  *cmd = eap->arg;
-    char_u  *expr = (char_u *)strstr((char *)cmd, "\\=");
-
-    if (expr != NULL)
-    {
-	int delimiter = *cmd++;
-
-	// There is a \=expr, find it in the substitute part.
-	cmd = skip_regexp_ex(cmd, delimiter, magic_isset(), NULL, NULL, NULL);
-	if (cmd[0] == delimiter && cmd[1] == '\\' && cmd[2] == '=')
-	{
-	    garray_T	save_ga = cctx->ctx_instr;
-	    char_u	*end;
-	    int		expr_res;
-	    int		trailing_error;
-	    int		instr_count;
-	    isn_T	*instr;
-	    isn_T	*isn;
-
-	    cmd += 3;
-	    end = skip_substitute(cmd, delimiter);
-
-	    // Temporarily reset the list of instructions so that the jump
-	    // labels are correct.
-	    cctx->ctx_instr.ga_len = 0;
-	    cctx->ctx_instr.ga_maxlen = 0;
-	    cctx->ctx_instr.ga_data = NULL;
-	    expr_res = compile_expr0(&cmd, cctx);
-	    if (end[-1] == NUL)
-		end[-1] = delimiter;
-	    cmd = skipwhite(cmd);
-	    trailing_error = *cmd != delimiter && *cmd != NUL;
-
-	    if (expr_res == FAIL || trailing_error
-				       || GA_GROW_FAILS(&cctx->ctx_instr, 1))
-	    {
-		if (trailing_error)
-		    semsg(_(e_trailing_arg), cmd);
-		clear_instr_ga(&cctx->ctx_instr);
-		cctx->ctx_instr = save_ga;
-		return NULL;
-	    }
-
-	    // Move the generated instructions into the ISN_SUBSTITUTE
-	    // instructions, then restore the list of instructions before
-	    // adding the ISN_SUBSTITUTE instruction.
-	    instr_count = cctx->ctx_instr.ga_len;
-	    instr = cctx->ctx_instr.ga_data;
-	    instr[instr_count].isn_type = ISN_FINISH;
-
-	    cctx->ctx_instr = save_ga;
-	    if ((isn = generate_instr(cctx, ISN_SUBSTITUTE)) == NULL)
-	    {
-		int idx;
-
-		for (idx = 0; idx < instr_count; ++idx)
-		    delete_instr(instr + idx);
-		vim_free(instr);
-		return NULL;
-	    }
-	    isn->isn_arg.subs.subs_cmd = vim_strsave(arg);
-	    isn->isn_arg.subs.subs_instr = instr;
-
-	    // skip over flags
-	    if (*end == '&')
-		++end;
-	    while (ASCII_ISALPHA(*end) || *end == '#')
-		++end;
-	    return end;
-	}
-    }
-
-    return compile_exec(arg, eap, cctx);
-}
-
-    static char_u *
-compile_redir(char_u *line, exarg_T *eap, cctx_T *cctx)
-{
-    char_u  *arg = eap->arg;
-    lhs_T   *lhs = &cctx->ctx_redir_lhs;
-
-    if (lhs->lhs_name != NULL)
-    {
-	if (STRNCMP(arg, "END", 3) == 0)
-	{
-	    if (lhs->lhs_append)
-	    {
-		// First load the current variable value.
-		if (compile_load_lhs_with_index(lhs, lhs->lhs_whole,
-								 cctx) == FAIL)
-		    return NULL;
-	    }
-
-	    // Gets the redirected text and put it on the stack, then store it
-	    // in the variable.
-	    generate_instr_type(cctx, ISN_REDIREND, &t_string);
-
-	    if (lhs->lhs_append)
-		generate_instr_drop(cctx, ISN_CONCAT, 1);
-
-	    if (lhs->lhs_has_index)
-	    {
-		// Use the info in "lhs" to store the value at the index in the
-		// list or dict.
-		if (compile_assign_unlet(lhs->lhs_whole, lhs, TRUE,
-						      &t_string, cctx) == FAIL)
-		    return NULL;
-	    }
-	    else if (generate_store_lhs(cctx, lhs, -1) == FAIL)
-		return NULL;
-
-	    VIM_CLEAR(lhs->lhs_name);
-	    VIM_CLEAR(lhs->lhs_whole);
-	    return arg + 3;
-	}
-	emsg(_(e_cannot_nest_redir));
-	return NULL;
-    }
-
-    if (arg[0] == '=' && arg[1] == '>')
-    {
-	int	    append = FALSE;
-
-	// redirect to a variable is compiled
-	arg += 2;
-	if (*arg == '>')
-	{
-	    ++arg;
-	    append = TRUE;
-	}
-	arg = skipwhite(arg);
-
-	if (compile_assign_lhs(arg, lhs, CMD_redir,
-						FALSE, FALSE, 1, cctx) == FAIL)
-	    return NULL;
-	if (need_type(&t_string, lhs->lhs_member_type,
-					    -1, 0, cctx, FALSE, FALSE) == FAIL)
-	    return NULL;
-	generate_instr(cctx, ISN_REDIRSTART);
-	lhs->lhs_append = append;
-	if (lhs->lhs_has_index)
-	{
-	    lhs->lhs_whole = vim_strnsave(arg, lhs->lhs_varlen_total);
-	    if (lhs->lhs_whole == NULL)
-		return NULL;
-	}
-
-	return arg + lhs->lhs_varlen_total;
-    }
-
-    // other redirects are handled like at script level
-    return compile_exec(line, eap, cctx);
-}
-
-#ifdef FEAT_QUICKFIX
-    static char_u *
-compile_cexpr(char_u *line, exarg_T *eap, cctx_T *cctx)
-{
-    isn_T	*isn;
-    char_u	*p;
-
-    isn = generate_instr(cctx, ISN_CEXPR_AUCMD);
-    if (isn == NULL)
-	return NULL;
-    isn->isn_arg.number = eap->cmdidx;
-
-    p = eap->arg;
-    if (compile_expr0(&p, cctx) == FAIL)
-	return NULL;
-
-    isn = generate_instr(cctx, ISN_CEXPR_CORE);
-    if (isn == NULL)
-	return NULL;
-    isn->isn_arg.cexpr.cexpr_ref = ALLOC_ONE(cexprref_T);
-    if (isn->isn_arg.cexpr.cexpr_ref == NULL)
-	return NULL;
-    isn->isn_arg.cexpr.cexpr_ref->cer_cmdidx = eap->cmdidx;
-    isn->isn_arg.cexpr.cexpr_ref->cer_forceit = eap->forceit;
-    isn->isn_arg.cexpr.cexpr_ref->cer_cmdline = vim_strsave(skipwhite(line));
-
-    return p;
-}
-#endif
-
-/*
- * Check if the separator for a :global or :substitute command is OK.
- */
-    int
-check_global_and_subst(char_u *cmd, char_u *arg)
-{
-    if (arg == cmd + 1 && vim_strchr((char_u *)":-.", *arg) != NULL)
-    {
-	semsg(_(e_separator_not_supported_str), arg);
-	return FAIL;
-    }
-    if (VIM_ISWHITE(cmd[1]))
-    {
-	semsg(_(e_no_white_space_allowed_before_separator_str), cmd);
-	return FAIL;
-    }
-    return OK;
-}
-
 
 /*
  * Add a function to the list of :def functions.
@@ -10448,272 +3217,6 @@
 					   argcount, &ufunc->uf_type_list);
 }
 
-
-/*
- * Delete an instruction, free what it contains.
- */
-    void
-delete_instr(isn_T *isn)
-{
-    switch (isn->isn_type)
-    {
-	case ISN_DEF:
-	case ISN_EXEC:
-	case ISN_EXECRANGE:
-	case ISN_EXEC_SPLIT:
-	case ISN_LEGACY_EVAL:
-	case ISN_LOADAUTO:
-	case ISN_LOADB:
-	case ISN_LOADENV:
-	case ISN_LOADG:
-	case ISN_LOADOPT:
-	case ISN_LOADT:
-	case ISN_LOADW:
-	case ISN_LOCKUNLOCK:
-	case ISN_PUSHEXC:
-	case ISN_PUSHFUNC:
-	case ISN_PUSHS:
-	case ISN_RANGE:
-	case ISN_STOREAUTO:
-	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;
-
-	case ISN_SUBSTITUTE:
-	    {
-		int	idx;
-		isn_T	*list = isn->isn_arg.subs.subs_instr;
-
-		vim_free(isn->isn_arg.subs.subs_cmd);
-		for (idx = 0; list[idx].isn_type != ISN_FINISH; ++idx)
-		    delete_instr(list + idx);
-		vim_free(list);
-	    }
-	    break;
-
-	case ISN_INSTR:
-	    {
-		int	idx;
-		isn_T	*list = isn->isn_arg.instr;
-
-		for (idx = 0; list[idx].isn_type != ISN_FINISH; ++idx)
-		    delete_instr(list + idx);
-		vim_free(list);
-	    }
-	    break;
-
-	case ISN_LOADS:
-	case ISN_STORES:
-	    vim_free(isn->isn_arg.loadstore.ls_name);
-	    break;
-
-	case ISN_UNLET:
-	case ISN_UNLETENV:
-	    vim_free(isn->isn_arg.unlet.ul_name);
-	    break;
-
-	case ISN_STOREOPT:
-	case ISN_STOREFUNCOPT:
-	    vim_free(isn->isn_arg.storeopt.so_name);
-	    break;
-
-	case ISN_PUSHBLOB:   // push blob isn_arg.blob
-	    blob_unref(isn->isn_arg.blob);
-	    break;
-
-	case ISN_PUSHJOB:
-#ifdef FEAT_JOB_CHANNEL
-	    job_unref(isn->isn_arg.job);
-#endif
-	    break;
-
-	case ISN_PUSHCHANNEL:
-#ifdef FEAT_JOB_CHANNEL
-	    channel_unref(isn->isn_arg.channel);
-#endif
-	    break;
-
-	case ISN_UCALL:
-	    vim_free(isn->isn_arg.ufunc.cuf_name);
-	    break;
-
-	case ISN_FUNCREF:
-	    {
-		if (isn->isn_arg.funcref.fr_func_name == NULL)
-		{
-		    dfunc_T *dfunc = ((dfunc_T *)def_functions.ga_data)
-					   + isn->isn_arg.funcref.fr_dfunc_idx;
-		    ufunc_T *ufunc = dfunc->df_ufunc;
-
-		    if (ufunc != NULL && func_name_refcount(ufunc->uf_name))
-			func_ptr_unref(ufunc);
-		}
-		else
-		{
-		    char_u *name = isn->isn_arg.funcref.fr_func_name;
-
-		    if (name != NULL)
-			func_unref(name);
-		    vim_free(isn->isn_arg.funcref.fr_func_name);
-		}
-	    }
-	    break;
-
-	case ISN_DCALL:
-	    {
-		dfunc_T *dfunc = ((dfunc_T *)def_functions.ga_data)
-					       + isn->isn_arg.dfunc.cdf_idx;
-
-		if (dfunc->df_ufunc != NULL
-			       && func_name_refcount(dfunc->df_ufunc->uf_name))
-		    func_ptr_unref(dfunc->df_ufunc);
-	    }
-	    break;
-
-	case ISN_NEWFUNC:
-	    {
-		char_u  *lambda = isn->isn_arg.newfunc.nf_lambda;
-		ufunc_T *ufunc = find_func_even_dead(lambda, TRUE, NULL);
-
-		if (ufunc != NULL)
-		{
-		    unlink_def_function(ufunc);
-		    func_ptr_unref(ufunc);
-		}
-
-		vim_free(lambda);
-		vim_free(isn->isn_arg.newfunc.nf_global);
-	    }
-	    break;
-
-	case ISN_CHECKTYPE:
-	case ISN_SETTYPE:
-	    free_type(isn->isn_arg.type.ct_type);
-	    break;
-
-	case ISN_CMDMOD:
-	    vim_regfree(isn->isn_arg.cmdmod.cf_cmdmod
-					       ->cmod_filter_regmatch.regprog);
-	    vim_free(isn->isn_arg.cmdmod.cf_cmdmod);
-	    break;
-
-	case ISN_LOADSCRIPT:
-	case ISN_STORESCRIPT:
-	    vim_free(isn->isn_arg.script.scriptref);
-	    break;
-
-	case ISN_TRY:
-	    vim_free(isn->isn_arg.try.try_ref);
-	    break;
-
-	case ISN_CEXPR_CORE:
-	    vim_free(isn->isn_arg.cexpr.cexpr_ref->cer_cmdline);
-	    vim_free(isn->isn_arg.cexpr.cexpr_ref);
-	    break;
-
-	case ISN_2BOOL:
-	case ISN_2STRING:
-	case ISN_2STRING_ANY:
-	case ISN_ADDBLOB:
-	case ISN_ADDLIST:
-	case ISN_ANYINDEX:
-	case ISN_ANYSLICE:
-	case ISN_BCALL:
-	case ISN_BLOBAPPEND:
-	case ISN_BLOBINDEX:
-	case ISN_BLOBSLICE:
-	case ISN_CATCH:
-	case ISN_CEXPR_AUCMD:
-	case ISN_CHECKLEN:
-	case ISN_CHECKNR:
-	case ISN_CLEARDICT:
-	case ISN_CMDMOD_REV:
-	case ISN_COMPAREANY:
-	case ISN_COMPAREBLOB:
-	case ISN_COMPAREBOOL:
-	case ISN_COMPAREDICT:
-	case ISN_COMPAREFLOAT:
-	case ISN_COMPAREFUNC:
-	case ISN_COMPARELIST:
-	case ISN_COMPARENR:
-	case ISN_COMPARESPECIAL:
-	case ISN_COMPARESTRING:
-	case ISN_CONCAT:
-	case ISN_COND2BOOL:
-	case ISN_DEBUG:
-	case ISN_DROP:
-	case ISN_ECHO:
-	case ISN_ECHOCONSOLE:
-	case ISN_ECHOERR:
-	case ISN_ECHOMSG:
-	case ISN_ENDTRY:
-	case ISN_EXECCONCAT:
-	case ISN_EXECUTE:
-	case ISN_FINALLY:
-	case ISN_FINISH:
-	case ISN_FOR:
-	case ISN_GETITEM:
-	case ISN_JUMP:
-	case ISN_JUMP_IF_ARG_SET:
-	case ISN_LISTAPPEND:
-	case ISN_LISTINDEX:
-	case ISN_LISTSLICE:
-	case ISN_LOAD:
-	case ISN_LOADBDICT:
-	case ISN_LOADGDICT:
-	case ISN_LOADOUTER:
-	case ISN_LOADREG:
-	case ISN_LOADTDICT:
-	case ISN_LOADV:
-	case ISN_LOADWDICT:
-	case ISN_LOCKCONST:
-	case ISN_MEMBER:
-	case ISN_NEGATENR:
-	case ISN_NEWDICT:
-	case ISN_NEWLIST:
-	case ISN_OPANY:
-	case ISN_OPFLOAT:
-	case ISN_OPNR:
-	case ISN_PCALL:
-	case ISN_PCALL_END:
-	case ISN_PROF_END:
-	case ISN_PROF_START:
-	case ISN_PUSHBOOL:
-	case ISN_PUSHF:
-	case ISN_PUSHNR:
-	case ISN_PUSHSPEC:
-	case ISN_PUT:
-	case ISN_REDIREND:
-	case ISN_REDIRSTART:
-	case ISN_RETURN:
-	case ISN_RETURN_VOID:
-	case ISN_SHUFFLE:
-	case ISN_SLICE:
-	case ISN_STORE:
-	case ISN_STOREINDEX:
-	case ISN_STORENR:
-	case ISN_STOREOUTER:
-	case ISN_STORERANGE:
-	case ISN_STOREREG:
-	case ISN_STOREV:
-	case ISN_STRINDEX:
-	case ISN_STRSLICE:
-	case ISN_THROW:
-	case ISN_TRYCONT:
-	case ISN_UNLETINDEX:
-	case ISN_UNLETRANGE:
-	case ISN_UNPACK:
-	case ISN_USEDICT:
-	    // nothing allocated
-	    break;
-    }
-}
-
 /*
  * Free all instructions for "dfunc" except df_name.
  */
