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: