blob: 6fe8e2af1ff044c7f1cb5a1d537029c3b1315a0e [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.
Bram Moolenaar59618fe2021-12-21 12:32:17 +000093 if ((*typep == &t_any || *typep == &t_unknown) && idxtype == &t_string)
Bram Moolenaardc7c3662021-12-20 15:04:29 +000094 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 }
Bram Moolenaar59618fe2021-12-21 12:32:17 +0000159 else if (vartype == VAR_LIST || *typep == &t_any || *typep == &t_unknown)
Bram Moolenaardc7c3662021-12-20 15:04:29 +0000160 {
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.
Bram Moolenaar59618fe2021-12-21 12:32:17 +0000418 res = generate_LOAD(cctx, isn_type, 0, name, &t_unknown);
Bram Moolenaardc7c3662021-12-20 15:04:29 +0000419 }
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
Bram Moolenaar59618fe2021-12-21 12:32:17 +00001431 if (type == &t_any
1432 || type == &t_unknown
1433 || type == &t_number
1434 || type == &t_number_bool)
Bram Moolenaardc7c3662021-12-20 15:04:29 +00001435 // Number 0 and 1 are OK to use as a bool. "any" could also be a bool.
1436 // This requires a runtime type check.
1437 return generate_COND2BOOL(cctx);
1438
1439 return need_type(type, &t_bool, -1, 0, cctx, FALSE, FALSE);
1440}
1441
1442/*
1443 * Give the "white on both sides" error, taking the operator from "p[len]".
1444 */
1445 void
1446error_white_both(char_u *op, int len)
1447{
1448 char_u buf[10];
1449
1450 vim_strncpy(buf, op, len);
1451 semsg(_(e_white_space_required_before_and_after_str_at_str), buf, op);
1452}
1453
1454/*
1455 * Compile code to apply '-', '+' and '!'.
1456 * When "numeric_only" is TRUE do not apply '!'.
1457 */
1458 static int
1459compile_leader(cctx_T *cctx, int numeric_only, char_u *start, char_u **end)
1460{
1461 char_u *p = *end;
1462
1463 // this works from end to start
1464 while (p > start)
1465 {
1466 --p;
1467 while (VIM_ISWHITE(*p))
1468 --p;
1469 if (*p == '-' || *p == '+')
1470 {
1471 int negate = *p == '-';
1472 isn_T *isn;
1473 garray_T *stack = &cctx->ctx_type_stack;
1474 type_T *type;
1475
1476 type = ((type_T **)stack->ga_data)[stack->ga_len - 1];
1477 if (type != &t_float && need_type(type, &t_number,
1478 -1, 0, cctx, FALSE, FALSE) == FAIL)
1479 return FAIL;
1480
1481 while (p > start && (p[-1] == '-' || p[-1] == '+'))
1482 {
1483 --p;
1484 if (*p == '-')
1485 negate = !negate;
1486 }
1487 // only '-' has an effect, for '+' we only check the type
1488 if (negate)
1489 {
1490 isn = generate_instr(cctx, ISN_NEGATENR);
1491 if (isn == NULL)
1492 return FAIL;
1493 }
1494 }
1495 else if (numeric_only)
1496 {
1497 ++p;
1498 break;
1499 }
1500 else
1501 {
1502 int invert = *p == '!';
1503
1504 while (p > start && (p[-1] == '!' || VIM_ISWHITE(p[-1])))
1505 {
1506 if (p[-1] == '!')
1507 invert = !invert;
1508 --p;
1509 }
1510 if (generate_2BOOL(cctx, invert, -1) == FAIL)
1511 return FAIL;
1512 }
1513 }
1514 *end = p;
1515 return OK;
1516}
1517
1518/*
1519 * Compile "(expression)": recursive!
1520 * Return FAIL/OK.
1521 */
1522 static int
1523compile_parenthesis(char_u **arg, cctx_T *cctx, ppconst_T *ppconst)
1524{
1525 int ret;
1526 char_u *p = *arg + 1;
1527
1528 if (may_get_next_line_error(p, arg, cctx) == FAIL)
1529 return FAIL;
1530 if (ppconst->pp_used <= PPSIZE - 10)
1531 {
1532 ret = compile_expr1(arg, cctx, ppconst);
1533 }
1534 else
1535 {
1536 // Not enough space in ppconst, flush constants.
1537 if (generate_ppconst(cctx, ppconst) == FAIL)
1538 return FAIL;
1539 ret = compile_expr0(arg, cctx);
1540 }
1541 if (may_get_next_line_error(*arg, arg, cctx) == FAIL)
1542 return FAIL;
1543 if (**arg == ')')
1544 ++*arg;
1545 else if (ret == OK)
1546 {
1547 emsg(_(e_missing_closing_paren));
1548 ret = FAIL;
1549 }
1550 return ret;
1551}
1552
1553/*
1554 * Compile whatever comes after "name" or "name()".
1555 * Advances "*arg" only when something was recognized.
1556 */
1557 static int
1558compile_subscript(
1559 char_u **arg,
1560 cctx_T *cctx,
1561 char_u *start_leader,
1562 char_u **end_leader,
1563 ppconst_T *ppconst)
1564{
1565 char_u *name_start = *end_leader;
1566 int keeping_dict = FALSE;
1567
1568 for (;;)
1569 {
1570 char_u *p = skipwhite(*arg);
1571
1572 if (*p == NUL || (VIM_ISWHITE(**arg) && vim9_comment_start(p)))
1573 {
1574 char_u *next = peek_next_line_from_context(cctx);
1575
1576 // If a following line starts with "->{" or "->X" advance to that
1577 // line, so that a line break before "->" is allowed.
1578 // Also if a following line starts with ".x".
1579 if (next != NULL &&
1580 ((next[0] == '-' && next[1] == '>'
1581 && (next[2] == '{'
1582 || ASCII_ISALPHA(*skipwhite(next + 2))))
1583 || (next[0] == '.' && eval_isdictc(next[1]))))
1584 {
1585 next = next_line_from_context(cctx, TRUE);
1586 if (next == NULL)
1587 return FAIL;
1588 *arg = next;
1589 p = skipwhite(*arg);
1590 }
1591 }
1592
1593 // Do not skip over white space to find the "(", "execute 'x' (expr)"
1594 // is not a function call.
1595 if (**arg == '(')
1596 {
1597 garray_T *stack = &cctx->ctx_type_stack;
1598 type_T *type;
1599 int argcount = 0;
1600
1601 if (generate_ppconst(cctx, ppconst) == FAIL)
1602 return FAIL;
1603 ppconst->pp_is_const = FALSE;
1604
1605 // funcref(arg)
1606 type = ((type_T **)stack->ga_data)[stack->ga_len - 1];
1607
1608 *arg = skipwhite(p + 1);
1609 if (compile_arguments(arg, cctx, &argcount, FALSE) == FAIL)
1610 return FAIL;
1611 if (generate_PCALL(cctx, argcount, name_start, type, TRUE) == FAIL)
1612 return FAIL;
1613 if (keeping_dict)
1614 {
1615 keeping_dict = FALSE;
1616 if (generate_instr(cctx, ISN_CLEARDICT) == NULL)
1617 return FAIL;
1618 }
1619 }
1620 else if (*p == '-' && p[1] == '>')
1621 {
1622 char_u *pstart = p;
1623
1624 if (generate_ppconst(cctx, ppconst) == FAIL)
1625 return FAIL;
1626 ppconst->pp_is_const = FALSE;
1627
1628 // something->method()
1629 // Apply the '!', '-' and '+' first:
1630 // -1.0->func() works like (-1.0)->func()
1631 if (compile_leader(cctx, TRUE, start_leader, end_leader) == FAIL)
1632 return FAIL;
1633
1634 p += 2;
1635 *arg = skipwhite(p);
1636 // No line break supported right after "->".
1637 if (**arg == '(')
1638 {
1639 int argcount = 1;
1640 garray_T *stack = &cctx->ctx_type_stack;
1641 int type_idx_start = stack->ga_len;
1642 type_T *type;
1643 int expr_isn_start = cctx->ctx_instr.ga_len;
1644 int expr_isn_end;
1645 int arg_isn_count;
1646
1647 // Funcref call: list->(Refs[2])(arg)
1648 // or lambda: list->((arg) => expr)(arg)
1649 //
1650 // Fist compile the function expression.
1651 if (compile_parenthesis(arg, cctx, ppconst) == FAIL)
1652 return FAIL;
1653
1654 // Remember the next instruction index, where the instructions
1655 // for arguments are being written.
1656 expr_isn_end = cctx->ctx_instr.ga_len;
1657
1658 // Compile the arguments.
1659 if (**arg != '(')
1660 {
1661 if (*skipwhite(*arg) == '(')
1662 emsg(_(e_nowhitespace));
1663 else
1664 semsg(_(e_missing_parenthesis_str), *arg);
1665 return FAIL;
1666 }
1667 *arg = skipwhite(*arg + 1);
1668 if (compile_arguments(arg, cctx, &argcount, FALSE) == FAIL)
1669 return FAIL;
1670
1671 // Move the instructions for the arguments to before the
1672 // instructions of the expression and move the type of the
1673 // expression after the argument types. This is what ISN_PCALL
1674 // expects.
1675 stack = &cctx->ctx_type_stack;
1676 arg_isn_count = cctx->ctx_instr.ga_len - expr_isn_end;
1677 if (arg_isn_count > 0)
1678 {
1679 int expr_isn_count = expr_isn_end - expr_isn_start;
1680 isn_T *isn = ALLOC_MULT(isn_T, expr_isn_count);
1681
1682 if (isn == NULL)
1683 return FAIL;
1684 mch_memmove(isn, ((isn_T *)cctx->ctx_instr.ga_data)
1685 + expr_isn_start,
1686 sizeof(isn_T) * expr_isn_count);
1687 mch_memmove(((isn_T *)cctx->ctx_instr.ga_data)
1688 + expr_isn_start,
1689 ((isn_T *)cctx->ctx_instr.ga_data) + expr_isn_end,
1690 sizeof(isn_T) * arg_isn_count);
1691 mch_memmove(((isn_T *)cctx->ctx_instr.ga_data)
1692 + expr_isn_start + arg_isn_count,
1693 isn, sizeof(isn_T) * expr_isn_count);
1694 vim_free(isn);
1695
1696 type = ((type_T **)stack->ga_data)[type_idx_start];
1697 mch_memmove(((type_T **)stack->ga_data) + type_idx_start,
1698 ((type_T **)stack->ga_data) + type_idx_start + 1,
1699 sizeof(type_T *)
1700 * (stack->ga_len - type_idx_start - 1));
1701 ((type_T **)stack->ga_data)[stack->ga_len - 1] = type;
1702 }
1703
1704 type = ((type_T **)stack->ga_data)[stack->ga_len - 1];
1705 if (generate_PCALL(cctx, argcount, p - 2, type, FALSE) == FAIL)
1706 return FAIL;
1707 }
1708 else
1709 {
1710 // method call: list->method()
1711 p = *arg;
1712 if (!eval_isnamec1(*p))
1713 {
1714 semsg(_(e_trailing_arg), pstart);
1715 return FAIL;
1716 }
1717 if (ASCII_ISALPHA(*p) && p[1] == ':')
1718 p += 2;
1719 for ( ; eval_isnamec(*p); ++p)
1720 ;
1721 if (*p != '(')
1722 {
1723 semsg(_(e_missing_parenthesis_str), *arg);
1724 return FAIL;
1725 }
1726 if (compile_call(arg, p - *arg, cctx, ppconst, 1) == FAIL)
1727 return FAIL;
1728 }
1729 if (keeping_dict)
1730 {
1731 keeping_dict = FALSE;
1732 if (generate_instr(cctx, ISN_CLEARDICT) == NULL)
1733 return FAIL;
1734 }
1735 }
1736 else if (**arg == '[')
1737 {
1738 int is_slice = FALSE;
1739
1740 // list index: list[123]
1741 // dict member: dict[key]
1742 // string index: text[123]
1743 // blob index: blob[123]
1744 if (generate_ppconst(cctx, ppconst) == FAIL)
1745 return FAIL;
1746 ppconst->pp_is_const = FALSE;
1747
1748 ++p;
1749 if (may_get_next_line_error(p, arg, cctx) == FAIL)
1750 return FAIL;
1751 if (**arg == ':')
1752 {
1753 // missing first index is equal to zero
1754 generate_PUSHNR(cctx, 0);
1755 }
1756 else
1757 {
1758 if (compile_expr0(arg, cctx) == FAIL)
1759 return FAIL;
1760 if (**arg == ':')
1761 {
1762 semsg(_(e_white_space_required_before_and_after_str_at_str),
1763 ":", *arg);
1764 return FAIL;
1765 }
1766 if (may_get_next_line_error(*arg, arg, cctx) == FAIL)
1767 return FAIL;
1768 *arg = skipwhite(*arg);
1769 }
1770 if (**arg == ':')
1771 {
1772 is_slice = TRUE;
1773 ++*arg;
1774 if (!IS_WHITE_OR_NUL(**arg) && **arg != ']')
1775 {
1776 semsg(_(e_white_space_required_before_and_after_str_at_str),
1777 ":", *arg);
1778 return FAIL;
1779 }
1780 if (may_get_next_line_error(*arg, arg, cctx) == FAIL)
1781 return FAIL;
1782 if (**arg == ']')
1783 // missing second index is equal to end of string
1784 generate_PUSHNR(cctx, -1);
1785 else
1786 {
1787 if (compile_expr0(arg, cctx) == FAIL)
1788 return FAIL;
1789 if (may_get_next_line_error(*arg, arg, cctx) == FAIL)
1790 return FAIL;
1791 *arg = skipwhite(*arg);
1792 }
1793 }
1794
1795 if (**arg != ']')
1796 {
1797 emsg(_(e_missing_closing_square_brace));
1798 return FAIL;
1799 }
1800 *arg = *arg + 1;
1801
1802 if (keeping_dict)
1803 {
1804 keeping_dict = FALSE;
1805 if (generate_instr(cctx, ISN_CLEARDICT) == NULL)
1806 return FAIL;
1807 }
1808 if (compile_member(is_slice, &keeping_dict, cctx) == FAIL)
1809 return FAIL;
1810 }
1811 else if (*p == '.' && p[1] != '.')
1812 {
1813 // dictionary member: dict.name
1814 if (generate_ppconst(cctx, ppconst) == FAIL)
1815 return FAIL;
1816 ppconst->pp_is_const = FALSE;
1817
1818 *arg = p + 1;
1819 if (IS_WHITE_OR_NUL(**arg))
1820 {
1821 emsg(_(e_missing_name_after_dot));
1822 return FAIL;
1823 }
1824 p = *arg;
1825 if (eval_isdictc(*p))
1826 while (eval_isnamec(*p))
1827 MB_PTR_ADV(p);
1828 if (p == *arg)
1829 {
1830 semsg(_(e_syntax_error_at_str), *arg);
1831 return FAIL;
1832 }
1833 if (keeping_dict && generate_instr(cctx, ISN_CLEARDICT) == NULL)
1834 return FAIL;
1835 if (generate_STRINGMEMBER(cctx, *arg, p - *arg) == FAIL)
1836 return FAIL;
1837 keeping_dict = TRUE;
1838 *arg = p;
1839 }
1840 else
1841 break;
1842 }
1843
1844 // Turn "dict.Func" into a partial for "Func" bound to "dict".
1845 // This needs to be done at runtime to be able to check the type.
1846 if (keeping_dict && generate_instr(cctx, ISN_USEDICT) == NULL)
1847 return FAIL;
1848
1849 return OK;
1850}
1851
1852/*
1853 * Compile an expression at "*arg" and add instructions to "cctx->ctx_instr".
1854 * "arg" is advanced until after the expression, skipping white space.
1855 *
1856 * If the value is a constant "ppconst->pp_used" will be non-zero.
1857 * Before instructions are generated, any values in "ppconst" will generated.
1858 *
1859 * This is the compiling equivalent of eval1(), eval2(), etc.
1860 */
1861
1862/*
1863 * number number constant
1864 * 0zFFFFFFFF Blob constant
1865 * "string" string constant
1866 * 'string' literal string constant
1867 * &option-name option value
1868 * @r register contents
1869 * identifier variable value
1870 * function() function call
1871 * $VAR environment variable
1872 * (expression) nested expression
1873 * [expr, expr] List
1874 * {key: val, [key]: val} Dictionary
1875 *
1876 * Also handle:
1877 * ! in front logical NOT
1878 * - in front unary minus
1879 * + in front unary plus (ignored)
1880 * trailing (arg) funcref/partial call
1881 * trailing [] subscript in String or List
1882 * trailing .name entry in Dictionary
1883 * trailing ->name() method call
1884 */
1885 static int
1886compile_expr7(
1887 char_u **arg,
1888 cctx_T *cctx,
1889 ppconst_T *ppconst)
1890{
1891 char_u *start_leader, *end_leader;
1892 int ret = OK;
1893 typval_T *rettv = &ppconst->pp_tv[ppconst->pp_used];
1894 int used_before = ppconst->pp_used;
1895
1896 ppconst->pp_is_const = FALSE;
1897
1898 /*
1899 * Skip '!', '-' and '+' characters. They are handled later.
1900 */
1901 start_leader = *arg;
1902 if (eval_leader(arg, TRUE) == FAIL)
1903 return FAIL;
1904 end_leader = *arg;
1905
1906 rettv->v_type = VAR_UNKNOWN;
1907 switch (**arg)
1908 {
1909 /*
1910 * Number constant.
1911 */
1912 case '0': // also for blob starting with 0z
1913 case '1':
1914 case '2':
1915 case '3':
1916 case '4':
1917 case '5':
1918 case '6':
1919 case '7':
1920 case '8':
1921 case '9':
1922 case '.': if (eval_number(arg, rettv, TRUE, FALSE) == FAIL)
1923 return FAIL;
1924 // Apply "-" and "+" just before the number now, right to
1925 // left. Matters especially when "->" follows. Stops at
1926 // '!'.
1927 if (apply_leader(rettv, TRUE,
1928 start_leader, &end_leader) == FAIL)
1929 {
1930 clear_tv(rettv);
1931 return FAIL;
1932 }
1933 break;
1934
1935 /*
1936 * String constant: "string".
1937 */
1938 case '"': if (eval_string(arg, rettv, TRUE) == FAIL)
1939 return FAIL;
1940 break;
1941
1942 /*
1943 * Literal string constant: 'str''ing'.
1944 */
1945 case '\'': if (eval_lit_string(arg, rettv, TRUE) == FAIL)
1946 return FAIL;
1947 break;
1948
1949 /*
1950 * Constant Vim variable.
1951 */
1952 case 'v': get_vim_constant(arg, rettv);
1953 ret = NOTDONE;
1954 break;
1955
1956 /*
1957 * "true" constant
1958 */
1959 case 't': if (STRNCMP(*arg, "true", 4) == 0
1960 && !eval_isnamec((*arg)[4]))
1961 {
1962 *arg += 4;
1963 rettv->v_type = VAR_BOOL;
1964 rettv->vval.v_number = VVAL_TRUE;
1965 }
1966 else
1967 ret = NOTDONE;
1968 break;
1969
1970 /*
1971 * "false" constant
1972 */
1973 case 'f': if (STRNCMP(*arg, "false", 5) == 0
1974 && !eval_isnamec((*arg)[5]))
1975 {
1976 *arg += 5;
1977 rettv->v_type = VAR_BOOL;
1978 rettv->vval.v_number = VVAL_FALSE;
1979 }
1980 else
1981 ret = NOTDONE;
1982 break;
1983
1984 /*
1985 * "null" constant
1986 */
1987 case 'n': if (STRNCMP(*arg, "null", 4) == 0
1988 && !eval_isnamec((*arg)[4]))
1989 {
1990 *arg += 4;
1991 rettv->v_type = VAR_SPECIAL;
1992 rettv->vval.v_number = VVAL_NULL;
1993 }
1994 else
1995 ret = NOTDONE;
1996 break;
1997
1998 /*
1999 * List: [expr, expr]
2000 */
2001 case '[': if (generate_ppconst(cctx, ppconst) == FAIL)
2002 return FAIL;
2003 ret = compile_list(arg, cctx, ppconst);
2004 break;
2005
2006 /*
2007 * Dictionary: {'key': val, 'key': val}
2008 */
2009 case '{': if (generate_ppconst(cctx, ppconst) == FAIL)
2010 return FAIL;
2011 ret = compile_dict(arg, cctx, ppconst);
2012 break;
2013
2014 /*
2015 * Option value: &name
2016 */
2017 case '&': if (generate_ppconst(cctx, ppconst) == FAIL)
2018 return FAIL;
2019 ret = compile_get_option(arg, cctx);
2020 break;
2021
2022 /*
2023 * Environment variable: $VAR.
2024 */
2025 case '$': if (generate_ppconst(cctx, ppconst) == FAIL)
2026 return FAIL;
2027 ret = compile_get_env(arg, cctx);
2028 break;
2029
2030 /*
2031 * Register contents: @r.
2032 */
2033 case '@': if (generate_ppconst(cctx, ppconst) == FAIL)
2034 return FAIL;
2035 ret = compile_get_register(arg, cctx);
2036 break;
2037 /*
2038 * nested expression: (expression).
2039 * lambda: (arg, arg) => expr
2040 * funcref: (arg, arg) => { statement }
2041 */
2042 case '(': // if compile_lambda returns NOTDONE then it must be (expr)
2043 ret = compile_lambda(arg, cctx);
2044 if (ret == NOTDONE)
2045 ret = compile_parenthesis(arg, cctx, ppconst);
2046 break;
2047
2048 default: ret = NOTDONE;
2049 break;
2050 }
2051 if (ret == FAIL)
2052 return FAIL;
2053
2054 if (rettv->v_type != VAR_UNKNOWN && used_before == ppconst->pp_used)
2055 {
2056 if (cctx->ctx_skip == SKIP_YES)
2057 clear_tv(rettv);
2058 else
2059 // A constant expression can possibly be handled compile time,
2060 // return the value instead of generating code.
2061 ++ppconst->pp_used;
2062 }
2063 else if (ret == NOTDONE)
2064 {
2065 char_u *p;
2066 int r;
2067
2068 if (!eval_isnamec1(**arg))
2069 {
2070 if (!vim9_bad_comment(*arg))
2071 {
2072 if (ends_excmd(*skipwhite(*arg)))
2073 semsg(_(e_empty_expression_str), *arg);
2074 else
2075 semsg(_(e_name_expected_str), *arg);
2076 }
2077 return FAIL;
2078 }
2079
2080 // "name" or "name()"
2081 p = to_name_end(*arg, TRUE);
2082 if (p - *arg == (size_t)1 && **arg == '_')
2083 {
2084 emsg(_(e_cannot_use_underscore_here));
2085 return FAIL;
2086 }
2087
2088 if (*p == '(')
2089 {
2090 r = compile_call(arg, p - *arg, cctx, ppconst, 0);
2091 }
2092 else
2093 {
2094 if (cctx->ctx_skip != SKIP_YES
2095 && generate_ppconst(cctx, ppconst) == FAIL)
2096 return FAIL;
2097 r = compile_load(arg, p, cctx, TRUE, TRUE);
2098 }
2099 if (r == FAIL)
2100 return FAIL;
2101 }
2102
2103 // Handle following "[]", ".member", etc.
2104 // Then deal with prefixed '-', '+' and '!', if not done already.
2105 if (compile_subscript(arg, cctx, start_leader, &end_leader,
2106 ppconst) == FAIL)
2107 return FAIL;
2108 if (ppconst->pp_used > 0)
2109 {
2110 // apply the '!', '-' and '+' before the constant
2111 rettv = &ppconst->pp_tv[ppconst->pp_used - 1];
2112 if (apply_leader(rettv, FALSE, start_leader, &end_leader) == FAIL)
2113 return FAIL;
2114 return OK;
2115 }
2116 if (compile_leader(cctx, FALSE, start_leader, &end_leader) == FAIL)
2117 return FAIL;
2118 return OK;
2119}
2120
2121/*
2122 * <type>expr7: runtime type check / conversion
2123 */
2124 static int
2125compile_expr7t(char_u **arg, cctx_T *cctx, ppconst_T *ppconst)
2126{
2127 type_T *want_type = NULL;
2128
2129 // Recognize <type>
2130 if (**arg == '<' && eval_isnamec1((*arg)[1]))
2131 {
2132 ++*arg;
2133 want_type = parse_type(arg, cctx->ctx_type_list, TRUE);
2134 if (want_type == NULL)
2135 return FAIL;
2136
2137 if (**arg != '>')
2138 {
2139 if (*skipwhite(*arg) == '>')
2140 semsg(_(e_no_white_space_allowed_before_str_str), ">", *arg);
2141 else
2142 emsg(_(e_missing_gt));
2143 return FAIL;
2144 }
2145 ++*arg;
2146 if (may_get_next_line_error(*arg, arg, cctx) == FAIL)
2147 return FAIL;
2148 }
2149
2150 if (compile_expr7(arg, cctx, ppconst) == FAIL)
2151 return FAIL;
2152
2153 if (want_type != NULL)
2154 {
2155 garray_T *stack = &cctx->ctx_type_stack;
2156 type_T *actual;
2157 where_T where = WHERE_INIT;
2158
2159 generate_ppconst(cctx, ppconst);
2160 actual = ((type_T **)stack->ga_data)[stack->ga_len - 1];
Bram Moolenaar59618fe2021-12-21 12:32:17 +00002161 if (check_type_maybe(want_type, actual, FALSE, where) != OK)
Bram Moolenaardc7c3662021-12-20 15:04:29 +00002162 {
Bram Moolenaar59618fe2021-12-21 12:32:17 +00002163 if (need_type(actual, want_type, -1, 0, cctx, FALSE, FALSE)
2164 == FAIL)
Bram Moolenaardc7c3662021-12-20 15:04:29 +00002165 return FAIL;
2166 }
2167 }
2168
2169 return OK;
2170}
2171
2172/*
2173 * * number multiplication
2174 * / number division
2175 * % number modulo
2176 */
2177 static int
2178compile_expr6(char_u **arg, cctx_T *cctx, ppconst_T *ppconst)
2179{
2180 char_u *op;
2181 char_u *next;
2182 int ppconst_used = ppconst->pp_used;
2183
2184 // get the first expression
2185 if (compile_expr7t(arg, cctx, ppconst) == FAIL)
2186 return FAIL;
2187
2188 /*
2189 * Repeat computing, until no "*", "/" or "%" is following.
2190 */
2191 for (;;)
2192 {
2193 op = may_peek_next_line(cctx, *arg, &next);
2194 if (*op != '*' && *op != '/' && *op != '%')
2195 break;
2196 if (next != NULL)
2197 {
2198 *arg = next_line_from_context(cctx, TRUE);
2199 op = skipwhite(*arg);
2200 }
2201
2202 if (!IS_WHITE_OR_NUL(**arg) || !IS_WHITE_OR_NUL(op[1]))
2203 {
2204 error_white_both(op, 1);
2205 return FAIL;
2206 }
2207 if (may_get_next_line_error(op + 1, arg, cctx) == FAIL)
2208 return FAIL;
2209
2210 // get the second expression
2211 if (compile_expr7t(arg, cctx, ppconst) == FAIL)
2212 return FAIL;
2213
2214 if (ppconst->pp_used == ppconst_used + 2
2215 && ppconst->pp_tv[ppconst_used].v_type == VAR_NUMBER
2216 && ppconst->pp_tv[ppconst_used + 1].v_type == VAR_NUMBER)
2217 {
2218 typval_T *tv1 = &ppconst->pp_tv[ppconst_used];
2219 typval_T *tv2 = &ppconst->pp_tv[ppconst_used + 1];
2220 varnumber_T res = 0;
2221 int failed = FALSE;
2222
2223 // both are numbers: compute the result
2224 switch (*op)
2225 {
2226 case '*': res = tv1->vval.v_number * tv2->vval.v_number;
2227 break;
2228 case '/': res = num_divide(tv1->vval.v_number,
2229 tv2->vval.v_number, &failed);
2230 break;
2231 case '%': res = num_modulus(tv1->vval.v_number,
2232 tv2->vval.v_number, &failed);
2233 break;
2234 }
2235 if (failed)
2236 return FAIL;
2237 tv1->vval.v_number = res;
2238 --ppconst->pp_used;
2239 }
2240 else
2241 {
2242 generate_ppconst(cctx, ppconst);
2243 generate_two_op(cctx, op);
2244 }
2245 }
2246
2247 return OK;
2248}
2249
2250/*
2251 * + number addition or list/blobl concatenation
2252 * - number subtraction
2253 * .. string concatenation
2254 */
2255 static int
2256compile_expr5(char_u **arg, cctx_T *cctx, ppconst_T *ppconst)
2257{
2258 char_u *op;
2259 char_u *next;
2260 int oplen;
2261 int ppconst_used = ppconst->pp_used;
2262
2263 // get the first variable
2264 if (compile_expr6(arg, cctx, ppconst) == FAIL)
2265 return FAIL;
2266
2267 /*
2268 * Repeat computing, until no "+", "-" or ".." is following.
2269 */
2270 for (;;)
2271 {
2272 op = may_peek_next_line(cctx, *arg, &next);
2273 if (*op != '+' && *op != '-' && !(*op == '.' && *(op + 1) == '.'))
2274 break;
2275 if (op[0] == op[1] && *op != '.' && next)
2276 // Finding "++" or "--" on the next line is a separate command.
2277 // But ".." is concatenation.
2278 break;
2279 oplen = (*op == '.' ? 2 : 1);
2280 if (next != NULL)
2281 {
2282 *arg = next_line_from_context(cctx, TRUE);
2283 op = skipwhite(*arg);
2284 }
2285
2286 if (!IS_WHITE_OR_NUL(**arg) || !IS_WHITE_OR_NUL(op[oplen]))
2287 {
2288 error_white_both(op, oplen);
2289 return FAIL;
2290 }
2291
2292 if (may_get_next_line_error(op + oplen, arg, cctx) == FAIL)
2293 return FAIL;
2294
2295 // get the second expression
2296 if (compile_expr6(arg, cctx, ppconst) == FAIL)
2297 return FAIL;
2298
2299 if (ppconst->pp_used == ppconst_used + 2
2300 && (*op == '.'
2301 ? (ppconst->pp_tv[ppconst_used].v_type == VAR_STRING
2302 && ppconst->pp_tv[ppconst_used + 1].v_type == VAR_STRING)
2303 : (ppconst->pp_tv[ppconst_used].v_type == VAR_NUMBER
2304 && ppconst->pp_tv[ppconst_used + 1].v_type == VAR_NUMBER)))
2305 {
2306 typval_T *tv1 = &ppconst->pp_tv[ppconst_used];
2307 typval_T *tv2 = &ppconst->pp_tv[ppconst_used + 1];
2308
2309 // concat/subtract/add constant numbers
2310 if (*op == '+')
2311 tv1->vval.v_number = tv1->vval.v_number + tv2->vval.v_number;
2312 else if (*op == '-')
2313 tv1->vval.v_number = tv1->vval.v_number - tv2->vval.v_number;
2314 else
2315 {
2316 // concatenate constant strings
2317 char_u *s1 = tv1->vval.v_string;
2318 char_u *s2 = tv2->vval.v_string;
2319 size_t len1 = STRLEN(s1);
2320
2321 tv1->vval.v_string = alloc((int)(len1 + STRLEN(s2) + 1));
2322 if (tv1->vval.v_string == NULL)
2323 {
2324 clear_ppconst(ppconst);
2325 return FAIL;
2326 }
2327 mch_memmove(tv1->vval.v_string, s1, len1);
2328 STRCPY(tv1->vval.v_string + len1, s2);
2329 vim_free(s1);
2330 vim_free(s2);
2331 }
2332 --ppconst->pp_used;
2333 }
2334 else
2335 {
2336 generate_ppconst(cctx, ppconst);
2337 ppconst->pp_is_const = FALSE;
2338 if (*op == '.')
2339 {
2340 if (may_generate_2STRING(-2, FALSE, cctx) == FAIL
2341 || may_generate_2STRING(-1, FALSE, cctx) == FAIL)
2342 return FAIL;
2343 generate_instr_drop(cctx, ISN_CONCAT, 1);
2344 }
2345 else
2346 generate_two_op(cctx, op);
2347 }
2348 }
2349
2350 return OK;
2351}
2352
2353/*
2354 * expr5a == expr5b
2355 * expr5a =~ expr5b
2356 * expr5a != expr5b
2357 * expr5a !~ expr5b
2358 * expr5a > expr5b
2359 * expr5a >= expr5b
2360 * expr5a < expr5b
2361 * expr5a <= expr5b
2362 * expr5a is expr5b
2363 * expr5a isnot expr5b
2364 *
2365 * Produces instructions:
2366 * EVAL expr5a Push result of "expr5a"
2367 * EVAL expr5b Push result of "expr5b"
2368 * COMPARE one of the compare instructions
2369 */
2370 static int
2371compile_expr4(char_u **arg, cctx_T *cctx, ppconst_T *ppconst)
2372{
2373 exprtype_T type = EXPR_UNKNOWN;
2374 char_u *p;
2375 char_u *next;
2376 int len = 2;
2377 int type_is = FALSE;
2378 int ppconst_used = ppconst->pp_used;
2379
2380 // get the first variable
2381 if (compile_expr5(arg, cctx, ppconst) == FAIL)
2382 return FAIL;
2383
2384 p = may_peek_next_line(cctx, *arg, &next);
2385 type = get_compare_type(p, &len, &type_is);
2386
2387 /*
2388 * If there is a comparative operator, use it.
2389 */
2390 if (type != EXPR_UNKNOWN)
2391 {
2392 int ic = FALSE; // Default: do not ignore case
2393
2394 if (next != NULL)
2395 {
2396 *arg = next_line_from_context(cctx, TRUE);
2397 p = skipwhite(*arg);
2398 }
2399 if (type_is && (p[len] == '?' || p[len] == '#'))
2400 {
2401 semsg(_(e_invalid_expression_str), *arg);
2402 return FAIL;
2403 }
2404 // extra question mark appended: ignore case
2405 if (p[len] == '?')
2406 {
2407 ic = TRUE;
2408 ++len;
2409 }
2410 // extra '#' appended: match case (ignored)
2411 else if (p[len] == '#')
2412 ++len;
2413 // nothing appended: match case
2414
2415 if (!IS_WHITE_OR_NUL(**arg) || !IS_WHITE_OR_NUL(p[len]))
2416 {
2417 error_white_both(p, len);
2418 return FAIL;
2419 }
2420
2421 // get the second variable
2422 if (may_get_next_line_error(p + len, arg, cctx) == FAIL)
2423 return FAIL;
2424
2425 if (compile_expr5(arg, cctx, ppconst) == FAIL)
2426 return FAIL;
2427
2428 if (ppconst->pp_used == ppconst_used + 2)
2429 {
2430 typval_T * tv1 = &ppconst->pp_tv[ppconst->pp_used - 2];
2431 typval_T *tv2 = &ppconst->pp_tv[ppconst->pp_used - 1];
2432 int ret;
2433
2434 // Both sides are a constant, compute the result now.
2435 // First check for a valid combination of types, this is more
2436 // strict than typval_compare().
2437 if (check_compare_types(type, tv1, tv2) == FAIL)
2438 ret = FAIL;
2439 else
2440 {
2441 ret = typval_compare(tv1, tv2, type, ic);
2442 tv1->v_type = VAR_BOOL;
2443 tv1->vval.v_number = tv1->vval.v_number
2444 ? VVAL_TRUE : VVAL_FALSE;
2445 clear_tv(tv2);
2446 --ppconst->pp_used;
2447 }
2448 return ret;
2449 }
2450
2451 generate_ppconst(cctx, ppconst);
2452 return generate_COMPARE(cctx, type, ic);
2453 }
2454
2455 return OK;
2456}
2457
2458static int compile_expr3(char_u **arg, cctx_T *cctx, ppconst_T *ppconst);
2459
2460/*
2461 * Compile || or &&.
2462 */
2463 static int
2464compile_and_or(
2465 char_u **arg,
2466 cctx_T *cctx,
2467 char *op,
2468 ppconst_T *ppconst,
2469 int ppconst_used UNUSED)
2470{
2471 char_u *next;
2472 char_u *p = may_peek_next_line(cctx, *arg, &next);
2473 int opchar = *op;
2474
2475 if (p[0] == opchar && p[1] == opchar)
2476 {
2477 garray_T *instr = &cctx->ctx_instr;
2478 garray_T end_ga;
2479 int save_skip = cctx->ctx_skip;
2480
2481 /*
2482 * Repeat until there is no following "||" or "&&"
2483 */
2484 ga_init2(&end_ga, sizeof(int), 10);
2485 while (p[0] == opchar && p[1] == opchar)
2486 {
2487 long start_lnum = SOURCING_LNUM;
2488 long save_sourcing_lnum;
2489 int start_ctx_lnum = cctx->ctx_lnum;
2490 int save_lnum;
2491 int const_used;
2492 int status;
2493 jumpwhen_T jump_when = opchar == '|'
2494 ? JUMP_IF_COND_TRUE : JUMP_IF_COND_FALSE;
2495
2496 if (next != NULL)
2497 {
2498 *arg = next_line_from_context(cctx, TRUE);
2499 p = skipwhite(*arg);
2500 }
2501
2502 if (!IS_WHITE_OR_NUL(**arg) || !IS_WHITE_OR_NUL(p[2]))
2503 {
2504 semsg(_(e_white_space_required_before_and_after_str_at_str),
2505 op, p);
2506 ga_clear(&end_ga);
2507 return FAIL;
2508 }
2509
2510 save_sourcing_lnum = SOURCING_LNUM;
2511 SOURCING_LNUM = start_lnum;
2512 save_lnum = cctx->ctx_lnum;
2513 cctx->ctx_lnum = start_ctx_lnum;
2514
2515 status = check_ppconst_bool(ppconst);
2516 if (status != FAIL)
2517 {
2518 // Use the last ppconst if possible.
2519 if (ppconst->pp_used > 0)
2520 {
2521 typval_T *tv = &ppconst->pp_tv[ppconst->pp_used - 1];
2522 int is_true = tv2bool(tv);
2523
2524 if ((is_true && opchar == '|')
2525 || (!is_true && opchar == '&'))
2526 {
2527 // For "false && expr" and "true || expr" the "expr"
2528 // does not need to be evaluated.
2529 cctx->ctx_skip = SKIP_YES;
2530 clear_tv(tv);
2531 tv->v_type = VAR_BOOL;
2532 tv->vval.v_number = is_true ? VVAL_TRUE : VVAL_FALSE;
2533 }
2534 else
2535 {
2536 // For "true && expr" and "false || expr" only "expr"
2537 // needs to be evaluated.
2538 --ppconst->pp_used;
2539 jump_when = JUMP_NEVER;
2540 }
2541 }
2542 else
2543 {
2544 // Every part must evaluate to a bool.
2545 status = bool_on_stack(cctx);
2546 }
2547 }
2548 if (status != FAIL)
2549 status = ga_grow(&end_ga, 1);
2550 cctx->ctx_lnum = save_lnum;
2551 if (status == FAIL)
2552 {
2553 ga_clear(&end_ga);
2554 return FAIL;
2555 }
2556
2557 if (jump_when != JUMP_NEVER)
2558 {
2559 if (cctx->ctx_skip != SKIP_YES)
2560 {
2561 *(((int *)end_ga.ga_data) + end_ga.ga_len) = instr->ga_len;
2562 ++end_ga.ga_len;
2563 }
2564 generate_JUMP(cctx, jump_when, 0);
2565 }
2566
2567 // eval the next expression
2568 SOURCING_LNUM = save_sourcing_lnum;
2569 if (may_get_next_line_error(p + 2, arg, cctx) == FAIL)
2570 {
2571 ga_clear(&end_ga);
2572 return FAIL;
2573 }
2574
2575 const_used = ppconst->pp_used;
2576 if ((opchar == '|' ? compile_expr3(arg, cctx, ppconst)
2577 : compile_expr4(arg, cctx, ppconst)) == FAIL)
2578 {
2579 ga_clear(&end_ga);
2580 return FAIL;
2581 }
2582
2583 // "0 || 1" results in true, "1 && 0" results in false.
2584 if (ppconst->pp_used == const_used + 1)
2585 {
2586 typval_T *tv = &ppconst->pp_tv[ppconst->pp_used - 1];
2587
2588 if (tv->v_type == VAR_NUMBER
2589 && (tv->vval.v_number == 1 || tv->vval.v_number == 0))
2590 {
2591 tv->vval.v_number = tv->vval.v_number == 1
2592 ? VVAL_TRUE : VVAL_FALSE;
2593 tv->v_type = VAR_BOOL;
2594 }
2595 }
2596
2597 p = may_peek_next_line(cctx, *arg, &next);
2598 }
2599
2600 if (check_ppconst_bool(ppconst) == FAIL)
2601 {
2602 ga_clear(&end_ga);
2603 return FAIL;
2604 }
2605
2606 if (cctx->ctx_skip != SKIP_YES && ppconst->pp_used == 0)
2607 // Every part must evaluate to a bool.
2608 if (bool_on_stack(cctx) == FAIL)
2609 {
2610 ga_clear(&end_ga);
2611 return FAIL;
2612 }
2613
2614 if (end_ga.ga_len > 0)
2615 {
2616 // Fill in the end label in all jumps.
2617 generate_ppconst(cctx, ppconst);
2618 while (end_ga.ga_len > 0)
2619 {
2620 isn_T *isn;
2621
2622 --end_ga.ga_len;
2623 isn = ((isn_T *)instr->ga_data)
2624 + *(((int *)end_ga.ga_data) + end_ga.ga_len);
2625 isn->isn_arg.jump.jump_where = instr->ga_len;
2626 }
2627 }
2628 ga_clear(&end_ga);
2629
2630 cctx->ctx_skip = save_skip;
2631 }
2632
2633 return OK;
2634}
2635
2636/*
2637 * expr4a && expr4a && expr4a logical AND
2638 *
2639 * Produces instructions:
2640 * EVAL expr4a Push result of "expr4a"
2641 * COND2BOOL convert to bool if needed
2642 * JUMP_IF_COND_FALSE end
2643 * EVAL expr4b Push result of "expr4b"
2644 * JUMP_IF_COND_FALSE end
2645 * EVAL expr4c Push result of "expr4c"
2646 * end:
2647 */
2648 static int
2649compile_expr3(char_u **arg, cctx_T *cctx, ppconst_T *ppconst)
2650{
2651 int ppconst_used = ppconst->pp_used;
2652
2653 // get the first variable
2654 if (compile_expr4(arg, cctx, ppconst) == FAIL)
2655 return FAIL;
2656
2657 // || and && work almost the same
2658 return compile_and_or(arg, cctx, "&&", ppconst, ppconst_used);
2659}
2660
2661/*
2662 * expr3a || expr3b || expr3c logical OR
2663 *
2664 * Produces instructions:
2665 * EVAL expr3a Push result of "expr3a"
2666 * COND2BOOL convert to bool if needed
2667 * JUMP_IF_COND_TRUE end
2668 * EVAL expr3b Push result of "expr3b"
2669 * JUMP_IF_COND_TRUE end
2670 * EVAL expr3c Push result of "expr3c"
2671 * end:
2672 */
2673 static int
2674compile_expr2(char_u **arg, cctx_T *cctx, ppconst_T *ppconst)
2675{
2676 int ppconst_used = ppconst->pp_used;
2677
2678 // eval the first expression
2679 if (compile_expr3(arg, cctx, ppconst) == FAIL)
2680 return FAIL;
2681
2682 // || and && work almost the same
2683 return compile_and_or(arg, cctx, "||", ppconst, ppconst_used);
2684}
2685
2686/*
2687 * Toplevel expression: expr2 ? expr1a : expr1b
2688 * Produces instructions:
2689 * EVAL expr2 Push result of "expr2"
2690 * JUMP_IF_FALSE alt jump if false
2691 * EVAL expr1a
2692 * JUMP_ALWAYS end
2693 * alt: EVAL expr1b
2694 * end:
2695 *
2696 * Toplevel expression: expr2 ?? expr1
2697 * Produces instructions:
2698 * EVAL expr2 Push result of "expr2"
2699 * JUMP_AND_KEEP_IF_TRUE end jump if true
2700 * EVAL expr1
2701 * end:
2702 */
2703 int
2704compile_expr1(char_u **arg, cctx_T *cctx, ppconst_T *ppconst)
2705{
2706 char_u *p;
2707 int ppconst_used = ppconst->pp_used;
2708 char_u *next;
2709
2710 // Ignore all kinds of errors when not producing code.
2711 if (cctx->ctx_skip == SKIP_YES)
2712 {
2713 skip_expr_cctx(arg, cctx);
2714 return OK;
2715 }
2716
2717 // Evaluate the first expression.
2718 if (compile_expr2(arg, cctx, ppconst) == FAIL)
2719 return FAIL;
2720
2721 p = may_peek_next_line(cctx, *arg, &next);
2722 if (*p == '?')
2723 {
2724 int op_falsy = p[1] == '?';
2725 garray_T *instr = &cctx->ctx_instr;
2726 garray_T *stack = &cctx->ctx_type_stack;
2727 int alt_idx = instr->ga_len;
2728 int end_idx = 0;
2729 isn_T *isn;
2730 type_T *type1 = NULL;
2731 int has_const_expr = FALSE;
2732 int const_value = FALSE;
2733 int save_skip = cctx->ctx_skip;
2734
2735 if (next != NULL)
2736 {
2737 *arg = next_line_from_context(cctx, TRUE);
2738 p = skipwhite(*arg);
2739 }
2740
2741 if (!IS_WHITE_OR_NUL(**arg) || !IS_WHITE_OR_NUL(p[1 + op_falsy]))
2742 {
2743 semsg(_(e_white_space_required_before_and_after_str_at_str),
2744 op_falsy ? "??" : "?", p);
2745 return FAIL;
2746 }
2747
2748 if (ppconst->pp_used == ppconst_used + 1)
2749 {
2750 // the condition is a constant, we know whether the ? or the :
2751 // expression is to be evaluated.
2752 has_const_expr = TRUE;
2753 if (op_falsy)
2754 const_value = tv2bool(&ppconst->pp_tv[ppconst_used]);
2755 else
2756 {
2757 int error = FALSE;
2758
2759 const_value = tv_get_bool_chk(&ppconst->pp_tv[ppconst_used],
2760 &error);
2761 if (error)
2762 return FAIL;
2763 }
2764 cctx->ctx_skip = save_skip == SKIP_YES ||
2765 (op_falsy ? const_value : !const_value) ? SKIP_YES : SKIP_NOT;
2766
2767 if (op_falsy && cctx->ctx_skip == SKIP_YES)
2768 // "left ?? right" and "left" is truthy: produce "left"
2769 generate_ppconst(cctx, ppconst);
2770 else
2771 {
2772 clear_tv(&ppconst->pp_tv[ppconst_used]);
2773 --ppconst->pp_used;
2774 }
2775 }
2776 else
2777 {
2778 generate_ppconst(cctx, ppconst);
2779 if (op_falsy)
2780 end_idx = instr->ga_len;
2781 generate_JUMP(cctx, op_falsy
2782 ? JUMP_AND_KEEP_IF_TRUE : JUMP_IF_FALSE, 0);
2783 if (op_falsy)
2784 type1 = ((type_T **)stack->ga_data)[stack->ga_len];
2785 }
2786
2787 // evaluate the second expression; any type is accepted
2788 if (may_get_next_line_error(p + 1 + op_falsy, arg, cctx) == FAIL)
2789 return FAIL;
2790 if (compile_expr1(arg, cctx, ppconst) == FAIL)
2791 return FAIL;
2792
2793 if (!has_const_expr)
2794 {
2795 generate_ppconst(cctx, ppconst);
2796
2797 if (!op_falsy)
2798 {
2799 // remember the type and drop it
2800 --stack->ga_len;
2801 type1 = ((type_T **)stack->ga_data)[stack->ga_len];
2802
2803 end_idx = instr->ga_len;
2804 generate_JUMP(cctx, JUMP_ALWAYS, 0);
2805
2806 // jump here from JUMP_IF_FALSE
2807 isn = ((isn_T *)instr->ga_data) + alt_idx;
2808 isn->isn_arg.jump.jump_where = instr->ga_len;
2809 }
2810 }
2811
2812 if (!op_falsy)
2813 {
2814 // Check for the ":".
2815 p = may_peek_next_line(cctx, *arg, &next);
2816 if (*p != ':')
2817 {
2818 emsg(_(e_missing_colon_after_questionmark));
2819 return FAIL;
2820 }
2821 if (next != NULL)
2822 {
2823 *arg = next_line_from_context(cctx, TRUE);
2824 p = skipwhite(*arg);
2825 }
2826
2827 if (!IS_WHITE_OR_NUL(**arg) || !IS_WHITE_OR_NUL(p[1]))
2828 {
2829 semsg(_(e_white_space_required_before_and_after_str_at_str),
2830 ":", p);
2831 return FAIL;
2832 }
2833
2834 // evaluate the third expression
2835 if (has_const_expr)
2836 cctx->ctx_skip = save_skip == SKIP_YES || const_value
2837 ? SKIP_YES : SKIP_NOT;
2838 if (may_get_next_line_error(p + 1, arg, cctx) == FAIL)
2839 return FAIL;
2840 if (compile_expr1(arg, cctx, ppconst) == FAIL)
2841 return FAIL;
2842 }
2843
2844 if (!has_const_expr)
2845 {
2846 type_T **typep;
2847
2848 generate_ppconst(cctx, ppconst);
2849
2850 // If the types differ, the result has a more generic type.
2851 typep = ((type_T **)stack->ga_data) + stack->ga_len - 1;
2852 common_type(type1, *typep, typep, cctx->ctx_type_list);
2853
2854 // jump here from JUMP_ALWAYS or JUMP_AND_KEEP_IF_TRUE
2855 isn = ((isn_T *)instr->ga_data) + end_idx;
2856 isn->isn_arg.jump.jump_where = instr->ga_len;
2857 }
2858
2859 cctx->ctx_skip = save_skip;
2860 }
2861 return OK;
2862}
2863
2864/*
2865 * Toplevel expression.
2866 * Sets "is_const" (if not NULL) to indicate the value is a constant.
2867 * Returns OK or FAIL.
2868 */
2869 int
2870compile_expr0_ext(char_u **arg, cctx_T *cctx, int *is_const)
2871{
2872 ppconst_T ppconst;
2873
2874 CLEAR_FIELD(ppconst);
2875 if (compile_expr1(arg, cctx, &ppconst) == FAIL)
2876 {
2877 clear_ppconst(&ppconst);
2878 return FAIL;
2879 }
2880 if (is_const != NULL)
2881 *is_const = ppconst.pp_used > 0 || ppconst.pp_is_const;
2882 if (generate_ppconst(cctx, &ppconst) == FAIL)
2883 return FAIL;
2884 return OK;
2885}
2886
2887/*
2888 * Toplevel expression.
2889 */
2890 int
2891compile_expr0(char_u **arg, cctx_T *cctx)
2892{
2893 return compile_expr0_ext(arg, cctx, NULL);
2894}
2895
2896
2897#endif // defined(FEAT_EVAL)