Allow variable declarations in for loops

Matches C, C++ and C#
This commit is contained in:
Bill Currie 2019-06-08 21:52:17 +09:00
parent be4c3a82a2
commit 5bd3c8c985

View file

@ -180,11 +180,12 @@ int yylex (void);
%type <symbol> methoddef %type <symbol> methoddef
%type <expr> opt_initializer var_initializer local_def %type <expr> opt_initializer var_initializer local_def
%type <expr> opt_expr fexpr expr element_list element vector_expr %type <expr> opt_init opt_expr fexpr expr element_list element
%type <expr> optional_state_expr texpr %type <expr> optional_state_expr texpr vector_expr
%type <expr> statement statements compound_statement %type <expr> statement statements compound_statement
%type <expr> else label break_label continue_label %type <expr> else label break_label continue_label
%type <expr> unary_expr cast_expr opt_arg_list arg_list %type <expr> unary_expr cast_expr opt_arg_list arg_list
%type <expr> init_var_decl_list init_var_decl
%type <switch_block> switch_block %type <switch_block> switch_block
%type <symbol> identifier %type <symbol> identifier
@ -1053,22 +1054,28 @@ optional_comma
| ',' | ','
; ;
compound_statement push_scope
: '{' : /* empty */
{ {
if (!options.traditional) { if (!options.traditional) {
current_symtab = new_symtab (current_symtab, stab_local); current_symtab = new_symtab (current_symtab, stab_local);
current_symtab->space = current_symtab->parent->space; current_symtab->space = current_symtab->parent->space;
} }
} }
statements '}' ;
pop_scope
: /* empty */
{ {
if (!options.traditional) if (!options.traditional)
current_symtab = current_symtab->parent; current_symtab = current_symtab->parent;
$$ = $3;
} }
; ;
compound_statement
: '{' push_scope statements '}' pop_scope { $$ = $3; }
;
statements statements
: /*empty*/ : /*empty*/
{ {
@ -1143,13 +1150,13 @@ statement
{ {
$$ = build_if_statement ($2, $4, $6, $7, $8); $$ = build_if_statement ($2, $4, $6, $7, $8);
} }
| FOR break_label continue_label | FOR push_scope break_label continue_label
'(' opt_expr ';' opt_expr ';' opt_expr ')' statement '(' opt_init ';' opt_expr ';' opt_expr ')' statement pop_scope
{ {
$$ = build_for_statement ($5, $7, $9, $11, $$ = build_for_statement ($6, $8, $10, $12,
break_label, continue_label); break_label, continue_label);
break_label = $2; break_label = $3;
continue_label = $3; continue_label = $4;
} }
| WHILE break_label continue_label not '(' texpr ')' statement | WHILE break_label continue_label not '(' texpr ')' statement
{ {
@ -1216,6 +1223,32 @@ switch_block
} }
; ;
opt_init
: fexpr
| type init_var_decl_list { $$ = $2; }
| /* empty */
{
$$ = 0;
}
;
init_var_decl_list
: init_var_decl
| init_var_decl_list ',' init_var_decl
;
init_var_decl
: var_decl opt_initializer
{
specifier_t spec = $<spec>0;
$1->type = append_type ($1->type, spec.type);
$1->type = find_type ($1->type);
$1->sy_type = sy_var;
initialize_def ($1, 0, current_symtab->space, spec.storage);
$$ = assign_expr (new_symbol_expr ($1), $2);
}
;
opt_expr opt_expr
: fexpr : fexpr
| /* empty */ | /* empty */