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