source: src/Parser/ExpressionNode.cc @ 59c24b6

ADTaaron-thesisarm-ehast-experimentalcleanup-dtorsctordeferred_resndemanglerenumforall-pointer-decayjacob/cs343-translationjenkins-sandboxmemorynew-astnew-ast-unique-exprnew-envno_listpersistent-indexerpthread-emulationqualifiedEnumresolv-newwith_gc
Last change on this file since 59c24b6 was 59c24b6, checked in by Peter A. Buhr <pabuhr@…>, 8 years ago

fix juxtaposed string concatenation in parser

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