From 7c2cf8b2fa89f012e85e9ab162459d2f70493f0a Mon Sep 17 00:00:00 2001 From: steve Date: Thu, 10 Jun 1999 04:03:52 +0000 Subject: [PATCH] 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. --- PExpr.cc | 18 ++++++++++- PExpr.h | 31 +++++++++++++++++-- elaborate.cc | 83 +++++++++++++++++++++++++++++++++++++++++++++++---- parse.y | 71 ++++++++++++++++++++++++++++++++----------- pform_dump.cc | 14 ++++++++- 5 files changed, 191 insertions(+), 26 deletions(-) diff --git a/PExpr.cc b/PExpr.cc index 688840f1d..fb9f067ca 100644 --- a/PExpr.cc +++ b/PExpr.cc @@ -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. diff --git a/PExpr.h b/PExpr.h index 9ea985bf6..84ac28132 100644 --- a/PExpr.h +++ b/PExpr.h @@ -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 @@ -71,7 +71,9 @@ ostream& operator << (ostream&, const PExpr&); class PEConcat : public PExpr { public: - PEConcat(const svector&p) : parms_(p) { } + PEConcat(const svector&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: svectorparms_; + 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. * diff --git a/elaborate.cc b/elaborate.cc index 68cb4be5b..e453843ff 100644 --- a/elaborate.cc +++ b/elaborate.cc @@ -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 { svectornets (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&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. * diff --git a/parse.y b/parse.y index 2f5f204f6..0bdc84ff9 100644 --- a/parse.y +++ b/parse.y @@ -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 diff --git a/pform_dump.cc b/pform_dump.cc index f0b67457a..64cbd55af 100644 --- a/pform_dump.cc +++ b/pform_dump.cc @@ -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 with an svector version,