diff --git a/src/vim9cmds.c b/src/vim9cmds.c
new file mode 100644
index 0000000..fe9ead2
--- /dev/null
+++ b/src/vim9cmds.c
@@ -0,0 +1,2274 @@
+/* vi:set ts=8 sts=4 sw=4 noet:
+ *
+ * VIM - Vi IMproved	by Bram Moolenaar
+ *
+ * Do ":help uganda"  in Vim to read copying and usage conditions.
+ * Do ":help credits" in Vim to see a list of people who contributed.
+ * See README.txt for an overview of the Vim source code.
+ */
+
+/*
+ * vim9cmds.c: Dealing with commands of a compiled function
+ */
+
+#define USING_FLOAT_STUFF
+#include "vim.h"
+
+#if defined(FEAT_EVAL) || defined(PROTO)
+
+// When not generating protos this is included in proto.h
+#ifdef PROTO
+# include "vim9.h"
+#endif
+
+/*
+ * 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;
+}
+/*
+ * 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.
+ */
+    void
+free_locals(cctx_T *cctx)
+{
+    unwind_locals(cctx, 0);
+    ga_clear(&cctx->ctx_locals);
+}
+
+
+/*
+ * 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".
+ */
+    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.
+ */
+    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);
+}
+
+    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;
+}
+
+/*
+ * 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:
+ */
+    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;
+}
+
+    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;
+}
+
+    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;
+}
+
+    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"
+ */
+    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"
+ */
+    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:
+ *
+ */
+    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"
+ */
+    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"
+ */
+    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"
+ */
+    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
+ */
+    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
+ */
+    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
+ */
+    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}".
+ */
+    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;
+}
+
+    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;
+}
+
+    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}"
+ */
+    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;
+}
+
+    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"
+ */
+    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}
+ */
+    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.
+ */
+    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
+ */
+    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/
+ */
+    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);
+}
+
+    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);
+}
+
+#if defined(FEAT_QUICKFIX) || defined(PROTO)
+    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
+
+/*
+ * Compile "return [expr]".
+ * When "legacy" is TRUE evaluate [expr] with legacy syntax
+ */
+    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);
+}
+
+/*
+ * 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;
+}
+
+
+#endif  // defined(FEAT_EVAL)
