source: translator/Parser.old/StatementNode.cc@ c8ffe20b

ADT aaron-thesis arm-eh ast-experimental cleanup-dtors ctor deferred_resn demangler enum forall-pointer-decay gc_noraii jacob/cs343-translation jenkins-sandbox memory new-ast new-ast-unique-expr new-env no_list persistent-indexer pthread-emulation qualifiedEnum resolv-new string with_gc
Last change on this file since c8ffe20b was 51b73452, checked in by Peter A. Buhr <pabuhr@…>, 11 years ago

initial commit

  • Property mode set to 100644
File size: 10.7 KB
Line 
1/* -*- C++ -*- */
2#include <list>
3#include <algorithm>
4
5#include "ParseNode.h"
6#include "SynTree/Statement.h"
7#include "SynTree/Expression.h"
8#include "parseutility.h"
9#include "utility.h"
10
11using namespace std;
12
13const char *StatementNode::StType[] =
14 { "Exp", "If", "Switch", "Case", "Default", "Choose", "Fallthru",
15 "While", "Do", "For",
16 "Goto", "Continue", "Break", "Return", "Throw",
17 "Try", "Catch", "Asm",
18 "Decl"
19 };
20
21/// StatementNode::StatementNode(void) :
22/// ParseNode(), control( 0 ), block( 0 ), labels( 0 ), target( 0 ), decl( 0 ), isCatchRest ( false ) {}
23
24StatementNode::StatementNode( struct token &tok )
25 : ParseNode( *tok->str, tok->filename, tok->lineno ), control( 0 ), block( 0 ), labels( 0 ), target( 0 ), decl( 0 ), isCatchRest ( false )
26{
27}
28
29StatementNode::StatementNode( char *filename, int lineno )
30 : ParseNode( "", filename, lineno ), control( 0 ), block( 0 ), labels( 0 ), target( 0 ), decl( 0 ), isCatchRest ( false )
31{
32}
33
34StatementNode::StatementNode( DeclarationNode *decl )
35 : ParseNode( decl->get_name(), decl->get_filename(), decl->get_lineno() ), type( Decl ), control( 0 ), block( 0 ), labels( 0 ), target( 0 ), isCatchRest ( false )
36{
37 if( decl ) {
38 if( DeclarationNode *agg = decl->extractAggregate() ) {
39 this->decl = agg;
40 StatementNode *nextStmt = new StatementNode;
41 nextStmt->type = Decl;
42 nextStmt->decl = decl;
43 next = nextStmt;
44 if( decl->get_link() ) {
45 next->set_next( new StatementNode( dynamic_cast< DeclarationNode* >( decl->get_link() ) ) );
46 decl->set_next( 0 );
47 }
48 } else {
49 if( decl->get_link() ) {
50 next = new StatementNode( dynamic_cast< DeclarationNode* >( decl->get_link() ) );
51 decl->set_next( 0 );
52 }
53 this->decl = decl;
54 }
55 }
56}
57
58StatementNode::StatementNode(Type t, char *filename, int lineno, ExpressionNode *ctrl_label, StatementNode *block_ )
59 : ParseNode( "", filename, lineno ), type(t), control(ctrl_label), block(block_), labels( 0 ), target( 0 ), decl( 0 ), isCatchRest ( false )
60{
61 if (t == Default)
62 control = 0;
63}
64
65StatementNode::StatementNode(Type t, char *filename, int lineno, string *_target)
66 : ParseNode( "", filename, lineno ), type(t), control(0), block(0), labels( 0 ), target(_target), decl( 0 ), isCatchRest ( false )
67{
68}
69
70StatementNode::~StatementNode(void){
71 delete control;
72 delete block;
73 delete labels;
74 delete target;
75 delete decl;
76}
77
78StatementNode * StatementNode::newCatchStmt( char *filename, int lineno, DeclarationNode *d, StatementNode *s, bool catchRestP ) {
79 StatementNode *ret = new StatementNode( StatementNode::Catch, filename, lineno, 0, s );
80 ret->addDeclaration( d );
81 ret->setCatchRest( catchRestP );
82
83 return ret;
84}
85
86std::string StatementNode::get_target() const{
87 if(target)
88 return *target;
89
90 return string("");
91}
92
93StatementNode *
94StatementNode::clone() const
95{
96 StatementNode *newnode = new StatementNode( type, filename, lineno, maybeClone( control ), maybeClone( block ) );
97 if( target ) {
98 newnode->target = new string( *target );
99 } else {
100 newnode->target = 0;
101 }
102 newnode->decl = maybeClone( decl );
103 return newnode;
104}
105
106void StatementNode::set_control(ExpressionNode *c){
107 control = c;
108}
109
110StatementNode * StatementNode::set_block(StatementNode *b){
111 block = b;
112
113 return this;
114}
115
116ExpressionNode *StatementNode::get_control(void) const {
117 return control;
118}
119
120StatementNode *StatementNode::get_block(void) const {
121 return block;
122}
123
124StatementNode::Type StatementNode::get_type(void) const {
125 return type;
126}
127
128StatementNode *StatementNode::add_label( struct token &l ){
129 if(l.str != 0){
130 if(labels == 0)
131 labels = new std::list<std::string>();
132
133 labels->push_front(*l.str);
134 delete l.str;
135 }
136 lineno = min( lineno, l.lineno );
137
138 return this;
139}
140
141std::list<std::string> *StatementNode::get_labels() const
142{ return labels; }
143
144StatementNode *StatementNode::add_controlexp(ExpressionNode *e){
145
146 if(control && e)
147 control->add_to_list(e); // xxx - check this
148
149 return this;
150}
151
152StatementNode *StatementNode::append_block(StatementNode *stmt){
153 if( stmt != 0)
154 if( block == 0 )
155 block = stmt;
156 else
157 block->set_link(stmt);
158
159 return this;
160}
161
162
163StatementNode *StatementNode::append_last_case(StatementNode *stmt){
164 if( stmt != 0 ) {
165 StatementNode *next = (StatementNode *)get_link();
166 if ( next && next->get_type() == StatementNode::Case )
167 next->append_last_case ( stmt );
168 else
169 if( block == 0 )
170 block = stmt;
171 else
172 block->set_link(stmt);
173 }
174
175 return this;
176}
177
178void StatementNode::print( std::ostream &os, int indent ) const {
179
180 if(labels != 0)
181 if(!labels->empty()){
182 std::list<std::string>::const_iterator i;
183
184 os << '\r' << string(indent, ' ');
185 for( i = labels->begin(); i != labels->end(); i++ )
186 os << *i << ":";
187 os << endl;
188 }
189
190 switch( type ) {
191 case Decl:
192 decl->print( os, indent );
193 break;
194
195 case Exp:
196 if( control ) {
197 os << string( indent, ' ' );
198 control->print( os, indent );
199 os << endl;
200 } else
201 os << string( indent, ' ' ) << "Null Statement" << endl;
202 break;
203
204 default:
205 os << '\r' << string(indent, ' ') << StatementNode::StType[type] << endl;
206
207 if ( type == Catch )
208 if( decl ){
209 os << '\r' << string( indent + ParseNode::indent_by, ' ' ) << "Declaration: " << endl;
210 decl->print( os, indent + 2*ParseNode::indent_by);
211 } else if ( isCatchRest ) {
212 os << '\r' << string( indent + ParseNode::indent_by, ' ' ) << "Catches the rest " << endl;
213 } else {
214 ; // should never reach here
215 }
216
217 if( control ){
218 os << '\r' << string( indent + ParseNode::indent_by, ' ' ) << "Expression: " << endl;
219 control->printList( os, indent + 2*ParseNode::indent_by);
220 }
221
222 if( block ){
223 os << '\r' << string( indent + ParseNode::indent_by, ' ' ) << "Branches of execution: " << endl;
224 block->printList( os, indent + 2*ParseNode::indent_by);
225 }
226
227 if( target ){
228 os << '\r' << string( indent + ParseNode::indent_by, ' ' ) << "Target: " << get_target() << endl;
229 }
230
231 break;
232 }
233}
234
235Statement *StatementNode::build() const {
236
237 std::list<Statement *> branches;
238 std::list<Expression *> exps;
239 std::list<Label> labs;
240
241 if(labels != 0){
242 std::back_insert_iterator< std::list<Label> > lab_it(labs);
243 copy(labels->begin(), labels->end(), lab_it);
244 }
245
246 // try {
247 buildList<Statement, StatementNode>(get_block(), branches);
248
249 switch( type ) {
250 case Decl:
251 return new DeclStmt( labs, maybeBuild< Declaration >( decl ) );
252
253 case Exp:
254 {
255 Expression *e = maybeBuild< Expression >( get_control() );
256
257 if(e)
258 return new ExprStmt( labs, e );
259 else
260 return new NullStmt( labs );
261 }
262
263 case If:
264 {
265 Statement *thenb = 0, *elseb = 0;
266
267 assert( branches.size() >= 1 );
268
269 thenb = branches.front(); branches.pop_front();
270 if(!branches.empty())
271 { elseb = branches.front(); branches.pop_front(); }
272
273 return new IfStmt( labs, notZeroExpr( get_control()->build() ), thenb, elseb);
274 }
275
276 case While:
277 assert(branches.size() == 1);
278 return new WhileStmt( labs, notZeroExpr( get_control()->build() ), branches.front() );
279
280 case Do:
281 assert(branches.size() == 1);
282 return new WhileStmt( labs, notZeroExpr( get_control()->build() ), branches.front(), true );
283
284 case For:
285 {
286 assert(branches.size() == 1);
287
288 ForCtlExprNode *ctl = dynamic_cast<ForCtlExprNode *>(get_control());
289 assert(ctl != 0);
290
291 Statement *stmt = 0;
292 if(ctl->get_init() != 0)
293 stmt = ctl->get_init()->build();
294
295 Expression *cond = 0;
296 if(ctl->get_condition() != 0)
297 cond = notZeroExpr( ctl->get_condition()->build() );
298
299 Expression *incr = 0;
300 if(ctl->get_change() != 0)
301 incr = ctl->get_change()->build();
302
303 return new ForStmt( labs, stmt, cond, incr, branches.front() );
304 }
305
306 case Switch:
307 // try{
308 return new SwitchStmt( labs, get_control()->build(), branches );
309
310 case Choose:
311 return new ChooseStmt( labs, get_control()->build(), branches );
312
313 case Fallthru:
314 return new FallthruStmt( labs );
315
316 case Case:
317 return new CaseStmt( labs, get_control()->build(), branches);
318
319 case Default:
320 return new CaseStmt( labs, 0, branches, true);
321
322 case Goto:
323 {
324 if (get_target() == "") { // computed goto
325 assert( get_control() != 0 );
326 return new BranchStmt( labs, get_control()->build(), BranchStmt::Goto );
327 }
328
329 return new BranchStmt( labs, get_target(), BranchStmt::Goto);
330 }
331
332 case Break:
333 return new BranchStmt( labs, get_target(), BranchStmt::Break);
334
335 case Continue:
336 return new BranchStmt( labs, get_target(), BranchStmt::Continue);
337
338 case Return:
339 case Throw :
340 buildList( get_control(), exps );
341 if( exps.size() ==0 )
342 return new ReturnStmt( labs, 0, type == Throw );
343 if( exps.size() > 0 )
344 return new ReturnStmt( labs, exps.back(), type == Throw );
345
346 case Try:
347 {
348 assert( branches.size() >= 0 );
349 CompoundStmt *tryBlock = dynamic_cast<CompoundStmt *>(branches.front());
350 branches.pop_front();
351 return new TryStmt( labs, tryBlock, branches );
352 }
353
354 case Catch:
355 {
356 assert( branches.size() == 1 );
357
358 return new CatchStmt( labs, maybeBuild< Declaration >( decl ), branches.front(), isCatchRest );
359 }
360
361 default:
362 // shouldn't be here
363 return 0;
364 }
365
366 // shouldn't be here
367}
368
369/// CompoundStmtNode::CompoundStmtNode(void)
370/// : first( 0 ), last( 0 )
371/// {
372/// }
373
374CompoundStmtNode::CompoundStmtNode( struct token &tok )
375 : StatementNode( *tok.str, tok.filename, tok.lineno ), first( 0 ), last( 0 )
376{
377}
378
379CompoundStmtNode::CompoundStmtNode(StatementNode *stmt)
380 : StatementNode( "", stmt->get_filename(), stmt->get_lineno() ), first(stmt)
381{
382 if( first ) {
383 last = (StatementNode *)(stmt->get_last());
384 } else {
385 last = 0;
386 }
387}
388
389CompoundStmtNode::~CompoundStmtNode()
390{
391 delete first;
392}
393
394void CompoundStmtNode::add_statement(StatementNode *stmt) {
395 if(stmt != 0){
396 last->set_link(stmt);
397 last = (StatementNode *)(stmt->get_link());
398 }
399}
400
401void CompoundStmtNode::print(ostream &os, int indent) const {
402 if( first ) {
403 first->printList( os, indent+2 );
404 }
405}
406
407Statement *CompoundStmtNode::build() const {
408
409 std::list<Label> labs;
410 std::list<std::string> *labels = get_labels();
411
412 if(labels != 0){
413 std::back_insert_iterator< std::list<Label> > lab_it(labs);
414 copy(labels->begin(), labels->end(), lab_it);
415 }
416
417 CompoundStmt *cs = new CompoundStmt( labs );
418 buildList( first, cs->get_kids() );
419 return cs;
420}
421
422void NullStmtNode::print(ostream &os, int indent) const {
423 os << "\r" << string(indent, ' ') << "Null Statement:" << endl;
424}
425
426Statement *NullStmtNode::build() const {
427 return new NullStmt;
428}
429
430// Local Variables: //
431// mode: C++ //
432// compile-command: "gmake -f ../Makefile" //
433// End: //
Note: See TracBrowser for help on using the repository browser.