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