Ignore:
Timestamp:
Dec 3, 2014, 3:08:38 PM (9 years ago)
Author:
Peter A. Buhr <pabuhr@…>
Branches:
ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, ctor, deferred_resn, demangler, enum, forall-pointer-decay, gc_noraii, jacob/cs343-translation, jenkins-sandbox, master, memory, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, string, with_gc
Children:
d9a0e76
Parents:
42dcae7
Message:

underscore changes, ptrdiff_t changes, formating, _Bool prelude

File:
1 edited

Legend:

Unmodified
Added
Removed
  • translator/Parser/ExpressionNode.cc

    r42dcae7 r3848e0e  
    1 /* -*- C++ -*- */
    21#include <cassert>
    32#include <cctype>
     
    1514using namespace std;
    1615
    17 ExpressionNode::ExpressionNode() : ParseNode(), argName( 0 ) {
    18 }
     16ExpressionNode::ExpressionNode() : ParseNode(), argName( 0 ) {}
    1917
    2018ExpressionNode::ExpressionNode(string *name_) : ParseNode( *name_ ), argName( 0 ) {
    21   delete name_;
    22 }
    23 
    24 ExpressionNode::ExpressionNode( const ExpressionNode &other )
    25   : ParseNode( other.name )
    26 {
    27   if( other.argName ) {
    28     argName = other.argName->clone();
    29   } else {
    30     argName = 0;
    31   }
     19    delete name_;
     20}
     21
     22ExpressionNode::ExpressionNode( const ExpressionNode &other ) : ParseNode( other.name ) {
     23    if ( other.argName ) {
     24        argName = other.argName->clone();
     25    } else {
     26        argName = 0;
     27    }
    3228}
    3329
    3430ExpressionNode * ExpressionNode::set_asArgName( std::string *aName ) {
    35   argName = new VarRefNode(aName);
    36   return this;
     31    argName = new VarRefNode(aName);
     32    return this;
    3733}
    3834
    3935ExpressionNode * ExpressionNode::set_asArgName( ExpressionNode *aDesignator ) {
    40   argName = aDesignator;
    41   return this;
     36    argName = aDesignator;
     37    return this;
    4238}
    4339
    4440void ExpressionNode::printDesignation( std::ostream &os, int indent ) const {
    45   if( argName ) {
    46     os << string(' ', indent) << "(designated by:  ";
    47     argName->printOneLine(os, indent );
    48     os << ")" << std::endl;
    49   }
    50 }
    51 
    52 NullExprNode::NullExprNode()
    53 {
    54 }
    55 
    56 NullExprNode *
    57 NullExprNode::clone() const
    58 {
    59   return new NullExprNode();
    60 }
    61 
    62 void
    63 NullExprNode::print(std::ostream & os, int indent) const
    64 {
    65   printDesignation(os);
    66   os << "null expression";
    67 }
    68 
    69 void
    70 NullExprNode::printOneLine(std::ostream & os, int indent) const
    71 {
    72   printDesignation(os);
    73   os << "null";
    74 }
    75 
    76 Expression *
    77 NullExprNode::build() const
    78 {
    79   return 0;
     41    if ( argName ) {
     42        os << string(' ', indent) << "(designated by:  ";
     43        argName->printOneLine(os, indent );
     44        os << ")" << std::endl;
     45    }
     46}
     47
     48NullExprNode::NullExprNode() {}
     49
     50NullExprNode *NullExprNode::clone() const {
     51    return new NullExprNode();
     52}
     53
     54void NullExprNode::print(std::ostream & os, int indent) const {
     55    printDesignation(os);
     56    os << "null expression";
     57}
     58
     59void NullExprNode::printOneLine(std::ostream & os, int indent) const {
     60    printDesignation(os);
     61    os << "null";
     62}
     63
     64Expression *NullExprNode::build() const {
     65    return 0;
    8066}
    8167
    8268CommaExprNode *ExpressionNode::add_to_list(ExpressionNode *exp){
    83   return new CommaExprNode(this, exp );
     69    return new CommaExprNode(this, exp );
    8470}
    8571
    8672//  enum ConstantNode::Type =  { Integer, Float, Character, String, Range }
    8773
    88 ConstantNode::ConstantNode(void) :
    89   ExpressionNode(), sign(true), longs(0), size(0)
    90 {}
    91 
    92 ConstantNode::ConstantNode(string *name_) :
    93   ExpressionNode(name_), sign(true), longs(0), size(0)
    94 {}
    95 
    96 ConstantNode::ConstantNode(Type t, string *inVal) :
    97   type(t), sign(true), longs(0), size(0)
    98 {
    99   if( inVal ) {
    100     value = *inVal;
    101     delete inVal;
    102   } else {
    103     value = "";
    104   }
    105 
    106   classify(value);
     74ConstantNode::ConstantNode(void) : ExpressionNode(), sign(true), longs(0), size(0) {}
     75
     76ConstantNode::ConstantNode(string *name_) : ExpressionNode(name_), sign(true), longs(0), size(0) {}
     77
     78ConstantNode::ConstantNode(Type t, string *inVal) : type(t), sign(true), longs(0), size(0) {
     79    if ( inVal ) {
     80        value = *inVal;
     81        delete inVal;
     82    } else {
     83        value = "";
     84    }
     85
     86    classify(value);
    10787}
    10888
    10989ConstantNode::ConstantNode( const ConstantNode &other )
    110   : ExpressionNode( other ), type( other.type ), value( other.value ), sign( other.sign ), base( other.base ), longs( other.longs ), size( other.size )
    111 {
     90    : ExpressionNode( other ), type( other.type ), value( other.value ), sign( other.sign ), base( other.base ), longs( other.longs ), size( other.size ) {
    11291}
    11392
    11493// for some reason, std::tolower doesn't work as an argument to std::transform in g++ 3.1
    115 inline char
    116 tolower_hack( char c )
    117 {
    118   return std::tolower( c );
     94inline char tolower_hack( char c ) {
     95    return std::tolower( c );
    11996}
    12097
    12198void ConstantNode::classify(std::string &str){
    122   switch(type){
    123     case Integer:
    124     case Float:
    125       {
    126         std::string sfx("");
    127         char c;
    128         int i = str.length() - 1;
    129 
    130         while( i >= 0 && !isxdigit(c = str.at(i--)) )
    131           sfx += c;
    132 
    133         value = str.substr( 0, i + 2 );
    134 
    135         // get rid of underscores
    136         value.erase(remove(value.begin(), value.end(), '_'), value.end());
    137 
    138         std::transform(sfx.begin(), sfx.end(), sfx.begin(), tolower_hack);
    139 
    140         if( sfx.find("ll") != string::npos ){
    141           longs = 2;
    142         } else if (sfx.find("l") != string::npos ){
    143           longs = 1;
     99    switch (type){
     100      case Integer:
     101      case Float:
     102        {
     103            std::string sfx("");
     104            char c;
     105            int i = str.length() - 1;
     106
     107            while ( i >= 0 && !isxdigit(c = str.at(i--)) )
     108                sfx += c;
     109
     110            value = str.substr( 0, i + 2 );
     111
     112            // get rid of underscores
     113            value.erase(remove(value.begin(), value.end(), '_'), value.end());
     114
     115            std::transform(sfx.begin(), sfx.end(), sfx.begin(), tolower_hack);
     116
     117            if ( sfx.find("ll") != string::npos ){
     118                longs = 2;
     119            } else if (sfx.find("l") != string::npos ){
     120                longs = 1;
     121            }
     122
     123            assert((longs >= 0) && (longs <= 2));
     124
     125            if ( sfx.find("u") != string::npos )
     126                sign = false;
     127
     128            break;
    144129        }
    145 
    146         assert((longs >= 0) && (longs <= 2));
    147 
    148         if( sfx.find("u") != string::npos )
    149           sign = false;
    150 
     130      case Character:
     131        {
     132            // remove underscores from hex and oct escapes
     133            if (str.substr(1,2) == "\\x")
     134                value.erase(remove(value.begin(), value.end(), '_'), value.end());
     135
     136            break;
     137        }
     138      default:
     139        // shouldn't be here
     140        ;
     141    }
     142}
     143
     144ConstantNode::Type ConstantNode::get_type(void) const {
     145    return type;
     146}
     147
     148ConstantNode *ConstantNode::append( std::string *newValue ) {
     149    if ( newValue ) {
     150        if (type == String){
     151            std::string temp = *newValue;
     152            value.resize( value.size() - 1 );
     153            value += newValue->substr(1, newValue->size());
     154        } else
     155            value += *newValue;
     156
     157        delete newValue;
     158    }
     159    return this;
     160}
     161
     162void ConstantNode::printOneLine(std::ostream &os, int indent ) const {
     163    os << string(indent, ' ');
     164    printDesignation(os);
     165
     166    switch ( type ) {
     167        /* integers */
     168      case Integer:
     169        os << value ;
    151170        break;
    152       }
    153     case Character:
    154       {
    155         // remove underscores from hex and oct escapes
    156         if(str.substr(1,2) == "\\x")
    157           value.erase(remove(value.begin(), value.end(), '_'), value.end());
    158 
     171      case Float:
     172        os << value ;
    159173        break;
    160       }
    161   default:
    162     // shouldn't be here
    163     ;
    164   }
    165 }
    166 
    167 ConstantNode::Type ConstantNode::get_type(void) const {
    168   return type;
    169 }
    170 
    171 ConstantNode*
    172 ConstantNode::append( std::string *newValue )
    173 {
    174   if( newValue ) {
    175     if (type == String){
    176       std::string temp = *newValue;
    177       value.resize( value.size() - 1 );
    178       value += newValue->substr(1, newValue->size());
    179     } else
    180       value += *newValue;
    181 
    182     delete newValue;
    183   }
    184   return this;
    185 }
    186 
    187 void ConstantNode::printOneLine(std::ostream &os, int indent ) const
    188 {
    189   os << string(indent, ' ');
    190   printDesignation(os);
    191 
    192   switch( type ) {
    193     /* integers */
    194   case Integer:
    195       os << value ;
    196       break;
    197   case Float:
    198     os << value ;
    199     break;
    200 
    201   case Character:
    202     os << "'" << value << "'";
    203     break;
    204 
    205   case String:
    206     os << '"' << value << '"';
    207     break;
    208   }
    209 
    210   os << ' ';
    211 }
    212 
    213 void ConstantNode::print(std::ostream &os, int indent ) const
    214 {
    215   printOneLine( os, indent );
    216   os << endl;
     174
     175      case Character:
     176        os << "'" << value << "'";
     177        break;
     178
     179      case String:
     180        os << '"' << value << '"';
     181        break;
     182    }
     183
     184    os << ' ';
     185}
     186
     187void ConstantNode::print(std::ostream &os, int indent ) const {
     188    printOneLine( os, indent );
     189    os << endl;
    217190}
    218191
    219192Expression *ConstantNode::build() const {
    220   ::Type::Qualifiers q;
    221   BasicType *bt;
    222 
    223   switch(get_type()){
    224   case Integer:
    225     /* Cfr. standard 6.4.4.1 */
    226     //bt.set_kind(BasicType::SignedInt);
    227     bt = new BasicType(q, BasicType::SignedInt);
    228     break;
    229 
    230   case Float:
    231     bt = new BasicType(q, BasicType::Float);
    232     break;
    233 
    234   case Character:
    235     bt = new BasicType(q, BasicType::Char);
    236     break;
    237 
    238   case String:
    239     // string should probably be a primitive type
    240     ArrayType *at;
    241     std::string value = get_value();
    242     at = new ArrayType(q, new BasicType(q, BasicType::Char),
    243                                 new ConstantExpr( Constant( new BasicType(q, BasicType::SignedInt),
    244                                                                               toString( value.size() - 1 ) ) ),  // account for '\0'
    245                                 false, false );
    246 
    247     return new ConstantExpr( Constant(at, value), maybeBuild< Expression >( get_argName() ) );
    248   }
    249 
    250   return new ConstantExpr(  Constant(bt, get_value()),  maybeBuild< Expression >( get_argName() ) );
    251 }
    252 
     193    ::Type::Qualifiers q;
     194    BasicType *bt;
     195
     196    switch (get_type()){
     197      case Integer:
     198        /* Cfr. standard 6.4.4.1 */
     199        //bt.set_kind(BasicType::SignedInt);
     200        bt = new BasicType(q, BasicType::SignedInt);
     201        break;
     202      case Float:
     203        bt = new BasicType(q, BasicType::Float);
     204        break;
     205      case Character:
     206        bt = new BasicType(q, BasicType::Char);
     207        break;
     208      case String:
     209        // string should probably be a primitive type
     210        ArrayType *at;
     211        std::string value = get_value();
     212        at = new ArrayType(q, new BasicType(q, BasicType::Char),
     213                           new ConstantExpr( Constant( new BasicType(q, BasicType::SignedInt),
     214                                                       toString( value.size() - 1 ) ) ),  // account for '\0'
     215                           false, false );
     216        return new ConstantExpr( Constant(at, value), maybeBuild< Expression >( get_argName() ) );
     217    }
     218    return new ConstantExpr(  Constant(bt, get_value()),  maybeBuild< Expression >( get_argName() ) );
     219}
    253220
    254221VarRefNode::VarRefNode() : isLabel(false) {}
    255222
    256 VarRefNode::VarRefNode(string *name_, bool labelp) :
    257   ExpressionNode(name_), isLabel(labelp) {}
    258 
    259 VarRefNode::VarRefNode( const VarRefNode &other )
    260   : ExpressionNode( other ), isLabel( other.isLabel )
    261 {
     223VarRefNode::VarRefNode(string *name_, bool labelp) : ExpressionNode(name_), isLabel(labelp) {}
     224
     225VarRefNode::VarRefNode( const VarRefNode &other ) : ExpressionNode( other ), isLabel( other.isLabel ) {
    262226}
    263227
    264228Expression *VarRefNode::build() const {
    265   return new NameExpr( get_name(), maybeBuild< Expression >( get_argName() ) );
     229    return new NameExpr( get_name(), maybeBuild< Expression >( get_argName() ) );
    266230}
    267231
    268232void VarRefNode::printOneLine(std::ostream &os, int indent ) const {
    269   printDesignation(os);
    270   os << get_name() << ' ';
     233    printDesignation(os);
     234    os << get_name() << ' ';
    271235}
    272236
    273237void VarRefNode::print(std::ostream &os, int indent ) const {
    274   printDesignation(os);
    275   os << '\r' << string(indent, ' ') << "Referencing: ";
    276 
    277   os << "Variable: " << get_name();
    278 
    279   os << endl;
    280 }
    281 
    282 
    283 OperatorNode::OperatorNode(Type t):type(t) {}
    284 
    285 OperatorNode::OperatorNode( const OperatorNode &other )
    286   : ExpressionNode( other ), type( other.type )
    287 {
     238    printDesignation(os);
     239    os << '\r' << string(indent, ' ') << "Referencing: ";
     240    os << "Variable: " << get_name();
     241    os << endl;
     242}
     243
     244OperatorNode::OperatorNode(Type t) : type(t) {}
     245
     246OperatorNode::OperatorNode( const OperatorNode &other ) : ExpressionNode( other ), type( other.type ) {
    288247}
    289248
     
    291250
    292251OperatorNode::Type OperatorNode::get_type(void) const{
    293   return type;
    294 }
    295 
    296 void OperatorNode::printOneLine( std::ostream &os, int indent ) const
    297 {
    298   printDesignation(os);
    299   os << OpName[ type ] << ' ';
     252    return type;
     253}
     254
     255void OperatorNode::printOneLine( std::ostream &os, int indent ) const {
     256    printDesignation(os);
     257    os << OpName[ type ] << ' ';
    300258}
    301259
    302260void OperatorNode::print( std::ostream &os, int indent ) const{
    303   printDesignation(os);
    304   os << '\r' << string(indent, ' ') << "Operator: " << OpName[type] << endl;
    305 
    306   return;
     261    printDesignation(os);
     262    os << '\r' << string(indent, ' ') << "Operator: " << OpName[type] << endl;
     263    return;
    307264}
    308265
    309266std::string OperatorNode::get_typename(void) const{
    310   return string(OpName[ type ]);
    311 }
    312 
    313 const char *OperatorNode::OpName[] =
    314   { "TupleC",  "Comma", "TupleFieldSel",// "TuplePFieldSel", //n-adic
     267    return string(OpName[ type ]);
     268}
     269
     270const char *OperatorNode::OpName[] = {
     271    "TupleC",  "Comma", "TupleFieldSel",// "TuplePFieldSel", //n-adic
    315272    // triadic
    316273    "Cond",   "NCond",
    317274    // diadic
    318275    "SizeOf",      "AlignOf", "Attr", "CompLit", "Plus",    "Minus",   "Mul",     "Div",     "Mod",      "Or",
    319       "And",       "BitOr",   "BitAnd",  "Xor",     "Cast",    "LShift",  "RShift",  "LThan",   "GThan",
    320       "LEThan",    "GEThan", "Eq",      "Neq",     "Assign",  "MulAssn", "DivAssn", "ModAssn", "PlusAssn",
    321       "MinusAssn", "LSAssn", "RSAssn",  "AndAssn", "ERAssn",  "OrAssn",  "Index",   "FieldSel","PFieldSel",
    322       "Range",
     276    "And",       "BitOr",   "BitAnd",  "Xor",     "Cast",    "LShift",  "RShift",  "LThan",   "GThan",
     277    "LEThan",    "GEThan", "Eq",      "Neq",     "Assign",  "MulAssn", "DivAssn", "ModAssn", "PlusAssn",
     278    "MinusAssn", "LSAssn", "RSAssn",  "AndAssn", "ERAssn",  "OrAssn",  "Index",   "FieldSel","PFieldSel",
     279    "Range",
    323280    // monadic
    324281    "UnPlus", "UnMinus", "AddressOf", "PointTo", "Neg", "BitNeg", "Incr", "IncrPost", "Decr", "DecrPost", "LabelAddress"
    325   };
     282};
    326283
    327284CompositeExprNode::CompositeExprNode(void) : ExpressionNode(), function( 0 ), arguments( 0 ) {
    328285}
    329286
    330 CompositeExprNode::CompositeExprNode(string *name_) : ExpressionNode(name_), function( 0 ), arguments( 0 )
    331 {
     287CompositeExprNode::CompositeExprNode(string *name_) : ExpressionNode(name_), function( 0 ), arguments( 0 ) {
    332288}
    333289
    334290CompositeExprNode::CompositeExprNode(ExpressionNode *f, ExpressionNode *args):
    335   function(f), arguments(args) {
     291    function(f), arguments(args) {
    336292}
    337293
    338294CompositeExprNode::CompositeExprNode(ExpressionNode *f, ExpressionNode *arg1, ExpressionNode *arg2):
    339   function(f), arguments(arg1) {
    340   arguments->set_link(arg2);
    341 }
    342 
    343 CompositeExprNode::CompositeExprNode( const CompositeExprNode &other )
    344   : ExpressionNode( other ), function( maybeClone( other.function ) )
    345 {
    346   ParseNode *cur = other.arguments;
    347   while( cur ) {
    348     if( arguments ) {
    349       arguments->set_link( cur->clone() );
    350     } else {
    351       arguments = (ExpressionNode*)cur->clone();
    352     }
    353     cur = cur->get_link();
    354   }
    355 }
    356 
    357 CompositeExprNode::~CompositeExprNode()
    358 {
    359   delete function;
    360   delete arguments;
     295    function(f), arguments(arg1) {
     296    arguments->set_link(arg2);
     297}
     298
     299CompositeExprNode::CompositeExprNode( const CompositeExprNode &other ) : ExpressionNode( other ), function( maybeClone( other.function ) ) {
     300    ParseNode *cur = other.arguments;
     301    while ( cur ) {
     302        if ( arguments ) {
     303            arguments->set_link( cur->clone() );
     304        } else {
     305            arguments = (ExpressionNode*)cur->clone();
     306        }
     307        cur = cur->get_link();
     308    }
     309}
     310
     311CompositeExprNode::~CompositeExprNode() {
     312    delete function;
     313    delete arguments;
    361314}
    362315
    363316// the names that users use to define operator functions
    364 static const char *opFuncName[] =
    365   { "",  "", "",
     317static const char *opFuncName[] = {
     318    "",  "", "",
    366319    "",   "",
    367320    // diadic
    368321    "",   "", "", "", "?+?",    "?-?",   "?*?",     "?/?",     "?%?",     "",       "",
    369       "?|?",  "?&?",  "?^?",     "",    "?<<?",  "?>>?",  "?<?",   "?>?",    "?<=?",
    370       "?>=?", "?==?",      "?!=?",     "?=?",  "?*=?", "?/=?", "?%=?", "?+=?", "?-=?",
    371       "?<<=?", "?>>=?",  "?&=?", "?^=?",  "?|=?",  "?[?]",   "","","Range",
     322    "?|?",  "?&?",  "?^?",     "",    "?<<?",  "?>>?",  "?<?",   "?>?",    "?<=?",
     323    "?>=?", "?==?",      "?!=?",     "?=?",  "?*=?", "?/=?", "?%=?", "?+=?", "?-=?",
     324    "?<<=?", "?>>=?",  "?&=?", "?^=?",  "?|=?",  "?[?]",   "","","Range",
    372325    // monadic
    373326    "+?", "-?", "", "*?", "!?", "~?", "++?", "?++", "--?", "?--", "LabAddress"
    374   };
     327};
    375328
    376329#include "utility.h"
     330
    377331Expression *CompositeExprNode::build() const {
    378   OperatorNode *op;
    379   std::list<Expression *> args;
    380 
    381   buildList(get_args(), args);
    382 
    383   if (!( op = dynamic_cast<OperatorNode *>(function)) ){
    384     // a function as opposed to an operator
    385     return new UntypedExpr(function->build(), args, maybeBuild< Expression >( get_argName() ));
    386 
    387   } else {
    388 
    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 
    410     default:
    411       /* do nothing */
    412       ;
    413     }
    414 
    415     switch(op->get_type()){
    416 
    417     case OperatorNode::Incr:
    418     case OperatorNode::Decr:
    419     case OperatorNode::IncrPost:
    420     case OperatorNode::DecrPost:
    421     case OperatorNode::Assign:
    422     case OperatorNode::MulAssn:
    423     case OperatorNode::DivAssn:
    424     case OperatorNode::ModAssn:
    425     case OperatorNode::PlusAssn:
    426     case OperatorNode::MinusAssn:
    427     case OperatorNode::LSAssn:
    428     case OperatorNode::RSAssn:
    429     case OperatorNode::AndAssn:
    430     case OperatorNode::ERAssn:
    431     case OperatorNode::OrAssn:
    432     case OperatorNode::Plus:
    433     case OperatorNode::Minus:
    434     case OperatorNode::Mul:
    435     case OperatorNode::Div:
    436     case OperatorNode::Mod:
    437     case OperatorNode::BitOr:
    438     case OperatorNode::BitAnd:
    439     case OperatorNode::Xor:
    440     case OperatorNode::LShift:
    441     case OperatorNode::RShift:
    442     case OperatorNode::LThan:
    443     case OperatorNode::GThan:
    444     case OperatorNode::LEThan:
    445     case OperatorNode::GEThan:
    446     case OperatorNode::Eq:
    447     case OperatorNode::Neq:
    448     case OperatorNode::Index:
    449     case OperatorNode::Range:
    450     case OperatorNode::UnPlus:
    451     case OperatorNode::UnMinus:
    452     case OperatorNode::PointTo:
    453     case OperatorNode::Neg:
    454     case OperatorNode::BitNeg:
    455     case OperatorNode::LabelAddress:
    456       return new UntypedExpr( new NameExpr( opFuncName[ op->get_type() ] ), args );
    457 
    458     case OperatorNode::AddressOf:
    459       assert( args.size() == 1 );
    460       assert( args.front() );
    461 
    462       return new AddressExpr( args.front() );
    463 
    464     case OperatorNode::Cast:
    465       {
    466         TypeValueNode * arg = dynamic_cast<TypeValueNode *>(get_args());
    467         assert( arg );
    468 
    469         DeclarationNode *decl_node = arg->get_decl();
    470         ExpressionNode *expr_node = dynamic_cast<ExpressionNode *>(arg->get_link());
    471 
    472         Type *targetType = decl_node->buildType();
    473         if( dynamic_cast< VoidType* >( targetType ) ) {
    474           delete targetType;
    475           return new CastExpr( expr_node->build(), maybeBuild< Expression >( get_argName() ) );
    476         } else {
    477           return new CastExpr(expr_node->build(),targetType, maybeBuild< Expression >( get_argName() ) );
    478         }
    479       }
    480 
    481     case OperatorNode::FieldSel:
    482       {
    483         assert( args.size() == 2 );
    484 
    485         NameExpr *member = dynamic_cast<NameExpr *>(args.back());
    486         // TupleExpr *memberTup = dynamic_cast<TupleExpr *>(args.back());
    487 
    488         if ( member != 0 )
    489           {
    490             UntypedMemberExpr *ret = new UntypedMemberExpr(member->get_name(), args.front());
    491             delete member;
    492             return ret;
    493           }
    494         /* else if ( memberTup != 0 )
    495           {
    496             UntypedMemberExpr *ret = new UntypedMemberExpr(memberTup->get_name(), args.front());
    497             delete member;
    498             return ret;
    499             } */
     332    OperatorNode *op;
     333    std::list<Expression *> args;
     334
     335    buildList(get_args(), args);
     336
     337    if ( ! ( op = dynamic_cast<OperatorNode *>(function)) ) {
     338        // a function as opposed to an operator
     339        return new UntypedExpr(function->build(), args, maybeBuild< Expression >( get_argName() ));
     340    } else {
     341        switch (op->get_type()){
     342          case OperatorNode::Incr:
     343          case OperatorNode::Decr:
     344          case OperatorNode::IncrPost:
     345          case OperatorNode::DecrPost:
     346          case OperatorNode::Assign:
     347          case OperatorNode::MulAssn:
     348          case OperatorNode::DivAssn:
     349          case OperatorNode::ModAssn:
     350          case OperatorNode::PlusAssn:
     351          case OperatorNode::MinusAssn:
     352          case OperatorNode::LSAssn:
     353          case OperatorNode::RSAssn:
     354          case OperatorNode::AndAssn:
     355          case OperatorNode::ERAssn:
     356          case OperatorNode::OrAssn:
     357            // the rewrite rules for these expressions specify that the first argument has its address taken
     358            assert( !args.empty() );
     359            args.front() = new AddressExpr( args.front() );
     360            break;
     361          default:
     362            /* do nothing */
     363            ;
     364        }
     365
     366        switch ( op->get_type() ) {
     367          case OperatorNode::Incr:
     368          case OperatorNode::Decr:
     369          case OperatorNode::IncrPost:
     370          case OperatorNode::DecrPost:
     371          case OperatorNode::Assign:
     372          case OperatorNode::MulAssn:
     373          case OperatorNode::DivAssn:
     374          case OperatorNode::ModAssn:
     375          case OperatorNode::PlusAssn:
     376          case OperatorNode::MinusAssn:
     377          case OperatorNode::LSAssn:
     378          case OperatorNode::RSAssn:
     379          case OperatorNode::AndAssn:
     380          case OperatorNode::ERAssn:
     381          case OperatorNode::OrAssn:
     382          case OperatorNode::Plus:
     383          case OperatorNode::Minus:
     384          case OperatorNode::Mul:
     385          case OperatorNode::Div:
     386          case OperatorNode::Mod:
     387          case OperatorNode::BitOr:
     388          case OperatorNode::BitAnd:
     389          case OperatorNode::Xor:
     390          case OperatorNode::LShift:
     391          case OperatorNode::RShift:
     392          case OperatorNode::LThan:
     393          case OperatorNode::GThan:
     394          case OperatorNode::LEThan:
     395          case OperatorNode::GEThan:
     396          case OperatorNode::Eq:
     397          case OperatorNode::Neq:
     398          case OperatorNode::Index:
     399          case OperatorNode::Range:
     400          case OperatorNode::UnPlus:
     401          case OperatorNode::UnMinus:
     402          case OperatorNode::PointTo:
     403          case OperatorNode::Neg:
     404          case OperatorNode::BitNeg:
     405          case OperatorNode::LabelAddress:
     406            return new UntypedExpr( new NameExpr( opFuncName[ op->get_type() ] ), args );
     407          case OperatorNode::AddressOf:
     408            assert( args.size() == 1 );
     409            assert( args.front() );
     410
     411            return new AddressExpr( args.front() );
     412          case OperatorNode::Cast:
     413            {
     414                TypeValueNode * arg = dynamic_cast<TypeValueNode *>(get_args());
     415                assert( arg );
     416
     417                DeclarationNode *decl_node = arg->get_decl();
     418                ExpressionNode *expr_node = dynamic_cast<ExpressionNode *>(arg->get_link());
     419
     420                Type *targetType = decl_node->buildType();
     421                if ( dynamic_cast< VoidType* >( targetType ) ) {
     422                    delete targetType;
     423                    return new CastExpr( expr_node->build(), maybeBuild< Expression >( get_argName() ) );
     424                } else {
     425                    return new CastExpr(expr_node->build(),targetType, maybeBuild< Expression >( get_argName() ) );
     426                }
     427            }
     428          case OperatorNode::FieldSel:
     429            {
     430                assert( args.size() == 2 );
     431
     432                NameExpr *member = dynamic_cast<NameExpr *>(args.back());
     433                // TupleExpr *memberTup = dynamic_cast<TupleExpr *>(args.back());
     434
     435                if ( member != 0 )
     436                    {
     437                        UntypedMemberExpr *ret = new UntypedMemberExpr(member->get_name(), args.front());
     438                        delete member;
     439                        return ret;
     440                    }
     441                /* else if ( memberTup != 0 )
     442                   {
     443                   UntypedMemberExpr *ret = new UntypedMemberExpr(memberTup->get_name(), args.front());
     444                   delete member;
     445                   return ret;
     446                   } */
     447                else
     448                    assert( false );
     449            }
     450          case OperatorNode::PFieldSel:
     451            {
     452                assert( args.size() == 2 );
     453
     454                NameExpr *member = dynamic_cast<NameExpr *>(args.back());  // modify for Tuples   xxx
     455                assert( member != 0 );
     456
     457                UntypedExpr *deref = new UntypedExpr( new NameExpr( "*?" ) );
     458                deref->get_args().push_back( args.front() );
     459
     460                UntypedMemberExpr *ret = new UntypedMemberExpr(member->get_name(), deref);
     461                delete member;
     462                return ret;
     463            }
     464          case OperatorNode::AlignOf:
     465          case OperatorNode::SizeOf:
     466            {
     467///     bool isSizeOf = (op->get_type() == OperatorNode::SizeOf);
     468
     469                if ( TypeValueNode * arg = dynamic_cast<TypeValueNode *>(get_args()) ) {
     470                    return new SizeofExpr(arg->get_decl()->buildType());
     471                } else {
     472                    return new SizeofExpr(args.front());
     473                }
     474            }
     475          case OperatorNode::Attr:
     476            {
     477                VarRefNode *var = dynamic_cast<VarRefNode *>(get_args());
     478                assert( var );
     479                if ( !get_args()->get_link() ) {
     480                    return new AttrExpr(var->build(), (Expression*)0);
     481                } else if ( TypeValueNode * arg = dynamic_cast<TypeValueNode *>(get_args()->get_link()) ) {
     482                    return new AttrExpr(var->build(), arg->get_decl()->buildType());
     483                } else {
     484                    return new AttrExpr(var->build(), args.back());
     485                }
     486            }
     487          case OperatorNode::CompLit:
     488            throw UnimplementedError( "C99 compound literals" );
     489            // the short-circuited operators
     490          case OperatorNode::Or:
     491          case OperatorNode::And:
     492            assert(args.size() == 2);
     493            return new LogicalExpr( notZeroExpr( args.front() ), notZeroExpr( args.back() ), (op->get_type() == OperatorNode::And) );
     494          case OperatorNode::Cond:
     495            {
     496                assert(args.size() == 3);
     497                std::list< Expression* >::const_iterator i = args.begin();
     498                Expression *arg1 = notZeroExpr( *i++ );
     499                Expression *arg2 = *i++;
     500                Expression *arg3 = *i++;
     501                return new ConditionalExpr( arg1, arg2, arg3 );
     502            }
     503          case OperatorNode::NCond:
     504            throw UnimplementedError( "GNU 2-argument conditional expression" );
     505          case OperatorNode::Comma:
     506            {
     507                assert(args.size() == 2);
     508                std::list< Expression* >::const_iterator i = args.begin();
     509                Expression *ret = *i++;
     510                while ( i != args.end() ) {
     511                    ret = new CommaExpr( ret, *i++ );
     512                }
     513                return ret;
     514            }
     515            // Tuples
     516          case OperatorNode::TupleC:
     517            {
     518                TupleExpr *ret = new TupleExpr();
     519                std::copy( args.begin(), args.end(), back_inserter( ret->get_exprs() ) );
     520                return ret;
     521            }
     522          default:
     523            // shouldn't happen
     524            return 0;
     525        }
     526    }
     527}
     528
     529void CompositeExprNode::printOneLine(std::ostream &os, int indent) const {
     530    printDesignation(os);
     531    os << "( ";
     532    function->printOneLine( os, indent );
     533    for( ExpressionNode *cur = arguments; cur != 0; cur = dynamic_cast< ExpressionNode* >( cur->get_link() ) ) {
     534        cur->printOneLine( os, indent );
     535    }
     536    os << ") ";
     537}
     538
     539void CompositeExprNode::print(std::ostream &os, int indent) const {
     540    printDesignation(os);
     541    os << '\r' << string(indent, ' ') << "Application of: " << endl;
     542    function->print( os, indent + ParseNode::indent_by );
     543
     544    os << '\r' << string(indent, ' ') ;
     545    if ( arguments ) {
     546        os << "... on arguments: " << endl;
     547        arguments->printList(os, indent + ParseNode::indent_by);
     548    } else
     549        os << "... on no arguments: " << endl;
     550}
     551
     552void CompositeExprNode::set_function(ExpressionNode *f){
     553    function = f;
     554}
     555
     556void CompositeExprNode::set_args(ExpressionNode *args){
     557    arguments = args;
     558}
     559
     560ExpressionNode *CompositeExprNode::get_function(void) const {
     561    return function;
     562}
     563
     564ExpressionNode *CompositeExprNode::get_args(void) const {
     565    return arguments;
     566}
     567
     568void CompositeExprNode::add_arg(ExpressionNode *arg){
     569    if (arguments)
     570        arguments->set_link(arg);
     571    else
     572        set_args(arg);
     573}
     574
     575CommaExprNode::CommaExprNode(): CompositeExprNode(new OperatorNode(OperatorNode::Comma)) {}
     576
     577CommaExprNode::CommaExprNode(ExpressionNode *exp) : CompositeExprNode( new OperatorNode(OperatorNode::Comma), exp ) {
     578}
     579
     580CommaExprNode::CommaExprNode(ExpressionNode *exp1, ExpressionNode *exp2) : CompositeExprNode(new OperatorNode(OperatorNode::Comma), exp1, exp2) {
     581}
     582
     583CommaExprNode *CommaExprNode::add_to_list(ExpressionNode *exp){
     584    add_arg(exp);
     585
     586    return this;
     587}
     588
     589CommaExprNode::CommaExprNode( const CommaExprNode &other ) : CompositeExprNode( other ) {
     590}
     591
     592ValofExprNode::ValofExprNode(StatementNode *s): body(s) {}
     593
     594ValofExprNode::ValofExprNode( const ValofExprNode &other ) : ExpressionNode( other ), body( maybeClone( body ) ) {
     595}
     596
     597ValofExprNode::~ValofExprNode() {
     598    delete body;
     599}
     600
     601void ValofExprNode::print( std::ostream &os, int indent ) const {
     602    printDesignation(os);
     603    os << string(indent, ' ') << "Valof Expression:" << std::endl;
     604    get_body()->print(os, indent + 4);
     605}
     606
     607void ValofExprNode::printOneLine( std::ostream &, int indent ) const {
     608    assert( false );
     609}
     610
     611Expression *ValofExprNode::build() const {
     612    return new UntypedValofExpr ( get_body()->build(), maybeBuild< Expression >( get_argName() ) );
     613}
     614
     615ForCtlExprNode::ForCtlExprNode(ParseNode *init_, ExpressionNode *cond, ExpressionNode *incr) throw (SemanticError) : condition(cond), change(incr) {
     616    if ( init_ == 0 )
     617        init = 0;
     618    else {
     619        DeclarationNode *decl;
     620        ExpressionNode *exp;
     621
     622        if ((decl = dynamic_cast<DeclarationNode *>(init_)) != 0)
     623            init = new StatementNode(decl);
     624        else if ((exp = dynamic_cast<ExpressionNode *>(init_)) != 0)
     625            init = new StatementNode(StatementNode::Exp, exp);
    500626        else
    501           assert( false );
    502       }
    503 
    504     case OperatorNode::PFieldSel:
    505       {
    506         assert( args.size() == 2 );
    507 
    508         NameExpr *member = dynamic_cast<NameExpr *>(args.back());  // modify for Tuples   xxx
    509         assert( member != 0 );
    510 
    511         UntypedExpr *deref = new UntypedExpr( new NameExpr( "*?" ) );
    512         deref->get_args().push_back( args.front() );
    513 
    514         UntypedMemberExpr *ret = new UntypedMemberExpr(member->get_name(), deref);
    515         delete member;
    516         return ret;
    517       }
    518 
    519     case OperatorNode::AlignOf:
    520     case OperatorNode::SizeOf:
    521       {
    522 ///     bool isSizeOf = (op->get_type() == OperatorNode::SizeOf);
    523 
    524         if( TypeValueNode * arg = dynamic_cast<TypeValueNode *>(get_args()) ) {
    525           return new SizeofExpr(arg->get_decl()->buildType());
    526         } else {
    527           return new SizeofExpr(args.front());
    528         }
    529       }
    530    
    531     case OperatorNode::Attr:
    532       {
    533         VarRefNode *var = dynamic_cast<VarRefNode *>(get_args());
    534         assert( var );
    535         if( !get_args()->get_link() ) {
    536           return new AttrExpr(var->build(), (Expression*)0);
    537         } else if( TypeValueNode * arg = dynamic_cast<TypeValueNode *>(get_args()->get_link()) ) {
    538           return new AttrExpr(var->build(), arg->get_decl()->buildType());
    539         } else {
    540           return new AttrExpr(var->build(), args.back());
    541         }
    542       }
    543    
    544 
    545     case OperatorNode::CompLit:
    546       throw UnimplementedError( "C99 compound literals" );
    547 
    548       // the short-circuited operators
    549     case OperatorNode::Or:
    550     case OperatorNode::And:
    551       assert(args.size() == 2);
    552       return new LogicalExpr( notZeroExpr( args.front() ), notZeroExpr( args.back() ), (op->get_type() == OperatorNode::And) );
    553 
    554     case OperatorNode::Cond:
    555       {
    556         assert(args.size() == 3);
    557         std::list< Expression* >::const_iterator i = args.begin();
    558         Expression *arg1 = notZeroExpr( *i++ );
    559         Expression *arg2 = *i++;
    560         Expression *arg3 = *i++;
    561         return new ConditionalExpr( arg1, arg2, arg3 );
    562       }
    563 
    564     case OperatorNode::NCond:
    565       throw UnimplementedError( "GNU 2-argument conditional expression" );
    566 
    567     case OperatorNode::Comma:
    568       {
    569         assert(args.size() == 2);
    570         std::list< Expression* >::const_iterator i = args.begin();
    571         Expression *ret = *i++;
    572         while( i != args.end() ) {
    573           ret = new CommaExpr( ret, *i++ );
    574         }
    575         return ret;
    576       }
    577 
    578       // Tuples
    579     case OperatorNode::TupleC:
    580       {
    581         TupleExpr *ret = new TupleExpr();
    582         std::copy( args.begin(), args.end(), back_inserter( ret->get_exprs() ) );
    583         return ret;
    584       }
    585 
    586     default:
    587       // shouldn't happen
    588       return 0;
    589     }
    590   }
    591 }
    592 
    593 void CompositeExprNode::printOneLine(std::ostream &os, int indent) const
    594 {
    595   printDesignation(os);
    596   os << "( ";
    597   function->printOneLine( os, indent );
    598   for( ExpressionNode *cur = arguments; cur != 0; cur = dynamic_cast< ExpressionNode* >( cur->get_link() ) ) {
    599     cur->printOneLine( os, indent );
    600   }
    601   os << ") ";
    602 }
    603 
    604 void CompositeExprNode::print(std::ostream &os, int indent) const
    605 {
    606   printDesignation(os);
    607   os << '\r' << string(indent, ' ') << "Application of: " << endl;
    608   function->print( os, indent + ParseNode::indent_by );
    609 
    610   os << '\r' << string(indent, ' ') ;
    611   if( arguments ) {
    612     os << "... on arguments: " << endl;
    613     arguments->printList(os, indent + ParseNode::indent_by);
    614   } else
    615     os << "... on no arguments: " << endl;
    616 }
    617 
    618 void CompositeExprNode::set_function(ExpressionNode *f){
    619   function = f;
    620 }
    621 
    622 void CompositeExprNode::set_args(ExpressionNode *args){
    623   arguments = args;
    624 }
    625 
    626 ExpressionNode *CompositeExprNode::get_function(void) const {
    627   return function;
    628 }
    629 
    630 ExpressionNode *CompositeExprNode::get_args(void) const {
    631   return arguments;
    632 }
    633 
    634 void CompositeExprNode::add_arg(ExpressionNode *arg){
    635   if(arguments)
    636     arguments->set_link(arg);
    637   else
    638     set_args(arg);
    639 }
    640 
    641 CommaExprNode::CommaExprNode(): CompositeExprNode(new OperatorNode(OperatorNode::Comma)) {}
    642 
    643 CommaExprNode::CommaExprNode(ExpressionNode *exp)
    644   : CompositeExprNode( new OperatorNode(OperatorNode::Comma), exp )
    645  {
    646  }
    647 
    648 CommaExprNode::CommaExprNode(ExpressionNode *exp1, ExpressionNode *exp2)
    649   : CompositeExprNode(new OperatorNode(OperatorNode::Comma), exp1, exp2)
    650 {
    651 }
    652 
    653 CommaExprNode *CommaExprNode::add_to_list(ExpressionNode *exp){
    654   add_arg(exp);
    655 
    656   return this;
    657 }
    658 
    659 CommaExprNode::CommaExprNode( const CommaExprNode &other )
    660   : CompositeExprNode( other )
    661 {
    662 }
    663 
    664 ValofExprNode::ValofExprNode(StatementNode *s): body(s) {}
    665 
    666 ValofExprNode::ValofExprNode( const ValofExprNode &other )
    667   : ExpressionNode( other ), body( maybeClone( body ) )
    668 {
    669 }
    670 
    671 ValofExprNode::~ValofExprNode() {
    672   delete body;
    673 }
    674 
    675 void ValofExprNode::print( std::ostream &os, int indent ) const {
    676   printDesignation(os);
    677   os << string(indent, ' ') << "Valof Expression:" << std::endl;
    678   get_body()->print(os, indent + 4);
    679 }
    680 
    681 void ValofExprNode::printOneLine( std::ostream &, int indent ) const
    682 {
    683   assert( false );
    684 }
    685 
    686 Expression *ValofExprNode::build() const {
    687   return new UntypedValofExpr ( get_body()->build(), maybeBuild< Expression >( get_argName() ) );
    688 }
    689 
    690 ForCtlExprNode::ForCtlExprNode(ParseNode *init_, ExpressionNode *cond, ExpressionNode *incr)
    691   throw (SemanticError)
    692   : condition(cond), change(incr)
    693 {
    694   if(init_ == 0)
    695     init = 0;
    696   else {
    697     DeclarationNode *decl;
    698     ExpressionNode *exp;
    699 
    700     if((decl = dynamic_cast<DeclarationNode *>(init_)) != 0)
    701       init = new StatementNode(decl);
    702     else if((exp = dynamic_cast<ExpressionNode *>(init_)) != 0)
    703       init = new StatementNode(StatementNode::Exp, exp);
    704     else
    705       throw SemanticError("Error in for control expression");
    706   }
     627            throw SemanticError("Error in for control expression");
     628    }
    707629}
    708630
    709631ForCtlExprNode::ForCtlExprNode( const ForCtlExprNode &other )
    710   : ExpressionNode( other ), init( maybeClone( other.init ) ), condition( maybeClone( other.condition ) ), change( maybeClone( other.change ) )
    711 {
     632    : ExpressionNode( other ), init( maybeClone( other.init ) ), condition( maybeClone( other.condition ) ), change( maybeClone( other.change ) ) {
    712633}
    713634
    714635ForCtlExprNode::~ForCtlExprNode(){
    715   delete init;
    716   delete condition;
    717   delete change;
     636    delete init;
     637    delete condition;
     638    delete change;
    718639}
    719640
    720641Expression *ForCtlExprNode::build() const {
    721   // this shouldn't be used!
    722   assert( false );
    723   return 0;
     642    // this shouldn't be used!
     643    assert( false );
     644    return 0;
    724645}
    725646
    726647void ForCtlExprNode::print( std::ostream &os, int indent ) const{
    727   os << string(indent,' ') << "For Control Expression -- : " << endl;
    728 
    729   os << "\r" << string(indent + 2,' ') << "initialization: ";
    730   if(init != 0)
    731     init->print(os, indent + 4);
    732 
    733   os << "\n\r" << string(indent + 2,' ') << "condition: ";
    734   if(condition != 0)
    735     condition->print(os, indent + 4);
    736   os << "\n\r" << string(indent + 2,' ') << "increment: ";
    737   if(change != 0)
    738     change->print(os, indent + 4);
    739 }
    740 
    741 void
    742 ForCtlExprNode::printOneLine( std::ostream &, int indent ) const
    743 {
    744   assert( false );
     648    os << string(indent,' ') << "For Control Expression -- : " << endl;
     649
     650    os << "\r" << string(indent + 2,' ') << "initialization: ";
     651    if (init != 0)
     652        init->print(os, indent + 4);
     653
     654    os << "\n\r" << string(indent + 2,' ') << "condition: ";
     655    if (condition != 0)
     656        condition->print(os, indent + 4);
     657    os << "\n\r" << string(indent + 2,' ') << "increment: ";
     658    if (change != 0)
     659        change->print(os, indent + 4);
     660}
     661
     662void ForCtlExprNode::printOneLine( std::ostream &, int indent ) const {
     663    assert( false );
    745664}
    746665
    747666TypeValueNode::TypeValueNode(DeclarationNode *decl)
    748   : decl( decl )
    749 {
     667    : decl( decl ) {
    750668}
    751669
    752670TypeValueNode::TypeValueNode( const TypeValueNode &other )
    753   : ExpressionNode( other ), decl( maybeClone( other.decl ) )
    754 {
    755 }
    756 
    757 Expression *
    758 TypeValueNode::build() const
    759 {
    760   return new TypeExpr( decl->buildType() );
    761 }
    762 
    763 void
    764 TypeValueNode::print(std::ostream &os, int indent) const
    765 {
    766   os << std::string( indent, ' ' ) << "Type:";
    767   get_decl()->print(os, indent + 2);
    768 }
    769 
    770 void
    771 TypeValueNode::printOneLine(std::ostream &os, int indent) const
    772 {
    773   os << "Type:";
    774   get_decl()->print(os, indent + 2);
    775 }
    776 
    777 ExpressionNode *flattenCommas( ExpressionNode *list )
    778 {
    779   if( CompositeExprNode *composite = dynamic_cast< CompositeExprNode * >( list ) )
    780     {
    781       OperatorNode *op;
    782            if ( (op = dynamic_cast< OperatorNode * >( composite->get_function() )) && (op->get_type() == OperatorNode::Comma) )
    783              {
    784                  if ( ExpressionNode *next = dynamic_cast< ExpressionNode * >( list->get_link() ) )
    785                    composite->add_arg( next );
    786                  return flattenCommas( composite->get_args() );
    787              }
    788     }
    789 
    790   if ( ExpressionNode *next = dynamic_cast< ExpressionNode * >( list->get_link() ) )
    791     list->set_next( flattenCommas( next ) );
    792 
    793   return list;
    794 }
    795 
    796 ExpressionNode *tupleContents( ExpressionNode *tuple )
    797 {
    798   if( CompositeExprNode *composite = dynamic_cast< CompositeExprNode * >( tuple ) ) {
    799     OperatorNode *op = 0;
    800     if ( (op = dynamic_cast< OperatorNode * >( composite->get_function() )) && (op->get_type() == OperatorNode::TupleC) )
    801       return composite->get_args();
    802   }
    803   return tuple;
    804 }
     671    : ExpressionNode( other ), decl( maybeClone( other.decl ) ) {
     672}
     673
     674Expression *TypeValueNode::build() const {
     675    return new TypeExpr( decl->buildType() );
     676}
     677
     678void TypeValueNode::print(std::ostream &os, int indent) const {
     679    os << std::string( indent, ' ' ) << "Type:";
     680    get_decl()->print(os, indent + 2);
     681}
     682
     683void TypeValueNode::printOneLine(std::ostream &os, int indent) const {
     684    os << "Type:";
     685    get_decl()->print(os, indent + 2);
     686}
     687
     688ExpressionNode *flattenCommas( ExpressionNode *list ) {
     689    if ( CompositeExprNode *composite = dynamic_cast< CompositeExprNode * >( list ) )
     690        {
     691            OperatorNode *op;
     692            if ( (op = dynamic_cast< OperatorNode * >( composite->get_function() )) && (op->get_type() == OperatorNode::Comma) )
     693                {
     694                    if ( ExpressionNode *next = dynamic_cast< ExpressionNode * >( list->get_link() ) )
     695                        composite->add_arg( next );
     696                    return flattenCommas( composite->get_args() );
     697                }
     698        }
     699
     700    if ( ExpressionNode *next = dynamic_cast< ExpressionNode * >( list->get_link() ) )
     701        list->set_next( flattenCommas( next ) );
     702
     703    return list;
     704}
     705
     706ExpressionNode *tupleContents( ExpressionNode *tuple ) {
     707    if ( CompositeExprNode *composite = dynamic_cast< CompositeExprNode * >( tuple ) ) {
     708        OperatorNode *op = 0;
     709        if ( (op = dynamic_cast< OperatorNode * >( composite->get_function() )) && (op->get_type() == OperatorNode::TupleC) )
     710            return composite->get_args();
     711    }
     712    return tuple;
     713}
Note: See TracChangeset for help on using the changeset viewer.