From 465941f3573642bd2a9256e7bbc850181cbb50de Mon Sep 17 00:00:00 2001 From: Dale Weiler Date: Tue, 2 Mar 2021 10:46:05 -0500 Subject: [PATCH] pass parent scope to parse_statement_or_block previous behavior when parsing a statement where a block is typically expected would fail to associate the statement with the parent block it's in, resulting in variable declarations ending up in global scope. this fixes #197 --- parser.cpp | 16 ++++++++-------- tests/parent_block_scope_for_locals.qc | 16 ++++++++++++++++ tests/parent_block_scope_for_locals.tmpl | 5 +++++ 3 files changed, 29 insertions(+), 8 deletions(-) create mode 100644 tests/parent_block_scope_for_locals.qc create mode 100644 tests/parent_block_scope_for_locals.tmpl diff --git a/parser.cpp b/parser.cpp index b0afc79..ac28fd7 100644 --- a/parser.cpp +++ b/parser.cpp @@ -20,7 +20,7 @@ static bool parse_typedef(parser_t *parser); static bool parse_variable(parser_t *parser, ast_block *localblock, bool nofields, int qualifier, ast_value *cached_typedef, bool noref, bool is_static, uint32_t qflags, char *vstring); static ast_block* parse_block(parser_t *parser); static bool parse_block_into(parser_t *parser, ast_block *block); -static bool parse_statement_or_block(parser_t *parser, ast_expression **out); +static bool parse_statement_or_block(parser_t *parser, ast_block* parent_block, ast_expression **out); static bool parse_statement(parser_t *parser, ast_block *block, ast_expression **out, bool allow_cases); static ast_expression* parse_expression_leave(parser_t *parser, bool stopatcomma, bool truthvalue, bool with_labels); static ast_expression* parse_expression(parser_t *parser, bool stopatcomma, bool with_labels); @@ -2162,7 +2162,7 @@ static bool parse_if(parser_t *parser, ast_block *block, ast_expression **out) ast_unref(cond); return false; } - if (!parse_statement_or_block(parser, &ontrue)) { + if (!parse_statement_or_block(parser, block, &ontrue)) { ast_unref(cond); return false; } @@ -2177,7 +2177,7 @@ static bool parse_if(parser_t *parser, ast_block *block, ast_expression **out) ast_unref(cond); return false; } - if (!parse_statement_or_block(parser, &onfalse)) { + if (!parse_statement_or_block(parser, block, &onfalse)) { delete ontrue; ast_unref(cond); return false; @@ -2285,7 +2285,7 @@ static bool parse_while_go(parser_t *parser, ast_block *block, ast_expression ** ast_unref(cond); return false; } - if (!parse_statement_or_block(parser, &ontrue)) { + if (!parse_statement_or_block(parser, block, &ontrue)) { ast_unref(cond); return false; } @@ -2360,7 +2360,7 @@ static bool parse_dowhile_go(parser_t *parser, ast_block *block, ast_expression (void)block; /* not touching */ - if (!parse_statement_or_block(parser, &ontrue)) + if (!parse_statement_or_block(parser, block, &ontrue)) return false; /* expect the "while" */ @@ -2561,7 +2561,7 @@ static bool parse_for_go(parser_t *parser, ast_block *block, ast_expression **ou parseerror(parser, "expected for-loop body"); goto onerr; } - if (!parse_statement_or_block(parser, &ontrue)) + if (!parse_statement_or_block(parser, block, &ontrue)) goto onerr; if (cond) { @@ -3805,13 +3805,13 @@ static ast_block* parse_block(parser_t *parser) return block; } -static bool parse_statement_or_block(parser_t *parser, ast_expression **out) +static bool parse_statement_or_block(parser_t *parser, ast_block* parent_block, ast_expression **out) { if (parser->tok == '{') { *out = parse_block(parser); return !!*out; } - return parse_statement(parser, nullptr, out, false); + return parse_statement(parser, parent_block, out, false); } static bool create_vector_members(ast_value *var, ast_member **me) diff --git a/tests/parent_block_scope_for_locals.qc b/tests/parent_block_scope_for_locals.qc new file mode 100644 index 0000000..fc3eef5 --- /dev/null +++ b/tests/parent_block_scope_for_locals.qc @@ -0,0 +1,16 @@ +void a() { + if (1) + for (float i = 0; i < 3; ++i) + print(ftos(i)); +} + +void b() { + if (1) + for (float i = 0; i < 3; ++i) + print(ftos(i)); +} + +void main() { + a(); + b(); +} \ No newline at end of file diff --git a/tests/parent_block_scope_for_locals.tmpl b/tests/parent_block_scope_for_locals.tmpl new file mode 100644 index 0000000..2eb9ae2 --- /dev/null +++ b/tests/parent_block_scope_for_locals.tmpl @@ -0,0 +1,5 @@ +I: parent_block_scope_for_locals.qc +D: when omitting braces ensure locals end up in parent block +T: -execute +C: -std=fteqcc +M: 012012 -- 2.39.2