1 /*
2  * Copyright (c) 2011 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  "sequential.h"
21 # include  "expression.h"
22 # include  <cassert>
23 
24 template<typename T>
visit_stmt_list(std::list<T * > & stmts,SeqStmtVisitor & func)25 inline static void visit_stmt_list(std::list<T*>& stmts, SeqStmtVisitor& func)
26 {
27     for(typename std::list<T*>::iterator it = stmts.begin(); it != stmts.end(); ++it) {
28         (*it)->visit(func);
29     }
30 }
31 
SequentialStmt()32 SequentialStmt::SequentialStmt()
33 {
34 }
35 
~SequentialStmt()36 SequentialStmt::~SequentialStmt()
37 {
38 }
39 
IfSequential(Expression * cond,std::list<SequentialStmt * > * tr,std::list<IfSequential::Elsif * > * el,std::list<SequentialStmt * > * fa)40 IfSequential::IfSequential(Expression*cond, std::list<SequentialStmt*>*tr,
41 			   std::list<IfSequential::Elsif*>*el,
42 			   std::list<SequentialStmt*>*fa)
43 {
44       cond_ = cond;
45       if (tr) if_.splice(if_.end(), *tr);
46       if (el) elsif_.splice(elsif_.end(), *el);
47       if (fa) else_.splice(else_.end(), *fa);
48 }
49 
~IfSequential()50 IfSequential::~IfSequential()
51 {
52       delete cond_;
53       while (if_.size() > 0) {
54 	    SequentialStmt*cur = if_.front();
55 	    if_.pop_front();
56 	    delete cur;
57       }
58       while (elsif_.size() > 0) {
59 	    IfSequential::Elsif*cur = elsif_.front();
60 	    elsif_.pop_front();
61 	    delete cur;
62       }
63       while (else_.size() > 0) {
64 	    SequentialStmt*cur = else_.front();
65 	    else_.pop_front();
66 	    delete cur;
67       }
68 
69 }
70 
extract_true(std::list<SequentialStmt * > & that)71 void IfSequential::extract_true(std::list<SequentialStmt*>&that)
72 {
73       while (! if_.empty()) {
74 	    that.push_back(if_.front());
75 	    if_.pop_front();
76       }
77 }
78 
extract_false(std::list<SequentialStmt * > & that)79 void IfSequential::extract_false(std::list<SequentialStmt*>&that)
80 {
81       while (! else_.empty()) {
82 	    that.push_back(else_.front());
83 	    else_.pop_front();
84       }
85 }
86 
visit(SeqStmtVisitor & func)87 void IfSequential::visit(SeqStmtVisitor& func)
88 {
89     visit_stmt_list(if_, func);
90     visit_stmt_list(elsif_, func);
91     visit_stmt_list(else_, func);
92     func(this);
93 }
94 
Elsif(Expression * cond,std::list<SequentialStmt * > * tr)95 IfSequential::Elsif::Elsif(Expression*cond, std::list<SequentialStmt*>*tr)
96 : cond_(cond)
97 {
98       if (tr) if_.splice(if_.end(), *tr);
99 }
100 
~Elsif()101 IfSequential::Elsif::~Elsif()
102 {
103       delete cond_;
104       while (if_.size() > 0) {
105 	    SequentialStmt*cur = if_.front();
106 	    if_.pop_front();
107 	    delete cur;
108       }
109 }
110 
visit(SeqStmtVisitor & func)111 void IfSequential::Elsif::visit(SeqStmtVisitor& func)
112 {
113     visit_stmt_list(if_, func);
114 }
115 
SignalSeqAssignment(Expression * sig,std::list<Expression * > * wav)116 SignalSeqAssignment::SignalSeqAssignment(Expression*sig, std::list<Expression*>*wav)
117 {
118       lval_ = sig;
119       if (wav) waveform_.splice(waveform_.end(), *wav);
120 }
121 
~SignalSeqAssignment()122 SignalSeqAssignment::~SignalSeqAssignment()
123 {
124       delete lval_;
125 }
126 
CaseSeqStmt(Expression * cond,list<CaseSeqStmt::CaseStmtAlternative * > * ap)127 CaseSeqStmt::CaseSeqStmt(Expression*cond, list<CaseSeqStmt::CaseStmtAlternative*>* ap)
128 : cond_(cond)
129 {
130       if (ap) alt_.splice(alt_.end(), *ap);
131 }
132 
~CaseSeqStmt()133 CaseSeqStmt::~CaseSeqStmt()
134 {
135       delete cond_;
136       while(alt_.size() > 0) {
137 	    CaseSeqStmt::CaseStmtAlternative* cur = alt_.front();
138 	    alt_.pop_front();
139 	    delete cur;
140       }
141 }
142 
visit(SeqStmtVisitor & func)143 void CaseSeqStmt::visit(SeqStmtVisitor& func)
144 {
145     visit_stmt_list(alt_, func);
146     func(this);
147 }
148 
CaseStmtAlternative(std::list<Expression * > * exp,list<SequentialStmt * > * stmts)149 CaseSeqStmt::CaseStmtAlternative::CaseStmtAlternative(std::list<Expression*>*exp,
150         list<SequentialStmt*>*stmts)
151 : exp_(exp)
152 {
153       if (stmts) stmts_.splice(stmts_.end(), *stmts);
154 }
155 
~CaseStmtAlternative()156 CaseSeqStmt::CaseStmtAlternative::~CaseStmtAlternative()
157 {
158       delete exp_;
159       while(stmts_.size() > 0) {
160 	    SequentialStmt* cur = stmts_.front();
161 	    stmts_.pop_front();
162 	    delete cur;
163       }
164 }
165 
visit(SeqStmtVisitor & func)166 void CaseSeqStmt::CaseStmtAlternative::visit(SeqStmtVisitor& func)
167 {
168     visit_stmt_list(stmts_, func);
169 }
170 
ProcedureCall(perm_string name)171 ProcedureCall::ProcedureCall(perm_string name)
172 : name_(name), param_list_(NULL), def_(NULL)
173 {
174 }
175 
ProcedureCall(perm_string name,std::list<named_expr_t * > * param_list)176 ProcedureCall::ProcedureCall(perm_string name, std::list<named_expr_t*>* param_list)
177 : name_(name), param_list_(param_list), def_(NULL)
178 {
179 }
180 
ProcedureCall(perm_string name,std::list<Expression * > * param_list)181 ProcedureCall::ProcedureCall(perm_string name, std::list<Expression*>* param_list)
182 : name_(name), def_(NULL)
183 {
184     param_list_ = new std::list<named_expr_t*>;
185     for(std::list<Expression*>::const_iterator it = param_list->begin();
186             it != param_list->end(); ++it)
187     {
188         param_list_->push_back(new named_expr_t(empty_perm_string, *it));
189     }
190 }
191 
~ProcedureCall()192 ProcedureCall::~ProcedureCall()
193 {
194     if(!param_list_)
195         return;
196 
197     while(param_list_->size() > 0) {
198         named_expr_t* cur = param_list_->front();
199         param_list_->pop_front();
200         delete cur;
201     }
202 
203     delete param_list_;
204 }
205 
ReturnStmt(Expression * val)206 ReturnStmt::ReturnStmt(Expression*val)
207 : val_(val)
208 {
209 }
210 
~ReturnStmt()211 ReturnStmt::~ReturnStmt()
212 {
213       delete val_;
214 }
215 
cast_to(const VType * type)216 void ReturnStmt::cast_to(const VType*type)
217 {
218     assert(val_);
219     val_ = new ExpCast(val_, type);
220 }
221 
LoopStatement(perm_string name,list<SequentialStmt * > * stmts)222 LoopStatement::LoopStatement(perm_string name, list<SequentialStmt*>* stmts)
223 : name_(name)
224 {
225     if (stmts) stmts_.splice(stmts_.end(), *stmts);
226 }
227 
~LoopStatement()228 LoopStatement::~LoopStatement()
229 {
230     while(stmts_.size() > 0) {
231         SequentialStmt* cur = stmts_.front();
232         stmts_.pop_front();
233         delete cur;
234     }
235 }
236 
visit(SeqStmtVisitor & func)237 void LoopStatement::visit(SeqStmtVisitor& func)
238 {
239     visit_stmt_list(stmts_, func);
240     func(this);
241 }
242 
ForLoopStatement(perm_string scope_name,perm_string it,ExpRange * range,list<SequentialStmt * > * stmts)243 ForLoopStatement::ForLoopStatement(perm_string scope_name, perm_string it, ExpRange* range, list<SequentialStmt*>* stmts)
244 : LoopStatement(scope_name, stmts), it_(it), range_(range)
245 {
246 }
247 
~ForLoopStatement()248 ForLoopStatement::~ForLoopStatement()
249 {
250     delete range_;
251 }
252 
VariableSeqAssignment(Expression * lval,Expression * rval)253 VariableSeqAssignment::VariableSeqAssignment(Expression*lval, Expression*rval)
254 : lval_(lval), rval_(rval)
255 {
256 }
257 
~VariableSeqAssignment()258 VariableSeqAssignment::~VariableSeqAssignment()
259 {
260       delete lval_;
261       delete rval_;
262 }
263 
WhileLoopStatement(perm_string lname,Expression * cond,list<SequentialStmt * > * stmts)264 WhileLoopStatement::WhileLoopStatement(perm_string lname, Expression* cond, list<SequentialStmt*>* stmts)
265 : LoopStatement(lname, stmts), cond_(cond)
266 {
267 }
268 
~WhileLoopStatement()269 WhileLoopStatement::~WhileLoopStatement()
270 {
271     delete cond_;
272 }
273 
BasicLoopStatement(perm_string lname,list<SequentialStmt * > * stmts)274 BasicLoopStatement::BasicLoopStatement(perm_string lname, list<SequentialStmt*>* stmts)
275 : LoopStatement(lname, stmts)
276 {
277 }
278 
~BasicLoopStatement()279 BasicLoopStatement::~BasicLoopStatement()
280 {
281 }
282 
ReportStmt(Expression * msg,severity_t sev)283 ReportStmt::ReportStmt(Expression*msg, severity_t sev)
284 : msg_(msg), severity_(sev)
285 {
286     if(sev == ReportStmt::UNSPECIFIED)
287         severity_ = ReportStmt::NOTE;
288 }
289 
AssertStmt(Expression * condition,Expression * msg,ReportStmt::severity_t sev)290 AssertStmt::AssertStmt(Expression*condition, Expression*msg, ReportStmt::severity_t sev)
291 : ReportStmt(msg, sev), cond_(condition)
292 {
293     if(msg == NULL)
294         msg_ = new ExpString(default_msg_);
295 
296     if(sev == ReportStmt::UNSPECIFIED)
297         severity_ = ReportStmt::ERROR;
298 }
299 
300 const char*AssertStmt::default_msg_ = "Assertion violation.";
301 
WaitForStmt(Expression * delay)302 WaitForStmt::WaitForStmt(Expression*delay)
303 : delay_(delay)
304 {
305 }
306 
WaitStmt(wait_type_t typ,Expression * expr)307 WaitStmt::WaitStmt(wait_type_t typ, Expression*expr)
308 : type_(typ), expr_(expr)
309 {
310 }
311