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,6 +1388,7 @@ void NetForLoop::dump(ostream&fd, unsigned ind) const
|
||||||
fd << "<nil>";
|
fd << "<nil>";
|
||||||
fd << endl;
|
fd << endl;
|
||||||
statement_->dump(fd, ind+4);
|
statement_->dump(fd, ind+4);
|
||||||
|
if (step_statement_)
|
||||||
step_statement_->dump(fd, ind+4);
|
step_statement_->dump(fd, ind+4);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
15
elaborate.cc
15
elaborate.cc
|
|
@ -5457,7 +5457,7 @@ NetProc* PForeach::elaborate_static_array_(Design*des, NetScope*scope,
|
||||||
* - index variable (name1_) (optional)
|
* - index variable (name1_) (optional)
|
||||||
* - initial value (expr1_) (only if name1_ is present)
|
* - initial value (expr1_) (only if name1_ is present)
|
||||||
* - condition expression (cond_)
|
* - condition expression (cond_)
|
||||||
* - step statement (step_)
|
* - step statement (step_) (optional)
|
||||||
* - sub-statement (statement_)
|
* - sub-statement (statement_)
|
||||||
*
|
*
|
||||||
* The rules that lead to the PForStatment look like:
|
* 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
|
// Now elaborate the for_step statement. I really should do
|
||||||
// some error checking here to make sure the step statement
|
// some error checking here to make sure the step statement
|
||||||
// really does step the variable.
|
// really does step the variable.
|
||||||
NetProc*step = step_->elaborate(des, scope);
|
NetProc*step = nullptr;
|
||||||
|
if (step_) {
|
||||||
|
step = step_->elaborate(des, scope);
|
||||||
if (!step)
|
if (!step)
|
||||||
error_flag = true;
|
error_flag = true;
|
||||||
|
}
|
||||||
|
|
||||||
// Elaborate the condition expression. Try to evaluate it too,
|
// Elaborate the condition expression. Try to evaluate it too,
|
||||||
// in case it is a constant. This is an interesting case
|
// 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
|
// Error recovery - if we failed to elaborate any of the loop
|
||||||
// expressions, give up now. Error counts where handled elsewhere.
|
// expressions, give up now. Error counts where handled elsewhere.
|
||||||
if (error_flag) {
|
if (error_flag) {
|
||||||
delete initial_expr;
|
if (initial_expr) delete initial_expr;
|
||||||
delete ce;
|
if (ce) delete ce;
|
||||||
delete step;
|
if (step) delete step;
|
||||||
delete sub;
|
if (sub) delete sub;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -212,7 +212,7 @@ void NetForLoop::wrap_up()
|
||||||
// statement. This can happen for example with statments like this:
|
// statement. This can happen for example with statments like this:
|
||||||
// for ( ; <condition> ; <step> ) <statement> ;
|
// for ( ; <condition> ; <step> ) <statement> ;
|
||||||
// If the index_ and init_expr_ are present, then generate the
|
// 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_) {
|
if (index_ || init_expr_) {
|
||||||
top->set_line(*this);
|
top->set_line(*this);
|
||||||
NetAssign_*lv = new NetAssign_(index_);
|
NetAssign_*lv = new NetAssign_(index_);
|
||||||
|
|
@ -225,6 +225,10 @@ void NetForLoop::wrap_up()
|
||||||
internal_block->set_line(*this);
|
internal_block->set_line(*this);
|
||||||
|
|
||||||
if (statement_) internal_block->append(statement_);
|
if (statement_) internal_block->append(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_);
|
internal_block->append(step_statement_);
|
||||||
|
|
||||||
NetWhile*wloop = new NetWhile(condition_, internal_block);
|
NetWhile*wloop = new NetWhile(condition_, internal_block);
|
||||||
|
|
|
||||||
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 <event_statement> event_control
|
||||||
%type <statement> statement statement_item statement_or_null
|
%type <statement> statement statement_item statement_or_null
|
||||||
%type <statement> compressed_statement
|
%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> concurrent_assertion_statement
|
||||||
%type <statement> deferred_immediate_assertion_statement
|
%type <statement> deferred_immediate_assertion_statement
|
||||||
%type <statement> simple_immediate_assertion_statement
|
%type <statement> simple_immediate_assertion_statement
|
||||||
|
|
@ -1418,6 +1418,10 @@ for_step /* IEEE1800-2005: A.6.8 */
|
||||||
{ $$ = $1; }
|
{ $$ = $1; }
|
||||||
;
|
;
|
||||||
|
|
||||||
|
for_step_opt
|
||||||
|
: for_step { $$ = $1; }
|
||||||
|
| { $$ = nullptr; }
|
||||||
|
;
|
||||||
|
|
||||||
/* The function declaration rule matches the function declaration
|
/* The function declaration rule matches the function declaration
|
||||||
header, then pushes the function scope. This causes the
|
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 statements are kinds of statements. */
|
||||||
|
|
||||||
loop_statement /* IEEE1800-2005: A.6.8 */
|
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
|
statement_or_null
|
||||||
{ PForStatement*tmp = new PForStatement($3, $5, $7, $9, $11);
|
{ PForStatement*tmp = new PForStatement($3, $5, $7, $9, $11);
|
||||||
FILE_NAME(tmp, @1);
|
FILE_NAME(tmp, @1);
|
||||||
|
|
@ -1624,7 +1628,7 @@ loop_statement /* IEEE1800-2005: A.6.8 */
|
||||||
}
|
}
|
||||||
|
|
||||||
// The initialization statement is optional.
|
// The initialization statement is optional.
|
||||||
| K_for '(' ';' expression ';' for_step ')'
|
| K_for '(' ';' expression ';' for_step_opt ')'
|
||||||
statement_or_null
|
statement_or_null
|
||||||
{ PForStatement*tmp = new PForStatement(nullptr, nullptr, $4, $6, $8);
|
{ PForStatement*tmp = new PForStatement(nullptr, nullptr, $4, $6, $8);
|
||||||
FILE_NAME(tmp, @1);
|
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
|
// statement in a synthetic named block. We can name the block
|
||||||
// after the variable that we are creating, that identifier is
|
// after the variable that we are creating, that identifier is
|
||||||
// safe in the controlling scope.
|
// 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;
|
{ static unsigned for_counter = 0;
|
||||||
char for_block_name [64];
|
char for_block_name [64];
|
||||||
snprintf(for_block_name, sizeof for_block_name, "$ivl_for_loop%u", for_counter);
|
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.");
|
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
|
statement_or_null
|
||||||
{ $$ = 0;
|
{ $$ = 0;
|
||||||
yyerror(@1, "error: Error in for loop condition expression.");
|
yyerror(@1, "error: Error in for loop condition expression.");
|
||||||
|
|
|
||||||
|
|
@ -1158,7 +1158,10 @@ void PForStatement::dump(ostream&out, unsigned ind) const
|
||||||
else
|
else
|
||||||
out << "<no-cond>";
|
out << "<no-cond>";
|
||||||
out << "; <for_step>)" << endl;
|
out << "; <for_step>)" << endl;
|
||||||
|
if (step_)
|
||||||
step_->dump(out, ind+6);
|
step_->dump(out, ind+6);
|
||||||
|
else
|
||||||
|
out << setw(ind+6) << "" << "<no for_step statement>" << endl;
|
||||||
if (statement_)
|
if (statement_)
|
||||||
statement_->dump(out, ind+3);
|
statement_->dump(out, ind+3);
|
||||||
else
|
else
|
||||||
|
|
|
||||||
|
|
@ -1458,6 +1458,11 @@ bool NetForLoop::synth_async(Design*des, NetScope*scope,
|
||||||
return false;
|
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_);
|
ivl_assert(*this, index_ && init_expr_);
|
||||||
if (debug_synth2) {
|
if (debug_synth2) {
|
||||||
cerr << get_fileline() << ": NetForLoop::synth_async: "
|
cerr << get_fileline() << ": NetForLoop::synth_async: "
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue