From: Dale Weiler Date: Fri, 4 Jan 2013 11:56:07 +0000 (+0000) Subject: Merge branch 'correct' X-Git-Tag: before-library~373 X-Git-Url: https://git.xonotic.org/?p=xonotic%2Fgmqcc.git;a=commitdiff_plain;h=2d96b2a3ecb3610493c261c297da8a0ed429cd15;hp=36d02d010e2dbfb76247a6c09a919b4710efc4da Merge branch 'correct' --- diff --git a/ast.c b/ast.c index b2b7064..2b4a456 100644 --- a/ast.c +++ b/ast.c @@ -724,9 +724,12 @@ ast_ternary* ast_ternary_new(lex_ctx ctx, ast_expression *cond, ast_expression * void ast_ternary_delete(ast_ternary *self) { - ast_unref(self->cond); - ast_unref(self->on_true); - ast_unref(self->on_false); + /* the if()s are only there because computed-gotos can set them + * to NULL + */ + if (self->cond) ast_unref(self->cond); + if (self->on_true) ast_unref(self->on_true); + if (self->on_false) ast_unref(self->on_false); ast_expression_delete((ast_expression*)self); mem_d(self); } diff --git a/ftepp.c b/ftepp.c index ea68661..838d0de 100644 --- a/ftepp.c +++ b/ftepp.c @@ -822,6 +822,7 @@ static bool ftepp_if_value(ftepp_t *ftepp, bool *out, double *value_out) { ppmacro *macro; bool wasnot = false; + bool wasneg = false; if (!ftepp_skipspace(ftepp)) return false; @@ -833,6 +834,14 @@ static bool ftepp_if_value(ftepp_t *ftepp, bool *out, double *value_out) return false; } + if (ftepp->token == TOKEN_OPERATOR && !strcmp(ftepp_tokval(ftepp), "-")) + { + wasneg = true; + ftepp_next(ftepp); + if (!ftepp_skipspace(ftepp)) + return false; + } + switch (ftepp->token) { case TOKEN_IDENT: case TOKEN_TYPENAME: @@ -889,6 +898,7 @@ static bool ftepp_if_value(ftepp_t *ftepp, bool *out, double *value_out) } break; case TOKEN_STRINGCONST: + *value_out = 0; *out = false; break; case TOKEN_INTCONST: @@ -912,8 +922,12 @@ static bool ftepp_if_value(ftepp_t *ftepp, bool *out, double *value_out) default: ftepp_error(ftepp, "junk in #if: `%s` ...", ftepp_tokval(ftepp)); + if (opts.debug) + ftepp_error(ftepp, "internal: token %i\n", ftepp->token); return false; } + if (wasneg) + *value_out = -*value_out; if (wasnot) { *out = !*out; *value_out = (*out ? 1 : 0); diff --git a/lexer.c b/lexer.c index 5e0414b..64cdb3d 100644 --- a/lexer.c +++ b/lexer.c @@ -1299,6 +1299,17 @@ int lex_do(lex_file *lex) lex_tokench(lex, nextch); lex_tokench(lex, thirdch); } + } + else if (lex->flags.preprocessing && + ch == '-' && isdigit(nextch)) + { + lex->tok.ttype = lex_finish_digit(lex, nextch); + if (lex->tok.ttype == TOKEN_INTCONST) + lex->tok.constval.i = -lex->tok.constval.i; + else + lex->tok.constval.f = -lex->tok.constval.f; + lex_endtoken(lex); + return lex->tok.ttype; } else lex_ungetch(lex, nextch); diff --git a/parser.c b/parser.c index b7831d4..2d7ebe3 100644 --- a/parser.c +++ b/parser.c @@ -3043,28 +3043,35 @@ static bool parse_switch_go(parser_t *parser, ast_block *block, ast_expression * } /* parse computed goto sides */ -static ast_expression *parse_goto_computed(parser_t *parser, ast_expression *side) { +static ast_expression *parse_goto_computed(parser_t *parser, ast_expression **side) { ast_expression *on_true; ast_expression *on_false; + ast_expression *cond; - if (!side) + if (!*side) return NULL; - if (ast_istype(side, ast_ternary)) { - on_true = parse_goto_computed(parser, ((ast_ternary*)side)->on_true); - on_false = parse_goto_computed(parser, ((ast_ternary*)side)->on_false); + if (ast_istype(*side, ast_ternary)) { + ast_ternary *tern = (ast_ternary*)*side; + on_true = parse_goto_computed(parser, &tern->on_true); + on_false = parse_goto_computed(parser, &tern->on_false); if (!on_true || !on_false) { parseerror(parser, "expected label or expression in ternary"); - if (((ast_ternary*)side)->on_false) ast_unref(((ast_ternary*)side)->on_false); - if (((ast_ternary*)side)->on_true) ast_unref(((ast_ternary*)side)->on_true); + if (on_true) ast_unref(on_true); + if (on_false) ast_unref(on_false); return NULL; } - return (ast_expression*)ast_ifthen_new(parser_ctx(parser), ((ast_ternary*)side)->cond, on_true, on_false); - } else if (ast_istype(side, ast_label)) { - ast_goto *gt = ast_goto_new(parser_ctx(parser), ((ast_label*)side)->name); - ast_goto_set_label(gt, ((ast_label*)side)); + cond = tern->cond; + tern->cond = NULL; + ast_delete(tern); + *side = NULL; + return (ast_expression*)ast_ifthen_new(parser_ctx(parser), cond, on_true, on_false); + } else if (ast_istype(*side, ast_label)) { + ast_goto *gt = ast_goto_new(parser_ctx(parser), ((ast_label*)*side)->name); + ast_goto_set_label(gt, ((ast_label*)*side)); + *side = NULL; return (ast_expression*)gt; } return NULL; @@ -3089,7 +3096,7 @@ static bool parse_goto(parser_t *parser, ast_expression **out) /* failed to parse expression for goto */ if (!(expression = parse_expression(parser, false, true)) || - !(*out = parse_goto_computed(parser, expression))) { + !(*out = parse_goto_computed(parser, &expression))) { parseerror(parser, "invalid goto expression"); ast_unref(expression); return false;