Mercurial > vim
comparison src/vim9instr.c @ 26935:ccb9be1cdd71 v8.2.3996
patch 8.2.3996: Vim9: type checking lacks information about declared type
Commit: https://github.com/vim/vim/commit/078a46161e8b1b30bf306d6c1f4f0af7c616a989
Author: Bram Moolenaar <Bram@vim.org>
Date: Tue Jan 4 15:17:03 2022 +0000
patch 8.2.3996: Vim9: type checking lacks information about declared type
Problem: Vim9: type checking for list and dict lacks information about
declared type.
Solution: Add dv_decl_type and lv_decl_type. Refactor the type stack to
store two types in each entry.
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Tue, 04 Jan 2022 16:30:06 +0100 |
parents | 06a137af96f8 |
children | 18cafa092e8d |
comparison
equal
deleted
inserted
replaced
26934:2d3dd8065e25 | 26935:ccb9be1cdd71 |
---|---|
55 * Returns a pointer to the new instruction, NULL if failed. | 55 * Returns a pointer to the new instruction, NULL if failed. |
56 */ | 56 */ |
57 isn_T * | 57 isn_T * |
58 generate_instr_drop(cctx_T *cctx, isntype_T isn_type, int drop) | 58 generate_instr_drop(cctx_T *cctx, isntype_T isn_type, int drop) |
59 { | 59 { |
60 garray_T *stack = &cctx->ctx_type_stack; | |
61 | |
62 RETURN_NULL_IF_SKIP(cctx); | 60 RETURN_NULL_IF_SKIP(cctx); |
63 stack->ga_len -= drop; | 61 cctx->ctx_type_stack.ga_len -= drop; |
64 return generate_instr(cctx, isn_type); | 62 return generate_instr(cctx, isn_type); |
65 } | 63 } |
66 | 64 |
67 /* | 65 /* |
66 * Generate instruction "isn_type" and put "type" on the type stack, | |
67 * use "decl_type" for the declared type. | |
68 */ | |
69 isn_T * | |
70 generate_instr_type2( | |
71 cctx_T *cctx, | |
72 isntype_T isn_type, | |
73 type_T *type, | |
74 type_T *decl_type) | |
75 { | |
76 isn_T *isn; | |
77 | |
78 if ((isn = generate_instr(cctx, isn_type)) == NULL) | |
79 return NULL; | |
80 | |
81 if (push_type_stack2(cctx, type == NULL ? &t_any : type, | |
82 decl_type == NULL ? &t_any : decl_type) == FAIL) | |
83 return NULL; | |
84 | |
85 return isn; | |
86 } | |
87 | |
88 /* | |
68 * Generate instruction "isn_type" and put "type" on the type stack. | 89 * Generate instruction "isn_type" and put "type" on the type stack. |
90 * Uses "any" for the declared type, which works for constants. For declared | |
91 * variables use generate_instr_type2(). | |
69 */ | 92 */ |
70 isn_T * | 93 isn_T * |
71 generate_instr_type(cctx_T *cctx, isntype_T isn_type, type_T *type) | 94 generate_instr_type(cctx_T *cctx, isntype_T isn_type, type_T *type) |
72 { | 95 { |
73 isn_T *isn; | 96 return generate_instr_type2(cctx, isn_type, type, &t_any); |
74 garray_T *stack = &cctx->ctx_type_stack; | |
75 | |
76 if ((isn = generate_instr(cctx, isn_type)) == NULL) | |
77 return NULL; | |
78 | |
79 if (GA_GROW_FAILS(stack, 1)) | |
80 return NULL; | |
81 ((type_T **)stack->ga_data)[stack->ga_len] = type == NULL ? &t_any : type; | |
82 ++stack->ga_len; | |
83 | |
84 return isn; | |
85 } | 97 } |
86 | 98 |
87 /* | 99 /* |
88 * Generate an ISN_DEBUG instruction. | 100 * Generate an ISN_DEBUG instruction. |
89 */ | 101 */ |
109 int | 121 int |
110 may_generate_2STRING(int offset, int tolerant, cctx_T *cctx) | 122 may_generate_2STRING(int offset, int tolerant, cctx_T *cctx) |
111 { | 123 { |
112 isn_T *isn; | 124 isn_T *isn; |
113 isntype_T isntype = ISN_2STRING; | 125 isntype_T isntype = ISN_2STRING; |
114 garray_T *stack = &cctx->ctx_type_stack; | 126 type_T *type; |
115 type_T **type; | 127 |
116 | 128 RETURN_OK_IF_SKIP(cctx); |
117 RETURN_OK_IF_SKIP(cctx); | 129 type = get_type_on_stack(cctx, -1 - offset); |
118 type = ((type_T **)stack->ga_data) + stack->ga_len + offset; | 130 switch (type->tt_type) |
119 switch ((*type)->tt_type) | |
120 { | 131 { |
121 // nothing to be done | 132 // nothing to be done |
122 case VAR_STRING: return OK; | 133 case VAR_STRING: return OK; |
123 | 134 |
124 // conversion possible | 135 // conversion possible |
150 case VAR_PARTIAL: | 161 case VAR_PARTIAL: |
151 case VAR_DICT: | 162 case VAR_DICT: |
152 case VAR_JOB: | 163 case VAR_JOB: |
153 case VAR_CHANNEL: | 164 case VAR_CHANNEL: |
154 case VAR_INSTR: | 165 case VAR_INSTR: |
155 to_string_error((*type)->tt_type); | 166 to_string_error(type->tt_type); |
156 return FAIL; | 167 return FAIL; |
157 } | 168 } |
158 | 169 |
159 *type = &t_string; | 170 set_type_on_stack(cctx, &t_string, -1 - offset); |
160 if ((isn = generate_instr(cctx, isntype)) == NULL) | 171 if ((isn = generate_instr(cctx, isntype)) == NULL) |
161 return FAIL; | 172 return FAIL; |
162 isn->isn_arg.tostring.offset = offset; | 173 isn->isn_arg.tostring.offset = offset; |
163 isn->isn_arg.tostring.tolerant = tolerant; | 174 isn->isn_arg.tostring.tolerant = tolerant; |
164 | 175 |
191 vartype_T vartype, | 202 vartype_T vartype, |
192 type_T *type1, | 203 type_T *type1, |
193 type_T *type2, | 204 type_T *type2, |
194 exprtype_T expr_type) | 205 exprtype_T expr_type) |
195 { | 206 { |
196 garray_T *stack = &cctx->ctx_type_stack; | |
197 isn_T *isn = generate_instr_drop(cctx, | 207 isn_T *isn = generate_instr_drop(cctx, |
198 vartype == VAR_NUMBER ? ISN_OPNR | 208 vartype == VAR_NUMBER ? ISN_OPNR |
199 : vartype == VAR_LIST ? ISN_ADDLIST | 209 : vartype == VAR_LIST ? ISN_ADDLIST |
200 : vartype == VAR_BLOB ? ISN_ADDBLOB | 210 : vartype == VAR_BLOB ? ISN_ADDBLOB |
201 #ifdef FEAT_FLOAT | 211 #ifdef FEAT_FLOAT |
223 // When concatenating two lists with different member types the member type | 233 // When concatenating two lists with different member types the member type |
224 // becomes "any". | 234 // becomes "any". |
225 if (vartype == VAR_LIST | 235 if (vartype == VAR_LIST |
226 && type1->tt_type == VAR_LIST && type2->tt_type == VAR_LIST | 236 && type1->tt_type == VAR_LIST && type2->tt_type == VAR_LIST |
227 && type1->tt_member != type2->tt_member) | 237 && type1->tt_member != type2->tt_member) |
228 (((type_T **)stack->ga_data)[stack->ga_len - 1]) = &t_list_any; | 238 set_type_on_stack(cctx, &t_list_any, 0); |
229 | 239 |
230 return isn == NULL ? FAIL : OK; | 240 return isn == NULL ? FAIL : OK; |
231 } | 241 } |
232 | 242 |
233 /* | 243 /* |
254 * type of the arguments. | 264 * type of the arguments. |
255 */ | 265 */ |
256 int | 266 int |
257 generate_two_op(cctx_T *cctx, char_u *op) | 267 generate_two_op(cctx_T *cctx, char_u *op) |
258 { | 268 { |
259 garray_T *stack = &cctx->ctx_type_stack; | |
260 type_T *type1; | 269 type_T *type1; |
261 type_T *type2; | 270 type_T *type2; |
262 vartype_T vartype; | 271 vartype_T vartype; |
263 isn_T *isn; | 272 isn_T *isn; |
264 | 273 |
265 RETURN_OK_IF_SKIP(cctx); | 274 RETURN_OK_IF_SKIP(cctx); |
266 | 275 |
267 // Get the known type of the two items on the stack. | 276 // Get the known type of the two items on the stack. |
268 type1 = ((type_T **)stack->ga_data)[stack->ga_len - 2]; | 277 type1 = get_type_on_stack(cctx, 1); |
269 type2 = ((type_T **)stack->ga_data)[stack->ga_len - 1]; | 278 type2 = get_type_on_stack(cctx, 0); |
270 vartype = operator_type(type1, type2); | 279 vartype = operator_type(type1, type2); |
271 | 280 |
272 switch (*op) | 281 switch (*op) |
273 { | 282 { |
274 case '+': | 283 case '+': |
321 // float+number and number+float results in float | 330 // float+number and number+float results in float |
322 if ((type1->tt_type == VAR_NUMBER || type1->tt_type == VAR_FLOAT) | 331 if ((type1->tt_type == VAR_NUMBER || type1->tt_type == VAR_FLOAT) |
323 && (type2->tt_type == VAR_NUMBER || type2->tt_type == VAR_FLOAT)) | 332 && (type2->tt_type == VAR_NUMBER || type2->tt_type == VAR_FLOAT)) |
324 type = &t_float; | 333 type = &t_float; |
325 #endif | 334 #endif |
326 ((type_T **)stack->ga_data)[stack->ga_len - 1] = type; | 335 set_type_on_stack(cctx, type, 0); |
327 } | 336 } |
328 | 337 |
329 return OK; | 338 return OK; |
330 } | 339 } |
331 | 340 |
413 RETURN_OK_IF_SKIP(cctx); | 422 RETURN_OK_IF_SKIP(cctx); |
414 | 423 |
415 // Get the known type of the two items on the stack. If they are matching | 424 // Get the known type of the two items on the stack. If they are matching |
416 // use a type-specific instruction. Otherwise fall back to runtime type | 425 // use a type-specific instruction. Otherwise fall back to runtime type |
417 // checking. | 426 // checking. |
418 type1 = ((type_T **)stack->ga_data)[stack->ga_len - 2]->tt_type; | 427 type1 = get_type_on_stack(cctx, 1)->tt_type; |
419 type2 = ((type_T **)stack->ga_data)[stack->ga_len - 1]->tt_type; | 428 type2 = get_type_on_stack(cctx, 0)->tt_type; |
420 isntype = get_compare_isn(exprtype, type1, type2); | 429 isntype = get_compare_isn(exprtype, type1, type2); |
421 if (isntype == ISN_DROP) | 430 if (isntype == ISN_DROP) |
422 return FAIL; | 431 return FAIL; |
423 | 432 |
424 if ((isn = generate_instr(cctx, isntype)) == NULL) | 433 if ((isn = generate_instr(cctx, isntype)) == NULL) |
428 | 437 |
429 // takes two arguments, puts one bool back | 438 // takes two arguments, puts one bool back |
430 if (stack->ga_len >= 2) | 439 if (stack->ga_len >= 2) |
431 { | 440 { |
432 --stack->ga_len; | 441 --stack->ga_len; |
433 ((type_T **)stack->ga_data)[stack->ga_len - 1] = &t_bool; | 442 set_type_on_stack(cctx, &t_bool, 0); |
434 } | 443 } |
435 | 444 |
436 return OK; | 445 return OK; |
437 } | 446 } |
438 | 447 |
442 */ | 451 */ |
443 int | 452 int |
444 generate_2BOOL(cctx_T *cctx, int invert, int offset) | 453 generate_2BOOL(cctx_T *cctx, int invert, int offset) |
445 { | 454 { |
446 isn_T *isn; | 455 isn_T *isn; |
447 garray_T *stack = &cctx->ctx_type_stack; | |
448 | 456 |
449 RETURN_OK_IF_SKIP(cctx); | 457 RETURN_OK_IF_SKIP(cctx); |
450 if ((isn = generate_instr(cctx, ISN_2BOOL)) == NULL) | 458 if ((isn = generate_instr(cctx, ISN_2BOOL)) == NULL) |
451 return FAIL; | 459 return FAIL; |
452 isn->isn_arg.tobool.invert = invert; | 460 isn->isn_arg.tobool.invert = invert; |
453 isn->isn_arg.tobool.offset = offset; | 461 isn->isn_arg.tobool.offset = offset; |
454 | 462 |
455 // type becomes bool | 463 // type becomes bool |
456 ((type_T **)stack->ga_data)[stack->ga_len + offset] = &t_bool; | 464 set_type_on_stack(cctx, &t_bool, -1 - offset); |
457 | 465 |
458 return OK; | 466 return OK; |
459 } | 467 } |
460 | 468 |
461 /* | 469 /* |
463 */ | 471 */ |
464 int | 472 int |
465 generate_COND2BOOL(cctx_T *cctx) | 473 generate_COND2BOOL(cctx_T *cctx) |
466 { | 474 { |
467 isn_T *isn; | 475 isn_T *isn; |
468 garray_T *stack = &cctx->ctx_type_stack; | |
469 | 476 |
470 RETURN_OK_IF_SKIP(cctx); | 477 RETURN_OK_IF_SKIP(cctx); |
471 if ((isn = generate_instr(cctx, ISN_COND2BOOL)) == NULL) | 478 if ((isn = generate_instr(cctx, ISN_COND2BOOL)) == NULL) |
472 return FAIL; | 479 return FAIL; |
473 | 480 |
474 // type becomes bool | 481 // type becomes bool |
475 ((type_T **)stack->ga_data)[stack->ga_len - 1] = &t_bool; | 482 set_type_on_stack(cctx, &t_bool, 0); |
476 | 483 |
477 return OK; | 484 return OK; |
478 } | 485 } |
479 | 486 |
480 int | 487 int |
483 type_T *expected, | 490 type_T *expected, |
484 int offset, | 491 int offset, |
485 int argidx) | 492 int argidx) |
486 { | 493 { |
487 isn_T *isn; | 494 isn_T *isn; |
488 garray_T *stack = &cctx->ctx_type_stack; | |
489 | 495 |
490 RETURN_OK_IF_SKIP(cctx); | 496 RETURN_OK_IF_SKIP(cctx); |
491 if ((isn = generate_instr(cctx, ISN_CHECKTYPE)) == NULL) | 497 if ((isn = generate_instr(cctx, ISN_CHECKTYPE)) == NULL) |
492 return FAIL; | 498 return FAIL; |
493 isn->isn_arg.type.ct_type = alloc_type(expected); | 499 isn->isn_arg.type.ct_type = alloc_type(expected); |
494 isn->isn_arg.type.ct_off = (int8_T)offset; | 500 isn->isn_arg.type.ct_off = (int8_T)offset; |
495 isn->isn_arg.type.ct_arg_idx = (int8_T)argidx; | 501 isn->isn_arg.type.ct_arg_idx = (int8_T)argidx; |
496 | 502 |
497 // type becomes expected | 503 // type becomes expected |
498 ((type_T **)stack->ga_data)[stack->ga_len + offset] = expected; | 504 set_type_on_stack(cctx, expected, -1 - offset); |
499 | 505 |
500 return OK; | 506 return OK; |
501 } | 507 } |
502 | 508 |
503 int | 509 int |
565 */ | 571 */ |
566 int | 572 int |
567 generate_PUSHNR(cctx_T *cctx, varnumber_T number) | 573 generate_PUSHNR(cctx_T *cctx, varnumber_T number) |
568 { | 574 { |
569 isn_T *isn; | 575 isn_T *isn; |
570 garray_T *stack = &cctx->ctx_type_stack; | |
571 | 576 |
572 RETURN_OK_IF_SKIP(cctx); | 577 RETURN_OK_IF_SKIP(cctx); |
573 if ((isn = generate_instr_type(cctx, ISN_PUSHNR, &t_number)) == NULL) | 578 if ((isn = generate_instr_type(cctx, ISN_PUSHNR, &t_number)) == NULL) |
574 return FAIL; | 579 return FAIL; |
575 isn->isn_arg.number = number; | 580 isn->isn_arg.number = number; |
576 | 581 |
577 if (number == 0 || number == 1) | 582 if (number == 0 || number == 1) |
578 // A 0 or 1 number can also be used as a bool. | 583 // A 0 or 1 number can also be used as a bool. |
579 ((type_T **)stack->ga_data)[stack->ga_len - 1] = &t_number_bool; | 584 set_type_on_stack(cctx, &t_number_bool, 0); |
580 return OK; | 585 return OK; |
581 } | 586 } |
582 | 587 |
583 /* | 588 /* |
584 * Generate an ISN_PUSHBOOL instruction. | 589 * Generate an ISN_PUSHBOOL instruction. |
745 */ | 750 */ |
746 int | 751 int |
747 generate_GETITEM(cctx_T *cctx, int index, int with_op) | 752 generate_GETITEM(cctx_T *cctx, int index, int with_op) |
748 { | 753 { |
749 isn_T *isn; | 754 isn_T *isn; |
750 garray_T *stack = &cctx->ctx_type_stack; | 755 type_T *type = get_type_on_stack(cctx, with_op ? 1 : 0); |
751 type_T *type = ((type_T **)stack->ga_data)[stack->ga_len | |
752 - (with_op ? 2 : 1)]; | |
753 type_T *item_type = &t_any; | 756 type_T *item_type = &t_any; |
754 | 757 |
755 RETURN_OK_IF_SKIP(cctx); | 758 RETURN_OK_IF_SKIP(cctx); |
756 | 759 |
757 if (type->tt_type != VAR_LIST) | 760 if (type->tt_type != VAR_LIST) |
765 return FAIL; | 768 return FAIL; |
766 isn->isn_arg.getitem.gi_index = index; | 769 isn->isn_arg.getitem.gi_index = index; |
767 isn->isn_arg.getitem.gi_with_op = with_op; | 770 isn->isn_arg.getitem.gi_with_op = with_op; |
768 | 771 |
769 // add the item type to the type stack | 772 // add the item type to the type stack |
770 if (GA_GROW_FAILS(stack, 1)) | 773 return push_type_stack(cctx, item_type); |
771 return FAIL; | |
772 ((type_T **)stack->ga_data)[stack->ga_len] = item_type; | |
773 ++stack->ga_len; | |
774 return OK; | |
775 } | 774 } |
776 | 775 |
777 /* | 776 /* |
778 * Generate an ISN_SLICE instruction with "count". | 777 * Generate an ISN_SLICE instruction with "count". |
779 */ | 778 */ |
893 type_T *type) | 892 type_T *type) |
894 { | 893 { |
895 isn_T *isn; | 894 isn_T *isn; |
896 | 895 |
897 RETURN_OK_IF_SKIP(cctx); | 896 RETURN_OK_IF_SKIP(cctx); |
898 if ((isn = generate_instr_type(cctx, isn_type, type)) == NULL) | 897 if ((isn = generate_instr_type2(cctx, isn_type, type, type)) == NULL) |
899 return FAIL; | 898 return FAIL; |
900 if (name != NULL) | 899 if (name != NULL) |
901 isn->isn_arg.string = vim_strsave(name); | 900 isn->isn_arg.string = vim_strsave(name); |
902 else | 901 else |
903 isn->isn_arg.number = idx; | 902 isn->isn_arg.number = idx; |
916 type_T *type) | 915 type_T *type) |
917 { | 916 { |
918 isn_T *isn; | 917 isn_T *isn; |
919 | 918 |
920 RETURN_OK_IF_SKIP(cctx); | 919 RETURN_OK_IF_SKIP(cctx); |
921 if ((isn = generate_instr_type(cctx, ISN_LOADOUTER, type)) == NULL) | 920 if ((isn = generate_instr_type2(cctx, ISN_LOADOUTER, type, type)) == NULL) |
922 return FAIL; | 921 return FAIL; |
923 isn->isn_arg.outer.outer_idx = idx; | 922 isn->isn_arg.outer.outer_idx = idx; |
924 isn->isn_arg.outer.outer_depth = nesting; | 923 isn->isn_arg.outer.outer_depth = nesting; |
925 | 924 |
926 return OK; | 925 return OK; |
1048 */ | 1047 */ |
1049 int | 1048 int |
1050 generate_NEWLIST(cctx_T *cctx, int count) | 1049 generate_NEWLIST(cctx_T *cctx, int count) |
1051 { | 1050 { |
1052 isn_T *isn; | 1051 isn_T *isn; |
1053 garray_T *stack = &cctx->ctx_type_stack; | 1052 type_T *member_type; |
1053 type_T *decl_member_type; | |
1054 type_T *type; | 1054 type_T *type; |
1055 type_T *member; | 1055 type_T *decl_type; |
1056 | 1056 |
1057 RETURN_OK_IF_SKIP(cctx); | 1057 RETURN_OK_IF_SKIP(cctx); |
1058 if ((isn = generate_instr(cctx, ISN_NEWLIST)) == NULL) | 1058 if ((isn = generate_instr(cctx, ISN_NEWLIST)) == NULL) |
1059 return FAIL; | 1059 return FAIL; |
1060 isn->isn_arg.number = count; | 1060 isn->isn_arg.number = count; |
1061 | 1061 |
1062 // get the member type from all the items on the stack. | 1062 // Get the member type and the declared member type from all the items on |
1063 if (count == 0) | 1063 // the stack. |
1064 member = &t_unknown; | 1064 member_type = get_member_type_from_stack(count, 1, &decl_member_type, cctx); |
1065 else | 1065 type = get_list_type(member_type, cctx->ctx_type_list); |
1066 member = get_member_type_from_stack( | 1066 decl_type = get_list_type(decl_member_type, cctx->ctx_type_list); |
1067 ((type_T **)stack->ga_data) + stack->ga_len, count, 1, | |
1068 cctx->ctx_type_list); | |
1069 type = get_list_type(member, cctx->ctx_type_list); | |
1070 | 1067 |
1071 // drop the value types | 1068 // drop the value types |
1072 stack->ga_len -= count; | 1069 cctx->ctx_type_stack.ga_len -= count; |
1073 | 1070 |
1074 // add the list type to the type stack | 1071 // add the list type to the type stack |
1075 if (GA_GROW_FAILS(stack, 1)) | 1072 return push_type_stack2(cctx, type, decl_type); |
1076 return FAIL; | |
1077 ((type_T **)stack->ga_data)[stack->ga_len] = type; | |
1078 ++stack->ga_len; | |
1079 | |
1080 return OK; | |
1081 } | 1073 } |
1082 | 1074 |
1083 /* | 1075 /* |
1084 * Generate an ISN_NEWDICT instruction. | 1076 * Generate an ISN_NEWDICT instruction. |
1085 */ | 1077 */ |
1086 int | 1078 int |
1087 generate_NEWDICT(cctx_T *cctx, int count) | 1079 generate_NEWDICT(cctx_T *cctx, int count) |
1088 { | 1080 { |
1089 isn_T *isn; | 1081 isn_T *isn; |
1090 garray_T *stack = &cctx->ctx_type_stack; | 1082 type_T *member_type; |
1083 type_T *decl_member_type; | |
1091 type_T *type; | 1084 type_T *type; |
1092 type_T *member; | 1085 type_T *decl_type; |
1093 | 1086 |
1094 RETURN_OK_IF_SKIP(cctx); | 1087 RETURN_OK_IF_SKIP(cctx); |
1095 if ((isn = generate_instr(cctx, ISN_NEWDICT)) == NULL) | 1088 if ((isn = generate_instr(cctx, ISN_NEWDICT)) == NULL) |
1096 return FAIL; | 1089 return FAIL; |
1097 isn->isn_arg.number = count; | 1090 isn->isn_arg.number = count; |
1098 | 1091 |
1099 if (count == 0) | 1092 member_type = get_member_type_from_stack(count, 2, |
1100 member = &t_void; | 1093 &decl_member_type, cctx); |
1101 else | 1094 type = get_dict_type(member_type, cctx->ctx_type_list); |
1102 member = get_member_type_from_stack( | 1095 decl_type = get_dict_type(decl_member_type, cctx->ctx_type_list); |
1103 ((type_T **)stack->ga_data) + stack->ga_len, count, 2, | |
1104 cctx->ctx_type_list); | |
1105 type = get_dict_type(member, cctx->ctx_type_list); | |
1106 | 1096 |
1107 // drop the key and value types | 1097 // drop the key and value types |
1108 stack->ga_len -= 2 * count; | 1098 cctx->ctx_type_stack.ga_len -= 2 * count; |
1109 | 1099 |
1110 // add the dict type to the type stack | 1100 // add the dict type to the type stack |
1111 if (GA_GROW_FAILS(stack, 1)) | 1101 return push_type_stack2(cctx, type, decl_type); |
1112 return FAIL; | |
1113 ((type_T **)stack->ga_data)[stack->ga_len] = type; | |
1114 ++stack->ga_len; | |
1115 | |
1116 return OK; | |
1117 } | 1102 } |
1118 | 1103 |
1119 /* | 1104 /* |
1120 * Generate an ISN_FUNCREF instruction. | 1105 * Generate an ISN_FUNCREF instruction. |
1121 */ | 1106 */ |
1122 int | 1107 int |
1123 generate_FUNCREF(cctx_T *cctx, ufunc_T *ufunc) | 1108 generate_FUNCREF(cctx_T *cctx, ufunc_T *ufunc) |
1124 { | 1109 { |
1125 isn_T *isn; | 1110 isn_T *isn; |
1126 garray_T *stack = &cctx->ctx_type_stack; | 1111 type_T *type; |
1127 | 1112 |
1128 RETURN_OK_IF_SKIP(cctx); | 1113 RETURN_OK_IF_SKIP(cctx); |
1129 if ((isn = generate_instr(cctx, ISN_FUNCREF)) == NULL) | 1114 if ((isn = generate_instr(cctx, ISN_FUNCREF)) == NULL) |
1130 return FAIL; | 1115 return FAIL; |
1131 if (ufunc->uf_def_status == UF_NOT_COMPILED) | 1116 if (ufunc->uf_def_status == UF_NOT_COMPILED) |
1137 // If the referenced function is a closure, it may use items further up in | 1122 // If the referenced function is a closure, it may use items further up in |
1138 // the nested context, including this one. | 1123 // the nested context, including this one. |
1139 if (ufunc->uf_flags & FC_CLOSURE) | 1124 if (ufunc->uf_flags & FC_CLOSURE) |
1140 cctx->ctx_ufunc->uf_flags |= FC_CLOSURE; | 1125 cctx->ctx_ufunc->uf_flags |= FC_CLOSURE; |
1141 | 1126 |
1142 if (GA_GROW_FAILS(stack, 1)) | 1127 type = ufunc->uf_func_type == NULL ? &t_func_any : ufunc->uf_func_type; |
1143 return FAIL; | 1128 return push_type_stack(cctx, type); |
1144 ((type_T **)stack->ga_data)[stack->ga_len] = | |
1145 ufunc->uf_func_type == NULL ? &t_func_any : ufunc->uf_func_type; | |
1146 ++stack->ga_len; | |
1147 | |
1148 return OK; | |
1149 } | 1129 } |
1150 | 1130 |
1151 /* | 1131 /* |
1152 * Generate an ISN_NEWFUNC instruction. | 1132 * Generate an ISN_NEWFUNC instruction. |
1153 * "lambda_name" and "func_name" must be in allocated memory and will be | 1133 * "lambda_name" and "func_name" must be in allocated memory and will be |
1235 | 1215 |
1236 int | 1216 int |
1237 generate_FOR(cctx_T *cctx, int loop_idx) | 1217 generate_FOR(cctx_T *cctx, int loop_idx) |
1238 { | 1218 { |
1239 isn_T *isn; | 1219 isn_T *isn; |
1240 garray_T *stack = &cctx->ctx_type_stack; | |
1241 | 1220 |
1242 RETURN_OK_IF_SKIP(cctx); | 1221 RETURN_OK_IF_SKIP(cctx); |
1243 if ((isn = generate_instr(cctx, ISN_FOR)) == NULL) | 1222 if ((isn = generate_instr(cctx, ISN_FOR)) == NULL) |
1244 return FAIL; | 1223 return FAIL; |
1245 isn->isn_arg.forloop.for_idx = loop_idx; | 1224 isn->isn_arg.forloop.for_idx = loop_idx; |
1246 | 1225 |
1247 if (GA_GROW_FAILS(stack, 1)) | |
1248 return FAIL; | |
1249 // type doesn't matter, will be stored next | 1226 // type doesn't matter, will be stored next |
1250 ((type_T **)stack->ga_data)[stack->ga_len] = &t_any; | 1227 return push_type_stack(cctx, &t_any); |
1251 ++stack->ga_len; | |
1252 | |
1253 return OK; | |
1254 } | 1228 } |
1255 /* | 1229 /* |
1256 * Generate an ISN_TRYCONT instruction. | 1230 * Generate an ISN_TRYCONT instruction. |
1257 */ | 1231 */ |
1258 int | 1232 int |
1279 generate_BCALL(cctx_T *cctx, int func_idx, int argcount, int method_call) | 1253 generate_BCALL(cctx_T *cctx, int func_idx, int argcount, int method_call) |
1280 { | 1254 { |
1281 isn_T *isn; | 1255 isn_T *isn; |
1282 garray_T *stack = &cctx->ctx_type_stack; | 1256 garray_T *stack = &cctx->ctx_type_stack; |
1283 int argoff; | 1257 int argoff; |
1284 type_T **argtypes = NULL; | 1258 type2_T *typep; |
1285 type_T *shuffled_argtypes[MAX_FUNC_ARGS]; | 1259 type2_T *argtypes = NULL; |
1286 type_T *maptype = NULL; | 1260 type2_T shuffled_argtypes[MAX_FUNC_ARGS]; |
1261 type2_T *maptype = NULL; | |
1262 type_T *type; | |
1287 | 1263 |
1288 RETURN_OK_IF_SKIP(cctx); | 1264 RETURN_OK_IF_SKIP(cctx); |
1289 argoff = check_internal_func(func_idx, argcount); | 1265 argoff = check_internal_func(func_idx, argcount); |
1290 if (argoff < 0) | 1266 if (argoff < 0) |
1291 return FAIL; | 1267 return FAIL; |
1299 } | 1275 } |
1300 | 1276 |
1301 if (argcount > 0) | 1277 if (argcount > 0) |
1302 { | 1278 { |
1303 // Check the types of the arguments. | 1279 // Check the types of the arguments. |
1304 argtypes = ((type_T **)stack->ga_data) + stack->ga_len - argcount; | 1280 typep = ((type2_T *)stack->ga_data) + stack->ga_len - argcount; |
1305 if (method_call && argoff > 1) | 1281 if (method_call && argoff > 1) |
1306 { | 1282 { |
1307 int i; | 1283 int i; |
1308 | 1284 |
1309 for (i = 0; i < argcount; ++i) | 1285 for (i = 0; i < argcount; ++i) |
1310 shuffled_argtypes[i] = (i < argoff - 1) | 1286 shuffled_argtypes[i] = (i < argoff - 1) |
1311 ? argtypes[i + 1] | 1287 ? typep[i + 1] |
1312 : (i == argoff - 1) ? argtypes[0] : argtypes[i]; | 1288 : (i == argoff - 1) ? typep[0] : typep[i]; |
1289 argtypes = shuffled_argtypes; | |
1290 } | |
1291 else | |
1292 { | |
1293 int i; | |
1294 | |
1295 for (i = 0; i < argcount; ++i) | |
1296 shuffled_argtypes[i] = typep[i]; | |
1313 argtypes = shuffled_argtypes; | 1297 argtypes = shuffled_argtypes; |
1314 } | 1298 } |
1315 if (internal_func_check_arg_types(argtypes, func_idx, argcount, | 1299 if (internal_func_check_arg_types(argtypes, func_idx, argcount, |
1316 cctx) == FAIL) | 1300 cctx) == FAIL) |
1317 return FAIL; | 1301 return FAIL; |
1318 if (internal_func_is_map(func_idx)) | 1302 if (internal_func_is_map(func_idx)) |
1319 maptype = *argtypes; | 1303 maptype = argtypes; |
1320 } | 1304 } |
1321 | 1305 |
1322 if ((isn = generate_instr(cctx, ISN_BCALL)) == NULL) | 1306 if ((isn = generate_instr(cctx, ISN_BCALL)) == NULL) |
1323 return FAIL; | 1307 return FAIL; |
1324 isn->isn_arg.bfunc.cbf_idx = func_idx; | 1308 isn->isn_arg.bfunc.cbf_idx = func_idx; |
1325 isn->isn_arg.bfunc.cbf_argcount = argcount; | 1309 isn->isn_arg.bfunc.cbf_argcount = argcount; |
1326 | 1310 |
1327 // Drop the argument types and push the return type. | 1311 // Drop the argument types and push the return type. |
1328 stack->ga_len -= argcount; | 1312 stack->ga_len -= argcount; |
1329 if (GA_GROW_FAILS(stack, 1)) | 1313 type = internal_func_ret_type(func_idx, argcount, argtypes); |
1330 return FAIL; | 1314 if (push_type_stack(cctx, type) == FAIL) |
1331 ((type_T **)stack->ga_data)[stack->ga_len] = | 1315 return FAIL; |
1332 internal_func_ret_type(func_idx, argcount, argtypes); | 1316 |
1333 ++stack->ga_len; | 1317 if (maptype != NULL && maptype[0].type_curr->tt_member != NULL |
1334 | 1318 && maptype[0].type_curr->tt_member != &t_any) |
1335 if (maptype != NULL && maptype->tt_member != NULL | |
1336 && maptype->tt_member != &t_any) | |
1337 // Check that map() didn't change the item types. | 1319 // Check that map() didn't change the item types. |
1338 generate_TYPECHECK(cctx, maptype, -1, 1); | 1320 generate_TYPECHECK(cctx, maptype[0].type_curr, -1, 1); |
1339 | 1321 |
1340 return OK; | 1322 return OK; |
1341 } | 1323 } |
1342 | 1324 |
1343 /* | 1325 /* |
1345 * Argument count is already checked. | 1327 * Argument count is already checked. |
1346 */ | 1328 */ |
1347 int | 1329 int |
1348 generate_LISTAPPEND(cctx_T *cctx) | 1330 generate_LISTAPPEND(cctx_T *cctx) |
1349 { | 1331 { |
1350 garray_T *stack = &cctx->ctx_type_stack; | |
1351 type_T *list_type; | 1332 type_T *list_type; |
1352 type_T *item_type; | 1333 type_T *item_type; |
1353 type_T *expected; | 1334 type_T *expected; |
1354 | 1335 |
1355 // Caller already checked that list_type is a list. | 1336 // Caller already checked that list_type is a list. |
1356 list_type = ((type_T **)stack->ga_data)[stack->ga_len - 2]; | 1337 list_type = get_type_on_stack(cctx, 1); |
1357 item_type = ((type_T **)stack->ga_data)[stack->ga_len - 1]; | 1338 item_type = get_type_on_stack(cctx, 0); |
1358 expected = list_type->tt_member; | 1339 expected = list_type->tt_member; |
1359 if (need_type(item_type, expected, -1, 0, cctx, FALSE, FALSE) == FAIL) | 1340 if (need_type(item_type, expected, -1, 0, cctx, FALSE, FALSE) == FAIL) |
1360 return FAIL; | 1341 return FAIL; |
1361 | 1342 |
1362 if (generate_instr(cctx, ISN_LISTAPPEND) == NULL) | 1343 if (generate_instr(cctx, ISN_LISTAPPEND) == NULL) |
1363 return FAIL; | 1344 return FAIL; |
1364 | 1345 |
1365 --stack->ga_len; // drop the argument | 1346 --cctx->ctx_type_stack.ga_len; // drop the argument |
1366 return OK; | 1347 return OK; |
1367 } | 1348 } |
1368 | 1349 |
1369 /* | 1350 /* |
1370 * Generate an ISN_BLOBAPPEND instruction. Works like add(). | 1351 * Generate an ISN_BLOBAPPEND instruction. Works like add(). |
1371 * Argument count is already checked. | 1352 * Argument count is already checked. |
1372 */ | 1353 */ |
1373 int | 1354 int |
1374 generate_BLOBAPPEND(cctx_T *cctx) | 1355 generate_BLOBAPPEND(cctx_T *cctx) |
1375 { | 1356 { |
1376 garray_T *stack = &cctx->ctx_type_stack; | |
1377 type_T *item_type; | 1357 type_T *item_type; |
1378 | 1358 |
1379 // Caller already checked that blob_type is a blob. | 1359 // Caller already checked that blob_type is a blob. |
1380 item_type = ((type_T **)stack->ga_data)[stack->ga_len - 1]; | 1360 item_type = get_type_on_stack(cctx, 0); |
1381 if (need_type(item_type, &t_number, -1, 0, cctx, FALSE, FALSE) == FAIL) | 1361 if (need_type(item_type, &t_number, -1, 0, cctx, FALSE, FALSE) == FAIL) |
1382 return FAIL; | 1362 return FAIL; |
1383 | 1363 |
1384 if (generate_instr(cctx, ISN_BLOBAPPEND) == NULL) | 1364 if (generate_instr(cctx, ISN_BLOBAPPEND) == NULL) |
1385 return FAIL; | 1365 return FAIL; |
1386 | 1366 |
1387 --stack->ga_len; // drop the argument | 1367 --cctx->ctx_type_stack.ga_len; // drop the argument |
1388 return OK; | 1368 return OK; |
1389 } | 1369 } |
1390 | 1370 |
1391 /* | 1371 /* |
1392 * Generate an ISN_DCALL or ISN_UCALL instruction. | 1372 * Generate an ISN_DCALL or ISN_UCALL instruction. |
1394 */ | 1374 */ |
1395 int | 1375 int |
1396 generate_CALL(cctx_T *cctx, ufunc_T *ufunc, int pushed_argcount) | 1376 generate_CALL(cctx_T *cctx, ufunc_T *ufunc, int pushed_argcount) |
1397 { | 1377 { |
1398 isn_T *isn; | 1378 isn_T *isn; |
1399 garray_T *stack = &cctx->ctx_type_stack; | |
1400 int regular_args = ufunc->uf_args.ga_len; | 1379 int regular_args = ufunc->uf_args.ga_len; |
1401 int argcount = pushed_argcount; | 1380 int argcount = pushed_argcount; |
1402 | 1381 |
1403 RETURN_OK_IF_SKIP(cctx); | 1382 RETURN_OK_IF_SKIP(cctx); |
1404 if (argcount > regular_args && !has_varargs(ufunc)) | 1383 if (argcount > regular_args && !has_varargs(ufunc)) |
1422 for (i = 0; i < argcount; ++i) | 1401 for (i = 0; i < argcount; ++i) |
1423 { | 1402 { |
1424 type_T *expected; | 1403 type_T *expected; |
1425 type_T *actual; | 1404 type_T *actual; |
1426 | 1405 |
1427 actual = ((type_T **)stack->ga_data)[stack->ga_len - argcount + i]; | 1406 actual = get_type_on_stack(cctx, argcount - i - 1); |
1428 if (actual == &t_special | 1407 if (actual == &t_special |
1429 && i >= regular_args - ufunc->uf_def_args.ga_len) | 1408 && i >= regular_args - ufunc->uf_def_args.ga_len) |
1430 { | 1409 { |
1431 // assume v:none used for default argument value | 1410 // assume v:none used for default argument value |
1432 continue; | 1411 continue; |
1477 // ufunc pointer, need to look it up again at runtime. | 1456 // ufunc pointer, need to look it up again at runtime. |
1478 isn->isn_arg.ufunc.cuf_name = vim_strsave(ufunc->uf_name); | 1457 isn->isn_arg.ufunc.cuf_name = vim_strsave(ufunc->uf_name); |
1479 isn->isn_arg.ufunc.cuf_argcount = argcount; | 1458 isn->isn_arg.ufunc.cuf_argcount = argcount; |
1480 } | 1459 } |
1481 | 1460 |
1482 stack->ga_len -= argcount; // drop the arguments | 1461 // drop the argument types |
1483 if (GA_GROW_FAILS(stack, 1)) | 1462 cctx->ctx_type_stack.ga_len -= argcount; |
1484 return FAIL; | 1463 |
1485 // add return value | 1464 // add return type |
1486 ((type_T **)stack->ga_data)[stack->ga_len] = ufunc->uf_ret_type; | 1465 return push_type_stack(cctx, ufunc->uf_ret_type); |
1487 ++stack->ga_len; | |
1488 | |
1489 return OK; | |
1490 } | 1466 } |
1491 | 1467 |
1492 /* | 1468 /* |
1493 * Generate an ISN_UCALL instruction when the function isn't defined yet. | 1469 * Generate an ISN_UCALL instruction when the function isn't defined yet. |
1494 */ | 1470 */ |
1495 int | 1471 int |
1496 generate_UCALL(cctx_T *cctx, char_u *name, int argcount) | 1472 generate_UCALL(cctx_T *cctx, char_u *name, int argcount) |
1497 { | 1473 { |
1498 isn_T *isn; | 1474 isn_T *isn; |
1499 garray_T *stack = &cctx->ctx_type_stack; | |
1500 | 1475 |
1501 RETURN_OK_IF_SKIP(cctx); | 1476 RETURN_OK_IF_SKIP(cctx); |
1502 if ((isn = generate_instr(cctx, ISN_UCALL)) == NULL) | 1477 if ((isn = generate_instr(cctx, ISN_UCALL)) == NULL) |
1503 return FAIL; | 1478 return FAIL; |
1504 isn->isn_arg.ufunc.cuf_name = vim_strsave(name); | 1479 isn->isn_arg.ufunc.cuf_name = vim_strsave(name); |
1505 isn->isn_arg.ufunc.cuf_argcount = argcount; | 1480 isn->isn_arg.ufunc.cuf_argcount = argcount; |
1506 | 1481 |
1507 stack->ga_len -= argcount; // drop the arguments | 1482 // drop the argument types |
1508 if (GA_GROW_FAILS(stack, 1)) | 1483 cctx->ctx_type_stack.ga_len -= argcount; |
1509 return FAIL; | 1484 |
1510 // add return value | 1485 // add return value |
1511 ((type_T **)stack->ga_data)[stack->ga_len] = &t_any; | 1486 return push_type_stack(cctx, &t_any); |
1512 ++stack->ga_len; | |
1513 | |
1514 return OK; | |
1515 } | 1487 } |
1516 | 1488 |
1517 /* | 1489 /* |
1518 * Generate an ISN_PCALL instruction. | 1490 * Generate an ISN_PCALL instruction. |
1519 * "type" is the type of the FuncRef. | 1491 * "type" is the type of the FuncRef. |
1525 char_u *name, | 1497 char_u *name, |
1526 type_T *type, | 1498 type_T *type, |
1527 int at_top) | 1499 int at_top) |
1528 { | 1500 { |
1529 isn_T *isn; | 1501 isn_T *isn; |
1530 garray_T *stack = &cctx->ctx_type_stack; | |
1531 type_T *ret_type; | 1502 type_T *ret_type; |
1532 | 1503 |
1533 RETURN_OK_IF_SKIP(cctx); | 1504 RETURN_OK_IF_SKIP(cctx); |
1534 | 1505 |
1535 if (type->tt_type == VAR_ANY || type->tt_type == VAR_UNKNOWN) | 1506 if (type->tt_type == VAR_ANY || type->tt_type == VAR_UNKNOWN) |
1555 int i; | 1526 int i; |
1556 | 1527 |
1557 for (i = 0; i < argcount; ++i) | 1528 for (i = 0; i < argcount; ++i) |
1558 { | 1529 { |
1559 int offset = -argcount + i - (at_top ? 0 : 1); | 1530 int offset = -argcount + i - (at_top ? 0 : 1); |
1560 type_T *actual = ((type_T **)stack->ga_data)[ | 1531 type_T *actual = get_type_on_stack(cctx, -1 - offset); |
1561 stack->ga_len + offset]; | |
1562 type_T *expected; | 1532 type_T *expected; |
1563 | 1533 |
1564 if (varargs && i >= type->tt_argcount - 1) | 1534 if (varargs && i >= type->tt_argcount - 1) |
1565 expected = type->tt_args[ | 1535 expected = type->tt_args[ |
1566 type->tt_argcount - 1]->tt_member; | 1536 type->tt_argcount - 1]->tt_member; |
1592 if ((isn = generate_instr(cctx, ISN_PCALL)) == NULL) | 1562 if ((isn = generate_instr(cctx, ISN_PCALL)) == NULL) |
1593 return FAIL; | 1563 return FAIL; |
1594 isn->isn_arg.pfunc.cpf_top = at_top; | 1564 isn->isn_arg.pfunc.cpf_top = at_top; |
1595 isn->isn_arg.pfunc.cpf_argcount = argcount; | 1565 isn->isn_arg.pfunc.cpf_argcount = argcount; |
1596 | 1566 |
1597 stack->ga_len -= argcount; // drop the arguments | 1567 // drop the arguments and the funcref/partial |
1598 | 1568 cctx->ctx_type_stack.ga_len -= argcount + 1; |
1599 // drop the funcref/partial, get back the return value | 1569 |
1600 ((type_T **)stack->ga_data)[stack->ga_len - 1] = ret_type; | 1570 // push the return value |
1571 push_type_stack(cctx, ret_type); | |
1601 | 1572 |
1602 // If partial is above the arguments it must be cleared and replaced with | 1573 // If partial is above the arguments it must be cleared and replaced with |
1603 // the return value. | 1574 // the return value. |
1604 if (at_top && generate_instr(cctx, ISN_PCALL_END) == NULL) | 1575 if (at_top && generate_instr(cctx, ISN_PCALL_END) == NULL) |
1605 return FAIL; | 1576 return FAIL; |
1612 */ | 1583 */ |
1613 int | 1584 int |
1614 generate_STRINGMEMBER(cctx_T *cctx, char_u *name, size_t len) | 1585 generate_STRINGMEMBER(cctx_T *cctx, char_u *name, size_t len) |
1615 { | 1586 { |
1616 isn_T *isn; | 1587 isn_T *isn; |
1617 garray_T *stack = &cctx->ctx_type_stack; | |
1618 type_T *type; | 1588 type_T *type; |
1619 | 1589 |
1620 RETURN_OK_IF_SKIP(cctx); | 1590 RETURN_OK_IF_SKIP(cctx); |
1621 if ((isn = generate_instr(cctx, ISN_STRINGMEMBER)) == NULL) | 1591 if ((isn = generate_instr(cctx, ISN_STRINGMEMBER)) == NULL) |
1622 return FAIL; | 1592 return FAIL; |
1623 isn->isn_arg.string = vim_strnsave(name, len); | 1593 isn->isn_arg.string = vim_strnsave(name, len); |
1624 | 1594 |
1625 // check for dict type | 1595 // check for dict type |
1626 type = ((type_T **)stack->ga_data)[stack->ga_len - 1]; | 1596 type = get_type_on_stack(cctx, 0); |
1627 if (type->tt_type != VAR_DICT && type != &t_any && type != &t_unknown) | 1597 if (type->tt_type != VAR_DICT && type != &t_any && type != &t_unknown) |
1628 { | 1598 { |
1629 char *tofree; | 1599 char *tofree; |
1630 | 1600 |
1631 semsg(_(e_expected_dictionary_for_using_key_str_but_got_str), | 1601 semsg(_(e_expected_dictionary_for_using_key_str_but_got_str), |
1634 return FAIL; | 1604 return FAIL; |
1635 } | 1605 } |
1636 // change dict type to dict member type | 1606 // change dict type to dict member type |
1637 if (type->tt_type == VAR_DICT) | 1607 if (type->tt_type == VAR_DICT) |
1638 { | 1608 { |
1639 ((type_T **)stack->ga_data)[stack->ga_len - 1] = | 1609 type_T *ntype = type->tt_member == &t_unknown |
1640 type->tt_member == &t_unknown ? &t_any : type->tt_member; | 1610 ? &t_any : type->tt_member; |
1611 set_type_on_stack(cctx, ntype, 0); | |
1641 } | 1612 } |
1642 | 1613 |
1643 return OK; | 1614 return OK; |
1644 } | 1615 } |
1645 | 1616 |
1732 | 1703 |
1733 int | 1704 int |
1734 generate_LEGACY_EVAL(cctx_T *cctx, char_u *line) | 1705 generate_LEGACY_EVAL(cctx_T *cctx, char_u *line) |
1735 { | 1706 { |
1736 isn_T *isn; | 1707 isn_T *isn; |
1737 garray_T *stack = &cctx->ctx_type_stack; | |
1738 | 1708 |
1739 RETURN_OK_IF_SKIP(cctx); | 1709 RETURN_OK_IF_SKIP(cctx); |
1740 if ((isn = generate_instr(cctx, ISN_LEGACY_EVAL)) == NULL) | 1710 if ((isn = generate_instr(cctx, ISN_LEGACY_EVAL)) == NULL) |
1741 return FAIL; | 1711 return FAIL; |
1742 isn->isn_arg.string = vim_strsave(line); | 1712 isn->isn_arg.string = vim_strsave(line); |
1743 | 1713 |
1744 if (GA_GROW_FAILS(stack, 1)) | 1714 return push_type_stack(cctx, &t_any); |
1745 return FAIL; | |
1746 ((type_T **)stack->ga_data)[stack->ga_len] = &t_any; | |
1747 ++stack->ga_len; | |
1748 | |
1749 return OK; | |
1750 } | 1715 } |
1751 | 1716 |
1752 int | 1717 int |
1753 generate_EXECCONCAT(cctx_T *cctx, int count) | 1718 generate_EXECCONCAT(cctx_T *cctx, int count) |
1754 { | 1719 { |
1765 */ | 1730 */ |
1766 int | 1731 int |
1767 generate_RANGE(cctx_T *cctx, char_u *range) | 1732 generate_RANGE(cctx_T *cctx, char_u *range) |
1768 { | 1733 { |
1769 isn_T *isn; | 1734 isn_T *isn; |
1770 garray_T *stack = &cctx->ctx_type_stack; | |
1771 | 1735 |
1772 if ((isn = generate_instr(cctx, ISN_RANGE)) == NULL) | 1736 if ((isn = generate_instr(cctx, ISN_RANGE)) == NULL) |
1773 return FAIL; | 1737 return FAIL; |
1774 isn->isn_arg.string = range; | 1738 isn->isn_arg.string = range; |
1775 | 1739 |
1776 if (GA_GROW_FAILS(stack, 1)) | 1740 return push_type_stack(cctx, &t_number); |
1777 return FAIL; | |
1778 ((type_T **)stack->ga_data)[stack->ga_len] = &t_number; | |
1779 ++stack->ga_len; | |
1780 return OK; | |
1781 } | 1741 } |
1782 | 1742 |
1783 int | 1743 int |
1784 generate_UNPACK(cctx_T *cctx, int var_count, int semicolon) | 1744 generate_UNPACK(cctx_T *cctx, int var_count, int semicolon) |
1785 { | 1745 { |