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
This commit is contained in:
Dale Weiler 2021-03-02 10:46:05 -05:00
parent 237722c0b2
commit 465941f357
3 changed files with 29 additions and 8 deletions

View file

@ -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)

View file

@ -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();
}

View file

@ -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