Implement enum first/last/num methods.

This commit is contained in:
Stephen Williams 2010-11-05 19:49:28 -07:00
parent 5506969882
commit d37126bda5
5 changed files with 67 additions and 5 deletions

View File

@ -26,6 +26,7 @@
# include "pform.h" # include "pform.h"
# include "netlist.h" # include "netlist.h"
# include "netenum.h"
# include "discipline.h" # include "discipline.h"
# include "netmisc.h" # include "netmisc.h"
# include "util.h" # include "util.h"
@ -2214,9 +2215,36 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope,
net, par, eve, ex1, ex2); net, par, eve, ex1, ex2);
if (net != 0) { if (net != 0) {
// Special case: The net is an enum, and the
// method name is "num".
netenum_t*netenum = net->enumeration();
if (netenum && method_name == "num") {
NetEConst*tmp = make_const_val(netenum->size());
tmp->set_line(*this);
return tmp;
}
// Special case: The net is an enum, and the
// method name is "first".
if (netenum && method_name == "first") {
netenum_t::iterator item = netenum->first_name();
NetEConstEnum*tmp = new NetEConstEnum(scope, item->first,
netenum, item->second);
tmp->set_line(*this);
return tmp;
}
if (netenum && method_name == "last") {
netenum_t::iterator item = netenum->last_name();
NetEConstEnum*tmp = new NetEConstEnum(scope, item->first,
netenum, item->second);
tmp->set_line(*this);
return tmp;
}
const char*func_name = 0; const char*func_name = 0;
if (method_name == "name") { if (method_name == "name") {
func_name = "$ivl_method$name"; func_name = "$ivl_method$name";
} else { } else {
cerr << get_fileline() << ": error: " cerr << get_fileline() << ": error: "
<< "Unknown method name `" << method_name << "'" << "Unknown method name `" << method_name << "'"

View File

@ -30,16 +30,31 @@ netenum_t::~netenum_t()
bool netenum_t::insert_name(perm_string name, const verinum&val) bool netenum_t::insert_name(perm_string name, const verinum&val)
{ {
names_[name] = verinum(val, msb_-lsb_+1); std::pair<std::map<perm_string,verinum>::iterator, bool> res;
return true;
res = names_map_.insert( make_pair(name,val) );
// Only add the name to the list if it is not there already.
if (res.second) names_.push_back(name);
return res.second;
} }
netenum_t::iterator netenum_t::find_name(perm_string name) const netenum_t::iterator netenum_t::find_name(perm_string name) const
{ {
return names_.find(name); return names_map_.find(name);
} }
netenum_t::iterator netenum_t::end_name() const netenum_t::iterator netenum_t::end_name() const
{ {
return names_.end(); return names_map_.end();
}
netenum_t::iterator netenum_t::first_name() const
{
return names_map_.find(names_.front());
}
netenum_t::iterator netenum_t::last_name() const
{
return names_map_.find(names_.back());
} }

View File

@ -22,6 +22,7 @@
# include "ivl_target.h" # include "ivl_target.h"
# include "verinum.h" # include "verinum.h"
# include "StringHeap.h" # include "StringHeap.h"
# include <list>
# include <map> # include <map>
class netenum_t { class netenum_t {
@ -31,18 +32,27 @@ class netenum_t {
long msb, long lsb); long msb, long lsb);
~netenum_t(); ~netenum_t();
size_t size() const;
bool insert_name(perm_string name, const verinum&val); bool insert_name(perm_string name, const verinum&val);
typedef std::map<perm_string,verinum>::const_iterator iterator; typedef std::map<perm_string,verinum>::const_iterator iterator;
iterator find_name(perm_string name) const; iterator find_name(perm_string name) const;
iterator end_name() const; iterator end_name() const;
// These methods roughly match the .first() and .last() methods.
iterator first_name() const;
iterator last_name() const;
private: private:
ivl_variable_type_t base_type_; ivl_variable_type_t base_type_;
bool signed_flag_; bool signed_flag_;
long msb_, lsb_; long msb_, lsb_;
std::map<perm_string,verinum> names_; std::map<perm_string,verinum> names_map_;
std::list<perm_string> names_;
}; };
inline size_t netenum_t::size() const { return names_.size(); }
#endif #endif

View File

@ -24,6 +24,7 @@
# include "netmisc.h" # include "netmisc.h"
# include "PExpr.h" # include "PExpr.h"
# include "pform_types.h" # include "pform_types.h"
# include "compiler.h"
# include "ivl_assert.h" # include "ivl_assert.h"
NetNet* add_to_net(Design*des, NetNet*sig, long val) NetNet* add_to_net(Design*des, NetNet*sig, long val)
@ -393,6 +394,13 @@ NetEConst* make_const_0(unsigned long wid)
return resx; return resx;
} }
NetEConst* make_const_val(unsigned long value)
{
verinum tmp (value, integer_width);
NetEConst*res = new NetEConst(tmp);
return res;
}
NetNet* make_const_x(Design*des, NetScope*scope, unsigned long wid) NetNet* make_const_x(Design*des, NetScope*scope, unsigned long wid)
{ {
verinum xxx (verinum::Vx, wid); verinum xxx (verinum::Vx, wid);

View File

@ -116,6 +116,7 @@ extern NetNet*sub_net_from(Design*des, NetScope*scope, long val, NetNet*sig);
*/ */
extern NetEConst*make_const_x(unsigned long wid); extern NetEConst*make_const_x(unsigned long wid);
extern NetEConst*make_const_0(unsigned long wid); extern NetEConst*make_const_0(unsigned long wid);
extern NetEConst*make_const_val(unsigned long val);
/* /*
* Make A const net * Make A const net