| [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 |  | 
|---|
| [51b73452] | 16 | #include <cassert> | 
|---|
|  | 17 | #include <cctype> | 
|---|
|  | 18 | #include <algorithm> | 
|---|
| [59db689] | 19 | #include <sstream> | 
|---|
|  | 20 | #include <cstdio> | 
|---|
| [51b73452] | 21 |  | 
|---|
|  | 22 | #include "ParseNode.h" | 
|---|
| [630a82a] | 23 | #include "TypeData.h" | 
|---|
| [51b73452] | 24 | #include "SynTree/Constant.h" | 
|---|
|  | 25 | #include "SynTree/Expression.h" | 
|---|
| [630a82a] | 26 | #include "SynTree/Declaration.h" | 
|---|
| [d3b7937] | 27 | #include "Common/UnimplementedError.h" | 
|---|
| [51b73452] | 28 | #include "parseutility.h" | 
|---|
| [d3b7937] | 29 | #include "Common/utility.h" | 
|---|
| [51b73452] | 30 |  | 
|---|
|  | 31 | using namespace std; | 
|---|
|  | 32 |  | 
|---|
| [e04ef3a] | 33 | ExpressionNode::ExpressionNode() : ParseNode() {} | 
|---|
| [51b73452] | 34 |  | 
|---|
| [e04ef3a] | 35 | ExpressionNode::ExpressionNode( const string *name ) : ParseNode( name ) {} | 
|---|
| [51b73452] | 36 |  | 
|---|
| [e04ef3a] | 37 | ExpressionNode::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 | 
|---|
| [51b73452] | 43 | } | 
|---|
|  | 44 |  | 
|---|
| [7f5566b] | 45 | ExpressionNode * ExpressionNode::set_argName( const std::string *aName ) { | 
|---|
| [b87a5ed] | 46 | argName = new VarRefNode( aName ); | 
|---|
|  | 47 | return this; | 
|---|
| [51b73452] | 48 | } | 
|---|
|  | 49 |  | 
|---|
| [7f5566b] | 50 | ExpressionNode * ExpressionNode::set_argName( ExpressionNode *aDesignator ) { | 
|---|
| [b87a5ed] | 51 | argName = aDesignator; | 
|---|
|  | 52 | return this; | 
|---|
| [51b73452] | 53 | } | 
|---|
|  | 54 |  | 
|---|
|  | 55 | void 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 | 
|---|
| [51b73452] | 61 | } | 
|---|
|  | 62 |  | 
|---|
| [cd623a4] | 63 | //############################################################################## | 
|---|
|  | 64 |  | 
|---|
| [3848e0e] | 65 | NullExprNode::NullExprNode() {} | 
|---|
| [51b73452] | 66 |  | 
|---|
| [3848e0e] | 67 | NullExprNode *NullExprNode::clone() const { | 
|---|
| [b87a5ed] | 68 | return new NullExprNode(); | 
|---|
| [51b73452] | 69 | } | 
|---|
|  | 70 |  | 
|---|
| [bdd516a] | 71 | void NullExprNode::print( std::ostream & os, int indent ) const { | 
|---|
| [b87a5ed] | 72 | printDesignation( os ); | 
|---|
|  | 73 | os << "null expression"; | 
|---|
| [51b73452] | 74 | } | 
|---|
|  | 75 |  | 
|---|
| [bdd516a] | 76 | void NullExprNode::printOneLine( std::ostream & os, int indent ) const { | 
|---|
| [b87a5ed] | 77 | printDesignation( os ); | 
|---|
|  | 78 | os << "null"; | 
|---|
| [51b73452] | 79 | } | 
|---|
|  | 80 |  | 
|---|
| [3848e0e] | 81 | Expression *NullExprNode::build() const { | 
|---|
| [b87a5ed] | 82 | return 0; | 
|---|
| [51b73452] | 83 | } | 
|---|
|  | 84 |  | 
|---|
| [a08ba92] | 85 | CommaExprNode *ExpressionNode::add_to_list( ExpressionNode *exp ) { | 
|---|
| [b87a5ed] | 86 | return new CommaExprNode( this, exp ); | 
|---|
| [51b73452] | 87 | } | 
|---|
|  | 88 |  | 
|---|
| [cd623a4] | 89 | //############################################################################## | 
|---|
|  | 90 |  | 
|---|
| [ca35c51] | 91 | ConstantNode::ConstantNode( ConstantExpr *expr ) : expr( expr ) { | 
|---|
| [59db689] | 92 | } // ConstantNode::ConstantNode | 
|---|
| [51b73452] | 93 |  | 
|---|
| [59db689] | 94 | ConstantNode *ConstantNode::appendstr( const std::string *newValue ) { | 
|---|
|  | 95 | assert( newValue != 0 ); | 
|---|
| [59c24b6] | 96 |  | 
|---|
| [ca35c51] | 97 | string value = expr->get_constant()->get_value(); | 
|---|
| [51b73452] | 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; | 
|---|
| [51b73452] | 105 | } | 
|---|
|  | 106 |  | 
|---|
| [bdd516a] | 107 | void 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 << ' '; | 
|---|
| [51b73452] | 125 | } | 
|---|
|  | 126 |  | 
|---|
| [bdd516a] | 127 | void ConstantNode::print( std::ostream &os, int indent ) const { | 
|---|
| [b87a5ed] | 128 | printOneLine( os, indent ); | 
|---|
|  | 129 | os << endl; | 
|---|
| [51b73452] | 130 | } | 
|---|
|  | 131 |  | 
|---|
|  | 132 | Expression *ConstantNode::build() const { | 
|---|
| [ca35c51] | 133 | return expr->clone(); | 
|---|
| [51b73452] | 134 | } | 
|---|
|  | 135 |  | 
|---|
| [cd623a4] | 136 | //############################################################################## | 
|---|
|  | 137 |  | 
|---|
| [bdd516a] | 138 | VarRefNode::VarRefNode() : isLabel( false ) {} | 
|---|
| [51b73452] | 139 |  | 
|---|
| [59db689] | 140 | VarRefNode::VarRefNode( const string *name_, bool labelp ) : ExpressionNode( name_ ), isLabel( labelp ) {} | 
|---|
| [51b73452] | 141 |  | 
|---|
| [3848e0e] | 142 | VarRefNode::VarRefNode( const VarRefNode &other ) : ExpressionNode( other ), isLabel( other.isLabel ) { | 
|---|
| [51b73452] | 143 | } | 
|---|
|  | 144 |  | 
|---|
|  | 145 | Expression *VarRefNode::build() const { | 
|---|
| [b87a5ed] | 146 | return new NameExpr( get_name(), maybeBuild< Expression >( get_argName() ) ); | 
|---|
| [51b73452] | 147 | } | 
|---|
|  | 148 |  | 
|---|
| [bdd516a] | 149 | void VarRefNode::printOneLine( std::ostream &os, int indent ) const { | 
|---|
| [b87a5ed] | 150 | printDesignation( os ); | 
|---|
|  | 151 | os << get_name() << ' '; | 
|---|
| [51b73452] | 152 | } | 
|---|
|  | 153 |  | 
|---|
| [bdd516a] | 154 | void 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; | 
|---|
| [51b73452] | 159 | } | 
|---|
|  | 160 |  | 
|---|
| [cd623a4] | 161 | //############################################################################## | 
|---|
|  | 162 |  | 
|---|
| [51b1202] | 163 | DesignatorNode::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 |  | 
|---|
|  | 184 | DesignatorNode::DesignatorNode( const DesignatorNode &other ) : ExpressionNode( other ), isArrayIndex( other.isArrayIndex ) { | 
|---|
|  | 185 | } | 
|---|
|  | 186 |  | 
|---|
| [e869d663] | 187 | class DesignatorFixer : public Mutator { | 
|---|
|  | 188 | public: | 
|---|
|  | 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] | 199 | Expression *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 |  | 
|---|
|  | 212 | void 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 |  | 
|---|
|  | 225 | void 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] | 240 | static 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] | 253 | OperatorNode::OperatorNode( Type t ) : type( t ) {} | 
|---|
| [51b73452] | 254 |  | 
|---|
| [3848e0e] | 255 | OperatorNode::OperatorNode( const OperatorNode &other ) : ExpressionNode( other ), type( other.type ) { | 
|---|
| [51b73452] | 256 | } | 
|---|
|  | 257 |  | 
|---|
|  | 258 | OperatorNode::~OperatorNode() {} | 
|---|
|  | 259 |  | 
|---|
| [bdd516a] | 260 | OperatorNode::Type OperatorNode::get_type( void ) const{ | 
|---|
| [b87a5ed] | 261 | return type; | 
|---|
| [51b73452] | 262 | } | 
|---|
|  | 263 |  | 
|---|
| [3848e0e] | 264 | void OperatorNode::printOneLine( std::ostream &os, int indent ) const { | 
|---|
| [b87a5ed] | 265 | printDesignation( os ); | 
|---|
| [5721a6d] | 266 | os << opName[ type ] << ' '; | 
|---|
| [51b73452] | 267 | } | 
|---|
|  | 268 |  | 
|---|
|  | 269 | void OperatorNode::print( std::ostream &os, int indent ) const{ | 
|---|
| [b87a5ed] | 270 | printDesignation( os ); | 
|---|
| [5721a6d] | 271 | os << string( indent, ' ' ) << "Operator: " << opName[type] << endl; | 
|---|
| [b87a5ed] | 272 | return; | 
|---|
| [51b73452] | 273 | } | 
|---|
|  | 274 |  | 
|---|
| [59db689] | 275 | const char *OperatorNode::get_typename( void ) const{ | 
|---|
| [5721a6d] | 276 | return opName[ type ]; | 
|---|
| [51b73452] | 277 | } | 
|---|
|  | 278 |  | 
|---|
| [cd623a4] | 279 | //############################################################################## | 
|---|
|  | 280 |  | 
|---|
| [7f5566b] | 281 | CompositeExprNode::CompositeExprNode() : ExpressionNode(), function( 0 ), arguments( 0 ) { | 
|---|
| [51b73452] | 282 | } | 
|---|
|  | 283 |  | 
|---|
| [59db689] | 284 | CompositeExprNode::CompositeExprNode( const string *name_ ) : ExpressionNode( name_ ), function( 0 ), arguments( 0 ) { | 
|---|
| [51b73452] | 285 | } | 
|---|
|  | 286 |  | 
|---|
| [bdd516a] | 287 | CompositeExprNode::CompositeExprNode( ExpressionNode *f, ExpressionNode *args ): | 
|---|
| [b87a5ed] | 288 | function( f ), arguments( args ) { | 
|---|
| [51b73452] | 289 | } | 
|---|
|  | 290 |  | 
|---|
| [bdd516a] | 291 | CompositeExprNode::CompositeExprNode( ExpressionNode *f, ExpressionNode *arg1, ExpressionNode *arg2): | 
|---|
| [097e2b0] | 292 | function( f ), arguments( arg1 ) { | 
|---|
|  | 293 | arguments->set_link( arg2 ); | 
|---|
| [51b73452] | 294 | } | 
|---|
|  | 295 |  | 
|---|
| [0caaa6a] | 296 | CompositeExprNode::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 | } | 
|---|
| [51b73452] | 306 | } | 
|---|
|  | 307 |  | 
|---|
| [3848e0e] | 308 | CompositeExprNode::~CompositeExprNode() { | 
|---|
| [b87a5ed] | 309 | delete function; | 
|---|
|  | 310 | delete arguments; | 
|---|
| [51b73452] | 311 | } | 
|---|
|  | 312 |  | 
|---|
| [d3b7937] | 313 | #include "Common/utility.h" | 
|---|
| [51b73452] | 314 |  | 
|---|
| [3848e0e] | 315 | Expression *CompositeExprNode::build() const { | 
|---|
| [b87a5ed] | 316 | OperatorNode *op; | 
|---|
|  | 317 | std::list<Expression *> args; | 
|---|
| [51b73452] | 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 | 
|---|
| [51b73452] | 521 | } | 
|---|
|  | 522 |  | 
|---|
| [bdd516a] | 523 | void 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 << ") "; | 
|---|
| [51b73452] | 531 | } | 
|---|
|  | 532 |  | 
|---|
| [bdd516a] | 533 | void 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 ); | 
|---|
| [51b73452] | 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; | 
|---|
| [51b73452] | 544 | } | 
|---|
|  | 545 |  | 
|---|
| [a08ba92] | 546 | void CompositeExprNode::set_function( ExpressionNode *f ) { | 
|---|
| [b87a5ed] | 547 | function = f; | 
|---|
| [51b73452] | 548 | } | 
|---|
|  | 549 |  | 
|---|
| [a08ba92] | 550 | void CompositeExprNode::set_args( ExpressionNode *args ) { | 
|---|
| [b87a5ed] | 551 | arguments = args; | 
|---|
| [51b73452] | 552 | } | 
|---|
|  | 553 |  | 
|---|
| [bdd516a] | 554 | ExpressionNode *CompositeExprNode::get_function( void ) const { | 
|---|
| [b87a5ed] | 555 | return function; | 
|---|
| [51b73452] | 556 | } | 
|---|
|  | 557 |  | 
|---|
| [bdd516a] | 558 | ExpressionNode *CompositeExprNode::get_args( void ) const { | 
|---|
| [b87a5ed] | 559 | return arguments; | 
|---|
| [51b73452] | 560 | } | 
|---|
|  | 561 |  | 
|---|
| [a08ba92] | 562 | void CompositeExprNode::add_arg( ExpressionNode *arg ) { | 
|---|
| [b87a5ed] | 563 | if ( arguments ) | 
|---|
|  | 564 | arguments->set_link( arg ); | 
|---|
|  | 565 | else | 
|---|
|  | 566 | set_args( arg ); | 
|---|
| [51b73452] | 567 | } | 
|---|
|  | 568 |  | 
|---|
| [cd623a4] | 569 | //############################################################################## | 
|---|
|  | 570 |  | 
|---|
| [7f5566b] | 571 | Expression *AsmExprNode::build() const { | 
|---|
| [e04ef3a] | 572 | return new AsmExpr( maybeBuild< Expression >( inout ), (ConstantExpr *)maybeBuild<Expression>(constraint), maybeBuild<Expression>(operand) ); | 
|---|
| [7f5566b] | 573 | } | 
|---|
|  | 574 |  | 
|---|
|  | 575 | void 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 |  | 
|---|
|  | 591 | void 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 |  | 
|---|
|  | 604 | void LabelNode::print( std::ostream &os, int indent ) const {} | 
|---|
|  | 605 |  | 
|---|
|  | 606 | void LabelNode::printOneLine( std::ostream &os, int indent ) const {} | 
|---|
|  | 607 |  | 
|---|
|  | 608 | //############################################################################## | 
|---|
|  | 609 |  | 
|---|
| [bdd516a] | 610 | CommaExprNode::CommaExprNode(): CompositeExprNode( new OperatorNode( OperatorNode::Comma )) {} | 
|---|
| [51b73452] | 611 |  | 
|---|
| [bdd516a] | 612 | CommaExprNode::CommaExprNode( ExpressionNode *exp ) : CompositeExprNode( new OperatorNode( OperatorNode::Comma ), exp ) { | 
|---|
| [3848e0e] | 613 | } | 
|---|
| [51b73452] | 614 |  | 
|---|
| [bdd516a] | 615 | CommaExprNode::CommaExprNode( ExpressionNode *exp1, ExpressionNode *exp2) : CompositeExprNode( new OperatorNode( OperatorNode::Comma ), exp1, exp2) { | 
|---|
| [51b73452] | 616 | } | 
|---|
|  | 617 |  | 
|---|
| [a08ba92] | 618 | CommaExprNode *CommaExprNode::add_to_list( ExpressionNode *exp ) { | 
|---|
| [b87a5ed] | 619 | add_arg( exp ); | 
|---|
| [51b73452] | 620 |  | 
|---|
| [b87a5ed] | 621 | return this; | 
|---|
| [51b73452] | 622 | } | 
|---|
|  | 623 |  | 
|---|
| [3848e0e] | 624 | CommaExprNode::CommaExprNode( const CommaExprNode &other ) : CompositeExprNode( other ) { | 
|---|
| [51b73452] | 625 | } | 
|---|
|  | 626 |  | 
|---|
| [cd623a4] | 627 | //############################################################################## | 
|---|
|  | 628 |  | 
|---|
| [bdd516a] | 629 | ValofExprNode::ValofExprNode( StatementNode *s ): body( s ) {} | 
|---|
| [51b73452] | 630 |  | 
|---|
| [3848e0e] | 631 | ValofExprNode::ValofExprNode( const ValofExprNode &other ) : ExpressionNode( other ), body( maybeClone( body ) ) { | 
|---|
| [51b73452] | 632 | } | 
|---|
|  | 633 |  | 
|---|
|  | 634 | ValofExprNode::~ValofExprNode() { | 
|---|
| [b87a5ed] | 635 | delete body; | 
|---|
| [51b73452] | 636 | } | 
|---|
|  | 637 |  | 
|---|
|  | 638 | void 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); | 
|---|
| [51b73452] | 642 | } | 
|---|
|  | 643 |  | 
|---|
| [3848e0e] | 644 | void ValofExprNode::printOneLine( std::ostream &, int indent ) const { | 
|---|
| [b87a5ed] | 645 | assert( false ); | 
|---|
| [51b73452] | 646 | } | 
|---|
|  | 647 |  | 
|---|
|  | 648 | Expression *ValofExprNode::build() const { | 
|---|
| [e04ef3a] | 649 | return new UntypedValofExpr ( maybeBuild<Statement>(get_body()), maybeBuild< Expression >( get_argName() ) ); | 
|---|
| [3848e0e] | 650 | } | 
|---|
|  | 651 |  | 
|---|
| [cd623a4] | 652 | //############################################################################## | 
|---|
|  | 653 |  | 
|---|
| [bdd516a] | 654 | ForCtlExprNode::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 | } | 
|---|
| [51b73452] | 668 | } | 
|---|
|  | 669 |  | 
|---|
|  | 670 | ForCtlExprNode::ForCtlExprNode( const ForCtlExprNode &other ) | 
|---|
| [b87a5ed] | 671 | : ExpressionNode( other ), init( maybeClone( other.init ) ), condition( maybeClone( other.condition ) ), change( maybeClone( other.change ) ) { | 
|---|
| [51b73452] | 672 | } | 
|---|
|  | 673 |  | 
|---|
| [a08ba92] | 674 | ForCtlExprNode::~ForCtlExprNode() { | 
|---|
| [b87a5ed] | 675 | delete init; | 
|---|
|  | 676 | delete condition; | 
|---|
|  | 677 | delete change; | 
|---|
| [51b73452] | 678 | } | 
|---|
|  | 679 |  | 
|---|
|  | 680 | Expression *ForCtlExprNode::build() const { | 
|---|
| [b87a5ed] | 681 | // this shouldn't be used! | 
|---|
|  | 682 | assert( false ); | 
|---|
|  | 683 | return 0; | 
|---|
| [51b73452] | 684 | } | 
|---|
|  | 685 |  | 
|---|
|  | 686 | void 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 ); | 
|---|
| [51b73452] | 699 | } | 
|---|
|  | 700 |  | 
|---|
| [3848e0e] | 701 | void ForCtlExprNode::printOneLine( std::ostream &, int indent ) const { | 
|---|
| [b87a5ed] | 702 | assert( false ); | 
|---|
| [51b73452] | 703 | } | 
|---|
|  | 704 |  | 
|---|
| [cd623a4] | 705 | //############################################################################## | 
|---|
|  | 706 |  | 
|---|
|  | 707 | TypeValueNode::TypeValueNode( DeclarationNode *decl ) : decl( decl ) { | 
|---|
| [51b73452] | 708 | } | 
|---|
|  | 709 |  | 
|---|
| [cd623a4] | 710 | TypeValueNode::TypeValueNode( const TypeValueNode &other ) : ExpressionNode( other ), decl( maybeClone( other.decl ) ) { | 
|---|
| [51b73452] | 711 | } | 
|---|
|  | 712 |  | 
|---|
| [3848e0e] | 713 | Expression *TypeValueNode::build() const { | 
|---|
| [b87a5ed] | 714 | return new TypeExpr( decl->buildType() ); | 
|---|
| [51b73452] | 715 | } | 
|---|
|  | 716 |  | 
|---|
| [bdd516a] | 717 | void TypeValueNode::print( std::ostream &os, int indent ) const { | 
|---|
| [b87a5ed] | 718 | os << std::string( indent, ' ' ) << "Type:"; | 
|---|
|  | 719 | get_decl()->print( os, indent + 2); | 
|---|
| [51b73452] | 720 | } | 
|---|
|  | 721 |  | 
|---|
| [bdd516a] | 722 | void TypeValueNode::printOneLine( std::ostream &os, int indent ) const { | 
|---|
| [b87a5ed] | 723 | os << "Type:"; | 
|---|
|  | 724 | get_decl()->print( os, indent + 2); | 
|---|
| [51b73452] | 725 | } | 
|---|
|  | 726 |  | 
|---|
| [630a82a] | 727 |  | 
|---|
|  | 728 | CompoundLiteralNode::CompoundLiteralNode( DeclarationNode *type, InitializerNode *kids ) : type( type ), kids( kids ) {} | 
|---|
|  | 729 | CompoundLiteralNode::CompoundLiteralNode( const CompoundLiteralNode &other ) : ExpressionNode( other ), type( other.type ), kids( other.kids ) {} | 
|---|
|  | 730 |  | 
|---|
|  | 731 | CompoundLiteralNode::~CompoundLiteralNode() { | 
|---|
|  | 732 | delete kids; | 
|---|
|  | 733 | delete type; | 
|---|
|  | 734 | } | 
|---|
|  | 735 |  | 
|---|
|  | 736 | CompoundLiteralNode *CompoundLiteralNode::clone() const { | 
|---|
|  | 737 | return new CompoundLiteralNode( *this ); | 
|---|
|  | 738 | } | 
|---|
|  | 739 |  | 
|---|
|  | 740 | void 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 |  | 
|---|
|  | 752 | void 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 |  | 
|---|
|  | 760 | Expression *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] | 777 | ExpressionNode *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 | 
|---|
| [51b73452] | 786 |  | 
|---|
| [b87a5ed] | 787 | if ( ExpressionNode *next = dynamic_cast< ExpressionNode * >( list->get_link() ) ) | 
|---|
|  | 788 | list->set_next( flattenCommas( next ) ); | 
|---|
| [51b73452] | 789 |  | 
|---|
| [b87a5ed] | 790 | return list; | 
|---|
| [51b73452] | 791 | } | 
|---|
|  | 792 |  | 
|---|
| [3848e0e] | 793 | ExpressionNode *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; | 
|---|
| [51b73452] | 800 | } | 
|---|
| [b87a5ed] | 801 |  | 
|---|
|  | 802 | // Local Variables: // | 
|---|
|  | 803 | // tab-width: 4 // | 
|---|
|  | 804 | // mode: c++ // | 
|---|
|  | 805 | // compile-command: "make install" // | 
|---|
|  | 806 | // End: // | 
|---|