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