Type name expressions down to elaboration.
This commit is contained in:
parent
a3b29dd70b
commit
8a4d769b3d
9
PExpr.cc
9
PExpr.cc
|
|
@ -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
15
PExpr.h
|
|
@ -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:
|
||||||
|
|
|
||||||
54
elab_expr.cc
54
elab_expr.cc
|
|
@ -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_) {
|
||||||
|
|
|
||||||
8
parse.y
8
parse.y
|
|
@ -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 */
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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_) {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue