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 "netlist.h"
# include "netenum.h"
# include "discipline.h"
# include "netmisc.h"
# include "util.h"
@ -2214,9 +2215,36 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope,
net, par, eve, ex1, ex2);
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;
if (method_name == "name") {
func_name = "$ivl_method$name";
} else {
cerr << get_fileline() << ": error: "
<< "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)
{
names_[name] = verinum(val, msb_-lsb_+1);
return true;
std::pair<std::map<perm_string,verinum>::iterator, bool> res;
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
{
return names_.find(name);
return names_map_.find(name);
}
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 "verinum.h"
# include "StringHeap.h"
# include <list>
# include <map>
class netenum_t {
@ -31,18 +32,27 @@ class netenum_t {
long msb, long lsb);
~netenum_t();
size_t size() const;
bool insert_name(perm_string name, const verinum&val);
typedef std::map<perm_string,verinum>::const_iterator iterator;
iterator find_name(perm_string name) const;
iterator end_name() const;
// These methods roughly match the .first() and .last() methods.
iterator first_name() const;
iterator last_name() const;
private:
ivl_variable_type_t base_type_;
bool signed_flag_;
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

View File

@ -24,6 +24,7 @@
# include "netmisc.h"
# include "PExpr.h"
# include "pform_types.h"
# include "compiler.h"
# include "ivl_assert.h"
NetNet* add_to_net(Design*des, NetNet*sig, long val)
@ -393,6 +394,13 @@ NetEConst* make_const_0(unsigned long wid)
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)
{
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_0(unsigned long wid);
extern NetEConst*make_const_val(unsigned long val);
/*
* Make A const net