Mercurial > vim
comparison src/vim9compile.c @ 22494:4c21f7f6f9e3 v8.2.1795
patch 8.2.1795: Vim9: operators && and || have a confusing result
Commit: https://github.com/vim/vim/commit/2bb2658bef9fb25b320f87147261b7154494a86f
Author: Bram Moolenaar <Bram@vim.org>
Date: Sat Oct 3 22:52:39 2020 +0200
patch 8.2.1795: Vim9: operators && and || have a confusing result
Problem: Vim9: operators && and || have a confusing result.
Solution: Make the result a boolean.
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Sat, 03 Oct 2020 23:00:04 +0200 |
parents | 0e03ef68e738 |
children | ef8a3177edc1 |
comparison
equal
deleted
inserted
replaced
22493:51353715e9a1 | 22494:4c21f7f6f9e3 |
---|---|
697 | 697 |
698 RETURN_OK_IF_SKIP(cctx); | 698 RETURN_OK_IF_SKIP(cctx); |
699 if ((isn = generate_instr(cctx, ISN_2BOOL)) == NULL) | 699 if ((isn = generate_instr(cctx, ISN_2BOOL)) == NULL) |
700 return FAIL; | 700 return FAIL; |
701 isn->isn_arg.number = invert; | 701 isn->isn_arg.number = invert; |
702 | |
703 // type becomes bool | |
704 ((type_T **)stack->ga_data)[stack->ga_len - 1] = &t_bool; | |
705 | |
706 return OK; | |
707 } | |
708 | |
709 /* | |
710 * Generate an ISN_COND2BOOL instruction. | |
711 */ | |
712 static int | |
713 generate_COND2BOOL(cctx_T *cctx) | |
714 { | |
715 isn_T *isn; | |
716 garray_T *stack = &cctx->ctx_type_stack; | |
717 | |
718 RETURN_OK_IF_SKIP(cctx); | |
719 if ((isn = generate_instr(cctx, ISN_COND2BOOL)) == NULL) | |
720 return FAIL; | |
702 | 721 |
703 // type becomes bool | 722 // type becomes bool |
704 ((type_T **)stack->ga_data)[stack->ga_len - 1] = &t_bool; | 723 ((type_T **)stack->ga_data)[stack->ga_len - 1] = &t_bool; |
705 | 724 |
706 return OK; | 725 return OK; |
4001 if (p[0] == opchar && p[1] == opchar) | 4020 if (p[0] == opchar && p[1] == opchar) |
4002 { | 4021 { |
4003 garray_T *instr = &cctx->ctx_instr; | 4022 garray_T *instr = &cctx->ctx_instr; |
4004 garray_T end_ga; | 4023 garray_T end_ga; |
4005 garray_T *stack = &cctx->ctx_type_stack; | 4024 garray_T *stack = &cctx->ctx_type_stack; |
4006 type_T **typep; | 4025 int all_bool_values = TRUE; |
4007 | 4026 |
4008 /* | 4027 /* |
4009 * Repeat until there is no following "||" or "&&" | 4028 * Repeat until there is no following "||" or "&&" |
4010 */ | 4029 */ |
4011 ga_init2(&end_ga, sizeof(int), 10); | 4030 ga_init2(&end_ga, sizeof(int), 10); |
4021 { | 4040 { |
4022 semsg(_(e_white_space_required_before_and_after_str), op); | 4041 semsg(_(e_white_space_required_before_and_after_str), op); |
4023 return FAIL; | 4042 return FAIL; |
4024 } | 4043 } |
4025 | 4044 |
4026 // TODO: use ppconst if the value is a constant | 4045 // TODO: use ppconst if the value is a constant and check |
4046 // evaluating to bool | |
4027 generate_ppconst(cctx, ppconst); | 4047 generate_ppconst(cctx, ppconst); |
4048 | |
4049 if (((type_T **)stack->ga_data)[stack->ga_len - 1] != &t_bool) | |
4050 all_bool_values = FALSE; | |
4028 | 4051 |
4029 if (ga_grow(&end_ga, 1) == FAIL) | 4052 if (ga_grow(&end_ga, 1) == FAIL) |
4030 { | 4053 { |
4031 ga_clear(&end_ga); | 4054 ga_clear(&end_ga); |
4032 return FAIL; | 4055 return FAIL; |
4033 } | 4056 } |
4034 *(((int *)end_ga.ga_data) + end_ga.ga_len) = instr->ga_len; | 4057 *(((int *)end_ga.ga_data) + end_ga.ga_len) = instr->ga_len; |
4035 ++end_ga.ga_len; | 4058 ++end_ga.ga_len; |
4036 generate_JUMP(cctx, opchar == '|' | 4059 generate_JUMP(cctx, opchar == '|' |
4037 ? JUMP_AND_KEEP_IF_TRUE : JUMP_AND_KEEP_IF_FALSE, 0); | 4060 ? JUMP_IF_COND_TRUE : JUMP_IF_COND_FALSE, 0); |
4038 | 4061 |
4039 // eval the next expression | 4062 // eval the next expression |
4040 *arg = skipwhite(p + 2); | 4063 *arg = skipwhite(p + 2); |
4041 if (may_get_next_line(p + 2, arg, cctx) == FAIL) | 4064 if (may_get_next_line(p + 2, arg, cctx) == FAIL) |
4042 return FAIL; | 4065 return FAIL; |
4062 + *(((int *)end_ga.ga_data) + end_ga.ga_len); | 4085 + *(((int *)end_ga.ga_data) + end_ga.ga_len); |
4063 isn->isn_arg.jump.jump_where = instr->ga_len; | 4086 isn->isn_arg.jump.jump_where = instr->ga_len; |
4064 } | 4087 } |
4065 ga_clear(&end_ga); | 4088 ga_clear(&end_ga); |
4066 | 4089 |
4067 // The resulting type can be used as a bool. | 4090 // The resulting type is converted to bool if needed. |
4068 typep = ((type_T **)stack->ga_data) + stack->ga_len - 1; | 4091 if (!all_bool_values) |
4069 if (*typep != &t_bool) | 4092 generate_COND2BOOL(cctx); |
4070 { | |
4071 type_T *type = get_type_ptr(cctx->ctx_type_list); | |
4072 | |
4073 if (type != NULL) | |
4074 { | |
4075 *type = **typep; | |
4076 type->tt_flags |= TTFLAG_BOOL_OK; | |
4077 *typep = type; | |
4078 } | |
4079 } | |
4080 } | 4093 } |
4081 | 4094 |
4082 return OK; | 4095 return OK; |
4083 } | 4096 } |
4084 | 4097 |
4085 /* | 4098 /* |
4086 * expr4a && expr4a && expr4a logical AND | 4099 * expr4a && expr4a && expr4a logical AND |
4087 * | 4100 * |
4088 * Produces instructions: | 4101 * Produces instructions: |
4089 * EVAL expr4a Push result of "expr4a" | 4102 * EVAL expr4a Push result of "expr4a" |
4090 * JUMP_AND_KEEP_IF_FALSE end | 4103 * JUMP_IF_COND_FALSE end |
4091 * EVAL expr4b Push result of "expr4b" | 4104 * EVAL expr4b Push result of "expr4b" |
4092 * JUMP_AND_KEEP_IF_FALSE end | 4105 * JUMP_IF_COND_FALSE end |
4093 * EVAL expr4c Push result of "expr4c" | 4106 * EVAL expr4c Push result of "expr4c" |
4107 * COND2BOOL | |
4094 * end: | 4108 * end: |
4095 */ | 4109 */ |
4096 static int | 4110 static int |
4097 compile_expr3(char_u **arg, cctx_T *cctx, ppconst_T *ppconst) | 4111 compile_expr3(char_u **arg, cctx_T *cctx, ppconst_T *ppconst) |
4098 { | 4112 { |
4109 /* | 4123 /* |
4110 * expr3a || expr3b || expr3c logical OR | 4124 * expr3a || expr3b || expr3c logical OR |
4111 * | 4125 * |
4112 * Produces instructions: | 4126 * Produces instructions: |
4113 * EVAL expr3a Push result of "expr3a" | 4127 * EVAL expr3a Push result of "expr3a" |
4114 * JUMP_AND_KEEP_IF_TRUE end | 4128 * JUMP_IF_COND_TRUE end |
4115 * EVAL expr3b Push result of "expr3b" | 4129 * EVAL expr3b Push result of "expr3b" |
4116 * JUMP_AND_KEEP_IF_TRUE end | 4130 * JUMP_IF_COND_TRUE end |
4117 * EVAL expr3c Push result of "expr3c" | 4131 * EVAL expr3c Push result of "expr3c" |
4132 * COND2BOOL | |
4118 * end: | 4133 * end: |
4119 */ | 4134 */ |
4120 static int | 4135 static int |
4121 compile_expr2(char_u **arg, cctx_T *cctx, ppconst_T *ppconst) | 4136 compile_expr2(char_u **arg, cctx_T *cctx, ppconst_T *ppconst) |
4122 { | 4137 { |
7413 case ISN_COMPARELIST: | 7428 case ISN_COMPARELIST: |
7414 case ISN_COMPARENR: | 7429 case ISN_COMPARENR: |
7415 case ISN_COMPARESPECIAL: | 7430 case ISN_COMPARESPECIAL: |
7416 case ISN_COMPARESTRING: | 7431 case ISN_COMPARESTRING: |
7417 case ISN_CONCAT: | 7432 case ISN_CONCAT: |
7433 case ISN_COND2BOOL: | |
7418 case ISN_DROP: | 7434 case ISN_DROP: |
7419 case ISN_ECHO: | 7435 case ISN_ECHO: |
7420 case ISN_ECHOERR: | 7436 case ISN_ECHOERR: |
7421 case ISN_ECHOMSG: | 7437 case ISN_ECHOMSG: |
7422 case ISN_ENDTRY: | 7438 case ISN_ENDTRY: |