source: src/Parser/ExpressionNode.cc@ 5aa708c

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 5aa708c was 1869adf, checked in by Rob Schluntz <rschlunt@…>, 10 years ago

fix label name in label address expression

  • Property mode set to 100644
File size: 22.9 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
[ea9b9d3]11// Last Modified By : Rob Schluntz
[1869adf]12// Last Modified On : Wed Jun 24 16:20:00 2015
13// Update Count : 158
[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
[59db689]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
[59db689]44ExpressionNode * ExpressionNode::set_asArgName( const std::string *aName ) {
[b87a5ed]45 argName = new VarRefNode( aName );
46 return this;
[51b73452]47}
48
49ExpressionNode * ExpressionNode::set_asArgName( 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
[cd623a4]212 // "abc" "def" "ghi" => "abcdefghi", so 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
[bdd516a]290OperatorNode::OperatorNode( Type t ) : type( t ) {}
[51b73452]291
[3848e0e]292OperatorNode::OperatorNode( const OperatorNode &other ) : ExpressionNode( other ), type( other.type ) {
[51b73452]293}
294
295OperatorNode::~OperatorNode() {}
296
[bdd516a]297OperatorNode::Type OperatorNode::get_type( void ) const{
[b87a5ed]298 return type;
[51b73452]299}
300
[3848e0e]301void OperatorNode::printOneLine( std::ostream &os, int indent ) const {
[b87a5ed]302 printDesignation( os );
303 os << OpName[ type ] << ' ';
[51b73452]304}
305
306void OperatorNode::print( std::ostream &os, int indent ) const{
[b87a5ed]307 printDesignation( os );
[44b5ca0]308 os << string( indent, ' ' ) << "Operator: " << OpName[type] << endl;
[b87a5ed]309 return;
[51b73452]310}
311
[59db689]312const char *OperatorNode::get_typename( void ) const{
313 return OpName[ type ];
[51b73452]314}
315
[3848e0e]316const char *OperatorNode::OpName[] = {
[b87a5ed]317 "TupleC", "Comma", "TupleFieldSel",// "TuplePFieldSel", //n-adic
318 // triadic
319 "Cond", "NCond",
320 // diadic
[cd623a4]321 "SizeOf", "AlignOf", "Attr", "CompLit", "Plus", "Minus", "Mul", "Div", "Mod", "Or",
[b87a5ed]322 "And", "BitOr", "BitAnd", "Xor", "Cast", "LShift", "RShift", "LThan", "GThan",
323 "LEThan", "GEThan", "Eq", "Neq", "Assign", "MulAssn", "DivAssn", "ModAssn", "PlusAssn",
324 "MinusAssn", "LSAssn", "RSAssn", "AndAssn", "ERAssn", "OrAssn", "Index", "FieldSel","PFieldSel",
325 "Range",
326 // monadic
327 "UnPlus", "UnMinus", "AddressOf", "PointTo", "Neg", "BitNeg", "Incr", "IncrPost", "Decr", "DecrPost", "LabelAddress"
[3848e0e]328};
[51b73452]329
[cd623a4]330//##############################################################################
331
[bdd516a]332CompositeExprNode::CompositeExprNode( void ) : ExpressionNode(), function( 0 ), arguments( 0 ) {
[51b73452]333}
334
[59db689]335CompositeExprNode::CompositeExprNode( const string *name_ ) : ExpressionNode( name_ ), function( 0 ), arguments( 0 ) {
[51b73452]336}
337
[bdd516a]338CompositeExprNode::CompositeExprNode( ExpressionNode *f, ExpressionNode *args ):
[b87a5ed]339 function( f ), arguments( args ) {
[51b73452]340}
341
[bdd516a]342CompositeExprNode::CompositeExprNode( ExpressionNode *f, ExpressionNode *arg1, ExpressionNode *arg2):
[b87a5ed]343 function( f ), arguments( arg1) {
344 arguments->set_link( arg2);
[51b73452]345}
346
[3848e0e]347CompositeExprNode::CompositeExprNode( const CompositeExprNode &other ) : ExpressionNode( other ), function( maybeClone( other.function ) ) {
[b87a5ed]348 ParseNode *cur = other.arguments;
349 while ( cur ) {
350 if ( arguments ) {
351 arguments->set_link( cur->clone() );
352 } else {
353 arguments = ( ExpressionNode*)cur->clone();
354 } // if
355 cur = cur->get_link();
356 }
[51b73452]357}
358
[3848e0e]359CompositeExprNode::~CompositeExprNode() {
[b87a5ed]360 delete function;
361 delete arguments;
[51b73452]362}
363
364// the names that users use to define operator functions
[3848e0e]365static const char *opFuncName[] = {
[de62360d]366 "", "", "",
367 "", "",
368 //diadic
369 "", "", "", "", "?+?", "?-?", "?*?", "?/?", "?%?", "", "",
370 "?|?", "?&?", "?^?", "", "?<<?", "?>>?", "?<?", "?>?", "?<=?",
371 "?>=?", "?==?", "?!=?", "?=?", "?*=?", "?/=?", "?%=?", "?+=?", "?-=?",
372 "?<<=?", "?>>=?", "?&=?", "?^=?", "?|=?", "?[?]", "", "", "Range",
373 //monadic
374 "+?", "-?", "", "*?", "!?", "~?", "++?", "?++", "--?", "?--", "&&"
[3848e0e]375};
[51b73452]376
377#include "utility.h"
378
[3848e0e]379Expression *CompositeExprNode::build() const {
[b87a5ed]380 OperatorNode *op;
381 std::list<Expression *> args;
[51b73452]382
[b87a5ed]383 buildList( get_args(), args );
384
[cd623a4]385 if ( ! ( op = dynamic_cast<OperatorNode *>( function ) ) ) { // function as opposed to operator
[b87a5ed]386 return new UntypedExpr( function->build(), args, maybeBuild< Expression >( get_argName() ));
[cd623a4]387 } // if
[b87a5ed]388
[cd623a4]389 switch ( op->get_type()) {
390 case OperatorNode::Incr:
391 case OperatorNode::Decr:
392 case OperatorNode::IncrPost:
393 case OperatorNode::DecrPost:
394 case OperatorNode::Assign:
395 case OperatorNode::MulAssn:
396 case OperatorNode::DivAssn:
397 case OperatorNode::ModAssn:
398 case OperatorNode::PlusAssn:
399 case OperatorNode::MinusAssn:
400 case OperatorNode::LSAssn:
401 case OperatorNode::RSAssn:
402 case OperatorNode::AndAssn:
403 case OperatorNode::ERAssn:
404 case OperatorNode::OrAssn:
405 // the rewrite rules for these expressions specify that the first argument has its address taken
406 assert( ! args.empty() );
407 args.front() = new AddressExpr( args.front() );
408 break;
409 default:
410 /* do nothing */
411 ;
412 }
413
414 switch ( op->get_type() ) {
415 case OperatorNode::Incr:
416 case OperatorNode::Decr:
417 case OperatorNode::IncrPost:
418 case OperatorNode::DecrPost:
419 case OperatorNode::Assign:
420 case OperatorNode::MulAssn:
421 case OperatorNode::DivAssn:
422 case OperatorNode::ModAssn:
423 case OperatorNode::PlusAssn:
424 case OperatorNode::MinusAssn:
425 case OperatorNode::LSAssn:
426 case OperatorNode::RSAssn:
427 case OperatorNode::AndAssn:
428 case OperatorNode::ERAssn:
429 case OperatorNode::OrAssn:
430 case OperatorNode::Plus:
431 case OperatorNode::Minus:
432 case OperatorNode::Mul:
433 case OperatorNode::Div:
434 case OperatorNode::Mod:
435 case OperatorNode::BitOr:
436 case OperatorNode::BitAnd:
437 case OperatorNode::Xor:
438 case OperatorNode::LShift:
439 case OperatorNode::RShift:
440 case OperatorNode::LThan:
441 case OperatorNode::GThan:
442 case OperatorNode::LEThan:
443 case OperatorNode::GEThan:
444 case OperatorNode::Eq:
445 case OperatorNode::Neq:
446 case OperatorNode::Index:
447 case OperatorNode::Range:
448 case OperatorNode::UnPlus:
449 case OperatorNode::UnMinus:
450 case OperatorNode::PointTo:
451 case OperatorNode::Neg:
452 case OperatorNode::BitNeg:
453 case OperatorNode::LabelAddress:
454 return new UntypedExpr( new NameExpr( opFuncName[ op->get_type() ] ), args );
455 case OperatorNode::AddressOf:
456 assert( args.size() == 1 );
457 assert( args.front() );
458
459 return new AddressExpr( args.front() );
460 case OperatorNode::Cast:
461 {
462 TypeValueNode * arg = dynamic_cast<TypeValueNode *>( get_args());
463 assert( arg );
[b87a5ed]464
[cd623a4]465 DeclarationNode *decl_node = arg->get_decl();
466 ExpressionNode *expr_node = dynamic_cast<ExpressionNode *>( arg->get_link());
[b87a5ed]467
[cd623a4]468 Type *targetType = decl_node->buildType();
469 if ( dynamic_cast< VoidType* >( targetType ) ) {
470 delete targetType;
471 return new CastExpr( expr_node->build(), maybeBuild< Expression >( get_argName() ) );
472 } else {
473 return new CastExpr( expr_node->build(),targetType, maybeBuild< Expression >( get_argName() ) );
474 } // if
475 }
476 case OperatorNode::FieldSel:
477 {
478 assert( args.size() == 2 );
479
480 NameExpr *member = dynamic_cast<NameExpr *>( args.back());
481 // TupleExpr *memberTup = dynamic_cast<TupleExpr *>( args.back());
[b87a5ed]482
[cd623a4]483 if ( member != 0 ) {
484 UntypedMemberExpr *ret = new UntypedMemberExpr( member->get_name(), args.front());
[b87a5ed]485 delete member;
486 return ret;
[cd623a4]487 /* else if ( memberTup != 0 )
488 {
489 UntypedMemberExpr *ret = new UntypedMemberExpr( memberTup->get_name(), args.front());
490 delete member;
491 return ret;
492 } */
493 } else
494 assert( false );
495 }
496 case OperatorNode::PFieldSel:
497 {
498 assert( args.size() == 2 );
499
500 NameExpr *member = dynamic_cast<NameExpr *>( args.back()); // modify for Tuples xxx
501 assert( member != 0 );
502
503 UntypedExpr *deref = new UntypedExpr( new NameExpr( "*?" ) );
504 deref->get_args().push_back( args.front() );
505
506 UntypedMemberExpr *ret = new UntypedMemberExpr( member->get_name(), deref );
507 delete member;
508 return ret;
509 }
510 case OperatorNode::AlignOf:
511 case OperatorNode::SizeOf:
512 {
[bdd516a]513/// bool isSizeOf = ( op->get_type() == OperatorNode::SizeOf );
[51b73452]514
[cd623a4]515 if ( TypeValueNode * arg = dynamic_cast<TypeValueNode *>( get_args()) ) {
516 return new SizeofExpr( arg->get_decl()->buildType());
517 } else {
518 return new SizeofExpr( args.front());
519 } // if
520 }
521 case OperatorNode::Attr:
522 {
523 VarRefNode *var = dynamic_cast<VarRefNode *>( get_args());
524 assert( var );
525 if ( ! get_args()->get_link() ) {
526 return new AttrExpr( var->build(), ( Expression*)0);
527 } else if ( TypeValueNode * arg = dynamic_cast<TypeValueNode *>( get_args()->get_link()) ) {
528 return new AttrExpr( var->build(), arg->get_decl()->buildType());
529 } else {
530 return new AttrExpr( var->build(), args.back());
531 } // if
532 }
533 case OperatorNode::CompLit:
534 throw UnimplementedError( "C99 compound literals" );
535 // the short-circuited operators
536 case OperatorNode::Or:
537 case OperatorNode::And:
538 assert( args.size() == 2);
539 return new LogicalExpr( notZeroExpr( args.front() ), notZeroExpr( args.back() ), ( op->get_type() == OperatorNode::And ) );
540 case OperatorNode::Cond:
541 {
542 assert( args.size() == 3);
543 std::list< Expression* >::const_iterator i = args.begin();
544 Expression *arg1 = notZeroExpr( *i++ );
545 Expression *arg2 = *i++;
546 Expression *arg3 = *i++;
547 return new ConditionalExpr( arg1, arg2, arg3 );
548 }
549 case OperatorNode::NCond:
550 throw UnimplementedError( "GNU 2-argument conditional expression" );
551 case OperatorNode::Comma:
552 {
[b87a5ed]553 assert( args.size() == 2);
[cd623a4]554 std::list< Expression* >::const_iterator i = args.begin();
555 Expression *ret = *i++;
556 while ( i != args.end() ) {
557 ret = new CommaExpr( ret, *i++ );
[b87a5ed]558 }
[cd623a4]559 return ret;
[3848e0e]560 }
[cd623a4]561 // Tuples
562 case OperatorNode::TupleC:
563 {
564 TupleExpr *ret = new TupleExpr();
565 std::copy( args.begin(), args.end(), back_inserter( ret->get_exprs() ) );
566 return ret;
567 }
568 default:
569 // shouldn't happen
570 return 0;
571 } // switch
[51b73452]572}
573
[bdd516a]574void CompositeExprNode::printOneLine( std::ostream &os, int indent ) const {
[b87a5ed]575 printDesignation( os );
576 os << "( ";
577 function->printOneLine( os, indent );
578 for ( ExpressionNode *cur = arguments; cur != 0; cur = dynamic_cast< ExpressionNode* >( cur->get_link() ) ) {
579 cur->printOneLine( os, indent );
580 }
581 os << ") ";
[51b73452]582}
583
[bdd516a]584void CompositeExprNode::print( std::ostream &os, int indent ) const {
[b87a5ed]585 printDesignation( os );
[44b5ca0]586 os << string( indent, ' ' ) << "Application of: " << endl;
[b87a5ed]587 function->print( os, indent + ParseNode::indent_by );
[51b73452]588
[44b5ca0]589 os << string( indent, ' ' ) ;
[b87a5ed]590 if ( arguments ) {
591 os << "... on arguments: " << endl;
592 arguments->printList( os, indent + ParseNode::indent_by );
593 } else
594 os << "... on no arguments: " << endl;
[51b73452]595}
596
[a08ba92]597void CompositeExprNode::set_function( ExpressionNode *f ) {
[b87a5ed]598 function = f;
[51b73452]599}
600
[a08ba92]601void CompositeExprNode::set_args( ExpressionNode *args ) {
[b87a5ed]602 arguments = args;
[51b73452]603}
604
[bdd516a]605ExpressionNode *CompositeExprNode::get_function( void ) const {
[b87a5ed]606 return function;
[51b73452]607}
608
[bdd516a]609ExpressionNode *CompositeExprNode::get_args( void ) const {
[b87a5ed]610 return arguments;
[51b73452]611}
612
[a08ba92]613void CompositeExprNode::add_arg( ExpressionNode *arg ) {
[b87a5ed]614 if ( arguments )
615 arguments->set_link( arg );
616 else
617 set_args( arg );
[51b73452]618}
619
[cd623a4]620//##############################################################################
621
[bdd516a]622CommaExprNode::CommaExprNode(): CompositeExprNode( new OperatorNode( OperatorNode::Comma )) {}
[51b73452]623
[bdd516a]624CommaExprNode::CommaExprNode( ExpressionNode *exp ) : CompositeExprNode( new OperatorNode( OperatorNode::Comma ), exp ) {
[3848e0e]625}
[51b73452]626
[bdd516a]627CommaExprNode::CommaExprNode( ExpressionNode *exp1, ExpressionNode *exp2) : CompositeExprNode( new OperatorNode( OperatorNode::Comma ), exp1, exp2) {
[51b73452]628}
629
[a08ba92]630CommaExprNode *CommaExprNode::add_to_list( ExpressionNode *exp ) {
[b87a5ed]631 add_arg( exp );
[51b73452]632
[b87a5ed]633 return this;
[51b73452]634}
635
[3848e0e]636CommaExprNode::CommaExprNode( const CommaExprNode &other ) : CompositeExprNode( other ) {
[51b73452]637}
638
[cd623a4]639//##############################################################################
640
[bdd516a]641ValofExprNode::ValofExprNode( StatementNode *s ): body( s ) {}
[51b73452]642
[3848e0e]643ValofExprNode::ValofExprNode( const ValofExprNode &other ) : ExpressionNode( other ), body( maybeClone( body ) ) {
[51b73452]644}
645
646ValofExprNode::~ValofExprNode() {
[b87a5ed]647 delete body;
[51b73452]648}
649
650void ValofExprNode::print( std::ostream &os, int indent ) const {
[b87a5ed]651 printDesignation( os );
[59db689]652 os << string( indent, ' ' ) << "Valof Expression:" << std::endl;
[b87a5ed]653 get_body()->print( os, indent + 4);
[51b73452]654}
655
[3848e0e]656void ValofExprNode::printOneLine( std::ostream &, int indent ) const {
[b87a5ed]657 assert( false );
[51b73452]658}
659
660Expression *ValofExprNode::build() const {
[b87a5ed]661 return new UntypedValofExpr ( get_body()->build(), maybeBuild< Expression >( get_argName() ) );
[3848e0e]662}
663
[cd623a4]664//##############################################################################
665
[bdd516a]666ForCtlExprNode::ForCtlExprNode( ParseNode *init_, ExpressionNode *cond, ExpressionNode *incr ) throw ( SemanticError ) : condition( cond ), change( incr ) {
[b87a5ed]667 if ( init_ == 0 )
668 init = 0;
669 else {
670 DeclarationNode *decl;
671 ExpressionNode *exp;
672
[a61fea9a]673 if (( decl = dynamic_cast<DeclarationNode *>(init_) ) != 0)
[b87a5ed]674 init = new StatementNode( decl );
675 else if (( exp = dynamic_cast<ExpressionNode *>( init_)) != 0)
676 init = new StatementNode( StatementNode::Exp, exp );
677 else
678 throw SemanticError("Error in for control expression");
679 }
[51b73452]680}
681
682ForCtlExprNode::ForCtlExprNode( const ForCtlExprNode &other )
[b87a5ed]683 : ExpressionNode( other ), init( maybeClone( other.init ) ), condition( maybeClone( other.condition ) ), change( maybeClone( other.change ) ) {
[51b73452]684}
685
[a08ba92]686ForCtlExprNode::~ForCtlExprNode() {
[b87a5ed]687 delete init;
688 delete condition;
689 delete change;
[51b73452]690}
691
692Expression *ForCtlExprNode::build() const {
[b87a5ed]693 // this shouldn't be used!
694 assert( false );
695 return 0;
[51b73452]696}
697
698void ForCtlExprNode::print( std::ostream &os, int indent ) const{
[59db689]699 os << string( indent,' ' ) << "For Control Expression -- :" << endl;
[a61fea9a]700
[59db689]701 os << string( indent + 2, ' ' ) << "initialization:" << endl;
[a61fea9a]702 if ( init != 0 )
703 init->printList( os, indent + 4 );
704
705 os << string( indent + 2, ' ' ) << "condition: " << endl;
706 if ( condition != 0 )
707 condition->print( os, indent + 4 );
[59db689]708 os << string( indent + 2, ' ' ) << "increment: " << endl;
[a61fea9a]709 if ( change != 0 )
710 change->print( os, indent + 4 );
[51b73452]711}
712
[3848e0e]713void ForCtlExprNode::printOneLine( std::ostream &, int indent ) const {
[b87a5ed]714 assert( false );
[51b73452]715}
716
[cd623a4]717//##############################################################################
718
719TypeValueNode::TypeValueNode( DeclarationNode *decl ) : decl( decl ) {
[51b73452]720}
721
[cd623a4]722TypeValueNode::TypeValueNode( const TypeValueNode &other ) : ExpressionNode( other ), decl( maybeClone( other.decl ) ) {
[51b73452]723}
724
[3848e0e]725Expression *TypeValueNode::build() const {
[b87a5ed]726 return new TypeExpr( decl->buildType() );
[51b73452]727}
728
[bdd516a]729void TypeValueNode::print( std::ostream &os, int indent ) const {
[b87a5ed]730 os << std::string( indent, ' ' ) << "Type:";
731 get_decl()->print( os, indent + 2);
[51b73452]732}
733
[bdd516a]734void TypeValueNode::printOneLine( std::ostream &os, int indent ) const {
[b87a5ed]735 os << "Type:";
736 get_decl()->print( os, indent + 2);
[51b73452]737}
738
[3848e0e]739ExpressionNode *flattenCommas( ExpressionNode *list ) {
[cd623a4]740 if ( CompositeExprNode *composite = dynamic_cast< CompositeExprNode * >( list ) ) {
741 OperatorNode *op;
742 if ( ( op = dynamic_cast< OperatorNode * >( composite->get_function() )) && ( op->get_type() == OperatorNode::Comma ) ) {
743 if ( ExpressionNode *next = dynamic_cast< ExpressionNode * >( list->get_link() ) )
744 composite->add_arg( next );
745 return flattenCommas( composite->get_args() );
746 } // if
747 } // if
[51b73452]748
[b87a5ed]749 if ( ExpressionNode *next = dynamic_cast< ExpressionNode * >( list->get_link() ) )
750 list->set_next( flattenCommas( next ) );
[51b73452]751
[b87a5ed]752 return list;
[51b73452]753}
754
[3848e0e]755ExpressionNode *tupleContents( ExpressionNode *tuple ) {
[b87a5ed]756 if ( CompositeExprNode *composite = dynamic_cast< CompositeExprNode * >( tuple ) ) {
757 OperatorNode *op = 0;
758 if ( ( op = dynamic_cast< OperatorNode * >( composite->get_function() )) && ( op->get_type() == OperatorNode::TupleC ) )
759 return composite->get_args();
[cd623a4]760 } // if
[b87a5ed]761 return tuple;
[51b73452]762}
[b87a5ed]763
764// Local Variables: //
765// tab-width: 4 //
766// mode: c++ //
767// compile-command: "make install" //
768// End: //
Note: See TracBrowser for help on using the repository browser.