source: src/Parser/ExpressionNode.cc@ cd623a4

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

constant types, second attempt

  • Property mode set to 100644
File size: 22.7 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
11// Last Modified By : Peter A. Buhr
[cd623a4]12// Last Modified On : Sun Jun 7 07:58:00 2015
13// Update Count : 135
[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
95// Very difficult to separate extra parts of constants during lexing because actions are not allow in the middle of
96// patterns:
97//
98// prefix action constant action suffix
99//
100// Alternatively, breaking a pattern using BEGIN does not work if the following pattern can be empty:
101//
102// constant BEGIN CONT ...
103// <CONT>(...)? BEGIN 0 ... // possible empty suffix
104//
105// because the CONT rule is NOT triggered if the pattern is empty. Hence, constants are reparsed here to determine their
106// type.
[51b73452]107
[59db689]108ConstantNode::ConstantNode( Type t, string *inVal ) : type( t ), value( *inVal ) {
[cd623a4]109 // lexing divides constants into 4 kinds
[a08ba92]110 switch ( type ) {
[59db689]111 case Integer:
[b87a5ed]112 {
[59db689]113 static const BasicType::Kind kind[2][3] = {
114 { BasicType::SignedInt, BasicType::LongSignedInt, BasicType::LongLongSignedInt },
115 { BasicType::UnsignedInt, BasicType::LongUnsignedInt, BasicType::LongLongUnsignedInt },
116 };
117 size_t last = value.length() - 1; // last character of constant
118 unsigned long long v; // converted integral value
119 bool dec = true, Unsigned = false; // decimal, unsigned constant
120 int size; // 0 => int, 1 => long, 2 => long long
121
[cd623a4]122 if ( value[0] == '0' ) { // octal constant ?
[59db689]123 dec = false;
[cd623a4]124 if ( last != 0 && checkX( value[1] ) ) { // hex constant ?
[59db689]125 sscanf( (char *)value.c_str(), "%llx", &v );
126 //printf( "%llx %llu\n", v, v );
127 } else {
128 sscanf( (char *)value.c_str(), "%llo", &v );
129 //printf( "%llo %llu\n", v, v );
130 } // if
[cd623a4]131 } else { // decimal constant ?
[59db689]132 sscanf( (char *)value.c_str(), "%lld", &v );
133 //printf( "%llu %llu\n", v, v );
134 } // if
135
136 if ( v <= INT_MAX ) { // signed int
137 size = 0;
138 } else if ( v <= UINT_MAX ) { // unsigned int
139 size = 0;
140 if ( ! dec ) Unsigned = true; // unsigned
141 } else if ( v <= LONG_MAX ) { // signed long int
142 size = 1;
143 } else if ( v <= ULONG_MAX ) { // signed long int
144 size = 1;
145 if ( ! dec ) Unsigned = true; // unsigned long int
146 } else if ( v <= LLONG_MAX ) { // signed long long int
147 size = 2;
148 } else { // signed long long int
149 size = 2;
150 if ( ! dec ) Unsigned = true; // unsigned long long int
151 } // if
[51b73452]152
[cd623a4]153 if ( checkU( value[last] ) ) { // suffix 'u' ?
[59db689]154 Unsigned = true;
[cd623a4]155 if ( checkL( value[ last - 1 ] ) ) { // suffix 'l' ?
[59db689]156 size = 1;
[cd623a4]157 if ( checkL( value[ last - 1 ] ) ) { // suffix 'll' ?
[59db689]158 size = 2;
159 } // if
160 } // if
[cd623a4]161 } else if ( checkL( value[ last ] ) ) { // suffix 'l' ?
[59db689]162 size = 1;
[cd623a4]163 if ( checkL( value[ last - 1 ] ) ) { // suffix 'll' ?
[59db689]164 size = 2;
165 } // if
[cd623a4]166 if ( checkU( value[ last - 1 ] ) ) { // suffix 'u' ?
[59db689]167 Unsigned = true;
168 } // if
169 } // if
[cd623a4]170 btype = kind[Unsigned][size]; // lookup constant type
171 break;
172 }
173 case Float:
174 {
175 size_t len = value.length() - 1;
176
177 btype = BasicType::Double; // default
178 if ( checkF( value[len] ) ) { // float ?
179 btype = BasicType::Float;
180 } // if
181 if ( checkL( value[len] ) ) { // long double ?
182 btype = BasicType::LongDouble;
183 } // if
[b87a5ed]184 break;
185 }
[59db689]186 case Character:
187 btype = BasicType::Char; // default
188 if ( string( "LUu" ).find( value[0] ) != string::npos ) {
189 // ???
190 } // if
191 break;
192 case String:
193 // array of char
194 if ( string( "LUu" ).find( value[0] ) != string::npos ) {
195 if ( value[0] == 'u' && value[1] == '8' ) {
196 // ???
197 } else {
198 // ???
199 } // if
200 } // if
201 break;
202 } // switch
203} // ConstantNode::ConstantNode
[51b73452]204
[59db689]205ConstantNode *ConstantNode::appendstr( const std::string *newValue ) {
206 assert( newValue != 0 );
207 assert( type == String );
[51b73452]208
[cd623a4]209 // "abc" "def" "ghi" => "abcdefghi", so remove new text from quotes and insert before last quote in old string.
[59db689]210 value.insert( value.length() - 1, newValue->substr( 1, newValue->length() - 2 ) );
211
[cd623a4]212 delete newValue; // allocated by lexer
[b87a5ed]213 return this;
[51b73452]214}
215
[bdd516a]216void ConstantNode::printOneLine( std::ostream &os, int indent ) const {
[59db689]217 os << string( indent, ' ' );
[b87a5ed]218 printDesignation( os );
219
220 switch ( type ) {
221 case Integer:
222 case Float:
223 os << value ;
224 break;
225 case Character:
226 os << "'" << value << "'";
227 break;
228 case String:
229 os << '"' << value << '"';
230 break;
[c7ed6d0]231 } // switch
[51b73452]232
[b87a5ed]233 os << ' ';
[51b73452]234}
235
[bdd516a]236void ConstantNode::print( std::ostream &os, int indent ) const {
[b87a5ed]237 printOneLine( os, indent );
238 os << endl;
[51b73452]239}
240
241Expression *ConstantNode::build() const {
[cd623a4]242 ::Type::Qualifiers q; // no qualifiers on constants
[b87a5ed]243
[59db689]244 switch ( get_type() ) {
[b87a5ed]245 case String:
[59db689]246 {
247 // string should probably be a primitive type
248 ArrayType *at = new ArrayType( q, new BasicType( q, BasicType::Char ),
249 new ConstantExpr(
250 Constant( new BasicType( q, BasicType::UnsignedInt ),
251 toString( value.size() + 1 ) ) ), // account for '\0'
252 false, false );
253 return new ConstantExpr( Constant( at, value ), maybeBuild< Expression >( get_argName() ) );
254 }
255 default:
[cd623a4]256 return new ConstantExpr( Constant( new BasicType( q, btype ), get_value() ), maybeBuild< Expression >( get_argName() ) );
[b87a5ed]257 }
[51b73452]258}
259
[cd623a4]260//##############################################################################
261
[bdd516a]262VarRefNode::VarRefNode() : isLabel( false ) {}
[51b73452]263
[59db689]264VarRefNode::VarRefNode( const string *name_, bool labelp ) : ExpressionNode( name_ ), isLabel( labelp ) {}
[51b73452]265
[3848e0e]266VarRefNode::VarRefNode( const VarRefNode &other ) : ExpressionNode( other ), isLabel( other.isLabel ) {
[51b73452]267}
268
269Expression *VarRefNode::build() const {
[b87a5ed]270 return new NameExpr( get_name(), maybeBuild< Expression >( get_argName() ) );
[51b73452]271}
272
[bdd516a]273void VarRefNode::printOneLine( std::ostream &os, int indent ) const {
[b87a5ed]274 printDesignation( os );
275 os << get_name() << ' ';
[51b73452]276}
277
[bdd516a]278void VarRefNode::print( std::ostream &os, int indent ) const {
[b87a5ed]279 printDesignation( os );
[44b5ca0]280 os << string( indent, ' ' ) << "Referencing: ";
[b87a5ed]281 os << "Variable: " << get_name();
282 os << endl;
[51b73452]283}
284
[cd623a4]285//##############################################################################
286
[bdd516a]287OperatorNode::OperatorNode( Type t ) : type( t ) {}
[51b73452]288
[3848e0e]289OperatorNode::OperatorNode( const OperatorNode &other ) : ExpressionNode( other ), type( other.type ) {
[51b73452]290}
291
292OperatorNode::~OperatorNode() {}
293
[bdd516a]294OperatorNode::Type OperatorNode::get_type( void ) const{
[b87a5ed]295 return type;
[51b73452]296}
297
[3848e0e]298void OperatorNode::printOneLine( std::ostream &os, int indent ) const {
[b87a5ed]299 printDesignation( os );
300 os << OpName[ type ] << ' ';
[51b73452]301}
302
303void OperatorNode::print( std::ostream &os, int indent ) const{
[b87a5ed]304 printDesignation( os );
[44b5ca0]305 os << string( indent, ' ' ) << "Operator: " << OpName[type] << endl;
[b87a5ed]306 return;
[51b73452]307}
308
[59db689]309const char *OperatorNode::get_typename( void ) const{
310 return OpName[ type ];
[51b73452]311}
312
[3848e0e]313const char *OperatorNode::OpName[] = {
[b87a5ed]314 "TupleC", "Comma", "TupleFieldSel",// "TuplePFieldSel", //n-adic
315 // triadic
316 "Cond", "NCond",
317 // diadic
[cd623a4]318 "SizeOf", "AlignOf", "Attr", "CompLit", "Plus", "Minus", "Mul", "Div", "Mod", "Or",
[b87a5ed]319 "And", "BitOr", "BitAnd", "Xor", "Cast", "LShift", "RShift", "LThan", "GThan",
320 "LEThan", "GEThan", "Eq", "Neq", "Assign", "MulAssn", "DivAssn", "ModAssn", "PlusAssn",
321 "MinusAssn", "LSAssn", "RSAssn", "AndAssn", "ERAssn", "OrAssn", "Index", "FieldSel","PFieldSel",
322 "Range",
323 // monadic
324 "UnPlus", "UnMinus", "AddressOf", "PointTo", "Neg", "BitNeg", "Incr", "IncrPost", "Decr", "DecrPost", "LabelAddress"
[3848e0e]325};
[51b73452]326
[cd623a4]327//##############################################################################
328
[bdd516a]329CompositeExprNode::CompositeExprNode( void ) : ExpressionNode(), function( 0 ), arguments( 0 ) {
[51b73452]330}
331
[59db689]332CompositeExprNode::CompositeExprNode( const string *name_ ) : ExpressionNode( name_ ), function( 0 ), arguments( 0 ) {
[51b73452]333}
334
[bdd516a]335CompositeExprNode::CompositeExprNode( ExpressionNode *f, ExpressionNode *args ):
[b87a5ed]336 function( f ), arguments( args ) {
[51b73452]337}
338
[bdd516a]339CompositeExprNode::CompositeExprNode( ExpressionNode *f, ExpressionNode *arg1, ExpressionNode *arg2):
[b87a5ed]340 function( f ), arguments( arg1) {
341 arguments->set_link( arg2);
[51b73452]342}
343
[3848e0e]344CompositeExprNode::CompositeExprNode( const CompositeExprNode &other ) : ExpressionNode( other ), function( maybeClone( other.function ) ) {
[b87a5ed]345 ParseNode *cur = other.arguments;
346 while ( cur ) {
347 if ( arguments ) {
348 arguments->set_link( cur->clone() );
349 } else {
350 arguments = ( ExpressionNode*)cur->clone();
351 } // if
352 cur = cur->get_link();
353 }
[51b73452]354}
355
[3848e0e]356CompositeExprNode::~CompositeExprNode() {
[b87a5ed]357 delete function;
358 delete arguments;
[51b73452]359}
360
361// the names that users use to define operator functions
[3848e0e]362static const char *opFuncName[] = {
[b87a5ed]363 "", "", "",
364 "", "",
365 // diadic
366 "", "", "", "", "?+?", "?-?", "?*?", "?/?", "?%?", "", "",
367 "?|?", "?&?", "?^?", "", "?<<?", "?>>?", "?<?", "?>?", "?<=?",
368 "?>=?", "?==?", "?!=?", "?=?", "?*=?", "?/=?", "?%=?", "?+=?", "?-=?",
369 "?<<=?", "?>>=?", "?&=?", "?^=?", "?|=?", "?[?]", "","","Range",
370 // monadic
371 "+?", "-?", "", "*?", "!?", "~?", "++?", "?++", "--?", "?--", "LabAddress"
[3848e0e]372};
[51b73452]373
374#include "utility.h"
375
[3848e0e]376Expression *CompositeExprNode::build() const {
[b87a5ed]377 OperatorNode *op;
378 std::list<Expression *> args;
[51b73452]379
[b87a5ed]380 buildList( get_args(), args );
381
[cd623a4]382 if ( ! ( op = dynamic_cast<OperatorNode *>( function ) ) ) { // function as opposed to operator
[b87a5ed]383 return new UntypedExpr( function->build(), args, maybeBuild< Expression >( get_argName() ));
[cd623a4]384 } // if
[b87a5ed]385
[cd623a4]386 switch ( op->get_type()) {
387 case OperatorNode::Incr:
388 case OperatorNode::Decr:
389 case OperatorNode::IncrPost:
390 case OperatorNode::DecrPost:
391 case OperatorNode::Assign:
392 case OperatorNode::MulAssn:
393 case OperatorNode::DivAssn:
394 case OperatorNode::ModAssn:
395 case OperatorNode::PlusAssn:
396 case OperatorNode::MinusAssn:
397 case OperatorNode::LSAssn:
398 case OperatorNode::RSAssn:
399 case OperatorNode::AndAssn:
400 case OperatorNode::ERAssn:
401 case OperatorNode::OrAssn:
402 // the rewrite rules for these expressions specify that the first argument has its address taken
403 assert( ! args.empty() );
404 args.front() = new AddressExpr( args.front() );
405 break;
406 default:
407 /* do nothing */
408 ;
409 }
410
411 switch ( op->get_type() ) {
412 case OperatorNode::Incr:
413 case OperatorNode::Decr:
414 case OperatorNode::IncrPost:
415 case OperatorNode::DecrPost:
416 case OperatorNode::Assign:
417 case OperatorNode::MulAssn:
418 case OperatorNode::DivAssn:
419 case OperatorNode::ModAssn:
420 case OperatorNode::PlusAssn:
421 case OperatorNode::MinusAssn:
422 case OperatorNode::LSAssn:
423 case OperatorNode::RSAssn:
424 case OperatorNode::AndAssn:
425 case OperatorNode::ERAssn:
426 case OperatorNode::OrAssn:
427 case OperatorNode::Plus:
428 case OperatorNode::Minus:
429 case OperatorNode::Mul:
430 case OperatorNode::Div:
431 case OperatorNode::Mod:
432 case OperatorNode::BitOr:
433 case OperatorNode::BitAnd:
434 case OperatorNode::Xor:
435 case OperatorNode::LShift:
436 case OperatorNode::RShift:
437 case OperatorNode::LThan:
438 case OperatorNode::GThan:
439 case OperatorNode::LEThan:
440 case OperatorNode::GEThan:
441 case OperatorNode::Eq:
442 case OperatorNode::Neq:
443 case OperatorNode::Index:
444 case OperatorNode::Range:
445 case OperatorNode::UnPlus:
446 case OperatorNode::UnMinus:
447 case OperatorNode::PointTo:
448 case OperatorNode::Neg:
449 case OperatorNode::BitNeg:
450 case OperatorNode::LabelAddress:
451 return new UntypedExpr( new NameExpr( opFuncName[ op->get_type() ] ), args );
452 case OperatorNode::AddressOf:
453 assert( args.size() == 1 );
454 assert( args.front() );
455
456 return new AddressExpr( args.front() );
457 case OperatorNode::Cast:
458 {
459 TypeValueNode * arg = dynamic_cast<TypeValueNode *>( get_args());
460 assert( arg );
[b87a5ed]461
[cd623a4]462 DeclarationNode *decl_node = arg->get_decl();
463 ExpressionNode *expr_node = dynamic_cast<ExpressionNode *>( arg->get_link());
[b87a5ed]464
[cd623a4]465 Type *targetType = decl_node->buildType();
466 if ( dynamic_cast< VoidType* >( targetType ) ) {
467 delete targetType;
468 return new CastExpr( expr_node->build(), maybeBuild< Expression >( get_argName() ) );
469 } else {
470 return new CastExpr( expr_node->build(),targetType, maybeBuild< Expression >( get_argName() ) );
471 } // if
472 }
473 case OperatorNode::FieldSel:
474 {
475 assert( args.size() == 2 );
476
477 NameExpr *member = dynamic_cast<NameExpr *>( args.back());
478 // TupleExpr *memberTup = dynamic_cast<TupleExpr *>( args.back());
[b87a5ed]479
[cd623a4]480 if ( member != 0 ) {
481 UntypedMemberExpr *ret = new UntypedMemberExpr( member->get_name(), args.front());
[b87a5ed]482 delete member;
483 return ret;
[cd623a4]484 /* else if ( memberTup != 0 )
485 {
486 UntypedMemberExpr *ret = new UntypedMemberExpr( memberTup->get_name(), args.front());
487 delete member;
488 return ret;
489 } */
490 } else
491 assert( false );
492 }
493 case OperatorNode::PFieldSel:
494 {
495 assert( args.size() == 2 );
496
497 NameExpr *member = dynamic_cast<NameExpr *>( args.back()); // modify for Tuples xxx
498 assert( member != 0 );
499
500 UntypedExpr *deref = new UntypedExpr( new NameExpr( "*?" ) );
501 deref->get_args().push_back( args.front() );
502
503 UntypedMemberExpr *ret = new UntypedMemberExpr( member->get_name(), deref );
504 delete member;
505 return ret;
506 }
507 case OperatorNode::AlignOf:
508 case OperatorNode::SizeOf:
509 {
[bdd516a]510/// bool isSizeOf = ( op->get_type() == OperatorNode::SizeOf );
[51b73452]511
[cd623a4]512 if ( TypeValueNode * arg = dynamic_cast<TypeValueNode *>( get_args()) ) {
513 return new SizeofExpr( arg->get_decl()->buildType());
514 } else {
515 return new SizeofExpr( args.front());
516 } // if
517 }
518 case OperatorNode::Attr:
519 {
520 VarRefNode *var = dynamic_cast<VarRefNode *>( get_args());
521 assert( var );
522 if ( ! get_args()->get_link() ) {
523 return new AttrExpr( var->build(), ( Expression*)0);
524 } else if ( TypeValueNode * arg = dynamic_cast<TypeValueNode *>( get_args()->get_link()) ) {
525 return new AttrExpr( var->build(), arg->get_decl()->buildType());
526 } else {
527 return new AttrExpr( var->build(), args.back());
528 } // if
529 }
530 case OperatorNode::CompLit:
531 throw UnimplementedError( "C99 compound literals" );
532 // the short-circuited operators
533 case OperatorNode::Or:
534 case OperatorNode::And:
535 assert( args.size() == 2);
536 return new LogicalExpr( notZeroExpr( args.front() ), notZeroExpr( args.back() ), ( op->get_type() == OperatorNode::And ) );
537 case OperatorNode::Cond:
538 {
539 assert( args.size() == 3);
540 std::list< Expression* >::const_iterator i = args.begin();
541 Expression *arg1 = notZeroExpr( *i++ );
542 Expression *arg2 = *i++;
543 Expression *arg3 = *i++;
544 return new ConditionalExpr( arg1, arg2, arg3 );
545 }
546 case OperatorNode::NCond:
547 throw UnimplementedError( "GNU 2-argument conditional expression" );
548 case OperatorNode::Comma:
549 {
[b87a5ed]550 assert( args.size() == 2);
[cd623a4]551 std::list< Expression* >::const_iterator i = args.begin();
552 Expression *ret = *i++;
553 while ( i != args.end() ) {
554 ret = new CommaExpr( ret, *i++ );
[b87a5ed]555 }
[cd623a4]556 return ret;
[3848e0e]557 }
[cd623a4]558 // Tuples
559 case OperatorNode::TupleC:
560 {
561 TupleExpr *ret = new TupleExpr();
562 std::copy( args.begin(), args.end(), back_inserter( ret->get_exprs() ) );
563 return ret;
564 }
565 default:
566 // shouldn't happen
567 return 0;
568 } // switch
[51b73452]569}
570
[bdd516a]571void CompositeExprNode::printOneLine( std::ostream &os, int indent ) const {
[b87a5ed]572 printDesignation( os );
573 os << "( ";
574 function->printOneLine( os, indent );
575 for ( ExpressionNode *cur = arguments; cur != 0; cur = dynamic_cast< ExpressionNode* >( cur->get_link() ) ) {
576 cur->printOneLine( os, indent );
577 }
578 os << ") ";
[51b73452]579}
580
[bdd516a]581void CompositeExprNode::print( std::ostream &os, int indent ) const {
[b87a5ed]582 printDesignation( os );
[44b5ca0]583 os << string( indent, ' ' ) << "Application of: " << endl;
[b87a5ed]584 function->print( os, indent + ParseNode::indent_by );
[51b73452]585
[44b5ca0]586 os << string( indent, ' ' ) ;
[b87a5ed]587 if ( arguments ) {
588 os << "... on arguments: " << endl;
589 arguments->printList( os, indent + ParseNode::indent_by );
590 } else
591 os << "... on no arguments: " << endl;
[51b73452]592}
593
[a08ba92]594void CompositeExprNode::set_function( ExpressionNode *f ) {
[b87a5ed]595 function = f;
[51b73452]596}
597
[a08ba92]598void CompositeExprNode::set_args( ExpressionNode *args ) {
[b87a5ed]599 arguments = args;
[51b73452]600}
601
[bdd516a]602ExpressionNode *CompositeExprNode::get_function( void ) const {
[b87a5ed]603 return function;
[51b73452]604}
605
[bdd516a]606ExpressionNode *CompositeExprNode::get_args( void ) const {
[b87a5ed]607 return arguments;
[51b73452]608}
609
[a08ba92]610void CompositeExprNode::add_arg( ExpressionNode *arg ) {
[b87a5ed]611 if ( arguments )
612 arguments->set_link( arg );
613 else
614 set_args( arg );
[51b73452]615}
616
[cd623a4]617//##############################################################################
618
[bdd516a]619CommaExprNode::CommaExprNode(): CompositeExprNode( new OperatorNode( OperatorNode::Comma )) {}
[51b73452]620
[bdd516a]621CommaExprNode::CommaExprNode( ExpressionNode *exp ) : CompositeExprNode( new OperatorNode( OperatorNode::Comma ), exp ) {
[3848e0e]622}
[51b73452]623
[bdd516a]624CommaExprNode::CommaExprNode( ExpressionNode *exp1, ExpressionNode *exp2) : CompositeExprNode( new OperatorNode( OperatorNode::Comma ), exp1, exp2) {
[51b73452]625}
626
[a08ba92]627CommaExprNode *CommaExprNode::add_to_list( ExpressionNode *exp ) {
[b87a5ed]628 add_arg( exp );
[51b73452]629
[b87a5ed]630 return this;
[51b73452]631}
632
[3848e0e]633CommaExprNode::CommaExprNode( const CommaExprNode &other ) : CompositeExprNode( other ) {
[51b73452]634}
635
[cd623a4]636//##############################################################################
637
[bdd516a]638ValofExprNode::ValofExprNode( StatementNode *s ): body( s ) {}
[51b73452]639
[3848e0e]640ValofExprNode::ValofExprNode( const ValofExprNode &other ) : ExpressionNode( other ), body( maybeClone( body ) ) {
[51b73452]641}
642
643ValofExprNode::~ValofExprNode() {
[b87a5ed]644 delete body;
[51b73452]645}
646
647void ValofExprNode::print( std::ostream &os, int indent ) const {
[b87a5ed]648 printDesignation( os );
[59db689]649 os << string( indent, ' ' ) << "Valof Expression:" << std::endl;
[b87a5ed]650 get_body()->print( os, indent + 4);
[51b73452]651}
652
[3848e0e]653void ValofExprNode::printOneLine( std::ostream &, int indent ) const {
[b87a5ed]654 assert( false );
[51b73452]655}
656
657Expression *ValofExprNode::build() const {
[b87a5ed]658 return new UntypedValofExpr ( get_body()->build(), maybeBuild< Expression >( get_argName() ) );
[3848e0e]659}
660
[cd623a4]661//##############################################################################
662
[bdd516a]663ForCtlExprNode::ForCtlExprNode( ParseNode *init_, ExpressionNode *cond, ExpressionNode *incr ) throw ( SemanticError ) : condition( cond ), change( incr ) {
[b87a5ed]664 if ( init_ == 0 )
665 init = 0;
666 else {
667 DeclarationNode *decl;
668 ExpressionNode *exp;
669
[a61fea9a]670 if (( decl = dynamic_cast<DeclarationNode *>(init_) ) != 0)
[b87a5ed]671 init = new StatementNode( decl );
672 else if (( exp = dynamic_cast<ExpressionNode *>( init_)) != 0)
673 init = new StatementNode( StatementNode::Exp, exp );
674 else
675 throw SemanticError("Error in for control expression");
676 }
[51b73452]677}
678
679ForCtlExprNode::ForCtlExprNode( const ForCtlExprNode &other )
[b87a5ed]680 : ExpressionNode( other ), init( maybeClone( other.init ) ), condition( maybeClone( other.condition ) ), change( maybeClone( other.change ) ) {
[51b73452]681}
682
[a08ba92]683ForCtlExprNode::~ForCtlExprNode() {
[b87a5ed]684 delete init;
685 delete condition;
686 delete change;
[51b73452]687}
688
689Expression *ForCtlExprNode::build() const {
[b87a5ed]690 // this shouldn't be used!
691 assert( false );
692 return 0;
[51b73452]693}
694
695void ForCtlExprNode::print( std::ostream &os, int indent ) const{
[59db689]696 os << string( indent,' ' ) << "For Control Expression -- :" << endl;
[a61fea9a]697
[59db689]698 os << string( indent + 2, ' ' ) << "initialization:" << endl;
[a61fea9a]699 if ( init != 0 )
700 init->printList( os, indent + 4 );
701
702 os << string( indent + 2, ' ' ) << "condition: " << endl;
703 if ( condition != 0 )
704 condition->print( os, indent + 4 );
[59db689]705 os << string( indent + 2, ' ' ) << "increment: " << endl;
[a61fea9a]706 if ( change != 0 )
707 change->print( os, indent + 4 );
[51b73452]708}
709
[3848e0e]710void ForCtlExprNode::printOneLine( std::ostream &, int indent ) const {
[b87a5ed]711 assert( false );
[51b73452]712}
713
[cd623a4]714//##############################################################################
715
716TypeValueNode::TypeValueNode( DeclarationNode *decl ) : decl( decl ) {
[51b73452]717}
718
[cd623a4]719TypeValueNode::TypeValueNode( const TypeValueNode &other ) : ExpressionNode( other ), decl( maybeClone( other.decl ) ) {
[51b73452]720}
721
[3848e0e]722Expression *TypeValueNode::build() const {
[b87a5ed]723 return new TypeExpr( decl->buildType() );
[51b73452]724}
725
[bdd516a]726void TypeValueNode::print( std::ostream &os, int indent ) const {
[b87a5ed]727 os << std::string( indent, ' ' ) << "Type:";
728 get_decl()->print( os, indent + 2);
[51b73452]729}
730
[bdd516a]731void TypeValueNode::printOneLine( std::ostream &os, int indent ) const {
[b87a5ed]732 os << "Type:";
733 get_decl()->print( os, indent + 2);
[51b73452]734}
735
[3848e0e]736ExpressionNode *flattenCommas( ExpressionNode *list ) {
[cd623a4]737 if ( CompositeExprNode *composite = dynamic_cast< CompositeExprNode * >( list ) ) {
738 OperatorNode *op;
739 if ( ( op = dynamic_cast< OperatorNode * >( composite->get_function() )) && ( op->get_type() == OperatorNode::Comma ) ) {
740 if ( ExpressionNode *next = dynamic_cast< ExpressionNode * >( list->get_link() ) )
741 composite->add_arg( next );
742 return flattenCommas( composite->get_args() );
743 } // if
744 } // if
[51b73452]745
[b87a5ed]746 if ( ExpressionNode *next = dynamic_cast< ExpressionNode * >( list->get_link() ) )
747 list->set_next( flattenCommas( next ) );
[51b73452]748
[b87a5ed]749 return list;
[51b73452]750}
751
[3848e0e]752ExpressionNode *tupleContents( ExpressionNode *tuple ) {
[b87a5ed]753 if ( CompositeExprNode *composite = dynamic_cast< CompositeExprNode * >( tuple ) ) {
754 OperatorNode *op = 0;
755 if ( ( op = dynamic_cast< OperatorNode * >( composite->get_function() )) && ( op->get_type() == OperatorNode::TupleC ) )
756 return composite->get_args();
[cd623a4]757 } // if
[b87a5ed]758 return tuple;
[51b73452]759}
[b87a5ed]760
761// Local Variables: //
762// tab-width: 4 //
763// mode: c++ //
764// compile-command: "make install" //
765// End: //
Note: See TracBrowser for help on using the repository browser.