diff --git a/PExpr.cc b/PExpr.cc index abc3c1000..694b86819 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.9 1999/09/16 04:18:15 steve Exp $" +#ident "$Id: PExpr.cc,v 1.10 1999/09/25 02:57:29 steve Exp $" #endif # include "PExpr.h" @@ -60,6 +60,15 @@ bool PEBinary::is_constant(Module*mod) const return left_->is_constant(mod) && right_->is_constant(mod); } +PECallFunction::PECallFunction(const string &n, const svector &parms) +: name_(n), parms_(parms) +{ +} + +PECallFunction::~PECallFunction() +{ +} + bool PEConcat::is_constant(Module *mod) const { bool constant = repeat_? repeat_->is_constant(mod) : true; @@ -119,6 +128,9 @@ bool PETernary::is_constant(Module*) const /* * $Log: PExpr.cc,v $ + * Revision 1.10 1999/09/25 02:57:29 steve + * Parse system function calls. + * * Revision 1.9 1999/09/16 04:18:15 steve * elaborate concatenation repeats. * diff --git a/PExpr.h b/PExpr.h index abc3229c6..5e38cb3ab 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.19 1999/09/15 04:17:52 steve Exp $" +#ident "$Id: PExpr.h,v 1.20 1999/09/25 02:57:29 steve Exp $" #endif # include @@ -263,23 +263,29 @@ class PETernary : public PExpr { PExpr*fal_; }; - +/* + * This class represents a parsed call to a function. + */ class PECallFunction : public PExpr { - public: - explicit PECallFunction(const string &n, const svector &parms) - : name_(n), parms_(parms) {} - ~PECallFunction() {} + public: + explicit PECallFunction(const string &n, const svector &parms); + ~PECallFunction(); virtual void dump(ostream &) const; - virtual NetEUFunc*elaborate_expr(Design*des, const string&path) const; + virtual NetExpr*elaborate_expr(Design*des, const string&path) const; - private: + private: string name_; svector parms_; + + NetESFunc* elaborate_sfunc_(Design*des, const string&path) const; }; /* * $Log: PExpr.h,v $ + * Revision 1.20 1999/09/25 02:57:29 steve + * Parse system function calls. + * * Revision 1.19 1999/09/15 04:17:52 steve * separate assign lval elaboration for error checking. * diff --git a/elab_expr.cc b/elab_expr.cc index c91902dcc..bd8daec50 100644 --- a/elab_expr.cc +++ b/elab_expr.cc @@ -17,13 +17,61 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: elab_expr.cc,v 1.2 1999/09/21 00:13:40 steve Exp $" +#ident "$Id: elab_expr.cc,v 1.3 1999/09/25 02:57:30 steve Exp $" #endif # include "pform.h" # include "netlist.h" +NetESFunc* PECallFunction::elaborate_sfunc_(Design*des, const string&path) const +{ + cerr << get_line() << ": sorry: system functions not supported." + << endl; + des->errors += 1; + return 0; +} + +NetExpr* PECallFunction::elaborate_expr(Design*des, const string&path) const +{ + if (name_[0] == '$') + return elaborate_sfunc_(des, path); + + string myname = path+"."+name_; + NetFuncDef*def = des->find_function(path, name_); + if (def == 0) { + cerr << get_line() << ": error: No function " << name_ << + " in this context (" << path << ")." << endl; + des->errors += 1; + return 0; + } + assert(def); + svector parms (parms_.count()); + + for (unsigned idx = 0 ; idx < parms.count() ; idx += 1) { + NetExpr*tmp = parms_[idx]->elaborate_expr(des, myname); + parms[idx] = tmp; + } + + /* Look for the return value signal for the called function in + the context of the function definition, not my context. */ + NetNet*res = des->find_signal(def->name(), name_); + if (res == 0) { + cerr << get_line() << ": internal error: Unable to locate " + "function return value for " << name_ << " in " << + def->name() << "." << endl; + des->errors += 1; + return 0; + } + + assert(res); + NetESignal*eres = new NetESignal(res); + assert(eres); + des->add_node(eres); + NetEUFunc*func = new NetEUFunc(def, eres, parms); + return func; +} + NetExpr* PEIdent::elaborate_expr(Design*des, const string&path) const { @@ -58,8 +106,9 @@ NetExpr* PEIdent::elaborate_expr(Design*des, const string&path) const verinum*lsn = lsb_->eval_const(des, path); verinum*msn = msb_->eval_const(des, path); if ((lsn == 0) || (msn == 0)) { - cerr << get_line() << ": Part select expresions " - " must be constant expressions." << endl; + cerr << get_line() << ": error: " + "Part select expresions must be " + "constant expressions." << endl; des->errors += 1; return 0; } @@ -130,7 +179,7 @@ NetExpr* PEIdent::elaborate_expr(Design*des, const string&path) const assert(idx_ == 0); NetExpr*i = msb_->elaborate_expr(des, path); if (i == 0) { - cerr << get_line() << ": Unable to exaborate " + cerr << get_line() << ": error: Unable to exaborate " "index expression `" << *msb_ << "'" << endl; des->errors += 1; return 0; @@ -142,7 +191,7 @@ NetExpr* PEIdent::elaborate_expr(Design*des, const string&path) const } // I cannot interpret this identifier. Error message. - cerr << get_line() << ": Unable to bind wire/reg/memory " + cerr << get_line() << ": error: Unable to bind wire/reg/memory " "`" << path << "." << text_ << "'" << endl; des->errors += 1; return 0; @@ -150,6 +199,9 @@ NetExpr* PEIdent::elaborate_expr(Design*des, const string&path) const /* * $Log: elab_expr.cc,v $ + * Revision 1.3 1999/09/25 02:57:30 steve + * Parse system function calls. + * * Revision 1.2 1999/09/21 00:13:40 steve * Support parameters that reference other paramters. * diff --git a/elaborate.cc b/elaborate.cc index 87fcb0f5c..f8df8a568 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.99 1999/09/23 03:56:57 steve Exp $" +#ident "$Id: elaborate.cc,v 1.100 1999/09/25 02:57:30 steve Exp $" #endif /* @@ -792,43 +792,6 @@ NetNet* PEBinary::elaborate_net(Design*des, const string&path, return osig; } -NetEUFunc* PECallFunction::elaborate_expr(Design*des, const string&path) const -{ - string myname = path+"."+name_; - NetFuncDef*def = des->find_function(path, name_); - if (def == 0) { - cerr << get_line() << ": No function " << name_ << - " in this context (" << path << ")." << endl; - des->errors += 1; - return 0; - } - assert(def); - svector parms (parms_.count()); - - for (unsigned idx = 0 ; idx < parms.count() ; idx += 1) { - NetExpr*tmp = parms_[idx]->elaborate_expr(des, myname); - parms[idx] = tmp; - } - - /* Look for the return value signal for the called function in - the context of the function definition, not my context. */ - NetNet*res = des->find_signal(def->name(), name_); - if (res == 0) { - cerr << get_line() << ": INTERNAL ERROR: Unable to locate " - "function return value for " << name_ << " in " << - def->name() << "." << endl; - des->errors += 1; - return 0; - } - - assert(res); - NetESignal*eres = new NetESignal(res); - assert(eres); - des->add_node(eres); - NetEUFunc*func = new NetEUFunc(def, eres, parms); - return func; -} - /* * The concatenation operator, as a net, is a wide signal that is * connected to all the pins of the elaborated expression nets. @@ -1456,11 +1419,9 @@ NetProc* PAssign::assign_to_memory_(NetMemory*mem, PExpr*ix, Design*des, const string&path) const { NetExpr*rv = rval()->elaborate_expr(des, path); - if (rv == 0) { - cerr << get_line() << ": " << "failed to elaborate expression." - << endl; + if (rv == 0) return 0; - } + assert(rv); rv->set_width(mem->width()); @@ -1613,11 +1574,9 @@ NetProc* PAssign::elaborate(Design*des, const string&path) const /* Elaborate the r-value expression. */ assert(rval()); NetExpr*rv = rval()->elaborate_expr(des, path); - if (rv == 0) { - cerr << get_line() << ": failed to elaborate expression." - << endl; + if (rv == 0) return 0; - } + assert(rv); /* Try to evaluate the expression, at least as far as possible. */ @@ -1757,11 +1716,9 @@ NetProc* PAssignNB::assign_to_memory_(NetMemory*mem, PExpr*ix, { /* Elaborate the r-value expression, ... */ NetExpr*rv = rval()->elaborate_expr(des, path); - if (rv == 0) { - cerr << get_line() << ": " << "failed to elaborate expression." - << endl; + if (rv == 0) return 0; - } + assert(rv); rv->set_width(mem->width()); @@ -1808,11 +1765,9 @@ NetProc* PAssignNB::elaborate(Design*des, const string&path) const /* Elaborate the r-value expression. This generates a procedural expression that I attach to the assignment. */ NetExpr*rv = rval()->elaborate_expr(des, path); - if (rv == 0) { - cerr << get_line() << ": failed to elaborate expression." - << endl; + if (rv == 0) return 0; - } + assert(rv); NetAssignNB*cur; @@ -2192,7 +2147,6 @@ NetProc* PEventStatement::elaborate_st(Design*des, const string&path, for (unsigned idx = 0 ; idx < expr_.count() ; idx += 1) { NetNet*expr = expr_[idx]->expr()->elaborate_net(des, path); if (expr == 0) { - cerr << get_line() << ": Failed to elaborate expression: "; expr_[0]->dump(cerr); cerr << endl; des->errors += 1; @@ -2637,6 +2591,9 @@ Design* elaborate(const map&modules, /* * $Log: elaborate.cc,v $ + * Revision 1.100 1999/09/25 02:57:30 steve + * Parse system function calls. + * * Revision 1.99 1999/09/23 03:56:57 steve * Support shift operators. * diff --git a/netlist.h b/netlist.h index e16522388..4bcdba3ea 100644 --- a/netlist.h +++ b/netlist.h @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: netlist.h,v 1.71 1999/09/23 03:56:57 steve Exp $" +#ident "$Id: netlist.h,v 1.72 1999/09/25 02:57:30 steve Exp $" #endif /* @@ -1348,6 +1348,39 @@ class NetEParam : public NetExpr { string name_; }; +/* + * This node represents a system function call in an expression. The + * object contains the name of the system function, which the backend + * uses to to VPI matching. + */ +class NetESFunc : public NetExpr { + + public: + NetESFunc(const string&name, NetESignal*, svector&); + ~NetESFunc(); + + const string& name() const; + + const NetESignal*result() const; + unsigned parm_count() const; + const NetExpr* parm(unsigned idx) const; + + virtual bool set_width(unsigned); + virtual void dump(ostream&) const; + + virtual void expr_scan(struct expr_scan_t*) const; + virtual NetESFunc*dup_expr() const; + + private: + string name_; + NetESignal*result_; + svector parms_; + + private: // not implemented + NetESFunc(const NetESFunc&); + NetESFunc& operator= (const NetESFunc&); +}; + /* * This class represents the ternary (?:) operator. It has 3 * expressions, one of which is a condition used to select which of @@ -1657,6 +1690,9 @@ extern ostream& operator << (ostream&, NetNet::Type); /* * $Log: netlist.h,v $ + * Revision 1.72 1999/09/25 02:57:30 steve + * Parse system function calls. + * * Revision 1.71 1999/09/23 03:56:57 steve * Support shift operators. * diff --git a/parse.y b/parse.y index f01f5f785..607c1f5a6 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.66 1999/09/22 04:30:04 steve Exp $" +#ident "$Id: parse.y,v 1.67 1999/09/25 02:57:30 steve Exp $" #endif # include "parse_misc.h" @@ -639,8 +639,10 @@ expr_primary $$ = tmp; } | SYSTEM_IDENTIFIER '(' expression_list ')' - { yyerror(@2, "Sorry, function calls not supported."); - $$ = 0; + { PECallFunction*tmp = new PECallFunction($1, *$3); + tmp->set_file(@1.text); + tmp->set_lineno(@1.first_line); + $$ = tmp; } | '(' expression ')' { $$ = $2; }