source: src/Parser/StatementNode.cc@ 1d4580a

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

more refactoring of parser code

  • Property mode set to 100644
File size: 17.0 KB
Line 
1//
2// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
3//
4// The contents of this file are covered under the licence agreement in the
5// file "LICENCE" distributed with Cforall.
6//
7// StatementNode.cc --
8//
9// Author : Rodolfo G. Esteves
10// Created On : Sat May 16 14:59:41 2015
11// Last Modified By : Peter A. Buhr
12// Last Modified On : Sun Aug 14 08:09:31 2016
13// Update Count : 271
14//
15
16#include <list>
17#include <algorithm>
18#include <cassert>
19
20#include "ParseNode.h"
21#include "SynTree/Statement.h"
22#include "SynTree/Expression.h"
23#include "parseutility.h"
24#include "Common/utility.h"
25
26using namespace std;
27
28const char *StatementNode::StType[] = {
29 "Exp", "If", "Switch", "Case", "Default", "Choose", "Fallthru",
30 "While", "Do", "For",
31 "Goto", "Continue", "Break", "Return", "Throw",
32 "Try", "Catch", "Finally", "Asm",
33 "Decl"
34};
35
36StatementNode::StatementNode() : ParseNode(), control( 0 ), block( 0 ), labels( 0 ), target( 0 ), decl( 0 ), catchAny( false ) {}
37
38StatementNode::StatementNode( const string *name ) : ParseNode( name ), control( 0 ), block( 0 ), labels( 0 ), target( 0 ), decl( 0 ), catchAny( false ) { assert( false ); }
39
40StatementNode::StatementNode( DeclarationNode *decl ) : type( Decl ), control( 0 ), block( 0 ), labels( 0 ), target( 0 ), catchAny( false ) {
41 assert( false );
42 if ( decl ) {
43 if ( DeclarationNode *agg = decl->extractAggregate() ) {
44 this->decl = agg;
45 StatementNode *nextStmt = new StatementNode;
46 nextStmt->type = Decl;
47 nextStmt->decl = decl;
48 next = nextStmt;
49 if ( decl->get_next() ) {
50 next->set_next( new StatementNode( dynamic_cast<DeclarationNode *>( decl->get_next() ) ) );
51 decl->set_next( 0 );
52 } // if
53 } else {
54 if ( decl->get_next() ) {
55 next = new StatementNode( dynamic_cast<DeclarationNode *>( decl->get_next() ) );
56 decl->set_next( 0 );
57 } // if
58 this->decl = decl;
59 } // if
60 } // if
61}
62
63StatementNode2::StatementNode2( DeclarationNode *decl ) {
64 if ( decl ) {
65 DeclarationNode *agg = decl->extractAggregate();
66 if ( agg ) {
67 StatementNode *nextStmt = new StatementNode;
68 nextStmt->type = Decl;
69 nextStmt->decl = decl;
70 next = nextStmt;
71 if ( decl->get_next() ) {
72 next->set_next( new StatementNode2( dynamic_cast<DeclarationNode *>(decl->get_next()) ) );
73 decl->set_next( 0 );
74 } // if
75 } else {
76 if ( decl->get_next() ) {
77 next = new StatementNode2( dynamic_cast<DeclarationNode *>( decl->get_next() ) );
78 decl->set_next( 0 );
79 } // if
80 agg = decl;
81 } // if
82 stmt = new DeclStmt( noLabels, maybeBuild<Declaration>(agg) );
83 } else {
84 assert( false );
85 } // if
86}
87
88StatementNode::StatementNode( Type t, ExpressionNode *ctrl_label, StatementNode *block ) : type( t ), control( ctrl_label ), block( block ), labels( 0 ), target( 0 ), decl( 0 ), catchAny( false ) {
89 this->control = ( t == Default ) ? 0 : control;
90}
91
92StatementNode::StatementNode( Type t, string *target ) : type( t ), control( 0 ), block( 0 ), labels( 0 ), target( target ), decl( 0 ), catchAny( false ) {}
93
94StatementNode::~StatementNode() {
95 delete control;
96 delete block;
97 delete target;
98 delete decl;
99}
100
101StatementNode * StatementNode::clone() const {
102 assert( false );
103 StatementNode *newnode = new StatementNode( type, maybeClone( control ), maybeClone( block ) );
104 if ( target ) {
105 newnode->target = new string( *target );
106 } else {
107 newnode->target = 0;
108 } // if
109 newnode->decl = maybeClone( decl );
110 return newnode;
111}
112
113StatementNode *StatementNode::add_label( const std::string *l ) {
114 if ( l != 0 ) {
115 labels.push_front( *l );
116 delete l;
117 } // if
118 return this;
119}
120
121StatementNode *StatementNode::append_block( StatementNode *stmt ) {
122 if ( stmt != 0 ) {
123 if ( block == 0 )
124 block = stmt;
125 else
126 block->set_last( stmt );
127 } // if
128 return this;
129}
130
131StatementNode *StatementNode::append_last_case( StatementNode *stmt ) {
132 assert( false );
133 if ( stmt != 0 ) {
134 StatementNode *next = ( StatementNode *)get_next();
135 if ( next && ( next->get_type() == StatementNode::Case || next->get_type() == StatementNode::Default ) )
136 next->append_last_case( stmt );
137 else
138 if ( block == 0 )
139 block = stmt;
140 else
141 block->set_last( stmt );
142 } // if
143 return this;
144}
145
146StatementNode *StatementNode2::append_last_case( StatementNode *stmt ) {
147 StatementNode *prev = this;
148 // find end of list and maintain previous pointer
149 for ( StatementNode * curr = prev; curr != nullptr; curr = (StatementNode *)curr->get_next() ) {
150 StatementNode2 *node = dynamic_cast<StatementNode2 *>(curr);
151 assert( node );
152 assert( dynamic_cast<CaseStmt *>(node->stmt) );
153 prev = curr;
154 } // for
155 // conver from StatementNode list to Statement list
156 StatementNode2 *node = dynamic_cast<StatementNode2 *>(prev);
157 std::list<Statement *> stmts;
158 buildList( stmt, stmts );
159 // splice any new Statements to end of currents Statements
160 CaseStmt * caseStmt = dynamic_cast<CaseStmt *>(node->stmt);
161 caseStmt->get_statements().splice( caseStmt->get_statements().end(), stmts );
162 return this;
163}
164
165void StatementNode::print( std::ostream &os, int indent ) const {
166 if ( ! labels.empty() ) {
167 std::list<std::string>::const_iterator i;
168
169 os << string( indent, ' ' );
170 for ( i = labels.begin(); i != labels.end(); i++ )
171 os << *i << ":";
172 os << endl;
173 } // if
174
175 switch ( type ) {
176 case Decl:
177 decl->print( os, indent );
178 break;
179 case Exp:
180 if ( control ) {
181 os << string( indent, ' ' );
182 control->print( os, indent );
183 os << endl;
184 } else
185 os << string( indent, ' ' ) << "Null Statement" << endl;
186 break;
187 default:
188 os << string( indent, ' ' ) << StatementNode::StType[type] << endl;
189 if ( type == Catch ) {
190 if ( decl ) {
191 os << string( indent + ParseNode::indent_by, ' ' ) << "Declaration: " << endl;
192 decl->print( os, indent + 2 * ParseNode::indent_by );
193 } else if ( catchAny ) {
194 os << string( indent + ParseNode::indent_by, ' ' ) << "Catches the rest " << endl;
195 } else {
196 ; // should never reach here
197 } // if
198 } // if
199 if ( control ) {
200 os << string( indent + ParseNode::indent_by, ' ' ) << "Control: " << endl;
201 control->printList( os, indent + 2 * ParseNode::indent_by );
202 } // if
203 if ( block ) {
204 os << string( indent + ParseNode::indent_by, ' ' ) << "Cases: " << endl;
205 block->printList( os, indent + 2 * ParseNode::indent_by );
206 } // if
207 break;
208 } // switch
209}
210
211Statement *StatementNode::build() const {
212 std::list<Statement *> branches;
213 std::list<Expression *> exps;
214 std::list<Label> labs;
215
216 if ( ! labels.empty() ) {
217 std::back_insert_iterator< std::list<Label> > lab_it( labs );
218 copy( labels.begin(), labels.end(), lab_it );
219 } // if
220
221 buildList<Statement, StatementNode>( get_block(), branches );
222
223 switch ( type ) {
224 case Decl:
225 return new DeclStmt( labs, maybeBuild< Declaration >( decl ) );
226 assert( false );
227 case Exp:
228 // {
229 // Expression *e = maybeBuild< Expression >( get_control() );
230
231 // if ( e )
232 // return new ExprStmt( labs, e );
233 // else
234 // return new NullStmt( labs );
235 // }
236 assert( false );
237 case If:
238 // {
239 // Statement *thenb = 0, *elseb = 0;
240 // assert( branches.size() >= 1 );
241
242 // thenb = branches.front();
243 // branches.pop_front();
244 // if ( ! branches.empty() ) {
245 // elseb = branches.front();
246 // branches.pop_front();
247 // } // if
248 // return new IfStmt( labs, notZeroExpr( maybeBuild<Expression>(get_control()) ), thenb, elseb );
249 // }
250 assert( false );
251 case Switch:
252 // return new SwitchStmt( labs, maybeBuild<Expression>(get_control()), branches );
253 assert( false );
254 case Case:
255 //return new CaseStmt( labs, maybeBuild<Expression>(get_control() ), branches );
256 assert( false );
257 case Default:
258 //return new CaseStmt( labs, 0, branches, true );
259 assert( false );
260 case While:
261 // assert( branches.size() == 1 );
262 // return new WhileStmt( labs, notZeroExpr( maybeBuild<Expression>(get_control()) ), branches.front() );
263 assert( false );
264 case Do:
265 // assert( branches.size() == 1 );
266 // return new WhileStmt( labs, notZeroExpr( maybeBuild<Expression>(get_control()) ), branches.front(), true );
267 assert( false );
268 case For:
269 // {
270 // assert( branches.size() == 1 );
271
272 // ForCtlExprNode *ctl = dynamic_cast<ForCtlExprNode *>( get_control() );
273 // assert( ctl != 0 );
274
275 // std::list<Statement *> init;
276 // if ( ctl->get_init() != 0 ) {
277 // buildList( ctl->get_init(), init );
278 // } // if
279
280 // Expression *cond = 0;
281 // if ( ctl->get_condition() != 0 )
282 // cond = notZeroExpr( maybeBuild<Expression>(ctl->get_condition()) );
283
284 // Expression *incr = 0;
285 // if ( ctl->get_change() != 0 )
286 // incr = maybeBuild<Expression>(ctl->get_change());
287
288 // return new ForStmt( labs, init, cond, incr, branches.front() );
289 // }
290 assert( false );
291 case Goto:
292 assert( false );
293 case Break:
294 assert( false );
295 case Continue:
296 assert( false );
297 case Return:
298 case Throw :
299 // buildList( get_control(), exps );
300 // if ( exps.size() ==0 )
301 // return new ReturnStmt( labs, 0, type == Throw );
302 // if ( exps.size() > 0 )
303 // return new ReturnStmt( labs, exps.back(), type == Throw );
304 assert( false );
305 case Try:
306 // {
307 // assert( branches.size() >= 0 );
308 // CompoundStmt *tryBlock = dynamic_cast<CompoundStmt *>( branches.front());
309 // branches.pop_front();
310 // FinallyStmt *finallyBlock = 0;
311 // if ( ( finallyBlock = dynamic_cast<FinallyStmt *>( branches.back())) ) {
312 // branches.pop_back();
313 // } // if
314 // return new TryStmt( labs, tryBlock, branches, finallyBlock );
315 // }
316 assert( false );
317 case Catch:
318 // {
319 // assert( branches.size() == 1 );
320
321 // return new CatchStmt( labs, maybeBuild< Declaration >( decl ), branches.front(), catchAny );
322 // }
323 assert( false );
324 case Finally:
325 // {
326 // assert( branches.size() == 1 );
327 // CompoundStmt *block = dynamic_cast<CompoundStmt *>( branches.front() );
328 // assert( block != 0 );
329
330 // return new FinallyStmt( labs, block );
331 // }
332 assert( false );
333 case Asm:
334 assert( false );
335 default:
336 assert( false );
337 return 0;
338 } // switch
339}
340
341Statement *build_expr( ExpressionNode *ctl ) {
342 Expression *e = maybeBuild< Expression >( ctl );
343
344 if ( e )
345 return new ExprStmt( noLabels, e );
346 else
347 return new NullStmt( noLabels );
348}
349
350Statement *build_if( ExpressionNode *ctl, StatementNode *then_stmt, StatementNode *else_stmt ) {
351 Statement *thenb, *elseb = 0;
352 std::list<Statement *> branches;
353 buildList<Statement, StatementNode>( then_stmt, branches );
354 assert( branches.size() == 1 );
355 thenb = branches.front();
356
357 if ( else_stmt ) {
358 std::list<Statement *> branches;
359 buildList<Statement, StatementNode>( else_stmt, branches );
360 assert( branches.size() == 1 );
361 elseb = branches.front();
362 } // if
363 return new IfStmt( noLabels, notZeroExpr( maybeBuild<Expression>(ctl) ), thenb, elseb );
364}
365
366Statement *build_switch( ExpressionNode *ctl, StatementNode *stmt ) {
367 std::list<Statement *> branches;
368 buildList<Statement, StatementNode>( stmt, branches );
369 assert( branches.size() >= 0 ); // size == 0 for switch (...) {}, i.e., no declaration or statements
370 return new SwitchStmt( noLabels, maybeBuild<Expression>(ctl), branches );
371}
372Statement *build_case( ExpressionNode *ctl ) {
373 std::list<Statement *> branches;
374 return new CaseStmt( noLabels, maybeBuild<Expression>(ctl), branches );
375}
376Statement *build_default() {
377 std::list<Statement *> branches;
378 return new CaseStmt( noLabels, nullptr, branches, true );
379}
380
381Statement *build_while( ExpressionNode *ctl, StatementNode *stmt, bool kind ) {
382 std::list<Statement *> branches;
383 buildList<Statement, StatementNode>( stmt, branches );
384 assert( branches.size() == 1 );
385 return new WhileStmt( noLabels, notZeroExpr( maybeBuild<Expression>(ctl) ), branches.front(), kind );
386}
387
388Statement *build_for( ForCtl *forctl, StatementNode *stmt ) {
389 std::list<Statement *> branches;
390 buildList<Statement, StatementNode>( stmt, branches );
391 assert( branches.size() == 1 );
392
393 std::list<Statement *> init;
394 if ( forctl->init != 0 ) {
395 buildList( forctl->init, init );
396 } // if
397
398 Expression *cond = 0;
399 if ( forctl->condition != 0 )
400 cond = notZeroExpr( maybeBuild<Expression>(forctl->condition) );
401
402 Expression *incr = 0;
403 if ( forctl->change != 0 )
404 incr = maybeBuild<Expression>(forctl->change);
405
406 delete forctl;
407 return new ForStmt( noLabels, init, cond, incr, branches.front() );
408}
409
410Statement *build_branch( std::string identifier, BranchStmt::Type kind ) {
411 return new BranchStmt( noLabels, identifier, kind );
412}
413Statement *build_computedgoto( ExpressionNode *ctl ) {
414 return new BranchStmt( noLabels, maybeBuild<Expression>(ctl), BranchStmt::Goto );
415}
416
417Statement *build_return( ExpressionNode *ctl ) {
418 std::list<Expression *> exps;
419 buildList( ctl, exps );
420 return new ReturnStmt( noLabels, exps.size() > 0 ? exps.back() : nullptr );
421}
422Statement *build_throw( ExpressionNode *ctl ) {
423 std::list<Expression *> exps;
424 buildList( ctl, exps );
425 return new ReturnStmt( noLabels, exps.size() > 0 ? exps.back() : nullptr, true );
426}
427
428Statement *build_try( StatementNode *try_stmt, StatementNode *catch_stmt, StatementNode *finally_stmt ) {
429 std::list<Statement *> branches;
430 buildList<Statement, StatementNode>( catch_stmt, branches );
431 CompoundStmt *tryBlock = dynamic_cast<CompoundStmt *>(maybeBuild<Statement>(try_stmt));
432 assert( tryBlock );
433 FinallyStmt *finallyBlock = dynamic_cast<FinallyStmt *>(maybeBuild<Statement>(finally_stmt) );
434 return new TryStmt( noLabels, tryBlock, branches, finallyBlock );
435}
436Statement *build_catch( DeclarationNode *decl, StatementNode *stmt, bool catchAny ) {
437 std::list<Statement *> branches;
438 buildList<Statement, StatementNode>( stmt, branches );
439 assert( branches.size() == 1 );
440 return new CatchStmt( noLabels, maybeBuild<Declaration>(decl), branches.front(), catchAny );
441}
442Statement *build_finally( StatementNode *stmt ) {
443 std::list<Statement *> branches;
444 buildList<Statement, StatementNode>( stmt, branches );
445 assert( branches.size() == 1 );
446 return new FinallyStmt( noLabels, dynamic_cast<CompoundStmt *>( branches.front() ) );
447}
448
449
450CompoundStmtNode::CompoundStmtNode() : first( 0 ), last( 0 ) {}
451
452CompoundStmtNode::CompoundStmtNode( StatementNode *stmt ) : first( stmt ) {
453 if ( first ) {
454 last = ( StatementNode *)( stmt->get_last());
455 } else {
456 last = 0;
457 } // if
458}
459
460CompoundStmtNode::~CompoundStmtNode() {
461 delete first;
462}
463
464void CompoundStmtNode::add_statement( StatementNode *stmt ) {
465 if ( stmt != 0 ) {
466 last->set_last( stmt );
467 last = ( StatementNode *)( stmt->get_next());
468 } // if
469}
470
471void CompoundStmtNode::print( ostream &os, int indent ) const {
472 if ( first ) {
473 first->printList( os, indent+2 );
474 } // if
475}
476
477Statement *CompoundStmtNode::build() const {
478 std::list<Label> labs;
479 const std::list<std::string> &labels = get_labels();
480
481 if ( ! labels.empty() ) {
482 std::back_insert_iterator< std::list<Label> > lab_it( labs );
483 copy( labels.begin(), labels.end(), lab_it );
484 } // if
485
486 CompoundStmt *cs = new CompoundStmt( labs );
487 buildList( first, cs->get_kids() );
488 return cs;
489}
490
491
492AsmStmtNode::AsmStmtNode( Type t, bool voltile, ConstantExpr *instruction, ExpressionNode *output, ExpressionNode *input, ExpressionNode *clobber, LabelNode *gotolabels ) :
493 StatementNode( t ), voltile( voltile ), instruction( instruction ), output( output ), input( input ), clobber( clobber ) {
494 if ( gotolabels ) {
495 this->gotolabels = gotolabels->get_labels();
496 delete gotolabels;
497 } // if
498}
499
500AsmStmtNode::~AsmStmtNode() {
501 delete output; delete input; delete clobber;
502}
503
504void AsmStmtNode::print( std::ostream &os, int indent ) const {
505 StatementNode::print( os, indent ); // print statement labels
506 os << string( indent + ParseNode::indent_by, ' ' ) << "volatile:" << voltile << endl;
507 if ( instruction ) {
508 os << string( indent + ParseNode::indent_by, ' ' ) << "Instruction:" << endl;
509// instruction->printList( os, indent + 2 * ParseNode::indent_by );
510 } // if
511 if ( output ) {
512 os << string( indent + ParseNode::indent_by, ' ' ) << "Output:" << endl;
513 output->printList( os, indent + 2 * ParseNode::indent_by );
514 } // if
515 if ( input ) {
516 os << string( indent + ParseNode::indent_by, ' ' ) << "Input:" << endl;
517 input->printList( os, indent + 2 * ParseNode::indent_by );
518 } // if
519 if ( clobber ) {
520 os << string( indent + ParseNode::indent_by, ' ' ) << "Clobber:" << endl;
521// clobber->printList( os, indent + 2 * ParseNode::indent_by );
522 } // if
523 if ( ! gotolabels.empty() ) {
524 os << string( indent + ParseNode::indent_by, ' ' ) << "Goto Labels:" << endl;
525 os << string( indent + 2 * ParseNode::indent_by, ' ' );
526 for ( std::list<Label>::const_iterator i = gotolabels.begin();; ) {
527 os << *i;
528 i++;
529 if ( i == gotolabels.end() ) break;
530 os << ", ";
531 }
532 os << endl;
533 } // if
534}
535
536Statement *AsmStmtNode::build() const {
537 std::list<Label> labs;
538
539 if ( ! get_labels().empty() ) {
540 std::back_insert_iterator< std::list<Label> > lab_it( labs );
541 copy( get_labels().begin(), get_labels().end(), lab_it );
542 } // if
543
544 std::list< Expression * > out, in;
545 std::list< ConstantExpr * > clob;
546 buildList( output, out );
547 buildList( input, in );
548 buildList( clobber, clob );
549 std::list< Label > gotolabs = gotolabels;
550 return new AsmStmt( labs, voltile, instruction, out, in, clob, gotolabs );
551}
552
553// Local Variables: //
554// tab-width: 4 //
555// mode: c++ //
556// compile-command: "make install" //
557// End: //
Note: See TracBrowser for help on using the repository browser.