xref: /vim-8.2.3635/src/vim9compile.c (revision ebd211c8)
1 /* vi:set ts=8 sts=4 sw=4 noet:
2  *
3  * VIM - Vi IMproved	by Bram Moolenaar
4  *
5  * Do ":help uganda"  in Vim to read copying and usage conditions.
6  * Do ":help credits" in Vim to see a list of people who contributed.
7  * See README.txt for an overview of the Vim source code.
8  */
9 
10 /*
11  * vim9compile.c: :def and dealing with instructions
12  */
13 
14 #define USING_FLOAT_STUFF
15 #include "vim.h"
16 
17 #if defined(FEAT_EVAL) || defined(PROTO)
18 
19 #ifdef VMS
20 # include <float.h>
21 #endif
22 
23 #define DEFINE_VIM9_GLOBALS
24 #include "vim9.h"
25 
26 // values for ctx_skip
27 typedef enum {
28     SKIP_NOT,		// condition is a constant, produce code
29     SKIP_YES,		// condition is a constant, do NOT produce code
30     SKIP_UNKNOWN	// condition is not a constant, produce code
31 } skip_T;
32 
33 /*
34  * Chain of jump instructions where the end label needs to be set.
35  */
36 typedef struct endlabel_S endlabel_T;
37 struct endlabel_S {
38     endlabel_T	*el_next;	    // chain end_label locations
39     int		el_end_label;	    // instruction idx where to set end
40 };
41 
42 /*
43  * info specific for the scope of :if / elseif / else
44  */
45 typedef struct {
46     int		is_seen_else;
47     int		is_seen_skip_not;   // a block was unconditionally executed
48     int		is_had_return;	    // every block ends in :return
49     int		is_if_label;	    // instruction idx at IF or ELSEIF
50     endlabel_T	*is_end_label;	    // instructions to set end label
51 } ifscope_T;
52 
53 /*
54  * info specific for the scope of :while
55  */
56 typedef struct {
57     int		ws_top_label;	    // instruction idx at WHILE
58     endlabel_T	*ws_end_label;	    // instructions to set end
59 } whilescope_T;
60 
61 /*
62  * info specific for the scope of :for
63  */
64 typedef struct {
65     int		fs_top_label;	    // instruction idx at FOR
66     endlabel_T	*fs_end_label;	    // break instructions
67 } forscope_T;
68 
69 /*
70  * info specific for the scope of :try
71  */
72 typedef struct {
73     int		ts_try_label;	    // instruction idx at TRY
74     endlabel_T	*ts_end_label;	    // jump to :finally or :endtry
75     int		ts_catch_label;	    // instruction idx of last CATCH
76     int		ts_caught_all;	    // "catch" without argument encountered
77 } tryscope_T;
78 
79 typedef enum {
80     NO_SCOPE,
81     IF_SCOPE,
82     WHILE_SCOPE,
83     FOR_SCOPE,
84     TRY_SCOPE,
85     BLOCK_SCOPE
86 } scopetype_T;
87 
88 /*
89  * Info for one scope, pointed to by "ctx_scope".
90  */
91 typedef struct scope_S scope_T;
92 struct scope_S {
93     scope_T	*se_outer;	    // scope containing this one
94     scopetype_T se_type;
95     int		se_local_count;	    // ctx_locals.ga_len before scope
96     skip_T	se_skip_save;	    // ctx_skip before the block
97     union {
98 	ifscope_T	se_if;
99 	whilescope_T	se_while;
100 	forscope_T	se_for;
101 	tryscope_T	se_try;
102     } se_u;
103 };
104 
105 /*
106  * Entry for "ctx_locals".  Used for arguments and local variables.
107  */
108 typedef struct {
109     char_u	*lv_name;
110     type_T	*lv_type;
111     int		lv_idx;		// index of the variable on the stack
112     int		lv_from_outer;	// nesting level, using ctx_outer scope
113     int		lv_const;	// when TRUE cannot be assigned to
114     int		lv_arg;		// when TRUE this is an argument
115 } lvar_T;
116 
117 /*
118  * Context for compiling lines of Vim script.
119  * Stores info about the local variables and condition stack.
120  */
121 struct cctx_S {
122     ufunc_T	*ctx_ufunc;	    // current function
123     int		ctx_lnum;	    // line number in current function
124     char_u	*ctx_line_start;    // start of current line or NULL
125     garray_T	ctx_instr;	    // generated instructions
126 
127     int		ctx_profiling;	    // when TRUE generate ISN_PROF_START
128 
129     garray_T	ctx_locals;	    // currently visible local variables
130     int		ctx_locals_count;   // total number of local variables
131 
132     int		ctx_has_closure;    // set to one if a closures was created in
133 				    // the function
134 
135     garray_T	ctx_imports;	    // imported items
136 
137     skip_T	ctx_skip;
138     scope_T	*ctx_scope;	    // current scope, NULL at toplevel
139     int		ctx_had_return;	    // last seen statement was "return"
140 
141     cctx_T	*ctx_outer;	    // outer scope for lambda or nested
142 				    // function
143     int		ctx_outer_used;	    // var in ctx_outer was used
144 
145     garray_T	ctx_type_stack;	    // type of each item on the stack
146     garray_T	*ctx_type_list;	    // list of pointers to allocated types
147 
148     int		ctx_has_cmdmod;	    // ISN_CMDMOD was generated
149 };
150 
151 static void delete_def_function_contents(dfunc_T *dfunc, int mark_deleted);
152 
153 /*
154  * Lookup variable "name" in the local scope and return it in "lvar".
155  * "lvar->lv_from_outer" is incremented accordingly.
156  * If "lvar" is NULL only check if the variable can be found.
157  * Return FAIL if not found.
158  */
159     static int
160 lookup_local(char_u *name, size_t len, lvar_T *lvar, cctx_T *cctx)
161 {
162     int	    idx;
163     lvar_T  *lvp;
164 
165     if (len == 0)
166 	return FAIL;
167 
168     // Find local in current function scope.
169     for (idx = 0; idx < cctx->ctx_locals.ga_len; ++idx)
170     {
171 	lvp = ((lvar_T *)cctx->ctx_locals.ga_data) + idx;
172 	if (STRNCMP(name, lvp->lv_name, len) == 0
173 					       && STRLEN(lvp->lv_name) == len)
174 	{
175 	    if (lvar != NULL)
176 	    {
177 		*lvar = *lvp;
178 		lvar->lv_from_outer = 0;
179 	    }
180 	    return OK;
181 	}
182     }
183 
184     // Find local in outer function scope.
185     if (cctx->ctx_outer != NULL)
186     {
187 	if (lookup_local(name, len, lvar, cctx->ctx_outer) == OK)
188 	{
189 	    if (lvar != NULL)
190 	    {
191 		cctx->ctx_outer_used = TRUE;
192 		++lvar->lv_from_outer;
193 	    }
194 	    return OK;
195 	}
196     }
197 
198     return FAIL;
199 }
200 
201 /*
202  * Lookup an argument in the current function and an enclosing function.
203  * Returns the argument index in "idxp"
204  * Returns the argument type in "type"
205  * Sets "gen_load_outer" to TRUE if found in outer scope.
206  * Returns OK when found, FAIL otherwise.
207  */
208     static int
209 arg_exists(
210 	char_u	*name,
211 	size_t	len,
212 	int	*idxp,
213 	type_T	**type,
214 	int	*gen_load_outer,
215 	cctx_T	*cctx)
216 {
217     int	    idx;
218     char_u  *va_name;
219 
220     if (len == 0)
221 	return FAIL;
222     for (idx = 0; idx < cctx->ctx_ufunc->uf_args.ga_len; ++idx)
223     {
224 	char_u *arg = FUNCARG(cctx->ctx_ufunc, idx);
225 
226 	if (STRNCMP(name, arg, len) == 0 && arg[len] == NUL)
227 	{
228 	    if (idxp != NULL)
229 	    {
230 		// Arguments are located above the frame pointer.  One further
231 		// if there is a vararg argument
232 		*idxp = idx - (cctx->ctx_ufunc->uf_args.ga_len
233 							    + STACK_FRAME_SIZE)
234 			      + (cctx->ctx_ufunc->uf_va_name != NULL ? -1 : 0);
235 
236 		if (cctx->ctx_ufunc->uf_arg_types != NULL)
237 		    *type = cctx->ctx_ufunc->uf_arg_types[idx];
238 		else
239 		    *type = &t_any;
240 	    }
241 	    return OK;
242 	}
243     }
244 
245     va_name = cctx->ctx_ufunc->uf_va_name;
246     if (va_name != NULL
247 		    && STRNCMP(name, va_name, len) == 0 && va_name[len] == NUL)
248     {
249 	if (idxp != NULL)
250 	{
251 	    // varargs is always the last argument
252 	    *idxp = -STACK_FRAME_SIZE - 1;
253 	    *type = cctx->ctx_ufunc->uf_va_type;
254 	}
255 	return OK;
256     }
257 
258     if (cctx->ctx_outer != NULL)
259     {
260 	// Lookup the name for an argument of the outer function.
261 	if (arg_exists(name, len, idxp, type, gen_load_outer, cctx->ctx_outer)
262 									 == OK)
263 	{
264 	    ++*gen_load_outer;
265 	    return OK;
266 	}
267     }
268 
269     return FAIL;
270 }
271 
272 /*
273  * Lookup a script-local variable in the current script, possibly defined in a
274  * block that contains the function "cctx->ctx_ufunc".
275  * "cctx" is NULL at the script level.
276  * if "len" is <= 0 "name" must be NUL terminated.
277  * Return NULL when not found.
278  */
279     static sallvar_T *
280 find_script_var(char_u *name, size_t len, cctx_T *cctx)
281 {
282     scriptitem_T    *si = SCRIPT_ITEM(current_sctx.sc_sid);
283     hashitem_T	    *hi;
284     int		    cc;
285     sallvar_T	    *sav;
286     ufunc_T	    *ufunc;
287 
288     // Find the list of all script variables with the right name.
289     if (len > 0)
290     {
291 	cc = name[len];
292 	name[len] = NUL;
293     }
294     hi = hash_find(&si->sn_all_vars.dv_hashtab, name);
295     if (len > 0)
296 	name[len] = cc;
297     if (HASHITEM_EMPTY(hi))
298 	return NULL;
299 
300     sav = HI2SAV(hi);
301     if (sav->sav_block_id == 0 || cctx == NULL)
302 	// variable defined in the script scope or not in a function.
303 	return sav;
304 
305     // Go over the variables with this name and find one that was visible
306     // from the function.
307     ufunc = cctx->ctx_ufunc;
308     while (sav != NULL)
309     {
310 	int idx;
311 
312 	// Go over the blocks that this function was defined in.  If the
313 	// variable block ID matches it was visible to the function.
314 	for (idx = 0; idx < ufunc->uf_block_depth; ++idx)
315 	    if (ufunc->uf_block_ids[idx] == sav->sav_block_id)
316 		return sav;
317 	sav = sav->sav_next;
318     }
319 
320     return NULL;
321 }
322 
323 /*
324  * Return TRUE if the script context is Vim9 script.
325  */
326     static int
327 script_is_vim9()
328 {
329     return SCRIPT_ITEM(current_sctx.sc_sid)->sn_version == SCRIPT_VERSION_VIM9;
330 }
331 
332 /*
333  * Lookup a variable (without s: prefix) in the current script.
334  * If "vim9script" is TRUE the script must be Vim9 script.  Used for "var"
335  * without "s:".
336  * "cctx" is NULL at the script level.
337  * Returns OK or FAIL.
338  */
339     static int
340 script_var_exists(char_u *name, size_t len, int vim9script, cctx_T *cctx)
341 {
342     int		    is_vim9_script;
343 
344     if (current_sctx.sc_sid <= 0)
345 	return FAIL;
346     is_vim9_script = script_is_vim9();
347     if (vim9script && !is_vim9_script)
348 	return FAIL;
349     if (is_vim9_script)
350     {
351 	// Check script variables that were visible where the function was
352 	// defined.
353 	if (find_script_var(name, len, cctx) != NULL)
354 	    return OK;
355     }
356     else
357     {
358 	hashtab_T	*ht = &SCRIPT_VARS(current_sctx.sc_sid);
359 	dictitem_T	*di;
360 	int		cc;
361 
362 	// Check script variables that are currently visible
363 	cc = name[len];
364 	name[len] = NUL;
365 	di = find_var_in_ht(ht, 0, name, TRUE);
366 	name[len] = cc;
367 	if (di != NULL)
368 	    return OK;
369     }
370 
371     return FAIL;
372 }
373 
374 /*
375  * Check if "p[len]" is already defined, either in script "import_sid" or in
376  * compilation context "cctx".  "cctx" is NULL at the script level.
377  * Does not check the global namespace.
378  * Return FAIL and give an error if it defined.
379  */
380     int
381 check_defined(char_u *p, size_t len, cctx_T *cctx)
382 {
383     int		c = p[len];
384     ufunc_T	*ufunc = NULL;
385 
386     p[len] = NUL;
387     if (script_var_exists(p, len, FALSE, cctx) == OK
388 	    || (cctx != NULL
389 		&& (lookup_local(p, len, NULL, cctx) == OK
390 		    || arg_exists(p, len, NULL, NULL, NULL, cctx) == OK))
391 	    || find_imported(p, len, cctx) != NULL
392 	    || (ufunc = find_func_even_dead(p, FALSE, cctx)) != NULL)
393     {
394 	// A local or script-local function can shadow a global function.
395 	if (ufunc == NULL || !func_is_global(ufunc)
396 		|| (p[0] == 'g' && p[1] == ':'))
397 	{
398 	    p[len] = c;
399 	    semsg(_(e_name_already_defined_str), p);
400 	    return FAIL;
401 	}
402     }
403     p[len] = c;
404     return OK;
405 }
406 
407 
408 /////////////////////////////////////////////////////////////////////
409 // Following generate_ functions expect the caller to call ga_grow().
410 
411 #define RETURN_NULL_IF_SKIP(cctx) if (cctx->ctx_skip == SKIP_YES) return NULL
412 #define RETURN_OK_IF_SKIP(cctx) if (cctx->ctx_skip == SKIP_YES) return OK
413 
414 /*
415  * Generate an instruction without arguments.
416  * Returns a pointer to the new instruction, NULL if failed.
417  */
418     static isn_T *
419 generate_instr(cctx_T *cctx, isntype_T isn_type)
420 {
421     garray_T	*instr = &cctx->ctx_instr;
422     isn_T	*isn;
423 
424     RETURN_NULL_IF_SKIP(cctx);
425     if (ga_grow(instr, 1) == FAIL)
426 	return NULL;
427     isn = ((isn_T *)instr->ga_data) + instr->ga_len;
428     isn->isn_type = isn_type;
429     isn->isn_lnum = cctx->ctx_lnum + 1;
430     ++instr->ga_len;
431 
432     return isn;
433 }
434 
435 /*
436  * Generate an instruction without arguments.
437  * "drop" will be removed from the stack.
438  * Returns a pointer to the new instruction, NULL if failed.
439  */
440     static isn_T *
441 generate_instr_drop(cctx_T *cctx, isntype_T isn_type, int drop)
442 {
443     garray_T	*stack = &cctx->ctx_type_stack;
444 
445     RETURN_NULL_IF_SKIP(cctx);
446     stack->ga_len -= drop;
447     return generate_instr(cctx, isn_type);
448 }
449 
450 /*
451  * Generate instruction "isn_type" and put "type" on the type stack.
452  */
453     static isn_T *
454 generate_instr_type(cctx_T *cctx, isntype_T isn_type, type_T *type)
455 {
456     isn_T	*isn;
457     garray_T	*stack = &cctx->ctx_type_stack;
458 
459     if ((isn = generate_instr(cctx, isn_type)) == NULL)
460 	return NULL;
461 
462     if (ga_grow(stack, 1) == FAIL)
463 	return NULL;
464     ((type_T **)stack->ga_data)[stack->ga_len] = type == NULL ? &t_any : type;
465     ++stack->ga_len;
466 
467     return isn;
468 }
469 
470 /*
471  * If type at "offset" isn't already VAR_STRING then generate ISN_2STRING.
472  * But only for simple types.
473  */
474     static int
475 may_generate_2STRING(int offset, cctx_T *cctx)
476 {
477     isn_T	*isn;
478     isntype_T	isntype = ISN_2STRING;
479     garray_T	*stack = &cctx->ctx_type_stack;
480     type_T	**type;
481 
482     RETURN_OK_IF_SKIP(cctx);
483     type = ((type_T **)stack->ga_data) + stack->ga_len + offset;
484     switch ((*type)->tt_type)
485     {
486 	// nothing to be done
487 	case VAR_STRING: return OK;
488 
489 	// conversion possible
490 	case VAR_SPECIAL:
491 	case VAR_BOOL:
492 	case VAR_NUMBER:
493 	case VAR_FLOAT:
494 			 break;
495 
496 	// conversion possible (with runtime check)
497 	case VAR_ANY:
498 	case VAR_UNKNOWN:
499 			 isntype = ISN_2STRING_ANY;
500 			 break;
501 
502 	// conversion not possible
503 	case VAR_VOID:
504 	case VAR_BLOB:
505 	case VAR_FUNC:
506 	case VAR_PARTIAL:
507 	case VAR_LIST:
508 	case VAR_DICT:
509 	case VAR_JOB:
510 	case VAR_CHANNEL:
511 			 to_string_error((*type)->tt_type);
512 			 return FAIL;
513     }
514 
515     *type = &t_string;
516     if ((isn = generate_instr(cctx, isntype)) == NULL)
517 	return FAIL;
518     isn->isn_arg.number = offset;
519 
520     return OK;
521 }
522 
523     static int
524 check_number_or_float(vartype_T type1, vartype_T type2, char_u *op)
525 {
526     if (!((type1 == VAR_NUMBER || type1 == VAR_FLOAT || type1 == VAR_ANY)
527 	    && (type2 == VAR_NUMBER || type2 == VAR_FLOAT
528 							 || type2 == VAR_ANY)))
529     {
530 	if (*op == '+')
531 	    emsg(_(e_wrong_argument_type_for_plus));
532 	else
533 	    semsg(_(e_char_requires_number_or_float_arguments), *op);
534 	return FAIL;
535     }
536     return OK;
537 }
538 
539     static int
540 generate_add_instr(
541 	cctx_T *cctx,
542 	vartype_T vartype,
543 	type_T *type1,
544 	type_T *type2)
545 {
546     garray_T	*stack = &cctx->ctx_type_stack;
547     isn_T	*isn = generate_instr_drop(cctx,
548 		      vartype == VAR_NUMBER ? ISN_OPNR
549 		    : vartype == VAR_LIST ? ISN_ADDLIST
550 		    : vartype == VAR_BLOB ? ISN_ADDBLOB
551 #ifdef FEAT_FLOAT
552 		    : vartype == VAR_FLOAT ? ISN_OPFLOAT
553 #endif
554 		    : ISN_OPANY, 1);
555 
556     if (vartype != VAR_LIST && vartype != VAR_BLOB
557 	    && type1->tt_type != VAR_ANY
558 	    && type2->tt_type != VAR_ANY
559 	    && check_number_or_float(
560 			type1->tt_type, type2->tt_type, (char_u *)"+") == FAIL)
561 	return FAIL;
562 
563     if (isn != NULL)
564 	isn->isn_arg.op.op_type = EXPR_ADD;
565 
566     // When concatenating two lists with different member types the member type
567     // becomes "any".
568     if (vartype == VAR_LIST
569 	    && type1->tt_type == VAR_LIST && type2->tt_type == VAR_LIST
570 	    && type1->tt_member != type2->tt_member)
571 	(((type_T **)stack->ga_data)[stack->ga_len - 1]) = &t_list_any;
572 
573     return isn == NULL ? FAIL : OK;
574 }
575 
576 /*
577  * Get the type to use for an instruction for an operation on "type1" and
578  * "type2".  If they are matching use a type-specific instruction. Otherwise
579  * fall back to runtime type checking.
580  */
581     static vartype_T
582 operator_type(type_T *type1, type_T *type2)
583 {
584     if (type1->tt_type == type2->tt_type
585 	    && (type1->tt_type == VAR_NUMBER
586 		|| type1->tt_type == VAR_LIST
587 #ifdef FEAT_FLOAT
588 		|| type1->tt_type == VAR_FLOAT
589 #endif
590 		|| type1->tt_type == VAR_BLOB))
591 	return type1->tt_type;
592     return VAR_ANY;
593 }
594 
595 /*
596  * Generate an instruction with two arguments.  The instruction depends on the
597  * type of the arguments.
598  */
599     static int
600 generate_two_op(cctx_T *cctx, char_u *op)
601 {
602     garray_T	*stack = &cctx->ctx_type_stack;
603     type_T	*type1;
604     type_T	*type2;
605     vartype_T	vartype;
606     isn_T	*isn;
607 
608     RETURN_OK_IF_SKIP(cctx);
609 
610     // Get the known type of the two items on the stack.
611     type1 = ((type_T **)stack->ga_data)[stack->ga_len - 2];
612     type2 = ((type_T **)stack->ga_data)[stack->ga_len - 1];
613     vartype = operator_type(type1, type2);
614 
615     switch (*op)
616     {
617 	case '+':
618 		  if (generate_add_instr(cctx, vartype, type1, type2) == FAIL)
619 		      return FAIL;
620 		  break;
621 
622 	case '-':
623 	case '*':
624 	case '/': if (check_number_or_float(type1->tt_type, type2->tt_type,
625 								   op) == FAIL)
626 		      return FAIL;
627 		  if (vartype == VAR_NUMBER)
628 		      isn = generate_instr_drop(cctx, ISN_OPNR, 1);
629 #ifdef FEAT_FLOAT
630 		  else if (vartype == VAR_FLOAT)
631 		      isn = generate_instr_drop(cctx, ISN_OPFLOAT, 1);
632 #endif
633 		  else
634 		      isn = generate_instr_drop(cctx, ISN_OPANY, 1);
635 		  if (isn != NULL)
636 		      isn->isn_arg.op.op_type = *op == '*'
637 				 ? EXPR_MULT : *op == '/'? EXPR_DIV : EXPR_SUB;
638 		  break;
639 
640 	case '%': if ((type1->tt_type != VAR_ANY
641 					       && type1->tt_type != VAR_NUMBER)
642 			  || (type2->tt_type != VAR_ANY
643 					      && type2->tt_type != VAR_NUMBER))
644 		  {
645 		      emsg(_(e_percent_requires_number_arguments));
646 		      return FAIL;
647 		  }
648 		  isn = generate_instr_drop(cctx,
649 			      vartype == VAR_NUMBER ? ISN_OPNR : ISN_OPANY, 1);
650 		  if (isn != NULL)
651 		      isn->isn_arg.op.op_type = EXPR_REM;
652 		  break;
653     }
654 
655     // correct type of result
656     if (vartype == VAR_ANY)
657     {
658 	type_T *type = &t_any;
659 
660 #ifdef FEAT_FLOAT
661 	// float+number and number+float results in float
662 	if ((type1->tt_type == VAR_NUMBER || type1->tt_type == VAR_FLOAT)
663 		&& (type2->tt_type == VAR_NUMBER || type2->tt_type == VAR_FLOAT))
664 	    type = &t_float;
665 #endif
666 	((type_T **)stack->ga_data)[stack->ga_len - 1] = type;
667     }
668 
669     return OK;
670 }
671 
672 /*
673  * Get the instruction to use for comparing "type1" with "type2"
674  * Return ISN_DROP when failed.
675  */
676     static isntype_T
677 get_compare_isn(exprtype_T exprtype, vartype_T type1, vartype_T type2)
678 {
679     isntype_T	isntype = ISN_DROP;
680 
681     if (type1 == VAR_UNKNOWN)
682 	type1 = VAR_ANY;
683     if (type2 == VAR_UNKNOWN)
684 	type2 = VAR_ANY;
685 
686     if (type1 == type2)
687     {
688 	switch (type1)
689 	{
690 	    case VAR_BOOL: isntype = ISN_COMPAREBOOL; break;
691 	    case VAR_SPECIAL: isntype = ISN_COMPARESPECIAL; break;
692 	    case VAR_NUMBER: isntype = ISN_COMPARENR; break;
693 	    case VAR_FLOAT: isntype = ISN_COMPAREFLOAT; break;
694 	    case VAR_STRING: isntype = ISN_COMPARESTRING; break;
695 	    case VAR_BLOB: isntype = ISN_COMPAREBLOB; break;
696 	    case VAR_LIST: isntype = ISN_COMPARELIST; break;
697 	    case VAR_DICT: isntype = ISN_COMPAREDICT; break;
698 	    case VAR_FUNC: isntype = ISN_COMPAREFUNC; break;
699 	    default: isntype = ISN_COMPAREANY; break;
700 	}
701     }
702     else if (type1 == VAR_ANY || type2 == VAR_ANY
703 	    || ((type1 == VAR_NUMBER || type1 == VAR_FLOAT)
704 	      && (type2 == VAR_NUMBER || type2 ==VAR_FLOAT)))
705 	isntype = ISN_COMPAREANY;
706 
707     if ((exprtype == EXPR_IS || exprtype == EXPR_ISNOT)
708 	    && (isntype == ISN_COMPAREBOOL
709 	    || isntype == ISN_COMPARESPECIAL
710 	    || isntype == ISN_COMPARENR
711 	    || isntype == ISN_COMPAREFLOAT))
712     {
713 	semsg(_(e_cannot_use_str_with_str),
714 		exprtype == EXPR_IS ? "is" : "isnot" , vartype_name(type1));
715 	return ISN_DROP;
716     }
717     if (isntype == ISN_DROP
718 	    || ((exprtype != EXPR_EQUAL && exprtype != EXPR_NEQUAL
719 		    && (type1 == VAR_BOOL || type1 == VAR_SPECIAL
720 		       || type2 == VAR_BOOL || type2 == VAR_SPECIAL)))
721 	    || ((exprtype != EXPR_EQUAL && exprtype != EXPR_NEQUAL
722 				 && exprtype != EXPR_IS && exprtype != EXPR_ISNOT
723 		    && (type1 == VAR_BLOB || type2 == VAR_BLOB
724 			|| type1 == VAR_LIST || type2 == VAR_LIST))))
725     {
726 	semsg(_(e_cannot_compare_str_with_str),
727 		vartype_name(type1), vartype_name(type2));
728 	return ISN_DROP;
729     }
730     return isntype;
731 }
732 
733     int
734 check_compare_types(exprtype_T type, typval_T *tv1, typval_T *tv2)
735 {
736     if (get_compare_isn(type, tv1->v_type, tv2->v_type) == ISN_DROP)
737 	return FAIL;
738     return OK;
739 }
740 
741 /*
742  * Generate an ISN_COMPARE* instruction with a boolean result.
743  */
744     static int
745 generate_COMPARE(cctx_T *cctx, exprtype_T exprtype, int ic)
746 {
747     isntype_T	isntype;
748     isn_T	*isn;
749     garray_T	*stack = &cctx->ctx_type_stack;
750     vartype_T	type1;
751     vartype_T	type2;
752 
753     RETURN_OK_IF_SKIP(cctx);
754 
755     // Get the known type of the two items on the stack.  If they are matching
756     // use a type-specific instruction. Otherwise fall back to runtime type
757     // checking.
758     type1 = ((type_T **)stack->ga_data)[stack->ga_len - 2]->tt_type;
759     type2 = ((type_T **)stack->ga_data)[stack->ga_len - 1]->tt_type;
760     isntype = get_compare_isn(exprtype, type1, type2);
761     if (isntype == ISN_DROP)
762 	return FAIL;
763 
764     if ((isn = generate_instr(cctx, isntype)) == NULL)
765 	return FAIL;
766     isn->isn_arg.op.op_type = exprtype;
767     isn->isn_arg.op.op_ic = ic;
768 
769     // takes two arguments, puts one bool back
770     if (stack->ga_len >= 2)
771     {
772 	--stack->ga_len;
773 	((type_T **)stack->ga_data)[stack->ga_len - 1] = &t_bool;
774     }
775 
776     return OK;
777 }
778 
779 /*
780  * Generate an ISN_2BOOL instruction.
781  */
782     static int
783 generate_2BOOL(cctx_T *cctx, int invert)
784 {
785     isn_T	*isn;
786     garray_T	*stack = &cctx->ctx_type_stack;
787 
788     RETURN_OK_IF_SKIP(cctx);
789     if ((isn = generate_instr(cctx, ISN_2BOOL)) == NULL)
790 	return FAIL;
791     isn->isn_arg.number = invert;
792 
793     // type becomes bool
794     ((type_T **)stack->ga_data)[stack->ga_len - 1] = &t_bool;
795 
796     return OK;
797 }
798 
799 /*
800  * Generate an ISN_COND2BOOL instruction.
801  */
802     static int
803 generate_COND2BOOL(cctx_T *cctx)
804 {
805     isn_T	*isn;
806     garray_T	*stack = &cctx->ctx_type_stack;
807 
808     RETURN_OK_IF_SKIP(cctx);
809     if ((isn = generate_instr(cctx, ISN_COND2BOOL)) == NULL)
810 	return FAIL;
811 
812     // type becomes bool
813     ((type_T **)stack->ga_data)[stack->ga_len - 1] = &t_bool;
814 
815     return OK;
816 }
817 
818     static int
819 generate_TYPECHECK(
820 	cctx_T	    *cctx,
821 	type_T	    *expected,
822 	int	    offset,
823 	int	    argidx)
824 {
825     isn_T	*isn;
826     garray_T	*stack = &cctx->ctx_type_stack;
827 
828     RETURN_OK_IF_SKIP(cctx);
829     if ((isn = generate_instr(cctx, ISN_CHECKTYPE)) == NULL)
830 	return FAIL;
831     isn->isn_arg.type.ct_type = alloc_type(expected);
832     isn->isn_arg.type.ct_off = (int8_T)offset;
833     isn->isn_arg.type.ct_arg_idx = (int8_T)argidx;
834 
835     // type becomes expected
836     ((type_T **)stack->ga_data)[stack->ga_len + offset] = expected;
837 
838     return OK;
839 }
840 
841     static int
842 generate_SETTYPE(
843 	cctx_T	    *cctx,
844 	type_T	    *expected)
845 {
846     isn_T	*isn;
847 
848     RETURN_OK_IF_SKIP(cctx);
849     if ((isn = generate_instr(cctx, ISN_SETTYPE)) == NULL)
850 	return FAIL;
851     isn->isn_arg.type.ct_type = alloc_type(expected);
852     return OK;
853 }
854 
855 /*
856  * Return TRUE if "actual" could be "expected" and a runtime typecheck is to be
857  * used.  Return FALSE if the types will never match.
858  */
859     int
860 use_typecheck(type_T *actual, type_T *expected)
861 {
862     if (actual->tt_type == VAR_ANY
863 	    || actual->tt_type == VAR_UNKNOWN
864 	    || (actual->tt_type == VAR_FUNC
865 		&& (expected->tt_type == VAR_FUNC
866 					   || expected->tt_type == VAR_PARTIAL)
867 		&& (actual->tt_member == &t_any || actual->tt_argcount < 0)
868 		&& ((actual->tt_member == &t_void)
869 					 == (expected->tt_member == &t_void))))
870 	return TRUE;
871     if ((actual->tt_type == VAR_LIST || actual->tt_type == VAR_DICT)
872 				       && actual->tt_type == expected->tt_type)
873 	// This takes care of a nested list or dict.
874 	return use_typecheck(actual->tt_member, expected->tt_member);
875     return FALSE;
876 }
877 
878 /*
879  * Check that
880  * - "actual" matches "expected" type or
881  * - "actual" is a type that can be "expected" type: add a runtime check; or
882  * - return FAIL.
883  * If "actual_is_const" is TRUE then the type won't change at runtime, do not
884  * generate a TYPECHECK.
885  */
886     int
887 need_type(
888 	type_T	*actual,
889 	type_T	*expected,
890 	int	offset,
891 	int	arg_idx,
892 	cctx_T	*cctx,
893 	int	silent,
894 	int	actual_is_const)
895 {
896     if (expected == &t_bool && actual != &t_bool
897 					&& (actual->tt_flags & TTFLAG_BOOL_OK))
898     {
899 	// Using "0", "1" or the result of an expression with "&&" or "||" as a
900 	// boolean is OK but requires a conversion.
901 	generate_2BOOL(cctx, FALSE);
902 	return OK;
903     }
904 
905     if (check_type(expected, actual, FALSE, arg_idx) == OK)
906 	return OK;
907 
908     // If the actual type can be the expected type add a runtime check.
909     // If it's a constant a runtime check makes no sense.
910     if (!actual_is_const && use_typecheck(actual, expected))
911     {
912 	generate_TYPECHECK(cctx, expected, offset, arg_idx);
913 	return OK;
914     }
915 
916     if (!silent)
917 	arg_type_mismatch(expected, actual, arg_idx);
918     return FAIL;
919 }
920 
921 /*
922  * Check that the top of the type stack has a type that can be used as a
923  * condition.  Give an error and return FAIL if not.
924  */
925     static int
926 bool_on_stack(cctx_T *cctx)
927 {
928     garray_T	*stack = &cctx->ctx_type_stack;
929     type_T	*type;
930 
931     type = ((type_T **)stack->ga_data)[stack->ga_len - 1];
932     if (type == &t_bool)
933 	return OK;
934 
935     if (type == &t_any || type == &t_number)
936 	// Number 0 and 1 are OK to use as a bool.  "any" could also be a bool.
937 	// This requires a runtime type check.
938 	return generate_COND2BOOL(cctx);
939 
940     return need_type(type, &t_bool, -1, 0, cctx, FALSE, FALSE);
941 }
942 
943 /*
944  * Generate an ISN_PUSHNR instruction.
945  */
946     static int
947 generate_PUSHNR(cctx_T *cctx, varnumber_T number)
948 {
949     isn_T	*isn;
950     garray_T	*stack = &cctx->ctx_type_stack;
951 
952     RETURN_OK_IF_SKIP(cctx);
953     if ((isn = generate_instr_type(cctx, ISN_PUSHNR, &t_number)) == NULL)
954 	return FAIL;
955     isn->isn_arg.number = number;
956 
957     if (number == 0 || number == 1)
958 	// A 0 or 1 number can also be used as a bool.
959 	((type_T **)stack->ga_data)[stack->ga_len - 1] = &t_number_bool;
960     return OK;
961 }
962 
963 /*
964  * Generate an ISN_PUSHBOOL instruction.
965  */
966     static int
967 generate_PUSHBOOL(cctx_T *cctx, varnumber_T number)
968 {
969     isn_T	*isn;
970 
971     RETURN_OK_IF_SKIP(cctx);
972     if ((isn = generate_instr_type(cctx, ISN_PUSHBOOL, &t_bool)) == NULL)
973 	return FAIL;
974     isn->isn_arg.number = number;
975 
976     return OK;
977 }
978 
979 /*
980  * Generate an ISN_PUSHSPEC instruction.
981  */
982     static int
983 generate_PUSHSPEC(cctx_T *cctx, varnumber_T number)
984 {
985     isn_T	*isn;
986 
987     RETURN_OK_IF_SKIP(cctx);
988     if ((isn = generate_instr_type(cctx, ISN_PUSHSPEC, &t_special)) == NULL)
989 	return FAIL;
990     isn->isn_arg.number = number;
991 
992     return OK;
993 }
994 
995 #ifdef FEAT_FLOAT
996 /*
997  * Generate an ISN_PUSHF instruction.
998  */
999     static int
1000 generate_PUSHF(cctx_T *cctx, float_T fnumber)
1001 {
1002     isn_T	*isn;
1003 
1004     RETURN_OK_IF_SKIP(cctx);
1005     if ((isn = generate_instr_type(cctx, ISN_PUSHF, &t_float)) == NULL)
1006 	return FAIL;
1007     isn->isn_arg.fnumber = fnumber;
1008 
1009     return OK;
1010 }
1011 #endif
1012 
1013 /*
1014  * Generate an ISN_PUSHS instruction.
1015  * Consumes "str".
1016  */
1017     static int
1018 generate_PUSHS(cctx_T *cctx, char_u *str)
1019 {
1020     isn_T	*isn;
1021 
1022     if (cctx->ctx_skip == SKIP_YES)
1023     {
1024 	vim_free(str);
1025 	return OK;
1026     }
1027     if ((isn = generate_instr_type(cctx, ISN_PUSHS, &t_string)) == NULL)
1028 	return FAIL;
1029     isn->isn_arg.string = str;
1030 
1031     return OK;
1032 }
1033 
1034 /*
1035  * Generate an ISN_PUSHCHANNEL instruction.
1036  * Consumes "channel".
1037  */
1038     static int
1039 generate_PUSHCHANNEL(cctx_T *cctx, channel_T *channel)
1040 {
1041     isn_T	*isn;
1042 
1043     RETURN_OK_IF_SKIP(cctx);
1044     if ((isn = generate_instr_type(cctx, ISN_PUSHCHANNEL, &t_channel)) == NULL)
1045 	return FAIL;
1046     isn->isn_arg.channel = channel;
1047 
1048     return OK;
1049 }
1050 
1051 /*
1052  * Generate an ISN_PUSHJOB instruction.
1053  * Consumes "job".
1054  */
1055     static int
1056 generate_PUSHJOB(cctx_T *cctx, job_T *job)
1057 {
1058     isn_T	*isn;
1059 
1060     RETURN_OK_IF_SKIP(cctx);
1061     if ((isn = generate_instr_type(cctx, ISN_PUSHJOB, &t_channel)) == NULL)
1062 	return FAIL;
1063     isn->isn_arg.job = job;
1064 
1065     return OK;
1066 }
1067 
1068 /*
1069  * Generate an ISN_PUSHBLOB instruction.
1070  * Consumes "blob".
1071  */
1072     static int
1073 generate_PUSHBLOB(cctx_T *cctx, blob_T *blob)
1074 {
1075     isn_T	*isn;
1076 
1077     RETURN_OK_IF_SKIP(cctx);
1078     if ((isn = generate_instr_type(cctx, ISN_PUSHBLOB, &t_blob)) == NULL)
1079 	return FAIL;
1080     isn->isn_arg.blob = blob;
1081 
1082     return OK;
1083 }
1084 
1085 /*
1086  * Generate an ISN_PUSHFUNC instruction with name "name".
1087  * Consumes "name".
1088  */
1089     static int
1090 generate_PUSHFUNC(cctx_T *cctx, char_u *name, type_T *type)
1091 {
1092     isn_T	*isn;
1093 
1094     RETURN_OK_IF_SKIP(cctx);
1095     if ((isn = generate_instr_type(cctx, ISN_PUSHFUNC, type)) == NULL)
1096 	return FAIL;
1097     isn->isn_arg.string = name == NULL ? NULL : vim_strsave(name);
1098 
1099     return OK;
1100 }
1101 
1102 /*
1103  * Generate an ISN_GETITEM instruction with "index".
1104  */
1105     static int
1106 generate_GETITEM(cctx_T *cctx, int index)
1107 {
1108     isn_T	*isn;
1109     garray_T	*stack = &cctx->ctx_type_stack;
1110     type_T	*type = ((type_T **)stack->ga_data)[stack->ga_len - 1];
1111     type_T	*item_type = &t_any;
1112 
1113     RETURN_OK_IF_SKIP(cctx);
1114 
1115     if (type->tt_type != VAR_LIST)
1116     {
1117 	// cannot happen, caller has checked the type
1118 	emsg(_(e_listreq));
1119 	return FAIL;
1120     }
1121     item_type = type->tt_member;
1122     if ((isn = generate_instr(cctx, ISN_GETITEM)) == NULL)
1123 	return FAIL;
1124     isn->isn_arg.number = index;
1125 
1126     // add the item type to the type stack
1127     if (ga_grow(stack, 1) == FAIL)
1128 	return FAIL;
1129     ((type_T **)stack->ga_data)[stack->ga_len] = item_type;
1130     ++stack->ga_len;
1131     return OK;
1132 }
1133 
1134 /*
1135  * Generate an ISN_SLICE instruction with "count".
1136  */
1137     static int
1138 generate_SLICE(cctx_T *cctx, int count)
1139 {
1140     isn_T	*isn;
1141 
1142     RETURN_OK_IF_SKIP(cctx);
1143     if ((isn = generate_instr(cctx, ISN_SLICE)) == NULL)
1144 	return FAIL;
1145     isn->isn_arg.number = count;
1146     return OK;
1147 }
1148 
1149 /*
1150  * Generate an ISN_CHECKLEN instruction with "min_len".
1151  */
1152     static int
1153 generate_CHECKLEN(cctx_T *cctx, int min_len, int more_OK)
1154 {
1155     isn_T	*isn;
1156 
1157     RETURN_OK_IF_SKIP(cctx);
1158 
1159     if ((isn = generate_instr(cctx, ISN_CHECKLEN)) == NULL)
1160 	return FAIL;
1161     isn->isn_arg.checklen.cl_min_len = min_len;
1162     isn->isn_arg.checklen.cl_more_OK = more_OK;
1163 
1164     return OK;
1165 }
1166 
1167 /*
1168  * Generate an ISN_STORE instruction.
1169  */
1170     static int
1171 generate_STORE(cctx_T *cctx, isntype_T isn_type, int idx, char_u *name)
1172 {
1173     isn_T	*isn;
1174 
1175     RETURN_OK_IF_SKIP(cctx);
1176     if ((isn = generate_instr_drop(cctx, isn_type, 1)) == NULL)
1177 	return FAIL;
1178     if (name != NULL)
1179 	isn->isn_arg.string = vim_strsave(name);
1180     else
1181 	isn->isn_arg.number = idx;
1182 
1183     return OK;
1184 }
1185 
1186 /*
1187  * Generate an ISN_STOREOUTER instruction.
1188  */
1189     static int
1190 generate_STOREOUTER(cctx_T *cctx, int idx, int level)
1191 {
1192     isn_T	*isn;
1193 
1194     RETURN_OK_IF_SKIP(cctx);
1195     if ((isn = generate_instr_drop(cctx, ISN_STOREOUTER, 1)) == NULL)
1196 	return FAIL;
1197     isn->isn_arg.outer.outer_idx = idx;
1198     isn->isn_arg.outer.outer_depth = level;
1199 
1200     return OK;
1201 }
1202 
1203 /*
1204  * Generate an ISN_STORENR instruction (short for ISN_PUSHNR + ISN_STORE)
1205  */
1206     static int
1207 generate_STORENR(cctx_T *cctx, int idx, varnumber_T value)
1208 {
1209     isn_T	*isn;
1210 
1211     RETURN_OK_IF_SKIP(cctx);
1212     if ((isn = generate_instr(cctx, ISN_STORENR)) == NULL)
1213 	return FAIL;
1214     isn->isn_arg.storenr.stnr_idx = idx;
1215     isn->isn_arg.storenr.stnr_val = value;
1216 
1217     return OK;
1218 }
1219 
1220 /*
1221  * Generate an ISN_STOREOPT instruction
1222  */
1223     static int
1224 generate_STOREOPT(cctx_T *cctx, char_u *name, int opt_flags)
1225 {
1226     isn_T	*isn;
1227 
1228     RETURN_OK_IF_SKIP(cctx);
1229     if ((isn = generate_instr_drop(cctx, ISN_STOREOPT, 1)) == NULL)
1230 	return FAIL;
1231     isn->isn_arg.storeopt.so_name = vim_strsave(name);
1232     isn->isn_arg.storeopt.so_flags = opt_flags;
1233 
1234     return OK;
1235 }
1236 
1237 /*
1238  * Generate an ISN_LOAD or similar instruction.
1239  */
1240     static int
1241 generate_LOAD(
1242 	cctx_T	    *cctx,
1243 	isntype_T   isn_type,
1244 	int	    idx,
1245 	char_u	    *name,
1246 	type_T	    *type)
1247 {
1248     isn_T	*isn;
1249 
1250     RETURN_OK_IF_SKIP(cctx);
1251     if ((isn = generate_instr_type(cctx, isn_type, type)) == NULL)
1252 	return FAIL;
1253     if (name != NULL)
1254 	isn->isn_arg.string = vim_strsave(name);
1255     else
1256 	isn->isn_arg.number = idx;
1257 
1258     return OK;
1259 }
1260 
1261 /*
1262  * Generate an ISN_LOADOUTER instruction
1263  */
1264     static int
1265 generate_LOADOUTER(
1266 	cctx_T	    *cctx,
1267 	int	    idx,
1268 	int	    nesting,
1269 	type_T	    *type)
1270 {
1271     isn_T	*isn;
1272 
1273     RETURN_OK_IF_SKIP(cctx);
1274     if ((isn = generate_instr_type(cctx, ISN_LOADOUTER, type)) == NULL)
1275 	return FAIL;
1276     isn->isn_arg.outer.outer_idx = idx;
1277     isn->isn_arg.outer.outer_depth = nesting;
1278 
1279     return OK;
1280 }
1281 
1282 /*
1283  * Generate an ISN_LOADV instruction for v:var.
1284  */
1285     static int
1286 generate_LOADV(
1287 	cctx_T	    *cctx,
1288 	char_u	    *name,
1289 	int	    error)
1290 {
1291     int	    di_flags;
1292     int	    vidx = find_vim_var(name, &di_flags);
1293     type_T  *type;
1294 
1295     RETURN_OK_IF_SKIP(cctx);
1296     if (vidx < 0)
1297     {
1298 	if (error)
1299 	    semsg(_(e_variable_not_found_str), name);
1300 	return FAIL;
1301     }
1302     type = typval2type_vimvar(get_vim_var_tv(vidx), cctx->ctx_type_list);
1303 
1304     return generate_LOAD(cctx, ISN_LOADV, vidx, NULL, type);
1305 }
1306 
1307 /*
1308  * Generate an ISN_UNLET instruction.
1309  */
1310     static int
1311 generate_UNLET(cctx_T *cctx, isntype_T isn_type, char_u *name, int forceit)
1312 {
1313     isn_T	*isn;
1314 
1315     RETURN_OK_IF_SKIP(cctx);
1316     if ((isn = generate_instr(cctx, isn_type)) == NULL)
1317 	return FAIL;
1318     isn->isn_arg.unlet.ul_name = vim_strsave(name);
1319     isn->isn_arg.unlet.ul_forceit = forceit;
1320 
1321     return OK;
1322 }
1323 
1324 /*
1325  * Generate an ISN_LOCKCONST instruction.
1326  */
1327     static int
1328 generate_LOCKCONST(cctx_T *cctx)
1329 {
1330     isn_T	*isn;
1331 
1332     RETURN_OK_IF_SKIP(cctx);
1333     if ((isn = generate_instr(cctx, ISN_LOCKCONST)) == NULL)
1334 	return FAIL;
1335     return OK;
1336 }
1337 
1338 /*
1339  * Generate an ISN_LOADS instruction.
1340  */
1341     static int
1342 generate_OLDSCRIPT(
1343 	cctx_T	    *cctx,
1344 	isntype_T   isn_type,
1345 	char_u	    *name,
1346 	int	    sid,
1347 	type_T	    *type)
1348 {
1349     isn_T	*isn;
1350 
1351     RETURN_OK_IF_SKIP(cctx);
1352     if (isn_type == ISN_LOADS)
1353 	isn = generate_instr_type(cctx, isn_type, type);
1354     else
1355 	isn = generate_instr_drop(cctx, isn_type, 1);
1356     if (isn == NULL)
1357 	return FAIL;
1358     isn->isn_arg.loadstore.ls_name = vim_strsave(name);
1359     isn->isn_arg.loadstore.ls_sid = sid;
1360 
1361     return OK;
1362 }
1363 
1364 /*
1365  * Generate an ISN_LOADSCRIPT or ISN_STORESCRIPT instruction.
1366  */
1367     static int
1368 generate_VIM9SCRIPT(
1369 	cctx_T	    *cctx,
1370 	isntype_T   isn_type,
1371 	int	    sid,
1372 	int	    idx,
1373 	type_T	    *type)
1374 {
1375     isn_T	*isn;
1376     scriptref_T	*sref;
1377     scriptitem_T *si = SCRIPT_ITEM(sid);
1378 
1379     RETURN_OK_IF_SKIP(cctx);
1380     if (isn_type == ISN_LOADSCRIPT)
1381 	isn = generate_instr_type(cctx, isn_type, type);
1382     else
1383 	isn = generate_instr_drop(cctx, isn_type, 1);
1384     if (isn == NULL)
1385 	return FAIL;
1386 
1387     // This requires three arguments, which doesn't fit in an instruction, thus
1388     // we need to allocate a struct for this.
1389     sref = ALLOC_ONE(scriptref_T);
1390     if (sref == NULL)
1391 	return FAIL;
1392     isn->isn_arg.script.scriptref = sref;
1393     sref->sref_sid = sid;
1394     sref->sref_idx = idx;
1395     sref->sref_seq = si->sn_script_seq;
1396     sref->sref_type = type;
1397     return OK;
1398 }
1399 
1400 /*
1401  * Generate an ISN_NEWLIST instruction.
1402  */
1403     static int
1404 generate_NEWLIST(cctx_T *cctx, int count)
1405 {
1406     isn_T	*isn;
1407     garray_T	*stack = &cctx->ctx_type_stack;
1408     type_T	*type;
1409     type_T	*member;
1410 
1411     RETURN_OK_IF_SKIP(cctx);
1412     if ((isn = generate_instr(cctx, ISN_NEWLIST)) == NULL)
1413 	return FAIL;
1414     isn->isn_arg.number = count;
1415 
1416     // get the member type from all the items on the stack.
1417     if (count == 0)
1418 	member = &t_void;
1419     else
1420 	member = get_member_type_from_stack(
1421 	    ((type_T **)stack->ga_data) + stack->ga_len, count, 1,
1422 							  cctx->ctx_type_list);
1423     type = get_list_type(member, cctx->ctx_type_list);
1424 
1425     // drop the value types
1426     stack->ga_len -= count;
1427 
1428     // add the list type to the type stack
1429     if (ga_grow(stack, 1) == FAIL)
1430 	return FAIL;
1431     ((type_T **)stack->ga_data)[stack->ga_len] = type;
1432     ++stack->ga_len;
1433 
1434     return OK;
1435 }
1436 
1437 /*
1438  * Generate an ISN_NEWDICT instruction.
1439  */
1440     static int
1441 generate_NEWDICT(cctx_T *cctx, int count)
1442 {
1443     isn_T	*isn;
1444     garray_T	*stack = &cctx->ctx_type_stack;
1445     type_T	*type;
1446     type_T	*member;
1447 
1448     RETURN_OK_IF_SKIP(cctx);
1449     if ((isn = generate_instr(cctx, ISN_NEWDICT)) == NULL)
1450 	return FAIL;
1451     isn->isn_arg.number = count;
1452 
1453     if (count == 0)
1454 	member = &t_void;
1455     else
1456 	member = get_member_type_from_stack(
1457 	    ((type_T **)stack->ga_data) + stack->ga_len, count, 2,
1458 							  cctx->ctx_type_list);
1459     type = get_dict_type(member, cctx->ctx_type_list);
1460 
1461     // drop the key and value types
1462     stack->ga_len -= 2 * count;
1463 
1464     // add the dict type to the type stack
1465     if (ga_grow(stack, 1) == FAIL)
1466 	return FAIL;
1467     ((type_T **)stack->ga_data)[stack->ga_len] = type;
1468     ++stack->ga_len;
1469 
1470     return OK;
1471 }
1472 
1473 /*
1474  * Generate an ISN_FUNCREF instruction.
1475  */
1476     static int
1477 generate_FUNCREF(cctx_T *cctx, ufunc_T *ufunc)
1478 {
1479     isn_T	*isn;
1480     garray_T	*stack = &cctx->ctx_type_stack;
1481 
1482     RETURN_OK_IF_SKIP(cctx);
1483     if ((isn = generate_instr(cctx, ISN_FUNCREF)) == NULL)
1484 	return FAIL;
1485     isn->isn_arg.funcref.fr_func = ufunc->uf_dfunc_idx;
1486     cctx->ctx_has_closure = 1;
1487 
1488     // if the referenced function is a closure, it may use items further up in
1489     // the nested context, including this one.
1490     if (ufunc->uf_flags & FC_CLOSURE)
1491 	cctx->ctx_ufunc->uf_flags |= FC_CLOSURE;
1492 
1493     if (ga_grow(stack, 1) == FAIL)
1494 	return FAIL;
1495     ((type_T **)stack->ga_data)[stack->ga_len] =
1496 	       ufunc->uf_func_type == NULL ? &t_func_any : ufunc->uf_func_type;
1497     ++stack->ga_len;
1498 
1499     return OK;
1500 }
1501 
1502 /*
1503  * Generate an ISN_NEWFUNC instruction.
1504  * "lambda_name" and "func_name" must be in allocated memory and will be
1505  * consumed.
1506  */
1507     static int
1508 generate_NEWFUNC(cctx_T *cctx, char_u *lambda_name, char_u *func_name)
1509 {
1510     isn_T	*isn;
1511 
1512     if (cctx->ctx_skip == SKIP_YES)
1513     {
1514 	vim_free(lambda_name);
1515 	vim_free(func_name);
1516 	return OK;
1517     }
1518     if ((isn = generate_instr(cctx, ISN_NEWFUNC)) == NULL)
1519     {
1520 	vim_free(lambda_name);
1521 	vim_free(func_name);
1522 	return FAIL;
1523     }
1524     isn->isn_arg.newfunc.nf_lambda = lambda_name;
1525     isn->isn_arg.newfunc.nf_global = func_name;
1526 
1527     return OK;
1528 }
1529 
1530 /*
1531  * Generate an ISN_DEF instruction: list functions
1532  */
1533     static int
1534 generate_DEF(cctx_T *cctx, char_u *name, size_t len)
1535 {
1536     isn_T	*isn;
1537 
1538     RETURN_OK_IF_SKIP(cctx);
1539     if ((isn = generate_instr(cctx, ISN_DEF)) == NULL)
1540 	return FAIL;
1541     if (len > 0)
1542     {
1543 	isn->isn_arg.string = vim_strnsave(name, len);
1544 	if (isn->isn_arg.string == NULL)
1545 	    return FAIL;
1546     }
1547     return OK;
1548 }
1549 
1550 /*
1551  * Generate an ISN_JUMP instruction.
1552  */
1553     static int
1554 generate_JUMP(cctx_T *cctx, jumpwhen_T when, int where)
1555 {
1556     isn_T	*isn;
1557     garray_T	*stack = &cctx->ctx_type_stack;
1558 
1559     RETURN_OK_IF_SKIP(cctx);
1560     if ((isn = generate_instr(cctx, ISN_JUMP)) == NULL)
1561 	return FAIL;
1562     isn->isn_arg.jump.jump_when = when;
1563     isn->isn_arg.jump.jump_where = where;
1564 
1565     if (when != JUMP_ALWAYS && stack->ga_len > 0)
1566 	--stack->ga_len;
1567 
1568     return OK;
1569 }
1570 
1571     static int
1572 generate_FOR(cctx_T *cctx, int loop_idx)
1573 {
1574     isn_T	*isn;
1575     garray_T	*stack = &cctx->ctx_type_stack;
1576 
1577     RETURN_OK_IF_SKIP(cctx);
1578     if ((isn = generate_instr(cctx, ISN_FOR)) == NULL)
1579 	return FAIL;
1580     isn->isn_arg.forloop.for_idx = loop_idx;
1581 
1582     if (ga_grow(stack, 1) == FAIL)
1583 	return FAIL;
1584     // type doesn't matter, will be stored next
1585     ((type_T **)stack->ga_data)[stack->ga_len] = &t_any;
1586     ++stack->ga_len;
1587 
1588     return OK;
1589 }
1590 
1591 /*
1592  * Generate an ISN_BCALL instruction.
1593  * "method_call" is TRUE for "value->method()"
1594  * Return FAIL if the number of arguments is wrong.
1595  */
1596     static int
1597 generate_BCALL(cctx_T *cctx, int func_idx, int argcount, int method_call)
1598 {
1599     isn_T	*isn;
1600     garray_T	*stack = &cctx->ctx_type_stack;
1601     int		argoff;
1602     type_T	**argtypes = NULL;
1603     type_T	*maptype = NULL;
1604 
1605     RETURN_OK_IF_SKIP(cctx);
1606     argoff = check_internal_func(func_idx, argcount);
1607     if (argoff < 0)
1608 	return FAIL;
1609 
1610     if (method_call && argoff > 1)
1611     {
1612 	if ((isn = generate_instr(cctx, ISN_SHUFFLE)) == NULL)
1613 	    return FAIL;
1614 	isn->isn_arg.shuffle.shfl_item = argcount;
1615 	isn->isn_arg.shuffle.shfl_up = argoff - 1;
1616     }
1617 
1618     if (argcount > 0)
1619     {
1620 	// Check the types of the arguments.
1621 	argtypes = ((type_T **)stack->ga_data) + stack->ga_len - argcount;
1622 	if (internal_func_check_arg_types(argtypes, func_idx, argcount,
1623 								 cctx) == FAIL)
1624 	    return FAIL;
1625 	if (internal_func_is_map(func_idx))
1626 	    maptype = *argtypes;
1627     }
1628 
1629     if ((isn = generate_instr(cctx, ISN_BCALL)) == NULL)
1630 	return FAIL;
1631     isn->isn_arg.bfunc.cbf_idx = func_idx;
1632     isn->isn_arg.bfunc.cbf_argcount = argcount;
1633 
1634     // Drop the argument types and push the return type.
1635     stack->ga_len -= argcount;
1636     if (ga_grow(stack, 1) == FAIL)
1637 	return FAIL;
1638     ((type_T **)stack->ga_data)[stack->ga_len] =
1639 			  internal_func_ret_type(func_idx, argcount, argtypes);
1640     ++stack->ga_len;
1641 
1642     if (maptype != NULL && maptype->tt_member != NULL
1643 					       && maptype->tt_member != &t_any)
1644 	// Check that map() didn't change the item types.
1645 	generate_TYPECHECK(cctx, maptype, -1, 1);
1646 
1647     return OK;
1648 }
1649 
1650 /*
1651  * Generate an ISN_LISTAPPEND instruction.  Works like add().
1652  * Argument count is already checked.
1653  */
1654     static int
1655 generate_LISTAPPEND(cctx_T *cctx)
1656 {
1657     garray_T	*stack = &cctx->ctx_type_stack;
1658     type_T	*list_type;
1659     type_T	*item_type;
1660     type_T	*expected;
1661 
1662     // Caller already checked that list_type is a list.
1663     list_type = ((type_T **)stack->ga_data)[stack->ga_len - 2];
1664     item_type = ((type_T **)stack->ga_data)[stack->ga_len - 1];
1665     expected = list_type->tt_member;
1666     if (need_type(item_type, expected, -1, 0, cctx, FALSE, FALSE) == FAIL)
1667 	return FAIL;
1668 
1669     if (generate_instr(cctx, ISN_LISTAPPEND) == NULL)
1670 	return FAIL;
1671 
1672     --stack->ga_len;	    // drop the argument
1673     return OK;
1674 }
1675 
1676 /*
1677  * Generate an ISN_BLOBAPPEND instruction.  Works like add().
1678  * Argument count is already checked.
1679  */
1680     static int
1681 generate_BLOBAPPEND(cctx_T *cctx)
1682 {
1683     garray_T	*stack = &cctx->ctx_type_stack;
1684     type_T	*item_type;
1685 
1686     // Caller already checked that blob_type is a blob.
1687     item_type = ((type_T **)stack->ga_data)[stack->ga_len - 1];
1688     if (need_type(item_type, &t_number, -1, 0, cctx, FALSE, FALSE) == FAIL)
1689 	return FAIL;
1690 
1691     if (generate_instr(cctx, ISN_BLOBAPPEND) == NULL)
1692 	return FAIL;
1693 
1694     --stack->ga_len;	    // drop the argument
1695     return OK;
1696 }
1697 
1698 /*
1699  * Return TRUE if "ufunc" should be compiled, taking into account whether
1700  * "profile" indicates profiling is to be done.
1701  */
1702     int
1703 func_needs_compiling(ufunc_T *ufunc, int profile UNUSED)
1704 {
1705     switch (ufunc->uf_def_status)
1706     {
1707 	case UF_NOT_COMPILED: break;
1708 	case UF_TO_BE_COMPILED: return TRUE;
1709 	case UF_COMPILED:
1710 	{
1711 #ifdef FEAT_PROFILE
1712 	    dfunc_T *dfunc = ((dfunc_T *)def_functions.ga_data)
1713 							 + ufunc->uf_dfunc_idx;
1714 
1715 	    return profile ? dfunc->df_instr_prof == NULL
1716 			   : dfunc->df_instr == NULL;
1717 #else
1718 	    break;
1719 #endif
1720 	}
1721 	case UF_COMPILING: break;
1722     }
1723     return FALSE;
1724 }
1725 
1726 /*
1727  * Generate an ISN_DCALL or ISN_UCALL instruction.
1728  * Return FAIL if the number of arguments is wrong.
1729  */
1730     static int
1731 generate_CALL(cctx_T *cctx, ufunc_T *ufunc, int pushed_argcount)
1732 {
1733     isn_T	*isn;
1734     garray_T	*stack = &cctx->ctx_type_stack;
1735     int		regular_args = ufunc->uf_args.ga_len;
1736     int		argcount = pushed_argcount;
1737 
1738     RETURN_OK_IF_SKIP(cctx);
1739     if (argcount > regular_args && !has_varargs(ufunc))
1740     {
1741 	semsg(_(e_toomanyarg), printable_func_name(ufunc));
1742 	return FAIL;
1743     }
1744     if (argcount < regular_args - ufunc->uf_def_args.ga_len)
1745     {
1746 	semsg(_(e_toofewarg), printable_func_name(ufunc));
1747 	return FAIL;
1748     }
1749 
1750     if (ufunc->uf_def_status != UF_NOT_COMPILED)
1751     {
1752 	int		i;
1753 
1754 	for (i = 0; i < argcount; ++i)
1755 	{
1756 	    type_T *expected;
1757 	    type_T *actual;
1758 
1759 	    if (i < regular_args)
1760 	    {
1761 		if (ufunc->uf_arg_types == NULL)
1762 		    continue;
1763 		expected = ufunc->uf_arg_types[i];
1764 	    }
1765 	    else if (ufunc->uf_va_type == NULL || ufunc->uf_va_type == &t_any)
1766 		// possibly a lambda or "...: any"
1767 		expected = &t_any;
1768 	    else
1769 		expected = ufunc->uf_va_type->tt_member;
1770 	    actual = ((type_T **)stack->ga_data)[stack->ga_len - argcount + i];
1771 	    if (need_type(actual, expected, -argcount + i, i + 1, cctx,
1772 							  TRUE, FALSE) == FAIL)
1773 	    {
1774 		arg_type_mismatch(expected, actual, i + 1);
1775 		return FAIL;
1776 	    }
1777 	}
1778 	if (func_needs_compiling(ufunc, PROFILING(ufunc))
1779 		&& compile_def_function(ufunc, ufunc->uf_ret_type == NULL,
1780 					       PROFILING(ufunc), NULL) == FAIL)
1781 	    return FAIL;
1782     }
1783 
1784     if ((isn = generate_instr(cctx,
1785 		    ufunc->uf_def_status != UF_NOT_COMPILED ? ISN_DCALL
1786 							 : ISN_UCALL)) == NULL)
1787 	return FAIL;
1788     if (isn->isn_type == ISN_DCALL)
1789     {
1790 	isn->isn_arg.dfunc.cdf_idx = ufunc->uf_dfunc_idx;
1791 	isn->isn_arg.dfunc.cdf_argcount = argcount;
1792     }
1793     else
1794     {
1795 	// A user function may be deleted and redefined later, can't use the
1796 	// ufunc pointer, need to look it up again at runtime.
1797 	isn->isn_arg.ufunc.cuf_name = vim_strsave(ufunc->uf_name);
1798 	isn->isn_arg.ufunc.cuf_argcount = argcount;
1799     }
1800 
1801     stack->ga_len -= argcount; // drop the arguments
1802     if (ga_grow(stack, 1) == FAIL)
1803 	return FAIL;
1804     // add return value
1805     ((type_T **)stack->ga_data)[stack->ga_len] = ufunc->uf_ret_type;
1806     ++stack->ga_len;
1807 
1808     return OK;
1809 }
1810 
1811 /*
1812  * Generate an ISN_UCALL instruction when the function isn't defined yet.
1813  */
1814     static int
1815 generate_UCALL(cctx_T *cctx, char_u *name, int argcount)
1816 {
1817     isn_T	*isn;
1818     garray_T	*stack = &cctx->ctx_type_stack;
1819 
1820     RETURN_OK_IF_SKIP(cctx);
1821     if ((isn = generate_instr(cctx, ISN_UCALL)) == NULL)
1822 	return FAIL;
1823     isn->isn_arg.ufunc.cuf_name = vim_strsave(name);
1824     isn->isn_arg.ufunc.cuf_argcount = argcount;
1825 
1826     stack->ga_len -= argcount; // drop the arguments
1827     if (ga_grow(stack, 1) == FAIL)
1828 	return FAIL;
1829     // add return value
1830     ((type_T **)stack->ga_data)[stack->ga_len] = &t_any;
1831     ++stack->ga_len;
1832 
1833     return OK;
1834 }
1835 
1836 /*
1837  * Generate an ISN_PCALL instruction.
1838  * "type" is the type of the FuncRef.
1839  */
1840     static int
1841 generate_PCALL(
1842 	cctx_T	*cctx,
1843 	int	argcount,
1844 	char_u	*name,
1845 	type_T	*type,
1846 	int	at_top)
1847 {
1848     isn_T	*isn;
1849     garray_T	*stack = &cctx->ctx_type_stack;
1850     type_T	*ret_type;
1851 
1852     RETURN_OK_IF_SKIP(cctx);
1853 
1854     if (type->tt_type == VAR_ANY)
1855 	ret_type = &t_any;
1856     else if (type->tt_type == VAR_FUNC || type->tt_type == VAR_PARTIAL)
1857     {
1858 	if (type->tt_argcount != -1)
1859 	{
1860 	    int	    varargs = (type->tt_flags & TTFLAG_VARARGS) ? 1 : 0;
1861 
1862 	    if (argcount < type->tt_min_argcount - varargs)
1863 	    {
1864 		semsg(_(e_toofewarg), name);
1865 		return FAIL;
1866 	    }
1867 	    if (!varargs && argcount > type->tt_argcount)
1868 	    {
1869 		semsg(_(e_toomanyarg), name);
1870 		return FAIL;
1871 	    }
1872 	    if (type->tt_args != NULL)
1873 	    {
1874 		int i;
1875 
1876 		for (i = 0; i < argcount; ++i)
1877 		{
1878 		    int	    offset = -argcount + i - 1;
1879 		    type_T *actual = ((type_T **)stack->ga_data)[
1880 						       stack->ga_len + offset];
1881 		    type_T *expected;
1882 
1883 		    if (varargs && i >= type->tt_argcount - 1)
1884 			expected = type->tt_args[
1885 					     type->tt_argcount - 1]->tt_member;
1886 		    else
1887 			expected = type->tt_args[i];
1888 		    if (need_type(actual, expected, offset, i + 1,
1889 						    cctx, TRUE, FALSE) == FAIL)
1890 		    {
1891 			arg_type_mismatch(expected, actual, i + 1);
1892 			return FAIL;
1893 		    }
1894 		}
1895 	    }
1896 	}
1897 	ret_type = type->tt_member;
1898     }
1899     else
1900     {
1901 	semsg(_(e_not_callable_type_str), name);
1902 	return FAIL;
1903     }
1904 
1905     if ((isn = generate_instr(cctx, ISN_PCALL)) == NULL)
1906 	return FAIL;
1907     isn->isn_arg.pfunc.cpf_top = at_top;
1908     isn->isn_arg.pfunc.cpf_argcount = argcount;
1909 
1910     stack->ga_len -= argcount; // drop the arguments
1911 
1912     // drop the funcref/partial, get back the return value
1913     ((type_T **)stack->ga_data)[stack->ga_len - 1] = ret_type;
1914 
1915     // If partial is above the arguments it must be cleared and replaced with
1916     // the return value.
1917     if (at_top && generate_instr(cctx, ISN_PCALL_END) == NULL)
1918 	return FAIL;
1919 
1920     return OK;
1921 }
1922 
1923 /*
1924  * Generate an ISN_STRINGMEMBER instruction.
1925  */
1926     static int
1927 generate_STRINGMEMBER(cctx_T *cctx, char_u *name, size_t len)
1928 {
1929     isn_T	*isn;
1930     garray_T	*stack = &cctx->ctx_type_stack;
1931     type_T	*type;
1932 
1933     RETURN_OK_IF_SKIP(cctx);
1934     if ((isn = generate_instr(cctx, ISN_STRINGMEMBER)) == NULL)
1935 	return FAIL;
1936     isn->isn_arg.string = vim_strnsave(name, len);
1937 
1938     // check for dict type
1939     type = ((type_T **)stack->ga_data)[stack->ga_len - 1];
1940     if (type->tt_type != VAR_DICT && type != &t_any)
1941     {
1942 	emsg(_(e_dictreq));
1943 	return FAIL;
1944     }
1945     // change dict type to dict member type
1946     if (type->tt_type == VAR_DICT)
1947     {
1948 	((type_T **)stack->ga_data)[stack->ga_len - 1] =
1949 		      type->tt_member == &t_unknown ? &t_any : type->tt_member;
1950     }
1951 
1952     return OK;
1953 }
1954 
1955 /*
1956  * Generate an ISN_ECHO instruction.
1957  */
1958     static int
1959 generate_ECHO(cctx_T *cctx, int with_white, int count)
1960 {
1961     isn_T	*isn;
1962 
1963     RETURN_OK_IF_SKIP(cctx);
1964     if ((isn = generate_instr_drop(cctx, ISN_ECHO, count)) == NULL)
1965 	return FAIL;
1966     isn->isn_arg.echo.echo_with_white = with_white;
1967     isn->isn_arg.echo.echo_count = count;
1968 
1969     return OK;
1970 }
1971 
1972 /*
1973  * Generate an ISN_EXECUTE/ISN_ECHOMSG/ISN_ECHOERR instruction.
1974  */
1975     static int
1976 generate_MULT_EXPR(cctx_T *cctx, isntype_T isn_type, int count)
1977 {
1978     isn_T	*isn;
1979 
1980     if ((isn = generate_instr_drop(cctx, isn_type, count)) == NULL)
1981 	return FAIL;
1982     isn->isn_arg.number = count;
1983 
1984     return OK;
1985 }
1986 
1987 /*
1988  * Generate an ISN_PUT instruction.
1989  */
1990     static int
1991 generate_PUT(cctx_T *cctx, int regname, linenr_T lnum)
1992 {
1993     isn_T	*isn;
1994 
1995     RETURN_OK_IF_SKIP(cctx);
1996     if ((isn = generate_instr(cctx, ISN_PUT)) == NULL)
1997 	return FAIL;
1998     isn->isn_arg.put.put_regname = regname;
1999     isn->isn_arg.put.put_lnum = lnum;
2000     return OK;
2001 }
2002 
2003     static int
2004 generate_EXEC(cctx_T *cctx, char_u *line)
2005 {
2006     isn_T	*isn;
2007 
2008     RETURN_OK_IF_SKIP(cctx);
2009     if ((isn = generate_instr(cctx, ISN_EXEC)) == NULL)
2010 	return FAIL;
2011     isn->isn_arg.string = vim_strsave(line);
2012     return OK;
2013 }
2014 
2015     static int
2016 generate_EXECCONCAT(cctx_T *cctx, int count)
2017 {
2018     isn_T	*isn;
2019 
2020     if ((isn = generate_instr_drop(cctx, ISN_EXECCONCAT, count)) == NULL)
2021 	return FAIL;
2022     isn->isn_arg.number = count;
2023     return OK;
2024 }
2025 
2026 /*
2027  * Generate ISN_RANGE.  Consumes "range".  Return OK/FAIL.
2028  */
2029     static int
2030 generate_RANGE(cctx_T *cctx, char_u *range)
2031 {
2032     isn_T	*isn;
2033     garray_T	*stack = &cctx->ctx_type_stack;
2034 
2035     if ((isn = generate_instr(cctx, ISN_RANGE)) == NULL)
2036 	return FAIL;
2037     isn->isn_arg.string = range;
2038 
2039     if (ga_grow(stack, 1) == FAIL)
2040 	return FAIL;
2041     ((type_T **)stack->ga_data)[stack->ga_len] = &t_number;
2042     ++stack->ga_len;
2043     return OK;
2044 }
2045 
2046     static int
2047 generate_UNPACK(cctx_T *cctx, int var_count, int semicolon)
2048 {
2049     isn_T	*isn;
2050 
2051     RETURN_OK_IF_SKIP(cctx);
2052     if ((isn = generate_instr(cctx, ISN_UNPACK)) == NULL)
2053 	return FAIL;
2054     isn->isn_arg.unpack.unp_count = var_count;
2055     isn->isn_arg.unpack.unp_semicolon = semicolon;
2056     return OK;
2057 }
2058 
2059 /*
2060  * Generate an instruction for any command modifiers.
2061  */
2062     static int
2063 generate_cmdmods(cctx_T *cctx, cmdmod_T *cmod)
2064 {
2065     isn_T	*isn;
2066 
2067     if (cmod->cmod_flags != 0
2068 	    || cmod->cmod_split != 0
2069 	    || cmod->cmod_verbose != 0
2070 	    || cmod->cmod_tab != 0
2071 	    || cmod->cmod_filter_regmatch.regprog != NULL)
2072     {
2073 	cctx->ctx_has_cmdmod = TRUE;
2074 
2075 	if ((isn = generate_instr(cctx, ISN_CMDMOD)) == NULL)
2076 	    return FAIL;
2077 	isn->isn_arg.cmdmod.cf_cmdmod = ALLOC_ONE(cmdmod_T);
2078 	if (isn->isn_arg.cmdmod.cf_cmdmod == NULL)
2079 	    return FAIL;
2080 	mch_memmove(isn->isn_arg.cmdmod.cf_cmdmod, cmod, sizeof(cmdmod_T));
2081 	// filter program now belongs to the instruction
2082 	cmod->cmod_filter_regmatch.regprog = NULL;
2083     }
2084 
2085     return OK;
2086 }
2087 
2088     static int
2089 generate_undo_cmdmods(cctx_T *cctx)
2090 {
2091     if (cctx->ctx_has_cmdmod && generate_instr(cctx, ISN_CMDMOD_REV) == NULL)
2092 	return FAIL;
2093     cctx->ctx_has_cmdmod = FALSE;
2094     return OK;
2095 }
2096 
2097 #ifdef FEAT_PROFILE
2098     static void
2099 may_generate_prof_end(cctx_T *cctx, int prof_lnum)
2100 {
2101     if (cctx->ctx_profiling && prof_lnum >= 0)
2102 	generate_instr(cctx, ISN_PROF_END);
2103 }
2104 #endif
2105 
2106 /*
2107  * Reserve space for a local variable.
2108  * Return the variable or NULL if it failed.
2109  */
2110     static lvar_T *
2111 reserve_local(
2112 	cctx_T	*cctx,
2113 	char_u	*name,
2114 	size_t	len,
2115 	int	isConst,
2116 	type_T	*type)
2117 {
2118     lvar_T  *lvar;
2119 
2120     if (arg_exists(name, len, NULL, NULL, NULL, cctx) == OK)
2121     {
2122 	emsg_namelen(_(e_str_is_used_as_argument), name, (int)len);
2123 	return NULL;
2124     }
2125 
2126     if (ga_grow(&cctx->ctx_locals, 1) == FAIL)
2127 	return NULL;
2128     lvar = ((lvar_T *)cctx->ctx_locals.ga_data) + cctx->ctx_locals.ga_len++;
2129     CLEAR_POINTER(lvar);
2130 
2131     // Every local variable uses the next entry on the stack.  We could re-use
2132     // the last ones when leaving a scope, but then variables used in a closure
2133     // might get overwritten.  To keep things simple do not re-use stack
2134     // entries.  This is less efficient, but memory is cheap these days.
2135     lvar->lv_idx = cctx->ctx_locals_count++;
2136 
2137     lvar->lv_name = vim_strnsave(name, len == 0 ? STRLEN(name) : len);
2138     lvar->lv_const = isConst;
2139     lvar->lv_type = type;
2140 
2141     return lvar;
2142 }
2143 
2144 /*
2145  * Remove local variables above "new_top".
2146  */
2147     static void
2148 unwind_locals(cctx_T *cctx, int new_top)
2149 {
2150     if (cctx->ctx_locals.ga_len > new_top)
2151     {
2152 	int	idx;
2153 	lvar_T	*lvar;
2154 
2155 	for (idx = new_top; idx < cctx->ctx_locals.ga_len; ++idx)
2156 	{
2157 	    lvar = ((lvar_T *)cctx->ctx_locals.ga_data) + idx;
2158 	    vim_free(lvar->lv_name);
2159 	}
2160     }
2161     cctx->ctx_locals.ga_len = new_top;
2162 }
2163 
2164 /*
2165  * Free all local variables.
2166  */
2167     static void
2168 free_locals(cctx_T *cctx)
2169 {
2170     unwind_locals(cctx, 0);
2171     ga_clear(&cctx->ctx_locals);
2172 }
2173 
2174 /*
2175  * If "check_writable" is ASSIGN_CONST give an error if the variable was
2176  * defined with :final or :const, if "check_writable" is ASSIGN_FINAL give an
2177  * error if the variable was defined with :const.
2178  */
2179     static int
2180 check_item_writable(svar_T *sv, int check_writable, char_u *name)
2181 {
2182     if ((check_writable == ASSIGN_CONST && sv->sv_const != 0)
2183 	    || (check_writable == ASSIGN_FINAL
2184 					      && sv->sv_const == ASSIGN_CONST))
2185     {
2186 	semsg(_(e_readonlyvar), name);
2187 	return FAIL;
2188     }
2189     return OK;
2190 }
2191 
2192 /*
2193  * Find "name" in script-local items of script "sid".
2194  * Pass "check_writable" to check_item_writable().
2195  * Returns the index in "sn_var_vals" if found.
2196  * If found but not in "sn_var_vals" returns -1.
2197  * If not found or the variable is not writable returns -2.
2198  */
2199     int
2200 get_script_item_idx(int sid, char_u *name, int check_writable, cctx_T *cctx)
2201 {
2202     hashtab_T	    *ht;
2203     dictitem_T	    *di;
2204     scriptitem_T    *si = SCRIPT_ITEM(sid);
2205     svar_T	    *sv;
2206     int		    idx;
2207 
2208     if (!SCRIPT_ID_VALID(sid))
2209 	return -1;
2210     if (sid == current_sctx.sc_sid)
2211     {
2212 	sallvar_T *sav = find_script_var(name, 0, cctx);
2213 
2214 	if (sav == NULL)
2215 	    return -2;
2216 	idx = sav->sav_var_vals_idx;
2217 	sv = ((svar_T *)si->sn_var_vals.ga_data) + idx;
2218 	if (check_item_writable(sv, check_writable, name) == FAIL)
2219 	    return -2;
2220 	return idx;
2221     }
2222 
2223     // First look the name up in the hashtable.
2224     ht = &SCRIPT_VARS(sid);
2225     di = find_var_in_ht(ht, 0, name, TRUE);
2226     if (di == NULL)
2227 	return -2;
2228 
2229     // Now find the svar_T index in sn_var_vals.
2230     for (idx = 0; idx < si->sn_var_vals.ga_len; ++idx)
2231     {
2232 	sv = ((svar_T *)si->sn_var_vals.ga_data) + idx;
2233 	if (sv->sv_tv == &di->di_tv)
2234 	{
2235 	    if (check_item_writable(sv, check_writable, name) == FAIL)
2236 		return -2;
2237 	    return idx;
2238 	}
2239     }
2240     return -1;
2241 }
2242 
2243 /*
2244  * Find "name" in imported items of the current script or in "cctx" if not
2245  * NULL.
2246  */
2247     imported_T *
2248 find_imported(char_u *name, size_t len, cctx_T *cctx)
2249 {
2250     int		    idx;
2251 
2252     if (!SCRIPT_ID_VALID(current_sctx.sc_sid))
2253 	return NULL;
2254     if (cctx != NULL)
2255 	for (idx = 0; idx < cctx->ctx_imports.ga_len; ++idx)
2256 	{
2257 	    imported_T *import = ((imported_T *)cctx->ctx_imports.ga_data)
2258 									 + idx;
2259 
2260 	    if (len == 0 ? STRCMP(name, import->imp_name) == 0
2261 			 : STRLEN(import->imp_name) == len
2262 				  && STRNCMP(name, import->imp_name, len) == 0)
2263 		return import;
2264 	}
2265 
2266     return find_imported_in_script(name, len, current_sctx.sc_sid);
2267 }
2268 
2269     imported_T *
2270 find_imported_in_script(char_u *name, size_t len, int sid)
2271 {
2272     scriptitem_T    *si;
2273     int		    idx;
2274 
2275     if (!SCRIPT_ID_VALID(sid))
2276 	return NULL;
2277     si = SCRIPT_ITEM(sid);
2278     for (idx = 0; idx < si->sn_imports.ga_len; ++idx)
2279     {
2280 	imported_T *import = ((imported_T *)si->sn_imports.ga_data) + idx;
2281 
2282 	if (len == 0 ? STRCMP(name, import->imp_name) == 0
2283 		     : STRLEN(import->imp_name) == len
2284 				  && STRNCMP(name, import->imp_name, len) == 0)
2285 	    return import;
2286     }
2287     return NULL;
2288 }
2289 
2290 /*
2291  * Free all imported variables.
2292  */
2293     static void
2294 free_imported(cctx_T *cctx)
2295 {
2296     int idx;
2297 
2298     for (idx = 0; idx < cctx->ctx_imports.ga_len; ++idx)
2299     {
2300 	imported_T *import = ((imported_T *)cctx->ctx_imports.ga_data) + idx;
2301 
2302 	vim_free(import->imp_name);
2303     }
2304     ga_clear(&cctx->ctx_imports);
2305 }
2306 
2307 /*
2308  * Return a pointer to the next line that isn't empty or only contains a
2309  * comment. Skips over white space.
2310  * Returns NULL if there is none.
2311  */
2312     char_u *
2313 peek_next_line_from_context(cctx_T *cctx)
2314 {
2315     int lnum = cctx->ctx_lnum;
2316 
2317     while (++lnum < cctx->ctx_ufunc->uf_lines.ga_len)
2318     {
2319 	char_u *line = ((char_u **)cctx->ctx_ufunc->uf_lines.ga_data)[lnum];
2320 	char_u *p;
2321 
2322 	// ignore NULLs inserted for continuation lines
2323 	if (line != NULL)
2324 	{
2325 	    p = skipwhite(line);
2326 	    if (*p != NUL && !vim9_comment_start(p))
2327 		return p;
2328 	}
2329     }
2330     return NULL;
2331 }
2332 
2333 /*
2334  * Called when checking for a following operator at "arg".  When the rest of
2335  * the line is empty or only a comment, peek the next line.  If there is a next
2336  * line return a pointer to it and set "nextp".
2337  * Otherwise skip over white space.
2338  */
2339     static char_u *
2340 may_peek_next_line(cctx_T *cctx, char_u *arg, char_u **nextp)
2341 {
2342     char_u *p = skipwhite(arg);
2343 
2344     *nextp = NULL;
2345     if (*p == NUL || (VIM_ISWHITE(*arg) && vim9_comment_start(p)))
2346     {
2347 	*nextp = peek_next_line_from_context(cctx);
2348 	if (*nextp != NULL)
2349 	    return *nextp;
2350     }
2351     return p;
2352 }
2353 
2354 /*
2355  * Get the next line of the function from "cctx".
2356  * Skips over empty lines.  Skips over comment lines if "skip_comment" is TRUE.
2357  * Returns NULL when at the end.
2358  */
2359     char_u *
2360 next_line_from_context(cctx_T *cctx, int skip_comment)
2361 {
2362     char_u	*line;
2363 
2364     do
2365     {
2366 	++cctx->ctx_lnum;
2367 	if (cctx->ctx_lnum >= cctx->ctx_ufunc->uf_lines.ga_len)
2368 	{
2369 	    line = NULL;
2370 	    break;
2371 	}
2372 	line = ((char_u **)cctx->ctx_ufunc->uf_lines.ga_data)[cctx->ctx_lnum];
2373 	cctx->ctx_line_start = line;
2374 	SOURCING_LNUM = cctx->ctx_lnum + 1;
2375     } while (line == NULL || *skipwhite(line) == NUL
2376 		     || (skip_comment && vim9_comment_start(skipwhite(line))));
2377     return line;
2378 }
2379 
2380 /*
2381  * Skip over white space at "whitep" and assign to "*arg".
2382  * If "*arg" is at the end of the line, advance to the next line.
2383  * Also when "whitep" points to white space and "*arg" is on a "#".
2384  * Return FAIL if beyond the last line, "*arg" is unmodified then.
2385  */
2386     static int
2387 may_get_next_line(char_u *whitep, char_u **arg, cctx_T *cctx)
2388 {
2389     *arg = skipwhite(whitep);
2390     if (**arg == NUL || (VIM_ISWHITE(*whitep) && vim9_comment_start(*arg)))
2391     {
2392 	char_u *next = next_line_from_context(cctx, TRUE);
2393 
2394 	if (next == NULL)
2395 	    return FAIL;
2396 	*arg = skipwhite(next);
2397     }
2398     return OK;
2399 }
2400 
2401 /*
2402  * Idem, and give an error when failed.
2403  */
2404     static int
2405 may_get_next_line_error(char_u *whitep, char_u **arg, cctx_T *cctx)
2406 {
2407     if (may_get_next_line(whitep, arg, cctx) == FAIL)
2408     {
2409 	SOURCING_LNUM = cctx->ctx_lnum + 1;
2410 	emsg(_(e_line_incomplete));
2411 	return FAIL;
2412     }
2413     return OK;
2414 }
2415 
2416 
2417 // Structure passed between the compile_expr* functions to keep track of
2418 // constants that have been parsed but for which no code was produced yet.  If
2419 // possible expressions on these constants are applied at compile time.  If
2420 // that is not possible, the code to push the constants needs to be generated
2421 // before other instructions.
2422 // Using 50 should be more than enough of 5 levels of ().
2423 #define PPSIZE 50
2424 typedef struct {
2425     typval_T	pp_tv[PPSIZE];	// stack of ppconst constants
2426     int		pp_used;	// active entries in pp_tv[]
2427     int		pp_is_const;	// all generated code was constants, used for a
2428 				// list or dict with constant members
2429 } ppconst_T;
2430 
2431 static int compile_expr0_ext(char_u **arg,  cctx_T *cctx, int *is_const);
2432 static int compile_expr0(char_u **arg,  cctx_T *cctx);
2433 static int compile_expr1(char_u **arg,  cctx_T *cctx, ppconst_T *ppconst);
2434 
2435 /*
2436  * Generate a PUSH instruction for "tv".
2437  * "tv" will be consumed or cleared.
2438  * Nothing happens if "tv" is NULL or of type VAR_UNKNOWN;
2439  */
2440     static int
2441 generate_tv_PUSH(cctx_T *cctx, typval_T *tv)
2442 {
2443     if (tv != NULL)
2444     {
2445 	switch (tv->v_type)
2446 	{
2447 	    case VAR_UNKNOWN:
2448 		break;
2449 	    case VAR_BOOL:
2450 		generate_PUSHBOOL(cctx, tv->vval.v_number);
2451 		break;
2452 	    case VAR_SPECIAL:
2453 		generate_PUSHSPEC(cctx, tv->vval.v_number);
2454 		break;
2455 	    case VAR_NUMBER:
2456 		generate_PUSHNR(cctx, tv->vval.v_number);
2457 		break;
2458 #ifdef FEAT_FLOAT
2459 	    case VAR_FLOAT:
2460 		generate_PUSHF(cctx, tv->vval.v_float);
2461 		break;
2462 #endif
2463 	    case VAR_BLOB:
2464 		generate_PUSHBLOB(cctx, tv->vval.v_blob);
2465 		tv->vval.v_blob = NULL;
2466 		break;
2467 	    case VAR_STRING:
2468 		generate_PUSHS(cctx, tv->vval.v_string);
2469 		tv->vval.v_string = NULL;
2470 		break;
2471 	    default:
2472 		iemsg("constant type not supported");
2473 		clear_tv(tv);
2474 		return FAIL;
2475 	}
2476 	tv->v_type = VAR_UNKNOWN;
2477     }
2478     return OK;
2479 }
2480 
2481 /*
2482  * Generate code for any ppconst entries.
2483  */
2484     static int
2485 generate_ppconst(cctx_T *cctx, ppconst_T *ppconst)
2486 {
2487     int	    i;
2488     int	    ret = OK;
2489     int	    save_skip = cctx->ctx_skip;
2490 
2491     cctx->ctx_skip = SKIP_NOT;
2492     for (i = 0; i < ppconst->pp_used; ++i)
2493 	if (generate_tv_PUSH(cctx, &ppconst->pp_tv[i]) == FAIL)
2494 	    ret = FAIL;
2495     ppconst->pp_used = 0;
2496     cctx->ctx_skip = save_skip;
2497     return ret;
2498 }
2499 
2500 /*
2501  * Clear ppconst constants.  Used when failing.
2502  */
2503     static void
2504 clear_ppconst(ppconst_T *ppconst)
2505 {
2506     int	    i;
2507 
2508     for (i = 0; i < ppconst->pp_used; ++i)
2509 	clear_tv(&ppconst->pp_tv[i]);
2510     ppconst->pp_used = 0;
2511 }
2512 
2513 /*
2514  * Generate an instruction to load script-local variable "name", without the
2515  * leading "s:".
2516  * Also finds imported variables.
2517  */
2518     static int
2519 compile_load_scriptvar(
2520 	cctx_T *cctx,
2521 	char_u *name,	    // variable NUL terminated
2522 	char_u *start,	    // start of variable
2523 	char_u **end,	    // end of variable
2524 	int    error)	    // when TRUE may give error
2525 {
2526     scriptitem_T    *si;
2527     int		    idx;
2528     imported_T	    *import;
2529 
2530     if (!SCRIPT_ID_VALID(current_sctx.sc_sid))
2531 	return FAIL;
2532     si = SCRIPT_ITEM(current_sctx.sc_sid);
2533     idx = get_script_item_idx(current_sctx.sc_sid, name, 0, cctx);
2534     if (idx == -1 || si->sn_version != SCRIPT_VERSION_VIM9)
2535     {
2536 	// variable is not in sn_var_vals: old style script.
2537 	return generate_OLDSCRIPT(cctx, ISN_LOADS, name, current_sctx.sc_sid,
2538 								       &t_any);
2539     }
2540     if (idx >= 0)
2541     {
2542 	svar_T		*sv = ((svar_T *)si->sn_var_vals.ga_data) + idx;
2543 
2544 	generate_VIM9SCRIPT(cctx, ISN_LOADSCRIPT,
2545 					current_sctx.sc_sid, idx, sv->sv_type);
2546 	return OK;
2547     }
2548 
2549     import = find_imported(name, 0, cctx);
2550     if (import != NULL)
2551     {
2552 	if (import->imp_flags & IMP_FLAGS_STAR)
2553 	{
2554 	    char_u	*p = skipwhite(*end);
2555 	    char_u	*exp_name;
2556 	    int		cc;
2557 	    ufunc_T	*ufunc;
2558 	    type_T	*type;
2559 
2560 	    // Used "import * as Name", need to lookup the member.
2561 	    if (*p != '.')
2562 	    {
2563 		semsg(_(e_expected_dot_after_name_str), start);
2564 		return FAIL;
2565 	    }
2566 	    ++p;
2567 	    if (VIM_ISWHITE(*p))
2568 	    {
2569 		emsg(_(e_no_white_space_allowed_after_dot));
2570 		return FAIL;
2571 	    }
2572 
2573 	    // isolate one name
2574 	    exp_name = p;
2575 	    while (eval_isnamec(*p))
2576 		++p;
2577 	    cc = *p;
2578 	    *p = NUL;
2579 
2580 	    idx = find_exported(import->imp_sid, exp_name, &ufunc, &type, cctx);
2581 	    *p = cc;
2582 	    p = skipwhite(p);
2583 
2584 	    // TODO: what if it is a function?
2585 	    if (idx < 0)
2586 		return FAIL;
2587 	    *end = p;
2588 
2589 	    generate_VIM9SCRIPT(cctx, ISN_LOADSCRIPT,
2590 		    import->imp_sid,
2591 		    idx,
2592 		    type);
2593 	}
2594 	else if (import->imp_funcname != NULL)
2595 	    generate_PUSHFUNC(cctx, import->imp_funcname, import->imp_type);
2596 	else
2597 	    generate_VIM9SCRIPT(cctx, ISN_LOADSCRIPT,
2598 		    import->imp_sid,
2599 		    import->imp_var_vals_idx,
2600 		    import->imp_type);
2601 	return OK;
2602     }
2603 
2604     if (error)
2605 	semsg(_(e_item_not_found_str), name);
2606     return FAIL;
2607 }
2608 
2609     static int
2610 generate_funcref(cctx_T *cctx, char_u *name)
2611 {
2612     ufunc_T *ufunc = find_func(name, FALSE, cctx);
2613 
2614     if (ufunc == NULL)
2615 	return FAIL;
2616 
2617     // Need to compile any default values to get the argument types.
2618     if (func_needs_compiling(ufunc, PROFILING(ufunc))
2619 	    && compile_def_function(ufunc, TRUE, PROFILING(ufunc), NULL)
2620 								       == FAIL)
2621 	return FAIL;
2622     return generate_PUSHFUNC(cctx, ufunc->uf_name, ufunc->uf_func_type);
2623 }
2624 
2625 /*
2626  * Compile a variable name into a load instruction.
2627  * "end" points to just after the name.
2628  * "is_expr" is TRUE when evaluating an expression, might be a funcref.
2629  * When "error" is FALSE do not give an error when not found.
2630  */
2631     static int
2632 compile_load(
2633 	char_u **arg,
2634 	char_u *end_arg,
2635 	cctx_T	*cctx,
2636 	int	is_expr,
2637 	int	error)
2638 {
2639     type_T	*type;
2640     char_u	*name = NULL;
2641     char_u	*end = end_arg;
2642     int		res = FAIL;
2643     int		prev_called_emsg = called_emsg;
2644 
2645     if (*(*arg + 1) == ':')
2646     {
2647 	// load namespaced variable
2648 	if (end <= *arg + 2)
2649 	{
2650 	    isntype_T  isn_type;
2651 
2652 	    switch (**arg)
2653 	    {
2654 		case 'g': isn_type = ISN_LOADGDICT; break;
2655 		case 'w': isn_type = ISN_LOADWDICT; break;
2656 		case 't': isn_type = ISN_LOADTDICT; break;
2657 		case 'b': isn_type = ISN_LOADBDICT; break;
2658 		default:
2659 		    semsg(_(e_namespace_not_supported_str), *arg);
2660 		    goto theend;
2661 	    }
2662 	    if (generate_instr_type(cctx, isn_type, &t_dict_any) == NULL)
2663 		goto theend;
2664 	    res = OK;
2665 	}
2666 	else
2667 	{
2668 	    isntype_T  isn_type = ISN_DROP;
2669 
2670 	    name = vim_strnsave(*arg + 2, end - (*arg + 2));
2671 	    if (name == NULL)
2672 		return FAIL;
2673 
2674 	    switch (**arg)
2675 	    {
2676 		case 'v': res = generate_LOADV(cctx, name, error);
2677 			  break;
2678 		case 's': res = compile_load_scriptvar(cctx, name,
2679 							    NULL, NULL, error);
2680 			  break;
2681 		case 'g': if (vim_strchr(name, AUTOLOAD_CHAR) == NULL)
2682 			      isn_type = ISN_LOADG;
2683 			  else
2684 			  {
2685 			      isn_type = ISN_LOADAUTO;
2686 			      vim_free(name);
2687 			      name = vim_strnsave(*arg, end - *arg);
2688 			      if (name == NULL)
2689 				  return FAIL;
2690 			  }
2691 			  break;
2692 		case 'w': isn_type = ISN_LOADW; break;
2693 		case 't': isn_type = ISN_LOADT; break;
2694 		case 'b': isn_type = ISN_LOADB; break;
2695 		default:  // cannot happen, just in case
2696 			  semsg(_(e_namespace_not_supported_str), *arg);
2697 			  goto theend;
2698 	    }
2699 	    if (isn_type != ISN_DROP)
2700 	    {
2701 		// Global, Buffer-local, Window-local and Tabpage-local
2702 		// variables can be defined later, thus we don't check if it
2703 		// exists, give error at runtime.
2704 		res = generate_LOAD(cctx, isn_type, 0, name, &t_any);
2705 	    }
2706 	}
2707     }
2708     else
2709     {
2710 	size_t	    len = end - *arg;
2711 	int	    idx;
2712 	int	    gen_load = FALSE;
2713 	int	    gen_load_outer = 0;
2714 
2715 	name = vim_strnsave(*arg, end - *arg);
2716 	if (name == NULL)
2717 	    return FAIL;
2718 
2719 	if (arg_exists(*arg, len, &idx, &type, &gen_load_outer, cctx) == OK)
2720 	{
2721 	    if (gen_load_outer == 0)
2722 		gen_load = TRUE;
2723 	}
2724 	else
2725 	{
2726 	    lvar_T lvar;
2727 
2728 	    if (lookup_local(*arg, len, &lvar, cctx) == OK)
2729 	    {
2730 		type = lvar.lv_type;
2731 		idx = lvar.lv_idx;
2732 		if (lvar.lv_from_outer != 0)
2733 		    gen_load_outer = lvar.lv_from_outer;
2734 		else
2735 		    gen_load = TRUE;
2736 	    }
2737 	    else
2738 	    {
2739 		// "var" can be script-local even without using "s:" if it
2740 		// already exists in a Vim9 script or when it's imported.
2741 		if (script_var_exists(*arg, len, TRUE, cctx) == OK
2742 			|| find_imported(name, 0, cctx) != NULL)
2743 		   res = compile_load_scriptvar(cctx, name, *arg, &end, FALSE);
2744 
2745 		// When evaluating an expression and the name starts with an
2746 		// uppercase letter or "x:" it can be a user defined function.
2747 		// TODO: this is just guessing
2748 		if (res == FAIL && is_expr
2749 				   && (ASCII_ISUPPER(*name) || name[1] == ':'))
2750 		    res = generate_funcref(cctx, name);
2751 	    }
2752 	}
2753 	if (gen_load)
2754 	    res = generate_LOAD(cctx, ISN_LOAD, idx, NULL, type);
2755 	if (gen_load_outer > 0)
2756 	{
2757 	    res = generate_LOADOUTER(cctx, idx, gen_load_outer, type);
2758 	    cctx->ctx_outer_used = TRUE;
2759 	}
2760     }
2761 
2762     *arg = end;
2763 
2764 theend:
2765     if (res == FAIL && error && called_emsg == prev_called_emsg)
2766 	semsg(_(e_variable_not_found_str), name);
2767     vim_free(name);
2768     return res;
2769 }
2770 
2771 /*
2772  * Compile the argument expressions.
2773  * "arg" points to just after the "(" and is advanced to after the ")"
2774  */
2775     static int
2776 compile_arguments(char_u **arg, cctx_T *cctx, int *argcount)
2777 {
2778     char_u  *p = *arg;
2779     char_u  *whitep = *arg;
2780     int	    must_end = FALSE;
2781 
2782     for (;;)
2783     {
2784 	if (may_get_next_line(whitep, &p, cctx) == FAIL)
2785 	    goto failret;
2786 	if (*p == ')')
2787 	{
2788 	    *arg = p + 1;
2789 	    return OK;
2790 	}
2791 	if (must_end)
2792 	{
2793 	    semsg(_(e_missing_comma_before_argument_str), p);
2794 	    return FAIL;
2795 	}
2796 
2797 	if (compile_expr0(&p, cctx) == FAIL)
2798 	    return FAIL;
2799 	++*argcount;
2800 
2801 	if (*p != ',' && *skipwhite(p) == ',')
2802 	{
2803 	    semsg(_(e_no_white_space_allowed_before_str), ",");
2804 	    p = skipwhite(p);
2805 	}
2806 	if (*p == ',')
2807 	{
2808 	    ++p;
2809 	    if (*p != NUL && !VIM_ISWHITE(*p))
2810 		semsg(_(e_white_space_required_after_str), ",");
2811 	}
2812 	else
2813 	    must_end = TRUE;
2814 	whitep = p;
2815 	p = skipwhite(p);
2816     }
2817 failret:
2818     emsg(_(e_missing_close));
2819     return FAIL;
2820 }
2821 
2822 /*
2823  * Compile a function call:  name(arg1, arg2)
2824  * "arg" points to "name", "arg + varlen" to the "(".
2825  * "argcount_init" is 1 for "value->method()"
2826  * Instructions:
2827  *	EVAL arg1
2828  *	EVAL arg2
2829  *	BCALL / DCALL / UCALL
2830  */
2831     static int
2832 compile_call(
2833 	char_u	    **arg,
2834 	size_t	    varlen,
2835 	cctx_T	    *cctx,
2836 	ppconst_T   *ppconst,
2837 	int	    argcount_init)
2838 {
2839     char_u	*name = *arg;
2840     char_u	*p;
2841     int		argcount = argcount_init;
2842     char_u	namebuf[100];
2843     char_u	fname_buf[FLEN_FIXED + 1];
2844     char_u	*tofree = NULL;
2845     int		error = FCERR_NONE;
2846     ufunc_T	*ufunc = NULL;
2847     int		res = FAIL;
2848     int		is_autoload;
2849 
2850     // we can evaluate "has('name')" at compile time
2851     if (varlen == 3 && STRNCMP(*arg, "has", 3) == 0)
2852     {
2853 	char_u	    *s = skipwhite(*arg + varlen + 1);
2854 	typval_T    argvars[2];
2855 
2856 	argvars[0].v_type = VAR_UNKNOWN;
2857 	if (*s == '"')
2858 	    (void)eval_string(&s, &argvars[0], TRUE);
2859 	else if (*s == '\'')
2860 	    (void)eval_lit_string(&s, &argvars[0], TRUE);
2861 	s = skipwhite(s);
2862 	if (*s == ')' && argvars[0].v_type == VAR_STRING
2863 		&& !dynamic_feature(argvars[0].vval.v_string))
2864 	{
2865 	    typval_T	*tv = &ppconst->pp_tv[ppconst->pp_used];
2866 
2867 	    *arg = s + 1;
2868 	    argvars[1].v_type = VAR_UNKNOWN;
2869 	    tv->v_type = VAR_NUMBER;
2870 	    tv->vval.v_number = 0;
2871 	    f_has(argvars, tv);
2872 	    clear_tv(&argvars[0]);
2873 	    ++ppconst->pp_used;
2874 	    return OK;
2875 	}
2876 	clear_tv(&argvars[0]);
2877     }
2878 
2879     if (generate_ppconst(cctx, ppconst) == FAIL)
2880 	return FAIL;
2881 
2882     if (varlen >= sizeof(namebuf))
2883     {
2884 	semsg(_(e_name_too_long_str), name);
2885 	return FAIL;
2886     }
2887     vim_strncpy(namebuf, *arg, varlen);
2888     name = fname_trans_sid(namebuf, fname_buf, &tofree, &error);
2889 
2890     *arg = skipwhite(*arg + varlen + 1);
2891     if (compile_arguments(arg, cctx, &argcount) == FAIL)
2892 	goto theend;
2893 
2894     is_autoload = vim_strchr(name, AUTOLOAD_CHAR) != NULL;
2895     if (ASCII_ISLOWER(*name) && name[1] != ':' && !is_autoload)
2896     {
2897 	int	    idx;
2898 
2899 	// builtin function
2900 	idx = find_internal_func(name);
2901 	if (idx >= 0)
2902 	{
2903 	    if (STRCMP(name, "add") == 0 && argcount == 2)
2904 	    {
2905 		garray_T    *stack = &cctx->ctx_type_stack;
2906 		type_T	    *type = ((type_T **)stack->ga_data)[
2907 							    stack->ga_len - 2];
2908 
2909 		// add() can be compiled to instructions if we know the type
2910 		if (type->tt_type == VAR_LIST)
2911 		{
2912 		    // inline "add(list, item)" so that the type can be checked
2913 		    res = generate_LISTAPPEND(cctx);
2914 		    idx = -1;
2915 		}
2916 		else if (type->tt_type == VAR_BLOB)
2917 		{
2918 		    // inline "add(blob, nr)" so that the type can be checked
2919 		    res = generate_BLOBAPPEND(cctx);
2920 		    idx = -1;
2921 		}
2922 	    }
2923 
2924 	    if (idx >= 0)
2925 		res = generate_BCALL(cctx, idx, argcount, argcount_init == 1);
2926 	}
2927 	else
2928 	    semsg(_(e_unknownfunc), namebuf);
2929 	goto theend;
2930     }
2931 
2932     // An argument or local variable can be a function reference, this
2933     // overrules a function name.
2934     if (lookup_local(namebuf, varlen, NULL, cctx) == FAIL
2935 	    && arg_exists(namebuf, varlen, NULL, NULL, NULL, cctx) != OK)
2936     {
2937 	// If we can find the function by name generate the right call.
2938 	// Skip global functions here, a local funcref takes precedence.
2939 	ufunc = find_func(name, FALSE, cctx);
2940 	if (ufunc != NULL && !func_is_global(ufunc))
2941 	{
2942 	    res = generate_CALL(cctx, ufunc, argcount);
2943 	    goto theend;
2944 	}
2945     }
2946 
2947     // If the name is a variable, load it and use PCALL.
2948     // Not for g:Func(), we don't know if it is a variable or not.
2949     // Not for eome#Func(), it will be loaded later.
2950     p = namebuf;
2951     if (STRNCMP(namebuf, "g:", 2) != 0 && !is_autoload
2952 	    && compile_load(&p, namebuf + varlen, cctx, FALSE, FALSE) == OK)
2953     {
2954 	garray_T    *stack = &cctx->ctx_type_stack;
2955 	type_T	    *type = ((type_T **)stack->ga_data)[stack->ga_len - 1];
2956 
2957 	res = generate_PCALL(cctx, argcount, namebuf, type, FALSE);
2958 	goto theend;
2959     }
2960 
2961     // If we can find a global function by name generate the right call.
2962     if (ufunc != NULL)
2963     {
2964 	res = generate_CALL(cctx, ufunc, argcount);
2965 	goto theend;
2966     }
2967 
2968     // A global function may be defined only later.  Need to figure out at
2969     // runtime.  Also handles a FuncRef at runtime.
2970     if (STRNCMP(namebuf, "g:", 2) == 0 || is_autoload)
2971 	res = generate_UCALL(cctx, name, argcount);
2972     else
2973 	semsg(_(e_unknownfunc), namebuf);
2974 
2975 theend:
2976     vim_free(tofree);
2977     return res;
2978 }
2979 
2980 // like NAMESPACE_CHAR but with 'a' and 'l'.
2981 #define VIM9_NAMESPACE_CHAR	(char_u *)"bgstvw"
2982 
2983 /*
2984  * Find the end of a variable or function name.  Unlike find_name_end() this
2985  * does not recognize magic braces.
2986  * When "use_namespace" is TRUE recognize "b:", "s:", etc.
2987  * Return a pointer to just after the name.  Equal to "arg" if there is no
2988  * valid name.
2989  */
2990     char_u *
2991 to_name_end(char_u *arg, int use_namespace)
2992 {
2993     char_u	*p;
2994 
2995     // Quick check for valid starting character.
2996     if (!eval_isnamec1(*arg))
2997 	return arg;
2998 
2999     for (p = arg + 1; *p != NUL && eval_isnamec(*p); MB_PTR_ADV(p))
3000 	// Include a namespace such as "s:var" and "v:var".  But "n:" is not
3001 	// and can be used in slice "[n:]".
3002 	if (*p == ':' && (p != arg + 1
3003 			     || !use_namespace
3004 			     || vim_strchr(VIM9_NAMESPACE_CHAR, *arg) == NULL))
3005 	    break;
3006     return p;
3007 }
3008 
3009 /*
3010  * Like to_name_end() but also skip over a list or dict constant.
3011  * This intentionally does not handle line continuation.
3012  */
3013     char_u *
3014 to_name_const_end(char_u *arg)
3015 {
3016     char_u	*p = to_name_end(arg, TRUE);
3017     typval_T	rettv;
3018 
3019     if (p == arg && *arg == '[')
3020     {
3021 
3022 	// Can be "[1, 2, 3]->Func()".
3023 	if (eval_list(&p, &rettv, NULL, FALSE) == FAIL)
3024 	    p = arg;
3025     }
3026     return p;
3027 }
3028 
3029 /*
3030  * parse a list: [expr, expr]
3031  * "*arg" points to the '['.
3032  * ppconst->pp_is_const is set if all items are a constant.
3033  */
3034     static int
3035 compile_list(char_u **arg, cctx_T *cctx, ppconst_T *ppconst)
3036 {
3037     char_u	*p = skipwhite(*arg + 1);
3038     char_u	*whitep = *arg + 1;
3039     int		count = 0;
3040     int		is_const;
3041     int		is_all_const = TRUE;	// reset when non-const encountered
3042 
3043     for (;;)
3044     {
3045 	if (may_get_next_line(whitep, &p, cctx) == FAIL)
3046 	{
3047 	    semsg(_(e_list_end), *arg);
3048 	    return FAIL;
3049 	}
3050 	if (*p == ',')
3051 	{
3052 	    semsg(_(e_no_white_space_allowed_before_str), ",");
3053 	    return FAIL;
3054 	}
3055 	if (*p == ']')
3056 	{
3057 	    ++p;
3058 	    break;
3059 	}
3060 	if (compile_expr0_ext(&p, cctx, &is_const) == FAIL)
3061 	    return FAIL;
3062 	if (!is_const)
3063 	    is_all_const = FALSE;
3064 	++count;
3065 	if (*p == ',')
3066 	{
3067 	    ++p;
3068 	    if (*p != ']' && !IS_WHITE_OR_NUL(*p))
3069 	    {
3070 		semsg(_(e_white_space_required_after_str), ",");
3071 		return FAIL;
3072 	    }
3073 	}
3074 	whitep = p;
3075 	p = skipwhite(p);
3076     }
3077     *arg = p;
3078 
3079     ppconst->pp_is_const = is_all_const;
3080     return generate_NEWLIST(cctx, count);
3081 }
3082 
3083 /*
3084  * Parse a lambda: "(arg, arg) => expr"
3085  * "*arg" points to the '{'.
3086  * Returns OK/FAIL when a lambda is recognized, NOTDONE if it's not a lambda.
3087  */
3088     static int
3089 compile_lambda(char_u **arg, cctx_T *cctx)
3090 {
3091     int		r;
3092     typval_T	rettv;
3093     ufunc_T	*ufunc;
3094     evalarg_T	evalarg;
3095 
3096     CLEAR_FIELD(evalarg);
3097     evalarg.eval_flags = EVAL_EVALUATE;
3098     evalarg.eval_cctx = cctx;
3099 
3100     // Get the funcref in "rettv".
3101     r = get_lambda_tv(arg, &rettv, TRUE, &evalarg);
3102     if (r != OK)
3103     {
3104 	clear_evalarg(&evalarg, NULL);
3105 	return r;
3106     }
3107 
3108     // "rettv" will now be a partial referencing the function.
3109     ufunc = rettv.vval.v_partial->pt_func;
3110     ++ufunc->uf_refcount;
3111     clear_tv(&rettv);
3112 
3113     // Compile the function into instructions.
3114     compile_def_function(ufunc, TRUE, PROFILING(ufunc), cctx);
3115 
3116     clear_evalarg(&evalarg, NULL);
3117 
3118     if (ufunc->uf_def_status == UF_COMPILED)
3119     {
3120 	// The return type will now be known.
3121 	set_function_type(ufunc);
3122 
3123 	// The function reference count will be 1.  When the ISN_FUNCREF
3124 	// instruction is deleted the reference count is decremented and the
3125 	// function is freed.
3126 	return generate_FUNCREF(cctx, ufunc);
3127     }
3128 
3129     func_ptr_unref(ufunc);
3130     return FAIL;
3131 }
3132 
3133 /*
3134  * parse a dict: {key: val, [key]: val}
3135  * "*arg" points to the '{'.
3136  * ppconst->pp_is_const is set if all item values are a constant.
3137  */
3138     static int
3139 compile_dict(char_u **arg, cctx_T *cctx, ppconst_T *ppconst)
3140 {
3141     garray_T	*instr = &cctx->ctx_instr;
3142     garray_T	*stack = &cctx->ctx_type_stack;
3143     int		count = 0;
3144     dict_T	*d = dict_alloc();
3145     dictitem_T	*item;
3146     char_u	*whitep = *arg + 1;
3147     char_u	*p;
3148     int		is_const;
3149     int		is_all_const = TRUE;	// reset when non-const encountered
3150 
3151     if (d == NULL)
3152 	return FAIL;
3153     if (generate_ppconst(cctx, ppconst) == FAIL)
3154 	return FAIL;
3155     for (;;)
3156     {
3157 	char_u	    *key = NULL;
3158 
3159 	if (may_get_next_line(whitep, arg, cctx) == FAIL)
3160 	{
3161 	    *arg = NULL;
3162 	    goto failret;
3163 	}
3164 
3165 	if (**arg == '}')
3166 	    break;
3167 
3168 	if (**arg == '[')
3169 	{
3170 	    isn_T	*isn;
3171 
3172 	    // {[expr]: value} uses an evaluated key.
3173 	    *arg = skipwhite(*arg + 1);
3174 	    if (compile_expr0(arg, cctx) == FAIL)
3175 		return FAIL;
3176 	    isn = ((isn_T *)instr->ga_data) + instr->ga_len - 1;
3177 	    if (isn->isn_type == ISN_PUSHS)
3178 		key = isn->isn_arg.string;
3179 	    else
3180 	    {
3181 		type_T *keytype = ((type_T **)stack->ga_data)
3182 						       [stack->ga_len - 1];
3183 		if (need_type(keytype, &t_string, -1, 0, cctx,
3184 						     FALSE, FALSE) == FAIL)
3185 		    return FAIL;
3186 	    }
3187 	    *arg = skipwhite(*arg);
3188 	    if (**arg != ']')
3189 	    {
3190 		emsg(_(e_missing_matching_bracket_after_dict_key));
3191 		return FAIL;
3192 	    }
3193 	    ++*arg;
3194 	}
3195 	else
3196 	{
3197 	    // {"name": value},
3198 	    // {'name': value},
3199 	    // {name: value} use "name" as a literal key
3200 	    key = get_literal_key(arg);
3201 	    if (key == NULL)
3202 		return FAIL;
3203 	    if (generate_PUSHS(cctx, key) == FAIL)
3204 		return FAIL;
3205 	}
3206 
3207 	// Check for duplicate keys, if using string keys.
3208 	if (key != NULL)
3209 	{
3210 	    item = dict_find(d, key, -1);
3211 	    if (item != NULL)
3212 	    {
3213 		semsg(_(e_duplicate_key), key);
3214 		goto failret;
3215 	    }
3216 	    item = dictitem_alloc(key);
3217 	    if (item != NULL)
3218 	    {
3219 		item->di_tv.v_type = VAR_UNKNOWN;
3220 		item->di_tv.v_lock = 0;
3221 		if (dict_add(d, item) == FAIL)
3222 		    dictitem_free(item);
3223 	    }
3224 	}
3225 
3226 	if (**arg != ':')
3227 	{
3228 	    if (*skipwhite(*arg) == ':')
3229 		semsg(_(e_no_white_space_allowed_before_str), ":");
3230 	    else
3231 		semsg(_(e_missing_dict_colon), *arg);
3232 	    return FAIL;
3233 	}
3234 	whitep = *arg + 1;
3235 	if (!IS_WHITE_OR_NUL(*whitep))
3236 	{
3237 	    semsg(_(e_white_space_required_after_str), ":");
3238 	    return FAIL;
3239 	}
3240 
3241 	if (may_get_next_line(whitep, arg, cctx) == FAIL)
3242 	{
3243 	    *arg = NULL;
3244 	    goto failret;
3245 	}
3246 
3247 	if (compile_expr0_ext(arg, cctx, &is_const) == FAIL)
3248 	    return FAIL;
3249 	if (!is_const)
3250 	    is_all_const = FALSE;
3251 	++count;
3252 
3253 	whitep = *arg;
3254 	if (may_get_next_line(whitep, arg, cctx) == FAIL)
3255 	{
3256 	    *arg = NULL;
3257 	    goto failret;
3258 	}
3259 	if (**arg == '}')
3260 	    break;
3261 	if (**arg != ',')
3262 	{
3263 	    semsg(_(e_missing_dict_comma), *arg);
3264 	    goto failret;
3265 	}
3266 	if (IS_WHITE_OR_NUL(*whitep))
3267 	{
3268 	    semsg(_(e_no_white_space_allowed_before_str), ",");
3269 	    return FAIL;
3270 	}
3271 	whitep = *arg + 1;
3272 	if (!IS_WHITE_OR_NUL(*whitep))
3273 	{
3274 	    semsg(_(e_white_space_required_after_str), ",");
3275 	    return FAIL;
3276 	}
3277 	*arg = skipwhite(*arg + 1);
3278     }
3279 
3280     *arg = *arg + 1;
3281 
3282     // Allow for following comment, after at least one space.
3283     p = skipwhite(*arg);
3284     if (VIM_ISWHITE(**arg) && vim9_comment_start(p))
3285 	*arg += STRLEN(*arg);
3286 
3287     dict_unref(d);
3288     ppconst->pp_is_const = is_all_const;
3289     return generate_NEWDICT(cctx, count);
3290 
3291 failret:
3292     if (*arg == NULL)
3293     {
3294 	semsg(_(e_missing_dict_end), _("[end of lines]"));
3295 	*arg = (char_u *)"";
3296     }
3297     dict_unref(d);
3298     return FAIL;
3299 }
3300 
3301 /*
3302  * Compile "&option".
3303  */
3304     static int
3305 compile_get_option(char_u **arg, cctx_T *cctx)
3306 {
3307     typval_T	rettv;
3308     char_u	*start = *arg;
3309     int		ret;
3310 
3311     // parse the option and get the current value to get the type.
3312     rettv.v_type = VAR_UNKNOWN;
3313     ret = eval_option(arg, &rettv, TRUE);
3314     if (ret == OK)
3315     {
3316 	// include the '&' in the name, eval_option() expects it.
3317 	char_u	*name = vim_strnsave(start, *arg - start);
3318 	type_T	*type = rettv.v_type == VAR_BOOL ? &t_bool
3319 			  : rettv.v_type == VAR_NUMBER ? &t_number : &t_string;
3320 
3321 	ret = generate_LOAD(cctx, ISN_LOADOPT, 0, name, type);
3322 	vim_free(name);
3323     }
3324     clear_tv(&rettv);
3325 
3326     return ret;
3327 }
3328 
3329 /*
3330  * Compile "$VAR".
3331  */
3332     static int
3333 compile_get_env(char_u **arg, cctx_T *cctx)
3334 {
3335     char_u	*start = *arg;
3336     int		len;
3337     int		ret;
3338     char_u	*name;
3339 
3340     ++*arg;
3341     len = get_env_len(arg);
3342     if (len == 0)
3343     {
3344 	semsg(_(e_syntax_error_at_str), start - 1);
3345 	return FAIL;
3346     }
3347 
3348     // include the '$' in the name, eval_env_var() expects it.
3349     name = vim_strnsave(start, len + 1);
3350     ret = generate_LOAD(cctx, ISN_LOADENV, 0, name, &t_string);
3351     vim_free(name);
3352     return ret;
3353 }
3354 
3355 /*
3356  * Compile "@r".
3357  */
3358     static int
3359 compile_get_register(char_u **arg, cctx_T *cctx)
3360 {
3361     int		ret;
3362 
3363     ++*arg;
3364     if (**arg == NUL)
3365     {
3366 	semsg(_(e_syntax_error_at_str), *arg - 1);
3367 	return FAIL;
3368     }
3369     if (!valid_yank_reg(**arg, FALSE))
3370     {
3371 	emsg_invreg(**arg);
3372 	return FAIL;
3373     }
3374     ret = generate_LOAD(cctx, ISN_LOADREG, **arg, NULL, &t_string);
3375     ++*arg;
3376     return ret;
3377 }
3378 
3379 /*
3380  * Apply leading '!', '-' and '+' to constant "rettv".
3381  * When "numeric_only" is TRUE do not apply '!'.
3382  */
3383     static int
3384 apply_leader(typval_T *rettv, int numeric_only, char_u *start, char_u **end)
3385 {
3386     char_u *p = *end;
3387 
3388     // this works from end to start
3389     while (p > start)
3390     {
3391 	--p;
3392 	if (*p == '-' || *p == '+')
3393 	{
3394 	    // only '-' has an effect, for '+' we only check the type
3395 #ifdef FEAT_FLOAT
3396 	    if (rettv->v_type == VAR_FLOAT)
3397 	    {
3398 		if (*p == '-')
3399 		    rettv->vval.v_float = -rettv->vval.v_float;
3400 	    }
3401 	    else
3402 #endif
3403 	    {
3404 		varnumber_T	val;
3405 		int		error = FALSE;
3406 
3407 		// tv_get_number_chk() accepts a string, but we don't want that
3408 		// here
3409 		if (check_not_string(rettv) == FAIL)
3410 		    return FAIL;
3411 		val = tv_get_number_chk(rettv, &error);
3412 		clear_tv(rettv);
3413 		if (error)
3414 		    return FAIL;
3415 		if (*p == '-')
3416 		    val = -val;
3417 		rettv->v_type = VAR_NUMBER;
3418 		rettv->vval.v_number = val;
3419 	    }
3420 	}
3421 	else if (numeric_only)
3422 	{
3423 	    ++p;
3424 	    break;
3425 	}
3426 	else if (*p == '!')
3427 	{
3428 	    int v = tv2bool(rettv);
3429 
3430 	    // '!' is permissive in the type.
3431 	    clear_tv(rettv);
3432 	    rettv->v_type = VAR_BOOL;
3433 	    rettv->vval.v_number = v ? VVAL_FALSE : VVAL_TRUE;
3434 	}
3435     }
3436     *end = p;
3437     return OK;
3438 }
3439 
3440 /*
3441  * Recognize v: variables that are constants and set "rettv".
3442  */
3443     static void
3444 get_vim_constant(char_u **arg, typval_T *rettv)
3445 {
3446     if (STRNCMP(*arg, "v:true", 6) == 0)
3447     {
3448 	rettv->v_type = VAR_BOOL;
3449 	rettv->vval.v_number = VVAL_TRUE;
3450 	*arg += 6;
3451     }
3452     else if (STRNCMP(*arg, "v:false", 7) == 0)
3453     {
3454 	rettv->v_type = VAR_BOOL;
3455 	rettv->vval.v_number = VVAL_FALSE;
3456 	*arg += 7;
3457     }
3458     else if (STRNCMP(*arg, "v:null", 6) == 0)
3459     {
3460 	rettv->v_type = VAR_SPECIAL;
3461 	rettv->vval.v_number = VVAL_NULL;
3462 	*arg += 6;
3463     }
3464     else if (STRNCMP(*arg, "v:none", 6) == 0)
3465     {
3466 	rettv->v_type = VAR_SPECIAL;
3467 	rettv->vval.v_number = VVAL_NONE;
3468 	*arg += 6;
3469     }
3470 }
3471 
3472     exprtype_T
3473 get_compare_type(char_u *p, int *len, int *type_is)
3474 {
3475     exprtype_T	type = EXPR_UNKNOWN;
3476     int		i;
3477 
3478     switch (p[0])
3479     {
3480 	case '=':   if (p[1] == '=')
3481 			type = EXPR_EQUAL;
3482 		    else if (p[1] == '~')
3483 			type = EXPR_MATCH;
3484 		    break;
3485 	case '!':   if (p[1] == '=')
3486 			type = EXPR_NEQUAL;
3487 		    else if (p[1] == '~')
3488 			type = EXPR_NOMATCH;
3489 		    break;
3490 	case '>':   if (p[1] != '=')
3491 		    {
3492 			type = EXPR_GREATER;
3493 			*len = 1;
3494 		    }
3495 		    else
3496 			type = EXPR_GEQUAL;
3497 		    break;
3498 	case '<':   if (p[1] != '=')
3499 		    {
3500 			type = EXPR_SMALLER;
3501 			*len = 1;
3502 		    }
3503 		    else
3504 			type = EXPR_SEQUAL;
3505 		    break;
3506 	case 'i':   if (p[1] == 's')
3507 		    {
3508 			// "is" and "isnot"; but not a prefix of a name
3509 			if (p[2] == 'n' && p[3] == 'o' && p[4] == 't')
3510 			    *len = 5;
3511 			i = p[*len];
3512 			if (!isalnum(i) && i != '_')
3513 			{
3514 			    type = *len == 2 ? EXPR_IS : EXPR_ISNOT;
3515 			    *type_is = TRUE;
3516 			}
3517 		    }
3518 		    break;
3519     }
3520     return type;
3521 }
3522 
3523 /*
3524  * Skip over an expression, ignoring most errors.
3525  */
3526     static void
3527 skip_expr_cctx(char_u **arg, cctx_T *cctx)
3528 {
3529     evalarg_T	evalarg;
3530 
3531     CLEAR_FIELD(evalarg);
3532     evalarg.eval_cctx = cctx;
3533     skip_expr(arg, &evalarg);
3534 }
3535 
3536 /*
3537  * Compile code to apply '-', '+' and '!'.
3538  * When "numeric_only" is TRUE do not apply '!'.
3539  */
3540     static int
3541 compile_leader(cctx_T *cctx, int numeric_only, char_u *start, char_u **end)
3542 {
3543     char_u	*p = *end;
3544 
3545     // this works from end to start
3546     while (p > start)
3547     {
3548 	--p;
3549 	while (VIM_ISWHITE(*p))
3550 	    --p;
3551 	if (*p == '-' || *p == '+')
3552 	{
3553 	    int	    negate = *p == '-';
3554 	    isn_T   *isn;
3555 
3556 	    // TODO: check type
3557 	    while (p > start && (p[-1] == '-' || p[-1] == '+'))
3558 	    {
3559 		--p;
3560 		if (*p == '-')
3561 		    negate = !negate;
3562 	    }
3563 	    // only '-' has an effect, for '+' we only check the type
3564 	    if (negate)
3565 		isn = generate_instr(cctx, ISN_NEGATENR);
3566 	    else
3567 		isn = generate_instr(cctx, ISN_CHECKNR);
3568 	    if (isn == NULL)
3569 		return FAIL;
3570 	}
3571 	else if (numeric_only)
3572 	{
3573 	    ++p;
3574 	    break;
3575 	}
3576 	else
3577 	{
3578 	    int  invert = *p == '!';
3579 
3580 	    while (p > start && (p[-1] == '!' || VIM_ISWHITE(p[-1])))
3581 	    {
3582 		if (p[-1] == '!')
3583 		    invert = !invert;
3584 		--p;
3585 	    }
3586 	    if (generate_2BOOL(cctx, invert) == FAIL)
3587 		return FAIL;
3588 	}
3589     }
3590     *end = p;
3591     return OK;
3592 }
3593 
3594 /*
3595  * Compile "(expression)": recursive!
3596  * Return FAIL/OK.
3597  */
3598     static int
3599 compile_parenthesis(char_u **arg, cctx_T *cctx, ppconst_T *ppconst)
3600 {
3601     int	    ret;
3602     char_u  *p = *arg + 1;
3603 
3604     if (may_get_next_line_error(p, arg, cctx) == FAIL)
3605 	return FAIL;
3606     if (ppconst->pp_used <= PPSIZE - 10)
3607     {
3608 	ret = compile_expr1(arg, cctx, ppconst);
3609     }
3610     else
3611     {
3612 	// Not enough space in ppconst, flush constants.
3613 	if (generate_ppconst(cctx, ppconst) == FAIL)
3614 	    return FAIL;
3615 	ret = compile_expr0(arg, cctx);
3616     }
3617     if (may_get_next_line_error(*arg, arg, cctx) == FAIL)
3618 	return FAIL;
3619     if (**arg == ')')
3620 	++*arg;
3621     else if (ret == OK)
3622     {
3623 	emsg(_(e_missing_close));
3624 	ret = FAIL;
3625     }
3626     return ret;
3627 }
3628 
3629 /*
3630  * Compile whatever comes after "name" or "name()".
3631  * Advances "*arg" only when something was recognized.
3632  */
3633     static int
3634 compile_subscript(
3635 	char_u **arg,
3636 	cctx_T *cctx,
3637 	char_u *start_leader,
3638 	char_u **end_leader,
3639 	ppconst_T *ppconst)
3640 {
3641     char_u	*name_start = *end_leader;
3642 
3643     for (;;)
3644     {
3645 	char_u *p = skipwhite(*arg);
3646 
3647 	if (*p == NUL || (VIM_ISWHITE(**arg) && vim9_comment_start(p)))
3648 	{
3649 	    char_u *next = peek_next_line_from_context(cctx);
3650 
3651 	    // If a following line starts with "->{" or "->X" advance to that
3652 	    // line, so that a line break before "->" is allowed.
3653 	    // Also if a following line starts with ".x".
3654 	    if (next != NULL &&
3655 		    ((next[0] == '-' && next[1] == '>'
3656 				 && (next[2] == '{' || ASCII_ISALPHA(next[2])))
3657 		    || (next[0] == '.' && eval_isdictc(next[1]))))
3658 	    {
3659 		next = next_line_from_context(cctx, TRUE);
3660 		if (next == NULL)
3661 		    return FAIL;
3662 		*arg = next;
3663 		p = skipwhite(*arg);
3664 	    }
3665 	}
3666 
3667 	// Do not skip over white space to find the "(", "execute 'x' ()" is
3668 	// not a function call.
3669 	if (**arg == '(')
3670 	{
3671 	    garray_T    *stack = &cctx->ctx_type_stack;
3672 	    type_T	*type;
3673 	    int		argcount = 0;
3674 
3675 	    if (generate_ppconst(cctx, ppconst) == FAIL)
3676 		return FAIL;
3677 	    ppconst->pp_is_const = FALSE;
3678 
3679 	    // funcref(arg)
3680 	    type = ((type_T **)stack->ga_data)[stack->ga_len - 1];
3681 
3682 	    *arg = skipwhite(p + 1);
3683 	    if (compile_arguments(arg, cctx, &argcount) == FAIL)
3684 		return FAIL;
3685 	    if (generate_PCALL(cctx, argcount, name_start, type, TRUE) == FAIL)
3686 		return FAIL;
3687 	}
3688 	else if (*p == '-' && p[1] == '>')
3689 	{
3690 	    char_u *pstart = p;
3691 
3692 	    if (generate_ppconst(cctx, ppconst) == FAIL)
3693 		return FAIL;
3694 	    ppconst->pp_is_const = FALSE;
3695 
3696 	    // something->method()
3697 	    // Apply the '!', '-' and '+' first:
3698 	    //   -1.0->func() works like (-1.0)->func()
3699 	    if (compile_leader(cctx, TRUE, start_leader, end_leader) == FAIL)
3700 		return FAIL;
3701 
3702 	    p += 2;
3703 	    *arg = skipwhite(p);
3704 	    // No line break supported right after "->".
3705 	    if (**arg == '(')
3706 	    {
3707 		int	    argcount = 1;
3708 		char_u	    *expr;
3709 		garray_T    *stack;
3710 		type_T	    *type;
3711 
3712 		// Funcref call:  list->(Refs[2])(arg)
3713 		// or lambda:	  list->((arg) => expr)(arg)
3714 		// Fist compile the arguments.
3715 		expr = *arg;
3716 		*arg = skipwhite(*arg + 1);
3717 		skip_expr_cctx(arg, cctx);
3718 		*arg = skipwhite(*arg);
3719 		if (**arg != ')')
3720 		{
3721 		    semsg(_(e_missing_paren), *arg);
3722 		    return FAIL;
3723 		}
3724 		++*arg;
3725 		if (**arg != '(')
3726 		{
3727 		    if (*skipwhite(*arg) == '(')
3728 			emsg(_(e_nowhitespace));
3729 		    else
3730 			semsg(_(e_missing_paren), *arg);
3731 		    return FAIL;
3732 		}
3733 
3734 		*arg = skipwhite(*arg + 1);
3735 		if (compile_arguments(arg, cctx, &argcount) == FAIL)
3736 		    return FAIL;
3737 
3738 		// Compile the function expression.
3739 		if (compile_parenthesis(&expr, cctx, ppconst) == FAIL)
3740 		    return FAIL;
3741 
3742 		stack = &cctx->ctx_type_stack;
3743 		type = ((type_T **)stack->ga_data)[stack->ga_len - 1];
3744 		if (generate_PCALL(cctx, argcount,
3745 				(char_u *)"[expression]", type, FALSE) == FAIL)
3746 		    return FAIL;
3747 	    }
3748 	    else
3749 	    {
3750 		// method call:  list->method()
3751 		p = *arg;
3752 		if (!eval_isnamec1(*p))
3753 		{
3754 		    semsg(_(e_trailing_arg), pstart);
3755 		    return FAIL;
3756 		}
3757 		if (ASCII_ISALPHA(*p) && p[1] == ':')
3758 		    p += 2;
3759 		for ( ; eval_isnamec(*p); ++p)
3760 		    ;
3761 		if (*p != '(')
3762 		{
3763 		    semsg(_(e_missing_paren), *arg);
3764 		    return FAIL;
3765 		}
3766 		// TODO: base value may not be the first argument
3767 		if (compile_call(arg, p - *arg, cctx, ppconst, 1) == FAIL)
3768 		    return FAIL;
3769 	    }
3770 	}
3771 	else if (**arg == '[')
3772 	{
3773 	    garray_T	*stack = &cctx->ctx_type_stack;
3774 	    type_T	**typep;
3775 	    type_T	*valtype;
3776 	    vartype_T	vtype;
3777 	    int		is_slice = FALSE;
3778 
3779 	    // list index: list[123]
3780 	    // dict member: dict[key]
3781 	    // string index: text[123]
3782 	    // TODO: blob index
3783 	    // TODO: more arguments
3784 	    // TODO: recognize list or dict at runtime
3785 	    if (generate_ppconst(cctx, ppconst) == FAIL)
3786 		return FAIL;
3787 	    ppconst->pp_is_const = FALSE;
3788 
3789 	    ++p;
3790 	    if (may_get_next_line_error(p, arg, cctx) == FAIL)
3791 		return FAIL;
3792 	    if (**arg == ':')
3793 	    {
3794 		// missing first index is equal to zero
3795 		generate_PUSHNR(cctx, 0);
3796 	    }
3797 	    else
3798 	    {
3799 		if (compile_expr0(arg, cctx) == FAIL)
3800 		    return FAIL;
3801 		if (**arg == ':')
3802 		{
3803 		    semsg(_(e_white_space_required_before_and_after_str_at_str),
3804 								    ":", *arg);
3805 		    return FAIL;
3806 		}
3807 		if (may_get_next_line_error(*arg, arg, cctx) == FAIL)
3808 		    return FAIL;
3809 		*arg = skipwhite(*arg);
3810 	    }
3811 	    if (**arg == ':')
3812 	    {
3813 		is_slice = TRUE;
3814 		++*arg;
3815 		if (!IS_WHITE_OR_NUL(**arg) && **arg != ']')
3816 		{
3817 		    semsg(_(e_white_space_required_before_and_after_str_at_str),
3818 								    ":", *arg);
3819 		    return FAIL;
3820 		}
3821 		if (may_get_next_line_error(*arg, arg, cctx) == FAIL)
3822 		    return FAIL;
3823 		if (**arg == ']')
3824 		    // missing second index is equal to end of string
3825 		    generate_PUSHNR(cctx, -1);
3826 		else
3827 		{
3828 		    if (compile_expr0(arg, cctx) == FAIL)
3829 			return FAIL;
3830 		    if (may_get_next_line_error(*arg, arg, cctx) == FAIL)
3831 			return FAIL;
3832 		    *arg = skipwhite(*arg);
3833 		}
3834 	    }
3835 
3836 	    if (**arg != ']')
3837 	    {
3838 		emsg(_(e_missbrac));
3839 		return FAIL;
3840 	    }
3841 	    *arg = *arg + 1;
3842 
3843 	    // We can index a list and a dict.  If we don't know the type
3844 	    // we can use the index value type.
3845 	    // TODO: If we don't know use an instruction to figure it out at
3846 	    // runtime.
3847 	    typep = ((type_T **)stack->ga_data) + stack->ga_len
3848 							  - (is_slice ? 3 : 2);
3849 	    vtype = (*typep)->tt_type;
3850 	    valtype = ((type_T **)stack->ga_data)[stack->ga_len - 1];
3851 	    // If the index is a string, the variable must be a Dict.
3852 	    if (*typep == &t_any && valtype == &t_string)
3853 		vtype = VAR_DICT;
3854 	    if (vtype == VAR_STRING || vtype == VAR_LIST || vtype == VAR_BLOB)
3855 	    {
3856 		if (need_type(valtype, &t_number, -1, 0, cctx,
3857 							 FALSE, FALSE) == FAIL)
3858 		    return FAIL;
3859 		if (is_slice)
3860 		{
3861 		    valtype = ((type_T **)stack->ga_data)[stack->ga_len - 2];
3862 		    if (need_type(valtype, &t_number, -2, 0, cctx,
3863 							 FALSE, FALSE) == FAIL)
3864 			return FAIL;
3865 		}
3866 	    }
3867 
3868 	    if (vtype == VAR_DICT)
3869 	    {
3870 		if (is_slice)
3871 		{
3872 		    emsg(_(e_cannot_slice_dictionary));
3873 		    return FAIL;
3874 		}
3875 		if ((*typep)->tt_type == VAR_DICT)
3876 		{
3877 		    *typep = (*typep)->tt_member;
3878 		    if (*typep == &t_unknown)
3879 			// empty dict was used
3880 			*typep = &t_any;
3881 		}
3882 		else
3883 		{
3884 		    if (need_type(*typep, &t_dict_any, -2, 0, cctx,
3885 							 FALSE, FALSE) == FAIL)
3886 			return FAIL;
3887 		    *typep = &t_any;
3888 		}
3889 		if (may_generate_2STRING(-1, cctx) == FAIL)
3890 		    return FAIL;
3891 		if (generate_instr_drop(cctx, ISN_MEMBER, 1) == FAIL)
3892 		    return FAIL;
3893 	    }
3894 	    else if (vtype == VAR_STRING)
3895 	    {
3896 		*typep = &t_string;
3897 		if ((is_slice
3898 			? generate_instr_drop(cctx, ISN_STRSLICE, 2)
3899 			: generate_instr_drop(cctx, ISN_STRINDEX, 1)) == FAIL)
3900 		    return FAIL;
3901 	    }
3902 	    else if (vtype == VAR_BLOB)
3903 	    {
3904 		emsg("Sorry, blob index and slice not implemented yet");
3905 		return FAIL;
3906 	    }
3907 	    else if (vtype == VAR_LIST || *typep == &t_any)
3908 	    {
3909 		if (is_slice)
3910 		{
3911 		    if (generate_instr_drop(cctx,
3912 			     vtype == VAR_LIST ?  ISN_LISTSLICE : ISN_ANYSLICE,
3913 								    2) == FAIL)
3914 			return FAIL;
3915 		}
3916 		else
3917 		{
3918 		    if ((*typep)->tt_type == VAR_LIST)
3919 		    {
3920 			*typep = (*typep)->tt_member;
3921 			if (*typep == &t_unknown)
3922 			    // empty list was used
3923 			    *typep = &t_any;
3924 		    }
3925 		    if (generate_instr_drop(cctx,
3926 			     vtype == VAR_LIST ?  ISN_LISTINDEX : ISN_ANYINDEX,
3927 								    1) == FAIL)
3928 			return FAIL;
3929 		}
3930 	    }
3931 	    else
3932 	    {
3933 		emsg(_(e_string_list_dict_or_blob_required));
3934 		return FAIL;
3935 	    }
3936 	}
3937 	else if (*p == '.' && p[1] != '.')
3938 	{
3939 	    // dictionary member: dict.name
3940 	    if (generate_ppconst(cctx, ppconst) == FAIL)
3941 		return FAIL;
3942 	    ppconst->pp_is_const = FALSE;
3943 
3944 	    *arg = p + 1;
3945 	    if (may_get_next_line(*arg, arg, cctx) == FAIL)
3946 	    {
3947 		emsg(_(e_missing_name_after_dot));
3948 		return FAIL;
3949 	    }
3950 	    p = *arg;
3951 	    if (eval_isdictc(*p))
3952 		while (eval_isnamec(*p))
3953 		    MB_PTR_ADV(p);
3954 	    if (p == *arg)
3955 	    {
3956 		semsg(_(e_syntax_error_at_str), *arg);
3957 		return FAIL;
3958 	    }
3959 	    if (generate_STRINGMEMBER(cctx, *arg, p - *arg) == FAIL)
3960 		return FAIL;
3961 	    *arg = p;
3962 	}
3963 	else
3964 	    break;
3965     }
3966 
3967     // TODO - see handle_subscript():
3968     // Turn "dict.Func" into a partial for "Func" bound to "dict".
3969     // Don't do this when "Func" is already a partial that was bound
3970     // explicitly (pt_auto is FALSE).
3971 
3972     return OK;
3973 }
3974 
3975 /*
3976  * Compile an expression at "*arg" and add instructions to "cctx->ctx_instr".
3977  * "arg" is advanced until after the expression, skipping white space.
3978  *
3979  * If the value is a constant "ppconst->pp_used" will be non-zero.
3980  * Before instructions are generated, any values in "ppconst" will generated.
3981  *
3982  * This is the compiling equivalent of eval1(), eval2(), etc.
3983  */
3984 
3985 /*
3986  *  number		number constant
3987  *  0zFFFFFFFF		Blob constant
3988  *  "string"		string constant
3989  *  'string'		literal string constant
3990  *  &option-name	option value
3991  *  @r			register contents
3992  *  identifier		variable value
3993  *  function()		function call
3994  *  $VAR		environment variable
3995  *  (expression)	nested expression
3996  *  [expr, expr]	List
3997  *  {key: val, [key]: val}   Dictionary
3998  *
3999  *  Also handle:
4000  *  ! in front		logical NOT
4001  *  - in front		unary minus
4002  *  + in front		unary plus (ignored)
4003  *  trailing (arg)	funcref/partial call
4004  *  trailing []		subscript in String or List
4005  *  trailing .name	entry in Dictionary
4006  *  trailing ->name()	method call
4007  */
4008     static int
4009 compile_expr7(
4010 	char_u **arg,
4011 	cctx_T *cctx,
4012 	ppconst_T *ppconst)
4013 {
4014     char_u	*start_leader, *end_leader;
4015     int		ret = OK;
4016     typval_T	*rettv = &ppconst->pp_tv[ppconst->pp_used];
4017     int		used_before = ppconst->pp_used;
4018 
4019     ppconst->pp_is_const = FALSE;
4020 
4021     /*
4022      * Skip '!', '-' and '+' characters.  They are handled later.
4023      */
4024     start_leader = *arg;
4025     if (eval_leader(arg, TRUE) == FAIL)
4026 	return FAIL;
4027     end_leader = *arg;
4028 
4029     rettv->v_type = VAR_UNKNOWN;
4030     switch (**arg)
4031     {
4032 	/*
4033 	 * Number constant.
4034 	 */
4035 	case '0':	// also for blob starting with 0z
4036 	case '1':
4037 	case '2':
4038 	case '3':
4039 	case '4':
4040 	case '5':
4041 	case '6':
4042 	case '7':
4043 	case '8':
4044 	case '9':
4045 	case '.':   if (eval_number(arg, rettv, TRUE, FALSE) == FAIL)
4046 			return FAIL;
4047 		    // Apply "-" and "+" just before the number now, right to
4048 		    // left.  Matters especially when "->" follows.  Stops at
4049 		    // '!'.
4050 		    if (apply_leader(rettv, TRUE,
4051 					    start_leader, &end_leader) == FAIL)
4052 		    {
4053 			clear_tv(rettv);
4054 			return FAIL;
4055 		    }
4056 		    break;
4057 
4058 	/*
4059 	 * String constant: "string".
4060 	 */
4061 	case '"':   if (eval_string(arg, rettv, TRUE) == FAIL)
4062 			return FAIL;
4063 		    break;
4064 
4065 	/*
4066 	 * Literal string constant: 'str''ing'.
4067 	 */
4068 	case '\'':  if (eval_lit_string(arg, rettv, TRUE) == FAIL)
4069 			return FAIL;
4070 		    break;
4071 
4072 	/*
4073 	 * Constant Vim variable.
4074 	 */
4075 	case 'v':   get_vim_constant(arg, rettv);
4076 		    ret = NOTDONE;
4077 		    break;
4078 
4079 	/*
4080 	 * "true" constant
4081 	 */
4082 	case 't':   if (STRNCMP(*arg, "true", 4) == 0
4083 						   && !eval_isnamec((*arg)[4]))
4084 		    {
4085 			*arg += 4;
4086 			rettv->v_type = VAR_BOOL;
4087 			rettv->vval.v_number = VVAL_TRUE;
4088 		    }
4089 		    else
4090 			ret = NOTDONE;
4091 		    break;
4092 
4093 	/*
4094 	 * "false" constant
4095 	 */
4096 	case 'f':   if (STRNCMP(*arg, "false", 5) == 0
4097 						   && !eval_isnamec((*arg)[5]))
4098 		    {
4099 			*arg += 5;
4100 			rettv->v_type = VAR_BOOL;
4101 			rettv->vval.v_number = VVAL_FALSE;
4102 		    }
4103 		    else
4104 			ret = NOTDONE;
4105 		    break;
4106 
4107 	/*
4108 	 * "null" constant
4109 	 */
4110 	case 'n':   if (STRNCMP(*arg, "null", 4) == 0
4111 						   && !eval_isnamec((*arg)[5]))
4112 		    {
4113 			*arg += 4;
4114 			rettv->v_type = VAR_SPECIAL;
4115 			rettv->vval.v_number = VVAL_NULL;
4116 		    }
4117 		    else
4118 			ret = NOTDONE;
4119 		    break;
4120 
4121 	/*
4122 	 * List: [expr, expr]
4123 	 */
4124 	case '[':   ret = compile_list(arg, cctx, ppconst);
4125 		    break;
4126 
4127 	/*
4128 	 * Dictionary: {'key': val, 'key': val}
4129 	 */
4130 	case '{':   ret = compile_dict(arg, cctx, ppconst);
4131 		    break;
4132 
4133 	/*
4134 	 * Option value: &name
4135 	 */
4136 	case '&':	if (generate_ppconst(cctx, ppconst) == FAIL)
4137 			    return FAIL;
4138 			ret = compile_get_option(arg, cctx);
4139 			break;
4140 
4141 	/*
4142 	 * Environment variable: $VAR.
4143 	 */
4144 	case '$':	if (generate_ppconst(cctx, ppconst) == FAIL)
4145 			    return FAIL;
4146 			ret = compile_get_env(arg, cctx);
4147 			break;
4148 
4149 	/*
4150 	 * Register contents: @r.
4151 	 */
4152 	case '@':	if (generate_ppconst(cctx, ppconst) == FAIL)
4153 			    return FAIL;
4154 			ret = compile_get_register(arg, cctx);
4155 			break;
4156 	/*
4157 	 * nested expression: (expression).
4158 	 * lambda: (arg, arg) => expr
4159 	 * funcref: (arg, arg) => { statement }
4160 	 */
4161 	case '(':   // if compile_lambda returns NOTDONE then it must be (expr)
4162 		    ret = compile_lambda(arg, cctx);
4163 		    if (ret == NOTDONE)
4164 			ret = compile_parenthesis(arg, cctx, ppconst);
4165 		    break;
4166 
4167 	default:    ret = NOTDONE;
4168 		    break;
4169     }
4170     if (ret == FAIL)
4171 	return FAIL;
4172 
4173     if (rettv->v_type != VAR_UNKNOWN && used_before == ppconst->pp_used)
4174     {
4175 	if (cctx->ctx_skip == SKIP_YES)
4176 	    clear_tv(rettv);
4177 	else
4178 	    // A constant expression can possibly be handled compile time,
4179 	    // return the value instead of generating code.
4180 	    ++ppconst->pp_used;
4181     }
4182     else if (ret == NOTDONE)
4183     {
4184 	char_u	    *p;
4185 	int	    r;
4186 
4187 	if (!eval_isnamec1(**arg))
4188 	{
4189 	    if (ends_excmd(*skipwhite(*arg)))
4190 		semsg(_(e_empty_expression_str), *arg);
4191 	    else
4192 		semsg(_(e_name_expected_str), *arg);
4193 	    return FAIL;
4194 	}
4195 
4196 	// "name" or "name()"
4197 	p = to_name_end(*arg, TRUE);
4198 	if (*p == '(')
4199 	{
4200 	    r = compile_call(arg, p - *arg, cctx, ppconst, 0);
4201 	}
4202 	else
4203 	{
4204 	    if (generate_ppconst(cctx, ppconst) == FAIL)
4205 		return FAIL;
4206 	    r = compile_load(arg, p, cctx, TRUE, TRUE);
4207 	}
4208 	if (r == FAIL)
4209 	    return FAIL;
4210     }
4211 
4212     // Handle following "[]", ".member", etc.
4213     // Then deal with prefixed '-', '+' and '!', if not done already.
4214     if (compile_subscript(arg, cctx, start_leader, &end_leader,
4215 							     ppconst) == FAIL)
4216 	return FAIL;
4217     if (ppconst->pp_used > 0)
4218     {
4219 	// apply the '!', '-' and '+' before the constant
4220 	rettv = &ppconst->pp_tv[ppconst->pp_used - 1];
4221 	if (apply_leader(rettv, FALSE, start_leader, &end_leader) == FAIL)
4222 	    return FAIL;
4223 	return OK;
4224     }
4225     if (compile_leader(cctx, FALSE, start_leader, &end_leader) == FAIL)
4226 	return FAIL;
4227     return OK;
4228 }
4229 
4230 /*
4231  * Give the "white on both sides" error, taking the operator from "p[len]".
4232  */
4233     void
4234 error_white_both(char_u *op, int len)
4235 {
4236     char_u	buf[10];
4237 
4238     vim_strncpy(buf, op, len);
4239     semsg(_(e_white_space_required_before_and_after_str_at_str), buf, op);
4240 }
4241 
4242 /*
4243  * <type>expr7: runtime type check / conversion
4244  */
4245     static int
4246 compile_expr7t(char_u **arg, cctx_T *cctx, ppconst_T *ppconst)
4247 {
4248     type_T *want_type = NULL;
4249 
4250     // Recognize <type>
4251     if (**arg == '<' && eval_isnamec1((*arg)[1]))
4252     {
4253 	++*arg;
4254 	want_type = parse_type(arg, cctx->ctx_type_list, TRUE);
4255 	if (want_type == NULL)
4256 	    return FAIL;
4257 
4258 	if (**arg != '>')
4259 	{
4260 	    if (*skipwhite(*arg) == '>')
4261 		semsg(_(e_no_white_space_allowed_before_str), ">");
4262 	    else
4263 		emsg(_(e_missing_gt));
4264 	    return FAIL;
4265 	}
4266 	++*arg;
4267 	if (may_get_next_line_error(*arg, arg, cctx) == FAIL)
4268 	    return FAIL;
4269     }
4270 
4271     if (compile_expr7(arg, cctx, ppconst) == FAIL)
4272 	return FAIL;
4273 
4274     if (want_type != NULL)
4275     {
4276 	garray_T    *stack = &cctx->ctx_type_stack;
4277 	type_T	    *actual;
4278 
4279 	generate_ppconst(cctx, ppconst);
4280 	actual = ((type_T **)stack->ga_data)[stack->ga_len - 1];
4281 	if (check_type(want_type, actual, FALSE, 0) == FAIL)
4282 	{
4283 	    if (need_type(actual, want_type, -1, 0, cctx, FALSE, FALSE) == FAIL)
4284 		return FAIL;
4285 	}
4286     }
4287 
4288     return OK;
4289 }
4290 
4291 /*
4292  *	*	number multiplication
4293  *	/	number division
4294  *	%	number modulo
4295  */
4296     static int
4297 compile_expr6(char_u **arg, cctx_T *cctx, ppconst_T *ppconst)
4298 {
4299     char_u	*op;
4300     char_u	*next;
4301     int		ppconst_used = ppconst->pp_used;
4302 
4303     // get the first expression
4304     if (compile_expr7t(arg, cctx, ppconst) == FAIL)
4305 	return FAIL;
4306 
4307     /*
4308      * Repeat computing, until no "*", "/" or "%" is following.
4309      */
4310     for (;;)
4311     {
4312 	op = may_peek_next_line(cctx, *arg, &next);
4313 	if (*op != '*' && *op != '/' && *op != '%')
4314 	    break;
4315 	if (next != NULL)
4316 	{
4317 	    *arg = next_line_from_context(cctx, TRUE);
4318 	    op = skipwhite(*arg);
4319 	}
4320 
4321 	if (!IS_WHITE_OR_NUL(**arg) || !IS_WHITE_OR_NUL(op[1]))
4322 	{
4323 	    error_white_both(op, 1);
4324 	    return FAIL;
4325 	}
4326 	if (may_get_next_line_error(op + 1, arg, cctx) == FAIL)
4327 	    return FAIL;
4328 
4329 	// get the second expression
4330 	if (compile_expr7t(arg, cctx, ppconst) == FAIL)
4331 	    return FAIL;
4332 
4333 	if (ppconst->pp_used == ppconst_used + 2
4334 		&& ppconst->pp_tv[ppconst_used].v_type == VAR_NUMBER
4335 		&& ppconst->pp_tv[ppconst_used + 1].v_type == VAR_NUMBER)
4336 	{
4337 	    typval_T	    *tv1 = &ppconst->pp_tv[ppconst_used];
4338 	    typval_T	    *tv2 = &ppconst->pp_tv[ppconst_used + 1];
4339 	    varnumber_T	    res = 0;
4340 	    int		    failed = FALSE;
4341 
4342 	    // both are numbers: compute the result
4343 	    switch (*op)
4344 	    {
4345 		case '*': res = tv1->vval.v_number * tv2->vval.v_number;
4346 			  break;
4347 		case '/': res = num_divide(tv1->vval.v_number,
4348 						  tv2->vval.v_number, &failed);
4349 			  break;
4350 		case '%': res = num_modulus(tv1->vval.v_number,
4351 						  tv2->vval.v_number, &failed);
4352 			  break;
4353 	    }
4354 	    if (failed)
4355 		return FAIL;
4356 	    tv1->vval.v_number = res;
4357 	    --ppconst->pp_used;
4358 	}
4359 	else
4360 	{
4361 	    generate_ppconst(cctx, ppconst);
4362 	    generate_two_op(cctx, op);
4363 	}
4364     }
4365 
4366     return OK;
4367 }
4368 
4369 /*
4370  *      +	number addition
4371  *      -	number subtraction
4372  *      ..	string concatenation
4373  */
4374     static int
4375 compile_expr5(char_u **arg, cctx_T *cctx, ppconst_T *ppconst)
4376 {
4377     char_u	*op;
4378     char_u	*next;
4379     int		oplen;
4380     int		ppconst_used = ppconst->pp_used;
4381 
4382     // get the first variable
4383     if (compile_expr6(arg, cctx, ppconst) == FAIL)
4384 	return FAIL;
4385 
4386     /*
4387      * Repeat computing, until no "+", "-" or ".." is following.
4388      */
4389     for (;;)
4390     {
4391 	op = may_peek_next_line(cctx, *arg, &next);
4392 	if (*op != '+' && *op != '-' && !(*op == '.' && *(op + 1) == '.'))
4393 	    break;
4394 	oplen = (*op == '.' ? 2 : 1);
4395 	if (next != NULL)
4396 	{
4397 	    *arg = next_line_from_context(cctx, TRUE);
4398 	    op = skipwhite(*arg);
4399 	}
4400 
4401 	if (!IS_WHITE_OR_NUL(**arg) || !IS_WHITE_OR_NUL(op[oplen]))
4402 	{
4403 	    error_white_both(op, oplen);
4404 	    return FAIL;
4405 	}
4406 
4407 	if (may_get_next_line_error(op + oplen, arg, cctx) == FAIL)
4408 	    return FAIL;
4409 
4410 	// get the second expression
4411 	if (compile_expr6(arg, cctx, ppconst) == FAIL)
4412 	    return FAIL;
4413 
4414 	if (ppconst->pp_used == ppconst_used + 2
4415 		&& (*op == '.'
4416 		    ? (ppconst->pp_tv[ppconst_used].v_type == VAR_STRING
4417 		    && ppconst->pp_tv[ppconst_used + 1].v_type == VAR_STRING)
4418 		    : (ppconst->pp_tv[ppconst_used].v_type == VAR_NUMBER
4419 		    && ppconst->pp_tv[ppconst_used + 1].v_type == VAR_NUMBER)))
4420 	{
4421 	    typval_T *tv1 = &ppconst->pp_tv[ppconst_used];
4422 	    typval_T *tv2 = &ppconst->pp_tv[ppconst_used + 1];
4423 
4424 	    // concat/subtract/add constant numbers
4425 	    if (*op == '+')
4426 		tv1->vval.v_number = tv1->vval.v_number + tv2->vval.v_number;
4427 	    else if (*op == '-')
4428 		tv1->vval.v_number = tv1->vval.v_number - tv2->vval.v_number;
4429 	    else
4430 	    {
4431 		// concatenate constant strings
4432 		char_u *s1 = tv1->vval.v_string;
4433 		char_u *s2 = tv2->vval.v_string;
4434 		size_t len1 = STRLEN(s1);
4435 
4436 		tv1->vval.v_string = alloc((int)(len1 + STRLEN(s2) + 1));
4437 		if (tv1->vval.v_string == NULL)
4438 		{
4439 		    clear_ppconst(ppconst);
4440 		    return FAIL;
4441 		}
4442 		mch_memmove(tv1->vval.v_string, s1, len1);
4443 		STRCPY(tv1->vval.v_string + len1, s2);
4444 		vim_free(s1);
4445 		vim_free(s2);
4446 	    }
4447 	    --ppconst->pp_used;
4448 	}
4449 	else
4450 	{
4451 	    generate_ppconst(cctx, ppconst);
4452 	    if (*op == '.')
4453 	    {
4454 		if (may_generate_2STRING(-2, cctx) == FAIL
4455 			|| may_generate_2STRING(-1, cctx) == FAIL)
4456 		    return FAIL;
4457 		generate_instr_drop(cctx, ISN_CONCAT, 1);
4458 	    }
4459 	    else
4460 		generate_two_op(cctx, op);
4461 	}
4462     }
4463 
4464     return OK;
4465 }
4466 
4467 /*
4468  * expr5a == expr5b
4469  * expr5a =~ expr5b
4470  * expr5a != expr5b
4471  * expr5a !~ expr5b
4472  * expr5a > expr5b
4473  * expr5a >= expr5b
4474  * expr5a < expr5b
4475  * expr5a <= expr5b
4476  * expr5a is expr5b
4477  * expr5a isnot expr5b
4478  *
4479  * Produces instructions:
4480  *	EVAL expr5a		Push result of "expr5a"
4481  *	EVAL expr5b		Push result of "expr5b"
4482  *	COMPARE			one of the compare instructions
4483  */
4484     static int
4485 compile_expr4(char_u **arg, cctx_T *cctx, ppconst_T *ppconst)
4486 {
4487     exprtype_T	type = EXPR_UNKNOWN;
4488     char_u	*p;
4489     char_u	*next;
4490     int		len = 2;
4491     int		type_is = FALSE;
4492     int		ppconst_used = ppconst->pp_used;
4493 
4494     // get the first variable
4495     if (compile_expr5(arg, cctx, ppconst) == FAIL)
4496 	return FAIL;
4497 
4498     p = may_peek_next_line(cctx, *arg, &next);
4499     type = get_compare_type(p, &len, &type_is);
4500 
4501     /*
4502      * If there is a comparative operator, use it.
4503      */
4504     if (type != EXPR_UNKNOWN)
4505     {
4506 	int ic = FALSE;  // Default: do not ignore case
4507 
4508 	if (next != NULL)
4509 	{
4510 	    *arg = next_line_from_context(cctx, TRUE);
4511 	    p = skipwhite(*arg);
4512 	}
4513 	if (type_is && (p[len] == '?' || p[len] == '#'))
4514 	{
4515 	    semsg(_(e_invexpr2), *arg);
4516 	    return FAIL;
4517 	}
4518 	// extra question mark appended: ignore case
4519 	if (p[len] == '?')
4520 	{
4521 	    ic = TRUE;
4522 	    ++len;
4523 	}
4524 	// extra '#' appended: match case (ignored)
4525 	else if (p[len] == '#')
4526 	    ++len;
4527 	// nothing appended: match case
4528 
4529 	if (!IS_WHITE_OR_NUL(**arg) || !IS_WHITE_OR_NUL(p[len]))
4530 	{
4531 	    error_white_both(p, len);
4532 	    return FAIL;
4533 	}
4534 
4535 	// get the second variable
4536 	if (may_get_next_line_error(p + len, arg, cctx) == FAIL)
4537 	    return FAIL;
4538 
4539 	if (compile_expr5(arg, cctx, ppconst) == FAIL)
4540 	    return FAIL;
4541 
4542 	if (ppconst->pp_used == ppconst_used + 2)
4543 	{
4544 	    typval_T *	tv1 = &ppconst->pp_tv[ppconst->pp_used - 2];
4545 	    typval_T	*tv2 = &ppconst->pp_tv[ppconst->pp_used - 1];
4546 	    int		ret;
4547 
4548 	    // Both sides are a constant, compute the result now.
4549 	    // First check for a valid combination of types, this is more
4550 	    // strict than typval_compare().
4551 	    if (check_compare_types(type, tv1, tv2) == FAIL)
4552 		ret = FAIL;
4553 	    else
4554 	    {
4555 		ret = typval_compare(tv1, tv2, type, ic);
4556 		tv1->v_type = VAR_BOOL;
4557 		tv1->vval.v_number = tv1->vval.v_number
4558 						      ? VVAL_TRUE : VVAL_FALSE;
4559 		clear_tv(tv2);
4560 		--ppconst->pp_used;
4561 	    }
4562 	    return ret;
4563 	}
4564 
4565 	generate_ppconst(cctx, ppconst);
4566 	return generate_COMPARE(cctx, type, ic);
4567     }
4568 
4569     return OK;
4570 }
4571 
4572 static int compile_expr3(char_u **arg,  cctx_T *cctx, ppconst_T *ppconst);
4573 
4574 /*
4575  * Compile || or &&.
4576  */
4577     static int
4578 compile_and_or(
4579 	char_u **arg,
4580 	cctx_T	*cctx,
4581 	char	*op,
4582 	ppconst_T *ppconst,
4583 	int	ppconst_used UNUSED)
4584 {
4585     char_u	*next;
4586     char_u	*p = may_peek_next_line(cctx, *arg, &next);
4587     int		opchar = *op;
4588 
4589     if (p[0] == opchar && p[1] == opchar)
4590     {
4591 	garray_T	*instr = &cctx->ctx_instr;
4592 	garray_T	end_ga;
4593 
4594 	/*
4595 	 * Repeat until there is no following "||" or "&&"
4596 	 */
4597 	ga_init2(&end_ga, sizeof(int), 10);
4598 	while (p[0] == opchar && p[1] == opchar)
4599 	{
4600 	    if (next != NULL)
4601 	    {
4602 		*arg = next_line_from_context(cctx, TRUE);
4603 		p = skipwhite(*arg);
4604 	    }
4605 
4606 	    if (!IS_WHITE_OR_NUL(**arg) || !IS_WHITE_OR_NUL(p[2]))
4607 	    {
4608 		semsg(_(e_white_space_required_before_and_after_str_at_str),
4609 								     op, *arg);
4610 		return FAIL;
4611 	    }
4612 
4613 	    // TODO: use ppconst if the value is a constant and check
4614 	    // evaluating to bool
4615 	    generate_ppconst(cctx, ppconst);
4616 
4617 	    // Every part must evaluate to a bool.
4618 	    if (bool_on_stack(cctx) == FAIL)
4619 	    {
4620 		ga_clear(&end_ga);
4621 		return FAIL;
4622 	    }
4623 
4624 	    if (ga_grow(&end_ga, 1) == FAIL)
4625 	    {
4626 		ga_clear(&end_ga);
4627 		return FAIL;
4628 	    }
4629 	    *(((int *)end_ga.ga_data) + end_ga.ga_len) = instr->ga_len;
4630 	    ++end_ga.ga_len;
4631 	    generate_JUMP(cctx, opchar == '|'
4632 				 ?  JUMP_IF_COND_TRUE : JUMP_IF_COND_FALSE, 0);
4633 
4634 	    // eval the next expression
4635 	    if (may_get_next_line_error(p + 2, arg, cctx) == FAIL)
4636 	    {
4637 		ga_clear(&end_ga);
4638 		return FAIL;
4639 	    }
4640 
4641 	    if ((opchar == '|' ? compile_expr3(arg, cctx, ppconst)
4642 				  : compile_expr4(arg, cctx, ppconst)) == FAIL)
4643 	    {
4644 		ga_clear(&end_ga);
4645 		return FAIL;
4646 	    }
4647 
4648 	    p = may_peek_next_line(cctx, *arg, &next);
4649 	}
4650 	generate_ppconst(cctx, ppconst);
4651 
4652 	// Every part must evaluate to a bool.
4653 	if (bool_on_stack(cctx) == FAIL)
4654 	{
4655 	    ga_clear(&end_ga);
4656 	    return FAIL;
4657 	}
4658 
4659 	// Fill in the end label in all jumps.
4660 	while (end_ga.ga_len > 0)
4661 	{
4662 	    isn_T	*isn;
4663 
4664 	    --end_ga.ga_len;
4665 	    isn = ((isn_T *)instr->ga_data)
4666 				  + *(((int *)end_ga.ga_data) + end_ga.ga_len);
4667 	    isn->isn_arg.jump.jump_where = instr->ga_len;
4668 	}
4669 	ga_clear(&end_ga);
4670     }
4671 
4672     return OK;
4673 }
4674 
4675 /*
4676  * expr4a && expr4a && expr4a	    logical AND
4677  *
4678  * Produces instructions:
4679  *	EVAL expr4a		Push result of "expr4a"
4680  *	COND2BOOL		convert to bool if needed
4681  *	JUMP_IF_COND_FALSE end
4682  *	EVAL expr4b		Push result of "expr4b"
4683  *	JUMP_IF_COND_FALSE end
4684  *	EVAL expr4c		Push result of "expr4c"
4685  * end:
4686  */
4687     static int
4688 compile_expr3(char_u **arg, cctx_T *cctx, ppconst_T *ppconst)
4689 {
4690     int		ppconst_used = ppconst->pp_used;
4691 
4692     // get the first variable
4693     if (compile_expr4(arg, cctx, ppconst) == FAIL)
4694 	return FAIL;
4695 
4696     // || and && work almost the same
4697     return compile_and_or(arg, cctx, "&&", ppconst, ppconst_used);
4698 }
4699 
4700 /*
4701  * expr3a || expr3b || expr3c	    logical OR
4702  *
4703  * Produces instructions:
4704  *	EVAL expr3a		Push result of "expr3a"
4705  *	COND2BOOL		convert to bool if needed
4706  *	JUMP_IF_COND_TRUE end
4707  *	EVAL expr3b		Push result of "expr3b"
4708  *	JUMP_IF_COND_TRUE end
4709  *	EVAL expr3c		Push result of "expr3c"
4710  * end:
4711  */
4712     static int
4713 compile_expr2(char_u **arg, cctx_T *cctx, ppconst_T *ppconst)
4714 {
4715     int		ppconst_used = ppconst->pp_used;
4716 
4717     // eval the first expression
4718     if (compile_expr3(arg, cctx, ppconst) == FAIL)
4719 	return FAIL;
4720 
4721     // || and && work almost the same
4722     return compile_and_or(arg, cctx, "||", ppconst, ppconst_used);
4723 }
4724 
4725 /*
4726  * Toplevel expression: expr2 ? expr1a : expr1b
4727  * Produces instructions:
4728  *	EVAL expr2		Push result of "expr2"
4729  *      JUMP_IF_FALSE alt	jump if false
4730  *      EVAL expr1a
4731  *      JUMP_ALWAYS end
4732  * alt:	EVAL expr1b
4733  * end:
4734  *
4735  * Toplevel expression: expr2 ?? expr1
4736  * Produces instructions:
4737  *	EVAL expr2		    Push result of "expr2"
4738  *      JUMP_AND_KEEP_IF_TRUE end   jump if true
4739  *      EVAL expr1
4740  * end:
4741  */
4742     static int
4743 compile_expr1(char_u **arg, cctx_T *cctx, ppconst_T *ppconst)
4744 {
4745     char_u	*p;
4746     int		ppconst_used = ppconst->pp_used;
4747     char_u	*next;
4748 
4749     // Ignore all kinds of errors when not producing code.
4750     if (cctx->ctx_skip == SKIP_YES)
4751     {
4752 	skip_expr_cctx(arg, cctx);
4753 	return OK;
4754     }
4755 
4756     // Evaluate the first expression.
4757     if (compile_expr2(arg, cctx, ppconst) == FAIL)
4758 	return FAIL;
4759 
4760     p = may_peek_next_line(cctx, *arg, &next);
4761     if (*p == '?')
4762     {
4763 	int		op_falsy = p[1] == '?';
4764 	garray_T	*instr = &cctx->ctx_instr;
4765 	garray_T	*stack = &cctx->ctx_type_stack;
4766 	int		alt_idx = instr->ga_len;
4767 	int		end_idx = 0;
4768 	isn_T		*isn;
4769 	type_T		*type1 = NULL;
4770 	int		has_const_expr = FALSE;
4771 	int		const_value = FALSE;
4772 	int		save_skip = cctx->ctx_skip;
4773 
4774 	if (next != NULL)
4775 	{
4776 	    *arg = next_line_from_context(cctx, TRUE);
4777 	    p = skipwhite(*arg);
4778 	}
4779 
4780 	if (!IS_WHITE_OR_NUL(**arg) || !IS_WHITE_OR_NUL(p[1 + op_falsy]))
4781 	{
4782 	    semsg(_(e_white_space_required_before_and_after_str_at_str),
4783 						  op_falsy ? "??" : "?", *arg);
4784 	    return FAIL;
4785 	}
4786 
4787 	if (ppconst->pp_used == ppconst_used + 1)
4788 	{
4789 	    // the condition is a constant, we know whether the ? or the :
4790 	    // expression is to be evaluated.
4791 	    has_const_expr = TRUE;
4792 	    if (op_falsy)
4793 		const_value = tv2bool(&ppconst->pp_tv[ppconst_used]);
4794 	    else
4795 	    {
4796 		int error = FALSE;
4797 
4798 		const_value = tv_get_bool_chk(&ppconst->pp_tv[ppconst_used],
4799 								       &error);
4800 		if (error)
4801 		    return FAIL;
4802 	    }
4803 	    cctx->ctx_skip = save_skip == SKIP_YES ||
4804 		 (op_falsy ? const_value : !const_value) ? SKIP_YES : SKIP_NOT;
4805 
4806 	    if (op_falsy && cctx->ctx_skip == SKIP_YES)
4807 		// "left ?? right" and "left" is truthy: produce "left"
4808 		generate_ppconst(cctx, ppconst);
4809 	    else
4810 	    {
4811 		clear_tv(&ppconst->pp_tv[ppconst_used]);
4812 		--ppconst->pp_used;
4813 	    }
4814 	}
4815 	else
4816 	{
4817 	    generate_ppconst(cctx, ppconst);
4818 	    if (op_falsy)
4819 		end_idx = instr->ga_len;
4820 	    generate_JUMP(cctx, op_falsy
4821 				   ? JUMP_AND_KEEP_IF_TRUE : JUMP_IF_FALSE, 0);
4822 	    if (op_falsy)
4823 		type1 = ((type_T **)stack->ga_data)[stack->ga_len];
4824 	}
4825 
4826 	// evaluate the second expression; any type is accepted
4827 	if (may_get_next_line_error(p + 1 + op_falsy, arg, cctx) == FAIL)
4828 	    return FAIL;
4829 	if (compile_expr1(arg, cctx, ppconst) == FAIL)
4830 	    return FAIL;
4831 
4832 	if (!has_const_expr)
4833 	{
4834 	    generate_ppconst(cctx, ppconst);
4835 
4836 	    if (!op_falsy)
4837 	    {
4838 		// remember the type and drop it
4839 		--stack->ga_len;
4840 		type1 = ((type_T **)stack->ga_data)[stack->ga_len];
4841 
4842 		end_idx = instr->ga_len;
4843 		generate_JUMP(cctx, JUMP_ALWAYS, 0);
4844 
4845 		// jump here from JUMP_IF_FALSE
4846 		isn = ((isn_T *)instr->ga_data) + alt_idx;
4847 		isn->isn_arg.jump.jump_where = instr->ga_len;
4848 	    }
4849 	}
4850 
4851 	if (!op_falsy)
4852 	{
4853 	    // Check for the ":".
4854 	    p = may_peek_next_line(cctx, *arg, &next);
4855 	    if (*p != ':')
4856 	    {
4857 		emsg(_(e_missing_colon));
4858 		return FAIL;
4859 	    }
4860 	    if (next != NULL)
4861 	    {
4862 		*arg = next_line_from_context(cctx, TRUE);
4863 		p = skipwhite(*arg);
4864 	    }
4865 
4866 	    if (!IS_WHITE_OR_NUL(**arg) || !IS_WHITE_OR_NUL(p[1]))
4867 	    {
4868 		semsg(_(e_white_space_required_before_and_after_str_at_str),
4869 								       ":", p);
4870 		return FAIL;
4871 	    }
4872 
4873 	    // evaluate the third expression
4874 	    if (has_const_expr)
4875 		cctx->ctx_skip = save_skip == SKIP_YES || const_value
4876 							 ? SKIP_YES : SKIP_NOT;
4877 	    if (may_get_next_line_error(p + 1, arg, cctx) == FAIL)
4878 		return FAIL;
4879 	    if (compile_expr1(arg, cctx, ppconst) == FAIL)
4880 		return FAIL;
4881 	}
4882 
4883 	if (!has_const_expr)
4884 	{
4885 	    type_T	**typep;
4886 
4887 	    generate_ppconst(cctx, ppconst);
4888 
4889 	    // If the types differ, the result has a more generic type.
4890 	    typep = ((type_T **)stack->ga_data) + stack->ga_len - 1;
4891 	    common_type(type1, *typep, typep, cctx->ctx_type_list);
4892 
4893 	    // jump here from JUMP_ALWAYS or JUMP_AND_KEEP_IF_TRUE
4894 	    isn = ((isn_T *)instr->ga_data) + end_idx;
4895 	    isn->isn_arg.jump.jump_where = instr->ga_len;
4896 	}
4897 
4898 	cctx->ctx_skip = save_skip;
4899     }
4900     return OK;
4901 }
4902 
4903 /*
4904  * Toplevel expression.
4905  * Sets "is_const" (if not NULL) to indicate the value is a constant.
4906  * Returns OK or FAIL.
4907  */
4908     static int
4909 compile_expr0_ext(char_u **arg,  cctx_T *cctx, int *is_const)
4910 {
4911     ppconst_T	ppconst;
4912 
4913     CLEAR_FIELD(ppconst);
4914     if (compile_expr1(arg, cctx, &ppconst) == FAIL)
4915     {
4916 	clear_ppconst(&ppconst);
4917 	return FAIL;
4918     }
4919     if (is_const != NULL)
4920 	*is_const = ppconst.pp_used > 0 || ppconst.pp_is_const;
4921     if (generate_ppconst(cctx, &ppconst) == FAIL)
4922 	return FAIL;
4923     return OK;
4924 }
4925 
4926 /*
4927  * Toplevel expression.
4928  */
4929     static int
4930 compile_expr0(char_u **arg,  cctx_T *cctx)
4931 {
4932     return compile_expr0_ext(arg, cctx, NULL);
4933 }
4934 
4935 /*
4936  * compile "return [expr]"
4937  */
4938     static char_u *
4939 compile_return(char_u *arg, int check_return_type, cctx_T *cctx)
4940 {
4941     char_u	*p = arg;
4942     garray_T	*stack = &cctx->ctx_type_stack;
4943     type_T	*stack_type;
4944 
4945     if (*p != NUL && *p != '|' && *p != '\n')
4946     {
4947 	// compile return argument into instructions
4948 	if (compile_expr0(&p, cctx) == FAIL)
4949 	    return NULL;
4950 
4951 	if (cctx->ctx_skip != SKIP_YES)
4952 	{
4953 	    stack_type = ((type_T **)stack->ga_data)[stack->ga_len - 1];
4954 	    if (check_return_type && (cctx->ctx_ufunc->uf_ret_type == NULL
4955 				|| cctx->ctx_ufunc->uf_ret_type == &t_unknown
4956 				|| cctx->ctx_ufunc->uf_ret_type == &t_any))
4957 	    {
4958 		cctx->ctx_ufunc->uf_ret_type = stack_type;
4959 	    }
4960 	    else
4961 	    {
4962 		if (cctx->ctx_ufunc->uf_ret_type->tt_type == VAR_VOID
4963 			&& stack_type->tt_type != VAR_VOID
4964 			&& stack_type->tt_type != VAR_UNKNOWN)
4965 		{
4966 		    emsg(_(e_returning_value_in_function_without_return_type));
4967 		    return NULL;
4968 		}
4969 		if (need_type(stack_type, cctx->ctx_ufunc->uf_ret_type, -1,
4970 						0, cctx, FALSE, FALSE) == FAIL)
4971 		    return NULL;
4972 	    }
4973 	}
4974     }
4975     else
4976     {
4977 	// "check_return_type" cannot be TRUE, only used for a lambda which
4978 	// always has an argument.
4979 	if (cctx->ctx_ufunc->uf_ret_type->tt_type != VAR_VOID
4980 		&& cctx->ctx_ufunc->uf_ret_type->tt_type != VAR_UNKNOWN)
4981 	{
4982 	    emsg(_(e_missing_return_value));
4983 	    return NULL;
4984 	}
4985 
4986 	// No argument, return zero.
4987 	generate_PUSHNR(cctx, 0);
4988     }
4989 
4990     // Undo any command modifiers.
4991     generate_undo_cmdmods(cctx);
4992 
4993     if (cctx->ctx_skip != SKIP_YES && generate_instr(cctx, ISN_RETURN) == NULL)
4994 	return NULL;
4995 
4996     // "return val | endif" is possible
4997     return skipwhite(p);
4998 }
4999 
5000 /*
5001  * Get a line from the compilation context, compatible with exarg_T getline().
5002  * Return a pointer to the line in allocated memory.
5003  * Return NULL for end-of-file or some error.
5004  */
5005     static char_u *
5006 exarg_getline(
5007 	int c UNUSED,
5008 	void *cookie,
5009 	int indent UNUSED,
5010 	getline_opt_T options UNUSED)
5011 {
5012     cctx_T  *cctx = (cctx_T *)cookie;
5013     char_u  *p;
5014 
5015     for (;;)
5016     {
5017 	if (cctx->ctx_lnum >= cctx->ctx_ufunc->uf_lines.ga_len - 1)
5018 	    return NULL;
5019 	++cctx->ctx_lnum;
5020 	p = ((char_u **)cctx->ctx_ufunc->uf_lines.ga_data)[cctx->ctx_lnum];
5021 	// Comment lines result in NULL pointers, skip them.
5022 	if (p != NULL)
5023 	    return vim_strsave(p);
5024     }
5025 }
5026 
5027 /*
5028  * Compile a nested :def command.
5029  */
5030     static char_u *
5031 compile_nested_function(exarg_T *eap, cctx_T *cctx)
5032 {
5033     int		is_global = *eap->arg == 'g' && eap->arg[1] == ':';
5034     char_u	*name_start = eap->arg;
5035     char_u	*name_end = to_name_end(eap->arg, TRUE);
5036     char_u	*lambda_name;
5037     ufunc_T	*ufunc;
5038     int		r = FAIL;
5039 
5040     if (eap->forceit)
5041     {
5042 	emsg(_(e_cannot_use_bang_with_nested_def));
5043 	return NULL;
5044     }
5045 
5046     if (*name_start == '/')
5047     {
5048 	name_end = skip_regexp(name_start + 1, '/', TRUE);
5049 	if (*name_end == '/')
5050 	    ++name_end;
5051 	eap->nextcmd = check_nextcmd(name_end);
5052     }
5053     if (name_end == name_start || *skipwhite(name_end) != '(')
5054     {
5055 	if (!ends_excmd2(name_start, name_end))
5056 	{
5057 	    semsg(_(e_invalid_command_str), eap->cmd);
5058 	    return NULL;
5059 	}
5060 
5061 	// "def" or "def Name": list functions
5062 	if (generate_DEF(cctx, name_start, name_end - name_start) == FAIL)
5063 	    return NULL;
5064 	return eap->nextcmd == NULL ? (char_u *)"" : eap->nextcmd;
5065     }
5066 
5067     // Only g:Func() can use a namespace.
5068     if (name_start[1] == ':' && !is_global)
5069     {
5070 	semsg(_(e_namespace_not_supported_str), name_start);
5071 	return NULL;
5072     }
5073     if (check_defined(name_start, name_end - name_start, cctx) == FAIL)
5074 	return NULL;
5075 
5076     eap->arg = name_end;
5077     eap->getline = exarg_getline;
5078     eap->cookie = cctx;
5079     eap->skip = cctx->ctx_skip == SKIP_YES;
5080     eap->forceit = FALSE;
5081     lambda_name = vim_strsave(get_lambda_name());
5082     if (lambda_name == NULL)
5083 	return NULL;
5084     ufunc = define_function(eap, lambda_name);
5085 
5086     if (ufunc == NULL)
5087     {
5088 	r = eap->skip ? OK : FAIL;
5089 	goto theend;
5090     }
5091     if (func_needs_compiling(ufunc, PROFILING(ufunc))
5092 	    && compile_def_function(ufunc, TRUE, PROFILING(ufunc), cctx)
5093 								       == FAIL)
5094     {
5095 	func_ptr_unref(ufunc);
5096 	goto theend;
5097     }
5098 
5099     if (is_global)
5100     {
5101 	char_u *func_name = vim_strnsave(name_start + 2,
5102 						    name_end - name_start - 2);
5103 
5104 	if (func_name == NULL)
5105 	    r = FAIL;
5106 	else
5107 	{
5108 	    r = generate_NEWFUNC(cctx, lambda_name, func_name);
5109 	    lambda_name = NULL;
5110 	}
5111     }
5112     else
5113     {
5114 	// Define a local variable for the function reference.
5115 	lvar_T	*lvar = reserve_local(cctx, name_start, name_end - name_start,
5116 						    TRUE, ufunc->uf_func_type);
5117 	int block_depth = cctx->ctx_ufunc->uf_block_depth;
5118 
5119 	if (lvar == NULL)
5120 	    goto theend;
5121 	if (generate_FUNCREF(cctx, ufunc) == FAIL)
5122 	    goto theend;
5123 	r = generate_STORE(cctx, ISN_STORE, lvar->lv_idx, NULL);
5124 
5125 	// copy over the block scope IDs
5126 	if (block_depth > 0)
5127 	{
5128 	    ufunc->uf_block_ids = ALLOC_MULT(int, block_depth);
5129 	    if (ufunc->uf_block_ids != NULL)
5130 	    {
5131 		mch_memmove(ufunc->uf_block_ids, cctx->ctx_ufunc->uf_block_ids,
5132 						    sizeof(int) * block_depth);
5133 		ufunc->uf_block_depth = block_depth;
5134 	    }
5135 	}
5136     }
5137     // TODO: warning for trailing text?
5138     r = OK;
5139 
5140 theend:
5141     vim_free(lambda_name);
5142     return r == FAIL ? NULL : (char_u *)"";
5143 }
5144 
5145 /*
5146  * Return the length of an assignment operator, or zero if there isn't one.
5147  */
5148     int
5149 assignment_len(char_u *p, int *heredoc)
5150 {
5151     if (*p == '=')
5152     {
5153 	if (p[1] == '<' && p[2] == '<')
5154 	{
5155 	    *heredoc = TRUE;
5156 	    return 3;
5157 	}
5158 	return 1;
5159     }
5160     if (vim_strchr((char_u *)"+-*/%", *p) != NULL && p[1] == '=')
5161 	return 2;
5162     if (STRNCMP(p, "..=", 3) == 0)
5163 	return 3;
5164     return 0;
5165 }
5166 
5167 // words that cannot be used as a variable
5168 static char *reserved[] = {
5169     "true",
5170     "false",
5171     "null",
5172     NULL
5173 };
5174 
5175 // Destination for an assignment or ":unlet" with an index.
5176 typedef enum {
5177     dest_local,
5178     dest_option,
5179     dest_env,
5180     dest_global,
5181     dest_buffer,
5182     dest_window,
5183     dest_tab,
5184     dest_vimvar,
5185     dest_script,
5186     dest_reg,
5187     dest_expr,
5188 } assign_dest_T;
5189 
5190 // Used by compile_lhs() to store information about the LHS of an assignment
5191 // and one argument of ":unlet" with an index.
5192 typedef struct {
5193     assign_dest_T   lhs_dest;	    // type of destination
5194 
5195     char_u	    *lhs_name;	    // allocated name including
5196 				    // "[expr]" or ".name".
5197     size_t	    lhs_varlen;	    // length of the variable without
5198 				    // "[expr]" or ".name"
5199     char_u	    *lhs_dest_end;  // end of the destination, including
5200 				    // "[expr]" or ".name".
5201 
5202     int		    lhs_has_index;  // has "[expr]" or ".name"
5203 
5204     int		    lhs_new_local;  // create new local variable
5205     int		    lhs_opt_flags;  // for when destination is an option
5206     int		    lhs_vimvaridx;  // for when destination is a v:var
5207 
5208     lvar_T	    lhs_local_lvar; // used for existing local destination
5209     lvar_T	    lhs_arg_lvar;   // used for argument destination
5210     lvar_T	    *lhs_lvar;	    // points to destination lvar
5211     int		    lhs_scriptvar_sid;
5212     int		    lhs_scriptvar_idx;
5213 
5214     int		    lhs_has_type;   // type was specified
5215     type_T	    *lhs_type;
5216     type_T	    *lhs_member_type;
5217 } lhs_T;
5218 
5219 /*
5220  * Generate the load instruction for "name".
5221  */
5222     static void
5223 generate_loadvar(
5224 	cctx_T		*cctx,
5225 	assign_dest_T	dest,
5226 	char_u		*name,
5227 	lvar_T		*lvar,
5228 	type_T		*type)
5229 {
5230     switch (dest)
5231     {
5232 	case dest_option:
5233 	    // TODO: check the option exists
5234 	    generate_LOAD(cctx, ISN_LOADOPT, 0, name, type);
5235 	    break;
5236 	case dest_global:
5237 	    if (vim_strchr(name, AUTOLOAD_CHAR) == NULL)
5238 		generate_LOAD(cctx, ISN_LOADG, 0, name + 2, type);
5239 	    else
5240 		generate_LOAD(cctx, ISN_LOADAUTO, 0, name, type);
5241 	    break;
5242 	case dest_buffer:
5243 	    generate_LOAD(cctx, ISN_LOADB, 0, name + 2, type);
5244 	    break;
5245 	case dest_window:
5246 	    generate_LOAD(cctx, ISN_LOADW, 0, name + 2, type);
5247 	    break;
5248 	case dest_tab:
5249 	    generate_LOAD(cctx, ISN_LOADT, 0, name + 2, type);
5250 	    break;
5251 	case dest_script:
5252 	    compile_load_scriptvar(cctx,
5253 		    name + (name[1] == ':' ? 2 : 0), NULL, NULL, TRUE);
5254 	    break;
5255 	case dest_env:
5256 	    // Include $ in the name here
5257 	    generate_LOAD(cctx, ISN_LOADENV, 0, name, type);
5258 	    break;
5259 	case dest_reg:
5260 	    generate_LOAD(cctx, ISN_LOADREG, name[1], NULL, &t_string);
5261 	    break;
5262 	case dest_vimvar:
5263 	    generate_LOADV(cctx, name + 2, TRUE);
5264 	    break;
5265 	case dest_local:
5266 	    if (lvar->lv_from_outer > 0)
5267 		generate_LOADOUTER(cctx, lvar->lv_idx, lvar->lv_from_outer,
5268 									 type);
5269 	    else
5270 		generate_LOAD(cctx, ISN_LOAD, lvar->lv_idx, NULL, type);
5271 	    break;
5272 	case dest_expr:
5273 	    // list or dict value should already be on the stack.
5274 	    break;
5275     }
5276 }
5277 
5278 /*
5279  * Skip over "[expr]" or ".member".
5280  * Does not check for any errors.
5281  */
5282     static char_u *
5283 skip_index(char_u *start)
5284 {
5285     char_u *p = start;
5286 
5287     if (*p == '[')
5288     {
5289 	p = skipwhite(p + 1);
5290 	(void)skip_expr(&p, NULL);
5291 	p = skipwhite(p);
5292 	if (*p == ']')
5293 	    return p + 1;
5294 	return p;
5295     }
5296     // if (*p == '.')
5297     return to_name_end(p + 1, TRUE);
5298 }
5299 
5300     void
5301 vim9_declare_error(char_u *name)
5302 {
5303     char *scope = "";
5304 
5305     switch (*name)
5306     {
5307 	case 'g': scope = _("global"); break;
5308 	case 'b': scope = _("buffer"); break;
5309 	case 'w': scope = _("window"); break;
5310 	case 't': scope = _("tab"); break;
5311 	case 'v': scope = "v:"; break;
5312 	case '$': semsg(_(e_cannot_declare_an_environment_variable), name);
5313 		  return;
5314 	case '&': semsg(_(e_cannot_declare_an_option), name);
5315 		  return;
5316 	case '@': semsg(_(e_cannot_declare_a_register_str), name);
5317 		  return;
5318 	default: return;
5319     }
5320     semsg(_(e_cannot_declare_a_scope_variable), scope, name);
5321 }
5322 
5323 /*
5324  * For one assignment figure out the type of destination.  Return it in "dest".
5325  * When not recognized "dest" is not set.
5326  * For an option "opt_flags" is set.
5327  * For a v:var "vimvaridx" is set.
5328  * "type" is set to the destination type if known, unchanted otherwise.
5329  * Return FAIL if an error message was given.
5330  */
5331     static int
5332 get_var_dest(
5333 	char_u		*name,
5334 	assign_dest_T	*dest,
5335 	int		cmdidx,
5336 	int		*opt_flags,
5337 	int		*vimvaridx,
5338 	type_T		**type,
5339 	cctx_T		*cctx)
5340 {
5341     char_u *p;
5342 
5343     if (*name == '&')
5344     {
5345 	int		cc;
5346 	long		numval;
5347 	getoption_T	opt_type;
5348 
5349 	*dest = dest_option;
5350 	if (cmdidx == CMD_final || cmdidx == CMD_const)
5351 	{
5352 	    emsg(_(e_const_option));
5353 	    return FAIL;
5354 	}
5355 	p = name;
5356 	p = find_option_end(&p, opt_flags);
5357 	if (p == NULL)
5358 	{
5359 	    // cannot happen?
5360 	    emsg(_(e_letunexp));
5361 	    return FAIL;
5362 	}
5363 	cc = *p;
5364 	*p = NUL;
5365 	opt_type = get_option_value(skip_option_env_lead(name),
5366 						    &numval, NULL, *opt_flags);
5367 	*p = cc;
5368 	switch (opt_type)
5369 	{
5370 	    case gov_unknown:
5371 		    semsg(_(e_unknown_option), name);
5372 		    return FAIL;
5373 	    case gov_string:
5374 	    case gov_hidden_string:
5375 		    *type = &t_string;
5376 		    break;
5377 	    case gov_bool:
5378 	    case gov_hidden_bool:
5379 		    *type = &t_bool;
5380 		    break;
5381 	    case gov_number:
5382 	    case gov_hidden_number:
5383 		    *type = &t_number;
5384 		    break;
5385 	}
5386     }
5387     else if (*name == '$')
5388     {
5389 	*dest = dest_env;
5390 	*type = &t_string;
5391     }
5392     else if (*name == '@')
5393     {
5394 	if (!valid_yank_reg(name[1], FALSE) || name[1] == '.')
5395 	{
5396 	    emsg_invreg(name[1]);
5397 	    return FAIL;
5398 	}
5399 	*dest = dest_reg;
5400 	*type = &t_string;
5401     }
5402     else if (STRNCMP(name, "g:", 2) == 0)
5403     {
5404 	*dest = dest_global;
5405     }
5406     else if (STRNCMP(name, "b:", 2) == 0)
5407     {
5408 	*dest = dest_buffer;
5409     }
5410     else if (STRNCMP(name, "w:", 2) == 0)
5411     {
5412 	*dest = dest_window;
5413     }
5414     else if (STRNCMP(name, "t:", 2) == 0)
5415     {
5416 	*dest = dest_tab;
5417     }
5418     else if (STRNCMP(name, "v:", 2) == 0)
5419     {
5420 	typval_T	*vtv;
5421 	int		di_flags;
5422 
5423 	*vimvaridx = find_vim_var(name + 2, &di_flags);
5424 	if (*vimvaridx < 0)
5425 	{
5426 	    semsg(_(e_variable_not_found_str), name);
5427 	    return FAIL;
5428 	}
5429 	// We use the current value of "sandbox" here, is that OK?
5430 	if (var_check_ro(di_flags, name, FALSE))
5431 	    return FAIL;
5432 	*dest = dest_vimvar;
5433 	vtv = get_vim_var_tv(*vimvaridx);
5434 	*type = typval2type_vimvar(vtv, cctx->ctx_type_list);
5435     }
5436     return OK;
5437 }
5438 
5439 /*
5440  * Generate a STORE instruction for "dest", not being "dest_local".
5441  * Return FAIL when out of memory.
5442  */
5443     static int
5444 generate_store_var(
5445 	cctx_T		*cctx,
5446 	assign_dest_T	dest,
5447 	int		opt_flags,
5448 	int		vimvaridx,
5449 	int		scriptvar_idx,
5450 	int		scriptvar_sid,
5451 	type_T		*type,
5452 	char_u		*name)
5453 {
5454     switch (dest)
5455     {
5456 	case dest_option:
5457 	    return generate_STOREOPT(cctx, skip_option_env_lead(name),
5458 								    opt_flags);
5459 	case dest_global:
5460 	    // include g: with the name, easier to execute that way
5461 	    return generate_STORE(cctx, vim_strchr(name, AUTOLOAD_CHAR) == NULL
5462 					? ISN_STOREG : ISN_STOREAUTO, 0, name);
5463 	case dest_buffer:
5464 	    // include b: with the name, easier to execute that way
5465 	    return generate_STORE(cctx, ISN_STOREB, 0, name);
5466 	case dest_window:
5467 	    // include w: with the name, easier to execute that way
5468 	    return generate_STORE(cctx, ISN_STOREW, 0, name);
5469 	case dest_tab:
5470 	    // include t: with the name, easier to execute that way
5471 	    return generate_STORE(cctx, ISN_STORET, 0, name);
5472 	case dest_env:
5473 	    return generate_STORE(cctx, ISN_STOREENV, 0, name + 1);
5474 	case dest_reg:
5475 	    return generate_STORE(cctx, ISN_STOREREG, name[1], NULL);
5476 	case dest_vimvar:
5477 	    return generate_STORE(cctx, ISN_STOREV, vimvaridx, NULL);
5478 	case dest_script:
5479 	    if (scriptvar_idx < 0)
5480 	    {
5481 		char_u  *name_s = name;
5482 		int	r;
5483 
5484 		// "s:" is included in the name.
5485 		r = generate_OLDSCRIPT(cctx, ISN_STORES, name_s,
5486 							  scriptvar_sid, type);
5487 		if (name_s != name)
5488 		    vim_free(name_s);
5489 		return r;
5490 	    }
5491 	    return generate_VIM9SCRIPT(cctx, ISN_STORESCRIPT,
5492 					   scriptvar_sid, scriptvar_idx, type);
5493 	case dest_local:
5494 	case dest_expr:
5495 	    // cannot happen
5496 	    break;
5497     }
5498     return FAIL;
5499 }
5500 
5501     static int
5502 is_decl_command(int cmdidx)
5503 {
5504     return cmdidx == CMD_let || cmdidx == CMD_var
5505 				 || cmdidx == CMD_final || cmdidx == CMD_const;
5506 }
5507 
5508 /*
5509  * Figure out the LHS type and other properties for an assignment or one item
5510  * of ":unlet" with an index.
5511  * Returns OK or FAIL.
5512  */
5513     static int
5514 compile_lhs(
5515 	char_u	*var_start,
5516 	lhs_T	*lhs,
5517 	int	cmdidx,
5518 	int	heredoc,
5519 	int	oplen,
5520 	cctx_T	*cctx)
5521 {
5522     char_u	*var_end;
5523     int		is_decl = is_decl_command(cmdidx);
5524 
5525     CLEAR_POINTER(lhs);
5526     lhs->lhs_dest = dest_local;
5527     lhs->lhs_vimvaridx = -1;
5528     lhs->lhs_scriptvar_idx = -1;
5529 
5530     // "dest_end" is the end of the destination, including "[expr]" or
5531     // ".name".
5532     // "var_end" is the end of the variable/option/etc. name.
5533     lhs->lhs_dest_end = skip_var_one(var_start, FALSE);
5534     if (*var_start == '@')
5535 	var_end = var_start + 2;
5536     else
5537     {
5538 	// skip over the leading "&", "&l:", "&g:" and "$"
5539 	var_end = skip_option_env_lead(var_start);
5540 	var_end = to_name_end(var_end, TRUE);
5541     }
5542 
5543     // "a: type" is declaring variable "a" with a type, not dict "a:".
5544     if (is_decl && lhs->lhs_dest_end == var_start + 2
5545 					       && lhs->lhs_dest_end[-1] == ':')
5546 	--lhs->lhs_dest_end;
5547     if (is_decl && var_end == var_start + 2 && var_end[-1] == ':')
5548 	--var_end;
5549 
5550     // compute the length of the destination without "[expr]" or ".name"
5551     lhs->lhs_varlen = var_end - var_start;
5552     lhs->lhs_name = vim_strnsave(var_start, lhs->lhs_varlen);
5553     if (lhs->lhs_name == NULL)
5554 	return FAIL;
5555 
5556     if (lhs->lhs_dest_end > var_start + lhs->lhs_varlen)
5557 	// Something follows after the variable: "var[idx]" or "var.key".
5558 	lhs->lhs_has_index = TRUE;
5559 
5560     if (heredoc)
5561 	lhs->lhs_type = &t_list_string;
5562     else
5563 	lhs->lhs_type = &t_any;
5564 
5565     if (cctx->ctx_skip != SKIP_YES)
5566     {
5567 	int	    declare_error = FALSE;
5568 
5569 	if (get_var_dest(lhs->lhs_name, &lhs->lhs_dest, cmdidx,
5570 				      &lhs->lhs_opt_flags, &lhs->lhs_vimvaridx,
5571 						 &lhs->lhs_type, cctx) == FAIL)
5572 	    return FAIL;
5573 	if (lhs->lhs_dest != dest_local)
5574 	{
5575 	    // Specific kind of variable recognized.
5576 	    declare_error = is_decl;
5577 	}
5578 	else
5579 	{
5580 	    int	    idx;
5581 
5582 	    // No specific kind of variable recognized, just a name.
5583 	    for (idx = 0; reserved[idx] != NULL; ++idx)
5584 		if (STRCMP(reserved[idx], lhs->lhs_name) == 0)
5585 		{
5586 		    semsg(_(e_cannot_use_reserved_name), lhs->lhs_name);
5587 		    return FAIL;
5588 		}
5589 
5590 
5591 	    if (lookup_local(var_start, lhs->lhs_varlen,
5592 					     &lhs->lhs_local_lvar, cctx) == OK)
5593 		lhs->lhs_lvar = &lhs->lhs_local_lvar;
5594 	    else
5595 	    {
5596 		CLEAR_FIELD(lhs->lhs_arg_lvar);
5597 		if (arg_exists(var_start, lhs->lhs_varlen,
5598 			 &lhs->lhs_arg_lvar.lv_idx, &lhs->lhs_arg_lvar.lv_type,
5599 			    &lhs->lhs_arg_lvar.lv_from_outer, cctx) == OK)
5600 		{
5601 		    if (is_decl)
5602 		    {
5603 			semsg(_(e_str_is_used_as_argument), lhs->lhs_name);
5604 			return FAIL;
5605 		    }
5606 		    lhs->lhs_lvar = &lhs->lhs_arg_lvar;
5607 		}
5608 	    }
5609 	    if (lhs->lhs_lvar != NULL)
5610 	    {
5611 		if (is_decl)
5612 		{
5613 		    semsg(_(e_variable_already_declared), lhs->lhs_name);
5614 		    return FAIL;
5615 		}
5616 	    }
5617 	    else
5618 	    {
5619 		int script_namespace = lhs->lhs_varlen > 1
5620 				       && STRNCMP(var_start, "s:", 2) == 0;
5621 		int script_var = (script_namespace
5622 			? script_var_exists(var_start + 2, lhs->lhs_varlen - 2,
5623 							       FALSE, cctx)
5624 			  : script_var_exists(var_start, lhs->lhs_varlen,
5625 							    TRUE, cctx)) == OK;
5626 		imported_T  *import =
5627 			       find_imported(var_start, lhs->lhs_varlen, cctx);
5628 
5629 		if (script_namespace || script_var || import != NULL)
5630 		{
5631 		    char_u	*rawname = lhs->lhs_name
5632 					   + (lhs->lhs_name[1] == ':' ? 2 : 0);
5633 
5634 		    if (is_decl)
5635 		    {
5636 			if (script_namespace)
5637 			    semsg(_(e_cannot_declare_script_variable_in_function),
5638 								lhs->lhs_name);
5639 			else
5640 			    semsg(_(e_variable_already_declared_in_script),
5641 								lhs->lhs_name);
5642 			return FAIL;
5643 		    }
5644 		    else if (cctx->ctx_ufunc->uf_script_ctx_version
5645 							 == SCRIPT_VERSION_VIM9
5646 				    && script_namespace
5647 				    && !script_var && import == NULL)
5648 		    {
5649 			semsg(_(e_unknown_variable_str), lhs->lhs_name);
5650 			return FAIL;
5651 		    }
5652 
5653 		    lhs->lhs_dest = dest_script;
5654 
5655 		    // existing script-local variables should have a type
5656 		    lhs->lhs_scriptvar_sid = current_sctx.sc_sid;
5657 		    if (import != NULL)
5658 			lhs->lhs_scriptvar_sid = import->imp_sid;
5659 		    if (SCRIPT_ID_VALID(lhs->lhs_scriptvar_sid))
5660 		    {
5661 			// Check writable only when no index follows.
5662 			lhs->lhs_scriptvar_idx = get_script_item_idx(
5663 					       lhs->lhs_scriptvar_sid, rawname,
5664 			      lhs->lhs_has_index ? ASSIGN_FINAL : ASSIGN_CONST,
5665 									 cctx);
5666 			if (lhs->lhs_scriptvar_idx >= 0)
5667 			{
5668 			    scriptitem_T *si = SCRIPT_ITEM(
5669 						       lhs->lhs_scriptvar_sid);
5670 			    svar_T	 *sv =
5671 					    ((svar_T *)si->sn_var_vals.ga_data)
5672 						      + lhs->lhs_scriptvar_idx;
5673 			    lhs->lhs_type = sv->sv_type;
5674 			}
5675 		    }
5676 		}
5677 		else if (check_defined(var_start, lhs->lhs_varlen, cctx)
5678 								       == FAIL)
5679 		    return FAIL;
5680 	    }
5681 	}
5682 
5683 	if (declare_error)
5684 	{
5685 	    vim9_declare_error(lhs->lhs_name);
5686 	    return FAIL;
5687 	}
5688     }
5689 
5690     // handle "a:name" as a name, not index "name" on "a"
5691     if (lhs->lhs_varlen > 1 || var_start[lhs->lhs_varlen] != ':')
5692 	var_end = lhs->lhs_dest_end;
5693 
5694     if (lhs->lhs_dest != dest_option)
5695     {
5696 	if (is_decl && *var_end == ':')
5697 	{
5698 	    char_u *p;
5699 
5700 	    // parse optional type: "let var: type = expr"
5701 	    if (!VIM_ISWHITE(var_end[1]))
5702 	    {
5703 		semsg(_(e_white_space_required_after_str), ":");
5704 		return FAIL;
5705 	    }
5706 	    p = skipwhite(var_end + 1);
5707 	    lhs->lhs_type = parse_type(&p, cctx->ctx_type_list, TRUE);
5708 	    if (lhs->lhs_type == NULL)
5709 		return FAIL;
5710 	    lhs->lhs_has_type = TRUE;
5711 	}
5712 	else if (lhs->lhs_lvar != NULL)
5713 	    lhs->lhs_type = lhs->lhs_lvar->lv_type;
5714     }
5715 
5716     if (oplen == 3 && !heredoc && lhs->lhs_dest != dest_global
5717 		    && lhs->lhs_type->tt_type != VAR_STRING
5718 		    && lhs->lhs_type->tt_type != VAR_ANY)
5719     {
5720 	emsg(_(e_can_only_concatenate_to_string));
5721 	return FAIL;
5722     }
5723 
5724     if (lhs->lhs_lvar == NULL && lhs->lhs_dest == dest_local
5725 						 && cctx->ctx_skip != SKIP_YES)
5726     {
5727 	if (oplen > 1 && !heredoc)
5728 	{
5729 	    // +=, /=, etc. require an existing variable
5730 	    semsg(_(e_cannot_use_operator_on_new_variable), lhs->lhs_name);
5731 	    return FAIL;
5732 	}
5733 	if (!is_decl)
5734 	{
5735 	    semsg(_(e_unknown_variable_str), lhs->lhs_name);
5736 	    return FAIL;
5737 	}
5738 
5739 	// new local variable
5740 	if ((lhs->lhs_type->tt_type == VAR_FUNC
5741 				      || lhs->lhs_type->tt_type == VAR_PARTIAL)
5742 				   && var_wrong_func_name(lhs->lhs_name, TRUE))
5743 	    return FAIL;
5744 	lhs->lhs_lvar = reserve_local(cctx, var_start, lhs->lhs_varlen,
5745 		    cmdidx == CMD_final || cmdidx == CMD_const, lhs->lhs_type);
5746 	if (lhs->lhs_lvar == NULL)
5747 	    return FAIL;
5748 	lhs->lhs_new_local = TRUE;
5749     }
5750 
5751     lhs->lhs_member_type = lhs->lhs_type;
5752     if (lhs->lhs_has_index)
5753     {
5754 	// Something follows after the variable: "var[idx]" or "var.key".
5755 	// TODO: should we also handle "->func()" here?
5756 	if (is_decl)
5757 	{
5758 	    emsg(_(e_cannot_use_index_when_declaring_variable));
5759 	    return FAIL;
5760 	}
5761 
5762 	if (var_start[lhs->lhs_varlen] == '['
5763 					  || var_start[lhs->lhs_varlen] == '.')
5764 	{
5765 	    char_u	*after = var_start + lhs->lhs_varlen;
5766 	    char_u	*p;
5767 
5768 	    // Only the last index is used below, if there are others
5769 	    // before it generate code for the expression.  Thus for
5770 	    // "ll[1][2]" the expression is "ll[1]" and "[2]" is the index.
5771 	    for (;;)
5772 	    {
5773 		p = skip_index(after);
5774 		if (*p != '[' && *p != '.')
5775 		    break;
5776 		after = p;
5777 	    }
5778 	    if (after > var_start + lhs->lhs_varlen)
5779 	    {
5780 		lhs->lhs_varlen = after - var_start;
5781 		lhs->lhs_dest = dest_expr;
5782 		// We don't know the type before evaluating the expression,
5783 		// use "any" until then.
5784 		lhs->lhs_type = &t_any;
5785 	    }
5786 
5787 	    if (lhs->lhs_type->tt_member == NULL)
5788 		lhs->lhs_member_type = &t_any;
5789 	    else
5790 		lhs->lhs_member_type = lhs->lhs_type->tt_member;
5791 	}
5792 	else
5793 	{
5794 	    semsg("Not supported yet: %s", var_start);
5795 	    return FAIL;
5796 	}
5797     }
5798     return OK;
5799 }
5800 
5801 /*
5802  * Assignment to a list or dict member, or ":unlet" for the item, using the
5803  * information in "lhs".
5804  * Returns OK or FAIL.
5805  */
5806     static int
5807 compile_assign_unlet(
5808 	char_u	*var_start,
5809 	lhs_T	*lhs,
5810 	int	is_assign,
5811 	type_T	*rhs_type,
5812 	cctx_T	*cctx)
5813 {
5814     char_u	*p;
5815     int		r;
5816     vartype_T	dest_type;
5817     size_t	varlen = lhs->lhs_varlen;
5818     garray_T    *stack = &cctx->ctx_type_stack;
5819 
5820     // Compile the "idx" in "var[idx]" or "key" in "var.key".
5821     p = var_start + varlen;
5822     if (*p == '[')
5823     {
5824 	p = skipwhite(p + 1);
5825 	r = compile_expr0(&p, cctx);
5826 	if (r == OK && *skipwhite(p) != ']')
5827 	{
5828 	    // this should not happen
5829 	    emsg(_(e_missbrac));
5830 	    r = FAIL;
5831 	}
5832     }
5833     else // if (*p == '.')
5834     {
5835 	char_u *key_end = to_name_end(p + 1, TRUE);
5836 	char_u *key = vim_strnsave(p + 1, key_end - p - 1);
5837 
5838 	r = generate_PUSHS(cctx, key);
5839     }
5840     if (r == FAIL)
5841 	return FAIL;
5842 
5843     if (lhs->lhs_type == &t_any)
5844     {
5845 	// Index on variable of unknown type: check at runtime.
5846 	dest_type = VAR_ANY;
5847     }
5848     else
5849     {
5850 	dest_type = lhs->lhs_type->tt_type;
5851 	if (dest_type == VAR_DICT && may_generate_2STRING(-1, cctx) == FAIL)
5852 	    return FAIL;
5853 	if (dest_type == VAR_LIST
5854 		&& need_type(((type_T **)stack->ga_data)[stack->ga_len - 1],
5855 				 &t_number, -1, 0, cctx, FALSE, FALSE) == FAIL)
5856 	    return FAIL;
5857     }
5858 
5859     // Load the dict or list.  On the stack we then have:
5860     // - value (for assignment, not for :unlet)
5861     // - index
5862     // - variable
5863     if (lhs->lhs_dest == dest_expr)
5864     {
5865 	int	    c = var_start[varlen];
5866 
5867 	// Evaluate "ll[expr]" of "ll[expr][idx]"
5868 	p = var_start;
5869 	var_start[varlen] = NUL;
5870 	if (compile_expr0(&p, cctx) == OK && p != var_start + varlen)
5871 	{
5872 	    // this should not happen
5873 	    emsg(_(e_missbrac));
5874 	    return FAIL;
5875 	}
5876 	var_start[varlen] = c;
5877 
5878 	lhs->lhs_type = stack->ga_len == 0 ? &t_void
5879 		  : ((type_T **)stack->ga_data)[stack->ga_len - 1];
5880 	// now we can properly check the type
5881 	if (lhs->lhs_type->tt_member != NULL && rhs_type != &t_void
5882 		&& need_type(rhs_type, lhs->lhs_type->tt_member, -2, 0, cctx,
5883 							 FALSE, FALSE) == FAIL)
5884 	    return FAIL;
5885     }
5886     else
5887 	generate_loadvar(cctx, lhs->lhs_dest, lhs->lhs_name,
5888 						 lhs->lhs_lvar, lhs->lhs_type);
5889 
5890     if (dest_type == VAR_LIST || dest_type == VAR_DICT || dest_type == VAR_ANY)
5891     {
5892 	if (is_assign)
5893 	{
5894 	    isn_T	*isn = generate_instr_drop(cctx, ISN_STOREINDEX, 3);
5895 
5896 	    if (isn == NULL)
5897 		return FAIL;
5898 	    isn->isn_arg.vartype = dest_type;
5899 	}
5900 	else
5901 	{
5902 	    if (generate_instr_drop(cctx, ISN_UNLETINDEX, 2) == NULL)
5903 		return FAIL;
5904 	}
5905     }
5906     else
5907     {
5908 	emsg(_(e_indexable_type_required));
5909 	return FAIL;
5910     }
5911 
5912     return OK;
5913 }
5914 
5915 /*
5916  * Compile declaration and assignment:
5917  * "let name"
5918  * "var name = expr"
5919  * "final name = expr"
5920  * "const name = expr"
5921  * "name = expr"
5922  * "arg" points to "name".
5923  * Return NULL for an error.
5924  * Return "arg" if it does not look like a variable list.
5925  */
5926     static char_u *
5927 compile_assignment(char_u *arg, exarg_T *eap, cmdidx_T cmdidx, cctx_T *cctx)
5928 {
5929     char_u	*var_start;
5930     char_u	*p;
5931     char_u	*end = arg;
5932     char_u	*ret = NULL;
5933     int		var_count = 0;
5934     int		var_idx;
5935     int		semicolon = 0;
5936     garray_T	*instr = &cctx->ctx_instr;
5937     garray_T    *stack = &cctx->ctx_type_stack;
5938     char_u	*op;
5939     int		oplen = 0;
5940     int		heredoc = FALSE;
5941     type_T	*rhs_type = &t_any;
5942     char_u	*sp;
5943     int		is_decl = is_decl_command(cmdidx);
5944     lhs_T	lhs;
5945 
5946     // Skip over the "var" or "[var, var]" to get to any "=".
5947     p = skip_var_list(arg, TRUE, &var_count, &semicolon, TRUE);
5948     if (p == NULL)
5949 	return *arg == '[' ? arg : NULL;
5950 
5951     if (var_count > 0 && is_decl)
5952     {
5953 	// TODO: should we allow this, and figure out type inference from list
5954 	// members?
5955 	emsg(_(e_cannot_use_list_for_declaration));
5956 	return NULL;
5957     }
5958     lhs.lhs_name = NULL;
5959 
5960     sp = p;
5961     p = skipwhite(p);
5962     op = p;
5963     oplen = assignment_len(p, &heredoc);
5964 
5965     if (var_count > 0 && oplen == 0)
5966 	// can be something like "[1, 2]->func()"
5967 	return arg;
5968 
5969     if (oplen > 0 && (!VIM_ISWHITE(*sp) || !IS_WHITE_OR_NUL(op[oplen])))
5970     {
5971 	error_white_both(op, oplen);
5972 	return NULL;
5973     }
5974 
5975     if (heredoc)
5976     {
5977 	list_T	   *l;
5978 	listitem_T *li;
5979 
5980 	// [let] varname =<< [trim] {end}
5981 	eap->getline = exarg_getline;
5982 	eap->cookie = cctx;
5983 	l = heredoc_get(eap, op + 3, FALSE);
5984 	if (l == NULL)
5985 	    return NULL;
5986 
5987 	if (cctx->ctx_skip != SKIP_YES)
5988 	{
5989 	    // Push each line and the create the list.
5990 	    FOR_ALL_LIST_ITEMS(l, li)
5991 	    {
5992 		generate_PUSHS(cctx, li->li_tv.vval.v_string);
5993 		li->li_tv.vval.v_string = NULL;
5994 	    }
5995 	    generate_NEWLIST(cctx, l->lv_len);
5996 	}
5997 	list_free(l);
5998 	p += STRLEN(p);
5999 	end = p;
6000     }
6001     else if (var_count > 0)
6002     {
6003 	char_u *wp;
6004 
6005 	// for "[var, var] = expr" evaluate the expression here, loop over the
6006 	// list of variables below.
6007 	// A line break may follow the "=".
6008 
6009 	wp = op + oplen;
6010 	if (may_get_next_line_error(wp, &p, cctx) == FAIL)
6011 	    return FAIL;
6012 	if (compile_expr0(&p, cctx) == FAIL)
6013 	    return NULL;
6014 	end = p;
6015 
6016 	if (cctx->ctx_skip != SKIP_YES)
6017 	{
6018 	    type_T	*stacktype;
6019 
6020 	    stacktype = stack->ga_len == 0 ? &t_void
6021 			      : ((type_T **)stack->ga_data)[stack->ga_len - 1];
6022 	    if (stacktype->tt_type == VAR_VOID)
6023 	    {
6024 		emsg(_(e_cannot_use_void_value));
6025 		goto theend;
6026 	    }
6027 	    if (need_type(stacktype, &t_list_any, -1, 0, cctx,
6028 							 FALSE, FALSE) == FAIL)
6029 		goto theend;
6030 	    // TODO: check the length of a constant list here
6031 	    generate_CHECKLEN(cctx, semicolon ? var_count - 1 : var_count,
6032 								    semicolon);
6033 	    if (stacktype->tt_member != NULL)
6034 		rhs_type = stacktype->tt_member;
6035 	}
6036     }
6037 
6038     /*
6039      * Loop over variables in "[var, var] = expr".
6040      * For "var = expr" and "let var: type" this is done only once.
6041      */
6042     if (var_count > 0)
6043 	var_start = skipwhite(arg + 1);  // skip over the "["
6044     else
6045 	var_start = arg;
6046     for (var_idx = 0; var_idx == 0 || var_idx < var_count; var_idx++)
6047     {
6048 	int		instr_count = -1;
6049 
6050 	vim_free(lhs.lhs_name);
6051 
6052 	/*
6053 	 * Figure out the LHS type and other properties.
6054 	 */
6055 	if (compile_lhs(var_start, &lhs, cmdidx, heredoc, oplen, cctx) == FAIL)
6056 	    goto theend;
6057 
6058 	if (!lhs.lhs_has_index && lhs.lhs_lvar == &lhs.lhs_arg_lvar)
6059 	{
6060 	    semsg(_(e_cannot_assign_to_argument), lhs.lhs_name);
6061 	    goto theend;
6062 	}
6063 	if (!is_decl && lhs.lhs_lvar != NULL
6064 			       && lhs.lhs_lvar->lv_const && !lhs.lhs_has_index)
6065 	{
6066 	    semsg(_(e_cannot_assign_to_constant), lhs.lhs_name);
6067 	    goto theend;
6068 	}
6069 
6070 	if (!heredoc)
6071 	{
6072 	    if (cctx->ctx_skip == SKIP_YES)
6073 	    {
6074 		if (oplen > 0 && var_count == 0)
6075 		{
6076 		    // skip over the "=" and the expression
6077 		    p = skipwhite(op + oplen);
6078 		    compile_expr0(&p, cctx);
6079 		}
6080 	    }
6081 	    else if (oplen > 0)
6082 	    {
6083 		int	is_const = FALSE;
6084 		char_u	*wp;
6085 
6086 		// For "var = expr" evaluate the expression.
6087 		if (var_count == 0)
6088 		{
6089 		    int	r;
6090 
6091 		    // for "+=", "*=", "..=" etc. first load the current value
6092 		    if (*op != '=')
6093 		    {
6094 			generate_loadvar(cctx, lhs.lhs_dest, lhs.lhs_name,
6095 						   lhs.lhs_lvar, lhs.lhs_type);
6096 
6097 			if (lhs.lhs_has_index)
6098 			{
6099 			    // TODO: get member from list or dict
6100 			    emsg("Index with operation not supported yet");
6101 			    goto theend;
6102 			}
6103 		    }
6104 
6105 		    // Compile the expression.  Temporarily hide the new local
6106 		    // variable here, it is not available to this expression.
6107 		    if (lhs.lhs_new_local)
6108 			--cctx->ctx_locals.ga_len;
6109 		    instr_count = instr->ga_len;
6110 		    wp = op + oplen;
6111 		    if (may_get_next_line_error(wp, &p, cctx) == FAIL)
6112 		    {
6113 			if (lhs.lhs_new_local)
6114 			    ++cctx->ctx_locals.ga_len;
6115 			goto theend;
6116 		    }
6117 		    r = compile_expr0_ext(&p, cctx, &is_const);
6118 		    if (lhs.lhs_new_local)
6119 			++cctx->ctx_locals.ga_len;
6120 		    if (r == FAIL)
6121 			goto theend;
6122 		}
6123 		else if (semicolon && var_idx == var_count - 1)
6124 		{
6125 		    // For "[var; var] = expr" get the rest of the list
6126 		    if (generate_SLICE(cctx, var_count - 1) == FAIL)
6127 			goto theend;
6128 		}
6129 		else
6130 		{
6131 		    // For "[var, var] = expr" get the "var_idx" item from the
6132 		    // list.
6133 		    if (generate_GETITEM(cctx, var_idx) == FAIL)
6134 			goto theend;
6135 		}
6136 
6137 		rhs_type = stack->ga_len == 0 ? &t_void
6138 			      : ((type_T **)stack->ga_data)[stack->ga_len - 1];
6139 		if (lhs.lhs_lvar != NULL && (is_decl || !lhs.lhs_has_type))
6140 		{
6141 		    if ((rhs_type->tt_type == VAR_FUNC
6142 				|| rhs_type->tt_type == VAR_PARTIAL)
6143 			    && var_wrong_func_name(lhs.lhs_name, TRUE))
6144 			goto theend;
6145 
6146 		    if (lhs.lhs_new_local && !lhs.lhs_has_type)
6147 		    {
6148 			if (rhs_type->tt_type == VAR_VOID)
6149 			{
6150 			    emsg(_(e_cannot_use_void_value));
6151 			    goto theend;
6152 			}
6153 			else
6154 			{
6155 			    // An empty list or dict has a &t_unknown member,
6156 			    // for a variable that implies &t_any.
6157 			    if (rhs_type == &t_list_empty)
6158 				lhs.lhs_lvar->lv_type = &t_list_any;
6159 			    else if (rhs_type == &t_dict_empty)
6160 				lhs.lhs_lvar->lv_type = &t_dict_any;
6161 			    else if (rhs_type == &t_unknown)
6162 				lhs.lhs_lvar->lv_type = &t_any;
6163 			    else
6164 				lhs.lhs_lvar->lv_type = rhs_type;
6165 			}
6166 		    }
6167 		    else if (*op == '=')
6168 		    {
6169 			type_T *use_type = lhs.lhs_lvar->lv_type;
6170 
6171 			// without operator check type here, otherwise below
6172 			if (lhs.lhs_has_index)
6173 			    use_type = lhs.lhs_member_type;
6174 			if (need_type(rhs_type, use_type, -1, 0, cctx,
6175 						      FALSE, is_const) == FAIL)
6176 			    goto theend;
6177 		    }
6178 		}
6179 		else if (*p != '=' && need_type(rhs_type, lhs.lhs_member_type,
6180 					    -1, 0, cctx, FALSE, FALSE) == FAIL)
6181 		    goto theend;
6182 	    }
6183 	    else if (cmdidx == CMD_final)
6184 	    {
6185 		emsg(_(e_final_requires_a_value));
6186 		goto theend;
6187 	    }
6188 	    else if (cmdidx == CMD_const)
6189 	    {
6190 		emsg(_(e_const_requires_a_value));
6191 		goto theend;
6192 	    }
6193 	    else if (!lhs.lhs_has_type || lhs.lhs_dest == dest_option)
6194 	    {
6195 		emsg(_(e_type_or_initialization_required));
6196 		goto theend;
6197 	    }
6198 	    else
6199 	    {
6200 		// variables are always initialized
6201 		if (ga_grow(instr, 1) == FAIL)
6202 		    goto theend;
6203 		switch (lhs.lhs_member_type->tt_type)
6204 		{
6205 		    case VAR_BOOL:
6206 			generate_PUSHBOOL(cctx, VVAL_FALSE);
6207 			break;
6208 		    case VAR_FLOAT:
6209 #ifdef FEAT_FLOAT
6210 			generate_PUSHF(cctx, 0.0);
6211 #endif
6212 			break;
6213 		    case VAR_STRING:
6214 			generate_PUSHS(cctx, NULL);
6215 			break;
6216 		    case VAR_BLOB:
6217 			generate_PUSHBLOB(cctx, blob_alloc());
6218 			break;
6219 		    case VAR_FUNC:
6220 			generate_PUSHFUNC(cctx, NULL, &t_func_void);
6221 			break;
6222 		    case VAR_LIST:
6223 			generate_NEWLIST(cctx, 0);
6224 			break;
6225 		    case VAR_DICT:
6226 			generate_NEWDICT(cctx, 0);
6227 			break;
6228 		    case VAR_JOB:
6229 			generate_PUSHJOB(cctx, NULL);
6230 			break;
6231 		    case VAR_CHANNEL:
6232 			generate_PUSHCHANNEL(cctx, NULL);
6233 			break;
6234 		    case VAR_NUMBER:
6235 		    case VAR_UNKNOWN:
6236 		    case VAR_ANY:
6237 		    case VAR_PARTIAL:
6238 		    case VAR_VOID:
6239 		    case VAR_SPECIAL:  // cannot happen
6240 			generate_PUSHNR(cctx, 0);
6241 			break;
6242 		}
6243 	    }
6244 	    if (var_count == 0)
6245 		end = p;
6246 	}
6247 
6248 	// no need to parse more when skipping
6249 	if (cctx->ctx_skip == SKIP_YES)
6250 	    break;
6251 
6252 	if (oplen > 0 && *op != '=')
6253 	{
6254 	    type_T	    *expected;
6255 	    type_T	    *stacktype;
6256 
6257 	    if (*op == '.')
6258 		expected = &t_string;
6259 	    else
6260 		expected = lhs.lhs_member_type;
6261 	    stacktype = ((type_T **)stack->ga_data)[stack->ga_len - 1];
6262 	    if (
6263 #ifdef FEAT_FLOAT
6264 		// If variable is float operation with number is OK.
6265 		!(expected == &t_float && stacktype == &t_number) &&
6266 #endif
6267 		    need_type(stacktype, expected, -1, 0, cctx,
6268 							 FALSE, FALSE) == FAIL)
6269 		goto theend;
6270 
6271 	    if (*op == '.')
6272 	    {
6273 		if (generate_instr_drop(cctx, ISN_CONCAT, 1) == NULL)
6274 		    goto theend;
6275 	    }
6276 	    else if (*op == '+')
6277 	    {
6278 		if (generate_add_instr(cctx,
6279 			    operator_type(lhs.lhs_member_type, stacktype),
6280 				       lhs.lhs_member_type, stacktype) == FAIL)
6281 		    goto theend;
6282 	    }
6283 	    else if (generate_two_op(cctx, op) == FAIL)
6284 		goto theend;
6285 	}
6286 
6287 	if (lhs.lhs_has_index)
6288 	{
6289 	    // Use the info in "lhs" to store the value at the index in the
6290 	    // list or dict.
6291 	    if (compile_assign_unlet(var_start, &lhs, TRUE, rhs_type, cctx)
6292 								       == FAIL)
6293 		goto theend;
6294 	}
6295 	else
6296 	{
6297 	    if (is_decl && cmdidx == CMD_const && (lhs.lhs_dest == dest_script
6298 						|| lhs.lhs_dest == dest_local))
6299 		// ":const var": lock the value, but not referenced variables
6300 		generate_LOCKCONST(cctx);
6301 
6302 	    if (is_decl
6303 		    && (lhs.lhs_type->tt_type == VAR_DICT
6304 					  || lhs.lhs_type->tt_type == VAR_LIST)
6305 		    && lhs.lhs_type->tt_member != NULL
6306 		    && lhs.lhs_type->tt_member != &t_any
6307 		    && lhs.lhs_type->tt_member != &t_unknown)
6308 		// Set the type in the list or dict, so that it can be checked,
6309 		// also in legacy script.
6310 		generate_SETTYPE(cctx, lhs.lhs_type);
6311 
6312 	    if (lhs.lhs_dest != dest_local)
6313 	    {
6314 		if (generate_store_var(cctx, lhs.lhs_dest,
6315 			    lhs.lhs_opt_flags, lhs.lhs_vimvaridx,
6316 			    lhs.lhs_scriptvar_idx, lhs.lhs_scriptvar_sid,
6317 					   lhs.lhs_type, lhs.lhs_name) == FAIL)
6318 		    goto theend;
6319 	    }
6320 	    else if (lhs.lhs_lvar != NULL)
6321 	    {
6322 		isn_T *isn = ((isn_T *)instr->ga_data)
6323 						   + instr->ga_len - 1;
6324 
6325 		// optimization: turn "var = 123" from ISN_PUSHNR +
6326 		// ISN_STORE into ISN_STORENR
6327 		if (lhs.lhs_lvar->lv_from_outer == 0
6328 				&& instr->ga_len == instr_count + 1
6329 				&& isn->isn_type == ISN_PUSHNR)
6330 		{
6331 		    varnumber_T val = isn->isn_arg.number;
6332 
6333 		    isn->isn_type = ISN_STORENR;
6334 		    isn->isn_arg.storenr.stnr_idx = lhs.lhs_lvar->lv_idx;
6335 		    isn->isn_arg.storenr.stnr_val = val;
6336 		    if (stack->ga_len > 0)
6337 			--stack->ga_len;
6338 		}
6339 		else if (lhs.lhs_lvar->lv_from_outer > 0)
6340 		    generate_STOREOUTER(cctx, lhs.lhs_lvar->lv_idx,
6341 						  lhs.lhs_lvar->lv_from_outer);
6342 		else
6343 		    generate_STORE(cctx, ISN_STORE, lhs.lhs_lvar->lv_idx, NULL);
6344 	    }
6345 	}
6346 
6347 	if (var_idx + 1 < var_count)
6348 	    var_start = skipwhite(lhs.lhs_dest_end + 1);
6349     }
6350 
6351     // for "[var, var] = expr" drop the "expr" value
6352     if (var_count > 0 && !semicolon)
6353     {
6354 	if (generate_instr_drop(cctx, ISN_DROP, 1) == NULL)
6355 	    goto theend;
6356     }
6357 
6358     ret = skipwhite(end);
6359 
6360 theend:
6361     vim_free(lhs.lhs_name);
6362     return ret;
6363 }
6364 
6365 /*
6366  * Check for an assignment at "eap->cmd", compile it if found.
6367  * Return NOTDONE if there is none, FAIL for failure, OK if done.
6368  */
6369     static int
6370 may_compile_assignment(exarg_T *eap, char_u **line, cctx_T *cctx)
6371 {
6372     char_u  *pskip;
6373     char_u  *p;
6374 
6375     // Assuming the command starts with a variable or function name,
6376     // find what follows.
6377     // Skip over "var.member", "var[idx]" and the like.
6378     // Also "&opt = val", "$ENV = val" and "@r = val".
6379     pskip = (*eap->cmd == '&' || *eap->cmd == '$' || *eap->cmd == '@')
6380 						 ? eap->cmd + 1 : eap->cmd;
6381     p = to_name_end(pskip, TRUE);
6382     if (p > eap->cmd && *p != NUL)
6383     {
6384 	char_u *var_end;
6385 	int	oplen;
6386 	int	heredoc;
6387 
6388 	if (eap->cmd[0] == '@')
6389 	    var_end = eap->cmd + 2;
6390 	else
6391 	    var_end = find_name_end(pskip, NULL, NULL,
6392 					FNE_CHECK_START | FNE_INCL_BR);
6393 	oplen = assignment_len(skipwhite(var_end), &heredoc);
6394 	if (oplen > 0)
6395 	{
6396 	    size_t len = p - eap->cmd;
6397 
6398 	    // Recognize an assignment if we recognize the variable
6399 	    // name:
6400 	    // "g:var = expr"
6401 	    // "local = expr"  where "local" is a local var.
6402 	    // "script = expr"  where "script" is a script-local var.
6403 	    // "import = expr"  where "import" is an imported var
6404 	    // "&opt = expr"
6405 	    // "$ENV = expr"
6406 	    // "@r = expr"
6407 	    if (*eap->cmd == '&'
6408 		    || *eap->cmd == '$'
6409 		    || *eap->cmd == '@'
6410 		    || ((len) > 2 && eap->cmd[1] == ':')
6411 		    || lookup_local(eap->cmd, len, NULL, cctx) == OK
6412 		    || arg_exists(eap->cmd, len, NULL, NULL, NULL, cctx) == OK
6413 		    || script_var_exists(eap->cmd, len, FALSE, cctx) == OK
6414 		    || find_imported(eap->cmd, len, cctx) != NULL)
6415 	    {
6416 		*line = compile_assignment(eap->cmd, eap, CMD_SIZE, cctx);
6417 		if (*line == NULL || *line == eap->cmd)
6418 		    return FAIL;
6419 		return OK;
6420 	    }
6421 	}
6422     }
6423 
6424     if (*eap->cmd == '[')
6425     {
6426 	// [var, var] = expr
6427 	*line = compile_assignment(eap->cmd, eap, CMD_SIZE, cctx);
6428 	if (*line == NULL)
6429 	    return FAIL;
6430 	if (*line != eap->cmd)
6431 	    return OK;
6432     }
6433     return NOTDONE;
6434 }
6435 
6436 /*
6437  * Check if "name" can be "unlet".
6438  */
6439     int
6440 check_vim9_unlet(char_u *name)
6441 {
6442     if (name[1] != ':' || vim_strchr((char_u *)"gwtb", *name) == NULL)
6443     {
6444 	// "unlet s:var" is allowed in legacy script.
6445 	if (*name == 's' && !script_is_vim9())
6446 	    return OK;
6447 	semsg(_(e_cannot_unlet_str), name);
6448 	return FAIL;
6449     }
6450     return OK;
6451 }
6452 
6453 /*
6454  * Callback passed to ex_unletlock().
6455  */
6456     static int
6457 compile_unlet(
6458     lval_T  *lvp,
6459     char_u  *name_end,
6460     exarg_T *eap,
6461     int	    deep UNUSED,
6462     void    *coookie)
6463 {
6464     cctx_T	*cctx = coookie;
6465     char_u	*p = lvp->ll_name;
6466     int		cc = *name_end;
6467     int		ret = OK;
6468 
6469     if (cctx->ctx_skip == SKIP_YES)
6470 	return OK;
6471 
6472     *name_end = NUL;
6473     if (*p == '$')
6474     {
6475 	// :unlet $ENV_VAR
6476 	ret = generate_UNLET(cctx, ISN_UNLETENV, p + 1, eap->forceit);
6477     }
6478     else if (vim_strchr(p, '.') != NULL || vim_strchr(p, '[') != NULL)
6479     {
6480 	lhs_T	    lhs;
6481 
6482 	// This is similar to assigning: lookup the list/dict, compile the
6483 	// idx/key.  Then instead of storing the value unlet the item.
6484 	// unlet {list}[idx]
6485 	// unlet {dict}[key]  dict.key
6486 	//
6487 	// Figure out the LHS type and other properties.
6488 	//
6489 	ret = compile_lhs(p, &lhs, CMD_unlet, FALSE, 0, cctx);
6490 
6491 	// : unlet an indexed item
6492 	if (!lhs.lhs_has_index)
6493 	{
6494 	    iemsg("called compile_lhs() without an index");
6495 	    ret = FAIL;
6496 	}
6497 	else
6498 	{
6499 	    // Use the info in "lhs" to unlet the item at the index in the
6500 	    // list or dict.
6501 	    ret = compile_assign_unlet(p, &lhs, FALSE, &t_void, cctx);
6502 	}
6503 
6504 	vim_free(lhs.lhs_name);
6505     }
6506     else if (check_vim9_unlet(p) == FAIL)
6507     {
6508 	ret = FAIL;
6509     }
6510     else
6511     {
6512 	// Normal name.  Only supports g:, w:, t: and b: namespaces.
6513 	ret = generate_UNLET(cctx, ISN_UNLET, p, eap->forceit);
6514     }
6515 
6516     *name_end = cc;
6517     return ret;
6518 }
6519 
6520 /*
6521  * compile "unlet var", "lock var" and "unlock var"
6522  * "arg" points to "var".
6523  */
6524     static char_u *
6525 compile_unletlock(char_u *arg, exarg_T *eap, cctx_T *cctx)
6526 {
6527     char_u *p = arg;
6528 
6529     if (eap->cmdidx != CMD_unlet)
6530     {
6531 	emsg("Sorry, :lock and unlock not implemented yet");
6532 	return NULL;
6533     }
6534 
6535     ex_unletlock(eap, p, 0, GLV_NO_AUTOLOAD | GLV_COMPILING,
6536 							  compile_unlet, cctx);
6537     return eap->nextcmd == NULL ? (char_u *)"" : eap->nextcmd;
6538 }
6539 
6540 /*
6541  * Compile an :import command.
6542  */
6543     static char_u *
6544 compile_import(char_u *arg, cctx_T *cctx)
6545 {
6546     return handle_import(arg, &cctx->ctx_imports, 0, NULL, cctx);
6547 }
6548 
6549 /*
6550  * generate a jump to the ":endif"/":endfor"/":endwhile"/":finally"/":endtry".
6551  */
6552     static int
6553 compile_jump_to_end(endlabel_T **el, jumpwhen_T when, cctx_T *cctx)
6554 {
6555     garray_T	*instr = &cctx->ctx_instr;
6556     endlabel_T  *endlabel = ALLOC_CLEAR_ONE(endlabel_T);
6557 
6558     if (endlabel == NULL)
6559 	return FAIL;
6560     endlabel->el_next = *el;
6561     *el = endlabel;
6562     endlabel->el_end_label = instr->ga_len;
6563 
6564     generate_JUMP(cctx, when, 0);
6565     return OK;
6566 }
6567 
6568     static void
6569 compile_fill_jump_to_end(endlabel_T **el, int jump_where, cctx_T *cctx)
6570 {
6571     garray_T	*instr = &cctx->ctx_instr;
6572 
6573     while (*el != NULL)
6574     {
6575 	endlabel_T  *cur = (*el);
6576 	isn_T	    *isn;
6577 
6578 	isn = ((isn_T *)instr->ga_data) + cur->el_end_label;
6579 	isn->isn_arg.jump.jump_where = jump_where;
6580 	*el = cur->el_next;
6581 	vim_free(cur);
6582     }
6583 }
6584 
6585     static void
6586 compile_free_jump_to_end(endlabel_T **el)
6587 {
6588     while (*el != NULL)
6589     {
6590 	endlabel_T  *cur = (*el);
6591 
6592 	*el = cur->el_next;
6593 	vim_free(cur);
6594     }
6595 }
6596 
6597 /*
6598  * Create a new scope and set up the generic items.
6599  */
6600     static scope_T *
6601 new_scope(cctx_T *cctx, scopetype_T type)
6602 {
6603     scope_T *scope = ALLOC_CLEAR_ONE(scope_T);
6604 
6605     if (scope == NULL)
6606 	return NULL;
6607     scope->se_outer = cctx->ctx_scope;
6608     cctx->ctx_scope = scope;
6609     scope->se_type = type;
6610     scope->se_local_count = cctx->ctx_locals.ga_len;
6611     return scope;
6612 }
6613 
6614 /*
6615  * Free the current scope and go back to the outer scope.
6616  */
6617     static void
6618 drop_scope(cctx_T *cctx)
6619 {
6620     scope_T *scope = cctx->ctx_scope;
6621 
6622     if (scope == NULL)
6623     {
6624 	iemsg("calling drop_scope() without a scope");
6625 	return;
6626     }
6627     cctx->ctx_scope = scope->se_outer;
6628     switch (scope->se_type)
6629     {
6630 	case IF_SCOPE:
6631 	    compile_free_jump_to_end(&scope->se_u.se_if.is_end_label); break;
6632 	case FOR_SCOPE:
6633 	    compile_free_jump_to_end(&scope->se_u.se_for.fs_end_label); break;
6634 	case WHILE_SCOPE:
6635 	    compile_free_jump_to_end(&scope->se_u.se_while.ws_end_label); break;
6636 	case TRY_SCOPE:
6637 	    compile_free_jump_to_end(&scope->se_u.se_try.ts_end_label); break;
6638 	case NO_SCOPE:
6639 	case BLOCK_SCOPE:
6640 	    break;
6641     }
6642     vim_free(scope);
6643 }
6644 
6645 /*
6646  * compile "if expr"
6647  *
6648  * "if expr" Produces instructions:
6649  *	EVAL expr		Push result of "expr"
6650  *	JUMP_IF_FALSE end
6651  *	... body ...
6652  * end:
6653  *
6654  * "if expr | else" Produces instructions:
6655  *	EVAL expr		Push result of "expr"
6656  *	JUMP_IF_FALSE else
6657  *	... body ...
6658  *	JUMP_ALWAYS end
6659  * else:
6660  *	... body ...
6661  * end:
6662  *
6663  * "if expr1 | elseif expr2 | else" Produces instructions:
6664  *	EVAL expr		Push result of "expr"
6665  *	JUMP_IF_FALSE elseif
6666  *	... body ...
6667  *	JUMP_ALWAYS end
6668  * elseif:
6669  *	EVAL expr		Push result of "expr"
6670  *	JUMP_IF_FALSE else
6671  *	... body ...
6672  *	JUMP_ALWAYS end
6673  * else:
6674  *	... body ...
6675  * end:
6676  */
6677     static char_u *
6678 compile_if(char_u *arg, cctx_T *cctx)
6679 {
6680     char_u	*p = arg;
6681     garray_T	*instr = &cctx->ctx_instr;
6682     int		instr_count = instr->ga_len;
6683     scope_T	*scope;
6684     skip_T	skip_save = cctx->ctx_skip;
6685     ppconst_T	ppconst;
6686 
6687     CLEAR_FIELD(ppconst);
6688     if (compile_expr1(&p, cctx, &ppconst) == FAIL)
6689     {
6690 	clear_ppconst(&ppconst);
6691 	return NULL;
6692     }
6693     if (cctx->ctx_skip == SKIP_YES)
6694 	clear_ppconst(&ppconst);
6695     else if (instr->ga_len == instr_count && ppconst.pp_used == 1)
6696     {
6697 	int error = FALSE;
6698 	int v;
6699 
6700 	// The expression results in a constant.
6701 	v = tv_get_bool_chk(&ppconst.pp_tv[0], &error);
6702 	clear_ppconst(&ppconst);
6703 	if (error)
6704 	    return NULL;
6705 	cctx->ctx_skip = v ? SKIP_NOT : SKIP_YES;
6706     }
6707     else
6708     {
6709 	// Not a constant, generate instructions for the expression.
6710 	cctx->ctx_skip = SKIP_UNKNOWN;
6711 	if (generate_ppconst(cctx, &ppconst) == FAIL)
6712 	    return NULL;
6713 	if (bool_on_stack(cctx) == FAIL)
6714 	    return NULL;
6715     }
6716 
6717     scope = new_scope(cctx, IF_SCOPE);
6718     if (scope == NULL)
6719 	return NULL;
6720     scope->se_skip_save = skip_save;
6721     // "is_had_return" will be reset if any block does not end in :return
6722     scope->se_u.se_if.is_had_return = TRUE;
6723 
6724     if (cctx->ctx_skip == SKIP_UNKNOWN)
6725     {
6726 	// "where" is set when ":elseif", "else" or ":endif" is found
6727 	scope->se_u.se_if.is_if_label = instr->ga_len;
6728 	generate_JUMP(cctx, JUMP_IF_FALSE, 0);
6729     }
6730     else
6731 	scope->se_u.se_if.is_if_label = -1;
6732 
6733 #ifdef FEAT_PROFILE
6734     if (cctx->ctx_profiling && cctx->ctx_skip == SKIP_YES
6735 						      && skip_save != SKIP_YES)
6736     {
6737 	// generated a profile start, need to generate a profile end, since it
6738 	// won't be done after returning
6739 	cctx->ctx_skip = SKIP_NOT;
6740 	generate_instr(cctx, ISN_PROF_END);
6741 	cctx->ctx_skip = SKIP_YES;
6742     }
6743 #endif
6744 
6745     return p;
6746 }
6747 
6748     static char_u *
6749 compile_elseif(char_u *arg, cctx_T *cctx)
6750 {
6751     char_u	*p = arg;
6752     garray_T	*instr = &cctx->ctx_instr;
6753     int		instr_count = instr->ga_len;
6754     isn_T	*isn;
6755     scope_T	*scope = cctx->ctx_scope;
6756     ppconst_T	ppconst;
6757     skip_T	save_skip = cctx->ctx_skip;
6758 
6759     if (scope == NULL || scope->se_type != IF_SCOPE)
6760     {
6761 	emsg(_(e_elseif_without_if));
6762 	return NULL;
6763     }
6764     unwind_locals(cctx, scope->se_local_count);
6765     if (!cctx->ctx_had_return)
6766 	scope->se_u.se_if.is_had_return = FALSE;
6767 
6768     if (cctx->ctx_skip == SKIP_NOT)
6769     {
6770 	// previous block was executed, this one and following will not
6771 	cctx->ctx_skip = SKIP_YES;
6772 	scope->se_u.se_if.is_seen_skip_not = TRUE;
6773     }
6774     if (scope->se_u.se_if.is_seen_skip_not)
6775     {
6776 	// A previous block was executed, skip over expression and bail out.
6777 	// Do not count the "elseif" for profiling.
6778 #ifdef FEAT_PROFILE
6779 	if (cctx->ctx_profiling && ((isn_T *)instr->ga_data)[instr->ga_len - 1]
6780 						   .isn_type == ISN_PROF_START)
6781 	    --instr->ga_len;
6782 #endif
6783 	skip_expr_cctx(&p, cctx);
6784 	return p;
6785     }
6786 
6787     if (cctx->ctx_skip == SKIP_UNKNOWN)
6788     {
6789 	if (compile_jump_to_end(&scope->se_u.se_if.is_end_label,
6790 						    JUMP_ALWAYS, cctx) == FAIL)
6791 	    return NULL;
6792 	// previous "if" or "elseif" jumps here
6793 	isn = ((isn_T *)instr->ga_data) + scope->se_u.se_if.is_if_label;
6794 	isn->isn_arg.jump.jump_where = instr->ga_len;
6795     }
6796 
6797     // compile "expr"; if we know it evaluates to FALSE skip the block
6798     CLEAR_FIELD(ppconst);
6799     if (cctx->ctx_skip == SKIP_YES)
6800     {
6801 	cctx->ctx_skip = SKIP_UNKNOWN;
6802 #ifdef FEAT_PROFILE
6803 	if (cctx->ctx_profiling)
6804 	{
6805 	    // the previous block was skipped, need to profile this line
6806 	    generate_instr(cctx, ISN_PROF_START);
6807 	    instr_count = instr->ga_len;
6808 	}
6809 #endif
6810     }
6811     if (compile_expr1(&p, cctx, &ppconst) == FAIL)
6812     {
6813 	clear_ppconst(&ppconst);
6814 	return NULL;
6815     }
6816     cctx->ctx_skip = save_skip;
6817     if (scope->se_skip_save == SKIP_YES)
6818 	clear_ppconst(&ppconst);
6819     else if (instr->ga_len == instr_count && ppconst.pp_used == 1)
6820     {
6821 	int error = FALSE;
6822 	int v;
6823 
6824 	// The expression results in a constant.
6825 	// TODO: how about nesting?
6826 	v = tv_get_bool_chk(&ppconst.pp_tv[0], &error);
6827 	if (error)
6828 	    return NULL;
6829 	cctx->ctx_skip = v ? SKIP_NOT : SKIP_YES;
6830 	clear_ppconst(&ppconst);
6831 	scope->se_u.se_if.is_if_label = -1;
6832     }
6833     else
6834     {
6835 	// Not a constant, generate instructions for the expression.
6836 	cctx->ctx_skip = SKIP_UNKNOWN;
6837 	if (generate_ppconst(cctx, &ppconst) == FAIL)
6838 	    return NULL;
6839 	if (bool_on_stack(cctx) == FAIL)
6840 	    return NULL;
6841 
6842 	// "where" is set when ":elseif", "else" or ":endif" is found
6843 	scope->se_u.se_if.is_if_label = instr->ga_len;
6844 	generate_JUMP(cctx, JUMP_IF_FALSE, 0);
6845     }
6846 
6847     return p;
6848 }
6849 
6850     static char_u *
6851 compile_else(char_u *arg, cctx_T *cctx)
6852 {
6853     char_u	*p = arg;
6854     garray_T	*instr = &cctx->ctx_instr;
6855     isn_T	*isn;
6856     scope_T	*scope = cctx->ctx_scope;
6857 
6858     if (scope == NULL || scope->se_type != IF_SCOPE)
6859     {
6860 	emsg(_(e_else_without_if));
6861 	return NULL;
6862     }
6863     unwind_locals(cctx, scope->se_local_count);
6864     if (!cctx->ctx_had_return)
6865 	scope->se_u.se_if.is_had_return = FALSE;
6866     scope->se_u.se_if.is_seen_else = TRUE;
6867 
6868 #ifdef FEAT_PROFILE
6869     if (cctx->ctx_profiling)
6870     {
6871 	if (cctx->ctx_skip == SKIP_NOT
6872 		&& ((isn_T *)instr->ga_data)[instr->ga_len - 1]
6873 						   .isn_type == ISN_PROF_START)
6874 	    // the previous block was executed, do not count "else" for profiling
6875 	    --instr->ga_len;
6876 	if (cctx->ctx_skip == SKIP_YES && !scope->se_u.se_if.is_seen_skip_not)
6877 	{
6878 	    // the previous block was not executed, this one will, do count the
6879 	    // "else" for profiling
6880 	    cctx->ctx_skip = SKIP_NOT;
6881 	    generate_instr(cctx, ISN_PROF_END);
6882 	    generate_instr(cctx, ISN_PROF_START);
6883 	    cctx->ctx_skip = SKIP_YES;
6884 	}
6885     }
6886 #endif
6887 
6888     if (!scope->se_u.se_if.is_seen_skip_not && scope->se_skip_save != SKIP_YES)
6889     {
6890 	// jump from previous block to the end, unless the else block is empty
6891 	if (cctx->ctx_skip == SKIP_UNKNOWN)
6892 	{
6893 	    if (!cctx->ctx_had_return
6894 		    && compile_jump_to_end(&scope->se_u.se_if.is_end_label,
6895 						    JUMP_ALWAYS, cctx) == FAIL)
6896 		return NULL;
6897 	}
6898 
6899 	if (cctx->ctx_skip == SKIP_UNKNOWN)
6900 	{
6901 	    if (scope->se_u.se_if.is_if_label >= 0)
6902 	    {
6903 		// previous "if" or "elseif" jumps here
6904 		isn = ((isn_T *)instr->ga_data) + scope->se_u.se_if.is_if_label;
6905 		isn->isn_arg.jump.jump_where = instr->ga_len;
6906 		scope->se_u.se_if.is_if_label = -1;
6907 	    }
6908 	}
6909 
6910 	if (cctx->ctx_skip != SKIP_UNKNOWN)
6911 	    cctx->ctx_skip = cctx->ctx_skip == SKIP_YES ? SKIP_NOT : SKIP_YES;
6912     }
6913 
6914     return p;
6915 }
6916 
6917     static char_u *
6918 compile_endif(char_u *arg, cctx_T *cctx)
6919 {
6920     scope_T	*scope = cctx->ctx_scope;
6921     ifscope_T	*ifscope;
6922     garray_T	*instr = &cctx->ctx_instr;
6923     isn_T	*isn;
6924 
6925     if (scope == NULL || scope->se_type != IF_SCOPE)
6926     {
6927 	emsg(_(e_endif_without_if));
6928 	return NULL;
6929     }
6930     ifscope = &scope->se_u.se_if;
6931     unwind_locals(cctx, scope->se_local_count);
6932     if (!cctx->ctx_had_return)
6933 	ifscope->is_had_return = FALSE;
6934 
6935     if (scope->se_u.se_if.is_if_label >= 0)
6936     {
6937 	// previous "if" or "elseif" jumps here
6938 	isn = ((isn_T *)instr->ga_data) + scope->se_u.se_if.is_if_label;
6939 	isn->isn_arg.jump.jump_where = instr->ga_len;
6940     }
6941     // Fill in the "end" label in jumps at the end of the blocks.
6942     compile_fill_jump_to_end(&ifscope->is_end_label, instr->ga_len, cctx);
6943 
6944 #ifdef FEAT_PROFILE
6945     // even when skipping we count the endif as executed, unless the block it's
6946     // in is skipped
6947     if (cctx->ctx_profiling && cctx->ctx_skip == SKIP_YES
6948 					    && scope->se_skip_save != SKIP_YES)
6949     {
6950 	cctx->ctx_skip = SKIP_NOT;
6951 	generate_instr(cctx, ISN_PROF_START);
6952     }
6953 #endif
6954     cctx->ctx_skip = scope->se_skip_save;
6955 
6956     // If all the blocks end in :return and there is an :else then the
6957     // had_return flag is set.
6958     cctx->ctx_had_return = ifscope->is_had_return && ifscope->is_seen_else;
6959 
6960     drop_scope(cctx);
6961     return arg;
6962 }
6963 
6964 /*
6965  * Compile "for var in expr":
6966  *
6967  * Produces instructions:
6968  *       PUSHNR -1
6969  *       STORE loop-idx		Set index to -1
6970  *       EVAL expr		result of "expr" on top of stack
6971  * top:  FOR loop-idx, end	Increment index, use list on bottom of stack
6972  *				- if beyond end, jump to "end"
6973  *				- otherwise get item from list and push it
6974  *       STORE var		Store item in "var"
6975  *       ... body ...
6976  *       JUMP top		Jump back to repeat
6977  * end:	 DROP			Drop the result of "expr"
6978  *
6979  * Compile "for [var1, var2] in expr" - as above, but instead of "STORE var":
6980  *	 UNPACK 2		Split item in 2
6981  *       STORE var1		Store item in "var1"
6982  *       STORE var2		Store item in "var2"
6983  */
6984     static char_u *
6985 compile_for(char_u *arg_start, cctx_T *cctx)
6986 {
6987     char_u	*arg;
6988     char_u	*arg_end;
6989     char_u	*name = NULL;
6990     char_u	*p;
6991     char_u	*wp;
6992     int		var_count = 0;
6993     int		semicolon = FALSE;
6994     size_t	varlen;
6995     garray_T	*instr = &cctx->ctx_instr;
6996     garray_T	*stack = &cctx->ctx_type_stack;
6997     scope_T	*scope;
6998     lvar_T	*loop_lvar;	// loop iteration variable
6999     lvar_T	*var_lvar;	// variable for "var"
7000     type_T	*vartype;
7001     type_T	*item_type = &t_any;
7002     int		idx;
7003 
7004     p = skip_var_list(arg_start, TRUE, &var_count, &semicolon, FALSE);
7005     if (p == NULL)
7006 	return NULL;
7007     if (var_count == 0)
7008 	var_count = 1;
7009 
7010     // consume "in"
7011     wp = p;
7012     if (may_get_next_line_error(wp, &p, cctx) == FAIL)
7013 	return NULL;
7014     if (STRNCMP(p, "in", 2) != 0 || !IS_WHITE_OR_NUL(p[2]))
7015     {
7016 	emsg(_(e_missing_in));
7017 	return NULL;
7018     }
7019     wp = p + 2;
7020     if (may_get_next_line_error(wp, &p, cctx) == FAIL)
7021 	return NULL;
7022 
7023     scope = new_scope(cctx, FOR_SCOPE);
7024     if (scope == NULL)
7025 	return NULL;
7026 
7027     // Reserve a variable to store the loop iteration counter and initialize it
7028     // to -1.
7029     loop_lvar = reserve_local(cctx, (char_u *)"", 0, FALSE, &t_number);
7030     if (loop_lvar == NULL)
7031     {
7032 	// out of memory
7033 	drop_scope(cctx);
7034 	return NULL;
7035     }
7036     generate_STORENR(cctx, loop_lvar->lv_idx, -1);
7037 
7038     // compile "expr", it remains on the stack until "endfor"
7039     arg = p;
7040     if (compile_expr0(&arg, cctx) == FAIL)
7041     {
7042 	drop_scope(cctx);
7043 	return NULL;
7044     }
7045     arg_end = arg;
7046 
7047     // Now that we know the type of "var", check that it is a list, now or at
7048     // runtime.
7049     vartype = ((type_T **)stack->ga_data)[stack->ga_len - 1];
7050     if (need_type(vartype, &t_list_any, -1, 0, cctx, FALSE, FALSE) == FAIL)
7051     {
7052 	drop_scope(cctx);
7053 	return NULL;
7054     }
7055 
7056     if (vartype->tt_type == VAR_LIST && vartype->tt_member->tt_type != VAR_ANY)
7057     {
7058 	if (var_count == 1)
7059 	    item_type = vartype->tt_member;
7060 	else if (vartype->tt_member->tt_type == VAR_LIST
7061 		      && vartype->tt_member->tt_member->tt_type != VAR_ANY)
7062 	    item_type = vartype->tt_member->tt_member;
7063     }
7064 
7065     // "for_end" is set when ":endfor" is found
7066     scope->se_u.se_for.fs_top_label = instr->ga_len;
7067     generate_FOR(cctx, loop_lvar->lv_idx);
7068 
7069     arg = arg_start;
7070     if (var_count > 1)
7071     {
7072 	generate_UNPACK(cctx, var_count, semicolon);
7073 	arg = skipwhite(arg + 1);	// skip white after '['
7074 
7075 	// the list item is replaced by a number of items
7076 	if (ga_grow(stack, var_count - 1) == FAIL)
7077 	{
7078 	    drop_scope(cctx);
7079 	    return NULL;
7080 	}
7081 	--stack->ga_len;
7082 	for (idx = 0; idx < var_count; ++idx)
7083 	{
7084 	    ((type_T **)stack->ga_data)[stack->ga_len] =
7085 				(semicolon && idx == 0) ? vartype : item_type;
7086 	    ++stack->ga_len;
7087 	}
7088     }
7089 
7090     for (idx = 0; idx < var_count; ++idx)
7091     {
7092 	assign_dest_T	dest = dest_local;
7093 	int		opt_flags = 0;
7094 	int		vimvaridx = -1;
7095 	type_T		*type = &t_any;
7096 
7097 	p = skip_var_one(arg, FALSE);
7098 	varlen = p - arg;
7099 	name = vim_strnsave(arg, varlen);
7100 	if (name == NULL)
7101 	    goto failed;
7102 
7103 	// TODO: script var not supported?
7104 	if (get_var_dest(name, &dest, CMD_for, &opt_flags,
7105 					      &vimvaridx, &type, cctx) == FAIL)
7106 	    goto failed;
7107 	if (dest != dest_local)
7108 	{
7109 	    if (generate_store_var(cctx, dest, opt_flags, vimvaridx,
7110 						     0, 0, type, name) == FAIL)
7111 		goto failed;
7112 	}
7113 	else
7114 	{
7115 	    if (lookup_local(arg, varlen, NULL, cctx) == OK)
7116 	    {
7117 		semsg(_(e_variable_already_declared), arg);
7118 		goto failed;
7119 	    }
7120 
7121 	    if (STRNCMP(name, "s:", 2) == 0)
7122 	    {
7123 		semsg(_(e_cannot_declare_script_variable_in_function), name);
7124 		goto failed;
7125 	    }
7126 
7127 	    // Reserve a variable to store "var".
7128 	    // TODO: check for type
7129 	    var_lvar = reserve_local(cctx, arg, varlen, FALSE, &t_any);
7130 	    if (var_lvar == NULL)
7131 		// out of memory or used as an argument
7132 		goto failed;
7133 
7134 	    if (semicolon && idx == var_count - 1)
7135 		var_lvar->lv_type = vartype;
7136 	    else
7137 		var_lvar->lv_type = item_type;
7138 	    generate_STORE(cctx, ISN_STORE, var_lvar->lv_idx, NULL);
7139 	}
7140 
7141 	if (*p == ':')
7142 	    p = skip_type(skipwhite(p + 1), FALSE);
7143 	if (*p == ',' || *p == ';')
7144 	    ++p;
7145 	arg = skipwhite(p);
7146 	vim_free(name);
7147     }
7148 
7149     return arg_end;
7150 
7151 failed:
7152     vim_free(name);
7153     drop_scope(cctx);
7154     return NULL;
7155 }
7156 
7157 /*
7158  * compile "endfor"
7159  */
7160     static char_u *
7161 compile_endfor(char_u *arg, cctx_T *cctx)
7162 {
7163     garray_T	*instr = &cctx->ctx_instr;
7164     scope_T	*scope = cctx->ctx_scope;
7165     forscope_T	*forscope;
7166     isn_T	*isn;
7167 
7168     if (scope == NULL || scope->se_type != FOR_SCOPE)
7169     {
7170 	emsg(_(e_for));
7171 	return NULL;
7172     }
7173     forscope = &scope->se_u.se_for;
7174     cctx->ctx_scope = scope->se_outer;
7175     unwind_locals(cctx, scope->se_local_count);
7176 
7177     // At end of ":for" scope jump back to the FOR instruction.
7178     generate_JUMP(cctx, JUMP_ALWAYS, forscope->fs_top_label);
7179 
7180     // Fill in the "end" label in the FOR statement so it can jump here
7181     isn = ((isn_T *)instr->ga_data) + forscope->fs_top_label;
7182     isn->isn_arg.forloop.for_end = instr->ga_len;
7183 
7184     // Fill in the "end" label any BREAK statements
7185     compile_fill_jump_to_end(&forscope->fs_end_label, instr->ga_len, cctx);
7186 
7187     // Below the ":for" scope drop the "expr" list from the stack.
7188     if (generate_instr_drop(cctx, ISN_DROP, 1) == NULL)
7189 	return NULL;
7190 
7191     vim_free(scope);
7192 
7193     return arg;
7194 }
7195 
7196 /*
7197  * compile "while expr"
7198  *
7199  * Produces instructions:
7200  * top:  EVAL expr		Push result of "expr"
7201  *       JUMP_IF_FALSE end	jump if false
7202  *       ... body ...
7203  *       JUMP top		Jump back to repeat
7204  * end:
7205  *
7206  */
7207     static char_u *
7208 compile_while(char_u *arg, cctx_T *cctx)
7209 {
7210     char_u	*p = arg;
7211     garray_T	*instr = &cctx->ctx_instr;
7212     scope_T	*scope;
7213 
7214     scope = new_scope(cctx, WHILE_SCOPE);
7215     if (scope == NULL)
7216 	return NULL;
7217 
7218     // "endwhile" jumps back here, one before when profiling
7219     scope->se_u.se_while.ws_top_label = instr->ga_len;
7220 #ifdef FEAT_PROFILE
7221     if (cctx->ctx_profiling && ((isn_T *)instr->ga_data)[instr->ga_len - 1]
7222 						   .isn_type == ISN_PROF_START)
7223 	--scope->se_u.se_while.ws_top_label;
7224 #endif
7225 
7226     // compile "expr"
7227     if (compile_expr0(&p, cctx) == FAIL)
7228 	return NULL;
7229 
7230     if (bool_on_stack(cctx) == FAIL)
7231 	return FAIL;
7232 
7233     // "while_end" is set when ":endwhile" is found
7234     if (compile_jump_to_end(&scope->se_u.se_while.ws_end_label,
7235 						  JUMP_IF_FALSE, cctx) == FAIL)
7236 	return FAIL;
7237 
7238     return p;
7239 }
7240 
7241 /*
7242  * compile "endwhile"
7243  */
7244     static char_u *
7245 compile_endwhile(char_u *arg, cctx_T *cctx)
7246 {
7247     scope_T	*scope = cctx->ctx_scope;
7248     garray_T	*instr = &cctx->ctx_instr;
7249 
7250     if (scope == NULL || scope->se_type != WHILE_SCOPE)
7251     {
7252 	emsg(_(e_while));
7253 	return NULL;
7254     }
7255     cctx->ctx_scope = scope->se_outer;
7256     unwind_locals(cctx, scope->se_local_count);
7257 
7258 #ifdef FEAT_PROFILE
7259     // count the endwhile before jumping
7260     may_generate_prof_end(cctx, cctx->ctx_lnum);
7261 #endif
7262 
7263     // At end of ":for" scope jump back to the FOR instruction.
7264     generate_JUMP(cctx, JUMP_ALWAYS, scope->se_u.se_while.ws_top_label);
7265 
7266     // Fill in the "end" label in the WHILE statement so it can jump here.
7267     // And in any jumps for ":break"
7268     compile_fill_jump_to_end(&scope->se_u.se_while.ws_end_label,
7269 							  instr->ga_len, cctx);
7270 
7271     vim_free(scope);
7272 
7273     return arg;
7274 }
7275 
7276 /*
7277  * compile "continue"
7278  */
7279     static char_u *
7280 compile_continue(char_u *arg, cctx_T *cctx)
7281 {
7282     scope_T	*scope = cctx->ctx_scope;
7283 
7284     for (;;)
7285     {
7286 	if (scope == NULL)
7287 	{
7288 	    emsg(_(e_continue));
7289 	    return NULL;
7290 	}
7291 	if (scope->se_type == FOR_SCOPE || scope->se_type == WHILE_SCOPE)
7292 	    break;
7293 	scope = scope->se_outer;
7294     }
7295 
7296     // Jump back to the FOR or WHILE instruction.
7297     generate_JUMP(cctx, JUMP_ALWAYS,
7298 	    scope->se_type == FOR_SCOPE ? scope->se_u.se_for.fs_top_label
7299 					  : scope->se_u.se_while.ws_top_label);
7300     return arg;
7301 }
7302 
7303 /*
7304  * compile "break"
7305  */
7306     static char_u *
7307 compile_break(char_u *arg, cctx_T *cctx)
7308 {
7309     scope_T	*scope = cctx->ctx_scope;
7310     endlabel_T	**el;
7311 
7312     for (;;)
7313     {
7314 	if (scope == NULL)
7315 	{
7316 	    emsg(_(e_break));
7317 	    return NULL;
7318 	}
7319 	if (scope->se_type == FOR_SCOPE || scope->se_type == WHILE_SCOPE)
7320 	    break;
7321 	scope = scope->se_outer;
7322     }
7323 
7324     // Jump to the end of the FOR or WHILE loop.
7325     if (scope->se_type == FOR_SCOPE)
7326 	el = &scope->se_u.se_for.fs_end_label;
7327     else
7328 	el = &scope->se_u.se_while.ws_end_label;
7329     if (compile_jump_to_end(el, JUMP_ALWAYS, cctx) == FAIL)
7330 	return FAIL;
7331 
7332     return arg;
7333 }
7334 
7335 /*
7336  * compile "{" start of block
7337  */
7338     static char_u *
7339 compile_block(char_u *arg, cctx_T *cctx)
7340 {
7341     if (new_scope(cctx, BLOCK_SCOPE) == NULL)
7342 	return NULL;
7343     return skipwhite(arg + 1);
7344 }
7345 
7346 /*
7347  * compile end of block: drop one scope
7348  */
7349     static void
7350 compile_endblock(cctx_T *cctx)
7351 {
7352     scope_T	*scope = cctx->ctx_scope;
7353 
7354     cctx->ctx_scope = scope->se_outer;
7355     unwind_locals(cctx, scope->se_local_count);
7356     vim_free(scope);
7357 }
7358 
7359 /*
7360  * compile "try"
7361  * Creates a new scope for the try-endtry, pointing to the first catch and
7362  * finally.
7363  * Creates another scope for the "try" block itself.
7364  * TRY instruction sets up exception handling at runtime.
7365  *
7366  *	"try"
7367  *	    TRY -> catch1, -> finally  push trystack entry
7368  *	    ... try block
7369  *	"throw {exception}"
7370  *	    EVAL {exception}
7371  *	    THROW		create exception
7372  *	    ... try block
7373  *	" catch {expr}"
7374  *	    JUMP -> finally
7375  * catch1:  PUSH exception
7376  *	    EVAL {expr}
7377  *	    MATCH
7378  *	    JUMP nomatch -> catch2
7379  *	    CATCH   remove exception
7380  *	    ... catch block
7381  *	" catch"
7382  *	    JUMP -> finally
7383  * catch2:  CATCH   remove exception
7384  *	    ... catch block
7385  *	" finally"
7386  * finally:
7387  *	    ... finally block
7388  *	" endtry"
7389  *	    ENDTRY  pop trystack entry, may rethrow
7390  */
7391     static char_u *
7392 compile_try(char_u *arg, cctx_T *cctx)
7393 {
7394     garray_T	*instr = &cctx->ctx_instr;
7395     scope_T	*try_scope;
7396     scope_T	*scope;
7397 
7398     // scope that holds the jumps that go to catch/finally/endtry
7399     try_scope = new_scope(cctx, TRY_SCOPE);
7400     if (try_scope == NULL)
7401 	return NULL;
7402 
7403     if (cctx->ctx_skip != SKIP_YES)
7404     {
7405 	// "catch" is set when the first ":catch" is found.
7406 	// "finally" is set when ":finally" or ":endtry" is found
7407 	try_scope->se_u.se_try.ts_try_label = instr->ga_len;
7408 	if (generate_instr(cctx, ISN_TRY) == NULL)
7409 	    return NULL;
7410     }
7411 
7412     // scope for the try block itself
7413     scope = new_scope(cctx, BLOCK_SCOPE);
7414     if (scope == NULL)
7415 	return NULL;
7416 
7417     return arg;
7418 }
7419 
7420 /*
7421  * compile "catch {expr}"
7422  */
7423     static char_u *
7424 compile_catch(char_u *arg, cctx_T *cctx UNUSED)
7425 {
7426     scope_T	*scope = cctx->ctx_scope;
7427     garray_T	*instr = &cctx->ctx_instr;
7428     char_u	*p;
7429     isn_T	*isn;
7430 
7431     // end block scope from :try or :catch
7432     if (scope != NULL && scope->se_type == BLOCK_SCOPE)
7433 	compile_endblock(cctx);
7434     scope = cctx->ctx_scope;
7435 
7436     // Error if not in a :try scope
7437     if (scope == NULL || scope->se_type != TRY_SCOPE)
7438     {
7439 	emsg(_(e_catch));
7440 	return NULL;
7441     }
7442 
7443     if (scope->se_u.se_try.ts_caught_all)
7444     {
7445 	emsg(_(e_catch_unreachable_after_catch_all));
7446 	return NULL;
7447     }
7448 
7449     if (cctx->ctx_skip != SKIP_YES)
7450     {
7451 #ifdef FEAT_PROFILE
7452 	// the profile-start should be after the jump
7453 	if (cctx->ctx_profiling && ((isn_T *)instr->ga_data)[instr->ga_len - 1]
7454 						   .isn_type == ISN_PROF_START)
7455 	    --instr->ga_len;
7456 #endif
7457 	// Jump from end of previous block to :finally or :endtry
7458 	if (compile_jump_to_end(&scope->se_u.se_try.ts_end_label,
7459 						    JUMP_ALWAYS, cctx) == FAIL)
7460 	    return NULL;
7461 
7462 	// End :try or :catch scope: set value in ISN_TRY instruction
7463 	isn = ((isn_T *)instr->ga_data) + scope->se_u.se_try.ts_try_label;
7464 	if (isn->isn_arg.try.try_catch == 0)
7465 	    isn->isn_arg.try.try_catch = instr->ga_len;
7466 	if (scope->se_u.se_try.ts_catch_label != 0)
7467 	{
7468 	    // Previous catch without match jumps here
7469 	    isn = ((isn_T *)instr->ga_data) + scope->se_u.se_try.ts_catch_label;
7470 	    isn->isn_arg.jump.jump_where = instr->ga_len;
7471 	}
7472 #ifdef FEAT_PROFILE
7473 	if (cctx->ctx_profiling)
7474 	{
7475 	    // a "throw" that jumps here needs to be counted
7476 	    generate_instr(cctx, ISN_PROF_END);
7477 	    // the "catch" is also counted
7478 	    generate_instr(cctx, ISN_PROF_START);
7479 	}
7480 #endif
7481     }
7482 
7483     p = skipwhite(arg);
7484     if (ends_excmd2(arg, p))
7485     {
7486 	scope->se_u.se_try.ts_caught_all = TRUE;
7487 	scope->se_u.se_try.ts_catch_label = 0;
7488     }
7489     else
7490     {
7491 	char_u *end;
7492 	char_u *pat;
7493 	char_u *tofree = NULL;
7494 	int	dropped = 0;
7495 	int	len;
7496 
7497 	// Push v:exception, push {expr} and MATCH
7498 	generate_instr_type(cctx, ISN_PUSHEXC, &t_string);
7499 
7500 	end = skip_regexp_ex(p + 1, *p, TRUE, &tofree, &dropped, NULL);
7501 	if (*end != *p)
7502 	{
7503 	    semsg(_(e_separator_mismatch_str), p);
7504 	    vim_free(tofree);
7505 	    return FAIL;
7506 	}
7507 	if (tofree == NULL)
7508 	    len = (int)(end - (p + 1));
7509 	else
7510 	    len = (int)(end - tofree);
7511 	pat = vim_strnsave(tofree == NULL ? p + 1 : tofree, len);
7512 	vim_free(tofree);
7513 	p += len + 2 + dropped;
7514 	if (pat == NULL)
7515 	    return FAIL;
7516 	if (generate_PUSHS(cctx, pat) == FAIL)
7517 	    return FAIL;
7518 
7519 	if (generate_COMPARE(cctx, EXPR_MATCH, FALSE) == FAIL)
7520 	    return NULL;
7521 
7522 	scope->se_u.se_try.ts_catch_label = instr->ga_len;
7523 	if (generate_JUMP(cctx, JUMP_IF_FALSE, 0) == FAIL)
7524 	    return NULL;
7525     }
7526 
7527     if (cctx->ctx_skip != SKIP_YES && generate_instr(cctx, ISN_CATCH) == NULL)
7528 	return NULL;
7529 
7530     if (new_scope(cctx, BLOCK_SCOPE) == NULL)
7531 	return NULL;
7532     return p;
7533 }
7534 
7535     static char_u *
7536 compile_finally(char_u *arg, cctx_T *cctx)
7537 {
7538     scope_T	*scope = cctx->ctx_scope;
7539     garray_T	*instr = &cctx->ctx_instr;
7540     isn_T	*isn;
7541     int		this_instr;
7542 
7543     // end block scope from :try or :catch
7544     if (scope != NULL && scope->se_type == BLOCK_SCOPE)
7545 	compile_endblock(cctx);
7546     scope = cctx->ctx_scope;
7547 
7548     // Error if not in a :try scope
7549     if (scope == NULL || scope->se_type != TRY_SCOPE)
7550     {
7551 	emsg(_(e_finally));
7552 	return NULL;
7553     }
7554 
7555     // End :catch or :finally scope: set value in ISN_TRY instruction
7556     isn = ((isn_T *)instr->ga_data) + scope->se_u.se_try.ts_try_label;
7557     if (isn->isn_arg.try.try_finally != 0)
7558     {
7559 	emsg(_(e_finally_dup));
7560 	return NULL;
7561     }
7562 
7563     this_instr = instr->ga_len;
7564 #ifdef FEAT_PROFILE
7565     if (cctx->ctx_profiling && ((isn_T *)instr->ga_data)[instr->ga_len - 1]
7566 						   .isn_type == ISN_PROF_START)
7567 	// jump to the profile start of the "finally"
7568 	--this_instr;
7569 #endif
7570 
7571     // Fill in the "end" label in jumps at the end of the blocks.
7572     compile_fill_jump_to_end(&scope->se_u.se_try.ts_end_label,
7573 							     this_instr, cctx);
7574 
7575     isn->isn_arg.try.try_finally = this_instr;
7576     if (scope->se_u.se_try.ts_catch_label != 0)
7577     {
7578 	// Previous catch without match jumps here
7579 	isn = ((isn_T *)instr->ga_data) + scope->se_u.se_try.ts_catch_label;
7580 	isn->isn_arg.jump.jump_where = this_instr;
7581 	scope->se_u.se_try.ts_catch_label = 0;
7582     }
7583 
7584     // TODO: set index in ts_finally_label jumps
7585 
7586     return arg;
7587 }
7588 
7589     static char_u *
7590 compile_endtry(char_u *arg, cctx_T *cctx)
7591 {
7592     scope_T	*scope = cctx->ctx_scope;
7593     garray_T	*instr = &cctx->ctx_instr;
7594     isn_T	*isn;
7595 
7596     // end block scope from :catch or :finally
7597     if (scope != NULL && scope->se_type == BLOCK_SCOPE)
7598 	compile_endblock(cctx);
7599     scope = cctx->ctx_scope;
7600 
7601     // Error if not in a :try scope
7602     if (scope == NULL || scope->se_type != TRY_SCOPE)
7603     {
7604 	if (scope == NULL)
7605 	    emsg(_(e_no_endtry));
7606 	else if (scope->se_type == WHILE_SCOPE)
7607 	    emsg(_(e_endwhile));
7608 	else if (scope->se_type == FOR_SCOPE)
7609 	    emsg(_(e_endfor));
7610 	else
7611 	    emsg(_(e_endif));
7612 	return NULL;
7613     }
7614 
7615     if (cctx->ctx_skip != SKIP_YES)
7616     {
7617 	isn = ((isn_T *)instr->ga_data) + scope->se_u.se_try.ts_try_label;
7618 	if (isn->isn_arg.try.try_catch == 0
7619 					  && isn->isn_arg.try.try_finally == 0)
7620 	{
7621 	    emsg(_(e_missing_catch_or_finally));
7622 	    return NULL;
7623 	}
7624 
7625 #ifdef FEAT_PROFILE
7626     if (cctx->ctx_profiling && ((isn_T *)instr->ga_data)[instr->ga_len - 1]
7627 						   .isn_type == ISN_PROF_START)
7628 	// move the profile start after "endtry" so that it's not counted when
7629 	// the exception is rethrown.
7630 	--instr->ga_len;
7631 #endif
7632 
7633 	// Fill in the "end" label in jumps at the end of the blocks, if not
7634 	// done by ":finally".
7635 	compile_fill_jump_to_end(&scope->se_u.se_try.ts_end_label,
7636 							  instr->ga_len, cctx);
7637 
7638 	// End :catch or :finally scope: set value in ISN_TRY instruction
7639 	if (isn->isn_arg.try.try_catch == 0)
7640 	    isn->isn_arg.try.try_catch = instr->ga_len;
7641 	if (isn->isn_arg.try.try_finally == 0)
7642 	    isn->isn_arg.try.try_finally = instr->ga_len;
7643 
7644 	if (scope->se_u.se_try.ts_catch_label != 0)
7645 	{
7646 	    // Last catch without match jumps here
7647 	    isn = ((isn_T *)instr->ga_data) + scope->se_u.se_try.ts_catch_label;
7648 	    isn->isn_arg.jump.jump_where = instr->ga_len;
7649 	}
7650     }
7651 
7652     compile_endblock(cctx);
7653 
7654     if (cctx->ctx_skip != SKIP_YES && generate_instr(cctx, ISN_ENDTRY) == NULL)
7655 	return NULL;
7656 #ifdef FEAT_PROFILE
7657 	if (cctx->ctx_profiling)
7658 	    generate_instr(cctx, ISN_PROF_START);
7659 #endif
7660     return arg;
7661 }
7662 
7663 /*
7664  * compile "throw {expr}"
7665  */
7666     static char_u *
7667 compile_throw(char_u *arg, cctx_T *cctx UNUSED)
7668 {
7669     char_u *p = skipwhite(arg);
7670 
7671     if (compile_expr0(&p, cctx) == FAIL)
7672 	return NULL;
7673     if (cctx->ctx_skip == SKIP_YES)
7674 	return p;
7675     if (may_generate_2STRING(-1, cctx) == FAIL)
7676 	return NULL;
7677     if (generate_instr_drop(cctx, ISN_THROW, 1) == NULL)
7678 	return NULL;
7679 
7680     return p;
7681 }
7682 
7683 /*
7684  * compile "echo expr"
7685  * compile "echomsg expr"
7686  * compile "echoerr expr"
7687  * compile "execute expr"
7688  */
7689     static char_u *
7690 compile_mult_expr(char_u *arg, int cmdidx, cctx_T *cctx)
7691 {
7692     char_u	*p = arg;
7693     char_u	*prev = arg;
7694     int		count = 0;
7695 
7696     for (;;)
7697     {
7698 	if (ends_excmd2(prev, p))
7699 	    break;
7700 	if (compile_expr0(&p, cctx) == FAIL)
7701 	    return NULL;
7702 	++count;
7703 	prev = p;
7704 	p = skipwhite(p);
7705     }
7706 
7707     if (count > 0)
7708     {
7709 	if (cmdidx == CMD_echo || cmdidx == CMD_echon)
7710 	    generate_ECHO(cctx, cmdidx == CMD_echo, count);
7711 	else if (cmdidx == CMD_execute)
7712 	    generate_MULT_EXPR(cctx, ISN_EXECUTE, count);
7713 	else if (cmdidx == CMD_echomsg)
7714 	    generate_MULT_EXPR(cctx, ISN_ECHOMSG, count);
7715 	else
7716 	    generate_MULT_EXPR(cctx, ISN_ECHOERR, count);
7717     }
7718     return p;
7719 }
7720 
7721 /*
7722  * If "eap" has a range that is not a constant generate an ISN_RANGE
7723  * instruction to compute it and return OK.
7724  * Otherwise return FAIL, the caller must deal with any range.
7725  */
7726     static int
7727 compile_variable_range(exarg_T *eap, cctx_T *cctx)
7728 {
7729     char_u *range_end = skip_range(eap->cmd, TRUE, NULL);
7730     char_u *p = skipdigits(eap->cmd);
7731 
7732     if (p == range_end)
7733 	return FAIL;
7734     return generate_RANGE(cctx, vim_strnsave(eap->cmd, range_end - eap->cmd));
7735 }
7736 
7737 /*
7738  * :put r
7739  * :put ={expr}
7740  */
7741     static char_u *
7742 compile_put(char_u *arg, exarg_T *eap, cctx_T *cctx)
7743 {
7744     char_u	*line = arg;
7745     linenr_T	lnum;
7746     char	*errormsg;
7747     int		above = eap->forceit;
7748 
7749     eap->regname = *line;
7750 
7751     if (eap->regname == '=')
7752     {
7753 	char_u *p = line + 1;
7754 
7755 	if (compile_expr0(&p, cctx) == FAIL)
7756 	    return NULL;
7757 	line = p;
7758     }
7759     else if (eap->regname != NUL)
7760 	++line;
7761 
7762     if (compile_variable_range(eap, cctx) == OK)
7763     {
7764 	lnum = above ? LNUM_VARIABLE_RANGE_ABOVE : LNUM_VARIABLE_RANGE;
7765     }
7766     else
7767     {
7768 	// Either no range or a number.
7769 	// "errormsg" will not be set because the range is ADDR_LINES.
7770 	if (parse_cmd_address(eap, &errormsg, FALSE) == FAIL)
7771 	    // cannot happen
7772 	    return NULL;
7773 	if (eap->addr_count == 0)
7774 	    lnum = -1;
7775 	else
7776 	    lnum = eap->line2;
7777 	if (above)
7778 	    --lnum;
7779     }
7780 
7781     generate_PUT(cctx, eap->regname, lnum);
7782     return line;
7783 }
7784 
7785 /*
7786  * A command that is not compiled, execute with legacy code.
7787  */
7788     static char_u *
7789 compile_exec(char_u *line, exarg_T *eap, cctx_T *cctx)
7790 {
7791     char_u  *p;
7792     int	    has_expr = FALSE;
7793     char_u  *nextcmd = (char_u *)"";
7794 
7795     if (cctx->ctx_skip == SKIP_YES)
7796 	goto theend;
7797 
7798     if (eap->cmdidx >= 0 && eap->cmdidx < CMD_SIZE)
7799     {
7800 	long	argt = eap->argt;
7801 	int	usefilter = FALSE;
7802 
7803 	has_expr = argt & (EX_XFILE | EX_EXPAND);
7804 
7805 	// If the command can be followed by a bar, find the bar and truncate
7806 	// it, so that the following command can be compiled.
7807 	// The '|' is overwritten with a NUL, it is put back below.
7808 	if ((eap->cmdidx == CMD_write || eap->cmdidx == CMD_read)
7809 							   && *eap->arg == '!')
7810 	    // :w !filter or :r !filter or :r! filter
7811 	    usefilter = TRUE;
7812 	if ((argt & EX_TRLBAR) && !usefilter)
7813 	{
7814 	    eap->argt = argt;
7815 	    separate_nextcmd(eap);
7816 	    if (eap->nextcmd != NULL)
7817 		nextcmd = eap->nextcmd;
7818 	}
7819 	else if (eap->cmdidx == CMD_wincmd)
7820 	{
7821 	    p = eap->arg;
7822 	    if (*p != NUL)
7823 		++p;
7824 	    if (*p == 'g' || *p == Ctrl_G)
7825 		++p;
7826 	    p = skipwhite(p);
7827 	    if (*p == '|')
7828 	    {
7829 		*p = NUL;
7830 		nextcmd = p + 1;
7831 	    }
7832 	}
7833     }
7834 
7835     if (eap->cmdidx == CMD_syntax && STRNCMP(eap->arg, "include ", 8) == 0)
7836     {
7837 	// expand filename in "syntax include [@group] filename"
7838 	has_expr = TRUE;
7839 	eap->arg = skipwhite(eap->arg + 7);
7840 	if (*eap->arg == '@')
7841 	    eap->arg = skiptowhite(eap->arg);
7842     }
7843 
7844     if ((eap->cmdidx == CMD_global || eap->cmdidx == CMD_vglobal)
7845 						       && STRLEN(eap->arg) > 4)
7846     {
7847 	int delim = *eap->arg;
7848 
7849 	p = skip_regexp_ex(eap->arg + 1, delim, TRUE, NULL, NULL, NULL);
7850 	if (*p == delim)
7851 	{
7852 	    eap->arg = p + 1;
7853 	    has_expr = TRUE;
7854 	}
7855     }
7856 
7857     if (eap->cmdidx == CMD_folddoopen || eap->cmdidx == CMD_folddoclosed)
7858     {
7859 	// TODO: should only expand when appropriate for the command
7860 	eap->arg = skiptowhite(eap->arg);
7861 	has_expr = TRUE;
7862     }
7863 
7864     if (has_expr && (p = (char_u *)strstr((char *)eap->arg, "`=")) != NULL)
7865     {
7866 	int	count = 0;
7867 	char_u	*start = skipwhite(line);
7868 
7869 	// :cmd xxx`=expr1`yyy`=expr2`zzz
7870 	// PUSHS ":cmd xxx"
7871 	// eval expr1
7872 	// PUSHS "yyy"
7873 	// eval expr2
7874 	// PUSHS "zzz"
7875 	// EXECCONCAT 5
7876 	for (;;)
7877 	{
7878 	    if (p > start)
7879 	    {
7880 		generate_PUSHS(cctx, vim_strnsave(start, p - start));
7881 		++count;
7882 	    }
7883 	    p += 2;
7884 	    if (compile_expr0(&p, cctx) == FAIL)
7885 		return NULL;
7886 	    may_generate_2STRING(-1, cctx);
7887 	    ++count;
7888 	    p = skipwhite(p);
7889 	    if (*p != '`')
7890 	    {
7891 		emsg(_(e_missing_backtick));
7892 		return NULL;
7893 	    }
7894 	    start = p + 1;
7895 
7896 	    p = (char_u *)strstr((char *)start, "`=");
7897 	    if (p == NULL)
7898 	    {
7899 		if (*skipwhite(start) != NUL)
7900 		{
7901 		    generate_PUSHS(cctx, vim_strsave(start));
7902 		    ++count;
7903 		}
7904 		break;
7905 	    }
7906 	}
7907 	generate_EXECCONCAT(cctx, count);
7908     }
7909     else
7910 	generate_EXEC(cctx, line);
7911 
7912 theend:
7913     if (*nextcmd != NUL)
7914     {
7915 	// the parser expects a pointer to the bar, put it back
7916 	--nextcmd;
7917 	*nextcmd = '|';
7918     }
7919 
7920     return nextcmd;
7921 }
7922 
7923 /*
7924  * Add a function to the list of :def functions.
7925  * This sets "ufunc->uf_dfunc_idx" but the function isn't compiled yet.
7926  */
7927     static int
7928 add_def_function(ufunc_T *ufunc)
7929 {
7930     dfunc_T *dfunc;
7931 
7932     if (def_functions.ga_len == 0)
7933     {
7934 	// The first position is not used, so that a zero uf_dfunc_idx means it
7935 	// wasn't set.
7936 	if (ga_grow(&def_functions, 1) == FAIL)
7937 	    return FAIL;
7938 	++def_functions.ga_len;
7939     }
7940 
7941     // Add the function to "def_functions".
7942     if (ga_grow(&def_functions, 1) == FAIL)
7943 	return FAIL;
7944     dfunc = ((dfunc_T *)def_functions.ga_data) + def_functions.ga_len;
7945     CLEAR_POINTER(dfunc);
7946     dfunc->df_idx = def_functions.ga_len;
7947     ufunc->uf_dfunc_idx = dfunc->df_idx;
7948     dfunc->df_ufunc = ufunc;
7949     dfunc->df_name = vim_strsave(ufunc->uf_name);
7950     ++dfunc->df_refcount;
7951     ++def_functions.ga_len;
7952     return OK;
7953 }
7954 
7955 /*
7956  * After ex_function() has collected all the function lines: parse and compile
7957  * the lines into instructions.
7958  * Adds the function to "def_functions".
7959  * When "check_return_type" is set then set ufunc->uf_ret_type to the type of
7960  * the return statement (used for lambda).  When uf_ret_type is already set
7961  * then check that it matches.
7962  * When "profiling" is true add ISN_PROF_START instructions.
7963  * "outer_cctx" is set for a nested function.
7964  * This can be used recursively through compile_lambda(), which may reallocate
7965  * "def_functions".
7966  * Returns OK or FAIL.
7967  */
7968     int
7969 compile_def_function(
7970 	ufunc_T	    *ufunc,
7971 	int	    check_return_type,
7972 	int	    profiling UNUSED,
7973 	cctx_T	    *outer_cctx)
7974 {
7975     char_u	*line = NULL;
7976     char_u	*p;
7977     char	*errormsg = NULL;	// error message
7978     cctx_T	cctx;
7979     garray_T	*instr;
7980     int		did_emsg_before = did_emsg;
7981     int		ret = FAIL;
7982     sctx_T	save_current_sctx = current_sctx;
7983     int		save_estack_compiling = estack_compiling;
7984     int		do_estack_push;
7985     int		new_def_function = FALSE;
7986 #ifdef FEAT_PROFILE
7987     int		prof_lnum = -1;
7988 #endif
7989 
7990     // When using a function that was compiled before: Free old instructions.
7991     // The index is reused.  Otherwise add a new entry in "def_functions".
7992     if (ufunc->uf_dfunc_idx > 0)
7993     {
7994 	dfunc_T *dfunc = ((dfunc_T *)def_functions.ga_data)
7995 							 + ufunc->uf_dfunc_idx;
7996 	delete_def_function_contents(dfunc, FALSE);
7997     }
7998     else
7999     {
8000 	if (add_def_function(ufunc) == FAIL)
8001 	    return FAIL;
8002 	new_def_function = TRUE;
8003     }
8004 
8005     ufunc->uf_def_status = UF_COMPILING;
8006 
8007     CLEAR_FIELD(cctx);
8008 
8009 #ifdef FEAT_PROFILE
8010     cctx.ctx_profiling = profiling;
8011 #endif
8012     cctx.ctx_ufunc = ufunc;
8013     cctx.ctx_lnum = -1;
8014     cctx.ctx_outer = outer_cctx;
8015     ga_init2(&cctx.ctx_locals, sizeof(lvar_T), 10);
8016     ga_init2(&cctx.ctx_type_stack, sizeof(type_T *), 50);
8017     ga_init2(&cctx.ctx_imports, sizeof(imported_T), 10);
8018     cctx.ctx_type_list = &ufunc->uf_type_list;
8019     ga_init2(&cctx.ctx_instr, sizeof(isn_T), 50);
8020     instr = &cctx.ctx_instr;
8021 
8022     // Set the context to the function, it may be compiled when called from
8023     // another script.  Set the script version to the most modern one.
8024     // The line number will be set in next_line_from_context().
8025     current_sctx = ufunc->uf_script_ctx;
8026     current_sctx.sc_version = SCRIPT_VERSION_VIM9;
8027 
8028     // Make sure error messages are OK.
8029     do_estack_push = !estack_top_is_ufunc(ufunc, 1);
8030     if (do_estack_push)
8031 	estack_push_ufunc(ufunc, 1);
8032     estack_compiling = TRUE;
8033 
8034     if (ufunc->uf_def_args.ga_len > 0)
8035     {
8036 	int	count = ufunc->uf_def_args.ga_len;
8037 	int	first_def_arg = ufunc->uf_args.ga_len - count;
8038 	int	i;
8039 	char_u	*arg;
8040 	int	off = STACK_FRAME_SIZE + (ufunc->uf_va_name != NULL ? 1 : 0);
8041 	int	did_set_arg_type = FALSE;
8042 
8043 	// Produce instructions for the default values of optional arguments.
8044 	// Store the instruction index in uf_def_arg_idx[] so that we know
8045 	// where to start when the function is called, depending on the number
8046 	// of arguments.
8047 	ufunc->uf_def_arg_idx = ALLOC_CLEAR_MULT(int, count + 1);
8048 	if (ufunc->uf_def_arg_idx == NULL)
8049 	    goto erret;
8050 	for (i = 0; i < count; ++i)
8051 	{
8052 	    garray_T	*stack = &cctx.ctx_type_stack;
8053 	    type_T	*val_type;
8054 	    int		arg_idx = first_def_arg + i;
8055 
8056 	    ufunc->uf_def_arg_idx[i] = instr->ga_len;
8057 	    arg = ((char_u **)(ufunc->uf_def_args.ga_data))[i];
8058 	    if (compile_expr0(&arg, &cctx) == FAIL)
8059 		goto erret;
8060 
8061 	    // If no type specified use the type of the default value.
8062 	    // Otherwise check that the default value type matches the
8063 	    // specified type.
8064 	    val_type = ((type_T **)stack->ga_data)[stack->ga_len - 1];
8065 	    if (ufunc->uf_arg_types[arg_idx] == &t_unknown)
8066 	    {
8067 		did_set_arg_type = TRUE;
8068 		ufunc->uf_arg_types[arg_idx] = val_type;
8069 	    }
8070 	    else if (check_type(ufunc->uf_arg_types[arg_idx], val_type,
8071 						    TRUE, arg_idx + 1) == FAIL)
8072 		goto erret;
8073 
8074 	    if (generate_STORE(&cctx, ISN_STORE, i - count - off, NULL) == FAIL)
8075 		goto erret;
8076 	}
8077 	ufunc->uf_def_arg_idx[count] = instr->ga_len;
8078 
8079 	if (did_set_arg_type)
8080 	    set_function_type(ufunc);
8081     }
8082 
8083     /*
8084      * Loop over all the lines of the function and generate instructions.
8085      */
8086     for (;;)
8087     {
8088 	exarg_T	    ea;
8089 	int	    starts_with_colon = FALSE;
8090 	char_u	    *cmd;
8091 	cmdmod_T    local_cmdmod;
8092 
8093 	// Bail out on the first error to avoid a flood of errors and report
8094 	// the right line number when inside try/catch.
8095 	if (did_emsg_before != did_emsg)
8096 	    goto erret;
8097 
8098 	if (line != NULL && *line == '|')
8099 	    // the line continues after a '|'
8100 	    ++line;
8101 	else if (line != NULL && *skipwhite(line) != NUL
8102 		&& !(*line == '#' && (line == cctx.ctx_line_start
8103 						    || VIM_ISWHITE(line[-1]))))
8104 	{
8105 	    semsg(_(e_trailing_arg), line);
8106 	    goto erret;
8107 	}
8108 	else
8109 	{
8110 	    line = next_line_from_context(&cctx, FALSE);
8111 	    if (cctx.ctx_lnum >= ufunc->uf_lines.ga_len)
8112 	    {
8113 		// beyond the last line
8114 #ifdef FEAT_PROFILE
8115 		if (cctx.ctx_skip != SKIP_YES)
8116 		    may_generate_prof_end(&cctx, prof_lnum);
8117 #endif
8118 		break;
8119 	    }
8120 	}
8121 
8122 	CLEAR_FIELD(ea);
8123 	ea.cmdlinep = &line;
8124 	ea.cmd = skipwhite(line);
8125 
8126 	if (*ea.cmd == '#')
8127 	{
8128 	    // "#" starts a comment
8129 	    line = (char_u *)"";
8130 	    continue;
8131 	}
8132 
8133 #ifdef FEAT_PROFILE
8134 	if (cctx.ctx_profiling && cctx.ctx_lnum != prof_lnum &&
8135 						     cctx.ctx_skip != SKIP_YES)
8136 	{
8137 	    may_generate_prof_end(&cctx, prof_lnum);
8138 
8139 	    prof_lnum = cctx.ctx_lnum;
8140 	    generate_instr(&cctx, ISN_PROF_START);
8141 	}
8142 #endif
8143 
8144 	// Some things can be recognized by the first character.
8145 	switch (*ea.cmd)
8146 	{
8147 	    case '}':
8148 		{
8149 		    // "}" ends a block scope
8150 		    scopetype_T stype = cctx.ctx_scope == NULL
8151 					  ? NO_SCOPE : cctx.ctx_scope->se_type;
8152 
8153 		    if (stype == BLOCK_SCOPE)
8154 		    {
8155 			compile_endblock(&cctx);
8156 			line = ea.cmd;
8157 		    }
8158 		    else
8159 		    {
8160 			emsg(_(e_using_rcurly_outside_if_block_scope));
8161 			goto erret;
8162 		    }
8163 		    if (line != NULL)
8164 			line = skipwhite(ea.cmd + 1);
8165 		    continue;
8166 		}
8167 
8168 	    case '{':
8169 		// "{" starts a block scope
8170 		// "{'a': 1}->func() is something else
8171 		if (ends_excmd(*skipwhite(ea.cmd + 1)))
8172 		{
8173 		    line = compile_block(ea.cmd, &cctx);
8174 		    continue;
8175 		}
8176 		break;
8177 	}
8178 
8179 	/*
8180 	 * COMMAND MODIFIERS
8181 	 */
8182 	cctx.ctx_has_cmdmod = FALSE;
8183 	if (parse_command_modifiers(&ea, &errormsg, &local_cmdmod, FALSE)
8184 								       == FAIL)
8185 	{
8186 	    if (errormsg != NULL)
8187 		goto erret;
8188 	    // empty line or comment
8189 	    line = (char_u *)"";
8190 	    continue;
8191 	}
8192 	generate_cmdmods(&cctx, &local_cmdmod);
8193 	undo_cmdmod(&local_cmdmod);
8194 
8195 	// Check if there was a colon after the last command modifier or before
8196 	// the current position.
8197 	for (p = ea.cmd; p >= line; --p)
8198 	{
8199 	    if (*p == ':')
8200 		starts_with_colon = TRUE;
8201 	    if (p < ea.cmd && !VIM_ISWHITE(*p))
8202 		break;
8203 	}
8204 
8205 	// Skip ":call" to get to the function name.
8206 	p = ea.cmd;
8207 	if (checkforcmd(&ea.cmd, "call", 3))
8208 	{
8209 	    if (*ea.cmd == '(')
8210 		// not for "call()"
8211 		ea.cmd = p;
8212 	    else
8213 		ea.cmd = skipwhite(ea.cmd);
8214 	}
8215 
8216 	if (!starts_with_colon)
8217 	{
8218 	    int	    assign;
8219 
8220 	    // Check for assignment after command modifiers.
8221 	    assign = may_compile_assignment(&ea, &line, &cctx);
8222 	    if (assign == OK)
8223 		goto nextline;
8224 	    if (assign == FAIL)
8225 		goto erret;
8226 	}
8227 
8228 	/*
8229 	 * COMMAND after range
8230 	 * 'text'->func() should not be confused with 'a mark
8231 	 */
8232 	cmd = ea.cmd;
8233 	if (*cmd != '\'' || starts_with_colon)
8234 	{
8235 	    ea.cmd = skip_range(ea.cmd, TRUE, NULL);
8236 	    if (ea.cmd > cmd)
8237 	    {
8238 		if (!starts_with_colon)
8239 		{
8240 		    semsg(_(e_colon_required_before_range_str), cmd);
8241 		    goto erret;
8242 		}
8243 		if (ends_excmd2(line, ea.cmd))
8244 		{
8245 		    // A range without a command: jump to the line.
8246 		    // TODO: compile to a more efficient command, possibly
8247 		    // calling parse_cmd_address().
8248 		    ea.cmdidx = CMD_SIZE;
8249 		    line = compile_exec(line, &ea, &cctx);
8250 		    goto nextline;
8251 		}
8252 	    }
8253 	}
8254 	p = find_ex_command(&ea, NULL, starts_with_colon ? NULL
8255 		   : (int (*)(char_u *, size_t, void *, cctx_T *))lookup_local,
8256 									&cctx);
8257 
8258 	if (p == NULL)
8259 	{
8260 	    if (cctx.ctx_skip != SKIP_YES)
8261 		emsg(_(e_ambiguous_use_of_user_defined_command));
8262 	    goto erret;
8263 	}
8264 
8265 	if (p == ea.cmd && ea.cmdidx != CMD_SIZE)
8266 	{
8267 	    if (cctx.ctx_skip == SKIP_YES)
8268 	    {
8269 		line += STRLEN(line);
8270 		goto nextline;
8271 	    }
8272 
8273 	    // Expression or function call.
8274 	    if (ea.cmdidx != CMD_eval)
8275 	    {
8276 		// CMD_var cannot happen, compile_assignment() above would be
8277 		// used.  Most likely an assignment to a non-existing variable.
8278 		semsg(_(e_command_not_recognized_str), ea.cmd);
8279 		goto erret;
8280 	    }
8281 	}
8282 
8283 	if (cctx.ctx_had_return
8284 		&& ea.cmdidx != CMD_elseif
8285 		&& ea.cmdidx != CMD_else
8286 		&& ea.cmdidx != CMD_endif
8287 		&& ea.cmdidx != CMD_endfor
8288 		&& ea.cmdidx != CMD_endwhile
8289 		&& ea.cmdidx != CMD_catch
8290 		&& ea.cmdidx != CMD_finally
8291 		&& ea.cmdidx != CMD_endtry)
8292 	{
8293 	    emsg(_(e_unreachable_code_after_return));
8294 	    goto erret;
8295 	}
8296 
8297 	p = skipwhite(p);
8298 	if (ea.cmdidx != CMD_SIZE
8299 			    && ea.cmdidx != CMD_write && ea.cmdidx != CMD_read)
8300 	{
8301 	    if (ea.cmdidx >= 0)
8302 		ea.argt = excmd_get_argt(ea.cmdidx);
8303 	    if ((ea.argt & EX_BANG) && *p == '!')
8304 	    {
8305 		ea.forceit = TRUE;
8306 		p = skipwhite(p + 1);
8307 	    }
8308 	}
8309 
8310 	switch (ea.cmdidx)
8311 	{
8312 	    case CMD_def:
8313 		    ea.arg = p;
8314 		    line = compile_nested_function(&ea, &cctx);
8315 		    break;
8316 
8317 	    case CMD_function:
8318 		    // TODO: should we allow this, e.g. to declare a global
8319 		    // function?
8320 		    emsg(_(e_cannot_use_function_inside_def));
8321 		    goto erret;
8322 
8323 	    case CMD_return:
8324 		    line = compile_return(p, check_return_type, &cctx);
8325 		    cctx.ctx_had_return = TRUE;
8326 		    break;
8327 
8328 	    case CMD_let:
8329 		    emsg(_(e_cannot_use_let_in_vim9_script));
8330 		    break;
8331 	    case CMD_var:
8332 	    case CMD_final:
8333 	    case CMD_const:
8334 		    line = compile_assignment(p, &ea, ea.cmdidx, &cctx);
8335 		    if (line == p)
8336 			line = NULL;
8337 		    break;
8338 
8339 	    case CMD_unlet:
8340 	    case CMD_unlockvar:
8341 	    case CMD_lockvar:
8342 		    line = compile_unletlock(p, &ea, &cctx);
8343 		    break;
8344 
8345 	    case CMD_import:
8346 		    line = compile_import(p, &cctx);
8347 		    break;
8348 
8349 	    case CMD_if:
8350 		    line = compile_if(p, &cctx);
8351 		    break;
8352 	    case CMD_elseif:
8353 		    line = compile_elseif(p, &cctx);
8354 		    cctx.ctx_had_return = FALSE;
8355 		    break;
8356 	    case CMD_else:
8357 		    line = compile_else(p, &cctx);
8358 		    cctx.ctx_had_return = FALSE;
8359 		    break;
8360 	    case CMD_endif:
8361 		    line = compile_endif(p, &cctx);
8362 		    break;
8363 
8364 	    case CMD_while:
8365 		    line = compile_while(p, &cctx);
8366 		    break;
8367 	    case CMD_endwhile:
8368 		    line = compile_endwhile(p, &cctx);
8369 		    cctx.ctx_had_return = FALSE;
8370 		    break;
8371 
8372 	    case CMD_for:
8373 		    line = compile_for(p, &cctx);
8374 		    break;
8375 	    case CMD_endfor:
8376 		    line = compile_endfor(p, &cctx);
8377 		    cctx.ctx_had_return = FALSE;
8378 		    break;
8379 	    case CMD_continue:
8380 		    line = compile_continue(p, &cctx);
8381 		    break;
8382 	    case CMD_break:
8383 		    line = compile_break(p, &cctx);
8384 		    break;
8385 
8386 	    case CMD_try:
8387 		    line = compile_try(p, &cctx);
8388 		    break;
8389 	    case CMD_catch:
8390 		    line = compile_catch(p, &cctx);
8391 		    cctx.ctx_had_return = FALSE;
8392 		    break;
8393 	    case CMD_finally:
8394 		    line = compile_finally(p, &cctx);
8395 		    cctx.ctx_had_return = FALSE;
8396 		    break;
8397 	    case CMD_endtry:
8398 		    line = compile_endtry(p, &cctx);
8399 		    cctx.ctx_had_return = FALSE;
8400 		    break;
8401 	    case CMD_throw:
8402 		    line = compile_throw(p, &cctx);
8403 		    break;
8404 
8405 	    case CMD_eval:
8406 		    if (compile_expr0(&p, &cctx) == FAIL)
8407 			goto erret;
8408 
8409 		    // drop the result
8410 		    generate_instr_drop(&cctx, ISN_DROP, 1);
8411 
8412 		    line = skipwhite(p);
8413 		    break;
8414 
8415 	    case CMD_echo:
8416 	    case CMD_echon:
8417 	    case CMD_execute:
8418 	    case CMD_echomsg:
8419 	    case CMD_echoerr:
8420 		    line = compile_mult_expr(p, ea.cmdidx, &cctx);
8421 		    break;
8422 
8423 	    case CMD_put:
8424 		    ea.cmd = cmd;
8425 		    line = compile_put(p, &ea, &cctx);
8426 		    break;
8427 
8428 	    // TODO: any other commands with an expression argument?
8429 
8430 	    case CMD_append:
8431 	    case CMD_change:
8432 	    case CMD_insert:
8433 	    case CMD_t:
8434 	    case CMD_xit:
8435 		    not_in_vim9(&ea);
8436 		    goto erret;
8437 
8438 	    case CMD_SIZE:
8439 		    if (cctx.ctx_skip != SKIP_YES)
8440 		    {
8441 			semsg(_(e_invalid_command_str), ea.cmd);
8442 			goto erret;
8443 		    }
8444 		    // We don't check for a next command here.
8445 		    line = (char_u *)"";
8446 		    break;
8447 
8448 	    default:
8449 		    if (cctx.ctx_skip == SKIP_YES)
8450 		    {
8451 			// We don't check for a next command here.
8452 			line = (char_u *)"";
8453 		    }
8454 		    else
8455 		    {
8456 			// Not recognized, execute with do_cmdline_cmd().
8457 			ea.arg = p;
8458 			line = compile_exec(line, &ea, &cctx);
8459 		    }
8460 		    break;
8461 	}
8462 nextline:
8463 	if (line == NULL)
8464 	    goto erret;
8465 	line = skipwhite(line);
8466 
8467 	// Undo any command modifiers.
8468 	generate_undo_cmdmods(&cctx);
8469 
8470 	if (cctx.ctx_type_stack.ga_len < 0)
8471 	{
8472 	    iemsg("Type stack underflow");
8473 	    goto erret;
8474 	}
8475     }
8476 
8477     if (cctx.ctx_scope != NULL)
8478     {
8479 	if (cctx.ctx_scope->se_type == IF_SCOPE)
8480 	    emsg(_(e_endif));
8481 	else if (cctx.ctx_scope->se_type == WHILE_SCOPE)
8482 	    emsg(_(e_endwhile));
8483 	else if (cctx.ctx_scope->se_type == FOR_SCOPE)
8484 	    emsg(_(e_endfor));
8485 	else
8486 	    emsg(_(e_missing_rcurly));
8487 	goto erret;
8488     }
8489 
8490     if (!cctx.ctx_had_return)
8491     {
8492 	if (ufunc->uf_ret_type->tt_type != VAR_VOID)
8493 	{
8494 	    emsg(_(e_missing_return_statement));
8495 	    goto erret;
8496 	}
8497 
8498 	// Return zero if there is no return at the end.
8499 	generate_instr(&cctx, ISN_RETURN_ZERO);
8500     }
8501 
8502     {
8503 	dfunc_T	*dfunc = ((dfunc_T *)def_functions.ga_data)
8504 							 + ufunc->uf_dfunc_idx;
8505 	dfunc->df_deleted = FALSE;
8506 	dfunc->df_script_seq = current_sctx.sc_seq;
8507 #ifdef FEAT_PROFILE
8508 	if (cctx.ctx_profiling)
8509 	{
8510 	    dfunc->df_instr_prof = instr->ga_data;
8511 	    dfunc->df_instr_prof_count = instr->ga_len;
8512 	}
8513 	else
8514 #endif
8515 	{
8516 	    dfunc->df_instr = instr->ga_data;
8517 	    dfunc->df_instr_count = instr->ga_len;
8518 	}
8519 	dfunc->df_varcount = cctx.ctx_locals_count;
8520 	dfunc->df_has_closure = cctx.ctx_has_closure;
8521 	if (cctx.ctx_outer_used)
8522 	    ufunc->uf_flags |= FC_CLOSURE;
8523 	ufunc->uf_def_status = UF_COMPILED;
8524     }
8525 
8526     ret = OK;
8527 
8528 erret:
8529     if (ret == FAIL)
8530     {
8531 	int idx;
8532 	dfunc_T	*dfunc = ((dfunc_T *)def_functions.ga_data)
8533 							 + ufunc->uf_dfunc_idx;
8534 
8535 	for (idx = 0; idx < instr->ga_len; ++idx)
8536 	    delete_instr(((isn_T *)instr->ga_data) + idx);
8537 	ga_clear(instr);
8538 	VIM_CLEAR(dfunc->df_name);
8539 
8540 	// If using the last entry in the table and it was added above, we
8541 	// might as well remove it.
8542 	if (!dfunc->df_deleted && new_def_function
8543 			    && ufunc->uf_dfunc_idx == def_functions.ga_len - 1)
8544 	{
8545 	    --def_functions.ga_len;
8546 	    ufunc->uf_dfunc_idx = 0;
8547 	}
8548 	ufunc->uf_def_status = UF_NOT_COMPILED;
8549 
8550 	while (cctx.ctx_scope != NULL)
8551 	    drop_scope(&cctx);
8552 
8553 	// Don't execute this function body.
8554 	ga_clear_strings(&ufunc->uf_lines);
8555 
8556 	if (errormsg != NULL)
8557 	    emsg(errormsg);
8558 	else if (did_emsg == did_emsg_before)
8559 	    emsg(_(e_compiling_def_function_failed));
8560     }
8561 
8562     current_sctx = save_current_sctx;
8563     estack_compiling = save_estack_compiling;
8564     if (do_estack_push)
8565 	estack_pop();
8566 
8567     free_imported(&cctx);
8568     free_locals(&cctx);
8569     ga_clear(&cctx.ctx_type_stack);
8570     return ret;
8571 }
8572 
8573     void
8574 set_function_type(ufunc_T *ufunc)
8575 {
8576     int varargs = ufunc->uf_va_name != NULL;
8577     int argcount = ufunc->uf_args.ga_len;
8578 
8579     // Create a type for the function, with the return type and any
8580     // argument types.
8581     // A vararg is included in uf_args.ga_len but not in uf_arg_types.
8582     // The type is included in "tt_args".
8583     if (argcount > 0 || varargs)
8584     {
8585 	ufunc->uf_func_type = alloc_func_type(ufunc->uf_ret_type,
8586 					   argcount, &ufunc->uf_type_list);
8587 	// Add argument types to the function type.
8588 	if (func_type_add_arg_types(ufunc->uf_func_type,
8589 				    argcount + varargs,
8590 				    &ufunc->uf_type_list) == FAIL)
8591 	    return;
8592 	ufunc->uf_func_type->tt_argcount = argcount + varargs;
8593 	ufunc->uf_func_type->tt_min_argcount =
8594 				      argcount - ufunc->uf_def_args.ga_len;
8595 	if (ufunc->uf_arg_types == NULL)
8596 	{
8597 	    int i;
8598 
8599 	    // lambda does not have argument types.
8600 	    for (i = 0; i < argcount; ++i)
8601 		ufunc->uf_func_type->tt_args[i] = &t_any;
8602 	}
8603 	else
8604 	    mch_memmove(ufunc->uf_func_type->tt_args,
8605 			 ufunc->uf_arg_types, sizeof(type_T *) * argcount);
8606 	if (varargs)
8607 	{
8608 	    ufunc->uf_func_type->tt_args[argcount] =
8609 		    ufunc->uf_va_type == NULL ? &t_any : ufunc->uf_va_type;
8610 	    ufunc->uf_func_type->tt_flags = TTFLAG_VARARGS;
8611 	}
8612     }
8613     else
8614 	// No arguments, can use a predefined type.
8615 	ufunc->uf_func_type = get_func_type(ufunc->uf_ret_type,
8616 					   argcount, &ufunc->uf_type_list);
8617 }
8618 
8619 
8620 /*
8621  * Delete an instruction, free what it contains.
8622  */
8623     void
8624 delete_instr(isn_T *isn)
8625 {
8626     switch (isn->isn_type)
8627     {
8628 	case ISN_DEF:
8629 	case ISN_EXEC:
8630 	case ISN_LOADAUTO:
8631 	case ISN_LOADB:
8632 	case ISN_LOADENV:
8633 	case ISN_LOADG:
8634 	case ISN_LOADOPT:
8635 	case ISN_LOADT:
8636 	case ISN_LOADW:
8637 	case ISN_PUSHEXC:
8638 	case ISN_PUSHFUNC:
8639 	case ISN_PUSHS:
8640 	case ISN_RANGE:
8641 	case ISN_STOREAUTO:
8642 	case ISN_STOREB:
8643 	case ISN_STOREENV:
8644 	case ISN_STOREG:
8645 	case ISN_STORET:
8646 	case ISN_STOREW:
8647 	case ISN_STRINGMEMBER:
8648 	    vim_free(isn->isn_arg.string);
8649 	    break;
8650 
8651 	case ISN_LOADS:
8652 	case ISN_STORES:
8653 	    vim_free(isn->isn_arg.loadstore.ls_name);
8654 	    break;
8655 
8656 	case ISN_UNLET:
8657 	case ISN_UNLETENV:
8658 	    vim_free(isn->isn_arg.unlet.ul_name);
8659 	    break;
8660 
8661 	case ISN_STOREOPT:
8662 	    vim_free(isn->isn_arg.storeopt.so_name);
8663 	    break;
8664 
8665 	case ISN_PUSHBLOB:   // push blob isn_arg.blob
8666 	    blob_unref(isn->isn_arg.blob);
8667 	    break;
8668 
8669 	case ISN_PUSHJOB:
8670 #ifdef FEAT_JOB_CHANNEL
8671 	    job_unref(isn->isn_arg.job);
8672 #endif
8673 	    break;
8674 
8675 	case ISN_PUSHCHANNEL:
8676 #ifdef FEAT_JOB_CHANNEL
8677 	    channel_unref(isn->isn_arg.channel);
8678 #endif
8679 	    break;
8680 
8681 	case ISN_UCALL:
8682 	    vim_free(isn->isn_arg.ufunc.cuf_name);
8683 	    break;
8684 
8685 	case ISN_FUNCREF:
8686 	    {
8687 		dfunc_T *dfunc = ((dfunc_T *)def_functions.ga_data)
8688 					       + isn->isn_arg.funcref.fr_func;
8689 		ufunc_T *ufunc = dfunc->df_ufunc;
8690 
8691 		if (ufunc != NULL && func_name_refcount(ufunc->uf_name))
8692 		    func_ptr_unref(ufunc);
8693 	    }
8694 	    break;
8695 
8696 	case ISN_DCALL:
8697 	    {
8698 		dfunc_T *dfunc = ((dfunc_T *)def_functions.ga_data)
8699 					       + isn->isn_arg.dfunc.cdf_idx;
8700 
8701 		if (dfunc->df_ufunc != NULL
8702 			       && func_name_refcount(dfunc->df_ufunc->uf_name))
8703 		    func_ptr_unref(dfunc->df_ufunc);
8704 	    }
8705 	    break;
8706 
8707 	case ISN_NEWFUNC:
8708 	    {
8709 		char_u  *lambda = isn->isn_arg.newfunc.nf_lambda;
8710 		ufunc_T *ufunc = find_func_even_dead(lambda, TRUE, NULL);
8711 
8712 		if (ufunc != NULL)
8713 		{
8714 		    unlink_def_function(ufunc);
8715 		    func_ptr_unref(ufunc);
8716 		}
8717 
8718 		vim_free(lambda);
8719 		vim_free(isn->isn_arg.newfunc.nf_global);
8720 	    }
8721 	    break;
8722 
8723 	case ISN_CHECKTYPE:
8724 	case ISN_SETTYPE:
8725 	    free_type(isn->isn_arg.type.ct_type);
8726 	    break;
8727 
8728 	case ISN_CMDMOD:
8729 	    vim_regfree(isn->isn_arg.cmdmod.cf_cmdmod
8730 					       ->cmod_filter_regmatch.regprog);
8731 	    vim_free(isn->isn_arg.cmdmod.cf_cmdmod);
8732 	    break;
8733 
8734 	case ISN_LOADSCRIPT:
8735 	case ISN_STORESCRIPT:
8736 	    vim_free(isn->isn_arg.script.scriptref);
8737 	    break;
8738 
8739 	case ISN_2BOOL:
8740 	case ISN_2STRING:
8741 	case ISN_2STRING_ANY:
8742 	case ISN_ADDBLOB:
8743 	case ISN_ADDLIST:
8744 	case ISN_ANYINDEX:
8745 	case ISN_ANYSLICE:
8746 	case ISN_BCALL:
8747 	case ISN_BLOBAPPEND:
8748 	case ISN_CATCH:
8749 	case ISN_CHECKLEN:
8750 	case ISN_CHECKNR:
8751 	case ISN_CMDMOD_REV:
8752 	case ISN_COMPAREANY:
8753 	case ISN_COMPAREBLOB:
8754 	case ISN_COMPAREBOOL:
8755 	case ISN_COMPAREDICT:
8756 	case ISN_COMPAREFLOAT:
8757 	case ISN_COMPAREFUNC:
8758 	case ISN_COMPARELIST:
8759 	case ISN_COMPARENR:
8760 	case ISN_COMPARESPECIAL:
8761 	case ISN_COMPARESTRING:
8762 	case ISN_CONCAT:
8763 	case ISN_COND2BOOL:
8764 	case ISN_DROP:
8765 	case ISN_ECHO:
8766 	case ISN_ECHOERR:
8767 	case ISN_ECHOMSG:
8768 	case ISN_ENDTRY:
8769 	case ISN_EXECCONCAT:
8770 	case ISN_EXECUTE:
8771 	case ISN_FOR:
8772 	case ISN_GETITEM:
8773 	case ISN_JUMP:
8774 	case ISN_LISTAPPEND:
8775 	case ISN_LISTINDEX:
8776 	case ISN_LISTSLICE:
8777 	case ISN_LOAD:
8778 	case ISN_LOADBDICT:
8779 	case ISN_LOADGDICT:
8780 	case ISN_LOADOUTER:
8781 	case ISN_LOADREG:
8782 	case ISN_LOADTDICT:
8783 	case ISN_LOADV:
8784 	case ISN_LOADWDICT:
8785 	case ISN_LOCKCONST:
8786 	case ISN_MEMBER:
8787 	case ISN_NEGATENR:
8788 	case ISN_NEWDICT:
8789 	case ISN_NEWLIST:
8790 	case ISN_OPANY:
8791 	case ISN_OPFLOAT:
8792 	case ISN_OPNR:
8793 	case ISN_PCALL:
8794 	case ISN_PCALL_END:
8795 	case ISN_PROF_END:
8796 	case ISN_PROF_START:
8797 	case ISN_PUSHBOOL:
8798 	case ISN_PUSHF:
8799 	case ISN_PUSHNR:
8800 	case ISN_PUSHSPEC:
8801 	case ISN_PUT:
8802 	case ISN_RETURN:
8803 	case ISN_RETURN_ZERO:
8804 	case ISN_SHUFFLE:
8805 	case ISN_SLICE:
8806 	case ISN_STORE:
8807 	case ISN_STOREINDEX:
8808 	case ISN_STORENR:
8809 	case ISN_STOREOUTER:
8810 	case ISN_STOREREG:
8811 	case ISN_STOREV:
8812 	case ISN_STRINDEX:
8813 	case ISN_STRSLICE:
8814 	case ISN_THROW:
8815 	case ISN_TRY:
8816 	case ISN_UNLETINDEX:
8817 	case ISN_UNPACK:
8818 	    // nothing allocated
8819 	    break;
8820     }
8821 }
8822 
8823 /*
8824  * Free all instructions for "dfunc" except df_name.
8825  */
8826     static void
8827 delete_def_function_contents(dfunc_T *dfunc, int mark_deleted)
8828 {
8829     int idx;
8830 
8831     ga_clear(&dfunc->df_def_args_isn);
8832 
8833     if (dfunc->df_instr != NULL)
8834     {
8835 	for (idx = 0; idx < dfunc->df_instr_count; ++idx)
8836 	    delete_instr(dfunc->df_instr + idx);
8837 	VIM_CLEAR(dfunc->df_instr);
8838 	dfunc->df_instr = NULL;
8839     }
8840 #ifdef FEAT_PROFILE
8841     if (dfunc->df_instr_prof != NULL)
8842     {
8843 	for (idx = 0; idx < dfunc->df_instr_prof_count; ++idx)
8844 	    delete_instr(dfunc->df_instr_prof + idx);
8845 	VIM_CLEAR(dfunc->df_instr_prof);
8846 	dfunc->df_instr_prof = NULL;
8847     }
8848 #endif
8849 
8850     if (mark_deleted)
8851 	dfunc->df_deleted = TRUE;
8852     if (dfunc->df_ufunc != NULL)
8853 	dfunc->df_ufunc->uf_def_status = UF_NOT_COMPILED;
8854 }
8855 
8856 /*
8857  * When a user function is deleted, clear the contents of any associated def
8858  * function, unless another user function still uses it.
8859  * The position in def_functions can be re-used.
8860  */
8861     void
8862 unlink_def_function(ufunc_T *ufunc)
8863 {
8864     if (ufunc->uf_dfunc_idx > 0)
8865     {
8866 	dfunc_T *dfunc = ((dfunc_T *)def_functions.ga_data)
8867 							 + ufunc->uf_dfunc_idx;
8868 
8869 	if (--dfunc->df_refcount <= 0)
8870 	    delete_def_function_contents(dfunc, TRUE);
8871 	ufunc->uf_def_status = UF_NOT_COMPILED;
8872 	ufunc->uf_dfunc_idx = 0;
8873 	if (dfunc->df_ufunc == ufunc)
8874 	    dfunc->df_ufunc = NULL;
8875     }
8876 }
8877 
8878 /*
8879  * Used when a user function refers to an existing dfunc.
8880  */
8881     void
8882 link_def_function(ufunc_T *ufunc)
8883 {
8884     if (ufunc->uf_dfunc_idx > 0)
8885     {
8886 	dfunc_T *dfunc = ((dfunc_T *)def_functions.ga_data)
8887 							 + ufunc->uf_dfunc_idx;
8888 
8889 	++dfunc->df_refcount;
8890     }
8891 }
8892 
8893 #if defined(EXITFREE) || defined(PROTO)
8894 /*
8895  * Free all functions defined with ":def".
8896  */
8897     void
8898 free_def_functions(void)
8899 {
8900     int idx;
8901 
8902     for (idx = 0; idx < def_functions.ga_len; ++idx)
8903     {
8904 	dfunc_T *dfunc = ((dfunc_T *)def_functions.ga_data) + idx;
8905 
8906 	delete_def_function_contents(dfunc, TRUE);
8907 	vim_free(dfunc->df_name);
8908     }
8909 
8910     ga_clear(&def_functions);
8911 }
8912 #endif
8913 
8914 
8915 #endif // FEAT_EVAL
8916