source: src/Parser/ExpressionNode.cc@ 258eb5c9

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 258eb5c9 was 097e2b0, checked in by Peter A. Buhr <pabuhr@…>, 10 years ago

constructor/destructor, more example programs

  • Property mode set to 100644
File size: 26.1 KB
RevLine 
[b87a5ed]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// ExpressionNode.cc --
8//
9// Author : Rodolfo G. Esteves
10// Created On : Sat May 16 13:17:07 2015
[097e2b0]11// Last Modified By : Peter A. Buhr
12// Last Modified On : Mon Oct 5 16:37:24 2015
13// Update Count : 255
[b87a5ed]14//
15
[51b73452]16#include <cassert>
17#include <cctype>
18#include <algorithm>
[59db689]19#include <sstream>
20#include <cstdio>
21#include <climits>
[51b73452]22
23#include "ParseNode.h"
24#include "SynTree/Constant.h"
25#include "SynTree/Expression.h"
26#include "UnimplementedError.h"
27#include "parseutility.h"
28#include "utility.h"
29
30using namespace std;
31
[3848e0e]32ExpressionNode::ExpressionNode() : ParseNode(), argName( 0 ) {}
[51b73452]33
[e869d663]34ExpressionNode::ExpressionNode( const string *name ) : ParseNode( name ), argName( 0 ) {}
[51b73452]35
[3848e0e]36ExpressionNode::ExpressionNode( const ExpressionNode &other ) : ParseNode( other.name ) {
[b87a5ed]37 if ( other.argName ) {
38 argName = other.argName->clone();
39 } else {
40 argName = 0;
41 } // if
[51b73452]42}
43
[7f5566b]44ExpressionNode * ExpressionNode::set_argName( const std::string *aName ) {
[b87a5ed]45 argName = new VarRefNode( aName );
46 return this;
[51b73452]47}
48
[7f5566b]49ExpressionNode * ExpressionNode::set_argName( ExpressionNode *aDesignator ) {
[b87a5ed]50 argName = aDesignator;
51 return this;
[51b73452]52}
53
54void ExpressionNode::printDesignation( std::ostream &os, int indent ) const {
[b87a5ed]55 if ( argName ) {
[59db689]56 os << string( indent, ' ' ) << "(designated by: ";
[b87a5ed]57 argName->printOneLine( os, indent );
58 os << ")" << std::endl;
59 } // if
[51b73452]60}
61
[cd623a4]62//##############################################################################
63
[3848e0e]64NullExprNode::NullExprNode() {}
[51b73452]65
[3848e0e]66NullExprNode *NullExprNode::clone() const {
[b87a5ed]67 return new NullExprNode();
[51b73452]68}
69
[bdd516a]70void NullExprNode::print( std::ostream & os, int indent ) const {
[b87a5ed]71 printDesignation( os );
72 os << "null expression";
[51b73452]73}
74
[bdd516a]75void NullExprNode::printOneLine( std::ostream & os, int indent ) const {
[b87a5ed]76 printDesignation( os );
77 os << "null";
[51b73452]78}
79
[3848e0e]80Expression *NullExprNode::build() const {
[b87a5ed]81 return 0;
[51b73452]82}
83
[a08ba92]84CommaExprNode *ExpressionNode::add_to_list( ExpressionNode *exp ) {
[b87a5ed]85 return new CommaExprNode( this, exp );
[51b73452]86}
87
[cd623a4]88//##############################################################################
89
90static inline bool checkU( char c ) { return c == 'u' || c == 'U'; }
91static inline bool checkL( char c ) { return c == 'l' || c == 'L'; }
92static inline bool checkF( char c ) { return c == 'f' || c == 'F'; }
93static inline bool checkX( char c ) { return c == 'x' || c == 'X'; }
94
[5f2f2d7]95// Difficult to separate extra parts of constants during lexing because actions are not allow in the middle of patterns:
[cd623a4]96//
97// prefix action constant action suffix
98//
99// Alternatively, breaking a pattern using BEGIN does not work if the following pattern can be empty:
100//
101// constant BEGIN CONT ...
102// <CONT>(...)? BEGIN 0 ... // possible empty suffix
103//
104// because the CONT rule is NOT triggered if the pattern is empty. Hence, constants are reparsed here to determine their
105// type.
[51b73452]106
[59db689]107ConstantNode::ConstantNode( Type t, string *inVal ) : type( t ), value( *inVal ) {
[cd623a4]108 // lexing divides constants into 4 kinds
[a08ba92]109 switch ( type ) {
[59db689]110 case Integer:
[b87a5ed]111 {
[59db689]112 static const BasicType::Kind kind[2][3] = {
113 { BasicType::SignedInt, BasicType::LongSignedInt, BasicType::LongLongSignedInt },
114 { BasicType::UnsignedInt, BasicType::LongUnsignedInt, BasicType::LongLongUnsignedInt },
115 };
116 size_t last = value.length() - 1; // last character of constant
117 unsigned long long v; // converted integral value
118 bool dec = true, Unsigned = false; // decimal, unsigned constant
119 int size; // 0 => int, 1 => long, 2 => long long
120
[cd623a4]121 if ( value[0] == '0' ) { // octal constant ?
[59db689]122 dec = false;
[cd623a4]123 if ( last != 0 && checkX( value[1] ) ) { // hex constant ?
[59db689]124 sscanf( (char *)value.c_str(), "%llx", &v );
125 //printf( "%llx %llu\n", v, v );
126 } else {
127 sscanf( (char *)value.c_str(), "%llo", &v );
128 //printf( "%llo %llu\n", v, v );
129 } // if
[cd623a4]130 } else { // decimal constant ?
[5f2f2d7]131 sscanf( (char *)value.c_str(), "%llu", &v );
[59db689]132 //printf( "%llu %llu\n", v, v );
133 } // if
134
135 if ( v <= INT_MAX ) { // signed int
136 size = 0;
[5f2f2d7]137 } else if ( v <= UINT_MAX && ! dec ) { // unsigned int
[59db689]138 size = 0;
[5f2f2d7]139 Unsigned = true; // unsigned
[59db689]140 } else if ( v <= LONG_MAX ) { // signed long int
141 size = 1;
[5f2f2d7]142 } else if ( v <= ULONG_MAX && ( ! dec || LONG_MAX == LLONG_MAX ) ) { // signed long int
[59db689]143 size = 1;
[5f2f2d7]144 Unsigned = true; // unsigned long int
[59db689]145 } else if ( v <= LLONG_MAX ) { // signed long long int
146 size = 2;
[5f2f2d7]147 } else { // unsigned long long int
[59db689]148 size = 2;
[5f2f2d7]149 Unsigned = true; // unsigned long long int
[59db689]150 } // if
[51b73452]151
[cd623a4]152 if ( checkU( value[last] ) ) { // suffix 'u' ?
[59db689]153 Unsigned = true;
[5f2f2d7]154 if ( last > 0 && checkL( value[ last - 1 ] ) ) { // suffix 'l' ?
[59db689]155 size = 1;
[5f2f2d7]156 if ( last > 1 && checkL( value[ last - 2 ] ) ) { // suffix 'll' ?
[59db689]157 size = 2;
158 } // if
159 } // if
[cd623a4]160 } else if ( checkL( value[ last ] ) ) { // suffix 'l' ?
[59db689]161 size = 1;
[5f2f2d7]162 if ( last > 0 && checkL( value[ last - 1 ] ) ) { // suffix 'll' ?
[59db689]163 size = 2;
[5f2f2d7]164 if ( last > 1 && checkU( value[ last - 2 ] ) ) { // suffix 'u' ?
165 Unsigned = true;
166 } // if
167 } else {
168 if ( last > 0 && checkU( value[ last - 1 ] ) ) { // suffix 'u' ?
169 Unsigned = true;
170 } // if
[59db689]171 } // if
172 } // if
[cd623a4]173 btype = kind[Unsigned][size]; // lookup constant type
174 break;
175 }
176 case Float:
177 {
178 size_t len = value.length() - 1;
179
180 btype = BasicType::Double; // default
181 if ( checkF( value[len] ) ) { // float ?
182 btype = BasicType::Float;
183 } // if
184 if ( checkL( value[len] ) ) { // long double ?
185 btype = BasicType::LongDouble;
186 } // if
[b87a5ed]187 break;
188 }
[59db689]189 case Character:
190 btype = BasicType::Char; // default
191 if ( string( "LUu" ).find( value[0] ) != string::npos ) {
192 // ???
193 } // if
194 break;
195 case String:
196 // array of char
197 if ( string( "LUu" ).find( value[0] ) != string::npos ) {
198 if ( value[0] == 'u' && value[1] == '8' ) {
199 // ???
200 } else {
201 // ???
202 } // if
203 } // if
204 break;
205 } // switch
206} // ConstantNode::ConstantNode
[51b73452]207
[59db689]208ConstantNode *ConstantNode::appendstr( const std::string *newValue ) {
209 assert( newValue != 0 );
210 assert( type == String );
[51b73452]211
[7f5566b]212 // "abc" "def" "ghi" => "abcdefghi", remove new text from quotes and insert before last quote in old string.
[59db689]213 value.insert( value.length() - 1, newValue->substr( 1, newValue->length() - 2 ) );
214
[cd623a4]215 delete newValue; // allocated by lexer
[b87a5ed]216 return this;
[51b73452]217}
218
[bdd516a]219void ConstantNode::printOneLine( std::ostream &os, int indent ) const {
[59db689]220 os << string( indent, ' ' );
[b87a5ed]221 printDesignation( os );
222
223 switch ( type ) {
224 case Integer:
225 case Float:
226 os << value ;
227 break;
228 case Character:
229 os << "'" << value << "'";
230 break;
231 case String:
232 os << '"' << value << '"';
233 break;
[c7ed6d0]234 } // switch
[51b73452]235
[b87a5ed]236 os << ' ';
[51b73452]237}
238
[bdd516a]239void ConstantNode::print( std::ostream &os, int indent ) const {
[b87a5ed]240 printOneLine( os, indent );
241 os << endl;
[51b73452]242}
243
244Expression *ConstantNode::build() const {
[cd623a4]245 ::Type::Qualifiers q; // no qualifiers on constants
[b87a5ed]246
[59db689]247 switch ( get_type() ) {
[b87a5ed]248 case String:
[59db689]249 {
250 // string should probably be a primitive type
251 ArrayType *at = new ArrayType( q, new BasicType( q, BasicType::Char ),
252 new ConstantExpr(
253 Constant( new BasicType( q, BasicType::UnsignedInt ),
[ea9b9d3]254 toString( value.size()+1-2 ) ) ), // +1 for '\0' and -2 for '"'
[59db689]255 false, false );
256 return new ConstantExpr( Constant( at, value ), maybeBuild< Expression >( get_argName() ) );
257 }
258 default:
[cd623a4]259 return new ConstantExpr( Constant( new BasicType( q, btype ), get_value() ), maybeBuild< Expression >( get_argName() ) );
[b87a5ed]260 }
[51b73452]261}
262
[cd623a4]263//##############################################################################
264
[bdd516a]265VarRefNode::VarRefNode() : isLabel( false ) {}
[51b73452]266
[59db689]267VarRefNode::VarRefNode( const string *name_, bool labelp ) : ExpressionNode( name_ ), isLabel( labelp ) {}
[51b73452]268
[3848e0e]269VarRefNode::VarRefNode( const VarRefNode &other ) : ExpressionNode( other ), isLabel( other.isLabel ) {
[51b73452]270}
271
272Expression *VarRefNode::build() const {
[b87a5ed]273 return new NameExpr( get_name(), maybeBuild< Expression >( get_argName() ) );
[51b73452]274}
275
[bdd516a]276void VarRefNode::printOneLine( std::ostream &os, int indent ) const {
[b87a5ed]277 printDesignation( os );
278 os << get_name() << ' ';
[51b73452]279}
280
[bdd516a]281void VarRefNode::print( std::ostream &os, int indent ) const {
[b87a5ed]282 printDesignation( os );
[44b5ca0]283 os << string( indent, ' ' ) << "Referencing: ";
[b87a5ed]284 os << "Variable: " << get_name();
285 os << endl;
[51b73452]286}
287
[cd623a4]288//##############################################################################
289
[51b1202]290DesignatorNode::DesignatorNode( ExpressionNode *expr, bool isArrayIndex ) : isArrayIndex( isArrayIndex ) {
291 set_argName( expr );
[e869d663]292 assert( get_argName() );
293
294 if ( ! isArrayIndex ) {
295 if ( VarRefNode * var = dynamic_cast< VarRefNode * >( expr ) ) {
296
297 stringstream ss( var->get_name() );
298 double value;
299 if ( ss >> value ) {
300 // this is a floating point constant. It MUST be
301 // ".0" or ".1", otherwise the program is invalid
302 if ( ! (var->get_name() == ".0" || var->get_name() == ".1") ) {
303 throw SemanticError( "invalid designator name: " + var->get_name() );
304 } // if
305 var->set_name( var->get_name().substr(1) );
306 } // if
307 } // if
308 } // if
[51b1202]309}
310
311DesignatorNode::DesignatorNode( const DesignatorNode &other ) : ExpressionNode( other ), isArrayIndex( other.isArrayIndex ) {
312}
313
[e869d663]314class DesignatorFixer : public Mutator {
315public:
316 virtual Expression* mutate( NameExpr *nameExpr ) {
317 if ( nameExpr->get_name() == "0" || nameExpr->get_name() == "1" ) {
318 Constant val( new BasicType( Type::Qualifiers(), BasicType::SignedInt ), nameExpr->get_name() );
319 delete nameExpr;
320 return new ConstantExpr( val );
321 }
322 return nameExpr;
323 }
324};
325
[51b1202]326Expression *DesignatorNode::build() const {
[e869d663]327 Expression * ret = get_argName()->build();
328
[51b1202]329 if ( isArrayIndex ) {
[e869d663]330 // need to traverse entire structure and change any instances of 0 or 1 to
331 // ConstantExpr
332 DesignatorFixer fixer;
333 ret = ret->acceptMutator( fixer );
[51b1202]334 } // if
[e869d663]335
336 return ret;
[51b1202]337}
338
339void DesignatorNode::printOneLine( std::ostream &os, int indent ) const {
340 if ( get_argName() ) {
341 if ( isArrayIndex ) {
342 os << "[";
343 get_argName()->printOneLine( os, indent );
344 os << "]";
345 } else {
346 os << ".";
347 get_argName()->printOneLine( os, indent );
348 }
349 } // if
350}
351
352void DesignatorNode::print( std::ostream &os, int indent ) const {
353 if ( get_argName() ) {
354 if ( isArrayIndex ) {
355 os << "[";
356 get_argName()->print( os, indent );
357 os << "]";
358 } else {
359 os << ".";
360 get_argName()->print( os, indent );
361 }
362 } // if
363}
364
365//##############################################################################
366
[bdd516a]367OperatorNode::OperatorNode( Type t ) : type( t ) {}
[51b73452]368
[3848e0e]369OperatorNode::OperatorNode( const OperatorNode &other ) : ExpressionNode( other ), type( other.type ) {
[51b73452]370}
371
372OperatorNode::~OperatorNode() {}
373
[bdd516a]374OperatorNode::Type OperatorNode::get_type( void ) const{
[b87a5ed]375 return type;
[51b73452]376}
377
[3848e0e]378void OperatorNode::printOneLine( std::ostream &os, int indent ) const {
[b87a5ed]379 printDesignation( os );
380 os << OpName[ type ] << ' ';
[51b73452]381}
382
383void OperatorNode::print( std::ostream &os, int indent ) const{
[b87a5ed]384 printDesignation( os );
[44b5ca0]385 os << string( indent, ' ' ) << "Operator: " << OpName[type] << endl;
[b87a5ed]386 return;
[51b73452]387}
388
[59db689]389const char *OperatorNode::get_typename( void ) const{
390 return OpName[ type ];
[51b73452]391}
392
[3848e0e]393const char *OperatorNode::OpName[] = {
[b87a5ed]394 "TupleC", "Comma", "TupleFieldSel",// "TuplePFieldSel", //n-adic
395 // triadic
396 "Cond", "NCond",
397 // diadic
[cd623a4]398 "SizeOf", "AlignOf", "Attr", "CompLit", "Plus", "Minus", "Mul", "Div", "Mod", "Or",
[b87a5ed]399 "And", "BitOr", "BitAnd", "Xor", "Cast", "LShift", "RShift", "LThan", "GThan",
400 "LEThan", "GEThan", "Eq", "Neq", "Assign", "MulAssn", "DivAssn", "ModAssn", "PlusAssn",
401 "MinusAssn", "LSAssn", "RSAssn", "AndAssn", "ERAssn", "OrAssn", "Index", "FieldSel","PFieldSel",
402 "Range",
403 // monadic
404 "UnPlus", "UnMinus", "AddressOf", "PointTo", "Neg", "BitNeg", "Incr", "IncrPost", "Decr", "DecrPost", "LabelAddress"
[3848e0e]405};
[51b73452]406
[cd623a4]407//##############################################################################
408
[7f5566b]409CompositeExprNode::CompositeExprNode() : ExpressionNode(), function( 0 ), arguments( 0 ) {
[51b73452]410}
411
[59db689]412CompositeExprNode::CompositeExprNode( const string *name_ ) : ExpressionNode( name_ ), function( 0 ), arguments( 0 ) {
[51b73452]413}
414
[bdd516a]415CompositeExprNode::CompositeExprNode( ExpressionNode *f, ExpressionNode *args ):
[b87a5ed]416 function( f ), arguments( args ) {
[51b73452]417}
418
[bdd516a]419CompositeExprNode::CompositeExprNode( ExpressionNode *f, ExpressionNode *arg1, ExpressionNode *arg2):
[097e2b0]420 function( f ), arguments( arg1 ) {
421 arguments->set_link( arg2 );
[51b73452]422}
423
[3848e0e]424CompositeExprNode::CompositeExprNode( const CompositeExprNode &other ) : ExpressionNode( other ), function( maybeClone( other.function ) ) {
[b87a5ed]425 ParseNode *cur = other.arguments;
426 while ( cur ) {
427 if ( arguments ) {
428 arguments->set_link( cur->clone() );
429 } else {
430 arguments = ( ExpressionNode*)cur->clone();
431 } // if
432 cur = cur->get_link();
433 }
[51b73452]434}
435
[3848e0e]436CompositeExprNode::~CompositeExprNode() {
[b87a5ed]437 delete function;
438 delete arguments;
[51b73452]439}
440
441// the names that users use to define operator functions
[3848e0e]442static const char *opFuncName[] = {
[de62360d]443 "", "", "",
444 "", "",
445 //diadic
446 "", "", "", "", "?+?", "?-?", "?*?", "?/?", "?%?", "", "",
447 "?|?", "?&?", "?^?", "", "?<<?", "?>>?", "?<?", "?>?", "?<=?",
448 "?>=?", "?==?", "?!=?", "?=?", "?*=?", "?/=?", "?%=?", "?+=?", "?-=?",
449 "?<<=?", "?>>=?", "?&=?", "?^=?", "?|=?", "?[?]", "", "", "Range",
450 //monadic
451 "+?", "-?", "", "*?", "!?", "~?", "++?", "?++", "--?", "?--", "&&"
[3848e0e]452};
[51b73452]453
454#include "utility.h"
455
[3848e0e]456Expression *CompositeExprNode::build() const {
[b87a5ed]457 OperatorNode *op;
458 std::list<Expression *> args;
[51b73452]459
[b87a5ed]460 buildList( get_args(), args );
461
[cd623a4]462 if ( ! ( op = dynamic_cast<OperatorNode *>( function ) ) ) { // function as opposed to operator
[b87a5ed]463 return new UntypedExpr( function->build(), args, maybeBuild< Expression >( get_argName() ));
[cd623a4]464 } // if
[b87a5ed]465
[cd623a4]466 switch ( op->get_type()) {
467 case OperatorNode::Incr:
468 case OperatorNode::Decr:
469 case OperatorNode::IncrPost:
470 case OperatorNode::DecrPost:
471 case OperatorNode::Assign:
472 case OperatorNode::MulAssn:
473 case OperatorNode::DivAssn:
474 case OperatorNode::ModAssn:
475 case OperatorNode::PlusAssn:
476 case OperatorNode::MinusAssn:
477 case OperatorNode::LSAssn:
478 case OperatorNode::RSAssn:
479 case OperatorNode::AndAssn:
480 case OperatorNode::ERAssn:
481 case OperatorNode::OrAssn:
482 // the rewrite rules for these expressions specify that the first argument has its address taken
483 assert( ! args.empty() );
484 args.front() = new AddressExpr( args.front() );
485 break;
486 default:
487 /* do nothing */
488 ;
489 }
490
491 switch ( op->get_type() ) {
492 case OperatorNode::Incr:
493 case OperatorNode::Decr:
494 case OperatorNode::IncrPost:
495 case OperatorNode::DecrPost:
496 case OperatorNode::Assign:
497 case OperatorNode::MulAssn:
498 case OperatorNode::DivAssn:
499 case OperatorNode::ModAssn:
500 case OperatorNode::PlusAssn:
501 case OperatorNode::MinusAssn:
502 case OperatorNode::LSAssn:
503 case OperatorNode::RSAssn:
504 case OperatorNode::AndAssn:
505 case OperatorNode::ERAssn:
506 case OperatorNode::OrAssn:
507 case OperatorNode::Plus:
508 case OperatorNode::Minus:
509 case OperatorNode::Mul:
510 case OperatorNode::Div:
511 case OperatorNode::Mod:
512 case OperatorNode::BitOr:
513 case OperatorNode::BitAnd:
514 case OperatorNode::Xor:
515 case OperatorNode::LShift:
516 case OperatorNode::RShift:
517 case OperatorNode::LThan:
518 case OperatorNode::GThan:
519 case OperatorNode::LEThan:
520 case OperatorNode::GEThan:
521 case OperatorNode::Eq:
522 case OperatorNode::Neq:
523 case OperatorNode::Index:
524 case OperatorNode::Range:
525 case OperatorNode::UnPlus:
526 case OperatorNode::UnMinus:
527 case OperatorNode::PointTo:
528 case OperatorNode::Neg:
529 case OperatorNode::BitNeg:
530 case OperatorNode::LabelAddress:
531 return new UntypedExpr( new NameExpr( opFuncName[ op->get_type() ] ), args );
532 case OperatorNode::AddressOf:
533 assert( args.size() == 1 );
534 assert( args.front() );
535
536 return new AddressExpr( args.front() );
537 case OperatorNode::Cast:
538 {
539 TypeValueNode * arg = dynamic_cast<TypeValueNode *>( get_args());
540 assert( arg );
[b87a5ed]541
[cd623a4]542 DeclarationNode *decl_node = arg->get_decl();
543 ExpressionNode *expr_node = dynamic_cast<ExpressionNode *>( arg->get_link());
[b87a5ed]544
[cd623a4]545 Type *targetType = decl_node->buildType();
546 if ( dynamic_cast< VoidType* >( targetType ) ) {
547 delete targetType;
548 return new CastExpr( expr_node->build(), maybeBuild< Expression >( get_argName() ) );
549 } else {
550 return new CastExpr( expr_node->build(),targetType, maybeBuild< Expression >( get_argName() ) );
551 } // if
552 }
553 case OperatorNode::FieldSel:
554 {
555 assert( args.size() == 2 );
556
557 NameExpr *member = dynamic_cast<NameExpr *>( args.back());
558 // TupleExpr *memberTup = dynamic_cast<TupleExpr *>( args.back());
[b87a5ed]559
[cd623a4]560 if ( member != 0 ) {
561 UntypedMemberExpr *ret = new UntypedMemberExpr( member->get_name(), args.front());
[b87a5ed]562 delete member;
563 return ret;
[cd623a4]564 /* else if ( memberTup != 0 )
565 {
566 UntypedMemberExpr *ret = new UntypedMemberExpr( memberTup->get_name(), args.front());
567 delete member;
568 return ret;
569 } */
570 } else
571 assert( false );
572 }
573 case OperatorNode::PFieldSel:
574 {
575 assert( args.size() == 2 );
576
577 NameExpr *member = dynamic_cast<NameExpr *>( args.back()); // modify for Tuples xxx
578 assert( member != 0 );
579
580 UntypedExpr *deref = new UntypedExpr( new NameExpr( "*?" ) );
581 deref->get_args().push_back( args.front() );
582
583 UntypedMemberExpr *ret = new UntypedMemberExpr( member->get_name(), deref );
584 delete member;
585 return ret;
586 }
587 case OperatorNode::AlignOf:
588 case OperatorNode::SizeOf:
589 {
[bdd516a]590/// bool isSizeOf = ( op->get_type() == OperatorNode::SizeOf );
[51b73452]591
[cd623a4]592 if ( TypeValueNode * arg = dynamic_cast<TypeValueNode *>( get_args()) ) {
593 return new SizeofExpr( arg->get_decl()->buildType());
594 } else {
595 return new SizeofExpr( args.front());
596 } // if
597 }
598 case OperatorNode::Attr:
599 {
600 VarRefNode *var = dynamic_cast<VarRefNode *>( get_args());
601 assert( var );
602 if ( ! get_args()->get_link() ) {
603 return new AttrExpr( var->build(), ( Expression*)0);
604 } else if ( TypeValueNode * arg = dynamic_cast<TypeValueNode *>( get_args()->get_link()) ) {
605 return new AttrExpr( var->build(), arg->get_decl()->buildType());
606 } else {
607 return new AttrExpr( var->build(), args.back());
608 } // if
609 }
610 case OperatorNode::CompLit:
611 throw UnimplementedError( "C99 compound literals" );
612 // the short-circuited operators
613 case OperatorNode::Or:
614 case OperatorNode::And:
615 assert( args.size() == 2);
616 return new LogicalExpr( notZeroExpr( args.front() ), notZeroExpr( args.back() ), ( op->get_type() == OperatorNode::And ) );
617 case OperatorNode::Cond:
618 {
619 assert( args.size() == 3);
[7f5566b]620 std::list< Expression * >::const_iterator i = args.begin();
[cd623a4]621 Expression *arg1 = notZeroExpr( *i++ );
622 Expression *arg2 = *i++;
623 Expression *arg3 = *i++;
624 return new ConditionalExpr( arg1, arg2, arg3 );
625 }
626 case OperatorNode::NCond:
627 throw UnimplementedError( "GNU 2-argument conditional expression" );
628 case OperatorNode::Comma:
629 {
[b87a5ed]630 assert( args.size() == 2);
[7f5566b]631 std::list< Expression * >::const_iterator i = args.begin();
[cd623a4]632 Expression *ret = *i++;
633 while ( i != args.end() ) {
634 ret = new CommaExpr( ret, *i++ );
[b87a5ed]635 }
[cd623a4]636 return ret;
[3848e0e]637 }
[cd623a4]638 // Tuples
639 case OperatorNode::TupleC:
640 {
641 TupleExpr *ret = new TupleExpr();
642 std::copy( args.begin(), args.end(), back_inserter( ret->get_exprs() ) );
643 return ret;
644 }
645 default:
646 // shouldn't happen
647 return 0;
648 } // switch
[51b73452]649}
650
[bdd516a]651void CompositeExprNode::printOneLine( std::ostream &os, int indent ) const {
[b87a5ed]652 printDesignation( os );
653 os << "( ";
654 function->printOneLine( os, indent );
655 for ( ExpressionNode *cur = arguments; cur != 0; cur = dynamic_cast< ExpressionNode* >( cur->get_link() ) ) {
656 cur->printOneLine( os, indent );
657 }
658 os << ") ";
[51b73452]659}
660
[bdd516a]661void CompositeExprNode::print( std::ostream &os, int indent ) const {
[b87a5ed]662 printDesignation( os );
[44b5ca0]663 os << string( indent, ' ' ) << "Application of: " << endl;
[b87a5ed]664 function->print( os, indent + ParseNode::indent_by );
[51b73452]665
[44b5ca0]666 os << string( indent, ' ' ) ;
[b87a5ed]667 if ( arguments ) {
668 os << "... on arguments: " << endl;
669 arguments->printList( os, indent + ParseNode::indent_by );
670 } else
671 os << "... on no arguments: " << endl;
[51b73452]672}
673
[a08ba92]674void CompositeExprNode::set_function( ExpressionNode *f ) {
[b87a5ed]675 function = f;
[51b73452]676}
677
[a08ba92]678void CompositeExprNode::set_args( ExpressionNode *args ) {
[b87a5ed]679 arguments = args;
[51b73452]680}
681
[bdd516a]682ExpressionNode *CompositeExprNode::get_function( void ) const {
[b87a5ed]683 return function;
[51b73452]684}
685
[bdd516a]686ExpressionNode *CompositeExprNode::get_args( void ) const {
[b87a5ed]687 return arguments;
[51b73452]688}
689
[a08ba92]690void CompositeExprNode::add_arg( ExpressionNode *arg ) {
[b87a5ed]691 if ( arguments )
692 arguments->set_link( arg );
693 else
694 set_args( arg );
[51b73452]695}
696
[cd623a4]697//##############################################################################
698
[7f5566b]699Expression *AsmExprNode::build() const {
700 return new AsmExpr( maybeBuild< Expression >( inout ), (ConstantExpr *)constraint->build(), operand->build() );
701}
702
703void AsmExprNode::print( std::ostream &os, int indent ) const {
704 os << string( indent, ' ' ) << "Assembler Expression:" << endl;
705 if ( inout ) {
706 os << string( indent, ' ' ) << "inout: " << std::endl;
707 inout->print( os, indent + 2 );
708 } // if
709 if ( constraint ) {
710 os << string( indent, ' ' ) << "constraint: " << std::endl;
711 constraint->print( os, indent + 2 );
712 } // if
713 if ( operand ) {
714 os << string( indent, ' ' ) << "operand: " << std::endl;
715 operand->print( os, indent + 2 );
716 } // if
717}
718
719void AsmExprNode::printOneLine( std::ostream &os, int indent ) const {
720 printDesignation( os );
721 os << "( ";
722 if ( inout ) inout->printOneLine( os, indent + 2 );
723 os << ", ";
724 if ( constraint ) constraint->printOneLine( os, indent + 2 );
725 os << ", ";
726 if ( operand ) operand->printOneLine( os, indent + 2 );
727 os << ") ";
728}
729
730//##############################################################################
731
732void LabelNode::print( std::ostream &os, int indent ) const {}
733
734void LabelNode::printOneLine( std::ostream &os, int indent ) const {}
735
736//##############################################################################
737
[bdd516a]738CommaExprNode::CommaExprNode(): CompositeExprNode( new OperatorNode( OperatorNode::Comma )) {}
[51b73452]739
[bdd516a]740CommaExprNode::CommaExprNode( ExpressionNode *exp ) : CompositeExprNode( new OperatorNode( OperatorNode::Comma ), exp ) {
[3848e0e]741}
[51b73452]742
[bdd516a]743CommaExprNode::CommaExprNode( ExpressionNode *exp1, ExpressionNode *exp2) : CompositeExprNode( new OperatorNode( OperatorNode::Comma ), exp1, exp2) {
[51b73452]744}
745
[a08ba92]746CommaExprNode *CommaExprNode::add_to_list( ExpressionNode *exp ) {
[b87a5ed]747 add_arg( exp );
[51b73452]748
[b87a5ed]749 return this;
[51b73452]750}
751
[3848e0e]752CommaExprNode::CommaExprNode( const CommaExprNode &other ) : CompositeExprNode( other ) {
[51b73452]753}
754
[cd623a4]755//##############################################################################
756
[bdd516a]757ValofExprNode::ValofExprNode( StatementNode *s ): body( s ) {}
[51b73452]758
[3848e0e]759ValofExprNode::ValofExprNode( const ValofExprNode &other ) : ExpressionNode( other ), body( maybeClone( body ) ) {
[51b73452]760}
761
762ValofExprNode::~ValofExprNode() {
[b87a5ed]763 delete body;
[51b73452]764}
765
766void ValofExprNode::print( std::ostream &os, int indent ) const {
[b87a5ed]767 printDesignation( os );
[59db689]768 os << string( indent, ' ' ) << "Valof Expression:" << std::endl;
[b87a5ed]769 get_body()->print( os, indent + 4);
[51b73452]770}
771
[3848e0e]772void ValofExprNode::printOneLine( std::ostream &, int indent ) const {
[b87a5ed]773 assert( false );
[51b73452]774}
775
776Expression *ValofExprNode::build() const {
[b87a5ed]777 return new UntypedValofExpr ( get_body()->build(), maybeBuild< Expression >( get_argName() ) );
[3848e0e]778}
779
[cd623a4]780//##############################################################################
781
[bdd516a]782ForCtlExprNode::ForCtlExprNode( ParseNode *init_, ExpressionNode *cond, ExpressionNode *incr ) throw ( SemanticError ) : condition( cond ), change( incr ) {
[b87a5ed]783 if ( init_ == 0 )
784 init = 0;
785 else {
786 DeclarationNode *decl;
787 ExpressionNode *exp;
788
[a61fea9a]789 if (( decl = dynamic_cast<DeclarationNode *>(init_) ) != 0)
[b87a5ed]790 init = new StatementNode( decl );
791 else if (( exp = dynamic_cast<ExpressionNode *>( init_)) != 0)
792 init = new StatementNode( StatementNode::Exp, exp );
793 else
794 throw SemanticError("Error in for control expression");
795 }
[51b73452]796}
797
798ForCtlExprNode::ForCtlExprNode( const ForCtlExprNode &other )
[b87a5ed]799 : ExpressionNode( other ), init( maybeClone( other.init ) ), condition( maybeClone( other.condition ) ), change( maybeClone( other.change ) ) {
[51b73452]800}
801
[a08ba92]802ForCtlExprNode::~ForCtlExprNode() {
[b87a5ed]803 delete init;
804 delete condition;
805 delete change;
[51b73452]806}
807
808Expression *ForCtlExprNode::build() const {
[b87a5ed]809 // this shouldn't be used!
810 assert( false );
811 return 0;
[51b73452]812}
813
814void ForCtlExprNode::print( std::ostream &os, int indent ) const{
[59db689]815 os << string( indent,' ' ) << "For Control Expression -- :" << endl;
[a61fea9a]816
[59db689]817 os << string( indent + 2, ' ' ) << "initialization:" << endl;
[a61fea9a]818 if ( init != 0 )
819 init->printList( os, indent + 4 );
820
821 os << string( indent + 2, ' ' ) << "condition: " << endl;
822 if ( condition != 0 )
823 condition->print( os, indent + 4 );
[59db689]824 os << string( indent + 2, ' ' ) << "increment: " << endl;
[a61fea9a]825 if ( change != 0 )
826 change->print( os, indent + 4 );
[51b73452]827}
828
[3848e0e]829void ForCtlExprNode::printOneLine( std::ostream &, int indent ) const {
[b87a5ed]830 assert( false );
[51b73452]831}
832
[cd623a4]833//##############################################################################
834
835TypeValueNode::TypeValueNode( DeclarationNode *decl ) : decl( decl ) {
[51b73452]836}
837
[cd623a4]838TypeValueNode::TypeValueNode( const TypeValueNode &other ) : ExpressionNode( other ), decl( maybeClone( other.decl ) ) {
[51b73452]839}
840
[3848e0e]841Expression *TypeValueNode::build() const {
[b87a5ed]842 return new TypeExpr( decl->buildType() );
[51b73452]843}
844
[bdd516a]845void TypeValueNode::print( std::ostream &os, int indent ) const {
[b87a5ed]846 os << std::string( indent, ' ' ) << "Type:";
847 get_decl()->print( os, indent + 2);
[51b73452]848}
849
[bdd516a]850void TypeValueNode::printOneLine( std::ostream &os, int indent ) const {
[b87a5ed]851 os << "Type:";
852 get_decl()->print( os, indent + 2);
[51b73452]853}
854
[3848e0e]855ExpressionNode *flattenCommas( ExpressionNode *list ) {
[cd623a4]856 if ( CompositeExprNode *composite = dynamic_cast< CompositeExprNode * >( list ) ) {
857 OperatorNode *op;
858 if ( ( op = dynamic_cast< OperatorNode * >( composite->get_function() )) && ( op->get_type() == OperatorNode::Comma ) ) {
859 if ( ExpressionNode *next = dynamic_cast< ExpressionNode * >( list->get_link() ) )
860 composite->add_arg( next );
861 return flattenCommas( composite->get_args() );
862 } // if
863 } // if
[51b73452]864
[b87a5ed]865 if ( ExpressionNode *next = dynamic_cast< ExpressionNode * >( list->get_link() ) )
866 list->set_next( flattenCommas( next ) );
[51b73452]867
[b87a5ed]868 return list;
[51b73452]869}
870
[3848e0e]871ExpressionNode *tupleContents( ExpressionNode *tuple ) {
[b87a5ed]872 if ( CompositeExprNode *composite = dynamic_cast< CompositeExprNode * >( tuple ) ) {
873 OperatorNode *op = 0;
874 if ( ( op = dynamic_cast< OperatorNode * >( composite->get_function() )) && ( op->get_type() == OperatorNode::TupleC ) )
875 return composite->get_args();
[cd623a4]876 } // if
[b87a5ed]877 return tuple;
[51b73452]878}
[b87a5ed]879
880// Local Variables: //
881// tab-width: 4 //
882// mode: c++ //
883// compile-command: "make install" //
884// End: //
Note: See TracBrowser for help on using the repository browser.