blob: 66d0fc441f91a2ce00d01f403612cea1ee2a8ca0 [file] [log] [blame]
Bram Moolenaardc7c3662021-12-20 15:04:29 +00001/* 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 * vim9cmds.c: Dealing with compiled function expressions
12 */
13
14#define USING_FLOAT_STUFF
15#include "vim.h"
16
17#if defined(FEAT_EVAL) || defined(PROTO)
18
19// When not generating protos this is included in proto.h
20#ifdef PROTO
21# include "vim9.h"
22#endif
23
24/*
25 * Generate code for any ppconst entries.
26 */
27 int
28generate_ppconst(cctx_T *cctx, ppconst_T *ppconst)
29{
30 int i;
31 int ret = OK;
32 int save_skip = cctx->ctx_skip;
33
34 cctx->ctx_skip = SKIP_NOT;
35 for (i = 0; i < ppconst->pp_used; ++i)
36 if (generate_tv_PUSH(cctx, &ppconst->pp_tv[i]) == FAIL)
37 ret = FAIL;
38 ppconst->pp_used = 0;
39 cctx->ctx_skip = save_skip;
40 return ret;
41}
42
43/*
44 * Check that the last item of "ppconst" is a bool, if there is an item.
45 */
46 static int
47check_ppconst_bool(ppconst_T *ppconst)
48{
49 if (ppconst->pp_used > 0)
50 {
51 typval_T *tv = &ppconst->pp_tv[ppconst->pp_used - 1];
52 where_T where = WHERE_INIT;
53
54 return check_typval_type(&t_bool, tv, where);
55 }
56 return OK;
57}
58
59/*
60 * Clear ppconst constants. Used when failing.
61 */
62 void
63clear_ppconst(ppconst_T *ppconst)
64{
65 int i;
66
67 for (i = 0; i < ppconst->pp_used; ++i)
68 clear_tv(&ppconst->pp_tv[i]);
69 ppconst->pp_used = 0;
70}
71
72/*
73 * Compile getting a member from a list/dict/string/blob. Stack has the
74 * indexable value and the index or the two indexes of a slice.
75 * "keeping_dict" is used for dict[func](arg) to pass dict to func.
76 */
77 int
78compile_member(int is_slice, int *keeping_dict, cctx_T *cctx)
79{
80 type_T **typep;
81 garray_T *stack = &cctx->ctx_type_stack;
82 vartype_T vartype;
83 type_T *idxtype;
84
85 // We can index a list, dict and blob. If we don't know the type
86 // we can use the index value type. If we still don't know use an "ANY"
87 // instruction.
88 typep = ((type_T **)stack->ga_data) + stack->ga_len
89 - (is_slice ? 3 : 2);
90 vartype = (*typep)->tt_type;
91 idxtype = ((type_T **)stack->ga_data)[stack->ga_len - 1];
92 // If the index is a string, the variable must be a Dict.
93 if (*typep == &t_any && idxtype == &t_string)
94 vartype = VAR_DICT;
95 if (vartype == VAR_STRING || vartype == VAR_LIST || vartype == VAR_BLOB)
96 {
97 if (need_type(idxtype, &t_number, -1, 0, cctx, FALSE, FALSE) == FAIL)
98 return FAIL;
99 if (is_slice)
100 {
101 idxtype = ((type_T **)stack->ga_data)[stack->ga_len - 2];
102 if (need_type(idxtype, &t_number, -2, 0, cctx,
103 FALSE, FALSE) == FAIL)
104 return FAIL;
105 }
106 }
107
108 if (vartype == VAR_DICT)
109 {
110 if (is_slice)
111 {
112 emsg(_(e_cannot_slice_dictionary));
113 return FAIL;
114 }
115 if ((*typep)->tt_type == VAR_DICT)
116 {
117 *typep = (*typep)->tt_member;
118 if (*typep == &t_unknown)
119 // empty dict was used
120 *typep = &t_any;
121 }
122 else
123 {
124 if (need_type(*typep, &t_dict_any, -2, 0, cctx,
125 FALSE, FALSE) == FAIL)
126 return FAIL;
127 *typep = &t_any;
128 }
129 if (may_generate_2STRING(-1, FALSE, cctx) == FAIL)
130 return FAIL;
131 if (generate_instr_drop(cctx, ISN_MEMBER, 1) == FAIL)
132 return FAIL;
133 if (keeping_dict != NULL)
134 *keeping_dict = TRUE;
135 }
136 else if (vartype == VAR_STRING)
137 {
138 *typep = &t_string;
139 if ((is_slice
140 ? generate_instr_drop(cctx, ISN_STRSLICE, 2)
141 : generate_instr_drop(cctx, ISN_STRINDEX, 1)) == FAIL)
142 return FAIL;
143 }
144 else if (vartype == VAR_BLOB)
145 {
146 if (is_slice)
147 {
148 *typep = &t_blob;
149 if (generate_instr_drop(cctx, ISN_BLOBSLICE, 2) == FAIL)
150 return FAIL;
151 }
152 else
153 {
154 *typep = &t_number;
155 if (generate_instr_drop(cctx, ISN_BLOBINDEX, 1) == FAIL)
156 return FAIL;
157 }
158 }
159 else if (vartype == VAR_LIST || *typep == &t_any)
160 {
161 if (is_slice)
162 {
163 if (generate_instr_drop(cctx,
164 vartype == VAR_LIST ? ISN_LISTSLICE : ISN_ANYSLICE,
165 2) == FAIL)
166 return FAIL;
167 }
168 else
169 {
170 if ((*typep)->tt_type == VAR_LIST)
171 {
172 *typep = (*typep)->tt_member;
173 if (*typep == &t_unknown)
174 // empty list was used
175 *typep = &t_any;
176 }
177 if (generate_instr_drop(cctx,
178 vartype == VAR_LIST ? ISN_LISTINDEX : ISN_ANYINDEX, 1)
179 == FAIL)
180 return FAIL;
181 }
182 }
183 else
184 {
185 switch (vartype)
186 {
187 case VAR_FUNC:
188 case VAR_PARTIAL:
189 emsg(_(e_cannot_index_a_funcref));
190 break;
191 case VAR_BOOL:
192 case VAR_SPECIAL:
193 case VAR_JOB:
194 case VAR_CHANNEL:
195 case VAR_INSTR:
196 case VAR_UNKNOWN:
197 case VAR_ANY:
198 case VAR_VOID:
199 emsg(_(e_cannot_index_special_variable));
200 break;
201 default:
202 emsg(_(e_string_list_dict_or_blob_required));
203 }
204 return FAIL;
205 }
206 return OK;
207}
208
209/*
210 * Generate an instruction to load script-local variable "name", without the
211 * leading "s:".
212 * Also finds imported variables.
213 */
214 int
215compile_load_scriptvar(
216 cctx_T *cctx,
217 char_u *name, // variable NUL terminated
218 char_u *start, // start of variable
219 char_u **end, // end of variable
220 int error) // when TRUE may give error
221{
222 scriptitem_T *si;
223 int idx;
224 imported_T *import;
225
226 if (!SCRIPT_ID_VALID(current_sctx.sc_sid))
227 return FAIL;
228 si = SCRIPT_ITEM(current_sctx.sc_sid);
229 idx = get_script_item_idx(current_sctx.sc_sid, name, 0, cctx);
230 if (idx == -1 || si->sn_version != SCRIPT_VERSION_VIM9)
231 {
232 // variable is not in sn_var_vals: old style script.
233 return generate_OLDSCRIPT(cctx, ISN_LOADS, name, current_sctx.sc_sid,
234 &t_any);
235 }
236 if (idx >= 0)
237 {
238 svar_T *sv = ((svar_T *)si->sn_var_vals.ga_data) + idx;
239
240 generate_VIM9SCRIPT(cctx, ISN_LOADSCRIPT,
241 current_sctx.sc_sid, idx, sv->sv_type);
242 return OK;
243 }
244
245 import = find_imported(name, 0, cctx);
246 if (import != NULL)
247 {
248 if (import->imp_flags & IMP_FLAGS_STAR)
249 {
250 char_u *p = skipwhite(*end);
251 char_u *exp_name;
252 int cc;
253 ufunc_T *ufunc;
254 type_T *type;
255
256 // Used "import * as Name", need to lookup the member.
257 if (*p != '.')
258 {
259 semsg(_(e_expected_dot_after_name_str), start);
260 return FAIL;
261 }
262 ++p;
263 if (VIM_ISWHITE(*p))
264 {
265 emsg(_(e_no_white_space_allowed_after_dot));
266 return FAIL;
267 }
268
269 // isolate one name
270 exp_name = p;
271 while (eval_isnamec(*p))
272 ++p;
273 cc = *p;
274 *p = NUL;
275
276 idx = find_exported(import->imp_sid, exp_name, &ufunc, &type,
277 cctx, TRUE);
278 *p = cc;
279 p = skipwhite(p);
280 *end = p;
281
282 if (idx < 0)
283 {
284 if (*p == '(' && ufunc != NULL)
285 {
286 generate_PUSHFUNC(cctx, ufunc->uf_name, import->imp_type);
287 return OK;
288 }
289 return FAIL;
290 }
291
292 generate_VIM9SCRIPT(cctx, ISN_LOADSCRIPT,
293 import->imp_sid,
294 idx,
295 type);
296 }
297 else if (import->imp_funcname != NULL)
298 generate_PUSHFUNC(cctx, import->imp_funcname, import->imp_type);
299 else
300 generate_VIM9SCRIPT(cctx, ISN_LOADSCRIPT,
301 import->imp_sid,
302 import->imp_var_vals_idx,
303 import->imp_type);
304 return OK;
305 }
306
307 if (error)
308 semsg(_(e_item_not_found_str), name);
309 return FAIL;
310}
311
312 static int
313generate_funcref(cctx_T *cctx, char_u *name)
314{
315 ufunc_T *ufunc = find_func(name, FALSE, cctx);
316
317 if (ufunc == NULL)
318 return FAIL;
319
320 // Need to compile any default values to get the argument types.
321 if (func_needs_compiling(ufunc, COMPILE_TYPE(ufunc))
322 && compile_def_function(ufunc, TRUE, COMPILE_TYPE(ufunc), NULL)
323 == FAIL)
324 return FAIL;
325 return generate_PUSHFUNC(cctx, ufunc->uf_name, ufunc->uf_func_type);
326}
327
328/*
329 * Compile a variable name into a load instruction.
330 * "end" points to just after the name.
331 * "is_expr" is TRUE when evaluating an expression, might be a funcref.
332 * When "error" is FALSE do not give an error when not found.
333 */
334 int
335compile_load(
336 char_u **arg,
337 char_u *end_arg,
338 cctx_T *cctx,
339 int is_expr,
340 int error)
341{
342 type_T *type;
343 char_u *name = NULL;
344 char_u *end = end_arg;
345 int res = FAIL;
346 int prev_called_emsg = called_emsg;
347
348 if (*(*arg + 1) == ':')
349 {
350 if (end <= *arg + 2)
351 {
352 isntype_T isn_type;
353
354 // load dictionary of namespace
355 switch (**arg)
356 {
357 case 'g': isn_type = ISN_LOADGDICT; break;
358 case 'w': isn_type = ISN_LOADWDICT; break;
359 case 't': isn_type = ISN_LOADTDICT; break;
360 case 'b': isn_type = ISN_LOADBDICT; break;
361 default:
362 semsg(_(e_namespace_not_supported_str), *arg);
363 goto theend;
364 }
365 if (generate_instr_type(cctx, isn_type, &t_dict_any) == NULL)
366 goto theend;
367 res = OK;
368 }
369 else
370 {
371 isntype_T isn_type = ISN_DROP;
372
373 // load namespaced variable
374 name = vim_strnsave(*arg + 2, end - (*arg + 2));
375 if (name == NULL)
376 return FAIL;
377
378 switch (**arg)
379 {
380 case 'v': res = generate_LOADV(cctx, name, error);
381 break;
382 case 's': if (is_expr && ASCII_ISUPPER(*name)
383 && find_func(name, FALSE, cctx) != NULL)
384 res = generate_funcref(cctx, name);
385 else
386 res = compile_load_scriptvar(cctx, name,
387 NULL, &end, error);
388 break;
389 case 'g': if (vim_strchr(name, AUTOLOAD_CHAR) == NULL)
390 {
391 if (is_expr && ASCII_ISUPPER(*name)
392 && find_func(name, FALSE, cctx) != NULL)
393 res = generate_funcref(cctx, name);
394 else
395 isn_type = ISN_LOADG;
396 }
397 else
398 {
399 isn_type = ISN_LOADAUTO;
400 vim_free(name);
401 name = vim_strnsave(*arg, end - *arg);
402 if (name == NULL)
403 return FAIL;
404 }
405 break;
406 case 'w': isn_type = ISN_LOADW; break;
407 case 't': isn_type = ISN_LOADT; break;
408 case 'b': isn_type = ISN_LOADB; break;
409 default: // cannot happen, just in case
410 semsg(_(e_namespace_not_supported_str), *arg);
411 goto theend;
412 }
413 if (isn_type != ISN_DROP)
414 {
415 // Global, Buffer-local, Window-local and Tabpage-local
416 // variables can be defined later, thus we don't check if it
417 // exists, give an error at runtime.
418 res = generate_LOAD(cctx, isn_type, 0, name, &t_any);
419 }
420 }
421 }
422 else
423 {
424 size_t len = end - *arg;
425 int idx;
426 int gen_load = FALSE;
427 int gen_load_outer = 0;
428
429 name = vim_strnsave(*arg, end - *arg);
430 if (name == NULL)
431 return FAIL;
432
433 if (vim_strchr(name, AUTOLOAD_CHAR) != NULL)
434 {
435 script_autoload(name, FALSE);
436 res = generate_LOAD(cctx, ISN_LOADAUTO, 0, name, &t_any);
437 }
438 else if (arg_exists(*arg, len, &idx, &type, &gen_load_outer, cctx)
439 == OK)
440 {
441 if (gen_load_outer == 0)
442 gen_load = TRUE;
443 }
444 else
445 {
446 lvar_T lvar;
447
448 if (lookup_local(*arg, len, &lvar, cctx) == OK)
449 {
450 type = lvar.lv_type;
451 idx = lvar.lv_idx;
452 if (lvar.lv_from_outer != 0)
453 gen_load_outer = lvar.lv_from_outer;
454 else
455 gen_load = TRUE;
456 }
457 else
458 {
459 // "var" can be script-local even without using "s:" if it
460 // already exists in a Vim9 script or when it's imported.
461 if (script_var_exists(*arg, len, cctx) == OK
462 || find_imported(name, 0, cctx) != NULL)
463 res = compile_load_scriptvar(cctx, name, *arg, &end, FALSE);
464
465 // When evaluating an expression and the name starts with an
466 // uppercase letter it can be a user defined function.
467 // generate_funcref() will fail if the function can't be found.
468 if (res == FAIL && is_expr && ASCII_ISUPPER(*name))
469 res = generate_funcref(cctx, name);
470 }
471 }
472 if (gen_load)
473 res = generate_LOAD(cctx, ISN_LOAD, idx, NULL, type);
474 if (gen_load_outer > 0)
475 {
476 res = generate_LOADOUTER(cctx, idx, gen_load_outer, type);
477 cctx->ctx_outer_used = TRUE;
478 }
479 }
480
481 *arg = end;
482
483theend:
484 if (res == FAIL && error && called_emsg == prev_called_emsg)
485 semsg(_(e_variable_not_found_str), name);
486 vim_free(name);
487 return res;
488}
489
490/*
491 * Compile a string in a ISN_PUSHS instruction into an ISN_INSTR.
492 * Returns FAIL if compilation fails.
493 */
494 static int
495compile_string(isn_T *isn, cctx_T *cctx)
496{
497 char_u *s = isn->isn_arg.string;
498 garray_T save_ga = cctx->ctx_instr;
499 int expr_res;
500 int trailing_error;
501 int instr_count;
502 isn_T *instr = NULL;
503
504 // Remove the string type from the stack.
505 --cctx->ctx_type_stack.ga_len;
506
507 // Temporarily reset the list of instructions so that the jump labels are
508 // correct.
509 cctx->ctx_instr.ga_len = 0;
510 cctx->ctx_instr.ga_maxlen = 0;
511 cctx->ctx_instr.ga_data = NULL;
512 expr_res = compile_expr0(&s, cctx);
513 s = skipwhite(s);
514 trailing_error = *s != NUL;
515
516 if (expr_res == FAIL || trailing_error
517 || GA_GROW_FAILS(&cctx->ctx_instr, 1))
518 {
519 if (trailing_error)
520 semsg(_(e_trailing_arg), s);
521 clear_instr_ga(&cctx->ctx_instr);
522 cctx->ctx_instr = save_ga;
523 ++cctx->ctx_type_stack.ga_len;
524 return FAIL;
525 }
526
527 // Move the generated instructions into the ISN_INSTR instruction, then
528 // restore the list of instructions.
529 instr_count = cctx->ctx_instr.ga_len;
530 instr = cctx->ctx_instr.ga_data;
531 instr[instr_count].isn_type = ISN_FINISH;
532
533 cctx->ctx_instr = save_ga;
534 vim_free(isn->isn_arg.string);
535 isn->isn_type = ISN_INSTR;
536 isn->isn_arg.instr = instr;
537 return OK;
538}
539
540/*
541 * Compile the argument expressions.
542 * "arg" points to just after the "(" and is advanced to after the ")"
543 */
544 static int
545compile_arguments(char_u **arg, cctx_T *cctx, int *argcount, int is_searchpair)
546{
547 char_u *p = *arg;
548 char_u *whitep = *arg;
549 int must_end = FALSE;
550 int instr_count;
551
552 for (;;)
553 {
554 if (may_get_next_line(whitep, &p, cctx) == FAIL)
555 goto failret;
556 if (*p == ')')
557 {
558 *arg = p + 1;
559 return OK;
560 }
561 if (must_end)
562 {
563 semsg(_(e_missing_comma_before_argument_str), p);
564 return FAIL;
565 }
566
567 instr_count = cctx->ctx_instr.ga_len;
568 if (compile_expr0(&p, cctx) == FAIL)
569 return FAIL;
570 ++*argcount;
571
572 if (is_searchpair && *argcount == 5
573 && cctx->ctx_instr.ga_len == instr_count + 1)
574 {
575 isn_T *isn = ((isn_T *)cctx->ctx_instr.ga_data) + instr_count;
576
577 // {skip} argument of searchpair() can be compiled if not empty
578 if (isn->isn_type == ISN_PUSHS && *isn->isn_arg.string != NUL)
579 compile_string(isn, cctx);
580 }
581
582 if (*p != ',' && *skipwhite(p) == ',')
583 {
584 semsg(_(e_no_white_space_allowed_before_str_str), ",", p);
585 p = skipwhite(p);
586 }
587 if (*p == ',')
588 {
589 ++p;
590 if (*p != NUL && !VIM_ISWHITE(*p))
591 semsg(_(e_white_space_required_after_str_str), ",", p - 1);
592 }
593 else
594 must_end = TRUE;
595 whitep = p;
596 p = skipwhite(p);
597 }
598failret:
599 emsg(_(e_missing_closing_paren));
600 return FAIL;
601}
602
603/*
604 * Compile a function call: name(arg1, arg2)
605 * "arg" points to "name", "arg + varlen" to the "(".
606 * "argcount_init" is 1 for "value->method()"
607 * Instructions:
608 * EVAL arg1
609 * EVAL arg2
610 * BCALL / DCALL / UCALL
611 */
612 static int
613compile_call(
614 char_u **arg,
615 size_t varlen,
616 cctx_T *cctx,
617 ppconst_T *ppconst,
618 int argcount_init)
619{
620 char_u *name = *arg;
621 char_u *p;
622 int argcount = argcount_init;
623 char_u namebuf[100];
624 char_u fname_buf[FLEN_FIXED + 1];
625 char_u *tofree = NULL;
626 int error = FCERR_NONE;
627 ufunc_T *ufunc = NULL;
628 int res = FAIL;
629 int is_autoload;
630 int is_searchpair;
631
632 // We can evaluate "has('name')" at compile time.
633 // We always evaluate "exists_compiled()" at compile time.
634 if ((varlen == 3 && STRNCMP(*arg, "has", 3) == 0)
635 || (varlen == 15 && STRNCMP(*arg, "exists_compiled", 6) == 0))
636 {
637 char_u *s = skipwhite(*arg + varlen + 1);
638 typval_T argvars[2];
639 int is_has = **arg == 'h';
640
641 argvars[0].v_type = VAR_UNKNOWN;
642 if (*s == '"')
643 (void)eval_string(&s, &argvars[0], TRUE);
644 else if (*s == '\'')
645 (void)eval_lit_string(&s, &argvars[0], TRUE);
646 s = skipwhite(s);
647 if (*s == ')' && argvars[0].v_type == VAR_STRING
648 && ((is_has && !dynamic_feature(argvars[0].vval.v_string))
649 || !is_has))
650 {
651 typval_T *tv = &ppconst->pp_tv[ppconst->pp_used];
652
653 *arg = s + 1;
654 argvars[1].v_type = VAR_UNKNOWN;
655 tv->v_type = VAR_NUMBER;
656 tv->vval.v_number = 0;
657 if (is_has)
658 f_has(argvars, tv);
659 else
660 f_exists(argvars, tv);
661 clear_tv(&argvars[0]);
662 ++ppconst->pp_used;
663 return OK;
664 }
665 clear_tv(&argvars[0]);
666 if (!is_has)
667 {
668 emsg(_(e_argument_of_exists_compiled_must_be_literal_string));
669 return FAIL;
670 }
671 }
672
673 if (generate_ppconst(cctx, ppconst) == FAIL)
674 return FAIL;
675
676 if (varlen >= sizeof(namebuf))
677 {
678 semsg(_(e_name_too_long_str), name);
679 return FAIL;
680 }
681 vim_strncpy(namebuf, *arg, varlen);
682 name = fname_trans_sid(namebuf, fname_buf, &tofree, &error);
683
684 // We handle the "skip" argument of searchpair() and searchpairpos()
685 // differently.
686 is_searchpair = (varlen == 6 && STRNCMP(*arg, "search", 6) == 0)
687 || (varlen == 9 && STRNCMP(*arg, "searchpos", 9) == 0)
688 || (varlen == 10 && STRNCMP(*arg, "searchpair", 10) == 0)
689 || (varlen == 13 && STRNCMP(*arg, "searchpairpos", 13) == 0);
690
691 *arg = skipwhite(*arg + varlen + 1);
692 if (compile_arguments(arg, cctx, &argcount, is_searchpair) == FAIL)
693 goto theend;
694
695 is_autoload = vim_strchr(name, AUTOLOAD_CHAR) != NULL;
696 if (ASCII_ISLOWER(*name) && name[1] != ':' && !is_autoload)
697 {
698 int idx;
699
700 // builtin function
701 idx = find_internal_func(name);
702 if (idx >= 0)
703 {
704 if (STRCMP(name, "flatten") == 0)
705 {
706 emsg(_(e_cannot_use_flatten_in_vim9_script));
707 goto theend;
708 }
709
710 if (STRCMP(name, "add") == 0 && argcount == 2)
711 {
712 garray_T *stack = &cctx->ctx_type_stack;
713 type_T *type = ((type_T **)stack->ga_data)[
714 stack->ga_len - 2];
715
716 // add() can be compiled to instructions if we know the type
717 if (type->tt_type == VAR_LIST)
718 {
719 // inline "add(list, item)" so that the type can be checked
720 res = generate_LISTAPPEND(cctx);
721 idx = -1;
722 }
723 else if (type->tt_type == VAR_BLOB)
724 {
725 // inline "add(blob, nr)" so that the type can be checked
726 res = generate_BLOBAPPEND(cctx);
727 idx = -1;
728 }
729 }
730
731 if (idx >= 0)
732 res = generate_BCALL(cctx, idx, argcount, argcount_init == 1);
733 }
734 else
735 semsg(_(e_unknown_function_str), namebuf);
736 goto theend;
737 }
738
739 // An argument or local variable can be a function reference, this
740 // overrules a function name.
741 if (lookup_local(namebuf, varlen, NULL, cctx) == FAIL
742 && arg_exists(namebuf, varlen, NULL, NULL, NULL, cctx) != OK)
743 {
744 // If we can find the function by name generate the right call.
745 // Skip global functions here, a local funcref takes precedence.
746 ufunc = find_func(name, FALSE, cctx);
747 if (ufunc != NULL && !func_is_global(ufunc))
748 {
749 res = generate_CALL(cctx, ufunc, argcount);
750 goto theend;
751 }
752 }
753
754 // If the name is a variable, load it and use PCALL.
755 // Not for g:Func(), we don't know if it is a variable or not.
756 // Not for eome#Func(), it will be loaded later.
757 p = namebuf;
758 if (STRNCMP(namebuf, "g:", 2) != 0 && !is_autoload
759 && compile_load(&p, namebuf + varlen, cctx, FALSE, FALSE) == OK)
760 {
761 garray_T *stack = &cctx->ctx_type_stack;
762 type_T *type = ((type_T **)stack->ga_data)[stack->ga_len - 1];
763
764 res = generate_PCALL(cctx, argcount, namebuf, type, FALSE);
765 goto theend;
766 }
767
768 // If we can find a global function by name generate the right call.
769 if (ufunc != NULL)
770 {
771 res = generate_CALL(cctx, ufunc, argcount);
772 goto theend;
773 }
774
775 // A global function may be defined only later. Need to figure out at
776 // runtime. Also handles a FuncRef at runtime.
777 if (STRNCMP(namebuf, "g:", 2) == 0 || is_autoload)
778 res = generate_UCALL(cctx, name, argcount);
779 else
780 semsg(_(e_unknown_function_str), namebuf);
781
782theend:
783 vim_free(tofree);
784 return res;
785}
786
787// like NAMESPACE_CHAR but with 'a' and 'l'.
788#define VIM9_NAMESPACE_CHAR (char_u *)"bgstvw"
789
790/*
791 * Find the end of a variable or function name. Unlike find_name_end() this
792 * does not recognize magic braces.
793 * When "use_namespace" is TRUE recognize "b:", "s:", etc.
794 * Return a pointer to just after the name. Equal to "arg" if there is no
795 * valid name.
796 */
797 char_u *
798to_name_end(char_u *arg, int use_namespace)
799{
800 char_u *p;
801
802 // Quick check for valid starting character.
803 if (!eval_isnamec1(*arg))
804 return arg;
805
806 for (p = arg + 1; *p != NUL && eval_isnamec(*p); MB_PTR_ADV(p))
807 // Include a namespace such as "s:var" and "v:var". But "n:" is not
808 // and can be used in slice "[n:]".
809 if (*p == ':' && (p != arg + 1
810 || !use_namespace
811 || vim_strchr(VIM9_NAMESPACE_CHAR, *arg) == NULL))
812 break;
813 return p;
814}
815
816/*
817 * Like to_name_end() but also skip over a list or dict constant.
818 * Also accept "<SNR>123_Func".
819 * This intentionally does not handle line continuation.
820 */
821 char_u *
822to_name_const_end(char_u *arg)
823{
824 char_u *p = arg;
825 typval_T rettv;
826
827 if (STRNCMP(p, "<SNR>", 5) == 0)
828 p = skipdigits(p + 5);
829 p = to_name_end(p, TRUE);
830 if (p == arg && *arg == '[')
831 {
832
833 // Can be "[1, 2, 3]->Func()".
834 if (eval_list(&p, &rettv, NULL, FALSE) == FAIL)
835 p = arg;
836 }
837 return p;
838}
839
840/*
841 * parse a list: [expr, expr]
842 * "*arg" points to the '['.
843 * ppconst->pp_is_const is set if all items are a constant.
844 */
845 static int
846compile_list(char_u **arg, cctx_T *cctx, ppconst_T *ppconst)
847{
848 char_u *p = skipwhite(*arg + 1);
849 char_u *whitep = *arg + 1;
850 int count = 0;
851 int is_const;
852 int is_all_const = TRUE; // reset when non-const encountered
853
854 for (;;)
855 {
856 if (may_get_next_line(whitep, &p, cctx) == FAIL)
857 {
858 semsg(_(e_list_end), *arg);
859 return FAIL;
860 }
861 if (*p == ',')
862 {
863 semsg(_(e_no_white_space_allowed_before_str_str), ",", p);
864 return FAIL;
865 }
866 if (*p == ']')
867 {
868 ++p;
869 break;
870 }
871 if (compile_expr0_ext(&p, cctx, &is_const) == FAIL)
872 return FAIL;
873 if (!is_const)
874 is_all_const = FALSE;
875 ++count;
876 if (*p == ',')
877 {
878 ++p;
879 if (*p != ']' && !IS_WHITE_OR_NUL(*p))
880 {
881 semsg(_(e_white_space_required_after_str_str), ",", p - 1);
882 return FAIL;
883 }
884 }
885 whitep = p;
886 p = skipwhite(p);
887 }
888 *arg = p;
889
890 ppconst->pp_is_const = is_all_const;
891 return generate_NEWLIST(cctx, count);
892}
893
894/*
895 * Parse a lambda: "(arg, arg) => expr"
896 * "*arg" points to the '('.
897 * Returns OK/FAIL when a lambda is recognized, NOTDONE if it's not a lambda.
898 */
899 static int
900compile_lambda(char_u **arg, cctx_T *cctx)
901{
902 int r;
903 typval_T rettv;
904 ufunc_T *ufunc;
905 evalarg_T evalarg;
906
907 init_evalarg(&evalarg);
908 evalarg.eval_flags = EVAL_EVALUATE;
909 evalarg.eval_cctx = cctx;
910
911 // Get the funcref in "rettv".
912 r = get_lambda_tv(arg, &rettv, TRUE, &evalarg);
913 if (r != OK)
914 {
915 clear_evalarg(&evalarg, NULL);
916 return r;
917 }
918
919 // "rettv" will now be a partial referencing the function.
920 ufunc = rettv.vval.v_partial->pt_func;
921 ++ufunc->uf_refcount;
922 clear_tv(&rettv);
923
924 // Compile it here to get the return type. The return type is optional,
925 // when it's missing use t_unknown. This is recognized in
926 // compile_return().
927 if (ufunc->uf_ret_type->tt_type == VAR_VOID)
928 ufunc->uf_ret_type = &t_unknown;
929 compile_def_function(ufunc, FALSE, cctx->ctx_compile_type, cctx);
930
931 // When the outer function is compiled for profiling or debugging, the
932 // lambda may be called without profiling or debugging. Compile it here in
933 // the right context.
934 if (cctx->ctx_compile_type == CT_DEBUG
935#ifdef FEAT_PROFILE
936 || cctx->ctx_compile_type == CT_PROFILE
937#endif
938 )
939 compile_def_function(ufunc, FALSE, CT_NONE, cctx);
940
941 // The last entry in evalarg.eval_tofree_ga is a copy of the last line and
942 // "*arg" may point into it. Point into the original line to avoid a
943 // dangling pointer.
944 if (evalarg.eval_using_cmdline)
945 {
946 garray_T *gap = &evalarg.eval_tofree_ga;
947 size_t off = *arg - ((char_u **)gap->ga_data)[gap->ga_len - 1];
948
949 *arg = ((char_u **)cctx->ctx_ufunc->uf_lines.ga_data)[cctx->ctx_lnum]
950 + off;
951 }
952
953 clear_evalarg(&evalarg, NULL);
954
955 if (ufunc->uf_def_status == UF_COMPILED)
956 {
957 // The return type will now be known.
958 set_function_type(ufunc);
959
960 // The function reference count will be 1. When the ISN_FUNCREF
961 // instruction is deleted the reference count is decremented and the
962 // function is freed.
963 return generate_FUNCREF(cctx, ufunc);
964 }
965
966 func_ptr_unref(ufunc);
967 return FAIL;
968}
969
970/*
971 * Get a lambda and compile it. Uses Vim9 syntax.
972 */
973 int
974get_lambda_tv_and_compile(
975 char_u **arg,
976 typval_T *rettv,
977 int types_optional,
978 evalarg_T *evalarg)
979{
980 int r;
981 ufunc_T *ufunc;
982 int save_sc_version = current_sctx.sc_version;
983
984 // Get the funcref in "rettv".
985 current_sctx.sc_version = SCRIPT_VERSION_VIM9;
986 r = get_lambda_tv(arg, rettv, types_optional, evalarg);
987 current_sctx.sc_version = save_sc_version;
988 if (r != OK)
989 return r;
990
991 // "rettv" will now be a partial referencing the function.
992 ufunc = rettv->vval.v_partial->pt_func;
993
994 // Compile it here to get the return type. The return type is optional,
995 // when it's missing use t_unknown. This is recognized in
996 // compile_return().
997 if (ufunc->uf_ret_type == NULL || ufunc->uf_ret_type->tt_type == VAR_VOID)
998 ufunc->uf_ret_type = &t_unknown;
999 compile_def_function(ufunc, FALSE, CT_NONE, NULL);
1000
1001 if (ufunc->uf_def_status == UF_COMPILED)
1002 {
1003 // The return type will now be known.
1004 set_function_type(ufunc);
1005 return OK;
1006 }
1007 clear_tv(rettv);
1008 return FAIL;
1009}
1010
1011/*
1012 * parse a dict: {key: val, [key]: val}
1013 * "*arg" points to the '{'.
1014 * ppconst->pp_is_const is set if all item values are a constant.
1015 */
1016 static int
1017compile_dict(char_u **arg, cctx_T *cctx, ppconst_T *ppconst)
1018{
1019 garray_T *instr = &cctx->ctx_instr;
1020 int count = 0;
1021 dict_T *d = dict_alloc();
1022 dictitem_T *item;
1023 char_u *whitep = *arg + 1;
1024 char_u *p;
1025 int is_const;
1026 int is_all_const = TRUE; // reset when non-const encountered
1027
1028 if (d == NULL)
1029 return FAIL;
1030 if (generate_ppconst(cctx, ppconst) == FAIL)
1031 return FAIL;
1032 for (;;)
1033 {
1034 char_u *key = NULL;
1035
1036 if (may_get_next_line(whitep, arg, cctx) == FAIL)
1037 {
1038 *arg = NULL;
1039 goto failret;
1040 }
1041
1042 if (**arg == '}')
1043 break;
1044
1045 if (**arg == '[')
1046 {
1047 isn_T *isn;
1048
1049 // {[expr]: value} uses an evaluated key.
1050 *arg = skipwhite(*arg + 1);
1051 if (compile_expr0(arg, cctx) == FAIL)
1052 return FAIL;
1053 isn = ((isn_T *)instr->ga_data) + instr->ga_len - 1;
1054 if (isn->isn_type == ISN_PUSHNR)
1055 {
1056 char buf[NUMBUFLEN];
1057
1058 // Convert to string at compile time.
1059 vim_snprintf(buf, NUMBUFLEN, "%lld", isn->isn_arg.number);
1060 isn->isn_type = ISN_PUSHS;
1061 isn->isn_arg.string = vim_strsave((char_u *)buf);
1062 }
1063 if (isn->isn_type == ISN_PUSHS)
1064 key = isn->isn_arg.string;
1065 else if (may_generate_2STRING(-1, FALSE, cctx) == FAIL)
1066 return FAIL;
1067 *arg = skipwhite(*arg);
1068 if (**arg != ']')
1069 {
1070 emsg(_(e_missing_matching_bracket_after_dict_key));
1071 return FAIL;
1072 }
1073 ++*arg;
1074 }
1075 else
1076 {
1077 // {"name": value},
1078 // {'name': value},
1079 // {name: value} use "name" as a literal key
1080 key = get_literal_key(arg);
1081 if (key == NULL)
1082 return FAIL;
1083 if (generate_PUSHS(cctx, &key) == FAIL)
1084 return FAIL;
1085 }
1086
1087 // Check for duplicate keys, if using string keys.
1088 if (key != NULL)
1089 {
1090 item = dict_find(d, key, -1);
1091 if (item != NULL)
1092 {
1093 semsg(_(e_duplicate_key), key);
1094 goto failret;
1095 }
1096 item = dictitem_alloc(key);
1097 if (item != NULL)
1098 {
1099 item->di_tv.v_type = VAR_UNKNOWN;
1100 item->di_tv.v_lock = 0;
1101 if (dict_add(d, item) == FAIL)
1102 dictitem_free(item);
1103 }
1104 }
1105
1106 if (**arg != ':')
1107 {
1108 if (*skipwhite(*arg) == ':')
1109 semsg(_(e_no_white_space_allowed_before_str_str), ":", *arg);
1110 else
1111 semsg(_(e_missing_dict_colon), *arg);
1112 return FAIL;
1113 }
1114 whitep = *arg + 1;
1115 if (!IS_WHITE_OR_NUL(*whitep))
1116 {
1117 semsg(_(e_white_space_required_after_str_str), ":", *arg);
1118 return FAIL;
1119 }
1120
1121 if (may_get_next_line(whitep, arg, cctx) == FAIL)
1122 {
1123 *arg = NULL;
1124 goto failret;
1125 }
1126
1127 if (compile_expr0_ext(arg, cctx, &is_const) == FAIL)
1128 return FAIL;
1129 if (!is_const)
1130 is_all_const = FALSE;
1131 ++count;
1132
1133 whitep = *arg;
1134 if (may_get_next_line(whitep, arg, cctx) == FAIL)
1135 {
1136 *arg = NULL;
1137 goto failret;
1138 }
1139 if (**arg == '}')
1140 break;
1141 if (**arg != ',')
1142 {
1143 semsg(_(e_missing_dict_comma), *arg);
1144 goto failret;
1145 }
1146 if (IS_WHITE_OR_NUL(*whitep))
1147 {
1148 semsg(_(e_no_white_space_allowed_before_str_str), ",", whitep);
1149 return FAIL;
1150 }
1151 whitep = *arg + 1;
1152 if (!IS_WHITE_OR_NUL(*whitep))
1153 {
1154 semsg(_(e_white_space_required_after_str_str), ",", *arg);
1155 return FAIL;
1156 }
1157 *arg = skipwhite(whitep);
1158 }
1159
1160 *arg = *arg + 1;
1161
1162 // Allow for following comment, after at least one space.
1163 p = skipwhite(*arg);
1164 if (VIM_ISWHITE(**arg) && vim9_comment_start(p))
1165 *arg += STRLEN(*arg);
1166
1167 dict_unref(d);
1168 ppconst->pp_is_const = is_all_const;
1169 return generate_NEWDICT(cctx, count);
1170
1171failret:
1172 if (*arg == NULL)
1173 {
1174 semsg(_(e_missing_dict_end), _("[end of lines]"));
1175 *arg = (char_u *)"";
1176 }
1177 dict_unref(d);
1178 return FAIL;
1179}
1180
1181/*
1182 * Compile "&option".
1183 */
1184 static int
1185compile_get_option(char_u **arg, cctx_T *cctx)
1186{
1187 typval_T rettv;
1188 char_u *start = *arg;
1189 int ret;
1190
1191 // parse the option and get the current value to get the type.
1192 rettv.v_type = VAR_UNKNOWN;
1193 ret = eval_option(arg, &rettv, TRUE);
1194 if (ret == OK)
1195 {
1196 // include the '&' in the name, eval_option() expects it.
1197 char_u *name = vim_strnsave(start, *arg - start);
1198 type_T *type = rettv.v_type == VAR_BOOL ? &t_bool
1199 : rettv.v_type == VAR_NUMBER ? &t_number : &t_string;
1200
1201 ret = generate_LOAD(cctx, ISN_LOADOPT, 0, name, type);
1202 vim_free(name);
1203 }
1204 clear_tv(&rettv);
1205
1206 return ret;
1207}
1208
1209/*
1210 * Compile "$VAR".
1211 */
1212 static int
1213compile_get_env(char_u **arg, cctx_T *cctx)
1214{
1215 char_u *start = *arg;
1216 int len;
1217 int ret;
1218 char_u *name;
1219
1220 ++*arg;
1221 len = get_env_len(arg);
1222 if (len == 0)
1223 {
1224 semsg(_(e_syntax_error_at_str), start - 1);
1225 return FAIL;
1226 }
1227
1228 // include the '$' in the name, eval_env_var() expects it.
1229 name = vim_strnsave(start, len + 1);
1230 ret = generate_LOAD(cctx, ISN_LOADENV, 0, name, &t_string);
1231 vim_free(name);
1232 return ret;
1233}
1234
1235/*
1236 * Compile "@r".
1237 */
1238 static int
1239compile_get_register(char_u **arg, cctx_T *cctx)
1240{
1241 int ret;
1242
1243 ++*arg;
1244 if (**arg == NUL)
1245 {
1246 semsg(_(e_syntax_error_at_str), *arg - 1);
1247 return FAIL;
1248 }
1249 if (!valid_yank_reg(**arg, FALSE))
1250 {
1251 emsg_invreg(**arg);
1252 return FAIL;
1253 }
1254 ret = generate_LOAD(cctx, ISN_LOADREG, **arg, NULL, &t_string);
1255 ++*arg;
1256 return ret;
1257}
1258
1259/*
1260 * Apply leading '!', '-' and '+' to constant "rettv".
1261 * When "numeric_only" is TRUE do not apply '!'.
1262 */
1263 static int
1264apply_leader(typval_T *rettv, int numeric_only, char_u *start, char_u **end)
1265{
1266 char_u *p = *end;
1267
1268 // this works from end to start
1269 while (p > start)
1270 {
1271 --p;
1272 if (*p == '-' || *p == '+')
1273 {
1274 // only '-' has an effect, for '+' we only check the type
1275#ifdef FEAT_FLOAT
1276 if (rettv->v_type == VAR_FLOAT)
1277 {
1278 if (*p == '-')
1279 rettv->vval.v_float = -rettv->vval.v_float;
1280 }
1281 else
1282#endif
1283 {
1284 varnumber_T val;
1285 int error = FALSE;
1286
1287 // tv_get_number_chk() accepts a string, but we don't want that
1288 // here
1289 if (check_not_string(rettv) == FAIL)
1290 return FAIL;
1291 val = tv_get_number_chk(rettv, &error);
1292 clear_tv(rettv);
1293 if (error)
1294 return FAIL;
1295 if (*p == '-')
1296 val = -val;
1297 rettv->v_type = VAR_NUMBER;
1298 rettv->vval.v_number = val;
1299 }
1300 }
1301 else if (numeric_only)
1302 {
1303 ++p;
1304 break;
1305 }
1306 else if (*p == '!')
1307 {
1308 int v = tv2bool(rettv);
1309
1310 // '!' is permissive in the type.
1311 clear_tv(rettv);
1312 rettv->v_type = VAR_BOOL;
1313 rettv->vval.v_number = v ? VVAL_FALSE : VVAL_TRUE;
1314 }
1315 }
1316 *end = p;
1317 return OK;
1318}
1319
1320/*
1321 * Recognize v: variables that are constants and set "rettv".
1322 */
1323 static void
1324get_vim_constant(char_u **arg, typval_T *rettv)
1325{
1326 if (STRNCMP(*arg, "v:true", 6) == 0)
1327 {
1328 rettv->v_type = VAR_BOOL;
1329 rettv->vval.v_number = VVAL_TRUE;
1330 *arg += 6;
1331 }
1332 else if (STRNCMP(*arg, "v:false", 7) == 0)
1333 {
1334 rettv->v_type = VAR_BOOL;
1335 rettv->vval.v_number = VVAL_FALSE;
1336 *arg += 7;
1337 }
1338 else if (STRNCMP(*arg, "v:null", 6) == 0)
1339 {
1340 rettv->v_type = VAR_SPECIAL;
1341 rettv->vval.v_number = VVAL_NULL;
1342 *arg += 6;
1343 }
1344 else if (STRNCMP(*arg, "v:none", 6) == 0)
1345 {
1346 rettv->v_type = VAR_SPECIAL;
1347 rettv->vval.v_number = VVAL_NONE;
1348 *arg += 6;
1349 }
1350}
1351
1352 exprtype_T
1353get_compare_type(char_u *p, int *len, int *type_is)
1354{
1355 exprtype_T type = EXPR_UNKNOWN;
1356 int i;
1357
1358 switch (p[0])
1359 {
1360 case '=': if (p[1] == '=')
1361 type = EXPR_EQUAL;
1362 else if (p[1] == '~')
1363 type = EXPR_MATCH;
1364 break;
1365 case '!': if (p[1] == '=')
1366 type = EXPR_NEQUAL;
1367 else if (p[1] == '~')
1368 type = EXPR_NOMATCH;
1369 break;
1370 case '>': if (p[1] != '=')
1371 {
1372 type = EXPR_GREATER;
1373 *len = 1;
1374 }
1375 else
1376 type = EXPR_GEQUAL;
1377 break;
1378 case '<': if (p[1] != '=')
1379 {
1380 type = EXPR_SMALLER;
1381 *len = 1;
1382 }
1383 else
1384 type = EXPR_SEQUAL;
1385 break;
1386 case 'i': if (p[1] == 's')
1387 {
1388 // "is" and "isnot"; but not a prefix of a name
1389 if (p[2] == 'n' && p[3] == 'o' && p[4] == 't')
1390 *len = 5;
1391 i = p[*len];
1392 if (!isalnum(i) && i != '_')
1393 {
1394 type = *len == 2 ? EXPR_IS : EXPR_ISNOT;
1395 *type_is = TRUE;
1396 }
1397 }
1398 break;
1399 }
1400 return type;
1401}
1402
1403/*
1404 * Skip over an expression, ignoring most errors.
1405 */
1406 void
1407skip_expr_cctx(char_u **arg, cctx_T *cctx)
1408{
1409 evalarg_T evalarg;
1410
1411 init_evalarg(&evalarg);
1412 evalarg.eval_cctx = cctx;
1413 skip_expr(arg, &evalarg);
1414 clear_evalarg(&evalarg, NULL);
1415}
1416
1417/*
1418 * Check that the top of the type stack has a type that can be used as a
1419 * condition. Give an error and return FAIL if not.
1420 */
1421 int
1422bool_on_stack(cctx_T *cctx)
1423{
1424 garray_T *stack = &cctx->ctx_type_stack;
1425 type_T *type;
1426
1427 type = ((type_T **)stack->ga_data)[stack->ga_len - 1];
1428 if (type == &t_bool)
1429 return OK;
1430
1431 if (type == &t_any || type == &t_number || type == &t_number_bool)
1432 // Number 0 and 1 are OK to use as a bool. "any" could also be a bool.
1433 // This requires a runtime type check.
1434 return generate_COND2BOOL(cctx);
1435
1436 return need_type(type, &t_bool, -1, 0, cctx, FALSE, FALSE);
1437}
1438
1439/*
1440 * Give the "white on both sides" error, taking the operator from "p[len]".
1441 */
1442 void
1443error_white_both(char_u *op, int len)
1444{
1445 char_u buf[10];
1446
1447 vim_strncpy(buf, op, len);
1448 semsg(_(e_white_space_required_before_and_after_str_at_str), buf, op);
1449}
1450
1451/*
1452 * Compile code to apply '-', '+' and '!'.
1453 * When "numeric_only" is TRUE do not apply '!'.
1454 */
1455 static int
1456compile_leader(cctx_T *cctx, int numeric_only, char_u *start, char_u **end)
1457{
1458 char_u *p = *end;
1459
1460 // this works from end to start
1461 while (p > start)
1462 {
1463 --p;
1464 while (VIM_ISWHITE(*p))
1465 --p;
1466 if (*p == '-' || *p == '+')
1467 {
1468 int negate = *p == '-';
1469 isn_T *isn;
1470 garray_T *stack = &cctx->ctx_type_stack;
1471 type_T *type;
1472
1473 type = ((type_T **)stack->ga_data)[stack->ga_len - 1];
1474 if (type != &t_float && need_type(type, &t_number,
1475 -1, 0, cctx, FALSE, FALSE) == FAIL)
1476 return FAIL;
1477
1478 while (p > start && (p[-1] == '-' || p[-1] == '+'))
1479 {
1480 --p;
1481 if (*p == '-')
1482 negate = !negate;
1483 }
1484 // only '-' has an effect, for '+' we only check the type
1485 if (negate)
1486 {
1487 isn = generate_instr(cctx, ISN_NEGATENR);
1488 if (isn == NULL)
1489 return FAIL;
1490 }
1491 }
1492 else if (numeric_only)
1493 {
1494 ++p;
1495 break;
1496 }
1497 else
1498 {
1499 int invert = *p == '!';
1500
1501 while (p > start && (p[-1] == '!' || VIM_ISWHITE(p[-1])))
1502 {
1503 if (p[-1] == '!')
1504 invert = !invert;
1505 --p;
1506 }
1507 if (generate_2BOOL(cctx, invert, -1) == FAIL)
1508 return FAIL;
1509 }
1510 }
1511 *end = p;
1512 return OK;
1513}
1514
1515/*
1516 * Compile "(expression)": recursive!
1517 * Return FAIL/OK.
1518 */
1519 static int
1520compile_parenthesis(char_u **arg, cctx_T *cctx, ppconst_T *ppconst)
1521{
1522 int ret;
1523 char_u *p = *arg + 1;
1524
1525 if (may_get_next_line_error(p, arg, cctx) == FAIL)
1526 return FAIL;
1527 if (ppconst->pp_used <= PPSIZE - 10)
1528 {
1529 ret = compile_expr1(arg, cctx, ppconst);
1530 }
1531 else
1532 {
1533 // Not enough space in ppconst, flush constants.
1534 if (generate_ppconst(cctx, ppconst) == FAIL)
1535 return FAIL;
1536 ret = compile_expr0(arg, cctx);
1537 }
1538 if (may_get_next_line_error(*arg, arg, cctx) == FAIL)
1539 return FAIL;
1540 if (**arg == ')')
1541 ++*arg;
1542 else if (ret == OK)
1543 {
1544 emsg(_(e_missing_closing_paren));
1545 ret = FAIL;
1546 }
1547 return ret;
1548}
1549
1550/*
1551 * Compile whatever comes after "name" or "name()".
1552 * Advances "*arg" only when something was recognized.
1553 */
1554 static int
1555compile_subscript(
1556 char_u **arg,
1557 cctx_T *cctx,
1558 char_u *start_leader,
1559 char_u **end_leader,
1560 ppconst_T *ppconst)
1561{
1562 char_u *name_start = *end_leader;
1563 int keeping_dict = FALSE;
1564
1565 for (;;)
1566 {
1567 char_u *p = skipwhite(*arg);
1568
1569 if (*p == NUL || (VIM_ISWHITE(**arg) && vim9_comment_start(p)))
1570 {
1571 char_u *next = peek_next_line_from_context(cctx);
1572
1573 // If a following line starts with "->{" or "->X" advance to that
1574 // line, so that a line break before "->" is allowed.
1575 // Also if a following line starts with ".x".
1576 if (next != NULL &&
1577 ((next[0] == '-' && next[1] == '>'
1578 && (next[2] == '{'
1579 || ASCII_ISALPHA(*skipwhite(next + 2))))
1580 || (next[0] == '.' && eval_isdictc(next[1]))))
1581 {
1582 next = next_line_from_context(cctx, TRUE);
1583 if (next == NULL)
1584 return FAIL;
1585 *arg = next;
1586 p = skipwhite(*arg);
1587 }
1588 }
1589
1590 // Do not skip over white space to find the "(", "execute 'x' (expr)"
1591 // is not a function call.
1592 if (**arg == '(')
1593 {
1594 garray_T *stack = &cctx->ctx_type_stack;
1595 type_T *type;
1596 int argcount = 0;
1597
1598 if (generate_ppconst(cctx, ppconst) == FAIL)
1599 return FAIL;
1600 ppconst->pp_is_const = FALSE;
1601
1602 // funcref(arg)
1603 type = ((type_T **)stack->ga_data)[stack->ga_len - 1];
1604
1605 *arg = skipwhite(p + 1);
1606 if (compile_arguments(arg, cctx, &argcount, FALSE) == FAIL)
1607 return FAIL;
1608 if (generate_PCALL(cctx, argcount, name_start, type, TRUE) == FAIL)
1609 return FAIL;
1610 if (keeping_dict)
1611 {
1612 keeping_dict = FALSE;
1613 if (generate_instr(cctx, ISN_CLEARDICT) == NULL)
1614 return FAIL;
1615 }
1616 }
1617 else if (*p == '-' && p[1] == '>')
1618 {
1619 char_u *pstart = p;
1620
1621 if (generate_ppconst(cctx, ppconst) == FAIL)
1622 return FAIL;
1623 ppconst->pp_is_const = FALSE;
1624
1625 // something->method()
1626 // Apply the '!', '-' and '+' first:
1627 // -1.0->func() works like (-1.0)->func()
1628 if (compile_leader(cctx, TRUE, start_leader, end_leader) == FAIL)
1629 return FAIL;
1630
1631 p += 2;
1632 *arg = skipwhite(p);
1633 // No line break supported right after "->".
1634 if (**arg == '(')
1635 {
1636 int argcount = 1;
1637 garray_T *stack = &cctx->ctx_type_stack;
1638 int type_idx_start = stack->ga_len;
1639 type_T *type;
1640 int expr_isn_start = cctx->ctx_instr.ga_len;
1641 int expr_isn_end;
1642 int arg_isn_count;
1643
1644 // Funcref call: list->(Refs[2])(arg)
1645 // or lambda: list->((arg) => expr)(arg)
1646 //
1647 // Fist compile the function expression.
1648 if (compile_parenthesis(arg, cctx, ppconst) == FAIL)
1649 return FAIL;
1650
1651 // Remember the next instruction index, where the instructions
1652 // for arguments are being written.
1653 expr_isn_end = cctx->ctx_instr.ga_len;
1654
1655 // Compile the arguments.
1656 if (**arg != '(')
1657 {
1658 if (*skipwhite(*arg) == '(')
1659 emsg(_(e_nowhitespace));
1660 else
1661 semsg(_(e_missing_parenthesis_str), *arg);
1662 return FAIL;
1663 }
1664 *arg = skipwhite(*arg + 1);
1665 if (compile_arguments(arg, cctx, &argcount, FALSE) == FAIL)
1666 return FAIL;
1667
1668 // Move the instructions for the arguments to before the
1669 // instructions of the expression and move the type of the
1670 // expression after the argument types. This is what ISN_PCALL
1671 // expects.
1672 stack = &cctx->ctx_type_stack;
1673 arg_isn_count = cctx->ctx_instr.ga_len - expr_isn_end;
1674 if (arg_isn_count > 0)
1675 {
1676 int expr_isn_count = expr_isn_end - expr_isn_start;
1677 isn_T *isn = ALLOC_MULT(isn_T, expr_isn_count);
1678
1679 if (isn == NULL)
1680 return FAIL;
1681 mch_memmove(isn, ((isn_T *)cctx->ctx_instr.ga_data)
1682 + expr_isn_start,
1683 sizeof(isn_T) * expr_isn_count);
1684 mch_memmove(((isn_T *)cctx->ctx_instr.ga_data)
1685 + expr_isn_start,
1686 ((isn_T *)cctx->ctx_instr.ga_data) + expr_isn_end,
1687 sizeof(isn_T) * arg_isn_count);
1688 mch_memmove(((isn_T *)cctx->ctx_instr.ga_data)
1689 + expr_isn_start + arg_isn_count,
1690 isn, sizeof(isn_T) * expr_isn_count);
1691 vim_free(isn);
1692
1693 type = ((type_T **)stack->ga_data)[type_idx_start];
1694 mch_memmove(((type_T **)stack->ga_data) + type_idx_start,
1695 ((type_T **)stack->ga_data) + type_idx_start + 1,
1696 sizeof(type_T *)
1697 * (stack->ga_len - type_idx_start - 1));
1698 ((type_T **)stack->ga_data)[stack->ga_len - 1] = type;
1699 }
1700
1701 type = ((type_T **)stack->ga_data)[stack->ga_len - 1];
1702 if (generate_PCALL(cctx, argcount, p - 2, type, FALSE) == FAIL)
1703 return FAIL;
1704 }
1705 else
1706 {
1707 // method call: list->method()
1708 p = *arg;
1709 if (!eval_isnamec1(*p))
1710 {
1711 semsg(_(e_trailing_arg), pstart);
1712 return FAIL;
1713 }
1714 if (ASCII_ISALPHA(*p) && p[1] == ':')
1715 p += 2;
1716 for ( ; eval_isnamec(*p); ++p)
1717 ;
1718 if (*p != '(')
1719 {
1720 semsg(_(e_missing_parenthesis_str), *arg);
1721 return FAIL;
1722 }
1723 if (compile_call(arg, p - *arg, cctx, ppconst, 1) == FAIL)
1724 return FAIL;
1725 }
1726 if (keeping_dict)
1727 {
1728 keeping_dict = FALSE;
1729 if (generate_instr(cctx, ISN_CLEARDICT) == NULL)
1730 return FAIL;
1731 }
1732 }
1733 else if (**arg == '[')
1734 {
1735 int is_slice = FALSE;
1736
1737 // list index: list[123]
1738 // dict member: dict[key]
1739 // string index: text[123]
1740 // blob index: blob[123]
1741 if (generate_ppconst(cctx, ppconst) == FAIL)
1742 return FAIL;
1743 ppconst->pp_is_const = FALSE;
1744
1745 ++p;
1746 if (may_get_next_line_error(p, arg, cctx) == FAIL)
1747 return FAIL;
1748 if (**arg == ':')
1749 {
1750 // missing first index is equal to zero
1751 generate_PUSHNR(cctx, 0);
1752 }
1753 else
1754 {
1755 if (compile_expr0(arg, cctx) == FAIL)
1756 return FAIL;
1757 if (**arg == ':')
1758 {
1759 semsg(_(e_white_space_required_before_and_after_str_at_str),
1760 ":", *arg);
1761 return FAIL;
1762 }
1763 if (may_get_next_line_error(*arg, arg, cctx) == FAIL)
1764 return FAIL;
1765 *arg = skipwhite(*arg);
1766 }
1767 if (**arg == ':')
1768 {
1769 is_slice = TRUE;
1770 ++*arg;
1771 if (!IS_WHITE_OR_NUL(**arg) && **arg != ']')
1772 {
1773 semsg(_(e_white_space_required_before_and_after_str_at_str),
1774 ":", *arg);
1775 return FAIL;
1776 }
1777 if (may_get_next_line_error(*arg, arg, cctx) == FAIL)
1778 return FAIL;
1779 if (**arg == ']')
1780 // missing second index is equal to end of string
1781 generate_PUSHNR(cctx, -1);
1782 else
1783 {
1784 if (compile_expr0(arg, cctx) == FAIL)
1785 return FAIL;
1786 if (may_get_next_line_error(*arg, arg, cctx) == FAIL)
1787 return FAIL;
1788 *arg = skipwhite(*arg);
1789 }
1790 }
1791
1792 if (**arg != ']')
1793 {
1794 emsg(_(e_missing_closing_square_brace));
1795 return FAIL;
1796 }
1797 *arg = *arg + 1;
1798
1799 if (keeping_dict)
1800 {
1801 keeping_dict = FALSE;
1802 if (generate_instr(cctx, ISN_CLEARDICT) == NULL)
1803 return FAIL;
1804 }
1805 if (compile_member(is_slice, &keeping_dict, cctx) == FAIL)
1806 return FAIL;
1807 }
1808 else if (*p == '.' && p[1] != '.')
1809 {
1810 // dictionary member: dict.name
1811 if (generate_ppconst(cctx, ppconst) == FAIL)
1812 return FAIL;
1813 ppconst->pp_is_const = FALSE;
1814
1815 *arg = p + 1;
1816 if (IS_WHITE_OR_NUL(**arg))
1817 {
1818 emsg(_(e_missing_name_after_dot));
1819 return FAIL;
1820 }
1821 p = *arg;
1822 if (eval_isdictc(*p))
1823 while (eval_isnamec(*p))
1824 MB_PTR_ADV(p);
1825 if (p == *arg)
1826 {
1827 semsg(_(e_syntax_error_at_str), *arg);
1828 return FAIL;
1829 }
1830 if (keeping_dict && generate_instr(cctx, ISN_CLEARDICT) == NULL)
1831 return FAIL;
1832 if (generate_STRINGMEMBER(cctx, *arg, p - *arg) == FAIL)
1833 return FAIL;
1834 keeping_dict = TRUE;
1835 *arg = p;
1836 }
1837 else
1838 break;
1839 }
1840
1841 // Turn "dict.Func" into a partial for "Func" bound to "dict".
1842 // This needs to be done at runtime to be able to check the type.
1843 if (keeping_dict && generate_instr(cctx, ISN_USEDICT) == NULL)
1844 return FAIL;
1845
1846 return OK;
1847}
1848
1849/*
1850 * Compile an expression at "*arg" and add instructions to "cctx->ctx_instr".
1851 * "arg" is advanced until after the expression, skipping white space.
1852 *
1853 * If the value is a constant "ppconst->pp_used" will be non-zero.
1854 * Before instructions are generated, any values in "ppconst" will generated.
1855 *
1856 * This is the compiling equivalent of eval1(), eval2(), etc.
1857 */
1858
1859/*
1860 * number number constant
1861 * 0zFFFFFFFF Blob constant
1862 * "string" string constant
1863 * 'string' literal string constant
1864 * &option-name option value
1865 * @r register contents
1866 * identifier variable value
1867 * function() function call
1868 * $VAR environment variable
1869 * (expression) nested expression
1870 * [expr, expr] List
1871 * {key: val, [key]: val} Dictionary
1872 *
1873 * Also handle:
1874 * ! in front logical NOT
1875 * - in front unary minus
1876 * + in front unary plus (ignored)
1877 * trailing (arg) funcref/partial call
1878 * trailing [] subscript in String or List
1879 * trailing .name entry in Dictionary
1880 * trailing ->name() method call
1881 */
1882 static int
1883compile_expr7(
1884 char_u **arg,
1885 cctx_T *cctx,
1886 ppconst_T *ppconst)
1887{
1888 char_u *start_leader, *end_leader;
1889 int ret = OK;
1890 typval_T *rettv = &ppconst->pp_tv[ppconst->pp_used];
1891 int used_before = ppconst->pp_used;
1892
1893 ppconst->pp_is_const = FALSE;
1894
1895 /*
1896 * Skip '!', '-' and '+' characters. They are handled later.
1897 */
1898 start_leader = *arg;
1899 if (eval_leader(arg, TRUE) == FAIL)
1900 return FAIL;
1901 end_leader = *arg;
1902
1903 rettv->v_type = VAR_UNKNOWN;
1904 switch (**arg)
1905 {
1906 /*
1907 * Number constant.
1908 */
1909 case '0': // also for blob starting with 0z
1910 case '1':
1911 case '2':
1912 case '3':
1913 case '4':
1914 case '5':
1915 case '6':
1916 case '7':
1917 case '8':
1918 case '9':
1919 case '.': if (eval_number(arg, rettv, TRUE, FALSE) == FAIL)
1920 return FAIL;
1921 // Apply "-" and "+" just before the number now, right to
1922 // left. Matters especially when "->" follows. Stops at
1923 // '!'.
1924 if (apply_leader(rettv, TRUE,
1925 start_leader, &end_leader) == FAIL)
1926 {
1927 clear_tv(rettv);
1928 return FAIL;
1929 }
1930 break;
1931
1932 /*
1933 * String constant: "string".
1934 */
1935 case '"': if (eval_string(arg, rettv, TRUE) == FAIL)
1936 return FAIL;
1937 break;
1938
1939 /*
1940 * Literal string constant: 'str''ing'.
1941 */
1942 case '\'': if (eval_lit_string(arg, rettv, TRUE) == FAIL)
1943 return FAIL;
1944 break;
1945
1946 /*
1947 * Constant Vim variable.
1948 */
1949 case 'v': get_vim_constant(arg, rettv);
1950 ret = NOTDONE;
1951 break;
1952
1953 /*
1954 * "true" constant
1955 */
1956 case 't': if (STRNCMP(*arg, "true", 4) == 0
1957 && !eval_isnamec((*arg)[4]))
1958 {
1959 *arg += 4;
1960 rettv->v_type = VAR_BOOL;
1961 rettv->vval.v_number = VVAL_TRUE;
1962 }
1963 else
1964 ret = NOTDONE;
1965 break;
1966
1967 /*
1968 * "false" constant
1969 */
1970 case 'f': if (STRNCMP(*arg, "false", 5) == 0
1971 && !eval_isnamec((*arg)[5]))
1972 {
1973 *arg += 5;
1974 rettv->v_type = VAR_BOOL;
1975 rettv->vval.v_number = VVAL_FALSE;
1976 }
1977 else
1978 ret = NOTDONE;
1979 break;
1980
1981 /*
1982 * "null" constant
1983 */
1984 case 'n': if (STRNCMP(*arg, "null", 4) == 0
1985 && !eval_isnamec((*arg)[4]))
1986 {
1987 *arg += 4;
1988 rettv->v_type = VAR_SPECIAL;
1989 rettv->vval.v_number = VVAL_NULL;
1990 }
1991 else
1992 ret = NOTDONE;
1993 break;
1994
1995 /*
1996 * List: [expr, expr]
1997 */
1998 case '[': if (generate_ppconst(cctx, ppconst) == FAIL)
1999 return FAIL;
2000 ret = compile_list(arg, cctx, ppconst);
2001 break;
2002
2003 /*
2004 * Dictionary: {'key': val, 'key': val}
2005 */
2006 case '{': if (generate_ppconst(cctx, ppconst) == FAIL)
2007 return FAIL;
2008 ret = compile_dict(arg, cctx, ppconst);
2009 break;
2010
2011 /*
2012 * Option value: &name
2013 */
2014 case '&': if (generate_ppconst(cctx, ppconst) == FAIL)
2015 return FAIL;
2016 ret = compile_get_option(arg, cctx);
2017 break;
2018
2019 /*
2020 * Environment variable: $VAR.
2021 */
2022 case '$': if (generate_ppconst(cctx, ppconst) == FAIL)
2023 return FAIL;
2024 ret = compile_get_env(arg, cctx);
2025 break;
2026
2027 /*
2028 * Register contents: @r.
2029 */
2030 case '@': if (generate_ppconst(cctx, ppconst) == FAIL)
2031 return FAIL;
2032 ret = compile_get_register(arg, cctx);
2033 break;
2034 /*
2035 * nested expression: (expression).
2036 * lambda: (arg, arg) => expr
2037 * funcref: (arg, arg) => { statement }
2038 */
2039 case '(': // if compile_lambda returns NOTDONE then it must be (expr)
2040 ret = compile_lambda(arg, cctx);
2041 if (ret == NOTDONE)
2042 ret = compile_parenthesis(arg, cctx, ppconst);
2043 break;
2044
2045 default: ret = NOTDONE;
2046 break;
2047 }
2048 if (ret == FAIL)
2049 return FAIL;
2050
2051 if (rettv->v_type != VAR_UNKNOWN && used_before == ppconst->pp_used)
2052 {
2053 if (cctx->ctx_skip == SKIP_YES)
2054 clear_tv(rettv);
2055 else
2056 // A constant expression can possibly be handled compile time,
2057 // return the value instead of generating code.
2058 ++ppconst->pp_used;
2059 }
2060 else if (ret == NOTDONE)
2061 {
2062 char_u *p;
2063 int r;
2064
2065 if (!eval_isnamec1(**arg))
2066 {
2067 if (!vim9_bad_comment(*arg))
2068 {
2069 if (ends_excmd(*skipwhite(*arg)))
2070 semsg(_(e_empty_expression_str), *arg);
2071 else
2072 semsg(_(e_name_expected_str), *arg);
2073 }
2074 return FAIL;
2075 }
2076
2077 // "name" or "name()"
2078 p = to_name_end(*arg, TRUE);
2079 if (p - *arg == (size_t)1 && **arg == '_')
2080 {
2081 emsg(_(e_cannot_use_underscore_here));
2082 return FAIL;
2083 }
2084
2085 if (*p == '(')
2086 {
2087 r = compile_call(arg, p - *arg, cctx, ppconst, 0);
2088 }
2089 else
2090 {
2091 if (cctx->ctx_skip != SKIP_YES
2092 && generate_ppconst(cctx, ppconst) == FAIL)
2093 return FAIL;
2094 r = compile_load(arg, p, cctx, TRUE, TRUE);
2095 }
2096 if (r == FAIL)
2097 return FAIL;
2098 }
2099
2100 // Handle following "[]", ".member", etc.
2101 // Then deal with prefixed '-', '+' and '!', if not done already.
2102 if (compile_subscript(arg, cctx, start_leader, &end_leader,
2103 ppconst) == FAIL)
2104 return FAIL;
2105 if (ppconst->pp_used > 0)
2106 {
2107 // apply the '!', '-' and '+' before the constant
2108 rettv = &ppconst->pp_tv[ppconst->pp_used - 1];
2109 if (apply_leader(rettv, FALSE, start_leader, &end_leader) == FAIL)
2110 return FAIL;
2111 return OK;
2112 }
2113 if (compile_leader(cctx, FALSE, start_leader, &end_leader) == FAIL)
2114 return FAIL;
2115 return OK;
2116}
2117
2118/*
2119 * <type>expr7: runtime type check / conversion
2120 */
2121 static int
2122compile_expr7t(char_u **arg, cctx_T *cctx, ppconst_T *ppconst)
2123{
2124 type_T *want_type = NULL;
2125
2126 // Recognize <type>
2127 if (**arg == '<' && eval_isnamec1((*arg)[1]))
2128 {
2129 ++*arg;
2130 want_type = parse_type(arg, cctx->ctx_type_list, TRUE);
2131 if (want_type == NULL)
2132 return FAIL;
2133
2134 if (**arg != '>')
2135 {
2136 if (*skipwhite(*arg) == '>')
2137 semsg(_(e_no_white_space_allowed_before_str_str), ">", *arg);
2138 else
2139 emsg(_(e_missing_gt));
2140 return FAIL;
2141 }
2142 ++*arg;
2143 if (may_get_next_line_error(*arg, arg, cctx) == FAIL)
2144 return FAIL;
2145 }
2146
2147 if (compile_expr7(arg, cctx, ppconst) == FAIL)
2148 return FAIL;
2149
2150 if (want_type != NULL)
2151 {
2152 garray_T *stack = &cctx->ctx_type_stack;
2153 type_T *actual;
2154 where_T where = WHERE_INIT;
2155
2156 generate_ppconst(cctx, ppconst);
2157 actual = ((type_T **)stack->ga_data)[stack->ga_len - 1];
2158 if (check_type(want_type, actual, FALSE, where) == FAIL)
2159 {
2160 if (need_type(actual, want_type, -1, 0, cctx, FALSE, FALSE) == FAIL)
2161 return FAIL;
2162 }
2163 }
2164
2165 return OK;
2166}
2167
2168/*
2169 * * number multiplication
2170 * / number division
2171 * % number modulo
2172 */
2173 static int
2174compile_expr6(char_u **arg, cctx_T *cctx, ppconst_T *ppconst)
2175{
2176 char_u *op;
2177 char_u *next;
2178 int ppconst_used = ppconst->pp_used;
2179
2180 // get the first expression
2181 if (compile_expr7t(arg, cctx, ppconst) == FAIL)
2182 return FAIL;
2183
2184 /*
2185 * Repeat computing, until no "*", "/" or "%" is following.
2186 */
2187 for (;;)
2188 {
2189 op = may_peek_next_line(cctx, *arg, &next);
2190 if (*op != '*' && *op != '/' && *op != '%')
2191 break;
2192 if (next != NULL)
2193 {
2194 *arg = next_line_from_context(cctx, TRUE);
2195 op = skipwhite(*arg);
2196 }
2197
2198 if (!IS_WHITE_OR_NUL(**arg) || !IS_WHITE_OR_NUL(op[1]))
2199 {
2200 error_white_both(op, 1);
2201 return FAIL;
2202 }
2203 if (may_get_next_line_error(op + 1, arg, cctx) == FAIL)
2204 return FAIL;
2205
2206 // get the second expression
2207 if (compile_expr7t(arg, cctx, ppconst) == FAIL)
2208 return FAIL;
2209
2210 if (ppconst->pp_used == ppconst_used + 2
2211 && ppconst->pp_tv[ppconst_used].v_type == VAR_NUMBER
2212 && ppconst->pp_tv[ppconst_used + 1].v_type == VAR_NUMBER)
2213 {
2214 typval_T *tv1 = &ppconst->pp_tv[ppconst_used];
2215 typval_T *tv2 = &ppconst->pp_tv[ppconst_used + 1];
2216 varnumber_T res = 0;
2217 int failed = FALSE;
2218
2219 // both are numbers: compute the result
2220 switch (*op)
2221 {
2222 case '*': res = tv1->vval.v_number * tv2->vval.v_number;
2223 break;
2224 case '/': res = num_divide(tv1->vval.v_number,
2225 tv2->vval.v_number, &failed);
2226 break;
2227 case '%': res = num_modulus(tv1->vval.v_number,
2228 tv2->vval.v_number, &failed);
2229 break;
2230 }
2231 if (failed)
2232 return FAIL;
2233 tv1->vval.v_number = res;
2234 --ppconst->pp_used;
2235 }
2236 else
2237 {
2238 generate_ppconst(cctx, ppconst);
2239 generate_two_op(cctx, op);
2240 }
2241 }
2242
2243 return OK;
2244}
2245
2246/*
2247 * + number addition or list/blobl concatenation
2248 * - number subtraction
2249 * .. string concatenation
2250 */
2251 static int
2252compile_expr5(char_u **arg, cctx_T *cctx, ppconst_T *ppconst)
2253{
2254 char_u *op;
2255 char_u *next;
2256 int oplen;
2257 int ppconst_used = ppconst->pp_used;
2258
2259 // get the first variable
2260 if (compile_expr6(arg, cctx, ppconst) == FAIL)
2261 return FAIL;
2262
2263 /*
2264 * Repeat computing, until no "+", "-" or ".." is following.
2265 */
2266 for (;;)
2267 {
2268 op = may_peek_next_line(cctx, *arg, &next);
2269 if (*op != '+' && *op != '-' && !(*op == '.' && *(op + 1) == '.'))
2270 break;
2271 if (op[0] == op[1] && *op != '.' && next)
2272 // Finding "++" or "--" on the next line is a separate command.
2273 // But ".." is concatenation.
2274 break;
2275 oplen = (*op == '.' ? 2 : 1);
2276 if (next != NULL)
2277 {
2278 *arg = next_line_from_context(cctx, TRUE);
2279 op = skipwhite(*arg);
2280 }
2281
2282 if (!IS_WHITE_OR_NUL(**arg) || !IS_WHITE_OR_NUL(op[oplen]))
2283 {
2284 error_white_both(op, oplen);
2285 return FAIL;
2286 }
2287
2288 if (may_get_next_line_error(op + oplen, arg, cctx) == FAIL)
2289 return FAIL;
2290
2291 // get the second expression
2292 if (compile_expr6(arg, cctx, ppconst) == FAIL)
2293 return FAIL;
2294
2295 if (ppconst->pp_used == ppconst_used + 2
2296 && (*op == '.'
2297 ? (ppconst->pp_tv[ppconst_used].v_type == VAR_STRING
2298 && ppconst->pp_tv[ppconst_used + 1].v_type == VAR_STRING)
2299 : (ppconst->pp_tv[ppconst_used].v_type == VAR_NUMBER
2300 && ppconst->pp_tv[ppconst_used + 1].v_type == VAR_NUMBER)))
2301 {
2302 typval_T *tv1 = &ppconst->pp_tv[ppconst_used];
2303 typval_T *tv2 = &ppconst->pp_tv[ppconst_used + 1];
2304
2305 // concat/subtract/add constant numbers
2306 if (*op == '+')
2307 tv1->vval.v_number = tv1->vval.v_number + tv2->vval.v_number;
2308 else if (*op == '-')
2309 tv1->vval.v_number = tv1->vval.v_number - tv2->vval.v_number;
2310 else
2311 {
2312 // concatenate constant strings
2313 char_u *s1 = tv1->vval.v_string;
2314 char_u *s2 = tv2->vval.v_string;
2315 size_t len1 = STRLEN(s1);
2316
2317 tv1->vval.v_string = alloc((int)(len1 + STRLEN(s2) + 1));
2318 if (tv1->vval.v_string == NULL)
2319 {
2320 clear_ppconst(ppconst);
2321 return FAIL;
2322 }
2323 mch_memmove(tv1->vval.v_string, s1, len1);
2324 STRCPY(tv1->vval.v_string + len1, s2);
2325 vim_free(s1);
2326 vim_free(s2);
2327 }
2328 --ppconst->pp_used;
2329 }
2330 else
2331 {
2332 generate_ppconst(cctx, ppconst);
2333 ppconst->pp_is_const = FALSE;
2334 if (*op == '.')
2335 {
2336 if (may_generate_2STRING(-2, FALSE, cctx) == FAIL
2337 || may_generate_2STRING(-1, FALSE, cctx) == FAIL)
2338 return FAIL;
2339 generate_instr_drop(cctx, ISN_CONCAT, 1);
2340 }
2341 else
2342 generate_two_op(cctx, op);
2343 }
2344 }
2345
2346 return OK;
2347}
2348
2349/*
2350 * expr5a == expr5b
2351 * expr5a =~ expr5b
2352 * expr5a != expr5b
2353 * expr5a !~ expr5b
2354 * expr5a > expr5b
2355 * expr5a >= expr5b
2356 * expr5a < expr5b
2357 * expr5a <= expr5b
2358 * expr5a is expr5b
2359 * expr5a isnot expr5b
2360 *
2361 * Produces instructions:
2362 * EVAL expr5a Push result of "expr5a"
2363 * EVAL expr5b Push result of "expr5b"
2364 * COMPARE one of the compare instructions
2365 */
2366 static int
2367compile_expr4(char_u **arg, cctx_T *cctx, ppconst_T *ppconst)
2368{
2369 exprtype_T type = EXPR_UNKNOWN;
2370 char_u *p;
2371 char_u *next;
2372 int len = 2;
2373 int type_is = FALSE;
2374 int ppconst_used = ppconst->pp_used;
2375
2376 // get the first variable
2377 if (compile_expr5(arg, cctx, ppconst) == FAIL)
2378 return FAIL;
2379
2380 p = may_peek_next_line(cctx, *arg, &next);
2381 type = get_compare_type(p, &len, &type_is);
2382
2383 /*
2384 * If there is a comparative operator, use it.
2385 */
2386 if (type != EXPR_UNKNOWN)
2387 {
2388 int ic = FALSE; // Default: do not ignore case
2389
2390 if (next != NULL)
2391 {
2392 *arg = next_line_from_context(cctx, TRUE);
2393 p = skipwhite(*arg);
2394 }
2395 if (type_is && (p[len] == '?' || p[len] == '#'))
2396 {
2397 semsg(_(e_invalid_expression_str), *arg);
2398 return FAIL;
2399 }
2400 // extra question mark appended: ignore case
2401 if (p[len] == '?')
2402 {
2403 ic = TRUE;
2404 ++len;
2405 }
2406 // extra '#' appended: match case (ignored)
2407 else if (p[len] == '#')
2408 ++len;
2409 // nothing appended: match case
2410
2411 if (!IS_WHITE_OR_NUL(**arg) || !IS_WHITE_OR_NUL(p[len]))
2412 {
2413 error_white_both(p, len);
2414 return FAIL;
2415 }
2416
2417 // get the second variable
2418 if (may_get_next_line_error(p + len, arg, cctx) == FAIL)
2419 return FAIL;
2420
2421 if (compile_expr5(arg, cctx, ppconst) == FAIL)
2422 return FAIL;
2423
2424 if (ppconst->pp_used == ppconst_used + 2)
2425 {
2426 typval_T * tv1 = &ppconst->pp_tv[ppconst->pp_used - 2];
2427 typval_T *tv2 = &ppconst->pp_tv[ppconst->pp_used - 1];
2428 int ret;
2429
2430 // Both sides are a constant, compute the result now.
2431 // First check for a valid combination of types, this is more
2432 // strict than typval_compare().
2433 if (check_compare_types(type, tv1, tv2) == FAIL)
2434 ret = FAIL;
2435 else
2436 {
2437 ret = typval_compare(tv1, tv2, type, ic);
2438 tv1->v_type = VAR_BOOL;
2439 tv1->vval.v_number = tv1->vval.v_number
2440 ? VVAL_TRUE : VVAL_FALSE;
2441 clear_tv(tv2);
2442 --ppconst->pp_used;
2443 }
2444 return ret;
2445 }
2446
2447 generate_ppconst(cctx, ppconst);
2448 return generate_COMPARE(cctx, type, ic);
2449 }
2450
2451 return OK;
2452}
2453
2454static int compile_expr3(char_u **arg, cctx_T *cctx, ppconst_T *ppconst);
2455
2456/*
2457 * Compile || or &&.
2458 */
2459 static int
2460compile_and_or(
2461 char_u **arg,
2462 cctx_T *cctx,
2463 char *op,
2464 ppconst_T *ppconst,
2465 int ppconst_used UNUSED)
2466{
2467 char_u *next;
2468 char_u *p = may_peek_next_line(cctx, *arg, &next);
2469 int opchar = *op;
2470
2471 if (p[0] == opchar && p[1] == opchar)
2472 {
2473 garray_T *instr = &cctx->ctx_instr;
2474 garray_T end_ga;
2475 int save_skip = cctx->ctx_skip;
2476
2477 /*
2478 * Repeat until there is no following "||" or "&&"
2479 */
2480 ga_init2(&end_ga, sizeof(int), 10);
2481 while (p[0] == opchar && p[1] == opchar)
2482 {
2483 long start_lnum = SOURCING_LNUM;
2484 long save_sourcing_lnum;
2485 int start_ctx_lnum = cctx->ctx_lnum;
2486 int save_lnum;
2487 int const_used;
2488 int status;
2489 jumpwhen_T jump_when = opchar == '|'
2490 ? JUMP_IF_COND_TRUE : JUMP_IF_COND_FALSE;
2491
2492 if (next != NULL)
2493 {
2494 *arg = next_line_from_context(cctx, TRUE);
2495 p = skipwhite(*arg);
2496 }
2497
2498 if (!IS_WHITE_OR_NUL(**arg) || !IS_WHITE_OR_NUL(p[2]))
2499 {
2500 semsg(_(e_white_space_required_before_and_after_str_at_str),
2501 op, p);
2502 ga_clear(&end_ga);
2503 return FAIL;
2504 }
2505
2506 save_sourcing_lnum = SOURCING_LNUM;
2507 SOURCING_LNUM = start_lnum;
2508 save_lnum = cctx->ctx_lnum;
2509 cctx->ctx_lnum = start_ctx_lnum;
2510
2511 status = check_ppconst_bool(ppconst);
2512 if (status != FAIL)
2513 {
2514 // Use the last ppconst if possible.
2515 if (ppconst->pp_used > 0)
2516 {
2517 typval_T *tv = &ppconst->pp_tv[ppconst->pp_used - 1];
2518 int is_true = tv2bool(tv);
2519
2520 if ((is_true && opchar == '|')
2521 || (!is_true && opchar == '&'))
2522 {
2523 // For "false && expr" and "true || expr" the "expr"
2524 // does not need to be evaluated.
2525 cctx->ctx_skip = SKIP_YES;
2526 clear_tv(tv);
2527 tv->v_type = VAR_BOOL;
2528 tv->vval.v_number = is_true ? VVAL_TRUE : VVAL_FALSE;
2529 }
2530 else
2531 {
2532 // For "true && expr" and "false || expr" only "expr"
2533 // needs to be evaluated.
2534 --ppconst->pp_used;
2535 jump_when = JUMP_NEVER;
2536 }
2537 }
2538 else
2539 {
2540 // Every part must evaluate to a bool.
2541 status = bool_on_stack(cctx);
2542 }
2543 }
2544 if (status != FAIL)
2545 status = ga_grow(&end_ga, 1);
2546 cctx->ctx_lnum = save_lnum;
2547 if (status == FAIL)
2548 {
2549 ga_clear(&end_ga);
2550 return FAIL;
2551 }
2552
2553 if (jump_when != JUMP_NEVER)
2554 {
2555 if (cctx->ctx_skip != SKIP_YES)
2556 {
2557 *(((int *)end_ga.ga_data) + end_ga.ga_len) = instr->ga_len;
2558 ++end_ga.ga_len;
2559 }
2560 generate_JUMP(cctx, jump_when, 0);
2561 }
2562
2563 // eval the next expression
2564 SOURCING_LNUM = save_sourcing_lnum;
2565 if (may_get_next_line_error(p + 2, arg, cctx) == FAIL)
2566 {
2567 ga_clear(&end_ga);
2568 return FAIL;
2569 }
2570
2571 const_used = ppconst->pp_used;
2572 if ((opchar == '|' ? compile_expr3(arg, cctx, ppconst)
2573 : compile_expr4(arg, cctx, ppconst)) == FAIL)
2574 {
2575 ga_clear(&end_ga);
2576 return FAIL;
2577 }
2578
2579 // "0 || 1" results in true, "1 && 0" results in false.
2580 if (ppconst->pp_used == const_used + 1)
2581 {
2582 typval_T *tv = &ppconst->pp_tv[ppconst->pp_used - 1];
2583
2584 if (tv->v_type == VAR_NUMBER
2585 && (tv->vval.v_number == 1 || tv->vval.v_number == 0))
2586 {
2587 tv->vval.v_number = tv->vval.v_number == 1
2588 ? VVAL_TRUE : VVAL_FALSE;
2589 tv->v_type = VAR_BOOL;
2590 }
2591 }
2592
2593 p = may_peek_next_line(cctx, *arg, &next);
2594 }
2595
2596 if (check_ppconst_bool(ppconst) == FAIL)
2597 {
2598 ga_clear(&end_ga);
2599 return FAIL;
2600 }
2601
2602 if (cctx->ctx_skip != SKIP_YES && ppconst->pp_used == 0)
2603 // Every part must evaluate to a bool.
2604 if (bool_on_stack(cctx) == FAIL)
2605 {
2606 ga_clear(&end_ga);
2607 return FAIL;
2608 }
2609
2610 if (end_ga.ga_len > 0)
2611 {
2612 // Fill in the end label in all jumps.
2613 generate_ppconst(cctx, ppconst);
2614 while (end_ga.ga_len > 0)
2615 {
2616 isn_T *isn;
2617
2618 --end_ga.ga_len;
2619 isn = ((isn_T *)instr->ga_data)
2620 + *(((int *)end_ga.ga_data) + end_ga.ga_len);
2621 isn->isn_arg.jump.jump_where = instr->ga_len;
2622 }
2623 }
2624 ga_clear(&end_ga);
2625
2626 cctx->ctx_skip = save_skip;
2627 }
2628
2629 return OK;
2630}
2631
2632/*
2633 * expr4a && expr4a && expr4a logical AND
2634 *
2635 * Produces instructions:
2636 * EVAL expr4a Push result of "expr4a"
2637 * COND2BOOL convert to bool if needed
2638 * JUMP_IF_COND_FALSE end
2639 * EVAL expr4b Push result of "expr4b"
2640 * JUMP_IF_COND_FALSE end
2641 * EVAL expr4c Push result of "expr4c"
2642 * end:
2643 */
2644 static int
2645compile_expr3(char_u **arg, cctx_T *cctx, ppconst_T *ppconst)
2646{
2647 int ppconst_used = ppconst->pp_used;
2648
2649 // get the first variable
2650 if (compile_expr4(arg, cctx, ppconst) == FAIL)
2651 return FAIL;
2652
2653 // || and && work almost the same
2654 return compile_and_or(arg, cctx, "&&", ppconst, ppconst_used);
2655}
2656
2657/*
2658 * expr3a || expr3b || expr3c logical OR
2659 *
2660 * Produces instructions:
2661 * EVAL expr3a Push result of "expr3a"
2662 * COND2BOOL convert to bool if needed
2663 * JUMP_IF_COND_TRUE end
2664 * EVAL expr3b Push result of "expr3b"
2665 * JUMP_IF_COND_TRUE end
2666 * EVAL expr3c Push result of "expr3c"
2667 * end:
2668 */
2669 static int
2670compile_expr2(char_u **arg, cctx_T *cctx, ppconst_T *ppconst)
2671{
2672 int ppconst_used = ppconst->pp_used;
2673
2674 // eval the first expression
2675 if (compile_expr3(arg, cctx, ppconst) == FAIL)
2676 return FAIL;
2677
2678 // || and && work almost the same
2679 return compile_and_or(arg, cctx, "||", ppconst, ppconst_used);
2680}
2681
2682/*
2683 * Toplevel expression: expr2 ? expr1a : expr1b
2684 * Produces instructions:
2685 * EVAL expr2 Push result of "expr2"
2686 * JUMP_IF_FALSE alt jump if false
2687 * EVAL expr1a
2688 * JUMP_ALWAYS end
2689 * alt: EVAL expr1b
2690 * end:
2691 *
2692 * Toplevel expression: expr2 ?? expr1
2693 * Produces instructions:
2694 * EVAL expr2 Push result of "expr2"
2695 * JUMP_AND_KEEP_IF_TRUE end jump if true
2696 * EVAL expr1
2697 * end:
2698 */
2699 int
2700compile_expr1(char_u **arg, cctx_T *cctx, ppconst_T *ppconst)
2701{
2702 char_u *p;
2703 int ppconst_used = ppconst->pp_used;
2704 char_u *next;
2705
2706 // Ignore all kinds of errors when not producing code.
2707 if (cctx->ctx_skip == SKIP_YES)
2708 {
2709 skip_expr_cctx(arg, cctx);
2710 return OK;
2711 }
2712
2713 // Evaluate the first expression.
2714 if (compile_expr2(arg, cctx, ppconst) == FAIL)
2715 return FAIL;
2716
2717 p = may_peek_next_line(cctx, *arg, &next);
2718 if (*p == '?')
2719 {
2720 int op_falsy = p[1] == '?';
2721 garray_T *instr = &cctx->ctx_instr;
2722 garray_T *stack = &cctx->ctx_type_stack;
2723 int alt_idx = instr->ga_len;
2724 int end_idx = 0;
2725 isn_T *isn;
2726 type_T *type1 = NULL;
2727 int has_const_expr = FALSE;
2728 int const_value = FALSE;
2729 int save_skip = cctx->ctx_skip;
2730
2731 if (next != NULL)
2732 {
2733 *arg = next_line_from_context(cctx, TRUE);
2734 p = skipwhite(*arg);
2735 }
2736
2737 if (!IS_WHITE_OR_NUL(**arg) || !IS_WHITE_OR_NUL(p[1 + op_falsy]))
2738 {
2739 semsg(_(e_white_space_required_before_and_after_str_at_str),
2740 op_falsy ? "??" : "?", p);
2741 return FAIL;
2742 }
2743
2744 if (ppconst->pp_used == ppconst_used + 1)
2745 {
2746 // the condition is a constant, we know whether the ? or the :
2747 // expression is to be evaluated.
2748 has_const_expr = TRUE;
2749 if (op_falsy)
2750 const_value = tv2bool(&ppconst->pp_tv[ppconst_used]);
2751 else
2752 {
2753 int error = FALSE;
2754
2755 const_value = tv_get_bool_chk(&ppconst->pp_tv[ppconst_used],
2756 &error);
2757 if (error)
2758 return FAIL;
2759 }
2760 cctx->ctx_skip = save_skip == SKIP_YES ||
2761 (op_falsy ? const_value : !const_value) ? SKIP_YES : SKIP_NOT;
2762
2763 if (op_falsy && cctx->ctx_skip == SKIP_YES)
2764 // "left ?? right" and "left" is truthy: produce "left"
2765 generate_ppconst(cctx, ppconst);
2766 else
2767 {
2768 clear_tv(&ppconst->pp_tv[ppconst_used]);
2769 --ppconst->pp_used;
2770 }
2771 }
2772 else
2773 {
2774 generate_ppconst(cctx, ppconst);
2775 if (op_falsy)
2776 end_idx = instr->ga_len;
2777 generate_JUMP(cctx, op_falsy
2778 ? JUMP_AND_KEEP_IF_TRUE : JUMP_IF_FALSE, 0);
2779 if (op_falsy)
2780 type1 = ((type_T **)stack->ga_data)[stack->ga_len];
2781 }
2782
2783 // evaluate the second expression; any type is accepted
2784 if (may_get_next_line_error(p + 1 + op_falsy, arg, cctx) == FAIL)
2785 return FAIL;
2786 if (compile_expr1(arg, cctx, ppconst) == FAIL)
2787 return FAIL;
2788
2789 if (!has_const_expr)
2790 {
2791 generate_ppconst(cctx, ppconst);
2792
2793 if (!op_falsy)
2794 {
2795 // remember the type and drop it
2796 --stack->ga_len;
2797 type1 = ((type_T **)stack->ga_data)[stack->ga_len];
2798
2799 end_idx = instr->ga_len;
2800 generate_JUMP(cctx, JUMP_ALWAYS, 0);
2801
2802 // jump here from JUMP_IF_FALSE
2803 isn = ((isn_T *)instr->ga_data) + alt_idx;
2804 isn->isn_arg.jump.jump_where = instr->ga_len;
2805 }
2806 }
2807
2808 if (!op_falsy)
2809 {
2810 // Check for the ":".
2811 p = may_peek_next_line(cctx, *arg, &next);
2812 if (*p != ':')
2813 {
2814 emsg(_(e_missing_colon_after_questionmark));
2815 return FAIL;
2816 }
2817 if (next != NULL)
2818 {
2819 *arg = next_line_from_context(cctx, TRUE);
2820 p = skipwhite(*arg);
2821 }
2822
2823 if (!IS_WHITE_OR_NUL(**arg) || !IS_WHITE_OR_NUL(p[1]))
2824 {
2825 semsg(_(e_white_space_required_before_and_after_str_at_str),
2826 ":", p);
2827 return FAIL;
2828 }
2829
2830 // evaluate the third expression
2831 if (has_const_expr)
2832 cctx->ctx_skip = save_skip == SKIP_YES || const_value
2833 ? SKIP_YES : SKIP_NOT;
2834 if (may_get_next_line_error(p + 1, arg, cctx) == FAIL)
2835 return FAIL;
2836 if (compile_expr1(arg, cctx, ppconst) == FAIL)
2837 return FAIL;
2838 }
2839
2840 if (!has_const_expr)
2841 {
2842 type_T **typep;
2843
2844 generate_ppconst(cctx, ppconst);
2845
2846 // If the types differ, the result has a more generic type.
2847 typep = ((type_T **)stack->ga_data) + stack->ga_len - 1;
2848 common_type(type1, *typep, typep, cctx->ctx_type_list);
2849
2850 // jump here from JUMP_ALWAYS or JUMP_AND_KEEP_IF_TRUE
2851 isn = ((isn_T *)instr->ga_data) + end_idx;
2852 isn->isn_arg.jump.jump_where = instr->ga_len;
2853 }
2854
2855 cctx->ctx_skip = save_skip;
2856 }
2857 return OK;
2858}
2859
2860/*
2861 * Toplevel expression.
2862 * Sets "is_const" (if not NULL) to indicate the value is a constant.
2863 * Returns OK or FAIL.
2864 */
2865 int
2866compile_expr0_ext(char_u **arg, cctx_T *cctx, int *is_const)
2867{
2868 ppconst_T ppconst;
2869
2870 CLEAR_FIELD(ppconst);
2871 if (compile_expr1(arg, cctx, &ppconst) == FAIL)
2872 {
2873 clear_ppconst(&ppconst);
2874 return FAIL;
2875 }
2876 if (is_const != NULL)
2877 *is_const = ppconst.pp_used > 0 || ppconst.pp_is_const;
2878 if (generate_ppconst(cctx, &ppconst) == FAIL)
2879 return FAIL;
2880 return OK;
2881}
2882
2883/*
2884 * Toplevel expression.
2885 */
2886 int
2887compile_expr0(char_u **arg, cctx_T *cctx)
2888{
2889 return compile_expr0_ext(arg, cctx, NULL);
2890}
2891
2892
2893#endif // defined(FEAT_EVAL)