source: src/Parser/ExpressionNode.cc @ e45215c

ADTaaron-thesisarm-ehast-experimentalcleanup-dtorsctordeferred_resndemanglerenumforall-pointer-decaygc_noraiijacob/cs343-translationjenkins-sandboxmemorynew-astnew-ast-unique-exprnew-envno_listpersistent-indexerpthread-emulationqualifiedEnumresolv-newstringwith_gc
Last change on this file since e45215c was 1869adf, checked in by Rob Schluntz <rschlunt@…>, 9 years ago

fix label name in label address expression

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