Type name expressions down to elaboration.

This commit is contained in:
Stephen Williams 2013-12-16 03:49:57 +02:00
parent a3b29dd70b
commit 8a4d769b3d
5 changed files with 82 additions and 9 deletions

View File

@ -540,6 +540,15 @@ bool PETernary::has_aa_term(Design*des, NetScope*scope) const
|| fal_->has_aa_term(des, scope); || fal_->has_aa_term(des, scope);
} }
PETypename::PETypename(data_type_t*dt)
: data_type_(dt)
{
}
PETypename::~PETypename()
{
}
PEUnary::PEUnary(char op, PExpr*ex) PEUnary::PEUnary(char op, PExpr*ex)
: op_(op), expr_(ex) : op_(op), expr_(ex)
{ {

15
PExpr.h
View File

@ -660,6 +660,21 @@ class PEString : public PExpr {
char*text_; char*text_;
}; };
class PETypename : public PExpr {
public:
explicit PETypename(data_type_t*data_type);
~PETypename();
virtual void dump(ostream&) const;
virtual unsigned test_width(Design*des, NetScope*scope,
width_mode_t&mode);
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
ivl_type_t type, unsigned flags) const;
private:
data_type_t*data_type_;
};
class PEUnary : public PExpr { class PEUnary : public PExpr {
public: public:

View File

@ -188,7 +188,7 @@ NetExpr* PExpr::elaborate_expr(Design*des, NetScope*, unsigned, unsigned) const
* supported, can assign to packed arrays and structs, unpacked arrays * supported, can assign to packed arrays and structs, unpacked arrays
* and dynamic arrays. * and dynamic arrays.
*/ */
unsigned PEAssignPattern::test_width(Design*des, NetScope*scope, width_mode_t&mode) unsigned PEAssignPattern::test_width(Design*, NetScope*, width_mode_t&)
{ {
expr_type_ = IVL_VT_DARRAY; expr_type_ = IVL_VT_DARRAY;
expr_width_ = 1; expr_width_ = 1;
@ -1078,10 +1078,14 @@ unsigned PECallFunction::test_width_sfunc_(Design*des, NetScope*scope,
if (expr == 0) if (expr == 0)
return 0; return 0;
// The argument type/width is self-determined and doesn't if (! dynamic_cast<PETypename*>(expr)) {
// affect the result type/width. // The argument type/width is self-determined and doesn't
width_mode_t arg_mode = SIZED; // affect the result type/width. Note that if the
expr->test_width(des, scope, arg_mode); // argument is a type name (a special case) then
// don't bother with this step.
width_mode_t arg_mode = SIZED;
expr->test_width(des, scope, arg_mode);
}
expr_type_ = IVL_VT_BOOL; expr_type_ = IVL_VT_BOOL;
expr_width_ = integer_width; expr_width_ = integer_width;
@ -1393,11 +1397,18 @@ NetExpr* PECallFunction::elaborate_sfunc_(Design*des, NetScope*scope,
PExpr*expr = parms_[0]; PExpr*expr = parms_[0];
verinum val ( (uint64_t)expr->expr_width(), integer_width); if (PETypename*type_expr = dynamic_cast<PETypename*>(expr)) {
NetEConst*sub = new NetEConst(val); cerr << get_fileline() << ": sorry: "
sub->set_line(*this); << "I don't yet support typename argumets to $bits." << endl;
des->errors += 1;
return 0;
} else {
verinum val ( (uint64_t)expr->expr_width(), integer_width);
NetEConst*sub = new NetEConst(val);
sub->set_line(*this);
return cast_to_width_(sub, expr_wid); return cast_to_width_(sub, expr_wid);
}
} }
/* Interpret the internal $is_signed system function to return /* Interpret the internal $is_signed system function to return
@ -5158,6 +5169,31 @@ NetExpr* PETernary::elab_and_eval_alternative_(Design*des, NetScope*scope,
return tmp; return tmp;
} }
/*
* A typename expression is only legal in very narrow cases. This is
* just a placeholder.
*/
unsigned PETypename::test_width(Design*des, NetScope*, width_mode_t&)
{
cerr << get_fileline() << ": error: "
<< "Type names are not valid expressions here." << endl;
des->errors += 1;
expr_type_ = IVL_VT_NO_TYPE;
expr_width_ = 1;
min_width_ = 1;
signed_flag_ = false;
return expr_width_;
}
NetExpr*PETypename::elaborate_expr(Design*des, NetScope*,
ivl_type_t, unsigned) const
{
cerr << get_fileline() << ": error: Type name not a valid expression here." << endl;
des->errors += 1;
return 0;
}
unsigned PEUnary::test_width(Design*des, NetScope*scope, width_mode_t&mode) unsigned PEUnary::test_width(Design*des, NetScope*scope, width_mode_t&mode)
{ {
switch (op_) { switch (op_) {

View File

@ -3097,6 +3097,14 @@ expr_primary
delete[]$1; delete[]$1;
} }
/* There are a few special cases (notably $bits argument) where the
expression may be a type name. Let the elaborator sort this out. */
| TYPE_IDENTIFIER
{ PETypename*tmp = new PETypename($1);
FILE_NAME(tmp,@1);
$$ = tmp;
}
/* The hierarchy_identifier rule matches simple identifiers as well as /* The hierarchy_identifier rule matches simple identifiers as well as
indexed arrays and part selects */ indexed arrays and part selects */

View File

@ -385,6 +385,11 @@ void PETernary::dump(ostream&out) const
out << "(" << *expr_ << ")?(" << *tru_ << "):(" << *fal_ << ")"; out << "(" << *expr_ << ")?(" << *tru_ << "):(" << *fal_ << ")";
} }
void PETypename::dump(ostream&fd) const
{
fd << "<type>";
}
void PEUnary::dump(ostream&out) const void PEUnary::dump(ostream&out) const
{ {
switch (op_) { switch (op_) {