From: Wolfgang (Blub) Bumiller Date: Sat, 11 Aug 2012 08:30:54 +0000 (+0200) Subject: let's be less insane with function naming and prepare parsing for control structures X-Git-Tag: 0.1-rc1~356 X-Git-Url: https://git.rm.cloudns.org/?a=commitdiff_plain;h=d3d2e00b649e21b51a83a33f1927e55538069077;p=xonotic%2Fgmqcc.git let's be less insane with function naming and prepare parsing for control structures --- diff --git a/parser.c b/parser.c index 04724a8..eb76810 100644 --- a/parser.c +++ b/parser.c @@ -741,13 +741,18 @@ onerr: } static bool parser_variable(parser_t *parser, ast_block *localblock); -static bool parser_body_do(parser_t *parser, ast_block *block) +static bool parser_parse_statement(parser_t *parser, ast_block *block, ast_expression **out) { if (parser->tok == TOKEN_TYPENAME) { /* local variable */ + if (!block) { + parseerror(parser, "cannot declare a variable from here"); + return false; + } if (!parser_variable(parser, block)) return false; + *out = NULL; return true; } else if (parser->tok == TOKEN_KEYWORD) @@ -778,10 +783,7 @@ static bool parser_body_do(parser_t *parser, ast_block *block) return false; } - if (!ast_block_exprs_add(block, (ast_expression*)ret)) { - ast_delete(ret); - return false; - } + *out = (ast_expression*)ret; } else if (!parser_next(parser)) { parseerror(parser, "expected semicolon"); if (expected->expression.next->expression.vtype != TYPE_VOID) { @@ -804,10 +806,7 @@ static bool parser_body_do(parser_t *parser, ast_block *block) ast_expression *exp = parser_expression(parser); if (!exp) return false; - if (!ast_block_exprs_add(block, exp)) { - ast_delete(exp); - return false; - } + *out = exp; return true; } } @@ -829,10 +828,19 @@ static ast_block* parser_parse_block(parser_t *parser) while (parser->tok != TOKEN_EOF && parser->tok < TOKEN_ERROR) { + ast_expression *expr; if (parser->tok == '}') break; - if (!parser_body_do(parser, block)) { + if (!parser_parse_statement(parser, block, &expr)) { + ast_block_delete(block); + block = NULL; + goto cleanup; + } + if (!expr) + continue; + if (!ast_block_exprs_add(block, expr)) { + ast_delete(expr); ast_block_delete(block); block = NULL; goto cleanup; @@ -851,6 +859,16 @@ cleanup: return block; } +static ast_expression* parser_parse_statement_or_block(parser_t *parser) +{ + ast_expression *expr; + if (parser->tok == '{') + return (ast_expression*)parser_parse_block(parser); + if (!parser_parse_statement(parser, NULL, &expr)) + return NULL; + return expr; +} + static void parser_pop_local(parser_t *parser) { parser->locals_count--;