Make the for_step of for loops optional
In IEEE Std 1800-2017 A.6.8: the for_step part of the for loop is optional. If missing, it is assumed that the programmer known what they are doing.
This commit is contained in:
parent
bb779112c7
commit
5b9ceee062
|
|
@ -1388,7 +1388,8 @@ void NetForLoop::dump(ostream&fd, unsigned ind) const
|
|||
fd << "<nil>";
|
||||
fd << endl;
|
||||
statement_->dump(fd, ind+4);
|
||||
step_statement_->dump(fd, ind+4);
|
||||
if (step_statement_)
|
||||
step_statement_->dump(fd, ind+4);
|
||||
}
|
||||
|
||||
void NetFree::dump(ostream&o, unsigned ind) const
|
||||
|
|
|
|||
19
elaborate.cc
19
elaborate.cc
|
|
@ -5457,7 +5457,7 @@ NetProc* PForeach::elaborate_static_array_(Design*des, NetScope*scope,
|
|||
* - index variable (name1_) (optional)
|
||||
* - initial value (expr1_) (only if name1_ is present)
|
||||
* - condition expression (cond_)
|
||||
* - step statement (step_)
|
||||
* - step statement (step_) (optional)
|
||||
* - sub-statement (statement_)
|
||||
*
|
||||
* The rules that lead to the PForStatment look like:
|
||||
|
|
@ -5526,9 +5526,12 @@ NetProc* PForStatement::elaborate(Design*des, NetScope*scope) const
|
|||
// Now elaborate the for_step statement. I really should do
|
||||
// some error checking here to make sure the step statement
|
||||
// really does step the variable.
|
||||
NetProc*step = step_->elaborate(des, scope);
|
||||
if (!step)
|
||||
error_flag = true;
|
||||
NetProc*step = nullptr;
|
||||
if (step_) {
|
||||
step = step_->elaborate(des, scope);
|
||||
if (!step)
|
||||
error_flag = true;
|
||||
}
|
||||
|
||||
// Elaborate the condition expression. Try to evaluate it too,
|
||||
// in case it is a constant. This is an interesting case
|
||||
|
|
@ -5544,10 +5547,10 @@ NetProc* PForStatement::elaborate(Design*des, NetScope*scope) const
|
|||
// Error recovery - if we failed to elaborate any of the loop
|
||||
// expressions, give up now. Error counts where handled elsewhere.
|
||||
if (error_flag) {
|
||||
delete initial_expr;
|
||||
delete ce;
|
||||
delete step;
|
||||
delete sub;
|
||||
if (initial_expr) delete initial_expr;
|
||||
if (ce) delete ce;
|
||||
if (step) delete step;
|
||||
if (sub) delete sub;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -212,7 +212,7 @@ void NetForLoop::wrap_up()
|
|||
// statement. This can happen for example with statments like this:
|
||||
// for ( ; <condition> ; <step> ) <statement> ;
|
||||
// If the index_ and init_expr_ are present, then generate the
|
||||
// inital assignment and push it into the sequential block
|
||||
// inital assignment and push it into the sequential block.
|
||||
if (index_ || init_expr_) {
|
||||
top->set_line(*this);
|
||||
NetAssign_*lv = new NetAssign_(index_);
|
||||
|
|
@ -225,7 +225,11 @@ void NetForLoop::wrap_up()
|
|||
internal_block->set_line(*this);
|
||||
|
||||
if (statement_) internal_block->append(statement_);
|
||||
internal_block->append(step_statement_);
|
||||
|
||||
// The step statement is optional. If missing, it is assumed that
|
||||
// the programmer has added it to the regular statement. Hopefully.
|
||||
if (step_statement_)
|
||||
internal_block->append(step_statement_);
|
||||
|
||||
NetWhile*wloop = new NetWhile(condition_, internal_block);
|
||||
wloop->set_line(*this);
|
||||
|
|
|
|||
14
parse.y
14
parse.y
|
|
@ -675,7 +675,7 @@ static void current_function_set_statement(const YYLTYPE&loc, std::vector<Statem
|
|||
%type <event_statement> event_control
|
||||
%type <statement> statement statement_item statement_or_null
|
||||
%type <statement> compressed_statement
|
||||
%type <statement> loop_statement for_step jump_statement
|
||||
%type <statement> loop_statement for_step for_step_opt jump_statement
|
||||
%type <statement> concurrent_assertion_statement
|
||||
%type <statement> deferred_immediate_assertion_statement
|
||||
%type <statement> simple_immediate_assertion_statement
|
||||
|
|
@ -1418,6 +1418,10 @@ for_step /* IEEE1800-2005: A.6.8 */
|
|||
{ $$ = $1; }
|
||||
;
|
||||
|
||||
for_step_opt
|
||||
: for_step { $$ = $1; }
|
||||
| { $$ = nullptr; }
|
||||
;
|
||||
|
||||
/* The function declaration rule matches the function declaration
|
||||
header, then pushes the function scope. This causes the
|
||||
|
|
@ -1616,7 +1620,7 @@ lifetime_opt /* IEEE1800-2005: A.2.1.3 */
|
|||
/* Loop statements are kinds of statements. */
|
||||
|
||||
loop_statement /* IEEE1800-2005: A.6.8 */
|
||||
: K_for '(' lpvalue '=' expression ';' expression ';' for_step ')'
|
||||
: K_for '(' lpvalue '=' expression ';' expression ';' for_step_opt ')'
|
||||
statement_or_null
|
||||
{ PForStatement*tmp = new PForStatement($3, $5, $7, $9, $11);
|
||||
FILE_NAME(tmp, @1);
|
||||
|
|
@ -1624,7 +1628,7 @@ loop_statement /* IEEE1800-2005: A.6.8 */
|
|||
}
|
||||
|
||||
// The initialization statement is optional.
|
||||
| K_for '(' ';' expression ';' for_step ')'
|
||||
| K_for '(' ';' expression ';' for_step_opt ')'
|
||||
statement_or_null
|
||||
{ PForStatement*tmp = new PForStatement(nullptr, nullptr, $4, $6, $8);
|
||||
FILE_NAME(tmp, @1);
|
||||
|
|
@ -1635,7 +1639,7 @@ loop_statement /* IEEE1800-2005: A.6.8 */
|
|||
// statement in a synthetic named block. We can name the block
|
||||
// after the variable that we are creating, that identifier is
|
||||
// safe in the controlling scope.
|
||||
| K_for '(' K_var_opt data_type IDENTIFIER '=' expression ';' expression ';' for_step ')'
|
||||
| K_for '(' K_var_opt data_type IDENTIFIER '=' expression ';' expression ';' for_step_opt ')'
|
||||
{ static unsigned for_counter = 0;
|
||||
char for_block_name [64];
|
||||
snprintf(for_block_name, sizeof for_block_name, "$ivl_for_loop%u", for_counter);
|
||||
|
|
@ -1726,7 +1730,7 @@ loop_statement /* IEEE1800-2005: A.6.8 */
|
|||
yyerror(@1, "error: Error in for loop step assignment.");
|
||||
}
|
||||
|
||||
| K_for '(' lpvalue '=' expression ';' error ';' for_step ')'
|
||||
| K_for '(' lpvalue '=' expression ';' error ';' for_step_opt ')'
|
||||
statement_or_null
|
||||
{ $$ = 0;
|
||||
yyerror(@1, "error: Error in for loop condition expression.");
|
||||
|
|
|
|||
|
|
@ -1158,7 +1158,10 @@ void PForStatement::dump(ostream&out, unsigned ind) const
|
|||
else
|
||||
out << "<no-cond>";
|
||||
out << "; <for_step>)" << endl;
|
||||
step_->dump(out, ind+6);
|
||||
if (step_)
|
||||
step_->dump(out, ind+6);
|
||||
else
|
||||
out << setw(ind+6) << "" << "<no for_step statement>" << endl;
|
||||
if (statement_)
|
||||
statement_->dump(out, ind+3);
|
||||
else
|
||||
|
|
|
|||
|
|
@ -1458,6 +1458,11 @@ bool NetForLoop::synth_async(Design*des, NetScope*scope,
|
|||
return false;
|
||||
}
|
||||
|
||||
if (!step_statement_) {
|
||||
cerr << get_fileline() << ": sorry: Unable to synthesize for-loop without for_step statement." << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
ivl_assert(*this, index_ && init_expr_);
|
||||
if (debug_synth2) {
|
||||
cerr << get_fileline() << ": NetForLoop::synth_async: "
|
||||
|
|
|
|||
Loading…
Reference in New Issue