source: translator/Parser/StatementNode.cc @ 3848e0e

ADTaaron-thesisarm-ehast-experimentalcleanup-dtorsctordeferred_resndemanglerenumforall-pointer-decaygc_noraiijacob/cs343-translationjenkins-sandboxmemorynew-astnew-ast-unique-exprnew-envno_listpersistent-indexerpthread-emulationqualifiedEnumresolv-newstringwith_gc
Last change on this file since 3848e0e was 51b7345, checked in by Peter A. Buhr <pabuhr@…>, 10 years ago

initial commit

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