Add support for the Ternary operator,

Add support for repeat concatenation,
 Correct some seg faults cause by elaboration
 errors,
 Parse the casex anc casez statements.
This commit is contained in:
steve 1999-06-10 04:03:52 +00:00
parent f69becd5e0
commit 7c2cf8b2fa
5 changed files with 191 additions and 26 deletions

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: PExpr.cc,v 1.3 1999/05/16 05:08:42 steve Exp $"
#ident "$Id: PExpr.cc,v 1.4 1999/06/10 04:03:52 steve Exp $"
#endif
# include "PExpr.h"
@ -38,6 +38,11 @@ bool PExpr::is_constant(Module*) const
return false;
}
PEConcat::~PEConcat()
{
delete repeat_;
}
/*
* An identifier can be in a constant expresion if (and only if) it is
* a parameter.
@ -67,8 +72,19 @@ bool PEString::is_constant(Module*) const
return true;
}
PETernary::~PETernary()
{
}
/*
* $Log: PExpr.cc,v $
* Revision 1.4 1999/06/10 04:03:52 steve
* Add support for the Ternary operator,
* Add support for repeat concatenation,
* Correct some seg faults cause by elaboration
* errors,
* Parse the casex anc casez statements.
*
* Revision 1.3 1999/05/16 05:08:42 steve
* Redo constant expression detection to happen
* after parsing.

31
PExpr.h
View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: PExpr.h,v 1.10 1999/06/09 03:00:05 steve Exp $"
#ident "$Id: PExpr.h,v 1.11 1999/06/10 04:03:52 steve Exp $"
#endif
# include <string>
@ -71,7 +71,9 @@ ostream& operator << (ostream&, const PExpr&);
class PEConcat : public PExpr {
public:
PEConcat(const svector<PExpr*>&p) : parms_(p) { }
PEConcat(const svector<PExpr*>&p, PExpr*r =0)
: parms_(p), repeat_(r) { }
~PEConcat();
virtual void dump(ostream&) const;
virtual NetNet* elaborate_net(Design*des, const string&path) const;
@ -79,6 +81,7 @@ class PEConcat : public PExpr {
private:
svector<PExpr*>parms_;
PExpr*repeat_;
};
class PEEvent : public PExpr {
@ -195,8 +198,32 @@ class PEBinary : public PExpr {
PExpr*right_;
};
/*
* This class supports the ternary (?:) operator. The operator takes
* three expressions, the test, the true result and the false result.
*/
class PETernary : public PExpr {
public:
explicit PETernary(PExpr*e, PExpr*t, PExpr*f)
: expr_(e), tru_(t), fal_(f) { }
~PETernary();
private:
PExpr*expr_;
PExpr*tru_;
PExpr*fal_;
};
/*
* $Log: PExpr.h,v $
* Revision 1.11 1999/06/10 04:03:52 steve
* Add support for the Ternary operator,
* Add support for repeat concatenation,
* Correct some seg faults cause by elaboration
* errors,
* Parse the casex anc casez statements.
*
* Revision 1.10 1999/06/09 03:00:05 steve
* Add support for procedural concatenation expression.
*

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: elaborate.cc,v 1.38 1999/06/09 03:00:06 steve Exp $"
#ident "$Id: elaborate.cc,v 1.39 1999/06/10 04:03:53 steve Exp $"
#endif
/*
@ -178,6 +178,8 @@ void PGate::elaborate(Design*des, const string&path) const
assign.) Elaborate the lvalue and rvalue, and do the assignment. */
void PGAssign::elaborate(Design*des, const string&path) const
{
assert(pin(0));
assert(pin(1));
NetNet*lval = pin(0)->elaborate_net(des, path);
NetNet*rval = pin(1)->elaborate_net(des, path);
@ -545,7 +547,7 @@ void PGModule::elaborate(Design*des, const string&path) const
return;
}
cerr << "Unknown module: " << type_ << endl;
cerr << get_line() << ": Unknown module: " << type_ << endl;
}
NetNet* PExpr::elaborate_net(Design*des, const string&path) const
@ -666,11 +668,31 @@ NetNet* PEConcat::elaborate_net(Design*des, const string&path) const
{
svector<NetNet*>nets (parms_.count());
unsigned pins = 0;
unsigned errors = 0;
if (repeat_) {
cerr << get_line() << ": Sorry, I do not know how to"
" elaborate repeat concatenation nets." << endl;
return 0;
}
/* Elaborate the operands of the concatenation. */
for (unsigned idx = 0 ; idx < nets.count() ; idx += 1) {
nets[idx] = parms_[idx]->elaborate_net(des, path);
pins += nets[idx]->pin_count();
if (nets[idx] == 0)
errors += 1;
else
pins += nets[idx]->pin_count();
}
/* If any of the sub expressions failed to elaborate, then
delete all those that did and abort myself. */
if (errors) {
for (unsigned idx = 0 ; idx < nets.count() ; idx += 1) {
if (nets[idx]) delete nets[idx];
}
des->errors += 1;
return 0;
}
/* Make the temporary signal that connects to all the
@ -696,6 +718,14 @@ NetNet* PEConcat::elaborate_net(Design*des, const string&path) const
NetNet* PEIdent::elaborate_net(Design*des, const string&path) const
{
NetNet*sig = des->find_signal(path+"."+text_);
if (sig == 0) {
cerr << get_line() << ": Unable to find signal ``" <<
text_ << "''" << endl;
des->errors+= 1;
return 0;
}
assert(sig);
if (msb_ && lsb_) {
verinum*mval = msb_->eval_const(des, path);
@ -757,6 +787,10 @@ NetNet* PENumber::elaborate_net(Design*des, const string&path) const
NetNet* PEUnary::elaborate_net(Design*des, const string&path) const
{
NetNet* sub_sig = expr_->elaborate_net(des, path);
if (sub_sig == 0) {
des->errors += 1;
return 0;
}
assert(sub_sig);
NetNet* sig;
@ -801,8 +835,15 @@ NetNet* PEUnary::elaborate_net(Design*des, const string&path) const
NetExpr* PEBinary::elaborate_expr(Design*des, const string&path) const
{
bool flag;
NetEBinary*tmp = new NetEBinary(op_, left_->elaborate_expr(des, path),
right_->elaborate_expr(des, path));
NetExpr*lp = left_->elaborate_expr(des, path);
NetExpr*rp = right_->elaborate_expr(des, path);
if ((lp == 0) || (rp == 0)) {
delete lp;
delete rp;
return 0;
}
NetEBinary*tmp = new NetEBinary(op_, lp, rp);
tmp->set_line(*this);
switch (op_) {
case 'e':
@ -824,6 +865,12 @@ NetExpr* PEBinary::elaborate_expr(Design*des, const string&path) const
NetExpr* PEConcat::elaborate_expr(Design*des, const string&path) const
{
if (repeat_) {
cerr << get_line() << ": Sorry, I do not know how to"
" elaborate repeat concatenation expressions." << endl;
return 0;
}
NetEConcat*tmp = new NetEConcat(parms_.count());
tmp->set_line(*this);
@ -962,6 +1009,13 @@ NetProc* PAssign::elaborate(Design*des, const string&path) const
return assign_to_memory_(mem, id->msb_, des, path);
if (id->lsb_ || id->msb_) {
cerr << get_line() << ": Sorry, cannot elaborate part/bit"
" selects in l-value." << endl;
des->errors += 1;
return 0;
}
NetNet*reg = des->find_signal(path+"."+id->name());
if (reg == 0) {
@ -1114,6 +1168,12 @@ NetProc* PBlock::elaborate(Design*des, const string&path) const
NetProc* PCase::elaborate(Design*des, const string&path) const
{
NetExpr*expr = expr_->elaborate_expr(des, path);
if (expr == 0) {
cerr << get_line() << ": Unable to elaborate the case"
" expression." << endl;
return 0;
}
NetCase*res = new NetCase(expr, items_->count());
for (unsigned idx = 0 ; idx < items_->count() ; idx += 1) {
@ -1135,6 +1195,12 @@ NetProc* PCondit::elaborate(Design*des, const string&path) const
{
// Elaborate and try to evaluate the conditional expression.
NetExpr*expr = expr_->elaborate_expr(des, path);
if (expr == 0) {
cerr << get_line() << ": Unable to elaborate"
" condition expression." << endl;
des->errors += 1;
return 0;
}
NetExpr*tmp = expr->eval_tree();
if (tmp) {
delete expr;
@ -1396,6 +1462,13 @@ Design* elaborate(const map<string,Module*>&modules,
/*
* $Log: elaborate.cc,v $
* Revision 1.39 1999/06/10 04:03:53 steve
* Add support for the Ternary operator,
* Add support for repeat concatenation,
* Correct some seg faults cause by elaboration
* errors,
* Parse the casex anc casez statements.
*
* Revision 1.38 1999/06/09 03:00:06 steve
* Add support for procedural concatenation expression.
*

71
parse.y
View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: parse.y,v 1.34 1999/06/09 03:00:06 steve Exp $"
#ident "$Id: parse.y,v 1.35 1999/06/10 04:03:53 steve Exp $"
#endif
# include "parse_misc.h"
@ -289,13 +289,6 @@ event_expression
expression
: expr_primary
{ $$ = $1; }
| '{' expression_list '}'
{ PEConcat*tmp = new PEConcat(*$2);
tmp->set_file(@2.text);
tmp->set_lineno(@2.first_line);
delete $2;
$$ = tmp;
}
| '+' expr_primary %prec UNARY_PREC
{ PEUnary*tmp = new PEUnary('+', $2);
tmp->set_file(@2.text);
@ -459,8 +452,10 @@ expression
$$ = tmp;
}
| expression '?' expression ':' expression
{ yyerror(@2, "Sorry, ?: operator not supported.");
$$ = 0;
{ PETernary*tmp = new PETernary($1, $3, $5);
tmp->set_file(@2.text);
tmp->set_lineno(@2.first_line);
$$ = tmp;
}
| IDENTIFIER '(' expression_list ')'
{ yyerror(@2, "Sorry, function calls not supported.");
@ -547,6 +542,27 @@ expr_primary
delete $2;
delete $6;
}
| '{' expression_list '}'
{ PEConcat*tmp = new PEConcat(*$2);
tmp->set_file(@2.text);
tmp->set_lineno(@2.first_line);
delete $2;
$$ = tmp;
}
| '{' expression '{' expression_list '}' '}'
{ PExpr*rep = $2;
if (!pform_expression_is_constant($2)) {
yyerror(@2, "Repeat expression must be constant.");
delete rep;
delete $2;
rep = 0;
}
PEConcat*tmp = new PEConcat(*$4, rep);
tmp->set_file(@1.text);
tmp->set_lineno(@1.first_line);
delete $4;
$$ = tmp;
}
;
@ -770,12 +786,13 @@ lpvalue
$$ = tmp;
}
| identifier '[' expression ':' expression ']'
{ yyerror(@1, "Sorry, part selects"
" not supported in lvalue.");
$$ = 0;
{ PEIdent*tmp = new PEIdent(*$1);
tmp->msb_ = $3;
tmp->lsb_ = $5;
tmp->set_file(@1.text);
tmp->set_lineno(@1.first_line);
delete $1;
delete $3;
delete $5;
$$ = tmp;
}
| '{' expression_list '}'
{ yyerror(@1, "Sorry, concatenation expressions"
@ -1100,7 +1117,7 @@ register_variable_list
statement
: K_assign lavalue '=' expression ';'
{ yyerror(@1, "Sorry, proceedural continuous assign not supported.");
{ yyerror(@1, "Sorry, procedural continuous assign not supported.");
$$ = 0;
}
| K_begin statement_list K_end
@ -1117,12 +1134,30 @@ statement
tmp->set_lineno(@1.first_line);
$$ = tmp;
}
| K_casex '(' expression ')' case_items K_endcase
{ PCase*tmp = new PCase($3, $5);
tmp->set_file(@1.text);
tmp->set_lineno(@1.first_line);
yywarn(@1, "casex not properly supported, using case.");
$$ = tmp;
}
| K_casez '(' expression ')' case_items K_endcase
{ PCase*tmp = new PCase($3, $5);
tmp->set_file(@1.text);
tmp->set_lineno(@1.first_line);
yywarn(@1, "casez not properly supported, using case.");
$$ = tmp;
}
| K_if '(' expression ')' statement_opt
{ PCondit*tmp = new PCondit($3, $5, 0);
tmp->set_file(@1.text);
tmp->set_lineno(@1.first_line);
$$ = tmp;
}
| K_if '(' expression ')' statement_opt K_else statement_opt
{ PCondit*tmp = new PCondit($3, $5, $7);
tmp->set_file(@1.text);
tmp->set_lineno(@1.first_line);
$$ = tmp;
}
| K_if '(' error ')' statement_opt
@ -1135,7 +1170,9 @@ statement
}
| K_for '(' lpvalue '=' expression ';' expression ';'
lpvalue '=' expression ')' statement
{ $$ = new PForStatement($3, $5, $7, $9, $11, $13);
{ PForStatement*tmp = new PForStatement($3, $5, $7, $9, $11, $13);
tmp->set_file(@1.text);
tmp->set_lineno(@1.first_line);
}
| K_for '(' lpvalue '=' expression ';' expression ';'
error ')' statement

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: pform_dump.cc,v 1.18 1999/06/06 20:45:39 steve Exp $"
#ident "$Id: pform_dump.cc,v 1.19 1999/06/10 04:03:53 steve Exp $"
#endif
/*
@ -44,6 +44,9 @@ void PExpr::dump(ostream&out) const
void PEConcat::dump(ostream&out) const
{
if (repeat_)
out << "{" << *repeat_;
if (parms_.count() == 0) {
out << "{}";
return;
@ -54,6 +57,8 @@ void PEConcat::dump(ostream&out) const
out << ", " << *parms_[idx];
out << "}";
if (repeat_) out << "}";
}
void PEEvent::dump(ostream&out) const
@ -475,6 +480,13 @@ void PUdp::dump(ostream&out) const
/*
* $Log: pform_dump.cc,v $
* Revision 1.19 1999/06/10 04:03:53 steve
* Add support for the Ternary operator,
* Add support for repeat concatenation,
* Correct some seg faults cause by elaboration
* errors,
* Parse the casex anc casez statements.
*
* Revision 1.18 1999/06/06 20:45:39 steve
* Add parse and elaboration of non-blocking assignments,
* Replace list<PCase::Item*> with an svector version,