Skip to content

Commit

Permalink
Parse contribution statements as far as pform.
Browse files Browse the repository at this point in the history
Contribution statements have an l-value and r-value. Parse those
expressions into pform so that elaboration has something to work with.

In this process, this patch also changes the PECallFunction class to
use the vector template instead of the svector template. The latter
doesn't add anything over the STL vector template, so this is a start
of working the svector out.
  • Loading branch information
steveicarus committed Jul 27, 2008
1 parent 03e306c commit 25a27f9
Show file tree
Hide file tree
Showing 12 changed files with 118 additions and 64 deletions.
5 changes: 4 additions & 1 deletion AStatement.cc
Expand Up @@ -25,12 +25,15 @@ AStatement::~AStatement()
{
}

AContrib::AContrib()
AContrib::AContrib(PExpr*lv, PExpr*rv)
: lval_(lv), rval_(rv)
{
}

AContrib::~AContrib()
{
delete lval_;
delete rval_;
}

AProcess::~AProcess()
Expand Down
16 changes: 15 additions & 1 deletion AStatement.h
Expand Up @@ -38,15 +38,29 @@ class AStatement : public LineInfo {
AStatement& operator= (const AStatement&);
};

/*
* A contribution statement is like an assignment: there is an l-value
* expression and an r-value expression. The l-value is a branch probe
* expression.
*/
class AContrib : public AStatement {

public:
AContrib();
AContrib(PExpr*lval, PExpr*rval);
~AContrib();

virtual void dump(ostream&out, unsigned ind) const;

private:
PExpr*lval_;
PExpr*rval_;
};

/*
* An analog process is not a statement, but contains an analog
* statement. The process is where we attach process characteristics
* such as initial vs. always, attributes....
*/
class AProcess : public LineInfo {

public:
Expand Down
15 changes: 13 additions & 2 deletions PExpr.cc
Expand Up @@ -90,7 +90,7 @@ PEBShift::~PEBShift()
{
}

PECallFunction::PECallFunction(const pform_name_t&n, const svector<PExpr *> &parms)
PECallFunction::PECallFunction(const pform_name_t&n, const vector<PExpr *> &parms)
: path_(n), parms_(parms)
{
}
Expand All @@ -103,7 +103,7 @@ static pform_name_t pn_from_ps(perm_string n)
return tmp;
}

PECallFunction::PECallFunction(perm_string n, const svector<PExpr*>&parms)
PECallFunction::PECallFunction(perm_string n, const vector<PExpr*>&parms)
: path_(pn_from_ps(n)), parms_(parms)
{
}
Expand All @@ -113,6 +113,17 @@ PECallFunction::PECallFunction(perm_string n)
{
}

// NOTE: Anachronism. Try to work all use of svector out.
PECallFunction::PECallFunction(const pform_name_t&n, const svector<PExpr *> &parms)
: path_(n), parms_(vector_from_svector(parms))
{
}

PECallFunction::PECallFunction(perm_string n, const svector<PExpr*>&parms)
: path_(pn_from_ps(n)), parms_(vector_from_svector(parms))
{
}

PECallFunction::~PECallFunction()
{
}
Expand Down
11 changes: 8 additions & 3 deletions PExpr.h
Expand Up @@ -697,10 +697,15 @@ class PETernary : public PExpr {
*/
class PECallFunction : public PExpr {
public:
explicit PECallFunction(const pform_name_t&n, const svector<PExpr *> &parms);
explicit PECallFunction(const pform_name_t&n, const vector<PExpr *> &parms);
// Call of system function (name is not hierarchical)
explicit PECallFunction(perm_string n, const svector<PExpr *> &parms);
explicit PECallFunction(perm_string n, const vector<PExpr *> &parms);
explicit PECallFunction(perm_string n);

// svector versions. Should be removed!
explicit PECallFunction(const pform_name_t&n, const svector<PExpr *> &parms);
explicit PECallFunction(perm_string n, const svector<PExpr *> &parms);

~PECallFunction();

virtual void dump(ostream &) const;
Expand All @@ -721,7 +726,7 @@ class PECallFunction : public PExpr {

private:
pform_name_t path_;
svector<PExpr *> parms_;
vector<PExpr *> parms_;

bool check_call_matches_definition_(Design*des, NetScope*dscope) const;

Expand Down
12 changes: 6 additions & 6 deletions elab_expr.cc
Expand Up @@ -449,7 +449,7 @@ NetExpr* PECallFunction::elaborate_sfunc_(Design*des, NetScope*scope, int expr_w
and makes it into a signed expression. No bits are changed,
it just changes the interpretation. */
if (strcmp(peek_tail_name(path_), "$signed") == 0) {
if ((parms_.count() != 1) || (parms_[0] == 0)) {
if ((parms_.size() != 1) || (parms_[0] == 0)) {
cerr << get_fileline() << ": error: The $signed() function "
<< "takes exactly one(1) argument." << endl;
des->errors += 1;
Expand All @@ -463,7 +463,7 @@ NetExpr* PECallFunction::elaborate_sfunc_(Design*des, NetScope*scope, int expr_w
}
/* add $unsigned to match $signed */
if (strcmp(peek_tail_name(path_), "$unsigned") == 0) {
if ((parms_.count() != 1) || (parms_[0] == 0)) {
if ((parms_.size() != 1) || (parms_[0] == 0)) {
cerr << get_fileline() << ": error: The $unsigned() function "
<< "takes exactly one(1) argument." << endl;
des->errors += 1;
Expand All @@ -486,7 +486,7 @@ NetExpr* PECallFunction::elaborate_sfunc_(Design*des, NetScope*scope, int expr_w
deleted. */
if ((strcmp(peek_tail_name(path_), "$sizeof") == 0)
|| (strcmp(peek_tail_name(path_), "$bits") == 0)) {
if ((parms_.count() != 1) || (parms_[0] == 0)) {
if ((parms_.size() != 1) || (parms_[0] == 0)) {
cerr << get_fileline() << ": error: The $bits() function "
<< "takes exactly one(1) argument." << endl;
des->errors += 1;
Expand Down Expand Up @@ -522,7 +522,7 @@ NetExpr* PECallFunction::elaborate_sfunc_(Design*des, NetScope*scope, int expr_w
otherwise. The subexpression is elaborated but not
evaluated. */
if (strcmp(peek_tail_name(path_), "$is_signed") == 0) {
if ((parms_.count() != 1) || (parms_[0] == 0)) {
if ((parms_.size() != 1) || (parms_[0] == 0)) {
cerr << get_fileline() << ": error: The $is_signed() function "
<< "takes exactly one(1) argument." << endl;
des->errors += 1;
Expand Down Expand Up @@ -558,7 +558,7 @@ NetExpr* PECallFunction::elaborate_sfunc_(Design*des, NetScope*scope, int expr_w
Functions cannot really take empty parameters, but the
case ``func()'' is the same as no parameters at all. So
catch that special case here. */
unsigned nparms = parms_.count();
unsigned nparms = parms_.size();
if ((nparms == 1) && (parms_[0] == 0))
nparms = 0;

Expand Down Expand Up @@ -622,7 +622,7 @@ NetExpr* PECallFunction::elaborate_expr(Design*des, NetScope*scope,
if (! check_call_matches_definition_(des, dscope))
return 0;

unsigned parms_count = parms_.count();
unsigned parms_count = parms_.size();
if ((parms_count == 1) && (parms_[0] == 0))
parms_count = 0;

Expand Down
8 changes: 4 additions & 4 deletions elab_net.cc
Expand Up @@ -1466,7 +1466,7 @@ NetNet* PECallFunction::elaborate_net_sfunc_(Design*des, NetScope*scope,
forces it to be a signed result. Otherwise, it is as if the
$signed did not exist. */
if (strcmp(name, "$signed") == 0) {
if ((parms_.count() != 1) || (parms_[0] == 0)) {
if ((parms_.size() != 1) || (parms_[0] == 0)) {
cerr << get_fileline() << ": error: The $signed() function "
<< "takes exactly one(1) argument." << endl;
des->errors += 1;
Expand All @@ -1482,7 +1482,7 @@ NetNet* PECallFunction::elaborate_net_sfunc_(Design*des, NetScope*scope,

/* handle $unsigned like $signed */
if (strcmp(name, "$unsigned") == 0) {
if ((parms_.count() != 1) || (parms_[0] == 0)) {
if ((parms_.size() != 1) || (parms_[0] == 0)) {
cerr << get_fileline() << ": error: The $unsigned() function "
<< "takes exactly one(1) argument." << endl;
des->errors += 1;
Expand Down Expand Up @@ -1514,7 +1514,7 @@ NetNet* PECallFunction::elaborate_net_sfunc_(Design*des, NetScope*scope,
}

NetSysFunc*net = new NetSysFunc(scope, scope->local_symbol(),
def, 1+parms_.count());
def, 1+parms_.size());
net->set_line(*this);
net->rise_time(rise);
net->fall_time(fall);
Expand All @@ -1531,7 +1531,7 @@ NetNet* PECallFunction::elaborate_net_sfunc_(Design*des, NetScope*scope,
connect(net->pin(0), osig->pin(0));

unsigned errors = 0;
for (unsigned idx = 0 ; idx < parms_.count() ; idx += 1) {
for (unsigned idx = 0 ; idx < parms_.size() ; idx += 1) {
NetNet*tmp = parms_[idx]->elaborate_net(des, scope, 0,
0, 0, 0,
Link::STRONG, Link::STRONG);
Expand Down
2 changes: 1 addition & 1 deletion net_func.cc
Expand Up @@ -104,7 +104,7 @@ bool PECallFunction::check_call_matches_definition_(Design*des, NetScope*dscope)
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();
unsigned parms_count = parms_.size();
if ((parms_count == 1) && (parms_[0] == 0))
parms_count = 0;

Expand Down
5 changes: 4 additions & 1 deletion parse.y
Expand Up @@ -283,6 +283,7 @@ static PECallFunction*make_call_function(perm_string tn, PExpr*arg1, PExpr*arg2)
%type <pform_name> hierarchy_identifier
%type <expr> expression expr_primary expr_mintypmax
%type <expr> lpvalue
%type <expr> branch_probe_expression
%type <expr> delay_value delay_value_simple
%type <exprs> delay1 delay3 delay3_opt delay_value_list
%type <exprs> expression_list_with_nuls expression_list_proper
Expand Down Expand Up @@ -854,7 +855,9 @@ event_expression
function name really is a nature attribute identifier. */
branch_probe_expression
: IDENTIFIER '(' IDENTIFIER ',' IDENTIFIER ')'
{ $$ = pform_make_branch_probe_expression(@1, $1, $3, $5); }
| IDENTIFIER '(' IDENTIFIER ')'
{ $$ = pform_make_branch_probe_expression(@1, $1, $3); }
;

expression
Expand Down Expand Up @@ -3728,7 +3731,7 @@ statement_or_null

analog_statement
: branch_probe_expression K_CONTRIBUTE expression ';'
{ $$ = pform_contribution_statement(@2); }
{ $$ = pform_contribution_statement(@2, $1, $3); }
;

/* Task items are, other than the statement, task port items and
Expand Down
8 changes: 7 additions & 1 deletion pform.h
Expand Up @@ -396,6 +396,12 @@ extern void pform_dump(ostream&out, const discipline_t*);
extern void pform_make_analog_behavior(const struct vlltype&loc,
AProcess::Type type, AStatement*st);

extern AStatement*pform_contribution_statement(const struct vlltype&loc);
extern AStatement*pform_contribution_statement(const struct vlltype&loc,
PExpr*lval, PExpr*rval);

extern PExpr* pform_make_branch_probe_expression(const struct vlltype&loc,
char*name, char*n1, char*n2);

extern PExpr* pform_make_branch_probe_expression(const struct vlltype&loc,
char*name, char*branch);
#endif
33 changes: 31 additions & 2 deletions pform_analog.cc
Expand Up @@ -23,9 +23,10 @@
# include "parse_misc.h"
# include "AStatement.h"

AStatement* pform_contribution_statement(const struct vlltype&loc)
AStatement* pform_contribution_statement(const struct vlltype&loc,
PExpr*lval, PExpr*rval)
{
AContrib*tmp = new AContrib;
AContrib*tmp = new AContrib(lval, rval);
FILE_NAME(tmp, loc);
return tmp;
}
Expand All @@ -38,3 +39,31 @@ void pform_make_analog_behavior(const struct vlltype&loc, AProcess::Type pt,

pform_put_behavior_in_scope(proc);
}

PExpr* pform_make_branch_probe_expression(const struct vlltype&loc,
char*name, char*n1, char*n2)
{
vector<PExpr*> parms (2);
parms[0] = new PEIdent(lex_strings.make(n1));
FILE_NAME(parms[0], loc);

parms[1] = new PEIdent(lex_strings.make(n2));
FILE_NAME(parms[1], loc);

PECallFunction*res = new PECallFunction(lex_strings.make(name), parms);
FILE_NAME(res, loc);
return res;
}

PExpr* pform_make_branch_probe_expression(const struct vlltype&loc,
char*name, char*branch_name)
{
vector<PExpr*> parms (1);
parms[0] = new PEIdent(lex_strings.make(branch_name));
FILE_NAME(parms[0], loc);

PECallFunction*res = new PECallFunction(lex_strings.make(name), parms);
FILE_NAME(res, loc);

return res;
}
12 changes: 10 additions & 2 deletions pform_dump.cc
Expand Up @@ -180,9 +180,9 @@ void PECallFunction::dump(ostream &out) const
{
out << path_ << "(";

if (parms_.count() > 0) {
if (parms_.size() > 0) {
if (parms_[0]) parms_[0]->dump(out);
for (unsigned idx = 1; idx < parms_.count(); ++idx) {
for (unsigned idx = 1; idx < parms_.size(); ++idx) {
out << ", ";
if (parms_[idx]) parms_[idx]->dump(out);
}
Expand Down Expand Up @@ -541,6 +541,14 @@ void AStatement::dump(ostream&out, unsigned ind) const
<< " */ ;" << endl;
}

void AContrib::dump(ostream&out, unsigned ind) const
{
out << setw(ind) << "";
out << *lval_ << " <+ " << *rval_
<< "; /* " << get_fileline() << " */"
<< endl;
}

void PAssign::dump(ostream&out, unsigned ind) const
{
out << setw(ind) << "";
Expand Down

0 comments on commit 25a27f9

Please sign in to comment.