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 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 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; width_mode_t mode = LOSSLESS;
unsigned use_wid = size_->test_width(des, scope, mode); unsigned use_wid = size_->test_width(des, scope, mode);
NetExpr*size = size_->elaborate_expr(des, scope, use_wid, flags); NetExpr*size = size_->elaborate_expr(des, scope, use_wid, flags);
NetExpr*init_val = 0;
NetENew*tmp = new NetENew(ntype, size); if (dynamic_cast<PEAssignPattern*> (init_)) {
tmp->set_line(*this); // 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_) { } else if (init_) {
cerr << get_fileline() << ": sorry: Dynamic array initialization expressions " // Regular case: The initial value is an
<< "not supported yet." << endl; // expression. Elaborate the expression as an element
des->errors += 1; // 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; 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 * table. That number can be passed to ivl_type_prop_*() functions to
* get details about the property. * 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 * - IVL_EX_SELECT
* This expression takes two operands, oper1 is the expression to * This expression takes two operands, oper1 is the expression to
* select from, and oper2 is the selection base. The ivl_expr_width * 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); extern ivl_nature_t ivl_expr_nature(ivl_expr_t net);
/* IVL_EX_BINARY IVL_EX_UNARY */ /* IVL_EX_BINARY IVL_EX_UNARY */
extern char ivl_expr_opcode(ivl_expr_t net); 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); 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); extern ivl_expr_t ivl_expr_oper2(ivl_expr_t net);
/* IVL_EX_TERNARY */ /* IVL_EX_TERNARY */
extern ivl_expr_t ivl_expr_oper3(ivl_expr_t net); 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) 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) NetENew::NetENew(ivl_type_t t, NetExpr*size, NetExpr*init_val)
: obj_type_(t), size_(size) : obj_type_(t), size_(size), init_val_(init_val)
{ {
} }

View File

@ -4030,11 +4030,12 @@ class NetENew : public NetExpr {
// Make class object // Make class object
explicit NetENew(ivl_type_t); explicit NetENew(ivl_type_t);
// dynamic array of objects. // dynamic array of objects.
explicit NetENew(ivl_type_t, NetExpr*); explicit NetENew(ivl_type_t, NetExpr*size, NetExpr* init_val=0);
~NetENew(); ~NetENew();
inline ivl_type_t get_type() const { return obj_type_; } inline ivl_type_t get_type() const { return obj_type_; }
inline const NetExpr*size_expr() const { return size_; } 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; virtual ivl_variable_type_t expr_type() const;
@ -4047,6 +4048,7 @@ class NetENew : public NetExpr {
private: private:
ivl_type_t obj_type_; ivl_type_t obj_type_;
NetExpr*size_; 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: case IVL_EX_BINARY:
return net->u_.binary_.rig_; return net->u_.binary_.rig_;
case IVL_EX_NEW:
return net->u_.new_.init_val;
case IVL_EX_SELECT: case IVL_EX_SELECT:
return net->u_.select_.base_; 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) void dll_target::expr_new(const NetENew*net)
{ {
ivl_expr_t size = 0; ivl_expr_t size = 0;
ivl_expr_t init_val = 0;
if (net->size_expr()) { if (net->size_expr()) {
net->size_expr()->expr_scan(this); net->size_expr()->expr_scan(this);
size = expr_; size = expr_;
expr_ = 0; expr_ = 0;
} }
if (net->init_expr()) {
net->init_expr()->expr_scan(this);
init_val = expr_;
expr_ = 0;
}
assert(expr_ == 0); assert(expr_ == 0);
expr_ = (ivl_expr_t)calloc(1, sizeof(struct ivl_expr_s)); expr_ = (ivl_expr_t)calloc(1, sizeof(struct ivl_expr_s));
expr_->width_ = net->expr_width(); 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_->value_ = net->expr_type(); // May be IVL_VT_DARRAY or _CLASS
expr_->net_type= net->get_type(); expr_->net_type= net->get_type();
expr_->u_.new_.size = size; expr_->u_.new_.size = size;
expr_->u_.new_.init_val = init_val;
} }
void dll_target::expr_null(const NetENull*net) void dll_target::expr_null(const NetENull*net)

View File

@ -337,6 +337,7 @@ struct ivl_expr_s {
struct { struct {
ivl_expr_t size; ivl_expr_t size;
ivl_expr_t init_val;
} new_; } new_;
struct { 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); show_expression(ivl_expr_oper1(net), ind+3);
stub_errors += 1; 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; break;
case IVL_VT_DARRAY: case IVL_VT_DARRAY:
fprintf(out, "%*snew [] <type>\n", ind, ""); 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", fprintf(out, "%*sERROR: darray_new missing size expression\n",
ind+3, ""); ind+3, "");
stub_errors += 1; 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; break;
default: default: