X-Git-Url: https://git.xonotic.org/?a=blobdiff_plain;f=parser.c;h=425668225f2ee37c21be88d8c1ab4bbf40bc17b1;hb=654eceb33b73a0c81f1d6fa15d14ba60aa973d35;hp=e2eabc1e680cbfb49e437700335239f68ff6bb8e;hpb=0c4806b4a0a4cdea4abf117f56c0e15b1bcb1927;p=xonotic%2Fgmqcc.git diff --git a/parser.c b/parser.c index e2eabc1..4256682 100644 --- a/parser.c +++ b/parser.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012 + * Copyright (C) 2012, 2013 * Wolfgang Bumiller * Dale Weiler * @@ -26,6 +26,7 @@ #include "gmqcc.h" #include "lexer.h" +#include "ast.h" /* beginning of locals */ #define PARSER_HT_LOCALS 2 @@ -983,14 +984,14 @@ static bool parser_sy_apply_operator(parser_t *parser, shunt *sy) return false; } vec_pop(parser->pot); - if (exprs[1]->expression.vtype != exprs[2]->expression.vtype) { + if (!ast_compare_type(exprs[1], exprs[2])) { ast_type_to_string(exprs[1], ty1, sizeof(ty1)); ast_type_to_string(exprs[2], ty2, sizeof(ty2)); parseerror(parser, "operands of ternary expression must have the same type, got %s and %s", ty1, ty2); return false; } if (CanConstFold1(exprs[0])) - out = (ConstF(0) ? exprs[1] : exprs[2]); + out = (immediate_is_true(ctx, asvalue[0]) ? exprs[1] : exprs[2]); else out = (ast_expression*)ast_ternary_new(ctx, exprs[0], exprs[1], exprs[2]); break; @@ -1041,8 +1042,7 @@ static bool parser_sy_apply_operator(parser_t *parser, shunt *sy) } else assignop = type_storep_instr[exprs[0]->expression.vtype]; - if (assignop == AINSTR_END || - !ast_compare_type(field->expression.next, exprs[1])) + if (assignop == AINSTR_END || !ast_compare_type(field->expression.next, exprs[1])) { ast_type_to_string(field->expression.next, ty1, sizeof(ty1)); ast_type_to_string(exprs[1], ty2, sizeof(ty2)); @@ -1074,8 +1074,7 @@ static bool parser_sy_apply_operator(parser_t *parser, shunt *sy) ast_type_to_string(exprs[1], ty2, sizeof(ty2)); parseerror(parser, "invalid types in assignment: cannot assign %s to %s", ty2, ty1); } - else if (exprs[1]->expression.vtype != TYPE_NIL && - !ast_compare_type(exprs[0], exprs[1])) + else if (!ast_compare_type(exprs[0], exprs[1])) { ast_type_to_string(exprs[0], ty1, sizeof(ty1)); ast_type_to_string(exprs[1], ty2, sizeof(ty2)); @@ -1405,35 +1404,18 @@ static bool parser_close_call(parser_t *parser, shunt *sy) vec_size(fun->expression.params) < paramcount)) { const char *fewmany = (vec_size(fun->expression.params) > paramcount) ? "few" : "many"; - if (opts.standard == COMPILER_GMQCC) - { - if (fval) - parseerror(parser, "too %s parameters for call to %s: expected %i, got %i\n" - " -> `%s` has been declared here: %s:%i", - fewmany, fval->name, (int)vec_size(fun->expression.params), (int)paramcount, - fval->name, ast_ctx(fun).file, (int)ast_ctx(fun).line); - else - parseerror(parser, "too %s parameters for function call: expected %i, got %i\n" - " -> it has been declared here: %s:%i", - fewmany, (int)vec_size(fun->expression.params), (int)paramcount, - ast_ctx(fun).file, (int)ast_ctx(fun).line); - return false; - } + if (fval) + return !parsewarning(parser, WARN_INVALID_PARAMETER_COUNT, + "too %s parameters for call to %s: expected %i, got %i\n" + " -> `%s` has been declared here: %s:%i", + fewmany, fval->name, (int)vec_size(fun->expression.params), (int)paramcount, + fval->name, ast_ctx(fun).file, (int)ast_ctx(fun).line); else - { - if (fval) - return !parsewarning(parser, WARN_TOO_FEW_PARAMETERS, - "too %s parameters for call to %s: expected %i, got %i\n" - " -> `%s` has been declared here: %s:%i", - fewmany, fval->name, (int)vec_size(fun->expression.params), (int)paramcount, - fval->name, ast_ctx(fun).file, (int)ast_ctx(fun).line); - else - return !parsewarning(parser, WARN_TOO_FEW_PARAMETERS, - "too %s parameters for function call: expected %i, got %i\n" - " -> it has been declared here: %s:%i", - fewmany, (int)vec_size(fun->expression.params), (int)paramcount, - ast_ctx(fun).file, (int)ast_ctx(fun).line); - } + return !parsewarning(parser, WARN_INVALID_PARAMETER_COUNT, + "too %s parameters for function call: expected %i, got %i\n" + " -> it has been declared here: %s:%i", + fewmany, (int)vec_size(fun->expression.params), (int)paramcount, + ast_ctx(fun).file, (int)ast_ctx(fun).line); } } @@ -2431,11 +2413,13 @@ static bool parse_for_go(parser_t *parser, ast_block *block, ast_expression **ou typevar = parser_find_typedef(parser, parser_tokval(parser), 0); if (typevar || parser->tok == TOKEN_TYPENAME) { +#if 0 if (opts.standard != COMPILER_GMQCC) { if (parsewarning(parser, WARN_EXTENSIONS, "current standard does not allow variable declarations in for-loop initializers")) goto onerr; } +#endif if (!parse_variable(parser, block, true, CV_VAR, typevar, false, false, 0, NULL)) goto onerr; } @@ -2536,7 +2520,9 @@ static bool parse_return(parser_t *parser, ast_block *block, ast_expression **ou if (!exp) return false; - if (exp->expression.vtype != expected->expression.next->expression.vtype) { + if (exp->expression.vtype != TYPE_NIL && + exp->expression.vtype != expected->expression.next->expression.vtype) + { parseerror(parser, "return with invalid expression"); } @@ -2549,10 +2535,7 @@ static bool parse_return(parser_t *parser, ast_block *block, ast_expression **ou if (!parser_next(parser)) parseerror(parser, "parse error"); if (expected->expression.next->expression.vtype != TYPE_VOID) { - if (opts.standard != COMPILER_GMQCC) - (void)!parsewarning(parser, WARN_MISSING_RETURN_VALUES, "return without value"); - else - parseerror(parser, "return without value"); + (void)!parsewarning(parser, WARN_MISSING_RETURN_VALUES, "return without value"); } ret = ast_return_new(ctx, NULL); } @@ -4579,35 +4562,28 @@ static bool parse_variable(parser_t *parser, ast_block *localblock, bool nofield { /* other globals */ if (old) { - if (opts.standard == COMPILER_GMQCC) { - parseerror(parser, "global `%s` already declared here: %s:%i", - var->name, ast_ctx(old).file, ast_ctx(old).line); + if (parsewarning(parser, WARN_DOUBLE_DECLARATION, + "global `%s` already declared here: %s:%i", + var->name, ast_ctx(old).file, ast_ctx(old).line)) + { retval = false; goto cleanup; - } else { - if (parsewarning(parser, WARN_DOUBLE_DECLARATION, - "global `%s` already declared here: %s:%i", - var->name, ast_ctx(old).file, ast_ctx(old).line)) - { - retval = false; - goto cleanup; - } - proto = (ast_value*)old; - if (!ast_istype(old, ast_value)) { - parseerror(parser, "internal error: not an ast_value"); - retval = false; - proto = NULL; - goto cleanup; - } - if (!parser_check_qualifiers(parser, var, proto)) { - retval = false; - proto = NULL; - goto cleanup; - } - proto->expression.flags |= var->expression.flags; - ast_delete(var); - var = proto; } + proto = (ast_value*)old; + if (!ast_istype(old, ast_value)) { + parseerror(parser, "internal error: not an ast_value"); + retval = false; + proto = NULL; + goto cleanup; + } + if (!parser_check_qualifiers(parser, var, proto)) { + retval = false; + proto = NULL; + goto cleanup; + } + proto->expression.flags |= var->expression.flags; + ast_delete(var); + var = proto; } if (opts.standard == COMPILER_QCC && (old = parser_find_field(parser, var->name))) @@ -4917,8 +4893,7 @@ skipvar: } else { - if (opts.standard != COMPILER_GMQCC && - !OPTS_FLAG(INITIALIZED_NONCONSTANTS) && + if (!OPTS_FLAG(INITIALIZED_NONCONSTANTS) && qualifier != CV_VAR) { var->cvq = CV_CONST;