source: src/Parser/ExpressionNode.cc@ d58ebf3

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 d58ebf3 was 51b1202, checked in by Peter A. Buhr <pabuhr@…>, 10 years ago

move constant/string to unary_expression, temporarily separate asm and local label, introduce DesignatorNode

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