Elaborate darray new element initializer to ivl_target API

This commit is contained in:
Stephen Williams 2013-10-13 17:54:39 -07:00
parent 96813f76c1
commit 3945b9df45
9 changed files with 68 additions and 13 deletions

View File

@ -1562,7 +1562,14 @@ void NetENetenum::dump(ostream&o) const
void NetENew::dump(ostream&o) const
{
o << "new <type>";
o << "new <type> [";
if (size_) size_->dump(o);
o << "]";
if (init_val_) {
o << "(";
init_val_->dump(o);
o << ")";
}
}
void NetENull::dump(ostream&o) const

View File

@ -4618,16 +4618,27 @@ NetExpr* PENewArray::elaborate_expr(Design*des, NetScope*scope,
width_mode_t mode = LOSSLESS;
unsigned use_wid = size_->test_width(des, scope, mode);
NetExpr*size = size_->elaborate_expr(des, scope, use_wid, flags);
NetExpr*init_val = 0;
NetENew*tmp = new NetENew(ntype, size);
tmp->set_line(*this);
if (dynamic_cast<PEAssignPattern*> (init_)) {
// Special case: the initial value expression is an
// array_pattern. Elaborate the expresion like the
// r-value to an assignment to array.
init_val = init_->elaborate_expr(des, scope, ntype, flags);
if (init_) {
cerr << get_fileline() << ": sorry: Dynamic array initialization expressions "
<< "not supported yet." << endl;
des->errors += 1;
} else if (init_) {
// Regular case: The initial value is an
// expression. Elaborate the expression as an element
// type. The run-time will assign this value to each element.
const netarray_t*array_type = dynamic_cast<const netarray_t*> (ntype);
ivl_type_t elem_type = array_type->element_type();
init_val = init_->elaborate_expr(des, scope, elem_type, flags);
}
NetENew*tmp = new NetENew(ntype, size, init_val);
tmp->set_line(*this);
return tmp;
}

View File

@ -828,6 +828,16 @@ extern unsigned ivl_event_lineno(ivl_event_t net);
* table. That number can be passed to ivl_type_prop_*() functions to
* get details about the property.
*
* - IVL_EX_NEW
* This expression takes one or two operands. The first operand,
* returned by ivl_expr_oper1() is the number of elements to create
* for the dynamic array. The second operand, if present, is returned
* by the ivl_expr_oper2() function. If this returns a non-nil
* expression, it is the initial value to be written to the elements
* of the array. If the expression is an IVL_EX_ARRAY_PATTERN, then
* this is the very special case of a list of values to be written to
* array elements.
*
* - IVL_EX_SELECT
* This expression takes two operands, oper1 is the expression to
* select from, and oper2 is the selection base. The ivl_expr_width
@ -896,9 +906,9 @@ extern const char* ivl_expr_name(ivl_expr_t net);
extern ivl_nature_t ivl_expr_nature(ivl_expr_t net);
/* IVL_EX_BINARY IVL_EX_UNARY */
extern char ivl_expr_opcode(ivl_expr_t net);
/* IVL_EX_BINARY IVL_EX_UNARY, IVL_EX_MEMORY IVL_EX_TERNARY */
/* IVL_EX_BINARY IVL_EX_UNARY, IVL_EX_MEMORY IVL_EX_NEW IVL_EX_TERNARY */
extern ivl_expr_t ivl_expr_oper1(ivl_expr_t net);
/* IVL_EX_BINARY IVL_EX_TERNARY */
/* IVL_EX_BINARY IVL_EX_NEW IVL_EX_TERNARY */
extern ivl_expr_t ivl_expr_oper2(ivl_expr_t net);
/* IVL_EX_TERNARY */
extern ivl_expr_t ivl_expr_oper3(ivl_expr_t net);

View File

@ -336,12 +336,12 @@ const netenum_t* NetENetenum::netenum() const
}
NetENew::NetENew(ivl_type_t t)
: obj_type_(t), size_(0)
: obj_type_(t), size_(0), init_val_(0)
{
}
NetENew::NetENew(ivl_type_t t, NetExpr*size)
: obj_type_(t), size_(size)
NetENew::NetENew(ivl_type_t t, NetExpr*size, NetExpr*init_val)
: obj_type_(t), size_(size), init_val_(init_val)
{
}

View File

@ -4030,11 +4030,12 @@ class NetENew : public NetExpr {
// Make class object
explicit NetENew(ivl_type_t);
// dynamic array of objects.
explicit NetENew(ivl_type_t, NetExpr*);
explicit NetENew(ivl_type_t, NetExpr*size, NetExpr* init_val=0);
~NetENew();
inline ivl_type_t get_type() const { return obj_type_; }
inline const NetExpr*size_expr() const { return size_; }
inline const NetExpr*init_expr() const { return init_val_; }
virtual ivl_variable_type_t expr_type() const;
@ -4047,6 +4048,7 @@ class NetENew : public NetExpr {
private:
ivl_type_t obj_type_;
NetExpr*size_;
NetExpr*init_val_;
};
/*

View File

@ -520,6 +520,9 @@ extern "C" ivl_expr_t ivl_expr_oper2(ivl_expr_t net)
case IVL_EX_BINARY:
return net->u_.binary_.rig_;
case IVL_EX_NEW:
return net->u_.new_.init_val;
case IVL_EX_SELECT:
return net->u_.select_.base_;

View File

@ -346,12 +346,20 @@ void dll_target::expr_creal(const NetECReal*net)
void dll_target::expr_new(const NetENew*net)
{
ivl_expr_t size = 0;
ivl_expr_t init_val = 0;
if (net->size_expr()) {
net->size_expr()->expr_scan(this);
size = expr_;
expr_ = 0;
}
if (net->init_expr()) {
net->init_expr()->expr_scan(this);
init_val = expr_;
expr_ = 0;
}
assert(expr_ == 0);
expr_ = (ivl_expr_t)calloc(1, sizeof(struct ivl_expr_s));
expr_->width_ = net->expr_width();
@ -362,6 +370,7 @@ void dll_target::expr_new(const NetENew*net)
expr_->value_ = net->expr_type(); // May be IVL_VT_DARRAY or _CLASS
expr_->net_type= net->get_type();
expr_->u_.new_.size = size;
expr_->u_.new_.init_val = init_val;
}
void dll_target::expr_null(const NetENull*net)

View File

@ -337,6 +337,7 @@ struct ivl_expr_s {
struct {
ivl_expr_t size;
ivl_expr_t init_val;
} new_;
struct {

View File

@ -186,6 +186,12 @@ static void show_new_expression(ivl_expr_t net, unsigned ind)
show_expression(ivl_expr_oper1(net), ind+3);
stub_errors += 1;
}
if (ivl_expr_oper2(net)){
fprintf(out, "%*sERROR: class_new with array element initializer!\n",
ind+3, "");
show_expression(ivl_expr_oper2(net), ind+3);
stub_errors += 1;
}
break;
case IVL_VT_DARRAY:
fprintf(out, "%*snew [] <type>\n", ind, "");
@ -195,6 +201,12 @@ static void show_new_expression(ivl_expr_t net, unsigned ind)
fprintf(out, "%*sERROR: darray_new missing size expression\n",
ind+3, "");
stub_errors += 1;
}
/* The IVL_EX_NEW expression may include an element
initializer. This may be an array pattern or simple
expression. */
if (ivl_expr_oper2(net)) {
show_expression(ivl_expr_oper2(net), ind+3);
}
break;
default: