source: translator/Parser.old/StatementNode.cc @ 42dcae7

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 42dcae7 was 51b7345, checked in by Peter A. Buhr <pabuhr@…>, 10 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.