Parse parameters within nested scopes.

This commit is contained in:
steve 2001-01-13 22:20:08 +00:00
parent 4e7a5d55d0
commit 02fc59fbdf
8 changed files with 145 additions and 80 deletions

View File

@ -17,13 +17,13 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: PFunction.cc,v 1.3 2000/02/23 02:56:53 steve Exp $"
#ident "$Id: PFunction.cc,v 1.4 2001/01/13 22:20:08 steve Exp $"
#endif
#include "PTask.h"
PFunction::PFunction(svector<PWire*>*p, Statement*s)
: out_(0), ports_(p), statement_(s)
PFunction::PFunction()
: out_(0), ports_(0), statement_(0)
{
}
@ -31,6 +31,19 @@ PFunction::~PFunction()
{
}
void PFunction::set_ports(svector<PWire *>*p)
{
assert(ports_ == 0);
ports_ = p;
}
void PFunction::set_statement(Statement*s)
{
assert(s != 0);
assert(statement_ == 0);
statement_ = s;
}
void PFunction::set_output(PWire*o)
{
assert(out_ == 0);
@ -39,6 +52,9 @@ void PFunction::set_output(PWire*o)
/*
* $Log: PFunction.cc,v $
* Revision 1.4 2001/01/13 22:20:08 steve
* Parse parameters within nested scopes.
*
* Revision 1.3 2000/02/23 02:56:53 steve
* Macintosh compilers do not support ident.
*

View File

@ -17,13 +17,13 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: PTask.cc,v 1.3 2000/02/23 02:56:53 steve Exp $"
#ident "$Id: PTask.cc,v 1.4 2001/01/13 22:20:08 steve Exp $"
#endif
# include "PTask.h"
PTask::PTask(svector<PWire*>*p, Statement*s)
: ports_(p), statement_(s)
PTask::PTask()
: ports_(0), statement_(0)
{
}
@ -31,8 +31,25 @@ PTask::~PTask()
{
}
void PTask::set_ports(svector<PWire*>*p)
{
assert(ports_ == 0);
ports_ = p;
}
void PTask::set_statement(Statement*s)
{
assert(statement_ == 0);
assert(s != 0);
statement_ = s;
}
/*
* $Log: PTask.cc,v $
* Revision 1.4 2001/01/13 22:20:08 steve
* Parse parameters within nested scopes.
*
* Revision 1.3 2000/02/23 02:56:53 steve
* Macintosh compilers do not support ident.
*

14
PTask.h
View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: PTask.h,v 1.9 2000/07/30 18:25:43 steve Exp $"
#ident "$Id: PTask.h,v 1.10 2001/01/13 22:20:08 steve Exp $"
#endif
# include "LineInfo.h"
@ -36,9 +36,12 @@ class Statement;
class PTask : public LineInfo {
public:
explicit PTask(svector<PWire*>*p, Statement*s);
explicit PTask();
~PTask();
void set_ports(svector<PWire *>*p);
void set_statement(Statement *s);
// Tasks introduce scope, to need to be handled during the
// scope elaboration pass. The scope passed is my scope,
// created by the containing scope. I fill it in with stuff if
@ -70,9 +73,11 @@ class PTask : public LineInfo {
class PFunction : public LineInfo {
public:
explicit PFunction(svector<PWire *>*p, Statement *s);
explicit PFunction();
~PFunction();
void set_ports(svector<PWire *>*p);
void set_statement(Statement *s);
void set_output(PWire*);
void elaborate_scope(Design*des, NetScope*scope) const;
@ -93,6 +98,9 @@ class PFunction : public LineInfo {
/*
* $Log: PTask.h,v $
* Revision 1.10 2001/01/13 22:20:08 steve
* Parse parameters within nested scopes.
*
* Revision 1.9 2000/07/30 18:25:43 steve
* Rearrange task and function elaboration so that the
* NetTaskDef and NetFuncDef functions are created during

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: design_dump.cc,v 1.108 2000/12/16 01:45:47 steve Exp $"
#ident "$Id: design_dump.cc,v 1.109 2001/01/13 22:20:08 steve Exp $"
#endif
/*
@ -947,11 +947,12 @@ void NetETernary::dump(ostream&o) const
void NetEUFunc::dump(ostream&o) const
{
o << name() << "(";
assert(parms_.count() > 0);
parms_[0]->dump(o);
for (unsigned idx = 1 ; idx < parms_.count() ; idx += 1) {
o << ", ";
parms_[idx]->dump(o);
if (parms_.count() > 0) {
parms_[0]->dump(o);
for (unsigned idx = 1 ; idx < parms_.count() ; idx += 1) {
o << ", ";
parms_[idx]->dump(o);
}
}
o << ")";
}
@ -998,6 +999,9 @@ void Design::dump(ostream&o) const
/*
* $Log: design_dump.cc,v $
* Revision 1.109 2001/01/13 22:20:08 steve
* Parse parameters within nested scopes.
*
* Revision 1.108 2000/12/16 01:45:47 steve
* Detect recursive instantiations (PR#2)
*

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: elab_expr.cc,v 1.32 2001/01/02 04:21:13 steve Exp $"
#ident "$Id: elab_expr.cc,v 1.33 2001/01/13 22:20:08 steve Exp $"
#endif
@ -179,7 +179,16 @@ NetExpr* PECallFunction::elaborate_expr(Design*des, NetScope*scope) const
NetScope*dscope = des->find_scope(def->name());
assert(dscope);
svector<NetExpr*> parms (parms_.count());
/* How many parameters have I got? Normally the size of the
list is correct, but there is the special case of a list of
1 nil pointer. This is how the parser tells me of no
parameter. In other words, ``func()'' is 1 nil parameter. */
unsigned parms_count = parms_.count();
if ((parms_count == 1) && (parms_[0] == 0))
parms_count = 0;
svector<NetExpr*> parms (parms_count);
/* Elaborate the input expressions for the function. This is
done in the scope of the function call, and not the scope
@ -187,8 +196,9 @@ NetExpr* PECallFunction::elaborate_expr(Design*des, NetScope*scope) const
function is elaborated when the definition is elaborated. */
for (unsigned idx = 0 ; idx < parms.count() ; idx += 1) {
NetExpr*tmp = parms_[idx]->elaborate_expr(des, scope);
parms[idx] = tmp;
PExpr*tmp = parms_[idx];
assert(tmp);
parms[idx] = tmp->elaborate_expr(des, scope);
}
@ -529,6 +539,9 @@ NetEUnary* PEUnary::elaborate_expr(Design*des, NetScope*scope) const
/*
* $Log: elab_expr.cc,v $
* Revision 1.33 2001/01/13 22:20:08 steve
* Parse parameters within nested scopes.
*
* Revision 1.32 2001/01/02 04:21:13 steve
* Support a bunch of unary operators in parameter expressions.
*

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: elab_sig.cc,v 1.9 2001/01/07 07:00:31 steve Exp $"
#ident "$Id: elab_sig.cc,v 1.10 2001/01/13 22:20:08 steve Exp $"
#endif
# include "Module.h"
@ -182,34 +182,36 @@ void PFunction::elaborate_sig(Design*des, NetScope*scope) const
return;
}
for (unsigned idx = 0 ; idx < ports_->count() ; idx += 1) {
if (ports_)
for (unsigned idx = 0 ; idx < ports_->count() ; idx += 1) {
/* Parse the port name into the task name and the reg
name. We know by design that the port name is given
as two components: <func>.<port>. */
/* Parse the port name into the task name and the reg
name. We know by design that the port name is given
as two components: <func>.<port>. */
string pname = (*ports_)[idx]->name();
string ppath = parse_first_name(pname);
string pname = (*ports_)[idx]->name();
string ppath = parse_first_name(pname);
if (ppath != scope->basename()) {
cerr << get_line() << ": internal error: function "
<< "port " << (*ports_)[idx]->name()
<< " has wrong name for function "
<< scope->name() << "." << endl;
des->errors += 1;
if (ppath != scope->basename()) {
cerr << get_line() << ": internal error: function "
<< "port " << (*ports_)[idx]->name()
<< " has wrong name for function "
<< scope->name() << "." << endl;
des->errors += 1;
}
NetNet*tmp = scope->find_signal(pname);
if (tmp == 0) {
cerr << get_line() << ": internal error: function "
<< scope->name() << " is missing port "
<< pname << "." << endl;
scope->dump(cerr);
des->errors += 1;
}
ports[idx+1] = tmp;
}
NetNet*tmp = scope->find_signal(pname);
if (tmp == 0) {
cerr << get_line() << ": internal error: function "
<< scope->name() << " is missing port "
<< pname << "." << endl;
scope->dump(cerr);
des->errors += 1;
}
ports[idx+1] = tmp;
}
NetFuncDef*def = new NetFuncDef(scope, ports);
scope->set_func_def(def);
@ -402,6 +404,9 @@ void PWire::elaborate_sig(Design*des, NetScope*scope) const
/*
* $Log: elab_sig.cc,v $
* Revision 1.10 2001/01/13 22:20:08 steve
* Parse parameters within nested scopes.
*
* Revision 1.9 2001/01/07 07:00:31 steve
* Detect port direction attached to non-ports.
*

60
parse.y
View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: parse.y,v 1.116 2001/01/06 06:31:59 steve Exp $"
#ident "$Id: parse.y,v 1.117 2001/01/13 22:20:08 steve Exp $"
#endif
# include "parse_misc.h"
@ -69,9 +69,6 @@ static struct str_pair_t decl_strength = { PGate::STRONG, PGate::STRONG };
PGBuiltin::Type gatetype;
NetNet::PortType porttype;
PTask*task;
PFunction*function;
PWire*wire;
svector<PWire*>*wires;
@ -152,8 +149,6 @@ static struct str_pair_t decl_strength = { PGate::STRONG, PGate::STRONG };
%type <porttype> port_type
%type <parmvalue> parameter_value_opt
%type <task> task_body
%type <function> func_body
%type <exprs> range_or_type_opt
%type <event_expr> event_expression_list
%type <event_expr> event_expression
@ -220,6 +215,8 @@ block_item_decl
{ delete $2;
yyerror(@1, "sorry: reatime variables not supported.");
}
| K_parameter parameter_assign_list ';'
| K_localparam localparam_assign_list ';'
/* Recover from errors that happen within variable lists. Use the
trailing semi-colon to resync the parser. */
@ -244,6 +241,14 @@ block_item_decl
{ yyerror(@1, "error: syntax error in realtime variable list.");
yyerrok;
}
| K_parameter error ';'
{ yyerror(@1, "error: syntax error in parameter list.");
yyerrok;
}
| K_localparam error ';'
{ yyerror(@1, "error: syntax error localparam list.");
yyerrok;
}
;
block_item_decls
@ -869,15 +874,6 @@ expr_primary
;
func_body
: function_item_list statement
{ $$ = new PFunction($1, $2); }
| function_item_list
{ yyerror(@1, "error: function body has no statement.");
$$ = new PFunction($1, 0);
}
;
/* A function_item is either a block item (i.e. a reg or integer
declaration) or an input declaration. There are no output or
inout ports. */
@ -1202,8 +1198,6 @@ module_item
| K_event list_of_variables ';'
{ pform_make_events($2, @1.text, @1.first_line);
}
| K_parameter parameter_assign_list ';'
| K_localparam localparam_assign_list ';' { }
/* Most gate types have an optional drive strength and optional
three-value delay. These rules handle the different cases. */
@ -1267,13 +1261,15 @@ module_item
| K_task IDENTIFIER ';'
{ pform_push_scope($2); }
task_body
{ pform_pop_scope(); }
task_item_list_opt statement_opt
K_endtask
{ PTask*tmp = $5;
{ PTask*tmp = new PTask;
tmp->set_file(@1.text);
tmp->set_lineno(@1.first_line);
pform_set_task($2, $5);
tmp->set_ports($5);
tmp->set_statement($6);
pform_set_task($2, tmp);
pform_pop_scope();
delete $2;
}
@ -1284,13 +1280,15 @@ module_item
| K_function range_or_type_opt IDENTIFIER ';'
{ pform_push_scope($3); }
func_body
{ pform_pop_scope(); }
function_item_list statement
K_endfunction
{ PFunction *tmp = $6;
{ PFunction *tmp = new PFunction;
tmp->set_file(@1.text);
tmp->set_lineno(@1.first_line);
pform_set_function($3, $2, $6);
tmp->set_ports($6);
tmp->set_statement($7);
pform_set_function($3, $2, tmp);
pform_pop_scope();
delete $3;
}
@ -1321,6 +1319,12 @@ module_item
yyerrok;
}
| K_function error K_endfunction
{ yyerror(@1, "error: I give up on this "
"function definition.");
yyerrok;
}
/* These rules are for the Icarus VErilog specific $attribute
extensions. Then catch the parameters of the $attribute keyword. */
@ -2190,12 +2194,6 @@ statement_opt
| ';' { $$ = 0; }
;
task_body
: task_item_list_opt statement_opt
{ PTask*tmp = new PTask($1, $2);
$$ = tmp;
}
;
task_item
: block_item_decl

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: pform_dump.cc,v 1.65 2000/12/11 00:31:43 steve Exp $"
#ident "$Id: pform_dump.cc,v 1.66 2001/01/13 22:20:08 steve Exp $"
#endif
/*
@ -586,11 +586,12 @@ void PForStatement::dump(ostream&out, unsigned ind) const
void PFunction::dump(ostream&out, unsigned ind) const
{
out << setw(ind) << "" << "output " << out_->name() << ";" << endl;
for (unsigned idx = 0 ; idx < ports_->count() ; idx += 1) {
out << setw(ind) << "";
out << "input ";
out << (*ports_)[idx]->name() << ";" << endl;
}
if (ports_)
for (unsigned idx = 0 ; idx < ports_->count() ; idx += 1) {
out << setw(ind) << "";
out << "input ";
out << (*ports_)[idx]->name() << ";" << endl;
}
if (statement_)
statement_->dump(out, ind);
@ -810,6 +811,9 @@ void PUdp::dump(ostream&out) const
/*
* $Log: pform_dump.cc,v $
* Revision 1.66 2001/01/13 22:20:08 steve
* Parse parameters within nested scopes.
*
* Revision 1.65 2000/12/11 00:31:43 steve
* Add support for signed reg variables,
* simulate in t-vvm signed comparisons.