SV: merge darray/queue method checks in elab_expr
Combine the nearly identical dynamic-array and queue method blocks in test_width_method_ and elaborate_expr_method_ (including class property paths), keeping queue-only pop_front/pop_back gated on queue type.
This commit is contained in:
parent
afe849249c
commit
f796a59367
212
elab_expr.cc
212
elab_expr.cc
|
|
@ -1872,13 +1872,12 @@ unsigned PECallFunction::test_width_method_(Design*, NetScope*,
|
||||||
perm_string method_name = search_results.path_tail.back().name;
|
perm_string method_name = search_results.path_tail.back().name;
|
||||||
|
|
||||||
// Dynamic array variable without a select expression. The method
|
// Dynamic array variable without a select expression. The method
|
||||||
// applies to the array itself, and not to the object that might be
|
// Dynamic array or queue without a select expression. The method
|
||||||
// indexed from it. So return
|
// applies to the array itself. For example: <scope>.x.size();
|
||||||
// the expr_width for the return value of the queue method. For example:
|
if (search_results.net &&
|
||||||
// <scope>.x.size();
|
(search_results.net->data_type()==IVL_VT_DARRAY ||
|
||||||
// In this example, x is a dynamic array.
|
search_results.net->data_type()==IVL_VT_QUEUE) &&
|
||||||
if (search_results.net && search_results.net->data_type()==IVL_VT_DARRAY
|
search_results.path_head.back().index.empty()) {
|
||||||
&& search_results.path_head.back().index.empty()) {
|
|
||||||
|
|
||||||
const NetNet*net = search_results.net;
|
const NetNet*net = search_results.net;
|
||||||
const netdarray_t*darray = net->darray_type();
|
const netdarray_t*darray = net->darray_type();
|
||||||
|
|
@ -1892,14 +1891,16 @@ unsigned PECallFunction::test_width_method_(Design*, NetScope*,
|
||||||
return expr_width_;
|
return expr_width_;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (method_name == "sum") {
|
if (net->queue_type() &&
|
||||||
expr_type_ = darray->element_base_type();
|
(method_name=="pop_back" || method_name=="pop_front")) {
|
||||||
expr_width_ = darray->element_width();
|
expr_type_ = darray->element_base_type();
|
||||||
min_width_ = expr_width_;
|
expr_width_ = darray->element_width();
|
||||||
signed_flag_ = darray->get_signed();
|
min_width_ = expr_width_;
|
||||||
|
signed_flag_= darray->get_signed();
|
||||||
return expr_width_;
|
return expr_width_;
|
||||||
}
|
}
|
||||||
if (method_name == "product") {
|
|
||||||
|
if (method_name == "sum" || method_name == "product") {
|
||||||
expr_type_ = darray->element_base_type();
|
expr_type_ = darray->element_base_type();
|
||||||
expr_width_ = darray->element_width();
|
expr_width_ = darray->element_width();
|
||||||
min_width_ = expr_width_;
|
min_width_ = expr_width_;
|
||||||
|
|
@ -1936,78 +1937,6 @@ unsigned PECallFunction::test_width_method_(Design*, NetScope*,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Queue variable without a select expression. The method applies to the
|
|
||||||
// queue, and not to the object that might be indexed from it. So return
|
|
||||||
// the expr_width for the return value of the queue method. For example:
|
|
||||||
// <scope>.x.size();
|
|
||||||
// In this example, x is a queue.
|
|
||||||
if (search_results.net && search_results.net->data_type()==IVL_VT_QUEUE &&
|
|
||||||
search_results.path_head.back().index.empty()) {
|
|
||||||
|
|
||||||
const NetNet*net = search_results.net;
|
|
||||||
const netdarray_t*darray = net->darray_type();
|
|
||||||
ivl_assert(*this, darray);
|
|
||||||
|
|
||||||
if (method_name == "size") {
|
|
||||||
expr_type_ = IVL_VT_BOOL;
|
|
||||||
expr_width_ = 32;
|
|
||||||
min_width_ = expr_width_;
|
|
||||||
signed_flag_= true;
|
|
||||||
return expr_width_;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (method_name=="pop_back" || method_name=="pop_front") {
|
|
||||||
expr_type_ = darray->element_base_type();
|
|
||||||
expr_width_ = darray->element_width();
|
|
||||||
min_width_ = expr_width_;
|
|
||||||
signed_flag_= darray->get_signed();
|
|
||||||
return expr_width_;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (method_name == "sum") {
|
|
||||||
expr_type_ = darray->element_base_type();
|
|
||||||
expr_width_ = darray->element_width();
|
|
||||||
min_width_ = expr_width_;
|
|
||||||
signed_flag_ = darray->get_signed();
|
|
||||||
return expr_width_;
|
|
||||||
}
|
|
||||||
if (method_name == "product") {
|
|
||||||
expr_type_ = darray->element_base_type();
|
|
||||||
expr_width_ = darray->element_width();
|
|
||||||
min_width_ = expr_width_;
|
|
||||||
signed_flag_ = darray->get_signed();
|
|
||||||
return expr_width_;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (method_name == "unique" || method_name == "unique_index" ||
|
|
||||||
method_name == "min" || method_name == "max" ||
|
|
||||||
method_name == "find" || method_name == "find_index") {
|
|
||||||
expr_type_ = IVL_VT_QUEUE;
|
|
||||||
expr_width_ = 1;
|
|
||||||
min_width_ = 1;
|
|
||||||
signed_flag_ = false;
|
|
||||||
return expr_width_;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (method_name == "find_first" || method_name == "find_last") {
|
|
||||||
expr_type_ = darray->element_base_type();
|
|
||||||
expr_width_ = darray->element_width();
|
|
||||||
min_width_ = expr_width_;
|
|
||||||
signed_flag_ = darray->get_signed();
|
|
||||||
return expr_width_;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (method_name == "find_first_index" || method_name == "find_last_index") {
|
|
||||||
expr_type_ = IVL_VT_BOOL;
|
|
||||||
expr_width_ = 32;
|
|
||||||
min_width_ = 32;
|
|
||||||
signed_flag_= true;
|
|
||||||
return expr_width_;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Queue variable with a select expression. The type of this expression
|
// Queue variable with a select expression. The type of this expression
|
||||||
// is the type of the object that will interpret the method. For
|
// is the type of the object that will interpret the method. For
|
||||||
// example:
|
// example:
|
||||||
|
|
@ -3882,13 +3811,15 @@ NetExpr* PECallFunction::elaborate_expr_method_(Design*des, NetScope*scope,
|
||||||
int pidx = cls->property_idx_from_name(prop_name);
|
int pidx = cls->property_idx_from_name(prop_name);
|
||||||
if (pidx >= 0) {
|
if (pidx >= 0) {
|
||||||
ivl_type_t ptype = cls->get_prop_type(pidx);
|
ivl_type_t ptype = cls->get_prop_type(pidx);
|
||||||
if (ptype && dynamic_cast<const netqueue_t*>(ptype)) {
|
if (ptype &&
|
||||||
|
(ptype->base_type() == IVL_VT_DARRAY ||
|
||||||
|
ptype->base_type() == IVL_VT_QUEUE)) {
|
||||||
NetEProperty*prop = new NetEProperty(search_results.net, pidx, nullptr);
|
NetEProperty*prop = new NetEProperty(search_results.net, pidx, nullptr);
|
||||||
prop->set_line(*this);
|
prop->set_line(*this);
|
||||||
perm_string method_name = search_results.path_tail.back().name;
|
perm_string method_name = search_results.path_tail.back().name;
|
||||||
|
ivl_type_t element_type = ivl_type_element(ptype);
|
||||||
const netqueue_t*queue = dynamic_cast<const netqueue_t*>(ptype);
|
const netqueue_t*queue = dynamic_cast<const netqueue_t*>(ptype);
|
||||||
ivl_assert(*this, queue);
|
const char* kind = queue ? "queue" : "dynamic array";
|
||||||
ivl_type_t element_type = queue->element_type();
|
|
||||||
if (method_name == "size") {
|
if (method_name == "size") {
|
||||||
if (parms_.size() != 0) {
|
if (parms_.size() != 0) {
|
||||||
cerr << get_fileline() << ": error: size() method "
|
cerr << get_fileline() << ": error: size() method "
|
||||||
|
|
@ -3900,7 +3831,7 @@ NetExpr* PECallFunction::elaborate_expr_method_(Design*des, NetScope*scope,
|
||||||
sys_expr->parm(0, prop);
|
sys_expr->parm(0, prop);
|
||||||
return sys_expr;
|
return sys_expr;
|
||||||
}
|
}
|
||||||
if (method_name == "pop_back") {
|
if (queue && method_name == "pop_back") {
|
||||||
if (parms_.size() != 0) {
|
if (parms_.size() != 0) {
|
||||||
cerr << get_fileline() << ": error: pop_back() method "
|
cerr << get_fileline() << ": error: pop_back() method "
|
||||||
<< "takes no arguments" << endl;
|
<< "takes no arguments" << endl;
|
||||||
|
|
@ -3912,7 +3843,7 @@ NetExpr* PECallFunction::elaborate_expr_method_(Design*des, NetScope*scope,
|
||||||
sys_expr->parm(0, prop);
|
sys_expr->parm(0, prop);
|
||||||
return sys_expr;
|
return sys_expr;
|
||||||
}
|
}
|
||||||
if (method_name == "pop_front") {
|
if (queue && method_name == "pop_front") {
|
||||||
if (parms_.size() != 0) {
|
if (parms_.size() != 0) {
|
||||||
cerr << get_fileline() << ": error: pop_front() method "
|
cerr << get_fileline() << ": error: pop_front() method "
|
||||||
<< "takes no arguments" << endl;
|
<< "takes no arguments" << endl;
|
||||||
|
|
@ -3927,43 +3858,12 @@ NetExpr* PECallFunction::elaborate_expr_method_(Design*des, NetScope*scope,
|
||||||
if (is_array_locator_method(method_name)) {
|
if (is_array_locator_method(method_name)) {
|
||||||
return elab_array_locator_method(des, scope, *this,
|
return elab_array_locator_method(des, scope, *this,
|
||||||
method_name, prop, element_type,
|
method_name, prop, element_type,
|
||||||
static_cast<ivl_type_t>(queue),
|
ptype, parms_, with_expr_, kind);
|
||||||
parms_, with_expr_, "queue");
|
|
||||||
}
|
}
|
||||||
if (is_array_reduction_method(method_name)) {
|
if (is_array_reduction_method(method_name)) {
|
||||||
return elab_array_reduction_method(des, scope, *this,
|
return elab_array_reduction_method(des, scope, *this,
|
||||||
method_name, prop, element_type,
|
method_name, prop, element_type,
|
||||||
parms_, with_expr_, "queue");
|
parms_, with_expr_, kind);
|
||||||
}
|
|
||||||
}
|
|
||||||
if (ptype &&
|
|
||||||
(ptype->base_type() == IVL_VT_DARRAY ||
|
|
||||||
ptype->base_type() == IVL_VT_QUEUE)) {
|
|
||||||
NetEProperty*prop = new NetEProperty(search_results.net, pidx, nullptr);
|
|
||||||
prop->set_line(*this);
|
|
||||||
perm_string method_name = search_results.path_tail.back().name;
|
|
||||||
ivl_type_t element_type = ivl_type_element(ptype);
|
|
||||||
if (method_name == "size") {
|
|
||||||
if (parms_.size() != 0) {
|
|
||||||
cerr << get_fileline() << ": error: size() method "
|
|
||||||
<< "takes no arguments" << endl;
|
|
||||||
des->errors += 1;
|
|
||||||
}
|
|
||||||
NetESFunc*sys_expr = new NetESFunc("$size", &netvector_t::atom2u32, 1);
|
|
||||||
sys_expr->set_line(*this);
|
|
||||||
sys_expr->parm(0, prop);
|
|
||||||
return sys_expr;
|
|
||||||
}
|
|
||||||
if (is_array_locator_method(method_name)) {
|
|
||||||
return elab_array_locator_method(des, scope, *this,
|
|
||||||
method_name, prop, element_type,
|
|
||||||
ptype, parms_, with_expr_,
|
|
||||||
"array");
|
|
||||||
}
|
|
||||||
if (is_array_reduction_method(method_name)) {
|
|
||||||
return elab_array_reduction_method(des, scope, *this,
|
|
||||||
method_name, prop, element_type,
|
|
||||||
parms_, with_expr_, "array");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -4039,12 +3939,12 @@ NetExpr* PECallFunction::elaborate_expr_method_(Design*des, NetScope*scope,
|
||||||
|
|
||||||
ivl_assert(*this, sub_expr);
|
ivl_assert(*this, sub_expr);
|
||||||
|
|
||||||
// Dynamic array methods. This handles the case that the located signal
|
// Dynamic array or queue methods when there is no index.
|
||||||
// is a dynamic array, and there is no index.
|
if (search_results.net &&
|
||||||
if (search_results.net && search_results.net->data_type()==IVL_VT_DARRAY
|
(search_results.net->data_type()==IVL_VT_DARRAY ||
|
||||||
&& search_results.path_head.back().index.size()==0) {
|
search_results.net->data_type()==IVL_VT_QUEUE) &&
|
||||||
|
search_results.path_head.back().index.size()==0) {
|
||||||
|
|
||||||
// Get the method name that we are looking for.
|
|
||||||
perm_string method_name = search_results.path_tail.back().name;
|
perm_string method_name = search_results.path_tail.back().name;
|
||||||
|
|
||||||
if (method_name == "size") {
|
if (method_name == "size") {
|
||||||
|
|
@ -4063,49 +3963,11 @@ NetExpr* PECallFunction::elaborate_expr_method_(Design*des, NetScope*scope,
|
||||||
ivl_assert(*this, dar);
|
ivl_assert(*this, dar);
|
||||||
ivl_type_t element_type = dar->element_type();
|
ivl_type_t element_type = dar->element_type();
|
||||||
const netqueue_t*queue = search_results.net->queue_type();
|
const netqueue_t*queue = search_results.net->queue_type();
|
||||||
ivl_type_t queue_rtype = queue ? static_cast<ivl_type_t>(queue)
|
ivl_type_t value_rtype = queue ? static_cast<ivl_type_t>(queue)
|
||||||
: static_cast<ivl_type_t>(dar);
|
: static_cast<ivl_type_t>(dar);
|
||||||
|
const char* kind = queue ? "queue" : "dynamic array";
|
||||||
|
|
||||||
if (is_array_locator_method(method_name)) {
|
if (queue && method_name == "pop_back") {
|
||||||
return elab_array_locator_method(des, scope, *this, method_name,
|
|
||||||
sub_expr, element_type,
|
|
||||||
queue_rtype, parms_, with_expr_,
|
|
||||||
"dynamic array");
|
|
||||||
}
|
|
||||||
if (is_array_reduction_method(method_name)) {
|
|
||||||
return elab_array_reduction_method(des, scope, *this, method_name,
|
|
||||||
sub_expr, element_type,
|
|
||||||
parms_, with_expr_,
|
|
||||||
"dynamic array");
|
|
||||||
}
|
|
||||||
|
|
||||||
cerr << get_fileline() << ": error: Method " << method_name
|
|
||||||
<< " is not a dynamic array method." << endl;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Queue methods. This handles the case that the located signal is a
|
|
||||||
// QUEUE object, and there is a method.
|
|
||||||
if (search_results.net && search_results.net->data_type()==IVL_VT_QUEUE &&
|
|
||||||
search_results.path_head.back().index.size()==0) {
|
|
||||||
|
|
||||||
// Get the method name that we are looking for.
|
|
||||||
perm_string method_name = search_results.path_tail.back().name;
|
|
||||||
if (method_name == "size") {
|
|
||||||
if (parms_.size() != 0) {
|
|
||||||
cerr << get_fileline() << ": error: size() method "
|
|
||||||
<< "takes no arguments" << endl;
|
|
||||||
des->errors += 1;
|
|
||||||
}
|
|
||||||
NetESFunc*sys_expr = new NetESFunc("$size", &netvector_t::atom2u32, 1);
|
|
||||||
sys_expr->set_line(*this);
|
|
||||||
sys_expr->parm(0, sub_expr);
|
|
||||||
return sys_expr;
|
|
||||||
}
|
|
||||||
|
|
||||||
const netqueue_t*queue = search_results.net->queue_type();
|
|
||||||
ivl_type_t element_type = queue->element_type();
|
|
||||||
if (method_name == "pop_back") {
|
|
||||||
if (parms_.size() != 0) {
|
if (parms_.size() != 0) {
|
||||||
cerr << get_fileline() << ": error: pop_back() method "
|
cerr << get_fileline() << ": error: pop_back() method "
|
||||||
<< "takes no arguments" << endl;
|
<< "takes no arguments" << endl;
|
||||||
|
|
@ -4118,7 +3980,7 @@ NetExpr* PECallFunction::elaborate_expr_method_(Design*des, NetScope*scope,
|
||||||
return sys_expr;
|
return sys_expr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (method_name == "pop_front") {
|
if (queue && method_name == "pop_front") {
|
||||||
if (parms_.size() != 0) {
|
if (parms_.size() != 0) {
|
||||||
cerr << get_fileline() << ": error: pop_front() method "
|
cerr << get_fileline() << ": error: pop_front() method "
|
||||||
<< "takes no arguments" << endl;
|
<< "takes no arguments" << endl;
|
||||||
|
|
@ -4134,17 +3996,17 @@ NetExpr* PECallFunction::elaborate_expr_method_(Design*des, NetScope*scope,
|
||||||
if (is_array_locator_method(method_name)) {
|
if (is_array_locator_method(method_name)) {
|
||||||
return elab_array_locator_method(des, scope, *this, method_name,
|
return elab_array_locator_method(des, scope, *this, method_name,
|
||||||
sub_expr, element_type,
|
sub_expr, element_type,
|
||||||
static_cast<ivl_type_t>(queue),
|
value_rtype, parms_, with_expr_,
|
||||||
parms_, with_expr_, "queue");
|
kind);
|
||||||
}
|
}
|
||||||
if (is_array_reduction_method(method_name)) {
|
if (is_array_reduction_method(method_name)) {
|
||||||
return elab_array_reduction_method(des, scope, *this, method_name,
|
return elab_array_reduction_method(des, scope, *this, method_name,
|
||||||
sub_expr, element_type,
|
sub_expr, element_type,
|
||||||
parms_, with_expr_, "queue");
|
parms_, with_expr_, kind);
|
||||||
}
|
}
|
||||||
|
|
||||||
cerr << get_fileline() << ": error: Method " << method_name
|
cerr << get_fileline() << ": error: Method " << method_name
|
||||||
<< " is not a queue method." << endl;
|
<< " is not a " << kind << " method." << endl;
|
||||||
des->errors += 1;
|
des->errors += 1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue