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,
|
PForStatement::PForStatement(PExpr*n1, PExpr*e1, PExpr*cond,
|
||||||
PExpr*n2, PExpr*e2, Statement*st)
|
Statement*step, Statement*st)
|
||||||
: name1_(n1), expr1_(e1), cond_(cond), name2_(n2), expr2_(e2),
|
: name1_(n1), expr1_(e1), cond_(cond), step_(step), statement_(st)
|
||||||
statement_(st)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -403,7 +403,7 @@ class PForStatement : public Statement {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
PForStatement(PExpr*n1, PExpr*e1, PExpr*cond,
|
PForStatement(PExpr*n1, PExpr*e1, PExpr*cond,
|
||||||
PExpr*n2, PExpr*e2, Statement*st);
|
Statement*step, Statement*body);
|
||||||
~PForStatement();
|
~PForStatement();
|
||||||
|
|
||||||
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
|
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
|
||||||
|
|
@ -417,8 +417,7 @@ class PForStatement : public Statement {
|
||||||
|
|
||||||
PExpr*cond_;
|
PExpr*cond_;
|
||||||
|
|
||||||
PExpr* name2_;
|
Statement*step_;
|
||||||
PExpr* expr2_;
|
|
||||||
|
|
||||||
Statement*statement_;
|
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_);
|
const PEIdent*id1 = dynamic_cast<const PEIdent*>(name1_);
|
||||||
assert(id1);
|
assert(id1);
|
||||||
const PEIdent*id2 = dynamic_cast<const PEIdent*>(name2_);
|
|
||||||
assert(id2);
|
|
||||||
|
|
||||||
NetBlock*top = new NetBlock(NetBlock::SEQU, 0);
|
NetBlock*top = new NetBlock(NetBlock::SEQU, 0);
|
||||||
top->set_line(*this);
|
top->set_line(*this);
|
||||||
|
|
@ -3826,32 +3824,15 @@ NetProc* PForStatement::elaborate(Design*des, NetScope*scope) const
|
||||||
body->append(tmp);
|
body->append(tmp);
|
||||||
|
|
||||||
|
|
||||||
/* Elaborate the increment assignment statement at the end of
|
/* Now elaborate the for_step statement. I really should do
|
||||||
the for loop. This is also a very specific assignment
|
some error checking here to make sure the step statement
|
||||||
statement. Put this into the "body" block. */
|
really does step the variable. */
|
||||||
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_);
|
|
||||||
|
|
||||||
if (debug_elaborate) {
|
if (debug_elaborate) {
|
||||||
cerr << get_fileline() << ": debug: FOR increment assign: "
|
cerr << get_fileline() << ": debug: Elaborate for_step statement "
|
||||||
<< sig->name() << " = " << *etmp << endl;
|
<< sig->name() << " = " << *etmp << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
NetAssign*step = new NetAssign(lv, etmp);
|
NetProc*step = step_->elaborate(des, scope);
|
||||||
step->set_line(*this);
|
|
||||||
|
|
||||||
body->append(step);
|
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_expr> event_expression
|
||||||
%type <event_statement> event_control
|
%type <event_statement> event_control
|
||||||
%type <statement> statement statement_or_null compressed_statement
|
%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 statement_or_null_list
|
||||||
%type <statement_list> statement_list_or_null
|
%type <statement_list> statement_list_or_null
|
||||||
|
|
||||||
|
|
@ -660,6 +661,19 @@ data_type /* IEEE1800-2005: A.2.2.1 */
|
||||||
|
|
||||||
endnew_opt : ':' K_new | ;
|
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 */
|
implicit_class_handle /* IEEE1800-2005: A.8.4 */
|
||||||
: K_this
|
: K_this
|
||||||
| K_super
|
| 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
|
number : BASED_NUMBER
|
||||||
{ $$ = $1; based_size = 0;}
|
{ $$ = $1; based_size = 0;}
|
||||||
| DEC_NUMBER
|
| DEC_NUMBER
|
||||||
|
|
@ -710,6 +784,16 @@ real_or_realtime
|
||||||
| K_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
|
/* The task declaration rule matches the task declaration
|
||||||
header, then pushes the function scope. This causes the
|
header, then pushes the function scope. This causes the
|
||||||
definitions in the task_body to take on the scope of the task
|
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;
|
delete $2;
|
||||||
$$ = tmp;
|
$$ = tmp;
|
||||||
}
|
}
|
||||||
| K_forever statement
|
|
||||||
{ PForever*tmp = new PForever($2);
|
| loop_statement { $$ = $1; }
|
||||||
FILE_NAME(tmp, @1);
|
|
||||||
$$ = tmp;
|
|
||||||
}
|
|
||||||
| K_repeat '(' expression ')' statement
|
|
||||||
{ PRepeat*tmp = new PRepeat($3, $5);
|
|
||||||
FILE_NAME(tmp, @1);
|
|
||||||
$$ = tmp;
|
|
||||||
}
|
|
||||||
| K_case '(' expression ')' case_items K_endcase
|
| K_case '(' expression ')' case_items K_endcase
|
||||||
{ PCase*tmp = new PCase(NetCase::EQ, $3, $5);
|
{ PCase*tmp = new PCase(NetCase::EQ, $3, $5);
|
||||||
FILE_NAME(tmp, @1);
|
FILE_NAME(tmp, @1);
|
||||||
|
|
@ -5128,36 +5205,6 @@ statement /* This is roughly statement_item in the LRM */
|
||||||
{ yyerror(@1, "error: Malformed conditional expression.");
|
{ yyerror(@1, "error: Malformed conditional expression.");
|
||||||
$$ = $5;
|
$$ = $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 */
|
/* SytemVerilog adds the compressed_statement */
|
||||||
|
|
||||||
| 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_list statement_or_null
|
: statement_or_null_list statement_or_null
|
||||||
{ vector<Statement*>*tmp = $1;
|
{ vector<Statement*>*tmp = $1;
|
||||||
|
|
|
||||||
|
|
@ -774,8 +774,8 @@ void PForever::dump(ostream&out, unsigned ind) const
|
||||||
void PForStatement::dump(ostream&out, unsigned ind) const
|
void PForStatement::dump(ostream&out, unsigned ind) const
|
||||||
{
|
{
|
||||||
out << setw(ind) << "" << "for (" << *name1_ << " = " << *expr1_
|
out << setw(ind) << "" << "for (" << *name1_ << " = " << *expr1_
|
||||||
<< "; " << *cond_ << "; " << *name2_ << " = " << *expr2_ <<
|
<< "; " << *cond_ << "; <for_step>)" << endl;
|
||||||
")" << endl;
|
step_->dump(out, ind+6);
|
||||||
statement_->dump(out, ind+3);
|
statement_->dump(out, ind+3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue