diff --git a/parser.c b/parser.c index eb76810..3d7ab0d 100644 --- a/parser.c +++ b/parser.c @@ -741,6 +741,7 @@ onerr: } static bool parser_variable(parser_t *parser, ast_block *localblock); +static ast_block* parser_parse_block(parser_t *parser); static bool parser_parse_statement(parser_t *parser, ast_block *block, ast_expression **out) { if (parser->tok == TOKEN_TYPENAME) @@ -797,9 +798,12 @@ static bool parser_parse_statement(parser_t *parser, ast_block *block, ast_expre } else if (parser->tok == '{') { - /* a block */ - parseerror(parser, "TODO: inner blocks: %s", parser_tokval(parser)); - return false; + ast_block *inner; + inner = parser_parse_block(parser); + if (!inner) + return false; + *out = (ast_expression*)inner; + return true; } else { @@ -811,6 +815,12 @@ static bool parser_parse_statement(parser_t *parser, ast_block *block, ast_expre } } +static void parser_pop_local(parser_t *parser) +{ + parser->locals_count--; + mem_d(parser->locals[parser->locals_count].name); +} + static ast_block* parser_parse_block(parser_t *parser) { size_t oldblocklocal; @@ -856,6 +866,9 @@ static ast_block* parser_parse_block(parser_t *parser) cleanup: parser->blocklocal = oldblocklocal; + /* unroll the local vector */ + while (parser->locals_count > parser->blocklocal) + parser_pop_local(parser); return block; } @@ -869,12 +882,6 @@ static ast_expression* parser_parse_statement_or_block(parser_t *parser) return expr; } -static void parser_pop_local(parser_t *parser) -{ - parser->locals_count--; - mem_d(parser->locals[parser->locals_count].name); -} - static bool parser_variable(parser_t *parser, ast_block *localblock) { bool isfunc = false;