X-Git-Url: https://git.xonotic.org/?a=blobdiff_plain;f=parser.c;h=2e8652800e9c78cfef0c4227c8985e728be98bec;hb=001d853f38ef06bd6bc5a8b349e6918d26d76c24;hp=cef598573dcf5f72cc0f7afe4cf01135633aa556;hpb=ba207cc04caa361d775055cd614ef73cae300872;p=xonotic%2Fgmqcc.git diff --git a/parser.c b/parser.c index cef5985..2e86528 100644 --- a/parser.c +++ b/parser.c @@ -135,16 +135,6 @@ static bool GMQCC_WARN parsewarning(parser_t *parser, int warntype, const char * return r; } -static bool GMQCC_WARN genwarning(lex_ctx ctx, int warntype, const char *fmt, ...) -{ - bool r; - va_list ap; - va_start(ap, fmt); - r = vcompile_warning(ctx, warntype, fmt, ap); - va_end(ap); - return r; -} - /********************************************************************** * some maths used for constant folding */ @@ -1991,9 +1981,13 @@ static ast_expression* parse_expression_leave(parser_t *parser, bool stopatcomma } } else if (parser->tok == ')') { + while (vec_size(sy.paren) && vec_last(sy.paren) == PAREN_TERNARY2) { + if (!parser_sy_apply_operator(parser, &sy)) + goto onerr; + } + if (!vec_size(sy.paren)) + break; if (wantop) { - if (!vec_size(sy.paren)) - break; if (vec_last(sy.paren) == PAREN_TERNARY1) { parseerror(parser, "mismatched parentheses (closing paren in ternary expression?)"); goto onerr; @@ -2002,8 +1996,6 @@ static ast_expression* parse_expression_leave(parser_t *parser, bool stopatcomma goto onerr; } else { /* must be a function call without parameters */ - if (!vec_size(sy.paren)) - break; if (vec_last(sy.paren) != PAREN_FUNC) { parseerror(parser, "closing paren in invalid position"); goto onerr; @@ -2022,14 +2014,19 @@ static ast_expression* parse_expression_leave(parser_t *parser, bool stopatcomma goto onerr; } else if (parser->tok == ']') { + while (vec_size(sy.paren) && vec_last(sy.paren) == PAREN_TERNARY2) { + if (!parser_sy_apply_operator(parser, &sy)) + goto onerr; + } if (!vec_size(sy.paren)) break; - if (!vec_size(sy.paren) || vec_last(sy.paren) != PAREN_INDEX) { + if (vec_last(sy.paren) != PAREN_INDEX) { parseerror(parser, "mismatched parentheses, unexpected ']'"); goto onerr; } if (!parser_close_paren(parser, &sy)) goto onerr; + wantop = true; } else if (!wantop) { if (!parse_sya_operand(parser, &sy, with_labels)) @@ -2198,6 +2195,12 @@ static ast_expression* process_condition(parser_t *parser, ast_expression *cond, ast_unary *unary; ast_expression *prev; + if (cond->expression.vtype == TYPE_VOID || cond->expression.vtype >= TYPE_VARIANT) { + char ty[1024]; + ast_type_to_string(cond, ty, sizeof(ty)); + compile_error(ast_ctx(cond), "invalid type for if() condition: %s", ty); + } + if (OPTS_FLAG(FALSE_EMPTY_STRINGS) && cond->expression.vtype == TYPE_STRING) { prev = cond; @@ -2677,11 +2680,12 @@ static bool parse_for_go(parser_t *parser, ast_block *block, ast_expression **ou /* parse the incrementor */ if (parser->tok != ')') { + lex_ctx condctx = parser_ctx(parser); increment = parse_expression_leave(parser, false, false, false); if (!increment) goto onerr; if (!ast_side_effects(increment)) { - if (genwarning(ast_ctx(increment), WARN_EFFECTLESS_STATEMENT, "statement has no effect")) + if (compile_warning(condctx, WARN_EFFECTLESS_STATEMENT, "statement has no effect")) goto onerr; } } @@ -3527,12 +3531,13 @@ static bool parse_statement(parser_t *parser, ast_block *block, ast_expression * } else { + lex_ctx ctx = parser_ctx(parser); ast_expression *exp = parse_expression(parser, false, false); if (!exp) return false; *out = exp; if (!ast_side_effects(exp)) { - if (genwarning(ast_ctx(exp), WARN_EFFECTLESS_STATEMENT, "statement has no effect")) + if (compile_warning(ctx, WARN_EFFECTLESS_STATEMENT, "statement has no effect")) return false; } return true; @@ -5840,8 +5845,8 @@ bool parser_finish(const char *output) continue; asvalue = (ast_value*)(parser->globals[i]); if (!asvalue->uses && !asvalue->hasvalue && asvalue->expression.vtype != TYPE_FUNCTION) { - retval = retval && !genwarning(ast_ctx(asvalue), WARN_UNUSED_VARIABLE, - "unused global: `%s`", asvalue->name); + retval = retval && !compile_warning(ast_ctx(asvalue), WARN_UNUSED_VARIABLE, + "unused global: `%s`", asvalue->name); } if (!ast_global_codegen(asvalue, ir, false)) { con_out("failed to generate global %s\n", asvalue->name);