Parse for declarations, implement for_step statements.
for-statement declarations still generate a "sorry" message, but the for_step statements work in general now.
This commit is contained in:
parent
cad7c74680
commit
d000147392
|
|
@ -276,9 +276,8 @@ PForever::~PForever()
|
|||
}
|
||||
|
||||
PForStatement::PForStatement(PExpr*n1, PExpr*e1, PExpr*cond,
|
||||
PExpr*n2, PExpr*e2, Statement*st)
|
||||
: name1_(n1), expr1_(e1), cond_(cond), name2_(n2), expr2_(e2),
|
||||
statement_(st)
|
||||
Statement*step, Statement*st)
|
||||
: name1_(n1), expr1_(e1), cond_(cond), step_(step), statement_(st)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -403,7 +403,7 @@ class PForStatement : public Statement {
|
|||
|
||||
public:
|
||||
PForStatement(PExpr*n1, PExpr*e1, PExpr*cond,
|
||||
PExpr*n2, PExpr*e2, Statement*st);
|
||||
Statement*step, Statement*body);
|
||||
~PForStatement();
|
||||
|
||||
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
|
||||
|
|
@ -417,8 +417,7 @@ class PForStatement : public Statement {
|
|||
|
||||
PExpr*cond_;
|
||||
|
||||
PExpr* name2_;
|
||||
PExpr* expr2_;
|
||||
Statement*step_;
|
||||
|
||||
Statement*statement_;
|
||||
};
|
||||
|
|
|
|||
29
elaborate.cc
29
elaborate.cc
|
|
@ -3780,8 +3780,6 @@ NetProc* PForStatement::elaborate(Design*des, NetScope*scope) const
|
|||
|
||||
const PEIdent*id1 = dynamic_cast<const PEIdent*>(name1_);
|
||||
assert(id1);
|
||||
const PEIdent*id2 = dynamic_cast<const PEIdent*>(name2_);
|
||||
assert(id2);
|
||||
|
||||
NetBlock*top = new NetBlock(NetBlock::SEQU, 0);
|
||||
top->set_line(*this);
|
||||
|
|
@ -3826,32 +3824,15 @@ NetProc* PForStatement::elaborate(Design*des, NetScope*scope) const
|
|||
body->append(tmp);
|
||||
|
||||
|
||||
/* Elaborate the increment assignment statement at the end of
|
||||
the for loop. This is also a very specific assignment
|
||||
statement. Put this into the "body" block. */
|
||||
sig = des->find_signal(scope, id2->path());
|
||||
if (sig == 0) {
|
||||
cerr << get_fileline() << ": error: Unable to find variable "
|
||||
<< id2->path() << " in for-loop increment expression." << endl;
|
||||
des->errors += 1;
|
||||
return body;
|
||||
}
|
||||
|
||||
assert(sig);
|
||||
lv = new NetAssign_(sig);
|
||||
|
||||
/* Make the r-value of the increment assignment, and size it
|
||||
properly. Then use it to build the assignment statement. */
|
||||
etmp = elaborate_rval_expr(des, scope, lv->expr_type(), lv->lwidth(),
|
||||
expr2_);
|
||||
|
||||
/* 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. */
|
||||
if (debug_elaborate) {
|
||||
cerr << get_fileline() << ": debug: FOR increment assign: "
|
||||
cerr << get_fileline() << ": debug: Elaborate for_step statement "
|
||||
<< sig->name() << " = " << *etmp << endl;
|
||||
}
|
||||
|
||||
NetAssign*step = new NetAssign(lv, etmp);
|
||||
step->set_line(*this);
|
||||
NetProc*step = step_->elaborate(des, scope);
|
||||
|
||||
body->append(step);
|
||||
|
||||
|
|
|
|||
134
parse.y
134
parse.y
|
|
@ -524,6 +524,7 @@ static void current_task_set_statement(vector<Statement*>*s)
|
|||
%type <event_expr> event_expression
|
||||
%type <event_statement> event_control
|
||||
%type <statement> statement statement_or_null compressed_statement
|
||||
%type <statement> loop_statement for_step
|
||||
%type <statement_list> statement_list statement_or_null_list
|
||||
%type <statement_list> statement_list_or_null
|
||||
|
||||
|
|
@ -660,6 +661,19 @@ data_type /* IEEE1800-2005: A.2.2.1 */
|
|||
|
||||
endnew_opt : ':' K_new | ;
|
||||
|
||||
for_step /* IEEE1800-2005: A.6.8 */
|
||||
: lpvalue '=' expression
|
||||
{ PAssign*tmp = new PAssign($1,$3);
|
||||
FILE_NAME(tmp, @1);
|
||||
$$ = tmp;
|
||||
}
|
||||
| inc_or_dec_expression
|
||||
{ $$ = pform_compressed_assign_from_inc_dec(@1, $1); }
|
||||
| compressed_statement
|
||||
{ $$ = $1; }
|
||||
;
|
||||
|
||||
|
||||
implicit_class_handle /* IEEE1800-2005: A.8.4 */
|
||||
: K_this
|
||||
| K_super
|
||||
|
|
@ -694,6 +708,66 @@ inc_or_dec_expression /* IEEE1800-2005: A.4.3 */
|
|||
}
|
||||
;
|
||||
|
||||
/* Loop statements are kinds of statements. */
|
||||
|
||||
loop_statement /* IEEE1800-2005: A.6.8 */
|
||||
: K_for '(' lpvalue '=' expression ';' expression ';' for_step ')'
|
||||
statement_or_null
|
||||
{ PForStatement*tmp = new PForStatement($3, $5, $7, $9, $11);
|
||||
FILE_NAME(tmp, @1);
|
||||
$$ = tmp;
|
||||
}
|
||||
|
||||
| K_for '(' data_type IDENTIFIER '=' expression ';' expression ';' for_step ')'
|
||||
statement_or_null
|
||||
{ $$ = 0;
|
||||
yyerror(@3, "sorry: for_variable_declaration not supported");
|
||||
}
|
||||
|
||||
| K_forever statement_or_null
|
||||
{ PForever*tmp = new PForever($2);
|
||||
FILE_NAME(tmp, @1);
|
||||
$$ = tmp;
|
||||
}
|
||||
|
||||
| K_repeat '(' expression ')' statement_or_null
|
||||
{ PRepeat*tmp = new PRepeat($3, $5);
|
||||
FILE_NAME(tmp, @1);
|
||||
$$ = tmp;
|
||||
}
|
||||
|
||||
| K_while '(' expression ')' statement_or_null
|
||||
{ PWhile*tmp = new PWhile($3, $5);
|
||||
FILE_NAME(tmp, @1);
|
||||
$$ = tmp;
|
||||
}
|
||||
|
||||
/* Error forms for loop statements. */
|
||||
|
||||
| K_for '(' lpvalue '=' expression ';' expression ';' error ')'
|
||||
statement_or_null
|
||||
{ $$ = 0;
|
||||
yyerror(@1, "error: Error in for loop step assignment.");
|
||||
}
|
||||
|
||||
| K_for '(' lpvalue '=' expression ';' error ';' for_step ')'
|
||||
statement_or_null
|
||||
{ $$ = 0;
|
||||
yyerror(@1, "error: Error in for loop condition expression.");
|
||||
}
|
||||
|
||||
| K_for '(' error ')' statement_or_null
|
||||
{ $$ = 0;
|
||||
yyerror(@1, "error: Incomprehensible for loop.");
|
||||
}
|
||||
|
||||
| K_while '(' error ')' statement_or_null
|
||||
{ $$ = 0;
|
||||
yyerror(@1, "error: Error in while loop condition.");
|
||||
}
|
||||
|
||||
;
|
||||
|
||||
number : BASED_NUMBER
|
||||
{ $$ = $1; based_size = 0;}
|
||||
| DEC_NUMBER
|
||||
|
|
@ -710,6 +784,16 @@ real_or_realtime
|
|||
| K_realtime
|
||||
;
|
||||
|
||||
/* Many places where statements are allowed can actually take a
|
||||
statement or a null statement marked with a naked semi-colon. */
|
||||
|
||||
statement_or_null /* IEEE1800-2005: A.6.4 */
|
||||
: statement
|
||||
{ $$ = $1; }
|
||||
| ';'
|
||||
{ $$ = 0; }
|
||||
;
|
||||
|
||||
/* The task declaration rule matches the task declaration
|
||||
header, then pushes the function scope. This causes the
|
||||
definitions in the task_body to take on the scope of the task
|
||||
|
|
@ -5079,16 +5163,9 @@ statement /* This is roughly statement_item in the LRM */
|
|||
delete $2;
|
||||
$$ = tmp;
|
||||
}
|
||||
| K_forever statement
|
||||
{ PForever*tmp = new PForever($2);
|
||||
FILE_NAME(tmp, @1);
|
||||
$$ = tmp;
|
||||
}
|
||||
| K_repeat '(' expression ')' statement
|
||||
{ PRepeat*tmp = new PRepeat($3, $5);
|
||||
FILE_NAME(tmp, @1);
|
||||
$$ = tmp;
|
||||
}
|
||||
|
||||
| loop_statement { $$ = $1; }
|
||||
|
||||
| K_case '(' expression ')' case_items K_endcase
|
||||
{ PCase*tmp = new PCase(NetCase::EQ, $3, $5);
|
||||
FILE_NAME(tmp, @1);
|
||||
|
|
@ -5128,36 +5205,6 @@ statement /* This is roughly statement_item in the LRM */
|
|||
{ yyerror(@1, "error: Malformed conditional expression.");
|
||||
$$ = $5;
|
||||
}
|
||||
| K_for '(' lpvalue '=' expression ';' expression ';'
|
||||
lpvalue '=' expression ')' statement
|
||||
{ PForStatement*tmp = new PForStatement($3, $5, $7, $9, $11, $13);
|
||||
FILE_NAME(tmp, @1);
|
||||
$$ = tmp;
|
||||
}
|
||||
| K_for '(' lpvalue '=' expression ';' expression ';'
|
||||
error ')' statement
|
||||
{ $$ = 0;
|
||||
yyerror(@1, "error: Error in for loop step assignment.");
|
||||
}
|
||||
| K_for '(' lpvalue '=' expression ';' error ';'
|
||||
lpvalue '=' expression ')' statement
|
||||
{ $$ = 0;
|
||||
yyerror(@1, "error: Error in for loop condition expression.");
|
||||
}
|
||||
| K_for '(' error ')' statement
|
||||
{ $$ = 0;
|
||||
yyerror(@1, "error: Incomprehensible for loop.");
|
||||
}
|
||||
| K_while '(' expression ')' statement
|
||||
{ PWhile*tmp = new PWhile($3, $5);
|
||||
FILE_NAME(tmp, @1);
|
||||
$$ = tmp;
|
||||
}
|
||||
| K_while '(' error ')' statement
|
||||
{ $$ = 0;
|
||||
yyerror(@1, "error: Error in while loop condition.");
|
||||
}
|
||||
|
||||
/* SytemVerilog adds the compressed_statement */
|
||||
|
||||
| compressed_statement ';'
|
||||
|
|
@ -5406,13 +5453,6 @@ statement_list
|
|||
}
|
||||
;
|
||||
|
||||
statement_or_null
|
||||
: statement
|
||||
{ $$ = $1; }
|
||||
| ';'
|
||||
{ $$ = 0; }
|
||||
;
|
||||
|
||||
statement_or_null_list
|
||||
: statement_or_null_list statement_or_null
|
||||
{ vector<Statement*>*tmp = $1;
|
||||
|
|
|
|||
|
|
@ -774,8 +774,8 @@ void PForever::dump(ostream&out, unsigned ind) const
|
|||
void PForStatement::dump(ostream&out, unsigned ind) const
|
||||
{
|
||||
out << setw(ind) << "" << "for (" << *name1_ << " = " << *expr1_
|
||||
<< "; " << *cond_ << "; " << *name2_ << " = " << *expr2_ <<
|
||||
")" << endl;
|
||||
<< "; " << *cond_ << "; <for_step>)" << endl;
|
||||
step_->dump(out, ind+6);
|
||||
statement_->dump(out, ind+3);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue