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