Mercurial > vim
comparison src/vim9compile.c @ 19922:1f42c49c3d29 v8.2.0517
patch 8.2.0517: Vim9: cannot separate "func" and "func(): void"
Commit: https://github.com/vim/vim/commit/4c68375057c25e99656bc996d3fa5c6b0b6a7e6a
Author: Bram Moolenaar <Bram@vim.org>
Date: Sun Apr 5 21:38:23 2020 +0200
patch 8.2.0517: Vim9: cannot separate "func" and "func(): void"
Problem: Vim9: cannot separate "func" and "func(): void".
Solution: Use VAR_ANY for "any" and VAR_UNKNOWN for "no type".
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Sun, 05 Apr 2020 21:45:25 +0200 |
parents | ccfeae6af59e |
children | d286bfc44149 |
comparison
equal
deleted
inserted
replaced
19921:05ac81e3e873 | 19922:1f42c49c3d29 |
---|---|
247 get_list_type(type_T *member_type, garray_T *type_gap) | 247 get_list_type(type_T *member_type, garray_T *type_gap) |
248 { | 248 { |
249 type_T *type; | 249 type_T *type; |
250 | 250 |
251 // recognize commonly used types | 251 // recognize commonly used types |
252 if (member_type->tt_type == VAR_UNKNOWN) | 252 if (member_type->tt_type == VAR_ANY) |
253 return &t_list_any; | 253 return &t_list_any; |
254 if (member_type->tt_type == VAR_VOID) | 254 if (member_type->tt_type == VAR_VOID |
255 || member_type->tt_type == VAR_UNKNOWN) | |
255 return &t_list_empty; | 256 return &t_list_empty; |
256 if (member_type->tt_type == VAR_BOOL) | 257 if (member_type->tt_type == VAR_BOOL) |
257 return &t_list_bool; | 258 return &t_list_bool; |
258 if (member_type->tt_type == VAR_NUMBER) | 259 if (member_type->tt_type == VAR_NUMBER) |
259 return &t_list_number; | 260 return &t_list_number; |
275 get_dict_type(type_T *member_type, garray_T *type_gap) | 276 get_dict_type(type_T *member_type, garray_T *type_gap) |
276 { | 277 { |
277 type_T *type; | 278 type_T *type; |
278 | 279 |
279 // recognize commonly used types | 280 // recognize commonly used types |
280 if (member_type->tt_type == VAR_UNKNOWN) | 281 if (member_type->tt_type == VAR_ANY) |
281 return &t_dict_any; | 282 return &t_dict_any; |
282 if (member_type->tt_type == VAR_VOID) | 283 if (member_type->tt_type == VAR_VOID |
284 || member_type->tt_type == VAR_UNKNOWN) | |
283 return &t_dict_empty; | 285 return &t_dict_empty; |
284 if (member_type->tt_type == VAR_BOOL) | 286 if (member_type->tt_type == VAR_BOOL) |
285 return &t_dict_bool; | 287 return &t_dict_bool; |
286 if (member_type->tt_type == VAR_NUMBER) | 288 if (member_type->tt_type == VAR_NUMBER) |
287 return &t_dict_number; | 289 return &t_dict_number; |
480 } | 482 } |
481 | 483 |
482 static int | 484 static int |
483 check_number_or_float(vartype_T type1, vartype_T type2, char_u *op) | 485 check_number_or_float(vartype_T type1, vartype_T type2, char_u *op) |
484 { | 486 { |
485 if (!((type1 == VAR_NUMBER || type1 == VAR_FLOAT || type1 == VAR_UNKNOWN) | 487 if (!((type1 == VAR_NUMBER || type1 == VAR_FLOAT || type1 == VAR_ANY) |
486 && (type2 == VAR_NUMBER || type2 == VAR_FLOAT | 488 && (type2 == VAR_NUMBER || type2 == VAR_FLOAT |
487 || type2 == VAR_UNKNOWN))) | 489 || type2 == VAR_ANY))) |
488 { | 490 { |
489 if (*op == '+') | 491 if (*op == '+') |
490 emsg(_("E1035: wrong argument type for +")); | 492 emsg(_("E1035: wrong argument type for +")); |
491 else | 493 else |
492 semsg(_("E1036: %c requires number or float arguments"), *op); | 494 semsg(_("E1036: %c requires number or float arguments"), *op); |
513 // Get the known type of the two items on the stack. If they are matching | 515 // Get the known type of the two items on the stack. If they are matching |
514 // use a type-specific instruction. Otherwise fall back to runtime type | 516 // use a type-specific instruction. Otherwise fall back to runtime type |
515 // checking. | 517 // checking. |
516 type1 = ((type_T **)stack->ga_data)[stack->ga_len - 2]; | 518 type1 = ((type_T **)stack->ga_data)[stack->ga_len - 2]; |
517 type2 = ((type_T **)stack->ga_data)[stack->ga_len - 1]; | 519 type2 = ((type_T **)stack->ga_data)[stack->ga_len - 1]; |
518 vartype = VAR_UNKNOWN; | 520 vartype = VAR_ANY; |
519 if (type1->tt_type == type2->tt_type | 521 if (type1->tt_type == type2->tt_type |
520 && (type1->tt_type == VAR_NUMBER | 522 && (type1->tt_type == VAR_NUMBER |
521 || type1->tt_type == VAR_LIST | 523 || type1->tt_type == VAR_LIST |
522 #ifdef FEAT_FLOAT | 524 #ifdef FEAT_FLOAT |
523 || type1->tt_type == VAR_FLOAT | 525 || type1->tt_type == VAR_FLOAT |
526 vartype = type1->tt_type; | 528 vartype = type1->tt_type; |
527 | 529 |
528 switch (*op) | 530 switch (*op) |
529 { | 531 { |
530 case '+': if (vartype != VAR_LIST && vartype != VAR_BLOB | 532 case '+': if (vartype != VAR_LIST && vartype != VAR_BLOB |
531 && type1->tt_type != VAR_UNKNOWN | 533 && type1->tt_type != VAR_ANY |
532 && type2->tt_type != VAR_UNKNOWN | 534 && type2->tt_type != VAR_ANY |
533 && check_number_or_float( | 535 && check_number_or_float( |
534 type1->tt_type, type2->tt_type, op) == FAIL) | 536 type1->tt_type, type2->tt_type, op) == FAIL) |
535 return FAIL; | 537 return FAIL; |
536 isn = generate_instr_drop(cctx, | 538 isn = generate_instr_drop(cctx, |
537 vartype == VAR_NUMBER ? ISN_OPNR | 539 vartype == VAR_NUMBER ? ISN_OPNR |
561 if (isn != NULL) | 563 if (isn != NULL) |
562 isn->isn_arg.op.op_type = *op == '*' | 564 isn->isn_arg.op.op_type = *op == '*' |
563 ? EXPR_MULT : *op == '/'? EXPR_DIV : EXPR_SUB; | 565 ? EXPR_MULT : *op == '/'? EXPR_DIV : EXPR_SUB; |
564 break; | 566 break; |
565 | 567 |
566 case '%': if ((type1->tt_type != VAR_UNKNOWN | 568 case '%': if ((type1->tt_type != VAR_ANY |
567 && type1->tt_type != VAR_NUMBER) | 569 && type1->tt_type != VAR_NUMBER) |
568 || (type2->tt_type != VAR_UNKNOWN | 570 || (type2->tt_type != VAR_ANY |
569 && type2->tt_type != VAR_NUMBER)) | 571 && type2->tt_type != VAR_NUMBER)) |
570 { | 572 { |
571 emsg(_("E1035: % requires number arguments")); | 573 emsg(_("E1035: % requires number arguments")); |
572 return FAIL; | 574 return FAIL; |
573 } | 575 } |
577 isn->isn_arg.op.op_type = EXPR_REM; | 579 isn->isn_arg.op.op_type = EXPR_REM; |
578 break; | 580 break; |
579 } | 581 } |
580 | 582 |
581 // correct type of result | 583 // correct type of result |
582 if (vartype == VAR_UNKNOWN) | 584 if (vartype == VAR_ANY) |
583 { | 585 { |
584 type_T *type = &t_any; | 586 type_T *type = &t_any; |
585 | 587 |
586 #ifdef FEAT_FLOAT | 588 #ifdef FEAT_FLOAT |
587 // float+number and number+float results in float | 589 // float+number and number+float results in float |
612 // Get the known type of the two items on the stack. If they are matching | 614 // Get the known type of the two items on the stack. If they are matching |
613 // use a type-specific instruction. Otherwise fall back to runtime type | 615 // use a type-specific instruction. Otherwise fall back to runtime type |
614 // checking. | 616 // checking. |
615 type1 = ((type_T **)stack->ga_data)[stack->ga_len - 2]->tt_type; | 617 type1 = ((type_T **)stack->ga_data)[stack->ga_len - 2]->tt_type; |
616 type2 = ((type_T **)stack->ga_data)[stack->ga_len - 1]->tt_type; | 618 type2 = ((type_T **)stack->ga_data)[stack->ga_len - 1]->tt_type; |
619 if (type1 == VAR_UNKNOWN) | |
620 type1 = VAR_ANY; | |
621 if (type2 == VAR_UNKNOWN) | |
622 type2 = VAR_ANY; | |
623 | |
617 if (type1 == type2) | 624 if (type1 == type2) |
618 { | 625 { |
619 switch (type1) | 626 switch (type1) |
620 { | 627 { |
621 case VAR_BOOL: isntype = ISN_COMPAREBOOL; break; | 628 case VAR_BOOL: isntype = ISN_COMPAREBOOL; break; |
629 case VAR_FUNC: isntype = ISN_COMPAREFUNC; break; | 636 case VAR_FUNC: isntype = ISN_COMPAREFUNC; break; |
630 case VAR_PARTIAL: isntype = ISN_COMPAREPARTIAL; break; | 637 case VAR_PARTIAL: isntype = ISN_COMPAREPARTIAL; break; |
631 default: isntype = ISN_COMPAREANY; break; | 638 default: isntype = ISN_COMPAREANY; break; |
632 } | 639 } |
633 } | 640 } |
634 else if (type1 == VAR_UNKNOWN || type2 == VAR_UNKNOWN | 641 else if (type1 == VAR_ANY || type2 == VAR_ANY |
635 || ((type1 == VAR_NUMBER || type1 == VAR_FLOAT) | 642 || ((type1 == VAR_NUMBER || type1 == VAR_FLOAT) |
636 && (type2 == VAR_NUMBER || type2 ==VAR_FLOAT))) | 643 && (type2 == VAR_NUMBER || type2 ==VAR_FLOAT))) |
637 isntype = ISN_COMPAREANY; | 644 isntype = ISN_COMPAREANY; |
638 | 645 |
639 if ((exptype == EXPR_IS || exptype == EXPR_ISNOT) | 646 if ((exptype == EXPR_IS || exptype == EXPR_ISNOT) |
1721 { | 1728 { |
1722 if (type1->tt_type != type2->tt_type) | 1729 if (type1->tt_type != type2->tt_type) |
1723 return FALSE; | 1730 return FALSE; |
1724 switch (type1->tt_type) | 1731 switch (type1->tt_type) |
1725 { | 1732 { |
1733 case VAR_UNKNOWN: | |
1734 case VAR_ANY: | |
1726 case VAR_VOID: | 1735 case VAR_VOID: |
1727 case VAR_UNKNOWN: | |
1728 case VAR_SPECIAL: | 1736 case VAR_SPECIAL: |
1729 case VAR_BOOL: | 1737 case VAR_BOOL: |
1730 case VAR_NUMBER: | 1738 case VAR_NUMBER: |
1731 case VAR_FLOAT: | 1739 case VAR_FLOAT: |
1732 case VAR_STRING: | 1740 case VAR_STRING: |
1783 vartype_name(vartype_T type) | 1791 vartype_name(vartype_T type) |
1784 { | 1792 { |
1785 switch (type) | 1793 switch (type) |
1786 { | 1794 { |
1787 case VAR_UNKNOWN: break; | 1795 case VAR_UNKNOWN: break; |
1796 case VAR_ANY: return "any"; | |
1788 case VAR_VOID: return "void"; | 1797 case VAR_VOID: return "void"; |
1789 case VAR_SPECIAL: return "special"; | 1798 case VAR_SPECIAL: return "special"; |
1790 case VAR_BOOL: return "bool"; | 1799 case VAR_BOOL: return "bool"; |
1791 case VAR_NUMBER: return "number"; | 1800 case VAR_NUMBER: return "number"; |
1792 case VAR_FLOAT: return "float"; | 1801 case VAR_FLOAT: return "float"; |
1797 case VAR_LIST: return "list"; | 1806 case VAR_LIST: return "list"; |
1798 case VAR_DICT: return "dict"; | 1807 case VAR_DICT: return "dict"; |
1799 case VAR_FUNC: return "func"; | 1808 case VAR_FUNC: return "func"; |
1800 case VAR_PARTIAL: return "partial"; | 1809 case VAR_PARTIAL: return "partial"; |
1801 } | 1810 } |
1802 return "any"; | 1811 return "unknown"; |
1803 } | 1812 } |
1804 | 1813 |
1805 /* | 1814 /* |
1806 * Return the name of a type. | 1815 * Return the name of a type. |
1807 * The result may be in allocated memory, in which case "tofree" is set. | 1816 * The result may be in allocated memory, in which case "tofree" is set. |
2394 static int | 2403 static int |
2395 check_type(type_T *expected, type_T *actual, int give_msg) | 2404 check_type(type_T *expected, type_T *actual, int give_msg) |
2396 { | 2405 { |
2397 int ret = OK; | 2406 int ret = OK; |
2398 | 2407 |
2399 if (expected->tt_type != VAR_UNKNOWN) | 2408 if (expected->tt_type != VAR_UNKNOWN && expected->tt_type != VAR_ANY) |
2400 { | 2409 { |
2401 if (expected->tt_type != actual->tt_type) | 2410 if (expected->tt_type != actual->tt_type) |
2402 { | 2411 { |
2403 if (give_msg) | 2412 if (give_msg) |
2404 type_mismatch(expected, actual); | 2413 type_mismatch(expected, actual); |
2405 return FAIL; | 2414 return FAIL; |
2406 } | 2415 } |
2407 if (expected->tt_type == VAR_DICT || expected->tt_type == VAR_LIST) | 2416 if (expected->tt_type == VAR_DICT || expected->tt_type == VAR_LIST) |
2408 { | 2417 { |
2409 // void is used for an empty list or dict | 2418 // "unknown" is used for an empty list or dict |
2410 if (actual->tt_member != &t_void) | 2419 if (actual->tt_member != &t_unknown) |
2411 ret = check_type(expected->tt_member, actual->tt_member, FALSE); | 2420 ret = check_type(expected->tt_member, actual->tt_member, FALSE); |
2412 } | 2421 } |
2413 else if (expected->tt_type == VAR_FUNC) | 2422 else if (expected->tt_type == VAR_FUNC) |
2414 { | 2423 { |
2415 if (expected->tt_member != &t_any) | 2424 if (expected->tt_member != &t_any |
2425 && expected->tt_member != &t_unknown) | |
2416 ret = check_type(expected->tt_member, actual->tt_member, FALSE); | 2426 ret = check_type(expected->tt_member, actual->tt_member, FALSE); |
2417 if (ret == OK && expected->tt_argcount != -1 | 2427 if (ret == OK && expected->tt_argcount != -1 |
2418 && (actual->tt_argcount < expected->tt_min_argcount | 2428 && (actual->tt_argcount < expected->tt_min_argcount |
2419 || actual->tt_argcount > expected->tt_argcount)) | 2429 || actual->tt_argcount > expected->tt_argcount)) |
2420 ret = FAIL; | 2430 ret = FAIL; |
2434 static int | 2444 static int |
2435 need_type(type_T *actual, type_T *expected, int offset, cctx_T *cctx) | 2445 need_type(type_T *actual, type_T *expected, int offset, cctx_T *cctx) |
2436 { | 2446 { |
2437 if (check_type(expected, actual, FALSE)) | 2447 if (check_type(expected, actual, FALSE)) |
2438 return OK; | 2448 return OK; |
2439 if (actual->tt_type != VAR_UNKNOWN) | 2449 if (actual->tt_type != VAR_ANY && actual->tt_type != VAR_UNKNOWN) |
2440 { | 2450 { |
2441 type_mismatch(expected, actual); | 2451 type_mismatch(expected, actual); |
2442 return FAIL; | 2452 return FAIL; |
2443 } | 2453 } |
2444 generate_TYPECHECK(cctx, expected, offset); | 2454 generate_TYPECHECK(cctx, expected, offset); |
3640 } | 3650 } |
3641 else | 3651 else |
3642 { | 3652 { |
3643 // "set_return_type" cannot be TRUE, only used for a lambda which | 3653 // "set_return_type" cannot be TRUE, only used for a lambda which |
3644 // always has an argument. | 3654 // always has an argument. |
3645 if (cctx->ctx_ufunc->uf_ret_type->tt_type != VAR_VOID) | 3655 if (cctx->ctx_ufunc->uf_ret_type->tt_type != VAR_VOID |
3656 && cctx->ctx_ufunc->uf_ret_type->tt_type != VAR_UNKNOWN) | |
3646 { | 3657 { |
3647 emsg(_("E1003: Missing return value")); | 3658 emsg(_("E1003: Missing return value")); |
3648 return NULL; | 3659 return NULL; |
3649 } | 3660 } |
3650 | 3661 |
3934 vim_strncpy(buf, op, oplen); | 3945 vim_strncpy(buf, op, oplen); |
3935 semsg(_(e_white_both), buf); | 3946 semsg(_(e_white_both), buf); |
3936 } | 3947 } |
3937 | 3948 |
3938 if (oplen == 3 && !heredoc && dest != dest_global | 3949 if (oplen == 3 && !heredoc && dest != dest_global |
3939 && type->tt_type != VAR_STRING && type->tt_type != VAR_UNKNOWN) | 3950 && type->tt_type != VAR_STRING && type->tt_type != VAR_ANY) |
3940 { | 3951 { |
3941 emsg(_("E1019: Can only concatenate to string")); | 3952 emsg(_("E1019: Can only concatenate to string")); |
3942 goto theend; | 3953 goto theend; |
3943 } | 3954 } |
3944 | 3955 |
4113 case VAR_CHANNEL: | 4124 case VAR_CHANNEL: |
4114 generate_PUSHCHANNEL(cctx, NULL); | 4125 generate_PUSHCHANNEL(cctx, NULL); |
4115 break; | 4126 break; |
4116 case VAR_NUMBER: | 4127 case VAR_NUMBER: |
4117 case VAR_UNKNOWN: | 4128 case VAR_UNKNOWN: |
4129 case VAR_ANY: | |
4118 case VAR_VOID: | 4130 case VAR_VOID: |
4119 case VAR_SPECIAL: // cannot happen | 4131 case VAR_SPECIAL: // cannot happen |
4120 generate_PUSHNR(cctx, 0); | 4132 generate_PUSHNR(cctx, 0); |
4121 break; | 4133 break; |
4122 } | 4134 } |
4901 { | 4913 { |
4902 emsg(_("E1024: need a List to iterate over")); | 4914 emsg(_("E1024: need a List to iterate over")); |
4903 drop_scope(cctx); | 4915 drop_scope(cctx); |
4904 return NULL; | 4916 return NULL; |
4905 } | 4917 } |
4906 if (vartype->tt_member->tt_type != VAR_UNKNOWN) | 4918 if (vartype->tt_member->tt_type != VAR_ANY) |
4907 { | 4919 { |
4908 lvar_T *lvar = ((lvar_T *)cctx->ctx_locals.ga_data) + var_idx; | 4920 lvar_T *lvar = ((lvar_T *)cctx->ctx_locals.ga_data) + var_idx; |
4909 | 4921 |
4910 lvar->lv_type = vartype->tt_member; | 4922 lvar->lv_type = vartype->tt_member; |
4911 } | 4923 } |