source: translator/Parser/ExpressionNode.cc@ fe3b61b

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 fe3b61b was 3848e0e, checked in by Peter A. Buhr <pabuhr@…>, 11 years ago

underscore changes, ptrdiff_t changes, formating, _Bool prelude

  • Property mode set to 100644
File size: 20.0 KB
RevLine 
[51b73452]1#include <cassert>
2#include <cctype>
3#include <algorithm>
4
5#include "ParseNode.h"
6#include "SynTree/Type.h"
7#include "SynTree/Constant.h"
8#include "SynTree/Expression.h"
9#include "SynTree/Declaration.h"
10#include "UnimplementedError.h"
11#include "parseutility.h"
12#include "utility.h"
13
14using namespace std;
15
[3848e0e]16ExpressionNode::ExpressionNode() : ParseNode(), argName( 0 ) {}
[51b73452]17
18ExpressionNode::ExpressionNode(string *name_) : ParseNode( *name_ ), argName( 0 ) {
[3848e0e]19 delete name_;
[51b73452]20}
21
[3848e0e]22ExpressionNode::ExpressionNode( const ExpressionNode &other ) : ParseNode( other.name ) {
23 if ( other.argName ) {
24 argName = other.argName->clone();
25 } else {
26 argName = 0;
27 }
[51b73452]28}
29
30ExpressionNode * ExpressionNode::set_asArgName( std::string *aName ) {
[3848e0e]31 argName = new VarRefNode(aName);
32 return this;
[51b73452]33}
34
35ExpressionNode * ExpressionNode::set_asArgName( ExpressionNode *aDesignator ) {
[3848e0e]36 argName = aDesignator;
37 return this;
[51b73452]38}
39
40void ExpressionNode::printDesignation( std::ostream &os, int indent ) const {
[3848e0e]41 if ( argName ) {
42 os << string(' ', indent) << "(designated by: ";
43 argName->printOneLine(os, indent );
44 os << ")" << std::endl;
45 }
[51b73452]46}
47
[3848e0e]48NullExprNode::NullExprNode() {}
[51b73452]49
[3848e0e]50NullExprNode *NullExprNode::clone() const {
51 return new NullExprNode();
[51b73452]52}
53
[3848e0e]54void NullExprNode::print(std::ostream & os, int indent) const {
55 printDesignation(os);
56 os << "null expression";
[51b73452]57}
58
[3848e0e]59void NullExprNode::printOneLine(std::ostream & os, int indent) const {
60 printDesignation(os);
61 os << "null";
[51b73452]62}
63
[3848e0e]64Expression *NullExprNode::build() const {
65 return 0;
[51b73452]66}
67
68CommaExprNode *ExpressionNode::add_to_list(ExpressionNode *exp){
[3848e0e]69 return new CommaExprNode(this, exp );
[51b73452]70}
71
72// enum ConstantNode::Type = { Integer, Float, Character, String, Range }
73
[3848e0e]74ConstantNode::ConstantNode(void) : ExpressionNode(), sign(true), longs(0), size(0) {}
[51b73452]75
[3848e0e]76ConstantNode::ConstantNode(string *name_) : ExpressionNode(name_), sign(true), longs(0), size(0) {}
[51b73452]77
[3848e0e]78ConstantNode::ConstantNode(Type t, string *inVal) : type(t), sign(true), longs(0), size(0) {
79 if ( inVal ) {
80 value = *inVal;
81 delete inVal;
82 } else {
83 value = "";
84 }
[51b73452]85
[3848e0e]86 classify(value);
[51b73452]87}
88
89ConstantNode::ConstantNode( const ConstantNode &other )
[3848e0e]90 : ExpressionNode( other ), type( other.type ), value( other.value ), sign( other.sign ), base( other.base ), longs( other.longs ), size( other.size ) {
[51b73452]91}
92
93// for some reason, std::tolower doesn't work as an argument to std::transform in g++ 3.1
[3848e0e]94inline char tolower_hack( char c ) {
95 return std::tolower( c );
[51b73452]96}
97
98void ConstantNode::classify(std::string &str){
[3848e0e]99 switch (type){
100 case Integer:
101 case Float:
102 {
103 std::string sfx("");
104 char c;
105 int i = str.length() - 1;
[51b73452]106
[3848e0e]107 while ( i >= 0 && !isxdigit(c = str.at(i--)) )
108 sfx += c;
[51b73452]109
[3848e0e]110 value = str.substr( 0, i + 2 );
[51b73452]111
[3848e0e]112 // get rid of underscores
113 value.erase(remove(value.begin(), value.end(), '_'), value.end());
[51b73452]114
[3848e0e]115 std::transform(sfx.begin(), sfx.end(), sfx.begin(), tolower_hack);
[51b73452]116
[3848e0e]117 if ( sfx.find("ll") != string::npos ){
118 longs = 2;
119 } else if (sfx.find("l") != string::npos ){
120 longs = 1;
121 }
[51b73452]122
[3848e0e]123 assert((longs >= 0) && (longs <= 2));
[51b73452]124
[3848e0e]125 if ( sfx.find("u") != string::npos )
126 sign = false;
[51b73452]127
[3848e0e]128 break;
129 }
130 case Character:
131 {
132 // remove underscores from hex and oct escapes
133 if (str.substr(1,2) == "\\x")
134 value.erase(remove(value.begin(), value.end(), '_'), value.end());
[51b73452]135
[3848e0e]136 break;
137 }
138 default:
139 // shouldn't be here
140 ;
141 }
[51b73452]142}
143
144ConstantNode::Type ConstantNode::get_type(void) const {
[3848e0e]145 return type;
[51b73452]146}
147
[3848e0e]148ConstantNode *ConstantNode::append( std::string *newValue ) {
149 if ( newValue ) {
150 if (type == String){
151 std::string temp = *newValue;
152 value.resize( value.size() - 1 );
153 value += newValue->substr(1, newValue->size());
154 } else
155 value += *newValue;
[51b73452]156
[3848e0e]157 delete newValue;
158 }
159 return this;
[51b73452]160}
161
[3848e0e]162void ConstantNode::printOneLine(std::ostream &os, int indent ) const {
163 os << string(indent, ' ');
164 printDesignation(os);
[51b73452]165
[3848e0e]166 switch ( type ) {
167 /* integers */
168 case Integer:
169 os << value ;
170 break;
171 case Float:
172 os << value ;
173 break;
[51b73452]174
[3848e0e]175 case Character:
176 os << "'" << value << "'";
177 break;
[51b73452]178
[3848e0e]179 case String:
180 os << '"' << value << '"';
181 break;
182 }
[51b73452]183
[3848e0e]184 os << ' ';
[51b73452]185}
186
[3848e0e]187void ConstantNode::print(std::ostream &os, int indent ) const {
188 printOneLine( os, indent );
189 os << endl;
[51b73452]190}
191
192Expression *ConstantNode::build() const {
[3848e0e]193 ::Type::Qualifiers q;
194 BasicType *bt;
195
196 switch (get_type()){
197 case Integer:
198 /* Cfr. standard 6.4.4.1 */
199 //bt.set_kind(BasicType::SignedInt);
200 bt = new BasicType(q, BasicType::SignedInt);
201 break;
202 case Float:
203 bt = new BasicType(q, BasicType::Float);
204 break;
205 case Character:
206 bt = new BasicType(q, BasicType::Char);
207 break;
208 case String:
209 // string should probably be a primitive type
210 ArrayType *at;
211 std::string value = get_value();
212 at = new ArrayType(q, new BasicType(q, BasicType::Char),
213 new ConstantExpr( Constant( new BasicType(q, BasicType::SignedInt),
214 toString( value.size() - 1 ) ) ), // account for '\0'
215 false, false );
216 return new ConstantExpr( Constant(at, value), maybeBuild< Expression >( get_argName() ) );
217 }
218 return new ConstantExpr( Constant(bt, get_value()), maybeBuild< Expression >( get_argName() ) );
[51b73452]219}
220
221VarRefNode::VarRefNode() : isLabel(false) {}
222
[3848e0e]223VarRefNode::VarRefNode(string *name_, bool labelp) : ExpressionNode(name_), isLabel(labelp) {}
[51b73452]224
[3848e0e]225VarRefNode::VarRefNode( const VarRefNode &other ) : ExpressionNode( other ), isLabel( other.isLabel ) {
[51b73452]226}
227
228Expression *VarRefNode::build() const {
[3848e0e]229 return new NameExpr( get_name(), maybeBuild< Expression >( get_argName() ) );
[51b73452]230}
231
232void VarRefNode::printOneLine(std::ostream &os, int indent ) const {
[3848e0e]233 printDesignation(os);
234 os << get_name() << ' ';
[51b73452]235}
236
237void VarRefNode::print(std::ostream &os, int indent ) const {
[3848e0e]238 printDesignation(os);
239 os << '\r' << string(indent, ' ') << "Referencing: ";
240 os << "Variable: " << get_name();
241 os << endl;
[51b73452]242}
243
[3848e0e]244OperatorNode::OperatorNode(Type t) : type(t) {}
[51b73452]245
[3848e0e]246OperatorNode::OperatorNode( const OperatorNode &other ) : ExpressionNode( other ), type( other.type ) {
[51b73452]247}
248
249OperatorNode::~OperatorNode() {}
250
251OperatorNode::Type OperatorNode::get_type(void) const{
[3848e0e]252 return type;
[51b73452]253}
254
[3848e0e]255void OperatorNode::printOneLine( std::ostream &os, int indent ) const {
256 printDesignation(os);
257 os << OpName[ type ] << ' ';
[51b73452]258}
259
260void OperatorNode::print( std::ostream &os, int indent ) const{
[3848e0e]261 printDesignation(os);
262 os << '\r' << string(indent, ' ') << "Operator: " << OpName[type] << endl;
263 return;
[51b73452]264}
265
266std::string OperatorNode::get_typename(void) const{
[3848e0e]267 return string(OpName[ type ]);
[51b73452]268}
269
[3848e0e]270const char *OperatorNode::OpName[] = {
271 "TupleC", "Comma", "TupleFieldSel",// "TuplePFieldSel", //n-adic
[51b73452]272 // triadic
273 "Cond", "NCond",
274 // diadic
275 "SizeOf", "AlignOf", "Attr", "CompLit", "Plus", "Minus", "Mul", "Div", "Mod", "Or",
[3848e0e]276 "And", "BitOr", "BitAnd", "Xor", "Cast", "LShift", "RShift", "LThan", "GThan",
277 "LEThan", "GEThan", "Eq", "Neq", "Assign", "MulAssn", "DivAssn", "ModAssn", "PlusAssn",
278 "MinusAssn", "LSAssn", "RSAssn", "AndAssn", "ERAssn", "OrAssn", "Index", "FieldSel","PFieldSel",
279 "Range",
[51b73452]280 // monadic
281 "UnPlus", "UnMinus", "AddressOf", "PointTo", "Neg", "BitNeg", "Incr", "IncrPost", "Decr", "DecrPost", "LabelAddress"
[3848e0e]282};
[51b73452]283
284CompositeExprNode::CompositeExprNode(void) : ExpressionNode(), function( 0 ), arguments( 0 ) {
285}
286
[3848e0e]287CompositeExprNode::CompositeExprNode(string *name_) : ExpressionNode(name_), function( 0 ), arguments( 0 ) {
[51b73452]288}
289
290CompositeExprNode::CompositeExprNode(ExpressionNode *f, ExpressionNode *args):
[3848e0e]291 function(f), arguments(args) {
[51b73452]292}
293
294CompositeExprNode::CompositeExprNode(ExpressionNode *f, ExpressionNode *arg1, ExpressionNode *arg2):
[3848e0e]295 function(f), arguments(arg1) {
296 arguments->set_link(arg2);
[51b73452]297}
298
[3848e0e]299CompositeExprNode::CompositeExprNode( const CompositeExprNode &other ) : ExpressionNode( other ), function( maybeClone( other.function ) ) {
300 ParseNode *cur = other.arguments;
301 while ( cur ) {
302 if ( arguments ) {
303 arguments->set_link( cur->clone() );
304 } else {
305 arguments = (ExpressionNode*)cur->clone();
306 }
307 cur = cur->get_link();
[51b73452]308 }
309}
310
[3848e0e]311CompositeExprNode::~CompositeExprNode() {
312 delete function;
313 delete arguments;
[51b73452]314}
315
316// the names that users use to define operator functions
[3848e0e]317static const char *opFuncName[] = {
318 "", "", "",
[51b73452]319 "", "",
320 // diadic
321 "", "", "", "", "?+?", "?-?", "?*?", "?/?", "?%?", "", "",
[3848e0e]322 "?|?", "?&?", "?^?", "", "?<<?", "?>>?", "?<?", "?>?", "?<=?",
323 "?>=?", "?==?", "?!=?", "?=?", "?*=?", "?/=?", "?%=?", "?+=?", "?-=?",
324 "?<<=?", "?>>=?", "?&=?", "?^=?", "?|=?", "?[?]", "","","Range",
[51b73452]325 // monadic
326 "+?", "-?", "", "*?", "!?", "~?", "++?", "?++", "--?", "?--", "LabAddress"
[3848e0e]327};
[51b73452]328
329#include "utility.h"
330
[3848e0e]331Expression *CompositeExprNode::build() const {
332 OperatorNode *op;
333 std::list<Expression *> args;
[51b73452]334
[3848e0e]335 buildList(get_args(), args);
[51b73452]336
[3848e0e]337 if ( ! ( op = dynamic_cast<OperatorNode *>(function)) ) {
338 // a function as opposed to an operator
339 return new UntypedExpr(function->build(), args, maybeBuild< Expression >( get_argName() ));
340 } else {
341 switch (op->get_type()){
342 case OperatorNode::Incr:
343 case OperatorNode::Decr:
344 case OperatorNode::IncrPost:
345 case OperatorNode::DecrPost:
346 case OperatorNode::Assign:
347 case OperatorNode::MulAssn:
348 case OperatorNode::DivAssn:
349 case OperatorNode::ModAssn:
350 case OperatorNode::PlusAssn:
351 case OperatorNode::MinusAssn:
352 case OperatorNode::LSAssn:
353 case OperatorNode::RSAssn:
354 case OperatorNode::AndAssn:
355 case OperatorNode::ERAssn:
356 case OperatorNode::OrAssn:
357 // the rewrite rules for these expressions specify that the first argument has its address taken
358 assert( !args.empty() );
359 args.front() = new AddressExpr( args.front() );
360 break;
361 default:
362 /* do nothing */
363 ;
364 }
[51b73452]365
[3848e0e]366 switch ( op->get_type() ) {
367 case OperatorNode::Incr:
368 case OperatorNode::Decr:
369 case OperatorNode::IncrPost:
370 case OperatorNode::DecrPost:
371 case OperatorNode::Assign:
372 case OperatorNode::MulAssn:
373 case OperatorNode::DivAssn:
374 case OperatorNode::ModAssn:
375 case OperatorNode::PlusAssn:
376 case OperatorNode::MinusAssn:
377 case OperatorNode::LSAssn:
378 case OperatorNode::RSAssn:
379 case OperatorNode::AndAssn:
380 case OperatorNode::ERAssn:
381 case OperatorNode::OrAssn:
382 case OperatorNode::Plus:
383 case OperatorNode::Minus:
384 case OperatorNode::Mul:
385 case OperatorNode::Div:
386 case OperatorNode::Mod:
387 case OperatorNode::BitOr:
388 case OperatorNode::BitAnd:
389 case OperatorNode::Xor:
390 case OperatorNode::LShift:
391 case OperatorNode::RShift:
392 case OperatorNode::LThan:
393 case OperatorNode::GThan:
394 case OperatorNode::LEThan:
395 case OperatorNode::GEThan:
396 case OperatorNode::Eq:
397 case OperatorNode::Neq:
398 case OperatorNode::Index:
399 case OperatorNode::Range:
400 case OperatorNode::UnPlus:
401 case OperatorNode::UnMinus:
402 case OperatorNode::PointTo:
403 case OperatorNode::Neg:
404 case OperatorNode::BitNeg:
405 case OperatorNode::LabelAddress:
406 return new UntypedExpr( new NameExpr( opFuncName[ op->get_type() ] ), args );
407 case OperatorNode::AddressOf:
408 assert( args.size() == 1 );
409 assert( args.front() );
410
411 return new AddressExpr( args.front() );
412 case OperatorNode::Cast:
413 {
414 TypeValueNode * arg = dynamic_cast<TypeValueNode *>(get_args());
415 assert( arg );
416
417 DeclarationNode *decl_node = arg->get_decl();
418 ExpressionNode *expr_node = dynamic_cast<ExpressionNode *>(arg->get_link());
419
420 Type *targetType = decl_node->buildType();
421 if ( dynamic_cast< VoidType* >( targetType ) ) {
422 delete targetType;
423 return new CastExpr( expr_node->build(), maybeBuild< Expression >( get_argName() ) );
424 } else {
425 return new CastExpr(expr_node->build(),targetType, maybeBuild< Expression >( get_argName() ) );
426 }
427 }
428 case OperatorNode::FieldSel:
429 {
430 assert( args.size() == 2 );
431
432 NameExpr *member = dynamic_cast<NameExpr *>(args.back());
433 // TupleExpr *memberTup = dynamic_cast<TupleExpr *>(args.back());
434
435 if ( member != 0 )
436 {
437 UntypedMemberExpr *ret = new UntypedMemberExpr(member->get_name(), args.front());
438 delete member;
439 return ret;
440 }
441 /* else if ( memberTup != 0 )
442 {
443 UntypedMemberExpr *ret = new UntypedMemberExpr(memberTup->get_name(), args.front());
444 delete member;
445 return ret;
446 } */
447 else
448 assert( false );
449 }
450 case OperatorNode::PFieldSel:
451 {
452 assert( args.size() == 2 );
453
454 NameExpr *member = dynamic_cast<NameExpr *>(args.back()); // modify for Tuples xxx
455 assert( member != 0 );
456
457 UntypedExpr *deref = new UntypedExpr( new NameExpr( "*?" ) );
458 deref->get_args().push_back( args.front() );
459
460 UntypedMemberExpr *ret = new UntypedMemberExpr(member->get_name(), deref);
461 delete member;
462 return ret;
463 }
464 case OperatorNode::AlignOf:
465 case OperatorNode::SizeOf:
466 {
[51b73452]467/// bool isSizeOf = (op->get_type() == OperatorNode::SizeOf);
468
[3848e0e]469 if ( TypeValueNode * arg = dynamic_cast<TypeValueNode *>(get_args()) ) {
470 return new SizeofExpr(arg->get_decl()->buildType());
471 } else {
472 return new SizeofExpr(args.front());
473 }
474 }
475 case OperatorNode::Attr:
476 {
477 VarRefNode *var = dynamic_cast<VarRefNode *>(get_args());
478 assert( var );
479 if ( !get_args()->get_link() ) {
480 return new AttrExpr(var->build(), (Expression*)0);
481 } else if ( TypeValueNode * arg = dynamic_cast<TypeValueNode *>(get_args()->get_link()) ) {
482 return new AttrExpr(var->build(), arg->get_decl()->buildType());
483 } else {
484 return new AttrExpr(var->build(), args.back());
485 }
486 }
487 case OperatorNode::CompLit:
488 throw UnimplementedError( "C99 compound literals" );
489 // the short-circuited operators
490 case OperatorNode::Or:
491 case OperatorNode::And:
492 assert(args.size() == 2);
493 return new LogicalExpr( notZeroExpr( args.front() ), notZeroExpr( args.back() ), (op->get_type() == OperatorNode::And) );
494 case OperatorNode::Cond:
495 {
496 assert(args.size() == 3);
497 std::list< Expression* >::const_iterator i = args.begin();
498 Expression *arg1 = notZeroExpr( *i++ );
499 Expression *arg2 = *i++;
500 Expression *arg3 = *i++;
501 return new ConditionalExpr( arg1, arg2, arg3 );
502 }
503 case OperatorNode::NCond:
504 throw UnimplementedError( "GNU 2-argument conditional expression" );
505 case OperatorNode::Comma:
506 {
507 assert(args.size() == 2);
508 std::list< Expression* >::const_iterator i = args.begin();
509 Expression *ret = *i++;
510 while ( i != args.end() ) {
511 ret = new CommaExpr( ret, *i++ );
512 }
513 return ret;
514 }
515 // Tuples
516 case OperatorNode::TupleC:
517 {
518 TupleExpr *ret = new TupleExpr();
519 std::copy( args.begin(), args.end(), back_inserter( ret->get_exprs() ) );
520 return ret;
521 }
522 default:
523 // shouldn't happen
524 return 0;
525 }
[51b73452]526 }
527}
528
[3848e0e]529void CompositeExprNode::printOneLine(std::ostream &os, int indent) const {
530 printDesignation(os);
531 os << "( ";
532 function->printOneLine( os, indent );
533 for( ExpressionNode *cur = arguments; cur != 0; cur = dynamic_cast< ExpressionNode* >( cur->get_link() ) ) {
534 cur->printOneLine( os, indent );
535 }
536 os << ") ";
[51b73452]537}
538
[3848e0e]539void CompositeExprNode::print(std::ostream &os, int indent) const {
540 printDesignation(os);
541 os << '\r' << string(indent, ' ') << "Application of: " << endl;
542 function->print( os, indent + ParseNode::indent_by );
[51b73452]543
[3848e0e]544 os << '\r' << string(indent, ' ') ;
545 if ( arguments ) {
546 os << "... on arguments: " << endl;
547 arguments->printList(os, indent + ParseNode::indent_by);
548 } else
549 os << "... on no arguments: " << endl;
[51b73452]550}
551
552void CompositeExprNode::set_function(ExpressionNode *f){
[3848e0e]553 function = f;
[51b73452]554}
555
556void CompositeExprNode::set_args(ExpressionNode *args){
[3848e0e]557 arguments = args;
[51b73452]558}
559
560ExpressionNode *CompositeExprNode::get_function(void) const {
[3848e0e]561 return function;
[51b73452]562}
563
564ExpressionNode *CompositeExprNode::get_args(void) const {
[3848e0e]565 return arguments;
[51b73452]566}
567
568void CompositeExprNode::add_arg(ExpressionNode *arg){
[3848e0e]569 if (arguments)
570 arguments->set_link(arg);
571 else
572 set_args(arg);
[51b73452]573}
574
575CommaExprNode::CommaExprNode(): CompositeExprNode(new OperatorNode(OperatorNode::Comma)) {}
576
[3848e0e]577CommaExprNode::CommaExprNode(ExpressionNode *exp) : CompositeExprNode( new OperatorNode(OperatorNode::Comma), exp ) {
578}
[51b73452]579
[3848e0e]580CommaExprNode::CommaExprNode(ExpressionNode *exp1, ExpressionNode *exp2) : CompositeExprNode(new OperatorNode(OperatorNode::Comma), exp1, exp2) {
[51b73452]581}
582
583CommaExprNode *CommaExprNode::add_to_list(ExpressionNode *exp){
[3848e0e]584 add_arg(exp);
[51b73452]585
[3848e0e]586 return this;
[51b73452]587}
588
[3848e0e]589CommaExprNode::CommaExprNode( const CommaExprNode &other ) : CompositeExprNode( other ) {
[51b73452]590}
591
592ValofExprNode::ValofExprNode(StatementNode *s): body(s) {}
593
[3848e0e]594ValofExprNode::ValofExprNode( const ValofExprNode &other ) : ExpressionNode( other ), body( maybeClone( body ) ) {
[51b73452]595}
596
597ValofExprNode::~ValofExprNode() {
[3848e0e]598 delete body;
[51b73452]599}
600
601void ValofExprNode::print( std::ostream &os, int indent ) const {
[3848e0e]602 printDesignation(os);
603 os << string(indent, ' ') << "Valof Expression:" << std::endl;
604 get_body()->print(os, indent + 4);
[51b73452]605}
606
[3848e0e]607void ValofExprNode::printOneLine( std::ostream &, int indent ) const {
608 assert( false );
[51b73452]609}
610
611Expression *ValofExprNode::build() const {
[3848e0e]612 return new UntypedValofExpr ( get_body()->build(), maybeBuild< Expression >( get_argName() ) );
613}
614
615ForCtlExprNode::ForCtlExprNode(ParseNode *init_, ExpressionNode *cond, ExpressionNode *incr) throw (SemanticError) : condition(cond), change(incr) {
616 if ( init_ == 0 )
617 init = 0;
618 else {
619 DeclarationNode *decl;
620 ExpressionNode *exp;
621
622 if ((decl = dynamic_cast<DeclarationNode *>(init_)) != 0)
623 init = new StatementNode(decl);
624 else if ((exp = dynamic_cast<ExpressionNode *>(init_)) != 0)
625 init = new StatementNode(StatementNode::Exp, exp);
626 else
627 throw SemanticError("Error in for control expression");
628 }
[51b73452]629}
630
631ForCtlExprNode::ForCtlExprNode( const ForCtlExprNode &other )
[3848e0e]632 : ExpressionNode( other ), init( maybeClone( other.init ) ), condition( maybeClone( other.condition ) ), change( maybeClone( other.change ) ) {
[51b73452]633}
634
635ForCtlExprNode::~ForCtlExprNode(){
[3848e0e]636 delete init;
637 delete condition;
638 delete change;
[51b73452]639}
640
641Expression *ForCtlExprNode::build() const {
[3848e0e]642 // this shouldn't be used!
643 assert( false );
644 return 0;
[51b73452]645}
646
647void ForCtlExprNode::print( std::ostream &os, int indent ) const{
[3848e0e]648 os << string(indent,' ') << "For Control Expression -- : " << endl;
[51b73452]649
[3848e0e]650 os << "\r" << string(indent + 2,' ') << "initialization: ";
651 if (init != 0)
652 init->print(os, indent + 4);
[51b73452]653
[3848e0e]654 os << "\n\r" << string(indent + 2,' ') << "condition: ";
655 if (condition != 0)
656 condition->print(os, indent + 4);
657 os << "\n\r" << string(indent + 2,' ') << "increment: ";
658 if (change != 0)
659 change->print(os, indent + 4);
[51b73452]660}
661
[3848e0e]662void ForCtlExprNode::printOneLine( std::ostream &, int indent ) const {
663 assert( false );
[51b73452]664}
665
666TypeValueNode::TypeValueNode(DeclarationNode *decl)
[3848e0e]667 : decl( decl ) {
[51b73452]668}
669
670TypeValueNode::TypeValueNode( const TypeValueNode &other )
[3848e0e]671 : ExpressionNode( other ), decl( maybeClone( other.decl ) ) {
[51b73452]672}
673
[3848e0e]674Expression *TypeValueNode::build() const {
675 return new TypeExpr( decl->buildType() );
[51b73452]676}
677
[3848e0e]678void TypeValueNode::print(std::ostream &os, int indent) const {
679 os << std::string( indent, ' ' ) << "Type:";
680 get_decl()->print(os, indent + 2);
[51b73452]681}
682
[3848e0e]683void TypeValueNode::printOneLine(std::ostream &os, int indent) const {
684 os << "Type:";
685 get_decl()->print(os, indent + 2);
[51b73452]686}
687
[3848e0e]688ExpressionNode *flattenCommas( ExpressionNode *list ) {
689 if ( CompositeExprNode *composite = dynamic_cast< CompositeExprNode * >( list ) )
690 {
691 OperatorNode *op;
692 if ( (op = dynamic_cast< OperatorNode * >( composite->get_function() )) && (op->get_type() == OperatorNode::Comma) )
693 {
694 if ( ExpressionNode *next = dynamic_cast< ExpressionNode * >( list->get_link() ) )
695 composite->add_arg( next );
696 return flattenCommas( composite->get_args() );
697 }
698 }
[51b73452]699
[3848e0e]700 if ( ExpressionNode *next = dynamic_cast< ExpressionNode * >( list->get_link() ) )
701 list->set_next( flattenCommas( next ) );
[51b73452]702
[3848e0e]703 return list;
[51b73452]704}
705
[3848e0e]706ExpressionNode *tupleContents( ExpressionNode *tuple ) {
707 if ( CompositeExprNode *composite = dynamic_cast< CompositeExprNode * >( tuple ) ) {
708 OperatorNode *op = 0;
709 if ( (op = dynamic_cast< OperatorNode * >( composite->get_function() )) && (op->get_type() == OperatorNode::TupleC) )
710 return composite->get_args();
711 }
712 return tuple;
[51b73452]713}
Note: See TracBrowser for help on using the repository browser.