Mercurial > vim
diff src/vim9compile.c @ 22860:53acb89ec9f2 v8.2.1977
patch 8.2.1977: Vim9: error for using a string in a condition is confusing
Commit: https://github.com/vim/vim/commit/ea2d407f9c144bb634c59017944e4930ed7f80a2
Author: Bram Moolenaar <Bram@vim.org>
Date: Thu Nov 12 12:08:51 2020 +0100
patch 8.2.1977: Vim9: error for using a string in a condition is confusing
Problem: Vim9: error for using a string in a condition is confusing.
Solution: Give a more specific error. Also adjust the compile time type
checking for || and &&.
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Thu, 12 Nov 2020 12:15:04 +0100 |
parents | f2fbbb72ff28 |
children | a8bccb0634bc |
line wrap: on
line diff
--- a/src/vim9compile.c +++ b/src/vim9compile.c @@ -880,6 +880,28 @@ need_type( } /* + * Check that the top of the type stack has a type that can be used as a + * condition. Give an error and return FAIL if not. + */ + static int +bool_on_stack(cctx_T *cctx) +{ + garray_T *stack = &cctx->ctx_type_stack; + type_T *type; + + type = ((type_T **)stack->ga_data)[stack->ga_len - 1]; + if (type == &t_bool) + return OK; + + if (type == &t_any || type == &t_number) + // Number 0 and 1 are OK to use as a bool. "any" could also be a bool. + // This requires a runtime type check. + return generate_COND2BOOL(cctx); + + return need_type(type, &t_bool, -1, cctx, FALSE, FALSE); +} + +/* * Generate an ISN_PUSHNR instruction. */ static int @@ -4306,8 +4328,6 @@ compile_and_or( { garray_T *instr = &cctx->ctx_instr; garray_T end_ga; - garray_T *stack = &cctx->ctx_type_stack; - int all_bool_values = TRUE; /* * Repeat until there is no following "||" or "&&" @@ -4331,8 +4351,12 @@ compile_and_or( // evaluating to bool generate_ppconst(cctx, ppconst); - if (((type_T **)stack->ga_data)[stack->ga_len - 1] != &t_bool) - all_bool_values = FALSE; + // Every part must evaluate to a bool. + if (bool_on_stack(cctx) == FAIL) + { + ga_clear(&end_ga); + return FAIL; + } if (ga_grow(&end_ga, 1) == FAIL) { @@ -4360,6 +4384,13 @@ compile_and_or( } generate_ppconst(cctx, ppconst); + // Every part must evaluate to a bool. + if (bool_on_stack(cctx) == FAIL) + { + ga_clear(&end_ga); + return FAIL; + } + // Fill in the end label in all jumps. while (end_ga.ga_len > 0) { @@ -4371,10 +4402,6 @@ compile_and_or( isn->isn_arg.jump.jump_where = instr->ga_len; } ga_clear(&end_ga); - - // The resulting type is converted to bool if needed. - if (!all_bool_values) - generate_COND2BOOL(cctx); } return OK; @@ -4385,11 +4412,11 @@ compile_and_or( * * Produces instructions: * EVAL expr4a Push result of "expr4a" + * COND2BOOL convert to bool if needed * JUMP_IF_COND_FALSE end * EVAL expr4b Push result of "expr4b" * JUMP_IF_COND_FALSE end * EVAL expr4c Push result of "expr4c" - * COND2BOOL * end: */ static int @@ -4410,11 +4437,11 @@ compile_expr3(char_u **arg, cctx_T *cctx * * Produces instructions: * EVAL expr3a Push result of "expr3a" + * COND2BOOL convert to bool if needed * JUMP_IF_COND_TRUE end * EVAL expr3b Push result of "expr3b" * JUMP_IF_COND_TRUE end * EVAL expr3c Push result of "expr3c" - * COND2BOOL * end: */ static int @@ -5968,23 +5995,6 @@ drop_scope(cctx_T *cctx) } /* - * Check that the top of the type stack has a type that can be used as a - * condition. Give an error and return FAIL if not. - */ - static int -bool_on_stack(cctx_T *cctx) -{ - garray_T *stack = &cctx->ctx_type_stack; - type_T *type; - - type = ((type_T **)stack->ga_data)[stack->ga_len - 1]; - if (type != &t_bool && type != &t_number && type != &t_any - && need_type(type, &t_bool, -1, cctx, FALSE, FALSE) == FAIL) - return FAIL; - return OK; -} - -/* * compile "if expr" * * "if expr" Produces instructions: