1 /*
2  * Copyright (c) 2012-2017 Stephen Williams (steve@icarus.com)
3  *
4  *    This source code is free software; you can redistribute it
5  *    and/or modify it in source code form under the terms of the GNU
6  *    General Public License as published by the Free Software
7  *    Foundation; either version 2 of the License, or (at your option)
8  *    any later version.
9  *
10  *    This program is distributed in the hope that it will be useful,
11  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  *    GNU General Public License for more details.
14  *
15  *    You should have received a copy of the GNU General Public License
16  *    along with this program; if not, write to the Free Software
17  *    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18  */
19 
20 # include  "netclass.h"
21 # include  "netlist.h"
22 # include  <iostream>
23 
24 using namespace std;
25 
netclass_t(perm_string name,netclass_t * sup)26 netclass_t::netclass_t(perm_string name, netclass_t*sup)
27 : name_(name), super_(sup), class_scope_(0), definition_scope_(0)
28 {
29 }
30 
~netclass_t()31 netclass_t::~netclass_t()
32 {
33 }
34 
set_property(perm_string pname,property_qualifier_t qual,ivl_type_s * ptype)35 bool netclass_t::set_property(perm_string pname, property_qualifier_t qual, ivl_type_s*ptype)
36 {
37       map<perm_string,size_t>::const_iterator cur;
38       cur = properties_.find(pname);
39       if (cur != properties_.end())
40 	    return false;
41 
42       prop_t tmp;
43       tmp.name = pname;
44       tmp.qual = qual;
45       tmp.type = ptype;
46       tmp.initialized_flag = false;
47       property_table_.push_back(tmp);
48 
49       properties_[pname] = property_table_.size()-1;
50       return true;
51 }
52 
set_class_scope(NetScope * class_scope__)53 void netclass_t::set_class_scope(NetScope*class_scope__)
54 {
55       assert(class_scope_ == 0);
56       class_scope_ = class_scope__;
57 }
58 
set_definition_scope(NetScope * use_definition_scope)59 void netclass_t::set_definition_scope(NetScope*use_definition_scope)
60 {
61       assert(definition_scope_ == 0);
62       definition_scope_ = use_definition_scope;
63 }
64 
base_type() const65 ivl_variable_type_t netclass_t::base_type() const
66 {
67       return IVL_VT_CLASS;
68 }
69 
get_properties(void) const70 size_t netclass_t::get_properties(void) const
71 {
72       size_t res = properties_.size();
73       if (super_) res += super_->get_properties();
74       return res;
75 }
76 
property_idx_from_name(perm_string pname) const77 int netclass_t::property_idx_from_name(perm_string pname) const
78 {
79       map<perm_string,size_t>::const_iterator cur;
80       cur = properties_.find(pname);
81       if (cur == properties_.end()) {
82 	    if (super_)
83 		  return super_->property_idx_from_name(pname);
84 	    else
85 		  return -1;
86       }
87 
88       int pidx = cur->second;
89       if (super_) pidx += super_->get_properties();
90       return pidx;
91 }
92 
get_prop_name(size_t idx) const93 const char*netclass_t::get_prop_name(size_t idx) const
94 {
95       size_t super_size = 0;
96       if (super_) super_size = super_->get_properties();
97 
98       assert(idx < (super_size + property_table_.size()));
99       if (idx < super_size)
100 	    return super_->get_prop_name(idx);
101       else
102 	    return property_table_[idx-super_size].name;
103 }
104 
get_prop_qual(size_t idx) const105 property_qualifier_t netclass_t::get_prop_qual(size_t idx) const
106 {
107       size_t super_size = 0;
108       if (super_) super_size = super_->get_properties();
109 
110       assert(idx < (super_size+property_table_.size()));
111       if (idx < super_size)
112 	    return super_->get_prop_qual(idx);
113       else
114 	    return property_table_[idx-super_size].qual;
115 }
116 
get_prop_type(size_t idx) const117 ivl_type_t netclass_t::get_prop_type(size_t idx) const
118 {
119       size_t super_size = 0;
120       if (super_) super_size = super_->get_properties();
121 
122       assert(idx < (super_size+property_table_.size()));
123       if (idx < super_size)
124 	    return super_->get_prop_type(idx);
125       else
126 	    return property_table_[idx-super_size].type;
127 }
128 
get_prop_initialized(size_t idx) const129 bool netclass_t::get_prop_initialized(size_t idx) const
130 {
131       size_t super_size = 0;
132       if (super_) super_size = super_->get_properties();
133 
134       assert(idx < (super_size+property_table_.size()));
135       if (idx < super_size)
136 	    return super_->get_prop_initialized(idx);
137       else
138 	    return property_table_[idx].initialized_flag;
139 }
140 
set_prop_initialized(size_t idx) const141 void netclass_t::set_prop_initialized(size_t idx) const
142 {
143       size_t super_size = 0;
144       if (super_) super_size = super_->get_properties();
145 
146       assert(idx >= super_size && idx < (super_size+property_table_.size()));
147       idx -= super_size;
148 
149       assert(! property_table_[idx].initialized_flag);
150       property_table_[idx].initialized_flag = true;
151 }
152 
test_for_missing_initializers() const153 bool netclass_t::test_for_missing_initializers() const
154 {
155       for (size_t idx = 0 ; idx < property_table_.size() ; idx += 1) {
156 	    if (property_table_[idx].initialized_flag)
157 		  continue;
158 	    if (property_table_[idx].qual.test_const())
159 		  return true;
160       }
161 
162       return false;
163 }
164 
method_from_name(perm_string name) const165 NetScope*netclass_t::method_from_name(perm_string name) const
166 {
167       NetScope*task = class_scope_->child( hname_t(name) );
168       if ((task == 0) && super_)
169 	    task = super_->method_from_name(name);
170       return task;
171 
172 }
173 
find_static_property(perm_string name) const174 NetNet* netclass_t::find_static_property(perm_string name) const
175 {
176       NetNet*tmp = class_scope_->find_signal(name);
177       return tmp;
178 }
179 
test_scope_is_method(const NetScope * scope) const180 bool netclass_t::test_scope_is_method(const NetScope*scope) const
181 {
182       while (scope && scope != class_scope_) {
183 	    scope = scope->parent();
184       }
185 
186       if (scope == 0)
187 	    return false;
188       else
189 	    return true;
190 }
191