Build for loop decl inits correctly

The multiple expressions are chained together and evaluate in left to
right order.
This commit is contained in:
Bill Currie 2019-06-09 13:54:03 +09:00
parent d29ea55826
commit ec89149b29
3 changed files with 39 additions and 1 deletions

View file

@ -314,6 +314,17 @@ expr_t *new_bool_expr (ex_list_t *true_list, ex_list_t *false_list, expr_t *e);
*/ */
expr_t *new_block_expr (void); expr_t *new_block_expr (void);
/** Create a new statement block expression node from an expression list
The returned block holds the expression list in reverse order. This makes
it easy to build the list in a parser.
\param expr_list The expression list to convert to an expression block.
Note that the evaluation order will be reversed.
\return The new block expression (::ex_block_t) node.
*/
expr_t *build_block_expr (expr_t *expr_list);
/** Create a new binary expression node node. /** Create a new binary expression node node.
If either \a e1 or \a e2 are error expressions, then that expression will If either \a e1 or \a e2 are error expressions, then that expression will

View file

@ -539,6 +539,20 @@ new_binary_expr (int op, expr_t *e1, expr_t *e2)
return e; return e;
} }
expr_t *
build_block_expr (expr_t *expr_list)
{
expr_t *b = new_block_expr ();
while (expr_list) {
expr_t *e = expr_list;
expr_list = e->next;
e->next = 0;
append_expr (b, e);
}
return b;
}
expr_t * expr_t *
new_unary_expr (int op, expr_t *e1) new_unary_expr (int op, expr_t *e1)
{ {

View file

@ -1153,6 +1153,9 @@ statement
| FOR push_scope break_label continue_label | FOR push_scope break_label continue_label
'(' opt_init ';' opt_expr ';' opt_expr ')' statement pop_scope '(' opt_init ';' opt_expr ';' opt_expr ')' statement pop_scope
{ {
if ($6) {
$6 = build_block_expr ($6);
}
$$ = build_for_statement ($6, $8, $10, $12, $$ = build_for_statement ($6, $8, $10, $12,
break_label, continue_label); break_label, continue_label);
break_label = $3; break_label = $3;
@ -1234,12 +1237,22 @@ opt_init
init_var_decl_list init_var_decl_list
: init_var_decl : init_var_decl
| init_var_decl_list ',' init_var_decl {
printf ("a\n");
$$ = $1;
}
| init_var_decl_list ',' { $<spec>$ = $<spec>0; } init_var_decl
{
printf ("b\n");
$4->next = $1;
$$ = $4;
}
; ;
init_var_decl init_var_decl
: var_decl opt_initializer : var_decl opt_initializer
{ {
printf ("c\n");
specifier_t spec = $<spec>0; specifier_t spec = $<spec>0;
$1->type = append_type ($1->type, spec.type); $1->type = append_type ($1->type, spec.type);
$1->type = find_type ($1->type); $1->type = find_type ($1->type);