xref: /vim-8.2.3635/src/vim9compile.c (revision 3fb377fa)
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 /*
27  * Chain of jump instructions where the end label needs to be set.
28  */
29 typedef struct endlabel_S endlabel_T;
30 struct endlabel_S {
31     endlabel_T	*el_next;	    // chain end_label locations
32     int		el_end_label;	    // instruction idx where to set end
33 };
34 
35 /*
36  * info specific for the scope of :if / elseif / else
37  */
38 typedef struct {
39     int		is_if_label;	    // instruction idx at IF or ELSEIF
40     endlabel_T	*is_end_label;	    // instructions to set end label
41 } ifscope_T;
42 
43 /*
44  * info specific for the scope of :while
45  */
46 typedef struct {
47     int		ws_top_label;	    // instruction idx at WHILE
48     endlabel_T	*ws_end_label;	    // instructions to set end
49 } whilescope_T;
50 
51 /*
52  * info specific for the scope of :for
53  */
54 typedef struct {
55     int		fs_top_label;	    // instruction idx at FOR
56     endlabel_T	*fs_end_label;	    // break instructions
57 } forscope_T;
58 
59 /*
60  * info specific for the scope of :try
61  */
62 typedef struct {
63     int		ts_try_label;	    // instruction idx at TRY
64     endlabel_T	*ts_end_label;	    // jump to :finally or :endtry
65     int		ts_catch_label;	    // instruction idx of last CATCH
66     int		ts_caught_all;	    // "catch" without argument encountered
67 } tryscope_T;
68 
69 typedef enum {
70     NO_SCOPE,
71     IF_SCOPE,
72     WHILE_SCOPE,
73     FOR_SCOPE,
74     TRY_SCOPE,
75     BLOCK_SCOPE
76 } scopetype_T;
77 
78 /*
79  * Info for one scope, pointed to by "ctx_scope".
80  */
81 typedef struct scope_S scope_T;
82 struct scope_S {
83     scope_T	*se_outer;	    // scope containing this one
84     scopetype_T se_type;
85     int		se_local_count;	    // ctx_locals.ga_len before scope
86     union {
87 	ifscope_T	se_if;
88 	whilescope_T	se_while;
89 	forscope_T	se_for;
90 	tryscope_T	se_try;
91     } se_u;
92 };
93 
94 /*
95  * Entry for "ctx_locals".  Used for arguments and local variables.
96  */
97 typedef struct {
98     char_u	*lv_name;
99     type_T	*lv_type;
100     int		lv_const;   // when TRUE cannot be assigned to
101     int		lv_arg;	    // when TRUE this is an argument
102 } lvar_T;
103 
104 /*
105  * Context for compiling lines of Vim script.
106  * Stores info about the local variables and condition stack.
107  */
108 struct cctx_S {
109     ufunc_T	*ctx_ufunc;	    // current function
110     int		ctx_lnum;	    // line number in current function
111     garray_T	ctx_instr;	    // generated instructions
112 
113     garray_T	ctx_locals;	    // currently visible local variables
114     int		ctx_max_local;	    // maximum number of locals at one time
115 
116     garray_T	ctx_imports;	    // imported items
117 
118     int		ctx_skip;	    // when TRUE skip commands, when FALSE skip
119 				    // commands after "else"
120     scope_T	*ctx_scope;	    // current scope, NULL at toplevel
121 
122     garray_T	ctx_type_stack;	    // type of each item on the stack
123     garray_T	*ctx_type_list;	    // space for adding types
124 };
125 
126 static char e_var_notfound[] = N_("E1001: variable not found: %s");
127 static char e_syntax_at[] = N_("E1002: Syntax error at %s");
128 
129 static int compile_expr1(char_u **arg,  cctx_T *cctx);
130 static int compile_expr2(char_u **arg,  cctx_T *cctx);
131 static int compile_expr3(char_u **arg,  cctx_T *cctx);
132 
133 /*
134  * Lookup variable "name" in the local scope and return the index.
135  */
136     static int
137 lookup_local(char_u *name, size_t len, cctx_T *cctx)
138 {
139     int	    idx;
140 
141     if (len <= 0)
142 	return -1;
143     for (idx = 0; idx < cctx->ctx_locals.ga_len; ++idx)
144     {
145 	lvar_T *lvar = ((lvar_T *)cctx->ctx_locals.ga_data) + idx;
146 
147 	if (STRNCMP(name, lvar->lv_name, len) == 0
148 					       && STRLEN(lvar->lv_name) == len)
149 	    return idx;
150     }
151     return -1;
152 }
153 
154 /*
155  * Lookup an argument in the current function.
156  * Returns the argument index or -1 if not found.
157  */
158     static int
159 lookup_arg(char_u *name, size_t len, cctx_T *cctx)
160 {
161     int	    idx;
162 
163     if (len <= 0)
164 	return -1;
165     for (idx = 0; idx < cctx->ctx_ufunc->uf_args.ga_len; ++idx)
166     {
167 	char_u *arg = FUNCARG(cctx->ctx_ufunc, idx);
168 
169 	if (STRNCMP(name, arg, len) == 0 && STRLEN(arg) == len)
170 	    return idx;
171     }
172     return -1;
173 }
174 
175 /*
176  * Lookup a vararg argument in the current function.
177  * Returns TRUE if there is a match.
178  */
179     static int
180 lookup_vararg(char_u *name, size_t len, cctx_T *cctx)
181 {
182     char_u  *va_name = cctx->ctx_ufunc->uf_va_name;
183 
184     return len > 0 && va_name != NULL
185 		 && STRNCMP(name, va_name, len) == 0 && STRLEN(va_name) == len;
186 }
187 
188 /*
189  * Lookup a variable in the current script.
190  * Returns OK or FAIL.
191  */
192     static int
193 lookup_script(char_u *name, size_t len)
194 {
195     int		    cc;
196     hashtab_T	    *ht = &SCRIPT_VARS(current_sctx.sc_sid);
197     dictitem_T	    *di;
198 
199     cc = name[len];
200     name[len] = NUL;
201     di = find_var_in_ht(ht, 0, name, TRUE);
202     name[len] = cc;
203     return di == NULL ? FAIL: OK;
204 }
205 
206     static type_T *
207 get_list_type(type_T *member_type, garray_T *type_list)
208 {
209     type_T *type;
210 
211     // recognize commonly used types
212     if (member_type->tt_type == VAR_UNKNOWN)
213 	return &t_list_any;
214     if (member_type->tt_type == VAR_NUMBER)
215 	return &t_list_number;
216     if (member_type->tt_type == VAR_STRING)
217 	return &t_list_string;
218 
219     // Not a common type, create a new entry.
220     if (ga_grow(type_list, 1) == FAIL)
221 	return FAIL;
222     type = ((type_T *)type_list->ga_data) + type_list->ga_len;
223     ++type_list->ga_len;
224     type->tt_type = VAR_LIST;
225     type->tt_member = member_type;
226     return type;
227 }
228 
229     static type_T *
230 get_dict_type(type_T *member_type, garray_T *type_list)
231 {
232     type_T *type;
233 
234     // recognize commonly used types
235     if (member_type->tt_type == VAR_UNKNOWN)
236 	return &t_dict_any;
237     if (member_type->tt_type == VAR_NUMBER)
238 	return &t_dict_number;
239     if (member_type->tt_type == VAR_STRING)
240 	return &t_dict_string;
241 
242     // Not a common type, create a new entry.
243     if (ga_grow(type_list, 1) == FAIL)
244 	return FAIL;
245     type = ((type_T *)type_list->ga_data) + type_list->ga_len;
246     ++type_list->ga_len;
247     type->tt_type = VAR_DICT;
248     type->tt_member = member_type;
249     return type;
250 }
251 
252 /////////////////////////////////////////////////////////////////////
253 // Following generate_ functions expect the caller to call ga_grow().
254 
255 /*
256  * Generate an instruction without arguments.
257  * Returns a pointer to the new instruction, NULL if failed.
258  */
259     static isn_T *
260 generate_instr(cctx_T *cctx, isntype_T isn_type)
261 {
262     garray_T	*instr = &cctx->ctx_instr;
263     isn_T	*isn;
264 
265     if (ga_grow(instr, 1) == FAIL)
266 	return NULL;
267     isn = ((isn_T *)instr->ga_data) + instr->ga_len;
268     isn->isn_type = isn_type;
269     isn->isn_lnum = cctx->ctx_lnum + 1;
270     ++instr->ga_len;
271 
272     return isn;
273 }
274 
275 /*
276  * Generate an instruction without arguments.
277  * "drop" will be removed from the stack.
278  * Returns a pointer to the new instruction, NULL if failed.
279  */
280     static isn_T *
281 generate_instr_drop(cctx_T *cctx, isntype_T isn_type, int drop)
282 {
283     garray_T	*stack = &cctx->ctx_type_stack;
284 
285     stack->ga_len -= drop;
286     return generate_instr(cctx, isn_type);
287 }
288 
289 /*
290  * Generate instruction "isn_type" and put "type" on the type stack.
291  */
292     static isn_T *
293 generate_instr_type(cctx_T *cctx, isntype_T isn_type, type_T *type)
294 {
295     isn_T	*isn;
296     garray_T	*stack = &cctx->ctx_type_stack;
297 
298     if ((isn = generate_instr(cctx, isn_type)) == NULL)
299 	return NULL;
300 
301     if (ga_grow(stack, 1) == FAIL)
302 	return NULL;
303     ((type_T **)stack->ga_data)[stack->ga_len] = type;
304     ++stack->ga_len;
305 
306     return isn;
307 }
308 
309 /*
310  * If type at "offset" isn't already VAR_STRING then generate ISN_2STRING.
311  */
312     static int
313 may_generate_2STRING(int offset, cctx_T *cctx)
314 {
315     isn_T	*isn;
316     garray_T	*stack = &cctx->ctx_type_stack;
317     type_T	**type = ((type_T **)stack->ga_data) + stack->ga_len + offset;
318 
319     if ((*type)->tt_type == VAR_STRING)
320 	return OK;
321     *type = &t_string;
322 
323     if ((isn = generate_instr(cctx, ISN_2STRING)) == NULL)
324 	return FAIL;
325     isn->isn_arg.number = offset;
326 
327     return OK;
328 }
329 
330     static int
331 check_number_or_float(vartype_T type1, vartype_T type2, char_u *op)
332 {
333     if (!((type1 == VAR_NUMBER || type1 == VAR_FLOAT || type1 == VAR_UNKNOWN)
334 	    && (type2 == VAR_NUMBER || type2 == VAR_FLOAT
335 						     || type2 == VAR_UNKNOWN)))
336     {
337 	if (*op == '+')
338 	    emsg(_("E1035: wrong argument type for +"));
339 	else
340 	    semsg(_("E1036: %c requires number or float arguments"), *op);
341 	return FAIL;
342     }
343     return OK;
344 }
345 
346 /*
347  * Generate an instruction with two arguments.  The instruction depends on the
348  * type of the arguments.
349  */
350     static int
351 generate_two_op(cctx_T *cctx, char_u *op)
352 {
353     garray_T	*stack = &cctx->ctx_type_stack;
354     type_T	*type1;
355     type_T	*type2;
356     vartype_T	vartype;
357     isn_T	*isn;
358 
359     // Get the known type of the two items on the stack.  If they are matching
360     // use a type-specific instruction. Otherwise fall back to runtime type
361     // checking.
362     type1 = ((type_T **)stack->ga_data)[stack->ga_len - 2];
363     type2 = ((type_T **)stack->ga_data)[stack->ga_len - 1];
364     vartype = VAR_UNKNOWN;
365     if (type1->tt_type == type2->tt_type
366 	    && (type1->tt_type == VAR_NUMBER
367 		|| type1->tt_type == VAR_LIST
368 #ifdef FEAT_FLOAT
369 		|| type1->tt_type == VAR_FLOAT
370 #endif
371 		|| type1->tt_type == VAR_BLOB))
372 	vartype = type1->tt_type;
373 
374     switch (*op)
375     {
376 	case '+': if (vartype != VAR_LIST && vartype != VAR_BLOB
377 			  && check_number_or_float(
378 				   type1->tt_type, type2->tt_type, op) == FAIL)
379 		      return FAIL;
380 		  isn = generate_instr_drop(cctx,
381 			    vartype == VAR_NUMBER ? ISN_OPNR
382 			  : vartype == VAR_LIST ? ISN_ADDLIST
383 			  : vartype == VAR_BLOB ? ISN_ADDBLOB
384 #ifdef FEAT_FLOAT
385 			  : vartype == VAR_FLOAT ? ISN_OPFLOAT
386 #endif
387 			  : ISN_OPANY, 1);
388 		  if (isn != NULL)
389 		      isn->isn_arg.op.op_type = EXPR_ADD;
390 		  break;
391 
392 	case '-':
393 	case '*':
394 	case '/': if (check_number_or_float(type1->tt_type, type2->tt_type,
395 								   op) == FAIL)
396 		      return FAIL;
397 		  if (vartype == VAR_NUMBER)
398 		      isn = generate_instr_drop(cctx, ISN_OPNR, 1);
399 #ifdef FEAT_FLOAT
400 		  else if (vartype == VAR_FLOAT)
401 		      isn = generate_instr_drop(cctx, ISN_OPFLOAT, 1);
402 #endif
403 		  else
404 		      isn = generate_instr_drop(cctx, ISN_OPANY, 1);
405 		  if (isn != NULL)
406 		      isn->isn_arg.op.op_type = *op == '*'
407 				 ? EXPR_MULT : *op == '/'? EXPR_DIV : EXPR_SUB;
408 		  break;
409 
410 	case '%': if ((type1->tt_type != VAR_UNKNOWN
411 					       && type1->tt_type != VAR_NUMBER)
412 			  || (type2->tt_type != VAR_UNKNOWN
413 					      && type2->tt_type != VAR_NUMBER))
414 		  {
415 		      emsg(_("E1035: % requires number arguments"));
416 		      return FAIL;
417 		  }
418 		  isn = generate_instr_drop(cctx,
419 			      vartype == VAR_NUMBER ? ISN_OPNR : ISN_OPANY, 1);
420 		  if (isn != NULL)
421 		      isn->isn_arg.op.op_type = EXPR_REM;
422 		  break;
423     }
424 
425     // correct type of result
426     if (vartype == VAR_UNKNOWN)
427     {
428 	type_T *type = &t_any;
429 
430 #ifdef FEAT_FLOAT
431 	// float+number and number+float results in float
432 	if ((type1->tt_type == VAR_NUMBER || type1->tt_type == VAR_FLOAT)
433 		&& (type2->tt_type == VAR_NUMBER || type2->tt_type == VAR_FLOAT))
434 	    type = &t_float;
435 #endif
436 	((type_T **)stack->ga_data)[stack->ga_len - 1] = type;
437     }
438 
439     return OK;
440 }
441 
442 /*
443  * Generate an ISN_COMPARE* instruction with a boolean result.
444  */
445     static int
446 generate_COMPARE(cctx_T *cctx, exptype_T exptype, int ic)
447 {
448     isntype_T	isntype = ISN_DROP;
449     isn_T	*isn;
450     garray_T	*stack = &cctx->ctx_type_stack;
451     vartype_T	type1;
452     vartype_T	type2;
453 
454     // Get the known type of the two items on the stack.  If they are matching
455     // use a type-specific instruction. Otherwise fall back to runtime type
456     // checking.
457     type1 = ((type_T **)stack->ga_data)[stack->ga_len - 2]->tt_type;
458     type2 = ((type_T **)stack->ga_data)[stack->ga_len - 1]->tt_type;
459     if (type1 == type2)
460     {
461 	switch (type1)
462 	{
463 	    case VAR_BOOL: isntype = ISN_COMPAREBOOL; break;
464 	    case VAR_SPECIAL: isntype = ISN_COMPARESPECIAL; break;
465 	    case VAR_NUMBER: isntype = ISN_COMPARENR; break;
466 	    case VAR_FLOAT: isntype = ISN_COMPAREFLOAT; break;
467 	    case VAR_STRING: isntype = ISN_COMPARESTRING; break;
468 	    case VAR_BLOB: isntype = ISN_COMPAREBLOB; break;
469 	    case VAR_LIST: isntype = ISN_COMPARELIST; break;
470 	    case VAR_DICT: isntype = ISN_COMPAREDICT; break;
471 	    case VAR_FUNC: isntype = ISN_COMPAREFUNC; break;
472 	    case VAR_PARTIAL: isntype = ISN_COMPAREPARTIAL; break;
473 	    default: isntype = ISN_COMPAREANY; break;
474 	}
475     }
476     else if (type1 == VAR_UNKNOWN || type2 == VAR_UNKNOWN
477 	    || ((type1 == VAR_NUMBER || type1 == VAR_FLOAT)
478 	      && (type2 == VAR_NUMBER || type2 ==VAR_FLOAT)))
479 	isntype = ISN_COMPAREANY;
480 
481     if ((exptype == EXPR_IS || exptype == EXPR_ISNOT)
482 	    && (isntype == ISN_COMPAREBOOL
483 	    || isntype == ISN_COMPARESPECIAL
484 	    || isntype == ISN_COMPARENR
485 	    || isntype == ISN_COMPAREFLOAT))
486     {
487 	semsg(_("E1037: Cannot use \"%s\" with %s"),
488 		exptype == EXPR_IS ? "is" : "isnot" , vartype_name(type1));
489 	return FAIL;
490     }
491     if (isntype == ISN_DROP
492 	    || ((exptype != EXPR_EQUAL && exptype != EXPR_NEQUAL
493 		    && (type1 == VAR_BOOL || type1 == VAR_SPECIAL
494 		       || type2 == VAR_BOOL || type2 == VAR_SPECIAL)))
495 	    || ((exptype != EXPR_EQUAL && exptype != EXPR_NEQUAL
496 				 && exptype != EXPR_IS && exptype != EXPR_ISNOT
497 		    && (type1 == VAR_BLOB || type2 == VAR_BLOB
498 			|| type1 == VAR_LIST || type2 == VAR_LIST))))
499     {
500 	semsg(_("E1037: Cannot compare %s with %s"),
501 		vartype_name(type1), vartype_name(type2));
502 	return FAIL;
503     }
504 
505     if ((isn = generate_instr(cctx, isntype)) == NULL)
506 	return FAIL;
507     isn->isn_arg.op.op_type = exptype;
508     isn->isn_arg.op.op_ic = ic;
509 
510     // takes two arguments, puts one bool back
511     if (stack->ga_len >= 2)
512     {
513 	--stack->ga_len;
514 	((type_T **)stack->ga_data)[stack->ga_len - 1] = &t_bool;
515     }
516 
517     return OK;
518 }
519 
520 /*
521  * Generate an ISN_2BOOL instruction.
522  */
523     static int
524 generate_2BOOL(cctx_T *cctx, int invert)
525 {
526     isn_T	*isn;
527     garray_T	*stack = &cctx->ctx_type_stack;
528 
529     if ((isn = generate_instr(cctx, ISN_2BOOL)) == NULL)
530 	return FAIL;
531     isn->isn_arg.number = invert;
532 
533     // type becomes bool
534     ((type_T **)stack->ga_data)[stack->ga_len - 1] = &t_bool;
535 
536     return OK;
537 }
538 
539     static int
540 generate_TYPECHECK(cctx_T *cctx, type_T *vartype, int offset)
541 {
542     isn_T	*isn;
543     garray_T	*stack = &cctx->ctx_type_stack;
544 
545     if ((isn = generate_instr(cctx, ISN_CHECKTYPE)) == NULL)
546 	return FAIL;
547     isn->isn_arg.type.ct_type = vartype->tt_type;  // TODO: whole type
548     isn->isn_arg.type.ct_off = offset;
549 
550     // type becomes vartype
551     ((type_T **)stack->ga_data)[stack->ga_len - 1] = vartype;
552 
553     return OK;
554 }
555 
556 /*
557  * Generate an ISN_PUSHNR instruction.
558  */
559     static int
560 generate_PUSHNR(cctx_T *cctx, varnumber_T number)
561 {
562     isn_T	*isn;
563 
564     if ((isn = generate_instr_type(cctx, ISN_PUSHNR, &t_number)) == NULL)
565 	return FAIL;
566     isn->isn_arg.number = number;
567 
568     return OK;
569 }
570 
571 /*
572  * Generate an ISN_PUSHBOOL instruction.
573  */
574     static int
575 generate_PUSHBOOL(cctx_T *cctx, varnumber_T number)
576 {
577     isn_T	*isn;
578 
579     if ((isn = generate_instr_type(cctx, ISN_PUSHBOOL, &t_bool)) == NULL)
580 	return FAIL;
581     isn->isn_arg.number = number;
582 
583     return OK;
584 }
585 
586 /*
587  * Generate an ISN_PUSHSPEC instruction.
588  */
589     static int
590 generate_PUSHSPEC(cctx_T *cctx, varnumber_T number)
591 {
592     isn_T	*isn;
593 
594     if ((isn = generate_instr_type(cctx, ISN_PUSHSPEC, &t_special)) == NULL)
595 	return FAIL;
596     isn->isn_arg.number = number;
597 
598     return OK;
599 }
600 
601 #ifdef FEAT_FLOAT
602 /*
603  * Generate an ISN_PUSHF instruction.
604  */
605     static int
606 generate_PUSHF(cctx_T *cctx, float_T fnumber)
607 {
608     isn_T	*isn;
609 
610     if ((isn = generate_instr_type(cctx, ISN_PUSHF, &t_float)) == NULL)
611 	return FAIL;
612     isn->isn_arg.fnumber = fnumber;
613 
614     return OK;
615 }
616 #endif
617 
618 /*
619  * Generate an ISN_PUSHS instruction.
620  * Consumes "str".
621  */
622     static int
623 generate_PUSHS(cctx_T *cctx, char_u *str)
624 {
625     isn_T	*isn;
626 
627     if ((isn = generate_instr_type(cctx, ISN_PUSHS, &t_string)) == NULL)
628 	return FAIL;
629     isn->isn_arg.string = str;
630 
631     return OK;
632 }
633 
634 /*
635  * Generate an ISN_PUSHBLOB instruction.
636  * Consumes "blob".
637  */
638     static int
639 generate_PUSHBLOB(cctx_T *cctx, blob_T *blob)
640 {
641     isn_T	*isn;
642 
643     if ((isn = generate_instr_type(cctx, ISN_PUSHBLOB, &t_blob)) == NULL)
644 	return FAIL;
645     isn->isn_arg.blob = blob;
646 
647     return OK;
648 }
649 
650 /*
651  * Generate an ISN_STORE instruction.
652  */
653     static int
654 generate_STORE(cctx_T *cctx, isntype_T isn_type, int idx, char_u *name)
655 {
656     isn_T	*isn;
657 
658     if ((isn = generate_instr_drop(cctx, isn_type, 1)) == NULL)
659 	return FAIL;
660     if (name != NULL)
661 	isn->isn_arg.string = vim_strsave(name);
662     else
663 	isn->isn_arg.number = idx;
664 
665     return OK;
666 }
667 
668 /*
669  * Generate an ISN_STORENR instruction (short for ISN_PUSHNR + ISN_STORE)
670  */
671     static int
672 generate_STORENR(cctx_T *cctx, int idx, varnumber_T value)
673 {
674     isn_T	*isn;
675 
676     if ((isn = generate_instr(cctx, ISN_STORENR)) == NULL)
677 	return FAIL;
678     isn->isn_arg.storenr.str_idx = idx;
679     isn->isn_arg.storenr.str_val = value;
680 
681     return OK;
682 }
683 
684 /*
685  * Generate an ISN_STOREOPT instruction
686  */
687     static int
688 generate_STOREOPT(cctx_T *cctx, char_u *name, int opt_flags)
689 {
690     isn_T	*isn;
691 
692     if ((isn = generate_instr(cctx, ISN_STOREOPT)) == NULL)
693 	return FAIL;
694     isn->isn_arg.storeopt.so_name = vim_strsave(name);
695     isn->isn_arg.storeopt.so_flags = opt_flags;
696 
697     return OK;
698 }
699 
700 /*
701  * Generate an ISN_LOAD or similar instruction.
702  */
703     static int
704 generate_LOAD(
705 	cctx_T	    *cctx,
706 	isntype_T   isn_type,
707 	int	    idx,
708 	char_u	    *name,
709 	type_T	    *type)
710 {
711     isn_T	*isn;
712 
713     if ((isn = generate_instr_type(cctx, isn_type, type)) == NULL)
714 	return FAIL;
715     if (name != NULL)
716 	isn->isn_arg.string = vim_strsave(name);
717     else
718 	isn->isn_arg.number = idx;
719 
720     return OK;
721 }
722 
723 /*
724  * Generate an ISN_LOADV instruction.
725  */
726     static int
727 generate_LOADV(
728 	cctx_T	    *cctx,
729 	char_u	    *name,
730 	int	    error)
731 {
732     // load v:var
733     int vidx = find_vim_var(name);
734 
735     if (vidx < 0)
736     {
737 	if (error)
738 	    semsg(_(e_var_notfound), name);
739 	return FAIL;
740     }
741 
742     // TODO: get actual type
743     return generate_LOAD(cctx, ISN_LOADV, vidx, NULL, &t_any);
744 }
745 
746 /*
747  * Generate an ISN_LOADS instruction.
748  */
749     static int
750 generate_OLDSCRIPT(
751 	cctx_T	    *cctx,
752 	isntype_T   isn_type,
753 	char_u	    *name,
754 	int	    sid,
755 	type_T	    *type)
756 {
757     isn_T	*isn;
758 
759     if (isn_type == ISN_LOADS)
760 	isn = generate_instr_type(cctx, isn_type, type);
761     else
762 	isn = generate_instr_drop(cctx, isn_type, 1);
763     if (isn == NULL)
764 	return FAIL;
765     isn->isn_arg.loadstore.ls_name = vim_strsave(name);
766     isn->isn_arg.loadstore.ls_sid = sid;
767 
768     return OK;
769 }
770 
771 /*
772  * Generate an ISN_LOADSCRIPT or ISN_STORESCRIPT instruction.
773  */
774     static int
775 generate_VIM9SCRIPT(
776 	cctx_T	    *cctx,
777 	isntype_T   isn_type,
778 	int	    sid,
779 	int	    idx,
780 	type_T	    *type)
781 {
782     isn_T	*isn;
783 
784     if (isn_type == ISN_LOADSCRIPT)
785 	isn = generate_instr_type(cctx, isn_type, type);
786     else
787 	isn = generate_instr_drop(cctx, isn_type, 1);
788     if (isn == NULL)
789 	return FAIL;
790     isn->isn_arg.script.script_sid = sid;
791     isn->isn_arg.script.script_idx = idx;
792     return OK;
793 }
794 
795 /*
796  * Generate an ISN_NEWLIST instruction.
797  */
798     static int
799 generate_NEWLIST(cctx_T *cctx, int count)
800 {
801     isn_T	*isn;
802     garray_T	*stack = &cctx->ctx_type_stack;
803     garray_T	*type_list = cctx->ctx_type_list;
804     type_T	*type;
805     type_T	*member;
806 
807     if ((isn = generate_instr(cctx, ISN_NEWLIST)) == NULL)
808 	return FAIL;
809     isn->isn_arg.number = count;
810 
811     // drop the value types
812     stack->ga_len -= count;
813 
814     // use the first value type for the list member type
815     if (count > 0)
816 	member = ((type_T **)stack->ga_data)[stack->ga_len];
817     else
818 	member = &t_any;
819     type = get_list_type(member, type_list);
820 
821     // add the list type to the type stack
822     if (ga_grow(stack, 1) == FAIL)
823 	return FAIL;
824     ((type_T **)stack->ga_data)[stack->ga_len] = type;
825     ++stack->ga_len;
826 
827     return OK;
828 }
829 
830 /*
831  * Generate an ISN_NEWDICT instruction.
832  */
833     static int
834 generate_NEWDICT(cctx_T *cctx, int count)
835 {
836     isn_T	*isn;
837     garray_T	*stack = &cctx->ctx_type_stack;
838     garray_T	*type_list = cctx->ctx_type_list;
839     type_T	*type;
840     type_T	*member;
841 
842     if ((isn = generate_instr(cctx, ISN_NEWDICT)) == NULL)
843 	return FAIL;
844     isn->isn_arg.number = count;
845 
846     // drop the key and value types
847     stack->ga_len -= 2 * count;
848 
849     // use the first value type for the list member type
850     if (count > 0)
851 	member = ((type_T **)stack->ga_data)[stack->ga_len + 1];
852     else
853 	member = &t_any;
854     type = get_dict_type(member, type_list);
855 
856     // add the dict type to the type stack
857     if (ga_grow(stack, 1) == FAIL)
858 	return FAIL;
859     ((type_T **)stack->ga_data)[stack->ga_len] = type;
860     ++stack->ga_len;
861 
862     return OK;
863 }
864 
865 /*
866  * Generate an ISN_FUNCREF instruction.
867  */
868     static int
869 generate_FUNCREF(cctx_T *cctx, int dfunc_idx)
870 {
871     isn_T	*isn;
872     garray_T	*stack = &cctx->ctx_type_stack;
873 
874     if ((isn = generate_instr(cctx, ISN_FUNCREF)) == NULL)
875 	return FAIL;
876     isn->isn_arg.number = dfunc_idx;
877 
878     if (ga_grow(stack, 1) == FAIL)
879 	return FAIL;
880     ((type_T **)stack->ga_data)[stack->ga_len] = &t_partial_any;
881     // TODO: argument and return types
882     ++stack->ga_len;
883 
884     return OK;
885 }
886 
887 /*
888  * Generate an ISN_JUMP instruction.
889  */
890     static int
891 generate_JUMP(cctx_T *cctx, jumpwhen_T when, int where)
892 {
893     isn_T	*isn;
894     garray_T	*stack = &cctx->ctx_type_stack;
895 
896     if ((isn = generate_instr(cctx, ISN_JUMP)) == NULL)
897 	return FAIL;
898     isn->isn_arg.jump.jump_when = when;
899     isn->isn_arg.jump.jump_where = where;
900 
901     if (when != JUMP_ALWAYS && stack->ga_len > 0)
902 	--stack->ga_len;
903 
904     return OK;
905 }
906 
907     static int
908 generate_FOR(cctx_T *cctx, int loop_idx)
909 {
910     isn_T	*isn;
911     garray_T	*stack = &cctx->ctx_type_stack;
912 
913     if ((isn = generate_instr(cctx, ISN_FOR)) == NULL)
914 	return FAIL;
915     isn->isn_arg.forloop.for_idx = loop_idx;
916 
917     if (ga_grow(stack, 1) == FAIL)
918 	return FAIL;
919     // type doesn't matter, will be stored next
920     ((type_T **)stack->ga_data)[stack->ga_len] = &t_any;
921     ++stack->ga_len;
922 
923     return OK;
924 }
925 
926 /*
927  * Generate an ISN_BCALL instruction.
928  * Return FAIL if the number of arguments is wrong.
929  */
930     static int
931 generate_BCALL(cctx_T *cctx, int func_idx, int argcount)
932 {
933     isn_T	*isn;
934     garray_T	*stack = &cctx->ctx_type_stack;
935 
936     if (check_internal_func(func_idx, argcount) == FAIL)
937 	return FAIL;
938 
939     if ((isn = generate_instr(cctx, ISN_BCALL)) == NULL)
940 	return FAIL;
941     isn->isn_arg.bfunc.cbf_idx = func_idx;
942     isn->isn_arg.bfunc.cbf_argcount = argcount;
943 
944     stack->ga_len -= argcount; // drop the arguments
945     if (ga_grow(stack, 1) == FAIL)
946 	return FAIL;
947     ((type_T **)stack->ga_data)[stack->ga_len] =
948 				    internal_func_ret_type(func_idx, argcount);
949     ++stack->ga_len;	    // add return value
950 
951     return OK;
952 }
953 
954 /*
955  * Generate an ISN_DCALL or ISN_UCALL instruction.
956  * Return FAIL if the number of arguments is wrong.
957  */
958     static int
959 generate_CALL(cctx_T *cctx, ufunc_T *ufunc, int pushed_argcount)
960 {
961     isn_T	*isn;
962     garray_T	*stack = &cctx->ctx_type_stack;
963     int		regular_args = ufunc->uf_args.ga_len;
964     int		argcount = pushed_argcount;
965 
966     if (argcount > regular_args && !has_varargs(ufunc))
967     {
968 	semsg(_(e_toomanyarg), ufunc->uf_name);
969 	return FAIL;
970     }
971     if (argcount < regular_args - ufunc->uf_def_args.ga_len)
972     {
973 	semsg(_(e_toofewarg), ufunc->uf_name);
974 	return FAIL;
975     }
976 
977     // Turn varargs into a list.
978     if (ufunc->uf_va_name != NULL)
979     {
980 	int count = argcount - regular_args;
981 
982 	// If count is negative an empty list will be added after evaluating
983 	// default values for missing optional arguments.
984 	if (count >= 0)
985 	{
986 	    generate_NEWLIST(cctx, count);
987 	    argcount = regular_args + 1;
988 	}
989     }
990 
991     if ((isn = generate_instr(cctx,
992 		    ufunc->uf_dfunc_idx >= 0 ? ISN_DCALL : ISN_UCALL)) == NULL)
993 	return FAIL;
994     if (ufunc->uf_dfunc_idx >= 0)
995     {
996 	isn->isn_arg.dfunc.cdf_idx = ufunc->uf_dfunc_idx;
997 	isn->isn_arg.dfunc.cdf_argcount = argcount;
998     }
999     else
1000     {
1001 	// A user function may be deleted and redefined later, can't use the
1002 	// ufunc pointer, need to look it up again at runtime.
1003 	isn->isn_arg.ufunc.cuf_name = vim_strsave(ufunc->uf_name);
1004 	isn->isn_arg.ufunc.cuf_argcount = argcount;
1005     }
1006 
1007     stack->ga_len -= argcount; // drop the arguments
1008     if (ga_grow(stack, 1) == FAIL)
1009 	return FAIL;
1010     // add return value
1011     ((type_T **)stack->ga_data)[stack->ga_len] = ufunc->uf_ret_type;
1012     ++stack->ga_len;
1013 
1014     return OK;
1015 }
1016 
1017 /*
1018  * Generate an ISN_UCALL instruction when the function isn't defined yet.
1019  */
1020     static int
1021 generate_UCALL(cctx_T *cctx, char_u *name, int argcount)
1022 {
1023     isn_T	*isn;
1024     garray_T	*stack = &cctx->ctx_type_stack;
1025 
1026     if ((isn = generate_instr(cctx, ISN_UCALL)) == NULL)
1027 	return FAIL;
1028     isn->isn_arg.ufunc.cuf_name = vim_strsave(name);
1029     isn->isn_arg.ufunc.cuf_argcount = argcount;
1030 
1031     stack->ga_len -= argcount; // drop the arguments
1032     if (ga_grow(stack, 1) == FAIL)
1033 	return FAIL;
1034     // add return value
1035     ((type_T **)stack->ga_data)[stack->ga_len] = &t_any;
1036     ++stack->ga_len;
1037 
1038     return OK;
1039 }
1040 
1041 /*
1042  * Generate an ISN_PCALL instruction.
1043  */
1044     static int
1045 generate_PCALL(cctx_T *cctx, int argcount, int at_top)
1046 {
1047     isn_T	*isn;
1048     garray_T	*stack = &cctx->ctx_type_stack;
1049 
1050     if ((isn = generate_instr(cctx, ISN_PCALL)) == NULL)
1051 	return FAIL;
1052     isn->isn_arg.pfunc.cpf_top = at_top;
1053     isn->isn_arg.pfunc.cpf_argcount = argcount;
1054 
1055     stack->ga_len -= argcount; // drop the arguments
1056 
1057     // drop the funcref/partial, get back the return value
1058     ((type_T **)stack->ga_data)[stack->ga_len - 1] = &t_any;
1059 
1060     return OK;
1061 }
1062 
1063 /*
1064  * Generate an ISN_MEMBER instruction.
1065  */
1066     static int
1067 generate_MEMBER(cctx_T *cctx, char_u *name, size_t len)
1068 {
1069     isn_T	*isn;
1070     garray_T	*stack = &cctx->ctx_type_stack;
1071     type_T	*type;
1072 
1073     if ((isn = generate_instr(cctx, ISN_MEMBER)) == NULL)
1074 	return FAIL;
1075     isn->isn_arg.string = vim_strnsave(name, (int)len);
1076 
1077     // change dict type to dict member type
1078     type = ((type_T **)stack->ga_data)[stack->ga_len - 1];
1079     ((type_T **)stack->ga_data)[stack->ga_len - 1] = type->tt_member;
1080 
1081     return OK;
1082 }
1083 
1084 /*
1085  * Generate an ISN_ECHO instruction.
1086  */
1087     static int
1088 generate_ECHO(cctx_T *cctx, int with_white, int count)
1089 {
1090     isn_T	*isn;
1091 
1092     if ((isn = generate_instr_drop(cctx, ISN_ECHO, count)) == NULL)
1093 	return FAIL;
1094     isn->isn_arg.echo.echo_with_white = with_white;
1095     isn->isn_arg.echo.echo_count = count;
1096 
1097     return OK;
1098 }
1099 
1100     static int
1101 generate_EXEC(cctx_T *cctx, char_u *line)
1102 {
1103     isn_T	*isn;
1104 
1105     if ((isn = generate_instr(cctx, ISN_EXEC)) == NULL)
1106 	return FAIL;
1107     isn->isn_arg.string = vim_strsave(line);
1108     return OK;
1109 }
1110 
1111 static char e_white_both[] =
1112 			N_("E1004: white space required before and after '%s'");
1113 
1114 /*
1115  * Reserve space for a local variable.
1116  * Return the index or -1 if it failed.
1117  */
1118     static int
1119 reserve_local(cctx_T *cctx, char_u *name, size_t len, int isConst, type_T *type)
1120 {
1121     int	    idx;
1122     lvar_T  *lvar;
1123 
1124     if (lookup_arg(name, len, cctx) >= 0 || lookup_vararg(name, len, cctx))
1125     {
1126 	emsg_namelen(_("E1006: %s is used as an argument"), name, (int)len);
1127 	return -1;
1128     }
1129 
1130     if (ga_grow(&cctx->ctx_locals, 1) == FAIL)
1131 	return -1;
1132     idx = cctx->ctx_locals.ga_len;
1133     if (cctx->ctx_max_local < idx + 1)
1134 	cctx->ctx_max_local = idx + 1;
1135     ++cctx->ctx_locals.ga_len;
1136 
1137     lvar = ((lvar_T *)cctx->ctx_locals.ga_data) + idx;
1138     lvar->lv_name = vim_strnsave(name, (int)(len == 0 ? STRLEN(name) : len));
1139     lvar->lv_const = isConst;
1140     lvar->lv_type = type;
1141 
1142     return idx;
1143 }
1144 
1145 /*
1146  * Skip over a type definition and return a pointer to just after it.
1147  */
1148     char_u *
1149 skip_type(char_u *start)
1150 {
1151     char_u *p = start;
1152 
1153     while (ASCII_ISALNUM(*p) || *p == '_')
1154 	++p;
1155 
1156     // Skip over "<type>"; this is permissive about white space.
1157     if (*skipwhite(p) == '<')
1158     {
1159 	p = skipwhite(p);
1160 	p = skip_type(skipwhite(p + 1));
1161 	p = skipwhite(p);
1162 	if (*p == '>')
1163 	    ++p;
1164     }
1165     return p;
1166 }
1167 
1168 /*
1169  * Parse the member type: "<type>" and return "type" with the member set.
1170  * Use "type_list" if a new type needs to be added.
1171  * Returns NULL in case of failure.
1172  */
1173     static type_T *
1174 parse_type_member(char_u **arg, type_T *type, garray_T *type_list)
1175 {
1176     type_T  *member_type;
1177 
1178     if (**arg != '<')
1179     {
1180 	if (*skipwhite(*arg) == '<')
1181 	    emsg(_("E1007: No white space allowed before <"));
1182 	else
1183 	    emsg(_("E1008: Missing <type>"));
1184 	return NULL;
1185     }
1186     *arg = skipwhite(*arg + 1);
1187 
1188     member_type = parse_type(arg, type_list);
1189     if (member_type == NULL)
1190 	return NULL;
1191 
1192     *arg = skipwhite(*arg);
1193     if (**arg != '>')
1194     {
1195 	emsg(_("E1009: Missing > after type"));
1196 	return NULL;
1197     }
1198     ++*arg;
1199 
1200     if (type->tt_type == VAR_LIST)
1201 	return get_list_type(member_type, type_list);
1202     return get_dict_type(member_type, type_list);
1203 }
1204 
1205 /*
1206  * Parse a type at "arg" and advance over it.
1207  * Return NULL for failure.
1208  */
1209     type_T *
1210 parse_type(char_u **arg, garray_T *type_list)
1211 {
1212     char_u  *p = *arg;
1213     size_t  len;
1214 
1215     // skip over the first word
1216     while (ASCII_ISALNUM(*p) || *p == '_')
1217 	++p;
1218     len = p - *arg;
1219 
1220     switch (**arg)
1221     {
1222 	case 'a':
1223 	    if (len == 3 && STRNCMP(*arg, "any", len) == 0)
1224 	    {
1225 		*arg += len;
1226 		return &t_any;
1227 	    }
1228 	    break;
1229 	case 'b':
1230 	    if (len == 4 && STRNCMP(*arg, "bool", len) == 0)
1231 	    {
1232 		*arg += len;
1233 		return &t_bool;
1234 	    }
1235 	    if (len == 4 && STRNCMP(*arg, "blob", len) == 0)
1236 	    {
1237 		*arg += len;
1238 		return &t_blob;
1239 	    }
1240 	    break;
1241 	case 'c':
1242 	    if (len == 7 && STRNCMP(*arg, "channel", len) == 0)
1243 	    {
1244 		*arg += len;
1245 		return &t_channel;
1246 	    }
1247 	    break;
1248 	case 'd':
1249 	    if (len == 4 && STRNCMP(*arg, "dict", len) == 0)
1250 	    {
1251 		*arg += len;
1252 		return parse_type_member(arg, &t_dict_any, type_list);
1253 	    }
1254 	    break;
1255 	case 'f':
1256 	    if (len == 5 && STRNCMP(*arg, "float", len) == 0)
1257 	    {
1258 #ifdef FEAT_FLOAT
1259 		*arg += len;
1260 		return &t_float;
1261 #else
1262 		emsg(_("E1055: This Vim is not compiled with float support"));
1263 		return &t_any;
1264 #endif
1265 	    }
1266 	    if (len == 4 && STRNCMP(*arg, "func", len) == 0)
1267 	    {
1268 		*arg += len;
1269 		// TODO: arguments and return type
1270 		return &t_func_any;
1271 	    }
1272 	    break;
1273 	case 'j':
1274 	    if (len == 3 && STRNCMP(*arg, "job", len) == 0)
1275 	    {
1276 		*arg += len;
1277 		return &t_job;
1278 	    }
1279 	    break;
1280 	case 'l':
1281 	    if (len == 4 && STRNCMP(*arg, "list", len) == 0)
1282 	    {
1283 		*arg += len;
1284 		return parse_type_member(arg, &t_list_any, type_list);
1285 	    }
1286 	    break;
1287 	case 'n':
1288 	    if (len == 6 && STRNCMP(*arg, "number", len) == 0)
1289 	    {
1290 		*arg += len;
1291 		return &t_number;
1292 	    }
1293 	    break;
1294 	case 'p':
1295 	    if (len == 4 && STRNCMP(*arg, "partial", len) == 0)
1296 	    {
1297 		*arg += len;
1298 		// TODO: arguments and return type
1299 		return &t_partial_any;
1300 	    }
1301 	    break;
1302 	case 's':
1303 	    if (len == 6 && STRNCMP(*arg, "string", len) == 0)
1304 	    {
1305 		*arg += len;
1306 		return &t_string;
1307 	    }
1308 	    break;
1309 	case 'v':
1310 	    if (len == 4 && STRNCMP(*arg, "void", len) == 0)
1311 	    {
1312 		*arg += len;
1313 		return &t_void;
1314 	    }
1315 	    break;
1316     }
1317 
1318     semsg(_("E1010: Type not recognized: %s"), *arg);
1319     return &t_any;
1320 }
1321 
1322 /*
1323  * Check if "type1" and "type2" are exactly the same.
1324  */
1325     static int
1326 equal_type(type_T *type1, type_T *type2)
1327 {
1328     if (type1->tt_type != type2->tt_type)
1329 	return FALSE;
1330     switch (type1->tt_type)
1331     {
1332 	case VAR_VOID:
1333 	case VAR_UNKNOWN:
1334 	case VAR_SPECIAL:
1335 	case VAR_BOOL:
1336 	case VAR_NUMBER:
1337 	case VAR_FLOAT:
1338 	case VAR_STRING:
1339 	case VAR_BLOB:
1340 	case VAR_JOB:
1341 	case VAR_CHANNEL:
1342 	    return TRUE;  // not composite is always OK
1343 	case VAR_LIST:
1344 	case VAR_DICT:
1345 	    return equal_type(type1->tt_member, type2->tt_member);
1346 	case VAR_FUNC:
1347 	case VAR_PARTIAL:
1348 	    // TODO; check argument types.
1349 	    return equal_type(type1->tt_member, type2->tt_member)
1350 		&& type1->tt_argcount == type2->tt_argcount;
1351     }
1352     return TRUE;
1353 }
1354 
1355 /*
1356  * Find the common type of "type1" and "type2" and put it in "dest".
1357  * "type2" and "dest" may be the same.
1358  */
1359     static void
1360 common_type(type_T *type1, type_T *type2, type_T *dest)
1361 {
1362     if (equal_type(type1, type2))
1363     {
1364 	if (dest != type2)
1365 	    *dest = *type2;
1366 	return;
1367     }
1368 
1369     if (type1->tt_type == type2->tt_type)
1370     {
1371 	dest->tt_type = type1->tt_type;
1372 	if (type1->tt_type == VAR_LIST || type2->tt_type == VAR_DICT)
1373 	{
1374 	    common_type(type1->tt_member, type2->tt_member, dest->tt_member);
1375 	    return;
1376 	}
1377 	// TODO: VAR_FUNC and VAR_PARTIAL
1378     }
1379 
1380     dest->tt_type = VAR_UNKNOWN;  // "any"
1381 }
1382 
1383     char *
1384 vartype_name(vartype_T type)
1385 {
1386     switch (type)
1387     {
1388 	case VAR_VOID: return "void";
1389 	case VAR_UNKNOWN: return "any";
1390 	case VAR_SPECIAL: return "special";
1391 	case VAR_BOOL: return "bool";
1392 	case VAR_NUMBER: return "number";
1393 	case VAR_FLOAT: return "float";
1394 	case VAR_STRING: return "string";
1395 	case VAR_BLOB: return "blob";
1396 	case VAR_JOB: return "job";
1397 	case VAR_CHANNEL: return "channel";
1398 	case VAR_LIST: return "list";
1399 	case VAR_DICT: return "dict";
1400 	case VAR_FUNC: return "function";
1401 	case VAR_PARTIAL: return "partial";
1402     }
1403     return "???";
1404 }
1405 
1406 /*
1407  * Return the name of a type.
1408  * The result may be in allocated memory, in which case "tofree" is set.
1409  */
1410     char *
1411 type_name(type_T *type, char **tofree)
1412 {
1413     char *name = vartype_name(type->tt_type);
1414 
1415     *tofree = NULL;
1416     if (type->tt_type == VAR_LIST || type->tt_type == VAR_DICT)
1417     {
1418 	char *member_free;
1419 	char *member_name = type_name(type->tt_member, &member_free);
1420 	size_t len;
1421 
1422 	len = STRLEN(name) + STRLEN(member_name) + 3;
1423 	*tofree = alloc(len);
1424 	if (*tofree != NULL)
1425 	{
1426 	    vim_snprintf(*tofree, len, "%s<%s>", name, member_name);
1427 	    vim_free(member_free);
1428 	    return *tofree;
1429 	}
1430     }
1431     // TODO: function and partial argument types
1432 
1433     return name;
1434 }
1435 
1436 /*
1437  * Find "name" in script-local items of script "sid".
1438  * Returns the index in "sn_var_vals" if found.
1439  * If found but not in "sn_var_vals" returns -1.
1440  * If not found returns -2.
1441  */
1442     int
1443 get_script_item_idx(int sid, char_u *name, int check_writable)
1444 {
1445     hashtab_T	    *ht;
1446     dictitem_T	    *di;
1447     scriptitem_T    *si = SCRIPT_ITEM(sid);
1448     int		    idx;
1449 
1450     // First look the name up in the hashtable.
1451     if (sid <= 0 || sid > script_items.ga_len)
1452 	return -1;
1453     ht = &SCRIPT_VARS(sid);
1454     di = find_var_in_ht(ht, 0, name, TRUE);
1455     if (di == NULL)
1456 	return -2;
1457 
1458     // Now find the svar_T index in sn_var_vals.
1459     for (idx = 0; idx < si->sn_var_vals.ga_len; ++idx)
1460     {
1461 	svar_T    *sv = ((svar_T *)si->sn_var_vals.ga_data) + idx;
1462 
1463 	if (sv->sv_tv == &di->di_tv)
1464 	{
1465 	    if (check_writable && sv->sv_const)
1466 		semsg(_(e_readonlyvar), name);
1467 	    return idx;
1468 	}
1469     }
1470     return -1;
1471 }
1472 
1473 /*
1474  * Find "name" in imported items of the current script/
1475  */
1476     imported_T *
1477 find_imported(char_u *name, size_t len, cctx_T *cctx)
1478 {
1479     scriptitem_T    *si = SCRIPT_ITEM(current_sctx.sc_sid);
1480     int		    idx;
1481 
1482     if (cctx != NULL)
1483 	for (idx = 0; idx < cctx->ctx_imports.ga_len; ++idx)
1484 	{
1485 	    imported_T *import = ((imported_T *)cctx->ctx_imports.ga_data)
1486 									 + idx;
1487 
1488 	    if (len == 0 ? STRCMP(name, import->imp_name) == 0
1489 			 : STRLEN(import->imp_name) == len
1490 				  && STRNCMP(name, import->imp_name, len) == 0)
1491 		return import;
1492 	}
1493 
1494     for (idx = 0; idx < si->sn_imports.ga_len; ++idx)
1495     {
1496 	imported_T *import = ((imported_T *)si->sn_imports.ga_data) + idx;
1497 
1498 	if (len == 0 ? STRCMP(name, import->imp_name) == 0
1499 		     : STRLEN(import->imp_name) == len
1500 				  && STRNCMP(name, import->imp_name, len) == 0)
1501 	    return import;
1502     }
1503     return NULL;
1504 }
1505 
1506 /*
1507  * Generate an instruction to load script-local variable "name".
1508  */
1509     static int
1510 compile_load_scriptvar(cctx_T *cctx, char_u *name)
1511 {
1512     scriptitem_T    *si = SCRIPT_ITEM(current_sctx.sc_sid);
1513     int		    idx = get_script_item_idx(current_sctx.sc_sid, name, FALSE);
1514     imported_T	    *import;
1515 
1516     if (idx == -1)
1517     {
1518 	// variable exists but is not in sn_var_vals: old style script.
1519 	return generate_OLDSCRIPT(cctx, ISN_LOADS, name, current_sctx.sc_sid,
1520 								       &t_any);
1521     }
1522     if (idx >= 0)
1523     {
1524 	svar_T		*sv = ((svar_T *)si->sn_var_vals.ga_data) + idx;
1525 
1526 	generate_VIM9SCRIPT(cctx, ISN_LOADSCRIPT,
1527 					current_sctx.sc_sid, idx, sv->sv_type);
1528 	return OK;
1529     }
1530 
1531     import = find_imported(name, 0, cctx);
1532     if (import != NULL)
1533     {
1534 	// TODO: check this is a variable, not a function
1535 	generate_VIM9SCRIPT(cctx, ISN_LOADSCRIPT,
1536 		import->imp_sid,
1537 		import->imp_var_vals_idx,
1538 		import->imp_type);
1539 	return OK;
1540     }
1541 
1542     semsg(_("E1050: Item not found: %s"), name);
1543     return FAIL;
1544 }
1545 
1546 /*
1547  * Compile a variable name into a load instruction.
1548  * "end" points to just after the name.
1549  * When "error" is FALSE do not give an error when not found.
1550  */
1551     static int
1552 compile_load(char_u **arg, char_u *end, cctx_T *cctx, int error)
1553 {
1554     type_T	*type;
1555     char_u	*name;
1556     int		res = FAIL;
1557 
1558     if (*(*arg + 1) == ':')
1559     {
1560 	// load namespaced variable
1561 	name = vim_strnsave(*arg + 2, end - (*arg + 2));
1562 	if (name == NULL)
1563 	    return FAIL;
1564 
1565 	if (**arg == 'v')
1566 	{
1567 	    res = generate_LOADV(cctx, name, error);
1568 	}
1569 	else if (**arg == 'g')
1570 	{
1571 	    // Global variables can be defined later, thus we don't check if it
1572 	    // exists, give error at runtime.
1573 	    res = generate_LOAD(cctx, ISN_LOADG, 0, name, &t_any);
1574 	}
1575 	else if (**arg == 's')
1576 	{
1577 	    res = compile_load_scriptvar(cctx, name);
1578 	}
1579 	else
1580 	{
1581 	    semsg("Namespace not supported yet: %s", **arg);
1582 	    goto theend;
1583 	}
1584     }
1585     else
1586     {
1587 	size_t	    len = end - *arg;
1588 	int	    idx;
1589 	int	    gen_load = FALSE;
1590 
1591 	name = vim_strnsave(*arg, end - *arg);
1592 	if (name == NULL)
1593 	    return FAIL;
1594 
1595 	idx = lookup_arg(*arg, len, cctx);
1596 	if (idx >= 0)
1597 	{
1598 	    if (cctx->ctx_ufunc->uf_arg_types != NULL)
1599 		type = cctx->ctx_ufunc->uf_arg_types[idx];
1600 	    else
1601 		type = &t_any;
1602 
1603 	    // Arguments are located above the frame pointer.
1604 	    idx -= cctx->ctx_ufunc->uf_args.ga_len + STACK_FRAME_SIZE;
1605 	    if (cctx->ctx_ufunc->uf_va_name != NULL)
1606 		--idx;
1607 	    gen_load = TRUE;
1608 	}
1609 	else if (lookup_vararg(*arg, len, cctx))
1610 	{
1611 	    // varargs is always the last argument
1612 	    idx = -STACK_FRAME_SIZE - 1;
1613 	    type = cctx->ctx_ufunc->uf_va_type;
1614 	    gen_load = TRUE;
1615 	}
1616 	else
1617 	{
1618 	    idx = lookup_local(*arg, len, cctx);
1619 	    if (idx >= 0)
1620 	    {
1621 		type = (((lvar_T *)cctx->ctx_locals.ga_data) + idx)->lv_type;
1622 		gen_load = TRUE;
1623 	    }
1624 	    else
1625 	    {
1626 		if ((len == 4 && STRNCMP("true", *arg, 4) == 0)
1627 			|| (len == 5 && STRNCMP("false", *arg, 5) == 0))
1628 		    res = generate_PUSHBOOL(cctx, **arg == 't'
1629 						     ? VVAL_TRUE : VVAL_FALSE);
1630 		else
1631 		   res = compile_load_scriptvar(cctx, name);
1632 	    }
1633 	}
1634 	if (gen_load)
1635 	    res = generate_LOAD(cctx, ISN_LOAD, idx, NULL, type);
1636     }
1637 
1638     *arg = end;
1639 
1640 theend:
1641     if (res == FAIL && error)
1642 	semsg(_(e_var_notfound), name);
1643     vim_free(name);
1644     return res;
1645 }
1646 
1647 /*
1648  * Compile the argument expressions.
1649  * "arg" points to just after the "(" and is advanced to after the ")"
1650  */
1651     static int
1652 compile_arguments(char_u **arg, cctx_T *cctx, int *argcount)
1653 {
1654     char_u *p = *arg;
1655 
1656     while (*p != NUL && *p != ')')
1657     {
1658 	if (compile_expr1(&p, cctx) == FAIL)
1659 	    return FAIL;
1660 	++*argcount;
1661 	if (*p == ',')
1662 	    p = skipwhite(p + 1);
1663     }
1664     if (*p != ')')
1665     {
1666 	emsg(_(e_missing_close));
1667 	return FAIL;
1668     }
1669     *arg = p + 1;
1670     return OK;
1671 }
1672 
1673 /*
1674  * Compile a function call:  name(arg1, arg2)
1675  * "arg" points to "name", "arg + varlen" to the "(".
1676  * "argcount_init" is 1 for "value->method()"
1677  * Instructions:
1678  *	EVAL arg1
1679  *	EVAL arg2
1680  *	BCALL / DCALL / UCALL
1681  */
1682     static int
1683 compile_call(char_u **arg, size_t varlen, cctx_T *cctx, int argcount_init)
1684 {
1685     char_u	*name = *arg;
1686     char_u	*p;
1687     int		argcount = argcount_init;
1688     char_u	namebuf[100];
1689     char_u	fname_buf[FLEN_FIXED + 1];
1690     char_u	*tofree = NULL;
1691     int		error = FCERR_NONE;
1692     ufunc_T	*ufunc;
1693     int		res = FAIL;
1694 
1695     if (varlen >= sizeof(namebuf))
1696     {
1697 	semsg(_("E1011: name too long: %s"), name);
1698 	return FAIL;
1699     }
1700     vim_strncpy(namebuf, *arg, varlen);
1701     name = fname_trans_sid(namebuf, fname_buf, &tofree, &error);
1702 
1703     *arg = skipwhite(*arg + varlen + 1);
1704     if (compile_arguments(arg, cctx, &argcount) == FAIL)
1705 	goto theend;
1706 
1707     if (ASCII_ISLOWER(*name) && name[1] != ':')
1708     {
1709 	int	    idx;
1710 
1711 	// builtin function
1712 	idx = find_internal_func(name);
1713 	if (idx >= 0)
1714 	{
1715 	    res = generate_BCALL(cctx, idx, argcount);
1716 	    goto theend;
1717 	}
1718 	semsg(_(e_unknownfunc), namebuf);
1719     }
1720 
1721     // If we can find the function by name generate the right call.
1722     ufunc = find_func(name, cctx);
1723     if (ufunc != NULL)
1724     {
1725 	res = generate_CALL(cctx, ufunc, argcount);
1726 	goto theend;
1727     }
1728 
1729     // If the name is a variable, load it and use PCALL.
1730     p = namebuf;
1731     if (compile_load(&p, namebuf + varlen, cctx, FALSE) == OK)
1732     {
1733 	res = generate_PCALL(cctx, argcount, FALSE);
1734 	goto theend;
1735     }
1736 
1737     // The function may be defined only later.  Need to figure out at runtime.
1738     res = generate_UCALL(cctx, name, argcount);
1739 
1740 theend:
1741     vim_free(tofree);
1742     return res;
1743 }
1744 
1745 // like NAMESPACE_CHAR but with 'a' and 'l'.
1746 #define VIM9_NAMESPACE_CHAR	(char_u *)"bgstvw"
1747 
1748 /*
1749  * Find the end of a variable or function name.  Unlike find_name_end() this
1750  * does not recognize magic braces.
1751  * Return a pointer to just after the name.  Equal to "arg" if there is no
1752  * valid name.
1753  */
1754     char_u *
1755 to_name_end(char_u *arg)
1756 {
1757     char_u	*p;
1758 
1759     // Quick check for valid starting character.
1760     if (!eval_isnamec1(*arg))
1761 	return arg;
1762 
1763     for (p = arg + 1; *p != NUL && eval_isnamec(*p); MB_PTR_ADV(p))
1764 	// Include a namespace such as "s:var" and "v:var".  But "n:" is not
1765 	// and can be used in slice "[n:]".
1766 	if (*p == ':' && (p != arg + 1
1767 			     || vim_strchr(VIM9_NAMESPACE_CHAR, *arg) == NULL))
1768 	    break;
1769     return p;
1770 }
1771 
1772 /*
1773  * Like to_name_end() but also skip over a list or dict constant.
1774  */
1775     char_u *
1776 to_name_const_end(char_u *arg)
1777 {
1778     char_u	*p = to_name_end(arg);
1779     typval_T	rettv;
1780 
1781     if (p == arg && *arg == '[')
1782     {
1783 
1784 	// Can be "[1, 2, 3]->Func()".
1785 	if (get_list_tv(&p, &rettv, FALSE, FALSE) == FAIL)
1786 	    p = arg;
1787     }
1788     else if (p == arg && *arg == '#' && arg[1] == '{')
1789     {
1790 	++p;
1791 	if (eval_dict(&p, &rettv, FALSE, TRUE) == FAIL)
1792 	    p = arg;
1793     }
1794     else if (p == arg && *arg == '{')
1795     {
1796 	int	    ret = get_lambda_tv(&p, &rettv, FALSE);
1797 
1798 	if (ret == NOTDONE)
1799 	    ret = eval_dict(&p, &rettv, FALSE, FALSE);
1800 	if (ret != OK)
1801 	    p = arg;
1802     }
1803 
1804     return p;
1805 }
1806 
1807     static void
1808 type_mismatch(type_T *expected, type_T *actual)
1809 {
1810     char *tofree1, *tofree2;
1811 
1812     semsg(_("E1013: type mismatch, expected %s but got %s"),
1813 		   type_name(expected, &tofree1), type_name(actual, &tofree2));
1814     vim_free(tofree1);
1815     vim_free(tofree2);
1816 }
1817 
1818 /*
1819  * Check if the expected and actual types match.
1820  */
1821     static int
1822 check_type(type_T *expected, type_T *actual, int give_msg)
1823 {
1824     if (expected->tt_type != VAR_UNKNOWN)
1825     {
1826 	if (expected->tt_type != actual->tt_type)
1827 	{
1828 	    if (give_msg)
1829 		type_mismatch(expected, actual);
1830 	    return FAIL;
1831 	}
1832 	if (expected->tt_type == VAR_DICT || expected->tt_type == VAR_LIST)
1833 	{
1834 	    int ret = check_type(expected->tt_member, actual->tt_member,
1835 									FALSE);
1836 	    if (ret == FAIL && give_msg)
1837 		type_mismatch(expected, actual);
1838 	    return ret;
1839 	}
1840     }
1841     return OK;
1842 }
1843 
1844 /*
1845  * Check that
1846  * - "actual" is "expected" type or
1847  * - "actual" is a type that can be "expected" type: add a runtime check; or
1848  * - return FAIL.
1849  */
1850     static int
1851 need_type(type_T *actual, type_T *expected, int offset, cctx_T *cctx)
1852 {
1853     if (equal_type(actual, expected) || expected->tt_type == VAR_UNKNOWN)
1854 	return OK;
1855     if (actual->tt_type != VAR_UNKNOWN)
1856     {
1857 	type_mismatch(expected, actual);
1858 	return FAIL;
1859     }
1860     generate_TYPECHECK(cctx, expected, offset);
1861     return OK;
1862 }
1863 
1864 /*
1865  * parse a list: [expr, expr]
1866  * "*arg" points to the '['.
1867  */
1868     static int
1869 compile_list(char_u **arg, cctx_T *cctx)
1870 {
1871     char_u	*p = skipwhite(*arg + 1);
1872     int		count = 0;
1873 
1874     while (*p != ']')
1875     {
1876 	if (*p == NUL)
1877 	    return FAIL;
1878 	if (compile_expr1(&p, cctx) == FAIL)
1879 	    break;
1880 	++count;
1881 	if (*p == ',')
1882 	    ++p;
1883 	p = skipwhite(p);
1884     }
1885     *arg = p + 1;
1886 
1887     generate_NEWLIST(cctx, count);
1888     return OK;
1889 }
1890 
1891 /*
1892  * parse a lambda: {arg, arg -> expr}
1893  * "*arg" points to the '{'.
1894  */
1895     static int
1896 compile_lambda(char_u **arg, cctx_T *cctx)
1897 {
1898     garray_T	*instr = &cctx->ctx_instr;
1899     typval_T	rettv;
1900     ufunc_T	*ufunc;
1901 
1902     // Get the funcref in "rettv".
1903     if (get_lambda_tv(arg, &rettv, TRUE) == FAIL)
1904 	return FAIL;
1905     ufunc = rettv.vval.v_partial->pt_func;
1906 
1907     // The function will have one line: "return {expr}".
1908     // Compile it into instructions.
1909     compile_def_function(ufunc, TRUE);
1910 
1911     if (ufunc->uf_dfunc_idx >= 0)
1912     {
1913 	if (ga_grow(instr, 1) == FAIL)
1914 	    return FAIL;
1915 	generate_FUNCREF(cctx, ufunc->uf_dfunc_idx);
1916 	return OK;
1917     }
1918     return FAIL;
1919 }
1920 
1921 /*
1922  * Compile a lamda call: expr->{lambda}(args)
1923  * "arg" points to the "{".
1924  */
1925     static int
1926 compile_lambda_call(char_u **arg, cctx_T *cctx)
1927 {
1928     ufunc_T	*ufunc;
1929     typval_T	rettv;
1930     int		argcount = 1;
1931     int		ret = FAIL;
1932 
1933     // Get the funcref in "rettv".
1934     if (get_lambda_tv(arg, &rettv, TRUE) == FAIL)
1935 	return FAIL;
1936 
1937     if (**arg != '(')
1938     {
1939 	if (*skipwhite(*arg) == '(')
1940 	    semsg(_(e_nowhitespace));
1941 	else
1942 	    semsg(_(e_missing_paren), "lambda");
1943 	clear_tv(&rettv);
1944 	return FAIL;
1945     }
1946 
1947     // The function will have one line: "return {expr}".
1948     // Compile it into instructions.
1949     ufunc = rettv.vval.v_partial->pt_func;
1950     ++ufunc->uf_refcount;
1951     compile_def_function(ufunc, TRUE);
1952 
1953     // compile the arguments
1954     *arg = skipwhite(*arg + 1);
1955     if (compile_arguments(arg, cctx, &argcount) == OK)
1956 	// call the compiled function
1957 	ret = generate_CALL(cctx, ufunc, argcount);
1958 
1959     clear_tv(&rettv);
1960     return ret;
1961 }
1962 
1963 /*
1964  * parse a dict: {'key': val} or #{key: val}
1965  * "*arg" points to the '{'.
1966  */
1967     static int
1968 compile_dict(char_u **arg, cctx_T *cctx, int literal)
1969 {
1970     garray_T	*instr = &cctx->ctx_instr;
1971     int		count = 0;
1972     dict_T	*d = dict_alloc();
1973     dictitem_T	*item;
1974 
1975     if (d == NULL)
1976 	return FAIL;
1977     *arg = skipwhite(*arg + 1);
1978     while (**arg != '}' && **arg != NUL)
1979     {
1980 	char_u *key = NULL;
1981 
1982 	if (literal)
1983 	{
1984 	    char_u *p = to_name_end(*arg);
1985 
1986 	    if (p == *arg)
1987 	    {
1988 		semsg(_("E1014: Invalid key: %s"), *arg);
1989 		return FAIL;
1990 	    }
1991 	    key = vim_strnsave(*arg, p - *arg);
1992 	    if (generate_PUSHS(cctx, key) == FAIL)
1993 		return FAIL;
1994 	    *arg = p;
1995 	}
1996 	else
1997 	{
1998 	    isn_T		*isn;
1999 
2000 	    if (compile_expr1(arg, cctx) == FAIL)
2001 		return FAIL;
2002 	    // TODO: check type is string
2003 	    isn = ((isn_T *)instr->ga_data) + instr->ga_len - 1;
2004 	    if (isn->isn_type == ISN_PUSHS)
2005 		key = isn->isn_arg.string;
2006 	}
2007 
2008 	// Check for duplicate keys, if using string keys.
2009 	if (key != NULL)
2010 	{
2011 	    item = dict_find(d, key, -1);
2012 	    if (item != NULL)
2013 	    {
2014 		semsg(_(e_duplicate_key), key);
2015 		goto failret;
2016 	    }
2017 	    item = dictitem_alloc(key);
2018 	    if (item != NULL)
2019 	    {
2020 		item->di_tv.v_type = VAR_UNKNOWN;
2021 		item->di_tv.v_lock = 0;
2022 		if (dict_add(d, item) == FAIL)
2023 		    dictitem_free(item);
2024 	    }
2025 	}
2026 
2027 	*arg = skipwhite(*arg);
2028 	if (**arg != ':')
2029 	{
2030 	    semsg(_(e_missing_dict_colon), *arg);
2031 	    return FAIL;
2032 	}
2033 
2034 	*arg = skipwhite(*arg + 1);
2035 	if (compile_expr1(arg, cctx) == FAIL)
2036 	    return FAIL;
2037 	++count;
2038 
2039 	if (**arg == '}')
2040 	    break;
2041 	if (**arg != ',')
2042 	{
2043 	    semsg(_(e_missing_dict_comma), *arg);
2044 	    goto failret;
2045 	}
2046 	*arg = skipwhite(*arg + 1);
2047     }
2048 
2049     if (**arg != '}')
2050     {
2051 	semsg(_(e_missing_dict_end), *arg);
2052 	goto failret;
2053     }
2054     *arg = *arg + 1;
2055 
2056     dict_unref(d);
2057     return generate_NEWDICT(cctx, count);
2058 
2059 failret:
2060     dict_unref(d);
2061     return FAIL;
2062 }
2063 
2064 /*
2065  * Compile "&option".
2066  */
2067     static int
2068 compile_get_option(char_u **arg, cctx_T *cctx)
2069 {
2070     typval_T	rettv;
2071     char_u	*start = *arg;
2072     int		ret;
2073 
2074     // parse the option and get the current value to get the type.
2075     rettv.v_type = VAR_UNKNOWN;
2076     ret = get_option_tv(arg, &rettv, TRUE);
2077     if (ret == OK)
2078     {
2079 	// include the '&' in the name, get_option_tv() expects it.
2080 	char_u *name = vim_strnsave(start, *arg - start);
2081 	type_T	*type = rettv.v_type == VAR_NUMBER ? &t_number : &t_string;
2082 
2083 	ret = generate_LOAD(cctx, ISN_LOADOPT, 0, name, type);
2084 	vim_free(name);
2085     }
2086     clear_tv(&rettv);
2087 
2088     return ret;
2089 }
2090 
2091 /*
2092  * Compile "$VAR".
2093  */
2094     static int
2095 compile_get_env(char_u **arg, cctx_T *cctx)
2096 {
2097     char_u	*start = *arg;
2098     int		len;
2099     int		ret;
2100     char_u	*name;
2101 
2102     ++*arg;
2103     len = get_env_len(arg);
2104     if (len == 0)
2105     {
2106 	semsg(_(e_syntax_at), start - 1);
2107 	return FAIL;
2108     }
2109 
2110     // include the '$' in the name, get_env_tv() expects it.
2111     name = vim_strnsave(start, len + 1);
2112     ret = generate_LOAD(cctx, ISN_LOADENV, 0, name, &t_string);
2113     vim_free(name);
2114     return ret;
2115 }
2116 
2117 /*
2118  * Compile "@r".
2119  */
2120     static int
2121 compile_get_register(char_u **arg, cctx_T *cctx)
2122 {
2123     int		ret;
2124 
2125     ++*arg;
2126     if (**arg == NUL)
2127     {
2128 	semsg(_(e_syntax_at), *arg - 1);
2129 	return FAIL;
2130     }
2131     if (!valid_yank_reg(**arg, TRUE))
2132     {
2133 	emsg_invreg(**arg);
2134 	return FAIL;
2135     }
2136     ret = generate_LOAD(cctx, ISN_LOADREG, **arg, NULL, &t_string);
2137     ++*arg;
2138     return ret;
2139 }
2140 
2141 /*
2142  * Apply leading '!', '-' and '+' to constant "rettv".
2143  */
2144     static int
2145 apply_leader(typval_T *rettv, char_u *start, char_u *end)
2146 {
2147     char_u *p = end;
2148 
2149     // this works from end to start
2150     while (p > start)
2151     {
2152 	--p;
2153 	if (*p == '-' || *p == '+')
2154 	{
2155 	    // only '-' has an effect, for '+' we only check the type
2156 #ifdef FEAT_FLOAT
2157 	    if (rettv->v_type == VAR_FLOAT)
2158 	    {
2159 		if (*p == '-')
2160 		    rettv->vval.v_float = -rettv->vval.v_float;
2161 	    }
2162 	    else
2163 #endif
2164 	    {
2165 		varnumber_T	val;
2166 		int		error = FALSE;
2167 
2168 		// tv_get_number_chk() accepts a string, but we don't want that
2169 		// here
2170 		if (check_not_string(rettv) == FAIL)
2171 		    return FAIL;
2172 		val = tv_get_number_chk(rettv, &error);
2173 		clear_tv(rettv);
2174 		if (error)
2175 		    return FAIL;
2176 		if (*p == '-')
2177 		    val = -val;
2178 		rettv->v_type = VAR_NUMBER;
2179 		rettv->vval.v_number = val;
2180 	    }
2181 	}
2182 	else
2183 	{
2184 	    int v = tv2bool(rettv);
2185 
2186 	    // '!' is permissive in the type.
2187 	    clear_tv(rettv);
2188 	    rettv->v_type = VAR_BOOL;
2189 	    rettv->vval.v_number = v ? VVAL_FALSE : VVAL_TRUE;
2190 	}
2191     }
2192     return OK;
2193 }
2194 
2195 /*
2196  * Recognize v: variables that are constants and set "rettv".
2197  */
2198     static void
2199 get_vim_constant(char_u **arg, typval_T *rettv)
2200 {
2201     if (STRNCMP(*arg, "v:true", 6) == 0)
2202     {
2203 	rettv->v_type = VAR_BOOL;
2204 	rettv->vval.v_number = VVAL_TRUE;
2205 	*arg += 6;
2206     }
2207     else if (STRNCMP(*arg, "v:false", 7) == 0)
2208     {
2209 	rettv->v_type = VAR_BOOL;
2210 	rettv->vval.v_number = VVAL_FALSE;
2211 	*arg += 7;
2212     }
2213     else if (STRNCMP(*arg, "v:null", 6) == 0)
2214     {
2215 	rettv->v_type = VAR_SPECIAL;
2216 	rettv->vval.v_number = VVAL_NULL;
2217 	*arg += 6;
2218     }
2219     else if (STRNCMP(*arg, "v:none", 6) == 0)
2220     {
2221 	rettv->v_type = VAR_SPECIAL;
2222 	rettv->vval.v_number = VVAL_NONE;
2223 	*arg += 6;
2224     }
2225 }
2226 
2227 /*
2228  * Compile code to apply '-', '+' and '!'.
2229  */
2230     static int
2231 compile_leader(cctx_T *cctx, char_u *start, char_u *end)
2232 {
2233     char_u	*p = end;
2234 
2235     // this works from end to start
2236     while (p > start)
2237     {
2238 	--p;
2239 	if (*p == '-' || *p == '+')
2240 	{
2241 	    int	    negate = *p == '-';
2242 	    isn_T   *isn;
2243 
2244 	    // TODO: check type
2245 	    while (p > start && (p[-1] == '-' || p[-1] == '+'))
2246 	    {
2247 		--p;
2248 		if (*p == '-')
2249 		    negate = !negate;
2250 	    }
2251 	    // only '-' has an effect, for '+' we only check the type
2252 	    if (negate)
2253 		isn = generate_instr(cctx, ISN_NEGATENR);
2254 	    else
2255 		isn = generate_instr(cctx, ISN_CHECKNR);
2256 	    if (isn == NULL)
2257 		return FAIL;
2258 	}
2259 	else
2260 	{
2261 	    int  invert = TRUE;
2262 
2263 	    while (p > start && p[-1] == '!')
2264 	    {
2265 		--p;
2266 		invert = !invert;
2267 	    }
2268 	    if (generate_2BOOL(cctx, invert) == FAIL)
2269 		return FAIL;
2270 	}
2271     }
2272     return OK;
2273 }
2274 
2275 /*
2276  * Compile whatever comes after "name" or "name()".
2277  */
2278     static int
2279 compile_subscript(
2280 	char_u **arg,
2281 	cctx_T *cctx,
2282 	char_u **start_leader,
2283 	char_u *end_leader)
2284 {
2285     for (;;)
2286     {
2287 	if (**arg == '(')
2288 	{
2289 	    int	    argcount = 0;
2290 
2291 	    // funcref(arg)
2292 	    *arg = skipwhite(*arg + 1);
2293 	    if (compile_arguments(arg, cctx, &argcount) == FAIL)
2294 		return FAIL;
2295 	    if (generate_PCALL(cctx, argcount, TRUE) == FAIL)
2296 		return FAIL;
2297 	}
2298 	else if (**arg == '-' && (*arg)[1] == '>')
2299 	{
2300 	    char_u *p;
2301 
2302 	    // something->method()
2303 	    // Apply the '!', '-' and '+' first:
2304 	    //   -1.0->func() works like (-1.0)->func()
2305 	    if (compile_leader(cctx, *start_leader, end_leader) == FAIL)
2306 		return FAIL;
2307 	    *start_leader = end_leader;   // don't apply again later
2308 
2309 	    *arg = skipwhite(*arg + 2);
2310 	    if (**arg == '{')
2311 	    {
2312 		// lambda call:  list->{lambda}
2313 		if (compile_lambda_call(arg, cctx) == FAIL)
2314 		    return FAIL;
2315 	    }
2316 	    else
2317 	    {
2318 		// method call:  list->method()
2319 		for (p = *arg; eval_isnamec1(*p); ++p)
2320 		    ;
2321 		if (*p != '(')
2322 		{
2323 		    semsg(_(e_missing_paren), arg);
2324 		    return FAIL;
2325 		}
2326 		// TODO: base value may not be the first argument
2327 		if (compile_call(arg, p - *arg, cctx, 1) == FAIL)
2328 		    return FAIL;
2329 	    }
2330 	}
2331 	else if (**arg == '[')
2332 	{
2333 	    // list index: list[123]
2334 	    // TODO: more arguments
2335 	    // TODO: dict member  dict['name']
2336 	    *arg = skipwhite(*arg + 1);
2337 	    if (compile_expr1(arg, cctx) == FAIL)
2338 		return FAIL;
2339 
2340 	    if (**arg != ']')
2341 	    {
2342 		emsg(_(e_missbrac));
2343 		return FAIL;
2344 	    }
2345 	    *arg = *arg + 1;
2346 
2347 	    if (generate_instr_drop(cctx, ISN_INDEX, 1) == FAIL)
2348 		return FAIL;
2349 	}
2350 	else if (**arg == '.' && (*arg)[1] != '.')
2351 	{
2352 	    char_u *p;
2353 
2354 	    ++*arg;
2355 	    p = *arg;
2356 	    // dictionary member: dict.name
2357 	    if (eval_isnamec1(*p))
2358 		while (eval_isnamec(*p))
2359 		    MB_PTR_ADV(p);
2360 	    if (p == *arg)
2361 	    {
2362 		semsg(_(e_syntax_at), *arg);
2363 		return FAIL;
2364 	    }
2365 	    // TODO: check type is dict
2366 	    if (generate_MEMBER(cctx, *arg, p - *arg) == FAIL)
2367 		return FAIL;
2368 	    *arg = p;
2369 	}
2370 	else
2371 	    break;
2372     }
2373 
2374     // TODO - see handle_subscript():
2375     // Turn "dict.Func" into a partial for "Func" bound to "dict".
2376     // Don't do this when "Func" is already a partial that was bound
2377     // explicitly (pt_auto is FALSE).
2378 
2379     return OK;
2380 }
2381 
2382 /*
2383  * Compile an expression at "*p" and add instructions to "instr".
2384  * "p" is advanced until after the expression, skipping white space.
2385  *
2386  * This is the equivalent of eval1(), eval2(), etc.
2387  */
2388 
2389 /*
2390  *  number		number constant
2391  *  0zFFFFFFFF		Blob constant
2392  *  "string"		string constant
2393  *  'string'		literal string constant
2394  *  &option-name	option value
2395  *  @r			register contents
2396  *  identifier		variable value
2397  *  function()		function call
2398  *  $VAR		environment variable
2399  *  (expression)	nested expression
2400  *  [expr, expr]	List
2401  *  {key: val, key: val}   Dictionary
2402  *  #{key: val, key: val}  Dictionary with literal keys
2403  *
2404  *  Also handle:
2405  *  ! in front		logical NOT
2406  *  - in front		unary minus
2407  *  + in front		unary plus (ignored)
2408  *  trailing (arg)	funcref/partial call
2409  *  trailing []		subscript in String or List
2410  *  trailing .name	entry in Dictionary
2411  *  trailing ->name()	method call
2412  */
2413     static int
2414 compile_expr7(char_u **arg, cctx_T *cctx)
2415 {
2416     typval_T	rettv;
2417     char_u	*start_leader, *end_leader;
2418     int		ret = OK;
2419 
2420     /*
2421      * Skip '!', '-' and '+' characters.  They are handled later.
2422      */
2423     start_leader = *arg;
2424     while (**arg == '!' || **arg == '-' || **arg == '+')
2425 	*arg = skipwhite(*arg + 1);
2426     end_leader = *arg;
2427 
2428     rettv.v_type = VAR_UNKNOWN;
2429     switch (**arg)
2430     {
2431 	/*
2432 	 * Number constant.
2433 	 */
2434 	case '0':	// also for blob starting with 0z
2435 	case '1':
2436 	case '2':
2437 	case '3':
2438 	case '4':
2439 	case '5':
2440 	case '6':
2441 	case '7':
2442 	case '8':
2443 	case '9':
2444 	case '.':   if (get_number_tv(arg, &rettv, TRUE, FALSE) == FAIL)
2445 			return FAIL;
2446 		    break;
2447 
2448 	/*
2449 	 * String constant: "string".
2450 	 */
2451 	case '"':   if (get_string_tv(arg, &rettv, TRUE) == FAIL)
2452 			return FAIL;
2453 		    break;
2454 
2455 	/*
2456 	 * Literal string constant: 'str''ing'.
2457 	 */
2458 	case '\'':  if (get_lit_string_tv(arg, &rettv, TRUE) == FAIL)
2459 			return FAIL;
2460 		    break;
2461 
2462 	/*
2463 	 * Constant Vim variable.
2464 	 */
2465 	case 'v':   get_vim_constant(arg, &rettv);
2466 		    ret = NOTDONE;
2467 		    break;
2468 
2469 	/*
2470 	 * List: [expr, expr]
2471 	 */
2472 	case '[':   ret = compile_list(arg, cctx);
2473 		    break;
2474 
2475 	/*
2476 	 * Dictionary: #{key: val, key: val}
2477 	 */
2478 	case '#':   if ((*arg)[1] == '{')
2479 		    {
2480 			++*arg;
2481 			ret = compile_dict(arg, cctx, TRUE);
2482 		    }
2483 		    else
2484 			ret = NOTDONE;
2485 		    break;
2486 
2487 	/*
2488 	 * Lambda: {arg, arg -> expr}
2489 	 * Dictionary: {'key': val, 'key': val}
2490 	 */
2491 	case '{':   {
2492 			char_u *start = skipwhite(*arg + 1);
2493 
2494 			// Find out what comes after the arguments.
2495 			ret = get_function_args(&start, '-', NULL,
2496 						       NULL, NULL, NULL, TRUE);
2497 			if (ret != FAIL && *start == '>')
2498 			    ret = compile_lambda(arg, cctx);
2499 			else
2500 			    ret = compile_dict(arg, cctx, FALSE);
2501 		    }
2502 		    break;
2503 
2504 	/*
2505 	 * Option value: &name
2506 	 */
2507 	case '&':	ret = compile_get_option(arg, cctx);
2508 			break;
2509 
2510 	/*
2511 	 * Environment variable: $VAR.
2512 	 */
2513 	case '$':	ret = compile_get_env(arg, cctx);
2514 			break;
2515 
2516 	/*
2517 	 * Register contents: @r.
2518 	 */
2519 	case '@':	ret = compile_get_register(arg, cctx);
2520 			break;
2521 	/*
2522 	 * nested expression: (expression).
2523 	 */
2524 	case '(':   *arg = skipwhite(*arg + 1);
2525 		    ret = compile_expr1(arg, cctx);	// recursive!
2526 		    *arg = skipwhite(*arg);
2527 		    if (**arg == ')')
2528 			++*arg;
2529 		    else if (ret == OK)
2530 		    {
2531 			emsg(_(e_missing_close));
2532 			ret = FAIL;
2533 		    }
2534 		    break;
2535 
2536 	default:    ret = NOTDONE;
2537 		    break;
2538     }
2539     if (ret == FAIL)
2540 	return FAIL;
2541 
2542     if (rettv.v_type != VAR_UNKNOWN)
2543     {
2544 	// apply the '!', '-' and '+' before the constant
2545 	if (apply_leader(&rettv, start_leader, end_leader) == FAIL)
2546 	{
2547 	    clear_tv(&rettv);
2548 	    return FAIL;
2549 	}
2550 	start_leader = end_leader;   // don't apply again below
2551 
2552 	// push constant
2553 	switch (rettv.v_type)
2554 	{
2555 	    case VAR_BOOL:
2556 		generate_PUSHBOOL(cctx, rettv.vval.v_number);
2557 		break;
2558 	    case VAR_SPECIAL:
2559 		generate_PUSHSPEC(cctx, rettv.vval.v_number);
2560 		break;
2561 	    case VAR_NUMBER:
2562 		generate_PUSHNR(cctx, rettv.vval.v_number);
2563 		break;
2564 #ifdef FEAT_FLOAT
2565 	    case VAR_FLOAT:
2566 		generate_PUSHF(cctx, rettv.vval.v_float);
2567 		break;
2568 #endif
2569 	    case VAR_BLOB:
2570 		generate_PUSHBLOB(cctx, rettv.vval.v_blob);
2571 		rettv.vval.v_blob = NULL;
2572 		break;
2573 	    case VAR_STRING:
2574 		generate_PUSHS(cctx, rettv.vval.v_string);
2575 		rettv.vval.v_string = NULL;
2576 		break;
2577 	    default:
2578 		iemsg("constant type missing");
2579 		return FAIL;
2580 	}
2581     }
2582     else if (ret == NOTDONE)
2583     {
2584 	char_u	    *p;
2585 	int	    r;
2586 
2587 	if (!eval_isnamec1(**arg))
2588 	{
2589 	    semsg(_("E1015: Name expected: %s"), *arg);
2590 	    return FAIL;
2591 	}
2592 
2593 	// "name" or "name()"
2594 	p = to_name_end(*arg);
2595 	if (*p == '(')
2596 	    r = compile_call(arg, p - *arg, cctx, 0);
2597 	else
2598 	    r = compile_load(arg, p, cctx, TRUE);
2599 	if (r == FAIL)
2600 	    return FAIL;
2601     }
2602 
2603     if (compile_subscript(arg, cctx, &start_leader, end_leader) == FAIL)
2604 	return FAIL;
2605 
2606     // Now deal with prefixed '-', '+' and '!', if not done already.
2607     return compile_leader(cctx, start_leader, end_leader);
2608 }
2609 
2610 /*
2611  *	*	number multiplication
2612  *	/	number division
2613  *	%	number modulo
2614  */
2615     static int
2616 compile_expr6(char_u **arg, cctx_T *cctx)
2617 {
2618     char_u	*op;
2619 
2620     // get the first variable
2621     if (compile_expr7(arg, cctx) == FAIL)
2622 	return FAIL;
2623 
2624     /*
2625      * Repeat computing, until no "*", "/" or "%" is following.
2626      */
2627     for (;;)
2628     {
2629 	op = skipwhite(*arg);
2630 	if (*op != '*' && *op != '/' && *op != '%')
2631 	    break;
2632 	if (!VIM_ISWHITE(**arg) || !VIM_ISWHITE(op[1]))
2633 	{
2634 	    char_u buf[3];
2635 
2636 	    vim_strncpy(buf, op, 1);
2637 	    semsg(_(e_white_both), buf);
2638 	}
2639 	*arg = skipwhite(op + 1);
2640 
2641 	// get the second variable
2642 	if (compile_expr7(arg, cctx) == FAIL)
2643 	    return FAIL;
2644 
2645 	generate_two_op(cctx, op);
2646     }
2647 
2648     return OK;
2649 }
2650 
2651 /*
2652  *      +	number addition
2653  *      -	number subtraction
2654  *      ..	string concatenation
2655  */
2656     static int
2657 compile_expr5(char_u **arg, cctx_T *cctx)
2658 {
2659     char_u	*op;
2660     int		oplen;
2661 
2662     // get the first variable
2663     if (compile_expr6(arg, cctx) == FAIL)
2664 	return FAIL;
2665 
2666     /*
2667      * Repeat computing, until no "+", "-" or ".." is following.
2668      */
2669     for (;;)
2670     {
2671 	op = skipwhite(*arg);
2672 	if (*op != '+' && *op != '-' && !(*op == '.' && (*(*arg + 1) == '.')))
2673 	    break;
2674 	oplen = (*op == '.' ? 2 : 1);
2675 
2676 	if (!VIM_ISWHITE(**arg) || !VIM_ISWHITE(op[oplen]))
2677 	{
2678 	    char_u buf[3];
2679 
2680 	    vim_strncpy(buf, op, oplen);
2681 	    semsg(_(e_white_both), buf);
2682 	}
2683 
2684 	*arg = skipwhite(op + oplen);
2685 
2686 	// get the second variable
2687 	if (compile_expr6(arg, cctx) == FAIL)
2688 	    return FAIL;
2689 
2690 	if (*op == '.')
2691 	{
2692 	    if (may_generate_2STRING(-2, cctx) == FAIL
2693 		    || may_generate_2STRING(-1, cctx) == FAIL)
2694 		return FAIL;
2695 	    generate_instr_drop(cctx, ISN_CONCAT, 1);
2696 	}
2697 	else
2698 	    generate_two_op(cctx, op);
2699     }
2700 
2701     return OK;
2702 }
2703 
2704 /*
2705  * expr5a == expr5b
2706  * expr5a =~ expr5b
2707  * expr5a != expr5b
2708  * expr5a !~ expr5b
2709  * expr5a > expr5b
2710  * expr5a >= expr5b
2711  * expr5a < expr5b
2712  * expr5a <= expr5b
2713  * expr5a is expr5b
2714  * expr5a isnot expr5b
2715  *
2716  * Produces instructions:
2717  *	EVAL expr5a		Push result of "expr5a"
2718  *	EVAL expr5b		Push result of "expr5b"
2719  *	COMPARE			one of the compare instructions
2720  */
2721     static int
2722 compile_expr4(char_u **arg, cctx_T *cctx)
2723 {
2724     exptype_T	type = EXPR_UNKNOWN;
2725     char_u	*p;
2726     int		len = 2;
2727     int		i;
2728     int		type_is = FALSE;
2729 
2730     // get the first variable
2731     if (compile_expr5(arg, cctx) == FAIL)
2732 	return FAIL;
2733 
2734     p = skipwhite(*arg);
2735     switch (p[0])
2736     {
2737 	case '=':   if (p[1] == '=')
2738 			type = EXPR_EQUAL;
2739 		    else if (p[1] == '~')
2740 			type = EXPR_MATCH;
2741 		    break;
2742 	case '!':   if (p[1] == '=')
2743 			type = EXPR_NEQUAL;
2744 		    else if (p[1] == '~')
2745 			type = EXPR_NOMATCH;
2746 		    break;
2747 	case '>':   if (p[1] != '=')
2748 		    {
2749 			type = EXPR_GREATER;
2750 			len = 1;
2751 		    }
2752 		    else
2753 			type = EXPR_GEQUAL;
2754 		    break;
2755 	case '<':   if (p[1] != '=')
2756 		    {
2757 			type = EXPR_SMALLER;
2758 			len = 1;
2759 		    }
2760 		    else
2761 			type = EXPR_SEQUAL;
2762 		    break;
2763 	case 'i':   if (p[1] == 's')
2764 		    {
2765 			// "is" and "isnot"; but not a prefix of a name
2766 			if (p[2] == 'n' && p[3] == 'o' && p[4] == 't')
2767 			    len = 5;
2768 			i = p[len];
2769 			if (!isalnum(i) && i != '_')
2770 			{
2771 			    type = len == 2 ? EXPR_IS : EXPR_ISNOT;
2772 			    type_is = TRUE;
2773 			}
2774 		    }
2775 		    break;
2776     }
2777 
2778     /*
2779      * If there is a comparative operator, use it.
2780      */
2781     if (type != EXPR_UNKNOWN)
2782     {
2783 	int ic = FALSE;  // Default: do not ignore case
2784 
2785 	if (type_is && (p[len] == '?' || p[len] == '#'))
2786 	{
2787 	    semsg(_(e_invexpr2), *arg);
2788 	    return FAIL;
2789 	}
2790 	// extra question mark appended: ignore case
2791 	if (p[len] == '?')
2792 	{
2793 	    ic = TRUE;
2794 	    ++len;
2795 	}
2796 	// extra '#' appended: match case (ignored)
2797 	else if (p[len] == '#')
2798 	    ++len;
2799 	// nothing appended: match case
2800 
2801 	if (!VIM_ISWHITE(**arg) || !VIM_ISWHITE(p[len]))
2802 	{
2803 	    char_u buf[7];
2804 
2805 	    vim_strncpy(buf, p, len);
2806 	    semsg(_(e_white_both), buf);
2807 	}
2808 
2809 	// get the second variable
2810 	*arg = skipwhite(p + len);
2811 	if (compile_expr5(arg, cctx) == FAIL)
2812 	    return FAIL;
2813 
2814 	generate_COMPARE(cctx, type, ic);
2815     }
2816 
2817     return OK;
2818 }
2819 
2820 /*
2821  * Compile || or &&.
2822  */
2823     static int
2824 compile_and_or(char_u **arg, cctx_T *cctx, char *op)
2825 {
2826     char_u	*p = skipwhite(*arg);
2827     int		opchar = *op;
2828 
2829     if (p[0] == opchar && p[1] == opchar)
2830     {
2831 	garray_T	*instr = &cctx->ctx_instr;
2832 	garray_T	end_ga;
2833 
2834 	/*
2835 	 * Repeat until there is no following "||" or "&&"
2836 	 */
2837 	ga_init2(&end_ga, sizeof(int), 10);
2838 	while (p[0] == opchar && p[1] == opchar)
2839 	{
2840 	    if (!VIM_ISWHITE(**arg) || !VIM_ISWHITE(p[2]))
2841 		semsg(_(e_white_both), op);
2842 
2843 	    if (ga_grow(&end_ga, 1) == FAIL)
2844 	    {
2845 		ga_clear(&end_ga);
2846 		return FAIL;
2847 	    }
2848 	    *(((int *)end_ga.ga_data) + end_ga.ga_len) = instr->ga_len;
2849 	    ++end_ga.ga_len;
2850 	    generate_JUMP(cctx, opchar == '|'
2851 			 ?  JUMP_AND_KEEP_IF_TRUE : JUMP_AND_KEEP_IF_FALSE, 0);
2852 
2853 	    // eval the next expression
2854 	    *arg = skipwhite(p + 2);
2855 	    if ((opchar == '|' ? compile_expr3(arg, cctx)
2856 					   : compile_expr4(arg, cctx)) == FAIL)
2857 	    {
2858 		ga_clear(&end_ga);
2859 		return FAIL;
2860 	    }
2861 	    p = skipwhite(*arg);
2862 	}
2863 
2864 	// Fill in the end label in all jumps.
2865 	while (end_ga.ga_len > 0)
2866 	{
2867 	    isn_T	*isn;
2868 
2869 	    --end_ga.ga_len;
2870 	    isn = ((isn_T *)instr->ga_data)
2871 				  + *(((int *)end_ga.ga_data) + end_ga.ga_len);
2872 	    isn->isn_arg.jump.jump_where = instr->ga_len;
2873 	}
2874 	ga_clear(&end_ga);
2875     }
2876 
2877     return OK;
2878 }
2879 
2880 /*
2881  * expr4a && expr4a && expr4a	    logical AND
2882  *
2883  * Produces instructions:
2884  *	EVAL expr4a		Push result of "expr4a"
2885  *	JUMP_AND_KEEP_IF_FALSE end
2886  *	EVAL expr4b		Push result of "expr4b"
2887  *	JUMP_AND_KEEP_IF_FALSE end
2888  *	EVAL expr4c		Push result of "expr4c"
2889  * end:
2890  */
2891     static int
2892 compile_expr3(char_u **arg, cctx_T *cctx)
2893 {
2894     // get the first variable
2895     if (compile_expr4(arg, cctx) == FAIL)
2896 	return FAIL;
2897 
2898     // || and && work almost the same
2899     return compile_and_or(arg, cctx, "&&");
2900 }
2901 
2902 /*
2903  * expr3a || expr3b || expr3c	    logical OR
2904  *
2905  * Produces instructions:
2906  *	EVAL expr3a		Push result of "expr3a"
2907  *	JUMP_AND_KEEP_IF_TRUE end
2908  *	EVAL expr3b		Push result of "expr3b"
2909  *	JUMP_AND_KEEP_IF_TRUE end
2910  *	EVAL expr3c		Push result of "expr3c"
2911  * end:
2912  */
2913     static int
2914 compile_expr2(char_u **arg, cctx_T *cctx)
2915 {
2916     // eval the first expression
2917     if (compile_expr3(arg, cctx) == FAIL)
2918 	return FAIL;
2919 
2920     // || and && work almost the same
2921     return compile_and_or(arg, cctx, "||");
2922 }
2923 
2924 /*
2925  * Toplevel expression: expr2 ? expr1a : expr1b
2926  *
2927  * Produces instructions:
2928  *	EVAL expr2		Push result of "expr"
2929  *      JUMP_IF_FALSE alt	jump if false
2930  *      EVAL expr1a
2931  *      JUMP_ALWAYS end
2932  * alt:	EVAL expr1b
2933  * end:
2934  */
2935     static int
2936 compile_expr1(char_u **arg,  cctx_T *cctx)
2937 {
2938     char_u	*p;
2939 
2940     // evaluate the first expression
2941     if (compile_expr2(arg, cctx) == FAIL)
2942 	return FAIL;
2943 
2944     p = skipwhite(*arg);
2945     if (*p == '?')
2946     {
2947 	garray_T	*instr = &cctx->ctx_instr;
2948 	garray_T	*stack = &cctx->ctx_type_stack;
2949 	int		alt_idx = instr->ga_len;
2950 	int		end_idx;
2951 	isn_T		*isn;
2952 	type_T		*type1;
2953 	type_T		*type2;
2954 
2955 	if (!VIM_ISWHITE(**arg) || !VIM_ISWHITE(p[1]))
2956 	    semsg(_(e_white_both), "?");
2957 
2958 	generate_JUMP(cctx, JUMP_IF_FALSE, 0);
2959 
2960 	// evaluate the second expression; any type is accepted
2961 	*arg = skipwhite(p + 1);
2962 	if (compile_expr1(arg, cctx) == FAIL)
2963 	    return FAIL;
2964 
2965 	// remember the type and drop it
2966 	--stack->ga_len;
2967 	type1 = ((type_T **)stack->ga_data)[stack->ga_len];
2968 
2969 	end_idx = instr->ga_len;
2970 	generate_JUMP(cctx, JUMP_ALWAYS, 0);
2971 
2972 	// jump here from JUMP_IF_FALSE
2973 	isn = ((isn_T *)instr->ga_data) + alt_idx;
2974 	isn->isn_arg.jump.jump_where = instr->ga_len;
2975 
2976 	// Check for the ":".
2977 	p = skipwhite(*arg);
2978 	if (*p != ':')
2979 	{
2980 	    emsg(_(e_missing_colon));
2981 	    return FAIL;
2982 	}
2983 	if (!VIM_ISWHITE(**arg) || !VIM_ISWHITE(p[1]))
2984 	    semsg(_(e_white_both), ":");
2985 
2986 	// evaluate the third expression
2987 	*arg = skipwhite(p + 1);
2988 	if (compile_expr1(arg, cctx) == FAIL)
2989 	    return FAIL;
2990 
2991 	// If the types differ, the result has a more generic type.
2992 	type2 = ((type_T **)stack->ga_data)[stack->ga_len - 1];
2993 	common_type(type1, type2, type2);
2994 
2995 	// jump here from JUMP_ALWAYS
2996 	isn = ((isn_T *)instr->ga_data) + end_idx;
2997 	isn->isn_arg.jump.jump_where = instr->ga_len;
2998     }
2999     return OK;
3000 }
3001 
3002 /*
3003  * compile "return [expr]"
3004  */
3005     static char_u *
3006 compile_return(char_u *arg, int set_return_type, cctx_T *cctx)
3007 {
3008     char_u	*p = arg;
3009     garray_T	*stack = &cctx->ctx_type_stack;
3010     type_T	*stack_type;
3011 
3012     if (*p != NUL && *p != '|' && *p != '\n')
3013     {
3014 	// compile return argument into instructions
3015 	if (compile_expr1(&p, cctx) == FAIL)
3016 	    return NULL;
3017 
3018 	stack_type = ((type_T **)stack->ga_data)[stack->ga_len - 1];
3019 	if (set_return_type)
3020 	    cctx->ctx_ufunc->uf_ret_type = stack_type;
3021 	else if (need_type(stack_type, cctx->ctx_ufunc->uf_ret_type, -1, cctx)
3022 								       == FAIL)
3023 	    return NULL;
3024     }
3025     else
3026     {
3027 	if (set_return_type)
3028 	    cctx->ctx_ufunc->uf_ret_type = &t_void;
3029 	else if (cctx->ctx_ufunc->uf_ret_type->tt_type != VAR_VOID)
3030 	{
3031 	    emsg(_("E1003: Missing return value"));
3032 	    return NULL;
3033 	}
3034 
3035 	// No argument, return zero.
3036 	generate_PUSHNR(cctx, 0);
3037     }
3038 
3039     if (generate_instr(cctx, ISN_RETURN) == NULL)
3040 	return NULL;
3041 
3042     // "return val | endif" is possible
3043     return skipwhite(p);
3044 }
3045 
3046 /*
3047  * Return the length of an assignment operator, or zero if there isn't one.
3048  */
3049     int
3050 assignment_len(char_u *p, int *heredoc)
3051 {
3052     if (*p == '=')
3053     {
3054 	if (p[1] == '<' && p[2] == '<')
3055 	{
3056 	    *heredoc = TRUE;
3057 	    return 3;
3058 	}
3059 	return 1;
3060     }
3061     if (vim_strchr((char_u *)"+-*/%", *p) != NULL && p[1] == '=')
3062 	return 2;
3063     if (STRNCMP(p, "..=", 3) == 0)
3064 	return 3;
3065     return 0;
3066 }
3067 
3068 // words that cannot be used as a variable
3069 static char *reserved[] = {
3070     "true",
3071     "false",
3072     NULL
3073 };
3074 
3075 /*
3076  * Get a line for "=<<".
3077  * Return a pointer to the line in allocated memory.
3078  * Return NULL for end-of-file or some error.
3079  */
3080     static char_u *
3081 heredoc_getline(
3082 	int c UNUSED,
3083 	void *cookie,
3084 	int indent UNUSED,
3085 	int do_concat UNUSED)
3086 {
3087     cctx_T  *cctx = (cctx_T *)cookie;
3088 
3089     if (cctx->ctx_lnum == cctx->ctx_ufunc->uf_lines.ga_len)
3090 	NULL;
3091     ++cctx->ctx_lnum;
3092     return vim_strsave(((char_u **)cctx->ctx_ufunc->uf_lines.ga_data)
3093 							     [cctx->ctx_lnum]);
3094 }
3095 
3096 typedef enum {
3097     dest_local,
3098     dest_option,
3099     dest_env,
3100     dest_global,
3101     dest_vimvar,
3102     dest_script,
3103     dest_reg,
3104 } assign_dest_T;
3105 
3106 /*
3107  * compile "let var [= expr]", "const var = expr" and "var = expr"
3108  * "arg" points to "var".
3109  */
3110     static char_u *
3111 compile_assignment(char_u *arg, exarg_T *eap, cmdidx_T cmdidx, cctx_T *cctx)
3112 {
3113     char_u	*p;
3114     char_u	*ret = NULL;
3115     int		var_count = 0;
3116     int		semicolon = 0;
3117     size_t	varlen;
3118     garray_T	*instr = &cctx->ctx_instr;
3119     int		idx = -1;
3120     char_u	*op;
3121     int		opt_type;
3122     assign_dest_T dest = dest_local;
3123     int		opt_flags = 0;
3124     int		vimvaridx = -1;
3125     int		oplen = 0;
3126     int		heredoc = FALSE;
3127     type_T	*type;
3128     lvar_T	*lvar;
3129     char_u	*name;
3130     char_u	*sp;
3131     int		has_type = FALSE;
3132     int		is_decl = cmdidx == CMD_let || cmdidx == CMD_const;
3133     int		instr_count = -1;
3134 
3135     p = skip_var_list(arg, FALSE, &var_count, &semicolon);
3136     if (p == NULL)
3137 	return NULL;
3138     if (var_count > 0)
3139     {
3140 	// TODO: let [var, var] = list
3141 	emsg("Cannot handle a list yet");
3142 	return NULL;
3143     }
3144 
3145     varlen = p - arg;
3146     name = vim_strnsave(arg, (int)varlen);
3147     if (name == NULL)
3148 	return NULL;
3149 
3150     if (*arg == '&')
3151     {
3152 	int	    cc;
3153 	long	    numval;
3154 	char_u	    *stringval = NULL;
3155 
3156 	dest = dest_option;
3157 	if (cmdidx == CMD_const)
3158 	{
3159 	    emsg(_(e_const_option));
3160 	    return NULL;
3161 	}
3162 	if (is_decl)
3163 	{
3164 	    semsg(_("E1052: Cannot declare an option: %s"), arg);
3165 	    goto theend;
3166 	}
3167 	p = arg;
3168 	p = find_option_end(&p, &opt_flags);
3169 	if (p == NULL)
3170 	{
3171 	    emsg(_(e_letunexp));
3172 	    return NULL;
3173 	}
3174 	cc = *p;
3175 	*p = NUL;
3176 	opt_type = get_option_value(arg + 1, &numval, &stringval, opt_flags);
3177 	*p = cc;
3178 	if (opt_type == -3)
3179 	{
3180 	    semsg(_(e_unknown_option), *arg);
3181 	    return NULL;
3182 	}
3183 	if (opt_type == -2 || opt_type == 0)
3184 	    type = &t_string;
3185 	else
3186 	    type = &t_number;	// both number and boolean option
3187     }
3188     else if (*arg == '$')
3189     {
3190 	dest = dest_env;
3191 	if (is_decl)
3192 	{
3193 	    semsg(_("E1065: Cannot declare an environment variable: %s"), name);
3194 	    goto theend;
3195 	}
3196     }
3197     else if (*arg == '@')
3198     {
3199 	if (!valid_yank_reg(arg[1], TRUE))
3200 	{
3201 	    emsg_invreg(arg[1]);
3202 	    return FAIL;
3203 	}
3204 	dest = dest_reg;
3205 	if (is_decl)
3206 	{
3207 	    semsg(_("E1066: Cannot declare a register: %s"), name);
3208 	    goto theend;
3209 	}
3210     }
3211     else if (STRNCMP(arg, "g:", 2) == 0)
3212     {
3213 	dest = dest_global;
3214 	if (is_decl)
3215 	{
3216 	    semsg(_("E1016: Cannot declare a global variable: %s"), name);
3217 	    goto theend;
3218 	}
3219     }
3220     else if (STRNCMP(arg, "v:", 2) == 0)
3221     {
3222 	vimvaridx = find_vim_var(name + 2);
3223 	if (vimvaridx < 0)
3224 	{
3225 	    semsg(_(e_var_notfound), arg);
3226 	    goto theend;
3227 	}
3228 	dest = dest_vimvar;
3229 	if (is_decl)
3230 	{
3231 	    semsg(_("E1064: Cannot declare a v: variable: %s"), name);
3232 	    goto theend;
3233 	}
3234     }
3235     else
3236     {
3237 	for (idx = 0; reserved[idx] != NULL; ++idx)
3238 	    if (STRCMP(reserved[idx], name) == 0)
3239 	    {
3240 		semsg(_("E1034: Cannot use reserved name %s"), name);
3241 		goto theend;
3242 	    }
3243 
3244 	idx = lookup_local(arg, varlen, cctx);
3245 	if (idx >= 0)
3246 	{
3247 	    if (is_decl)
3248 	    {
3249 		semsg(_("E1017: Variable already declared: %s"), name);
3250 		goto theend;
3251 	    }
3252 	    else
3253 	    {
3254 		lvar = ((lvar_T *)cctx->ctx_locals.ga_data) + idx;
3255 		if (lvar->lv_const)
3256 		{
3257 		    semsg(_("E1018: Cannot assign to a constant: %s"), name);
3258 		    goto theend;
3259 		}
3260 	    }
3261 	}
3262 	else if ((STRNCMP(arg, "s:", 2) == 0
3263 		    ? lookup_script(arg + 2, varlen - 2)
3264 		    : lookup_script(arg, varlen)) == OK
3265 				   || find_imported(arg, varlen, cctx) != NULL)
3266 	{
3267 	    dest = dest_script;
3268 	    if (is_decl)
3269 	    {
3270 		semsg(_("E1054: Variable already declared in the script: %s"),
3271 									 name);
3272 		goto theend;
3273 	    }
3274 	}
3275     }
3276 
3277     if (dest != dest_option)
3278     {
3279 	if (is_decl && *p == ':')
3280 	{
3281 	    // parse optional type: "let var: type = expr"
3282 	    p = skipwhite(p + 1);
3283 	    type = parse_type(&p, cctx->ctx_type_list);
3284 	    if (type == NULL)
3285 		goto theend;
3286 	    has_type = TRUE;
3287 	}
3288 	else if (idx < 0)
3289 	{
3290 	    // global and new local default to "any" type
3291 	    type = &t_any;
3292 	}
3293 	else
3294 	{
3295 	    lvar = ((lvar_T *)cctx->ctx_locals.ga_data) + idx;
3296 	    type = lvar->lv_type;
3297 	}
3298     }
3299 
3300     sp = p;
3301     p = skipwhite(p);
3302     op = p;
3303     oplen = assignment_len(p, &heredoc);
3304     if (oplen > 0 && (!VIM_ISWHITE(*sp) || !VIM_ISWHITE(op[oplen])))
3305     {
3306 	char_u  buf[4];
3307 
3308 	vim_strncpy(buf, op, oplen);
3309 	semsg(_(e_white_both), buf);
3310     }
3311 
3312     if (oplen == 3 && !heredoc && dest != dest_global
3313 	    && type->tt_type != VAR_STRING && type->tt_type != VAR_UNKNOWN)
3314     {
3315 	emsg("E1019: Can only concatenate to string");
3316 	goto theend;
3317     }
3318 
3319     // +=, /=, etc. require an existing variable
3320     if (idx < 0 && dest == dest_local)
3321     {
3322 	if (oplen > 1 && !heredoc)
3323 	{
3324 	    semsg(_("E1020: cannot use an operator on a new variable: %s"),
3325 									 name);
3326 	    goto theend;
3327 	}
3328 
3329 	// new local variable
3330 	idx = reserve_local(cctx, arg, varlen, cmdidx == CMD_const, type);
3331 	if (idx < 0)
3332 	    goto theend;
3333     }
3334 
3335     if (heredoc)
3336     {
3337 	list_T	   *l;
3338 	listitem_T *li;
3339 
3340 	// [let] varname =<< [trim] {end}
3341 	eap->getline = heredoc_getline;
3342 	eap->cookie = cctx;
3343 	l = heredoc_get(eap, op + 3);
3344 
3345 	// Push each line and the create the list.
3346 	for (li = l->lv_first; li != NULL; li = li->li_next)
3347 	{
3348 	    generate_PUSHS(cctx, li->li_tv.vval.v_string);
3349 	    li->li_tv.vval.v_string = NULL;
3350 	}
3351 	generate_NEWLIST(cctx, l->lv_len);
3352 	type = &t_list_string;
3353 	list_free(l);
3354 	p += STRLEN(p);
3355     }
3356     else if (oplen > 0)
3357     {
3358 	// for "+=", "*=", "..=" etc. first load the current value
3359 	if (*op != '=')
3360 	{
3361 	    switch (dest)
3362 	    {
3363 		case dest_option:
3364 		    // TODO: check the option exists
3365 		    generate_LOAD(cctx, ISN_LOADOPT, 0, name + 1, type);
3366 		    break;
3367 		case dest_global:
3368 		    generate_LOAD(cctx, ISN_LOADG, 0, name + 2, type);
3369 		    break;
3370 		case dest_script:
3371 		    compile_load_scriptvar(cctx, name);
3372 		    break;
3373 		case dest_env:
3374 		    // Include $ in the name here
3375 		    generate_LOAD(cctx, ISN_LOADENV, 0, name, type);
3376 		    break;
3377 		case dest_reg:
3378 		    generate_LOAD(cctx, ISN_LOADREG, arg[1], NULL, &t_string);
3379 		    break;
3380 		case dest_vimvar:
3381 		    generate_LOADV(cctx, name + 2, TRUE);
3382 		    break;
3383 		case dest_local:
3384 		    generate_LOAD(cctx, ISN_LOAD, idx, NULL, type);
3385 		    break;
3386 	    }
3387 	}
3388 
3389 	// compile the expression
3390 	instr_count = instr->ga_len;
3391 	p = skipwhite(p + oplen);
3392 	if (compile_expr1(&p, cctx) == FAIL)
3393 	    goto theend;
3394 
3395 	if (idx >= 0 && (is_decl || !has_type))
3396 	{
3397 	    garray_T	*stack = &cctx->ctx_type_stack;
3398 	    type_T	*stacktype =
3399 				((type_T **)stack->ga_data)[stack->ga_len - 1];
3400 
3401 	    lvar = ((lvar_T *)cctx->ctx_locals.ga_data) + idx;
3402 	    if (!has_type)
3403 	    {
3404 		if (stacktype->tt_type == VAR_VOID)
3405 		{
3406 		    emsg(_("E1031: Cannot use void value"));
3407 		    goto theend;
3408 		}
3409 		else
3410 		    lvar->lv_type = stacktype;
3411 	    }
3412 	    else
3413 		if (check_type(lvar->lv_type, stacktype, TRUE) == FAIL)
3414 		    goto theend;
3415 	}
3416     }
3417     else if (cmdidx == CMD_const)
3418     {
3419 	emsg(_("E1021: const requires a value"));
3420 	goto theend;
3421     }
3422     else if (!has_type || dest == dest_option)
3423     {
3424 	emsg(_("E1022: type or initialization required"));
3425 	goto theend;
3426     }
3427     else
3428     {
3429 	// variables are always initialized
3430 	if (ga_grow(instr, 1) == FAIL)
3431 	    goto theend;
3432 	switch (type->tt_type)
3433 	{
3434 	    case VAR_BOOL:
3435 		generate_PUSHBOOL(cctx, VVAL_FALSE);
3436 		break;
3437 	    case VAR_SPECIAL:
3438 		generate_PUSHSPEC(cctx, VVAL_NONE);
3439 		break;
3440 	    case VAR_FLOAT:
3441 #ifdef FEAT_FLOAT
3442 		generate_PUSHF(cctx, 0.0);
3443 #endif
3444 		break;
3445 	    case VAR_STRING:
3446 		generate_PUSHS(cctx, NULL);
3447 		break;
3448 	    case VAR_BLOB:
3449 		generate_PUSHBLOB(cctx, NULL);
3450 		break;
3451 	    case VAR_FUNC:
3452 		// generate_PUSHS(cctx, NULL); TODO
3453 		break;
3454 	    case VAR_PARTIAL:
3455 		// generate_PUSHS(cctx, NULL); TODO
3456 		break;
3457 	    case VAR_LIST:
3458 		generate_NEWLIST(cctx, 0);
3459 		break;
3460 	    case VAR_DICT:
3461 		generate_NEWDICT(cctx, 0);
3462 		break;
3463 	    case VAR_JOB:
3464 		// generate_PUSHS(cctx, NULL); TODO
3465 		break;
3466 	    case VAR_CHANNEL:
3467 		// generate_PUSHS(cctx, NULL); TODO
3468 		break;
3469 	    case VAR_NUMBER:
3470 	    case VAR_UNKNOWN:
3471 	    case VAR_VOID:
3472 		generate_PUSHNR(cctx, 0);
3473 		break;
3474 	}
3475     }
3476 
3477     if (oplen > 0 && *op != '=')
3478     {
3479 	type_T	    *expected = &t_number;
3480 	garray_T    *stack = &cctx->ctx_type_stack;
3481 	type_T	    *stacktype;
3482 
3483 	// TODO: if type is known use float or any operation
3484 
3485 	if (*op == '.')
3486 	    expected = &t_string;
3487 	stacktype = ((type_T **)stack->ga_data)[stack->ga_len - 1];
3488 	if (need_type(stacktype, expected, -1, cctx) == FAIL)
3489 	    goto theend;
3490 
3491 	if (*op == '.')
3492 	    generate_instr_drop(cctx, ISN_CONCAT, 1);
3493 	else
3494 	{
3495 	    isn_T *isn = generate_instr_drop(cctx, ISN_OPNR, 1);
3496 
3497 	    if (isn == NULL)
3498 		goto theend;
3499 	    switch (*op)
3500 	    {
3501 		case '+': isn->isn_arg.op.op_type = EXPR_ADD; break;
3502 		case '-': isn->isn_arg.op.op_type = EXPR_SUB; break;
3503 		case '*': isn->isn_arg.op.op_type = EXPR_MULT; break;
3504 		case '/': isn->isn_arg.op.op_type = EXPR_DIV; break;
3505 		case '%': isn->isn_arg.op.op_type = EXPR_REM; break;
3506 	    }
3507 	}
3508     }
3509 
3510     switch (dest)
3511     {
3512 	case dest_option:
3513 	    generate_STOREOPT(cctx, name + 1, opt_flags);
3514 	    break;
3515 	case dest_global:
3516 	    // include g: with the name, easier to execute that way
3517 	    generate_STORE(cctx, ISN_STOREG, 0, name);
3518 	    break;
3519 	case dest_env:
3520 	    generate_STORE(cctx, ISN_STOREENV, 0, name + 1);
3521 	    break;
3522 	case dest_reg:
3523 	    generate_STORE(cctx, ISN_STOREREG, name[1], NULL);
3524 	    break;
3525 	case dest_vimvar:
3526 	    generate_STORE(cctx, ISN_STOREV, vimvaridx, NULL);
3527 	    break;
3528 	case dest_script:
3529 	    {
3530 		char_u	    *rawname = name + (name[1] == ':' ? 2 : 0);
3531 		imported_T  *import = NULL;
3532 		int	    sid = current_sctx.sc_sid;
3533 
3534 		if (name[1] != ':')
3535 		{
3536 		    import = find_imported(name, 0, cctx);
3537 		    if (import != NULL)
3538 			sid = import->imp_sid;
3539 		}
3540 
3541 		idx = get_script_item_idx(sid, rawname, TRUE);
3542 		// TODO: specific type
3543 		if (idx < 0)
3544 		    generate_OLDSCRIPT(cctx, ISN_STORES, rawname, sid, &t_any);
3545 		else
3546 		    generate_VIM9SCRIPT(cctx, ISN_STORESCRIPT,
3547 							     sid, idx, &t_any);
3548 	    }
3549 	    break;
3550 	case dest_local:
3551 	    {
3552 		isn_T *isn = ((isn_T *)instr->ga_data) + instr->ga_len - 1;
3553 
3554 		// optimization: turn "var = 123" from ISN_PUSHNR + ISN_STORE
3555 		// into ISN_STORENR
3556 		if (instr->ga_len == instr_count + 1
3557 						&& isn->isn_type == ISN_PUSHNR)
3558 		{
3559 		    varnumber_T val = isn->isn_arg.number;
3560 		    garray_T	*stack = &cctx->ctx_type_stack;
3561 
3562 		    isn->isn_type = ISN_STORENR;
3563 		    isn->isn_arg.storenr.str_idx = idx;
3564 		    isn->isn_arg.storenr.str_val = val;
3565 		    if (stack->ga_len > 0)
3566 			--stack->ga_len;
3567 		}
3568 		else
3569 		    generate_STORE(cctx, ISN_STORE, idx, NULL);
3570 	    }
3571 	    break;
3572     }
3573     ret = p;
3574 
3575 theend:
3576     vim_free(name);
3577     return ret;
3578 }
3579 
3580 /*
3581  * Compile an :import command.
3582  */
3583     static char_u *
3584 compile_import(char_u *arg, cctx_T *cctx)
3585 {
3586     return handle_import(arg, &cctx->ctx_imports, 0);
3587 }
3588 
3589 /*
3590  * generate a jump to the ":endif"/":endfor"/":endwhile"/":finally"/":endtry".
3591  */
3592     static int
3593 compile_jump_to_end(endlabel_T **el, jumpwhen_T when, cctx_T *cctx)
3594 {
3595     garray_T	*instr = &cctx->ctx_instr;
3596     endlabel_T  *endlabel = ALLOC_CLEAR_ONE(endlabel_T);
3597 
3598     if (endlabel == NULL)
3599 	return FAIL;
3600     endlabel->el_next = *el;
3601     *el = endlabel;
3602     endlabel->el_end_label = instr->ga_len;
3603 
3604     generate_JUMP(cctx, when, 0);
3605     return OK;
3606 }
3607 
3608     static void
3609 compile_fill_jump_to_end(endlabel_T **el, cctx_T *cctx)
3610 {
3611     garray_T	*instr = &cctx->ctx_instr;
3612 
3613     while (*el != NULL)
3614     {
3615 	endlabel_T  *cur = (*el);
3616 	isn_T	    *isn;
3617 
3618 	isn = ((isn_T *)instr->ga_data) + cur->el_end_label;
3619 	isn->isn_arg.jump.jump_where = instr->ga_len;
3620 	*el = cur->el_next;
3621 	vim_free(cur);
3622     }
3623 }
3624 
3625 /*
3626  * Create a new scope and set up the generic items.
3627  */
3628     static scope_T *
3629 new_scope(cctx_T *cctx, scopetype_T type)
3630 {
3631     scope_T *scope = ALLOC_CLEAR_ONE(scope_T);
3632 
3633     if (scope == NULL)
3634 	return NULL;
3635     scope->se_outer = cctx->ctx_scope;
3636     cctx->ctx_scope = scope;
3637     scope->se_type = type;
3638     scope->se_local_count = cctx->ctx_locals.ga_len;
3639     return scope;
3640 }
3641 
3642 /*
3643  * Evaluate an expression that is a constant:
3644  *  has(arg)
3645  *
3646  * Also handle:
3647  *  ! in front		logical NOT
3648  *
3649  * Return FAIL if the expression is not a constant.
3650  */
3651     static int
3652 evaluate_const_expr7(char_u **arg, cctx_T *cctx UNUSED, typval_T *tv)
3653 {
3654     typval_T	argvars[2];
3655     char_u	*start_leader, *end_leader;
3656 
3657     /*
3658      * Skip '!' characters.  They are handled later.
3659      */
3660     start_leader = *arg;
3661     while (**arg == '!')
3662 	*arg = skipwhite(*arg + 1);
3663     end_leader = *arg;
3664 
3665     /*
3666      * Recognize only has() for now.
3667      */
3668     if (STRNCMP("has(", *arg, 4) != 0)
3669 	return FAIL;
3670     *arg = skipwhite(*arg + 4);
3671 
3672     if (**arg == '"')
3673     {
3674 	if (get_string_tv(arg, tv, TRUE) == FAIL)
3675 	    return FAIL;
3676     }
3677     else if (**arg == '\'')
3678     {
3679 	if (get_lit_string_tv(arg, tv, TRUE) == FAIL)
3680 	    return FAIL;
3681     }
3682     else
3683 	return FAIL;
3684 
3685     *arg = skipwhite(*arg);
3686     if (**arg != ')')
3687 	return FAIL;
3688     *arg = skipwhite(*arg + 1);
3689 
3690     argvars[0] = *tv;
3691     argvars[1].v_type = VAR_UNKNOWN;
3692     tv->v_type = VAR_NUMBER;
3693     tv->vval.v_number = 0;
3694     f_has(argvars, tv);
3695     clear_tv(&argvars[0]);
3696 
3697     while (start_leader < end_leader)
3698     {
3699 	if (*start_leader == '!')
3700 	    tv->vval.v_number = !tv->vval.v_number;
3701 	++start_leader;
3702     }
3703 
3704     return OK;
3705 }
3706 
3707 static int evaluate_const_expr3(char_u **arg, cctx_T *cctx, typval_T *tv);
3708 
3709 /*
3710  * Compile constant || or &&.
3711  */
3712     static int
3713 evaluate_const_and_or(char_u **arg, cctx_T *cctx, char *op, typval_T *tv)
3714 {
3715     char_u	*p = skipwhite(*arg);
3716     int		opchar = *op;
3717 
3718     if (p[0] == opchar && p[1] == opchar)
3719     {
3720 	int	val = tv2bool(tv);
3721 
3722 	/*
3723 	 * Repeat until there is no following "||" or "&&"
3724 	 */
3725 	while (p[0] == opchar && p[1] == opchar)
3726 	{
3727 	    typval_T	tv2;
3728 
3729 	    if (!VIM_ISWHITE(**arg) || !VIM_ISWHITE(p[2]))
3730 		return FAIL;
3731 
3732 	    // eval the next expression
3733 	    *arg = skipwhite(p + 2);
3734 	    tv2.v_type = VAR_UNKNOWN;
3735 	    tv2.v_lock = 0;
3736 	    if ((opchar == '|' ? evaluate_const_expr3(arg, cctx, &tv2)
3737 			       : evaluate_const_expr7(arg, cctx, &tv2)) == FAIL)
3738 	    {
3739 		clear_tv(&tv2);
3740 		return FAIL;
3741 	    }
3742 	    if ((opchar == '&') == val)
3743 	    {
3744 		// false || tv2  or true && tv2: use tv2
3745 		clear_tv(tv);
3746 		*tv = tv2;
3747 		val = tv2bool(tv);
3748 	    }
3749 	    else
3750 		clear_tv(&tv2);
3751 	    p = skipwhite(*arg);
3752 	}
3753     }
3754 
3755     return OK;
3756 }
3757 
3758 /*
3759  * Evaluate an expression that is a constant: expr4 && expr4 && expr4
3760  * Return FAIL if the expression is not a constant.
3761  */
3762     static int
3763 evaluate_const_expr3(char_u **arg, cctx_T *cctx, typval_T *tv)
3764 {
3765     // evaluate the first expression
3766     if (evaluate_const_expr7(arg, cctx, tv) == FAIL)
3767 	return FAIL;
3768 
3769     // || and && work almost the same
3770     return evaluate_const_and_or(arg, cctx, "&&", tv);
3771 }
3772 
3773 /*
3774  * Evaluate an expression that is a constant: expr3 || expr3 || expr3
3775  * Return FAIL if the expression is not a constant.
3776  */
3777     static int
3778 evaluate_const_expr2(char_u **arg, cctx_T *cctx, typval_T *tv)
3779 {
3780     // evaluate the first expression
3781     if (evaluate_const_expr3(arg, cctx, tv) == FAIL)
3782 	return FAIL;
3783 
3784     // || and && work almost the same
3785     return evaluate_const_and_or(arg, cctx, "||", tv);
3786 }
3787 
3788 /*
3789  * Evaluate an expression that is a constant: expr2 ? expr1 : expr1
3790  * E.g. for "has('feature')".
3791  * This does not produce error messages.  "tv" should be cleared afterwards.
3792  * Return FAIL if the expression is not a constant.
3793  */
3794     static int
3795 evaluate_const_expr1(char_u **arg, cctx_T *cctx, typval_T *tv)
3796 {
3797     char_u	*p;
3798 
3799     // evaluate the first expression
3800     if (evaluate_const_expr2(arg, cctx, tv) == FAIL)
3801 	return FAIL;
3802 
3803     p = skipwhite(*arg);
3804     if (*p == '?')
3805     {
3806 	int		val = tv2bool(tv);
3807 	typval_T	tv2;
3808 
3809 	if (!VIM_ISWHITE(**arg) || !VIM_ISWHITE(p[1]))
3810 	    return FAIL;
3811 
3812 	// evaluate the second expression; any type is accepted
3813 	clear_tv(tv);
3814 	*arg = skipwhite(p + 1);
3815 	if (evaluate_const_expr1(arg, cctx, tv) == FAIL)
3816 	    return FAIL;
3817 
3818 	// Check for the ":".
3819 	p = skipwhite(*arg);
3820 	if (*p != ':' || !VIM_ISWHITE(**arg) || !VIM_ISWHITE(p[1]))
3821 	    return FAIL;
3822 
3823 	// evaluate the third expression
3824 	*arg = skipwhite(p + 1);
3825 	tv2.v_type = VAR_UNKNOWN;
3826 	if (evaluate_const_expr1(arg, cctx, &tv2) == FAIL)
3827 	{
3828 	    clear_tv(&tv2);
3829 	    return FAIL;
3830 	}
3831 	if (val)
3832 	{
3833 	    // use the expr after "?"
3834 	    clear_tv(&tv2);
3835 	}
3836 	else
3837 	{
3838 	    // use the expr after ":"
3839 	    clear_tv(tv);
3840 	    *tv = tv2;
3841 	}
3842     }
3843     return OK;
3844 }
3845 
3846 /*
3847  * compile "if expr"
3848  *
3849  * "if expr" Produces instructions:
3850  *	EVAL expr		Push result of "expr"
3851  *	JUMP_IF_FALSE end
3852  *	... body ...
3853  * end:
3854  *
3855  * "if expr | else" Produces instructions:
3856  *	EVAL expr		Push result of "expr"
3857  *	JUMP_IF_FALSE else
3858  *	... body ...
3859  *	JUMP_ALWAYS end
3860  * else:
3861  *	... body ...
3862  * end:
3863  *
3864  * "if expr1 | elseif expr2 | else" Produces instructions:
3865  *	EVAL expr		Push result of "expr"
3866  *	JUMP_IF_FALSE elseif
3867  *	... body ...
3868  *	JUMP_ALWAYS end
3869  * elseif:
3870  *	EVAL expr		Push result of "expr"
3871  *	JUMP_IF_FALSE else
3872  *	... body ...
3873  *	JUMP_ALWAYS end
3874  * else:
3875  *	... body ...
3876  * end:
3877  */
3878     static char_u *
3879 compile_if(char_u *arg, cctx_T *cctx)
3880 {
3881     char_u	*p = arg;
3882     garray_T	*instr = &cctx->ctx_instr;
3883     scope_T	*scope;
3884     typval_T	tv;
3885 
3886     // compile "expr"; if we know it evaluates to FALSE skip the block
3887     tv.v_type = VAR_UNKNOWN;
3888     if (evaluate_const_expr1(&p, cctx, &tv) == OK)
3889 	cctx->ctx_skip = tv2bool(&tv) ? FALSE : TRUE;
3890     else
3891 	cctx->ctx_skip = MAYBE;
3892     clear_tv(&tv);
3893     if (cctx->ctx_skip == MAYBE)
3894     {
3895 	p = arg;
3896 	if (compile_expr1(&p, cctx) == FAIL)
3897 	    return NULL;
3898     }
3899 
3900     scope = new_scope(cctx, IF_SCOPE);
3901     if (scope == NULL)
3902 	return NULL;
3903 
3904     if (cctx->ctx_skip == MAYBE)
3905     {
3906 	// "where" is set when ":elseif", "else" or ":endif" is found
3907 	scope->se_u.se_if.is_if_label = instr->ga_len;
3908 	generate_JUMP(cctx, JUMP_IF_FALSE, 0);
3909     }
3910     else
3911 	scope->se_u.se_if.is_if_label = -1;
3912 
3913     return p;
3914 }
3915 
3916     static char_u *
3917 compile_elseif(char_u *arg, cctx_T *cctx)
3918 {
3919     char_u	*p = arg;
3920     garray_T	*instr = &cctx->ctx_instr;
3921     isn_T	*isn;
3922     scope_T	*scope = cctx->ctx_scope;
3923     typval_T	tv;
3924 
3925     if (scope == NULL || scope->se_type != IF_SCOPE)
3926     {
3927 	emsg(_(e_elseif_without_if));
3928 	return NULL;
3929     }
3930     cctx->ctx_locals.ga_len = scope->se_local_count;
3931 
3932     if (cctx->ctx_skip == MAYBE)
3933     {
3934 	if (compile_jump_to_end(&scope->se_u.se_if.is_end_label,
3935 						    JUMP_ALWAYS, cctx) == FAIL)
3936 	    return NULL;
3937 	// previous "if" or "elseif" jumps here
3938 	isn = ((isn_T *)instr->ga_data) + scope->se_u.se_if.is_if_label;
3939 	isn->isn_arg.jump.jump_where = instr->ga_len;
3940     }
3941 
3942     // compile "expr"; if we know it evaluates to FALSE skip the block
3943     tv.v_type = VAR_UNKNOWN;
3944     if (evaluate_const_expr1(&p, cctx, &tv) == OK)
3945 	cctx->ctx_skip = tv2bool(&tv) ? FALSE : TRUE;
3946     else
3947 	cctx->ctx_skip = MAYBE;
3948     clear_tv(&tv);
3949     if (cctx->ctx_skip == MAYBE)
3950     {
3951 	p = arg;
3952 	if (compile_expr1(&p, cctx) == FAIL)
3953 	    return NULL;
3954 
3955 	// "where" is set when ":elseif", "else" or ":endif" is found
3956 	scope->se_u.se_if.is_if_label = instr->ga_len;
3957 	generate_JUMP(cctx, JUMP_IF_FALSE, 0);
3958     }
3959     else
3960 	scope->se_u.se_if.is_if_label = -1;
3961 
3962     return p;
3963 }
3964 
3965     static char_u *
3966 compile_else(char_u *arg, cctx_T *cctx)
3967 {
3968     char_u	*p = arg;
3969     garray_T	*instr = &cctx->ctx_instr;
3970     isn_T	*isn;
3971     scope_T	*scope = cctx->ctx_scope;
3972 
3973     if (scope == NULL || scope->se_type != IF_SCOPE)
3974     {
3975 	emsg(_(e_else_without_if));
3976 	return NULL;
3977     }
3978     cctx->ctx_locals.ga_len = scope->se_local_count;
3979 
3980     // jump from previous block to the end, unless the else block is empty
3981     if (cctx->ctx_skip == MAYBE)
3982     {
3983 	if (compile_jump_to_end(&scope->se_u.se_if.is_end_label,
3984 						    JUMP_ALWAYS, cctx) == FAIL)
3985 	    return NULL;
3986     }
3987 
3988     if (cctx->ctx_skip == MAYBE)
3989     {
3990 	if (scope->se_u.se_if.is_if_label >= 0)
3991 	{
3992 	    // previous "if" or "elseif" jumps here
3993 	    isn = ((isn_T *)instr->ga_data) + scope->se_u.se_if.is_if_label;
3994 	    isn->isn_arg.jump.jump_where = instr->ga_len;
3995 	    scope->se_u.se_if.is_if_label = -1;
3996 	}
3997     }
3998 
3999     if (cctx->ctx_skip != MAYBE)
4000 	cctx->ctx_skip = !cctx->ctx_skip;
4001 
4002     return p;
4003 }
4004 
4005     static char_u *
4006 compile_endif(char_u *arg, cctx_T *cctx)
4007 {
4008     scope_T	*scope = cctx->ctx_scope;
4009     ifscope_T	*ifscope;
4010     garray_T	*instr = &cctx->ctx_instr;
4011     isn_T	*isn;
4012 
4013     if (scope == NULL || scope->se_type != IF_SCOPE)
4014     {
4015 	emsg(_(e_endif_without_if));
4016 	return NULL;
4017     }
4018     ifscope = &scope->se_u.se_if;
4019     cctx->ctx_scope = scope->se_outer;
4020     cctx->ctx_locals.ga_len = scope->se_local_count;
4021 
4022     if (scope->se_u.se_if.is_if_label >= 0)
4023     {
4024 	// previous "if" or "elseif" jumps here
4025 	isn = ((isn_T *)instr->ga_data) + scope->se_u.se_if.is_if_label;
4026 	isn->isn_arg.jump.jump_where = instr->ga_len;
4027     }
4028     // Fill in the "end" label in jumps at the end of the blocks.
4029     compile_fill_jump_to_end(&ifscope->is_end_label, cctx);
4030     cctx->ctx_skip = FALSE;
4031 
4032     vim_free(scope);
4033     return arg;
4034 }
4035 
4036 /*
4037  * compile "for var in expr"
4038  *
4039  * Produces instructions:
4040  *       PUSHNR -1
4041  *       STORE loop-idx		Set index to -1
4042  *       EVAL expr		Push result of "expr"
4043  * top:  FOR loop-idx, end	Increment index, use list on bottom of stack
4044  *				- if beyond end, jump to "end"
4045  *				- otherwise get item from list and push it
4046  *       STORE var		Store item in "var"
4047  *       ... body ...
4048  *       JUMP top		Jump back to repeat
4049  * end:	 DROP			Drop the result of "expr"
4050  *
4051  */
4052     static char_u *
4053 compile_for(char_u *arg, cctx_T *cctx)
4054 {
4055     char_u	*p;
4056     size_t	varlen;
4057     garray_T	*instr = &cctx->ctx_instr;
4058     garray_T	*stack = &cctx->ctx_type_stack;
4059     scope_T	*scope;
4060     int		loop_idx;	// index of loop iteration variable
4061     int		var_idx;	// index of "var"
4062     type_T	*vartype;
4063 
4064     // TODO: list of variables: "for [key, value] in dict"
4065     // parse "var"
4066     for (p = arg; eval_isnamec1(*p); ++p)
4067 	;
4068     varlen = p - arg;
4069     var_idx = lookup_local(arg, varlen, cctx);
4070     if (var_idx >= 0)
4071     {
4072 	semsg(_("E1023: variable already defined: %s"), arg);
4073 	return NULL;
4074     }
4075 
4076     // consume "in"
4077     p = skipwhite(p);
4078     if (STRNCMP(p, "in", 2) != 0 || !VIM_ISWHITE(p[2]))
4079     {
4080 	emsg(_(e_missing_in));
4081 	return NULL;
4082     }
4083     p = skipwhite(p + 2);
4084 
4085 
4086     scope = new_scope(cctx, FOR_SCOPE);
4087     if (scope == NULL)
4088 	return NULL;
4089 
4090     // Reserve a variable to store the loop iteration counter.
4091     loop_idx = reserve_local(cctx, (char_u *)"", 0, FALSE, &t_number);
4092     if (loop_idx < 0)
4093 	return NULL;
4094 
4095     // Reserve a variable to store "var"
4096     var_idx = reserve_local(cctx, arg, varlen, FALSE, &t_any);
4097     if (var_idx < 0)
4098 	return NULL;
4099 
4100     generate_STORENR(cctx, loop_idx, -1);
4101 
4102     // compile "expr", it remains on the stack until "endfor"
4103     arg = p;
4104     if (compile_expr1(&arg, cctx) == FAIL)
4105 	return NULL;
4106 
4107     // now we know the type of "var"
4108     vartype = ((type_T **)stack->ga_data)[stack->ga_len - 1];
4109     if (vartype->tt_type != VAR_LIST)
4110     {
4111 	emsg(_("E1024: need a List to iterate over"));
4112 	return NULL;
4113     }
4114     if (vartype->tt_member->tt_type != VAR_UNKNOWN)
4115     {
4116 	lvar_T *lvar = ((lvar_T *)cctx->ctx_locals.ga_data) + var_idx;
4117 
4118 	lvar->lv_type = vartype->tt_member;
4119     }
4120 
4121     // "for_end" is set when ":endfor" is found
4122     scope->se_u.se_for.fs_top_label = instr->ga_len;
4123 
4124     generate_FOR(cctx, loop_idx);
4125     generate_STORE(cctx, ISN_STORE, var_idx, NULL);
4126 
4127     return arg;
4128 }
4129 
4130 /*
4131  * compile "endfor"
4132  */
4133     static char_u *
4134 compile_endfor(char_u *arg, cctx_T *cctx)
4135 {
4136     garray_T	*instr = &cctx->ctx_instr;
4137     scope_T	*scope = cctx->ctx_scope;
4138     forscope_T	*forscope;
4139     isn_T	*isn;
4140 
4141     if (scope == NULL || scope->se_type != FOR_SCOPE)
4142     {
4143 	emsg(_(e_for));
4144 	return NULL;
4145     }
4146     forscope = &scope->se_u.se_for;
4147     cctx->ctx_scope = scope->se_outer;
4148     cctx->ctx_locals.ga_len = scope->se_local_count;
4149 
4150     // At end of ":for" scope jump back to the FOR instruction.
4151     generate_JUMP(cctx, JUMP_ALWAYS, forscope->fs_top_label);
4152 
4153     // Fill in the "end" label in the FOR statement so it can jump here
4154     isn = ((isn_T *)instr->ga_data) + forscope->fs_top_label;
4155     isn->isn_arg.forloop.for_end = instr->ga_len;
4156 
4157     // Fill in the "end" label any BREAK statements
4158     compile_fill_jump_to_end(&forscope->fs_end_label, cctx);
4159 
4160     // Below the ":for" scope drop the "expr" list from the stack.
4161     if (generate_instr_drop(cctx, ISN_DROP, 1) == NULL)
4162 	return NULL;
4163 
4164     vim_free(scope);
4165 
4166     return arg;
4167 }
4168 
4169 /*
4170  * compile "while expr"
4171  *
4172  * Produces instructions:
4173  * top:  EVAL expr		Push result of "expr"
4174  *       JUMP_IF_FALSE end	jump if false
4175  *       ... body ...
4176  *       JUMP top		Jump back to repeat
4177  * end:
4178  *
4179  */
4180     static char_u *
4181 compile_while(char_u *arg, cctx_T *cctx)
4182 {
4183     char_u	*p = arg;
4184     garray_T	*instr = &cctx->ctx_instr;
4185     scope_T	*scope;
4186 
4187     scope = new_scope(cctx, WHILE_SCOPE);
4188     if (scope == NULL)
4189 	return NULL;
4190 
4191     scope->se_u.se_while.ws_top_label = instr->ga_len;
4192 
4193     // compile "expr"
4194     if (compile_expr1(&p, cctx) == FAIL)
4195 	return NULL;
4196 
4197     // "while_end" is set when ":endwhile" is found
4198     if (compile_jump_to_end(&scope->se_u.se_while.ws_end_label,
4199 						  JUMP_IF_FALSE, cctx) == FAIL)
4200 	return FAIL;
4201 
4202     return p;
4203 }
4204 
4205 /*
4206  * compile "endwhile"
4207  */
4208     static char_u *
4209 compile_endwhile(char_u *arg, cctx_T *cctx)
4210 {
4211     scope_T	*scope = cctx->ctx_scope;
4212 
4213     if (scope == NULL || scope->se_type != WHILE_SCOPE)
4214     {
4215 	emsg(_(e_while));
4216 	return NULL;
4217     }
4218     cctx->ctx_scope = scope->se_outer;
4219     cctx->ctx_locals.ga_len = scope->se_local_count;
4220 
4221     // At end of ":for" scope jump back to the FOR instruction.
4222     generate_JUMP(cctx, JUMP_ALWAYS, scope->se_u.se_while.ws_top_label);
4223 
4224     // Fill in the "end" label in the WHILE statement so it can jump here.
4225     // And in any jumps for ":break"
4226     compile_fill_jump_to_end(&scope->se_u.se_while.ws_end_label, cctx);
4227 
4228     vim_free(scope);
4229 
4230     return arg;
4231 }
4232 
4233 /*
4234  * compile "continue"
4235  */
4236     static char_u *
4237 compile_continue(char_u *arg, cctx_T *cctx)
4238 {
4239     scope_T	*scope = cctx->ctx_scope;
4240 
4241     for (;;)
4242     {
4243 	if (scope == NULL)
4244 	{
4245 	    emsg(_(e_continue));
4246 	    return NULL;
4247 	}
4248 	if (scope->se_type == FOR_SCOPE || scope->se_type == WHILE_SCOPE)
4249 	    break;
4250 	scope = scope->se_outer;
4251     }
4252 
4253     // Jump back to the FOR or WHILE instruction.
4254     generate_JUMP(cctx, JUMP_ALWAYS,
4255 	    scope->se_type == FOR_SCOPE ? scope->se_u.se_for.fs_top_label
4256 					  : scope->se_u.se_while.ws_top_label);
4257     return arg;
4258 }
4259 
4260 /*
4261  * compile "break"
4262  */
4263     static char_u *
4264 compile_break(char_u *arg, cctx_T *cctx)
4265 {
4266     scope_T	*scope = cctx->ctx_scope;
4267     endlabel_T	**el;
4268 
4269     for (;;)
4270     {
4271 	if (scope == NULL)
4272 	{
4273 	    emsg(_(e_break));
4274 	    return NULL;
4275 	}
4276 	if (scope->se_type == FOR_SCOPE || scope->se_type == WHILE_SCOPE)
4277 	    break;
4278 	scope = scope->se_outer;
4279     }
4280 
4281     // Jump to the end of the FOR or WHILE loop.
4282     if (scope->se_type == FOR_SCOPE)
4283 	el = &scope->se_u.se_for.fs_end_label;
4284     else
4285 	el = &scope->se_u.se_while.ws_end_label;
4286     if (compile_jump_to_end(el, JUMP_ALWAYS, cctx) == FAIL)
4287 	return FAIL;
4288 
4289     return arg;
4290 }
4291 
4292 /*
4293  * compile "{" start of block
4294  */
4295     static char_u *
4296 compile_block(char_u *arg, cctx_T *cctx)
4297 {
4298     if (new_scope(cctx, BLOCK_SCOPE) == NULL)
4299 	return NULL;
4300     return skipwhite(arg + 1);
4301 }
4302 
4303 /*
4304  * compile end of block: drop one scope
4305  */
4306     static void
4307 compile_endblock(cctx_T *cctx)
4308 {
4309     scope_T	*scope = cctx->ctx_scope;
4310 
4311     cctx->ctx_scope = scope->se_outer;
4312     cctx->ctx_locals.ga_len = scope->se_local_count;
4313     vim_free(scope);
4314 }
4315 
4316 /*
4317  * compile "try"
4318  * Creates a new scope for the try-endtry, pointing to the first catch and
4319  * finally.
4320  * Creates another scope for the "try" block itself.
4321  * TRY instruction sets up exception handling at runtime.
4322  *
4323  *	"try"
4324  *	    TRY -> catch1, -> finally  push trystack entry
4325  *	    ... try block
4326  *	"throw {exception}"
4327  *	    EVAL {exception}
4328  *	    THROW		create exception
4329  *	    ... try block
4330  *	" catch {expr}"
4331  *	    JUMP -> finally
4332  * catch1:  PUSH exeception
4333  *	    EVAL {expr}
4334  *	    MATCH
4335  *	    JUMP nomatch -> catch2
4336  *	    CATCH   remove exception
4337  *	    ... catch block
4338  *	" catch"
4339  *	    JUMP -> finally
4340  * catch2:  CATCH   remove exception
4341  *	    ... catch block
4342  *	" finally"
4343  * finally:
4344  *	    ... finally block
4345  *	" endtry"
4346  *	    ENDTRY  pop trystack entry, may rethrow
4347  */
4348     static char_u *
4349 compile_try(char_u *arg, cctx_T *cctx)
4350 {
4351     garray_T	*instr = &cctx->ctx_instr;
4352     scope_T	*try_scope;
4353     scope_T	*scope;
4354 
4355     // scope that holds the jumps that go to catch/finally/endtry
4356     try_scope = new_scope(cctx, TRY_SCOPE);
4357     if (try_scope == NULL)
4358 	return NULL;
4359 
4360     // "catch" is set when the first ":catch" is found.
4361     // "finally" is set when ":finally" or ":endtry" is found
4362     try_scope->se_u.se_try.ts_try_label = instr->ga_len;
4363     if (generate_instr(cctx, ISN_TRY) == NULL)
4364 	return NULL;
4365 
4366     // scope for the try block itself
4367     scope = new_scope(cctx, BLOCK_SCOPE);
4368     if (scope == NULL)
4369 	return NULL;
4370 
4371     return arg;
4372 }
4373 
4374 /*
4375  * compile "catch {expr}"
4376  */
4377     static char_u *
4378 compile_catch(char_u *arg, cctx_T *cctx UNUSED)
4379 {
4380     scope_T	*scope = cctx->ctx_scope;
4381     garray_T	*instr = &cctx->ctx_instr;
4382     char_u	*p;
4383     isn_T	*isn;
4384 
4385     // end block scope from :try or :catch
4386     if (scope != NULL && scope->se_type == BLOCK_SCOPE)
4387 	compile_endblock(cctx);
4388     scope = cctx->ctx_scope;
4389 
4390     // Error if not in a :try scope
4391     if (scope == NULL || scope->se_type != TRY_SCOPE)
4392     {
4393 	emsg(_(e_catch));
4394 	return NULL;
4395     }
4396 
4397     if (scope->se_u.se_try.ts_caught_all)
4398     {
4399 	emsg(_("E1033: catch unreachable after catch-all"));
4400 	return NULL;
4401     }
4402 
4403     // Jump from end of previous block to :finally or :endtry
4404     if (compile_jump_to_end(&scope->se_u.se_try.ts_end_label,
4405 						    JUMP_ALWAYS, cctx) == FAIL)
4406 	return NULL;
4407 
4408     // End :try or :catch scope: set value in ISN_TRY instruction
4409     isn = ((isn_T *)instr->ga_data) + scope->se_u.se_try.ts_try_label;
4410     if (isn->isn_arg.try.try_catch == 0)
4411 	isn->isn_arg.try.try_catch = instr->ga_len;
4412     if (scope->se_u.se_try.ts_catch_label != 0)
4413     {
4414 	// Previous catch without match jumps here
4415 	isn = ((isn_T *)instr->ga_data) + scope->se_u.se_try.ts_catch_label;
4416 	isn->isn_arg.jump.jump_where = instr->ga_len;
4417     }
4418 
4419     p = skipwhite(arg);
4420     if (ends_excmd(*p))
4421     {
4422 	scope->se_u.se_try.ts_caught_all = TRUE;
4423 	scope->se_u.se_try.ts_catch_label = 0;
4424     }
4425     else
4426     {
4427 	char_u *end;
4428 	char_u *pat;
4429 	char_u *tofree = NULL;
4430 	size_t len;
4431 
4432 	// Push v:exception, push {expr} and MATCH
4433 	generate_instr_type(cctx, ISN_PUSHEXC, &t_string);
4434 
4435 	end = skip_regexp(p + 1, *p, TRUE, &tofree);
4436 	if (*end != *p)
4437 	{
4438 	    semsg(_("E1067: Separator mismatch: %s"), p);
4439 	    vim_free(tofree);
4440 	    return FAIL;
4441 	}
4442 	if (tofree == NULL)
4443 	    len = end - (p + 1);
4444 	else
4445 	    len = end - (tofree + 1);
4446 	pat = vim_strnsave(p + 1, len);
4447 	vim_free(tofree);
4448 	p += len + 2;
4449 	if (pat == NULL)
4450 	    return FAIL;
4451 	if (generate_PUSHS(cctx, pat) == FAIL)
4452 	    return FAIL;
4453 
4454 	if (generate_COMPARE(cctx, EXPR_MATCH, FALSE) == FAIL)
4455 	    return NULL;
4456 
4457 	scope->se_u.se_try.ts_catch_label = instr->ga_len;
4458 	if (generate_JUMP(cctx, JUMP_IF_FALSE, 0) == FAIL)
4459 	    return NULL;
4460     }
4461 
4462     if (generate_instr(cctx, ISN_CATCH) == NULL)
4463 	return NULL;
4464 
4465     if (new_scope(cctx, BLOCK_SCOPE) == NULL)
4466 	return NULL;
4467     return p;
4468 }
4469 
4470     static char_u *
4471 compile_finally(char_u *arg, cctx_T *cctx)
4472 {
4473     scope_T	*scope = cctx->ctx_scope;
4474     garray_T	*instr = &cctx->ctx_instr;
4475     isn_T	*isn;
4476 
4477     // end block scope from :try or :catch
4478     if (scope != NULL && scope->se_type == BLOCK_SCOPE)
4479 	compile_endblock(cctx);
4480     scope = cctx->ctx_scope;
4481 
4482     // Error if not in a :try scope
4483     if (scope == NULL || scope->se_type != TRY_SCOPE)
4484     {
4485 	emsg(_(e_finally));
4486 	return NULL;
4487     }
4488 
4489     // End :catch or :finally scope: set value in ISN_TRY instruction
4490     isn = ((isn_T *)instr->ga_data) + scope->se_u.se_try.ts_try_label;
4491     if (isn->isn_arg.try.try_finally != 0)
4492     {
4493 	emsg(_(e_finally_dup));
4494 	return NULL;
4495     }
4496 
4497     // Fill in the "end" label in jumps at the end of the blocks.
4498     compile_fill_jump_to_end(&scope->se_u.se_try.ts_end_label, cctx);
4499 
4500     if (scope->se_u.se_try.ts_catch_label != 0)
4501     {
4502 	// Previous catch without match jumps here
4503 	isn = ((isn_T *)instr->ga_data) + scope->se_u.se_try.ts_catch_label;
4504 	isn->isn_arg.jump.jump_where = instr->ga_len;
4505     }
4506 
4507     isn->isn_arg.try.try_finally = instr->ga_len;
4508     // TODO: set index in ts_finally_label jumps
4509 
4510     return arg;
4511 }
4512 
4513     static char_u *
4514 compile_endtry(char_u *arg, cctx_T *cctx)
4515 {
4516     scope_T	*scope = cctx->ctx_scope;
4517     garray_T	*instr = &cctx->ctx_instr;
4518     isn_T	*isn;
4519 
4520     // end block scope from :catch or :finally
4521     if (scope != NULL && scope->se_type == BLOCK_SCOPE)
4522 	compile_endblock(cctx);
4523     scope = cctx->ctx_scope;
4524 
4525     // Error if not in a :try scope
4526     if (scope == NULL || scope->se_type != TRY_SCOPE)
4527     {
4528 	if (scope == NULL)
4529 	    emsg(_(e_no_endtry));
4530 	else if (scope->se_type == WHILE_SCOPE)
4531 	    emsg(_(e_endwhile));
4532 	else if (scope->se_type == FOR_SCOPE)
4533 	    emsg(_(e_endfor));
4534 	else
4535 	    emsg(_(e_endif));
4536 	return NULL;
4537     }
4538 
4539     isn = ((isn_T *)instr->ga_data) + scope->se_u.se_try.ts_try_label;
4540     if (isn->isn_arg.try.try_catch == 0 && isn->isn_arg.try.try_finally == 0)
4541     {
4542 	emsg(_("E1032: missing :catch or :finally"));
4543 	return NULL;
4544     }
4545 
4546     // Fill in the "end" label in jumps at the end of the blocks, if not done
4547     // by ":finally".
4548     compile_fill_jump_to_end(&scope->se_u.se_try.ts_end_label, cctx);
4549 
4550     // End :catch or :finally scope: set value in ISN_TRY instruction
4551     if (isn->isn_arg.try.try_finally == 0)
4552 	isn->isn_arg.try.try_finally = instr->ga_len;
4553     compile_endblock(cctx);
4554 
4555     if (generate_instr(cctx, ISN_ENDTRY) == NULL)
4556 	return NULL;
4557     return arg;
4558 }
4559 
4560 /*
4561  * compile "throw {expr}"
4562  */
4563     static char_u *
4564 compile_throw(char_u *arg, cctx_T *cctx UNUSED)
4565 {
4566     char_u *p = skipwhite(arg);
4567 
4568     if (ends_excmd(*p))
4569     {
4570 	emsg(_(e_argreq));
4571 	return NULL;
4572     }
4573     if (compile_expr1(&p, cctx) == FAIL)
4574 	return NULL;
4575     if (may_generate_2STRING(-1, cctx) == FAIL)
4576 	return NULL;
4577     if (generate_instr_drop(cctx, ISN_THROW, 1) == NULL)
4578 	return NULL;
4579 
4580     return p;
4581 }
4582 
4583 /*
4584  * compile "echo expr"
4585  */
4586     static char_u *
4587 compile_echo(char_u *arg, int with_white, cctx_T *cctx)
4588 {
4589     char_u	*p = arg;
4590     int		count = 0;
4591 
4592     // for ()
4593     {
4594 	if (compile_expr1(&p, cctx) == FAIL)
4595 	    return NULL;
4596 	++count;
4597     }
4598 
4599     generate_ECHO(cctx, with_white, count);
4600 
4601     return p;
4602 }
4603 
4604 /*
4605  * After ex_function() has collected all the function lines: parse and compile
4606  * the lines into instructions.
4607  * Adds the function to "def_functions".
4608  * When "set_return_type" is set then set ufunc->uf_ret_type to the type of the
4609  * return statement (used for lambda).
4610  */
4611     void
4612 compile_def_function(ufunc_T *ufunc, int set_return_type)
4613 {
4614     dfunc_T	*dfunc;
4615     char_u	*line = NULL;
4616     char_u	*p;
4617     exarg_T	ea;
4618     char	*errormsg = NULL;	// error message
4619     int		had_return = FALSE;
4620     cctx_T	cctx;
4621     garray_T	*instr;
4622     int		called_emsg_before = called_emsg;
4623     int		ret = FAIL;
4624     sctx_T	save_current_sctx = current_sctx;
4625 
4626     if (ufunc->uf_dfunc_idx >= 0)
4627     {
4628 	// redefining a function that was compiled before
4629 	dfunc = ((dfunc_T *)def_functions.ga_data) + ufunc->uf_dfunc_idx;
4630 	dfunc->df_deleted = FALSE;
4631     }
4632     else
4633     {
4634 	// Add the function to "def_functions".
4635 	if (ga_grow(&def_functions, 1) == FAIL)
4636 	    return;
4637 	dfunc = ((dfunc_T *)def_functions.ga_data) + def_functions.ga_len;
4638 	vim_memset(dfunc, 0, sizeof(dfunc_T));
4639 	dfunc->df_idx = def_functions.ga_len;
4640 	ufunc->uf_dfunc_idx = dfunc->df_idx;
4641 	dfunc->df_ufunc = ufunc;
4642 	++def_functions.ga_len;
4643     }
4644 
4645     vim_memset(&cctx, 0, sizeof(cctx));
4646     cctx.ctx_ufunc = ufunc;
4647     cctx.ctx_lnum = -1;
4648     ga_init2(&cctx.ctx_locals, sizeof(lvar_T), 10);
4649     ga_init2(&cctx.ctx_type_stack, sizeof(type_T *), 50);
4650     ga_init2(&cctx.ctx_imports, sizeof(imported_T), 10);
4651     cctx.ctx_type_list = &ufunc->uf_type_list;
4652     ga_init2(&cctx.ctx_instr, sizeof(isn_T), 50);
4653     instr = &cctx.ctx_instr;
4654 
4655     // Most modern script version.
4656     current_sctx.sc_version = SCRIPT_VERSION_VIM9;
4657 
4658     if (ufunc->uf_def_args.ga_len > 0)
4659     {
4660 	int	count = ufunc->uf_def_args.ga_len;
4661 	int	i;
4662 	char_u	*arg;
4663 	int	off = STACK_FRAME_SIZE + (ufunc->uf_va_name != NULL ? 1 : 0);
4664 
4665 	// Produce instructions for the default values of optional arguments.
4666 	// Store the instruction index in uf_def_arg_idx[] so that we know
4667 	// where to start when the function is called, depending on the number
4668 	// of arguments.
4669 	ufunc->uf_def_arg_idx = ALLOC_CLEAR_MULT(int, count + 1);
4670 	if (ufunc->uf_def_arg_idx == NULL)
4671 	    goto erret;
4672 	for (i = 0; i < count; ++i)
4673 	{
4674 	    ufunc->uf_def_arg_idx[i] = instr->ga_len;
4675 	    arg = ((char_u **)(ufunc->uf_def_args.ga_data))[i];
4676 	    if (compile_expr1(&arg, &cctx) == FAIL
4677 		    || generate_STORE(&cctx, ISN_STORE,
4678 						i - count - off, NULL) == FAIL)
4679 		goto erret;
4680 	}
4681 
4682 	// If a varargs is following, push an empty list.
4683 	if (ufunc->uf_va_name != NULL)
4684 	{
4685 	    if (generate_NEWLIST(&cctx, 0) == FAIL
4686 		    || generate_STORE(&cctx, ISN_STORE, -off, NULL) == FAIL)
4687 		goto erret;
4688 	}
4689 
4690 	ufunc->uf_def_arg_idx[count] = instr->ga_len;
4691     }
4692 
4693     /*
4694      * Loop over all the lines of the function and generate instructions.
4695      */
4696     for (;;)
4697     {
4698 	if (line != NULL && *line == '|')
4699 	    // the line continues after a '|'
4700 	    ++line;
4701 	else if (line != NULL && *line != NUL)
4702 	{
4703 	    semsg(_("E488: Trailing characters: %s"), line);
4704 	    goto erret;
4705 	}
4706 	else
4707 	{
4708 	    do
4709 	    {
4710 		++cctx.ctx_lnum;
4711 		if (cctx.ctx_lnum == ufunc->uf_lines.ga_len)
4712 		    break;
4713 		line = ((char_u **)ufunc->uf_lines.ga_data)[cctx.ctx_lnum];
4714 	    } while (line == NULL);
4715 	    if (cctx.ctx_lnum == ufunc->uf_lines.ga_len)
4716 		break;
4717 	    SOURCING_LNUM = ufunc->uf_script_ctx.sc_lnum + cctx.ctx_lnum + 1;
4718 	}
4719 
4720 	had_return = FALSE;
4721 	vim_memset(&ea, 0, sizeof(ea));
4722 	ea.cmdlinep = &line;
4723 	ea.cmd = skipwhite(line);
4724 
4725 	// "}" ends a block scope
4726 	if (*ea.cmd == '}')
4727 	{
4728 	    scopetype_T stype = cctx.ctx_scope == NULL
4729 					 ? NO_SCOPE : cctx.ctx_scope->se_type;
4730 
4731 	    if (stype == BLOCK_SCOPE)
4732 	    {
4733 		compile_endblock(&cctx);
4734 		line = ea.cmd;
4735 	    }
4736 	    else
4737 	    {
4738 		emsg("E1025: using } outside of a block scope");
4739 		goto erret;
4740 	    }
4741 	    if (line != NULL)
4742 		line = skipwhite(ea.cmd + 1);
4743 	    continue;
4744 	}
4745 
4746 	// "{" starts a block scope
4747 	if (*ea.cmd == '{')
4748 	{
4749 	    line = compile_block(ea.cmd, &cctx);
4750 	    continue;
4751 	}
4752 
4753 	/*
4754 	 * COMMAND MODIFIERS
4755 	 */
4756 	if (parse_command_modifiers(&ea, &errormsg, FALSE) == FAIL)
4757 	{
4758 	    if (errormsg != NULL)
4759 		goto erret;
4760 	    // empty line or comment
4761 	    line = (char_u *)"";
4762 	    continue;
4763 	}
4764 
4765 	// Skip ":call" to get to the function name.
4766 	if (checkforcmd(&ea.cmd, "call", 3))
4767 	    ea.cmd = skipwhite(ea.cmd);
4768 
4769 	// Assuming the command starts with a variable or function name, find
4770 	// what follows.  Also "&opt = val", "$ENV = val" and "@r = val".
4771 	p = (*ea.cmd == '&' || *ea.cmd == '$' || *ea.cmd == '@')
4772 							 ? ea.cmd + 1 : ea.cmd;
4773 	p = to_name_end(p);
4774 	if (p > ea.cmd && *p != NUL)
4775 	{
4776 	    int oplen;
4777 	    int heredoc;
4778 
4779 	    // "funcname(" is always a function call.
4780 	    // "varname[]" is an expression.
4781 	    // "varname->expr" is an expression.
4782 	    if (*p == '('
4783 		    || *p == '['
4784 		    || ((p - ea.cmd) > 2 && ea.cmd[1] == ':')
4785 		    || (*p == '-' && p[1] == '>'))
4786 	    {
4787 		// TODO
4788 	    }
4789 
4790 	    oplen = assignment_len(skipwhite(p), &heredoc);
4791 	    if (oplen > 0)
4792 	    {
4793 		// Recognize an assignment if we recognize the variable name:
4794 		// "g:var = expr"
4795 		// "var = expr"  where "var" is a local var name.
4796 		// "&opt = expr"
4797 		// "$ENV = expr"
4798 		// "@r = expr"
4799 		if (*ea.cmd == '&'
4800 			|| *ea.cmd == '$'
4801 			|| *ea.cmd == '@'
4802 			|| ((p - ea.cmd) > 2 && ea.cmd[1] == ':')
4803 			|| lookup_local(ea.cmd, p - ea.cmd, &cctx) >= 0
4804 			|| lookup_script(ea.cmd, p - ea.cmd) == OK
4805 			|| find_imported(ea.cmd, p - ea.cmd, &cctx) != NULL)
4806 		{
4807 		    line = compile_assignment(ea.cmd, &ea, CMD_SIZE, &cctx);
4808 		    if (line == NULL)
4809 			goto erret;
4810 		    continue;
4811 		}
4812 	    }
4813 	}
4814 
4815 	/*
4816 	 * COMMAND after range
4817 	 */
4818 	ea.cmd = skip_range(ea.cmd, NULL);
4819 	p = find_ex_command(&ea, NULL, lookup_local, &cctx);
4820 
4821 	if (p == ea.cmd && ea.cmdidx != CMD_SIZE)
4822 	{
4823 	    if (cctx.ctx_skip == TRUE)
4824 	    {
4825 		line += STRLEN(line);
4826 		continue;
4827 	    }
4828 
4829 	    // Expression or function call.
4830 	    if (ea.cmdidx == CMD_eval)
4831 	    {
4832 		p = ea.cmd;
4833 		if (compile_expr1(&p, &cctx) == FAIL)
4834 		    goto erret;
4835 
4836 		// drop the return value
4837 		generate_instr_drop(&cctx, ISN_DROP, 1);
4838 		line = p;
4839 		continue;
4840 	    }
4841 	    if (ea.cmdidx == CMD_let)
4842 	    {
4843 		line = compile_assignment(ea.cmd, &ea, CMD_SIZE, &cctx);
4844 		if (line == NULL)
4845 		    goto erret;
4846 		continue;
4847 	    }
4848 	    iemsg("Command from find_ex_command() not handled");
4849 	    goto erret;
4850 	}
4851 
4852 	p = skipwhite(p);
4853 
4854 	if (cctx.ctx_skip == TRUE
4855 		&& ea.cmdidx != CMD_elseif
4856 		&& ea.cmdidx != CMD_else
4857 		&& ea.cmdidx != CMD_endif)
4858 	{
4859 	    line += STRLEN(line);
4860 	    continue;
4861 	}
4862 
4863 	switch (ea.cmdidx)
4864 	{
4865 	    case CMD_def:
4866 	    case CMD_function:
4867 		    // TODO: Nested function
4868 		    emsg("Nested function not implemented yet");
4869 		    goto erret;
4870 
4871 	    case CMD_return:
4872 		    line = compile_return(p, set_return_type, &cctx);
4873 		    had_return = TRUE;
4874 		    break;
4875 
4876 	    case CMD_let:
4877 	    case CMD_const:
4878 		    line = compile_assignment(p, &ea, ea.cmdidx, &cctx);
4879 		    break;
4880 
4881 	    case CMD_import:
4882 		    line = compile_import(p, &cctx);
4883 		    break;
4884 
4885 	    case CMD_if:
4886 		    line = compile_if(p, &cctx);
4887 		    break;
4888 	    case CMD_elseif:
4889 		    line = compile_elseif(p, &cctx);
4890 		    break;
4891 	    case CMD_else:
4892 		    line = compile_else(p, &cctx);
4893 		    break;
4894 	    case CMD_endif:
4895 		    line = compile_endif(p, &cctx);
4896 		    break;
4897 
4898 	    case CMD_while:
4899 		    line = compile_while(p, &cctx);
4900 		    break;
4901 	    case CMD_endwhile:
4902 		    line = compile_endwhile(p, &cctx);
4903 		    break;
4904 
4905 	    case CMD_for:
4906 		    line = compile_for(p, &cctx);
4907 		    break;
4908 	    case CMD_endfor:
4909 		    line = compile_endfor(p, &cctx);
4910 		    break;
4911 	    case CMD_continue:
4912 		    line = compile_continue(p, &cctx);
4913 		    break;
4914 	    case CMD_break:
4915 		    line = compile_break(p, &cctx);
4916 		    break;
4917 
4918 	    case CMD_try:
4919 		    line = compile_try(p, &cctx);
4920 		    break;
4921 	    case CMD_catch:
4922 		    line = compile_catch(p, &cctx);
4923 		    break;
4924 	    case CMD_finally:
4925 		    line = compile_finally(p, &cctx);
4926 		    break;
4927 	    case CMD_endtry:
4928 		    line = compile_endtry(p, &cctx);
4929 		    break;
4930 	    case CMD_throw:
4931 		    line = compile_throw(p, &cctx);
4932 		    break;
4933 
4934 	    case CMD_echo:
4935 		    line = compile_echo(p, TRUE, &cctx);
4936 		    break;
4937 	    case CMD_echon:
4938 		    line = compile_echo(p, FALSE, &cctx);
4939 		    break;
4940 
4941 	    default:
4942 		    // Not recognized, execute with do_cmdline_cmd().
4943 		    generate_EXEC(&cctx, line);
4944 		    line = (char_u *)"";
4945 		    break;
4946 	}
4947 	if (line == NULL)
4948 	    goto erret;
4949 
4950 	if (cctx.ctx_type_stack.ga_len < 0)
4951 	{
4952 	    iemsg("Type stack underflow");
4953 	    goto erret;
4954 	}
4955     }
4956 
4957     if (cctx.ctx_scope != NULL)
4958     {
4959 	if (cctx.ctx_scope->se_type == IF_SCOPE)
4960 	    emsg(_(e_endif));
4961 	else if (cctx.ctx_scope->se_type == WHILE_SCOPE)
4962 	    emsg(_(e_endwhile));
4963 	else if (cctx.ctx_scope->se_type == FOR_SCOPE)
4964 	    emsg(_(e_endfor));
4965 	else
4966 	    emsg(_("E1026: Missing }"));
4967 	goto erret;
4968     }
4969 
4970     if (!had_return)
4971     {
4972 	if (ufunc->uf_ret_type->tt_type != VAR_VOID)
4973 	{
4974 	    emsg(_("E1027: Missing return statement"));
4975 	    goto erret;
4976 	}
4977 
4978 	// Return zero if there is no return at the end.
4979 	generate_PUSHNR(&cctx, 0);
4980 	generate_instr(&cctx, ISN_RETURN);
4981     }
4982 
4983     dfunc->df_instr = instr->ga_data;
4984     dfunc->df_instr_count = instr->ga_len;
4985     dfunc->df_varcount = cctx.ctx_max_local;
4986 
4987     ret = OK;
4988 
4989 erret:
4990     if (ret == FAIL)
4991     {
4992 	ga_clear(instr);
4993 	ufunc->uf_dfunc_idx = -1;
4994 	--def_functions.ga_len;
4995 	if (errormsg != NULL)
4996 	    emsg(errormsg);
4997 	else if (called_emsg == called_emsg_before)
4998 	    emsg("E1028: compile_def_function failed");
4999 
5000 	// don't execute this function body
5001 	ufunc->uf_lines.ga_len = 0;
5002     }
5003 
5004     current_sctx = save_current_sctx;
5005     ga_clear(&cctx.ctx_type_stack);
5006     ga_clear(&cctx.ctx_locals);
5007 }
5008 
5009 /*
5010  * Delete an instruction, free what it contains.
5011  */
5012     static void
5013 delete_instr(isn_T *isn)
5014 {
5015     switch (isn->isn_type)
5016     {
5017 	case ISN_EXEC:
5018 	case ISN_LOADENV:
5019 	case ISN_LOADG:
5020 	case ISN_LOADOPT:
5021 	case ISN_MEMBER:
5022 	case ISN_PUSHEXC:
5023 	case ISN_PUSHS:
5024 	case ISN_STOREENV:
5025 	case ISN_STOREG:
5026 	    vim_free(isn->isn_arg.string);
5027 	    break;
5028 
5029 	case ISN_LOADS:
5030 	case ISN_STORES:
5031 	    vim_free(isn->isn_arg.loadstore.ls_name);
5032 	    break;
5033 
5034 	case ISN_STOREOPT:
5035 	    vim_free(isn->isn_arg.storeopt.so_name);
5036 	    break;
5037 
5038 	case ISN_PUSHBLOB:   // push blob isn_arg.blob
5039 	    blob_unref(isn->isn_arg.blob);
5040 	    break;
5041 
5042 	case ISN_UCALL:
5043 	    vim_free(isn->isn_arg.ufunc.cuf_name);
5044 	    break;
5045 
5046 	case ISN_2BOOL:
5047 	case ISN_2STRING:
5048 	case ISN_ADDBLOB:
5049 	case ISN_ADDLIST:
5050 	case ISN_BCALL:
5051 	case ISN_CATCH:
5052 	case ISN_CHECKNR:
5053 	case ISN_CHECKTYPE:
5054 	case ISN_COMPAREANY:
5055 	case ISN_COMPAREBLOB:
5056 	case ISN_COMPAREBOOL:
5057 	case ISN_COMPAREDICT:
5058 	case ISN_COMPAREFLOAT:
5059 	case ISN_COMPAREFUNC:
5060 	case ISN_COMPARELIST:
5061 	case ISN_COMPARENR:
5062 	case ISN_COMPAREPARTIAL:
5063 	case ISN_COMPARESPECIAL:
5064 	case ISN_COMPARESTRING:
5065 	case ISN_CONCAT:
5066 	case ISN_DCALL:
5067 	case ISN_DROP:
5068 	case ISN_ECHO:
5069 	case ISN_ENDTRY:
5070 	case ISN_FOR:
5071 	case ISN_FUNCREF:
5072 	case ISN_INDEX:
5073 	case ISN_JUMP:
5074 	case ISN_LOAD:
5075 	case ISN_LOADSCRIPT:
5076 	case ISN_LOADREG:
5077 	case ISN_LOADV:
5078 	case ISN_NEGATENR:
5079 	case ISN_NEWDICT:
5080 	case ISN_NEWLIST:
5081 	case ISN_OPNR:
5082 	case ISN_OPFLOAT:
5083 	case ISN_OPANY:
5084 	case ISN_PCALL:
5085 	case ISN_PUSHF:
5086 	case ISN_PUSHNR:
5087 	case ISN_PUSHBOOL:
5088 	case ISN_PUSHSPEC:
5089 	case ISN_RETURN:
5090 	case ISN_STORE:
5091 	case ISN_STOREV:
5092 	case ISN_STORENR:
5093 	case ISN_STOREREG:
5094 	case ISN_STORESCRIPT:
5095 	case ISN_THROW:
5096 	case ISN_TRY:
5097 	    // nothing allocated
5098 	    break;
5099     }
5100 }
5101 
5102 /*
5103  * When a user function is deleted, delete any associated def function.
5104  */
5105     void
5106 delete_def_function(ufunc_T *ufunc)
5107 {
5108     int idx;
5109 
5110     if (ufunc->uf_dfunc_idx >= 0)
5111     {
5112 	dfunc_T *dfunc = ((dfunc_T *)def_functions.ga_data)
5113 							 + ufunc->uf_dfunc_idx;
5114 	ga_clear(&dfunc->df_def_args_isn);
5115 
5116 	for (idx = 0; idx < dfunc->df_instr_count; ++idx)
5117 	    delete_instr(dfunc->df_instr + idx);
5118 	VIM_CLEAR(dfunc->df_instr);
5119 
5120 	dfunc->df_deleted = TRUE;
5121     }
5122 }
5123 
5124 #if defined(EXITFREE) || defined(PROTO)
5125     void
5126 free_def_functions(void)
5127 {
5128     vim_free(def_functions.ga_data);
5129 }
5130 #endif
5131 
5132 
5133 #endif // FEAT_EVAL
5134