Changeset 04273e9 for src/Parser/ExpressionNode.cc
- Timestamp:
- Aug 8, 2016, 5:29:03 PM (9 years ago)
- Branches:
- ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, ctor, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
- Children:
- 03da511
- Parents:
- 0853178 (diff), 7bf7fb9 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)links above to see all the changes relative to each parent. - File:
-
- 1 edited
-
src/Parser/ExpressionNode.cc (modified) (9 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/Parser/ExpressionNode.cc
r0853178 r04273e9 10 10 // Created On : Sat May 16 13:17:07 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Aug 5 07:56:23201613 // Update Count : 37512 // Last Modified On : Sun Aug 7 09:23:12 2016 13 // Update Count : 437 14 14 // 15 15 16 16 #include <cassert> 17 17 #include <cctype> 18 #include <climits> 19 #include <cstdio> 18 20 #include <algorithm> 19 21 #include <sstream> 20 #include <cstdio>21 22 22 23 #include "ParseNode.h" … … 37 38 ExpressionNode::ExpressionNode( const ExpressionNode &other ) : ParseNode( other.name ), extension( other.extension ) { 38 39 if ( other.argName ) { 40 std::cout << "ExpressionNode" << std::endl; 39 41 argName = other.argName->clone(); 40 42 } else { … … 83 85 } 84 86 85 // CommaExprNode *ExpressionNode::add_to_list( ExpressionNode *exp ) { 86 // return new CommaExprNode( this, exp ); 87 // } 88 89 //############################################################################## 90 91 ConstantNode::ConstantNode( ConstantExpr *expr ) : expr( expr ) { 92 } // ConstantNode::ConstantNode 93 94 ConstantNode *ConstantNode::appendstr( const std::string *newValue ) { 95 assert( newValue != 0 ); 96 97 string value = expr->get_constant()->get_value(); 98 99 // "abc" "def" "ghi" => "abcdefghi", remove new text from quotes and insert before last quote in old string. 100 value.insert( value.length() - 1, newValue->substr( 1, newValue->length() - 2 ) ); 101 expr->get_constant()->set_value( value ); 102 103 delete newValue; // allocated by lexer 104 return this; 105 } 106 107 void ConstantNode::printOneLine( std::ostream &os, int indent ) const { 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 123 124 // os << ' '; 125 } 126 127 void ConstantNode::print( std::ostream &os, int indent ) const { 128 printOneLine( os, indent ); 129 os << endl; 130 } 131 132 Expression *ConstantNode::build() const { 133 return expr->clone(); 134 } 135 136 //############################################################################## 137 138 VarRefNode::VarRefNode() : isLabel( false ) {} 139 140 VarRefNode::VarRefNode( const string *name_, bool labelp ) : ExpressionNode( name_ ), isLabel( labelp ) {} 87 //############################################################################## 88 89 // Difficult to separate extra parts of constants during lexing because actions are not allow in the middle of patterns: 90 // 91 // prefix action constant action suffix 92 // 93 // Alternatively, breaking a pattern using BEGIN does not work if the following pattern can be empty: 94 // 95 // constant BEGIN CONT ... 96 // <CONT>(...)? BEGIN 0 ... // possible empty suffix 97 // 98 // because the CONT rule is NOT triggered if the pattern is empty. Hence, constants are reparsed here to determine their 99 // type. 100 101 static Type::Qualifiers emptyQualifiers; // no qualifiers on constants 102 103 static inline bool checkU( char c ) { return c == 'u' || c == 'U'; } 104 static inline bool checkL( char c ) { return c == 'l' || c == 'L'; } 105 static inline bool checkF( char c ) { return c == 'f' || c == 'F'; } 106 static inline bool checkD( char c ) { return c == 'd' || c == 'D'; } 107 static inline bool checkI( char c ) { return c == 'i' || c == 'I'; } 108 static inline bool checkX( char c ) { return c == 'x' || c == 'X'; } 109 110 ConstantNode *build_constantInteger( std::string & str ) { 111 static const BasicType::Kind kind[2][3] = { 112 { BasicType::SignedInt, BasicType::LongSignedInt, BasicType::LongLongSignedInt }, 113 { BasicType::UnsignedInt, BasicType::LongUnsignedInt, BasicType::LongLongUnsignedInt }, 114 }; 115 bool dec = true, Unsigned = false; // decimal, unsigned constant 116 int size; // 0 => int, 1 => long, 2 => long long 117 unsigned long long v; // converted integral value 118 size_t last = str.length() - 1; // last character of constant 119 120 if ( str[0] == '0' ) { // octal/hex constant ? 121 dec = false; 122 if ( last != 0 && checkX( str[1] ) ) { // hex constant ? 123 sscanf( (char *)str.c_str(), "%llx", &v ); 124 //printf( "%llx %llu\n", v, v ); 125 } else { // octal constant 126 sscanf( (char *)str.c_str(), "%llo", &v ); 127 //printf( "%llo %llu\n", v, v ); 128 } // if 129 } else { // decimal constant ? 130 sscanf( (char *)str.c_str(), "%llu", &v ); 131 //printf( "%llu %llu\n", v, v ); 132 } // if 133 134 if ( v <= INT_MAX ) { // signed int 135 size = 0; 136 } else if ( v <= UINT_MAX && ! dec ) { // unsigned int 137 size = 0; 138 Unsigned = true; // unsigned 139 } else if ( v <= LONG_MAX ) { // signed long int 140 size = 1; 141 } else if ( v <= ULONG_MAX && ( ! dec || LONG_MAX == LLONG_MAX ) ) { // signed long int 142 size = 1; 143 Unsigned = true; // unsigned long int 144 } else if ( v <= LLONG_MAX ) { // signed long long int 145 size = 2; 146 } else { // unsigned long long int 147 size = 2; 148 Unsigned = true; // unsigned long long int 149 } // if 150 151 if ( checkU( str[last] ) ) { // suffix 'u' ? 152 Unsigned = true; 153 if ( last > 0 && checkL( str[last - 1] ) ) { // suffix 'l' ? 154 size = 1; 155 if ( last > 1 && checkL( str[last - 2] ) ) { // suffix 'll' ? 156 size = 2; 157 } // if 158 } // if 159 } else if ( checkL( str[ last ] ) ) { // suffix 'l' ? 160 size = 1; 161 if ( last > 0 && checkL( str[last - 1] ) ) { // suffix 'll' ? 162 size = 2; 163 if ( last > 1 && checkU( str[last - 2] ) ) { // suffix 'u' ? 164 Unsigned = true; 165 } // if 166 } else { 167 if ( last > 0 && checkU( str[last - 1] ) ) { // suffix 'u' ? 168 Unsigned = true; 169 } // if 170 } // if 171 } // if 172 173 return new ConstantNode( new ConstantExpr( Constant( new BasicType( emptyQualifiers, kind[Unsigned][size] ), str ) ) ); 174 } // build_constantInteger 175 176 ConstantNode *build_constantFloat( std::string & str ) { 177 static const BasicType::Kind kind[2][3] = { 178 { BasicType::Float, BasicType::Double, BasicType::LongDouble }, 179 { BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex }, 180 }; 181 182 bool complx = false; // real, complex 183 int size = 1; // 0 => float, 1 => double (default), 2 => long double 184 // floating-point constant has minimum of 2 characters: 1. or .1 185 size_t last = str.length() - 1; 186 187 if ( checkI( str[last] ) ) { // imaginary ? 188 complx = true; 189 last -= 1; // backup one character 190 } // if 191 192 if ( checkF( str[last] ) ) { // float ? 193 size = 0; 194 } else if ( checkD( str[last] ) ) { // double ? 195 size = 1; 196 } else if ( checkL( str[last] ) ) { // long double ? 197 size = 2; 198 } // if 199 if ( ! complx && checkI( str[last - 1] ) ) { // imaginary ? 200 complx = true; 201 } // if 202 203 return new ConstantNode( new ConstantExpr( Constant( new BasicType( emptyQualifiers, kind[complx][size] ), str ) ) ); 204 } // build_constantFloat 205 206 ConstantNode *build_constantChar( std::string & str ) { 207 return new ConstantNode( new ConstantExpr( Constant( new BasicType( emptyQualifiers, BasicType::Char ), str ) ) ); 208 } // build_constantChar 209 210 ConstantNode *build_constantStr( std::string & str ) { 211 // string should probably be a primitive type 212 ArrayType *at = new ArrayType( emptyQualifiers, new BasicType( emptyQualifiers, BasicType::Char ), 213 new ConstantExpr( Constant( new BasicType( emptyQualifiers, BasicType::UnsignedInt ), 214 toString( str.size()+1-2 ) ) ), // +1 for '\0' and -2 for '"' 215 false, false ); 216 return new ConstantNode( new ConstantExpr( Constant( at, str ) ) ); 217 } // build_constantStr 218 219 //############################################################################## 220 221 //Expression *build_varref( ExpressionNode expr ) { 222 // return new NameExpr( get_name(), maybeBuild<Expression>( get_argName() ) ); 223 //} 224 225 VarRefNode::VarRefNode( const string *name, bool labelp ) : ExpressionNode( name ), isLabel( labelp ) {} 141 226 142 227 VarRefNode::VarRefNode( const VarRefNode &other ) : ExpressionNode( other ), isLabel( other.isLabel ) { … … 171 256 double value; 172 257 if ( ss >> value ) { 173 // this is a floating point constant. It MUST be 174 // ".0" or ".1", otherwise the program is invalid 258 // this is a floating point constant. It MUST be ".0" or ".1", otherwise the program is invalid 175 259 if ( ! (var->get_name() == ".0" || var->get_name() == ".1") ) { 176 260 throw SemanticError( "invalid designator name: " + var->get_name() ); … … 201 285 202 286 if ( isArrayIndex ) { 203 // need to traverse entire structure and change any instances of 0 or 1 to 204 // ConstantExpr 287 // need to traverse entire structure and change any instances of 0 or 1 to ConstantExpr 205 288 DesignatorFixer fixer; 206 289 ret = ret->acceptMutator( fixer ); … … 238 321 //############################################################################## 239 322 240 static const char *opName[] = { 241 "TupleC", "Comma", "TupleFieldSel", // "TuplePFieldSel", // n-adic 242 // triadic 243 "Cond", "NCond", 323 static const char *OperName[] = { 244 324 // diadic 245 "SizeOf", "AlignOf", "OffsetOf", " Attr", "?+?", "?-?", "?*?", "?/?", "?%?", "||", "&&",325 "SizeOf", "AlignOf", "OffsetOf", "?+?", "?-?", "?*?", "?/?", "?%?", "||", "&&", 246 326 "?|?", "?&?", "?^?", "Cast", "?<<?", "?>>?", "?<?", "?>?", "?<=?", "?>=?", "?==?", "?!=?", 247 327 "?=?", "?*=?", "?/=?", "?%=?", "?+=?", "?-=?", "?<<=?", "?>>=?", "?&=?", "?^=?", "?|=?", 248 "?[?]", " FieldSel", "PFieldSel", "...",328 "?[?]", "...", 249 329 // monadic 250 330 "+?", "-?", "AddressOf", "*?", "!?", "~?", "++?", "?++", "--?", "?--", "&&" 251 331 }; 252 332 253 OperatorNode::OperatorNode( Type t ) : type( t ) {} 254 255 OperatorNode::OperatorNode( const OperatorNode &other ) : ExpressionNode( other ), type( other.type ) { 256 } 257 258 OperatorNode::~OperatorNode() {} 259 260 OperatorNode::Type OperatorNode::get_type( void ) const { 261 return type; 262 } 263 264 void OperatorNode::printOneLine( std::ostream &os, int indent ) const { 265 printDesignation( os ); 266 os << opName[ type ] << ' '; 267 } 268 269 void OperatorNode::print( std::ostream &os, int indent ) const{ 270 printDesignation( os ); 271 os << string( indent, ' ' ) << "Operator: " << opName[type] << endl; 272 return; 273 } 274 275 const char *OperatorNode::get_typename( void ) const{ 276 return opName[ type ]; 277 } 278 279 //############################################################################## 280 281 CompositeExprNode::CompositeExprNode() : ExpressionNode(), function( 0 ), arguments( 0 ) { 282 } 283 284 CompositeExprNode::CompositeExprNode( const string *name_ ) : ExpressionNode( name_ ), function( 0 ), arguments( 0 ) { 285 } 286 287 CompositeExprNode::CompositeExprNode( ExpressionNode *f, ExpressionNode *args ): 288 function( f ), arguments( args ) { 289 } 290 291 CompositeExprNode::CompositeExprNode( ExpressionNode *f, ExpressionNode *arg1, ExpressionNode *arg2): 292 function( f ), arguments( arg1 ) { 293 arguments->set_link( arg2 ); 294 } 295 296 CompositeExprNode::CompositeExprNode( const CompositeExprNode &other ) : ExpressionNode( other ), function( maybeClone( other.function ) ), arguments( 0 ) { 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 } 306 } 307 308 CompositeExprNode::~CompositeExprNode() { 309 delete function; 310 delete arguments; 311 } 312 333 //############################################################################## 313 334 314 335 Expression *build_cast( TypeValueNode * arg, ExpressionNode *expr_node ) { … … 369 390 } 370 391 371 Expression *build_opr1( OperatorNode::Type op, ExpressionNode *expr_node ) { 392 Expression *build_unary_val( OperKinds op, ExpressionNode *expr_node ) { 393 std::list<Expression *> args; 394 args.push_back( maybeBuild<Expression>(expr_node) ); 395 return new UntypedExpr( new NameExpr( OperName[ (int)op ] ), args ); 396 } 397 Expression *build_unary_ptr( OperKinds op, ExpressionNode *expr_node ) { 372 398 std::list<Expression *> args; 373 399 args.push_back( new AddressExpr( maybeBuild<Expression>(expr_node) ) ); 374 return new UntypedExpr( new NameExpr( opName[op ] ), args );375 } 376 Expression *build_ opr2( OperatorNode::Typeop, ExpressionNode *expr_node1, ExpressionNode *expr_node2 ) {400 return new UntypedExpr( new NameExpr( OperName[ (int)op ] ), args ); 401 } 402 Expression *build_binary_val( OperKinds op, ExpressionNode *expr_node1, ExpressionNode *expr_node2 ) { 377 403 std::list<Expression *> args; 378 404 args.push_back( maybeBuild<Expression>(expr_node1) ); 379 405 args.push_back( maybeBuild<Expression>(expr_node2) ); 380 return new UntypedExpr( new NameExpr( opName[ op ] ), args ); 406 return new UntypedExpr( new NameExpr( OperName[ (int)op ] ), args ); 407 } 408 Expression *build_binary_ptr( OperKinds op, ExpressionNode *expr_node1, ExpressionNode *expr_node2 ) { 409 std::list<Expression *> args; 410 args.push_back( new AddressExpr( maybeBuild<Expression>(expr_node1) ) ); 411 args.push_back( maybeBuild<Expression>(expr_node2) ); 412 return new UntypedExpr( new NameExpr( OperName[ (int)op ] ), args ); 381 413 } 382 414 … … 389 421 } 390 422 391 CompositeExprNode2::CompositeExprNode2( Expression *expr ) : expr( expr ) {} 392 CompositeExprNode2::CompositeExprNode2( const CompositeExprNode2 &other ) : expr( other.expr->clone() ) {} 393 CompositeExprNode2::~CompositeExprNode2() { delete expr; } 394 void CompositeExprNode2::print( std::ostream &, int indent ) const { assert( false ); } 395 void CompositeExprNode2::printOneLine( std::ostream &, int indent ) const { assert( false ); } 396 397 398 Expression *CompositeExprNode::build() const { 399 OperatorNode *op; 423 Expression *build_attr( VarRefNode *var, ExpressionNode * expr ) { 424 if ( TypeValueNode * arg = dynamic_cast<TypeValueNode *>( expr ) ) { 425 return new AttrExpr( maybeBuild<Expression>(var), arg->get_decl()->buildType() ); 426 } else { 427 return new AttrExpr( maybeBuild<Expression>(var), maybeBuild<Expression>(expr) ); 428 } // if 429 } 430 431 Expression *build_tuple( ExpressionNode * expr ) { 432 TupleExpr *ret = new TupleExpr(); 433 buildList( expr, ret->get_exprs() ); 434 return ret; 435 } 436 437 Expression *build_func( ExpressionNode * function, ExpressionNode * expr ) { 400 438 std::list<Expression *> args; 401 439 402 buildList( get_args(), args ); 403 404 if ( ! ( op = dynamic_cast<OperatorNode *>( function ) ) ) { // function as opposed to operator 405 return new UntypedExpr( maybeBuild<Expression>(function), args, maybeBuild< Expression >( get_argName() )); 406 } // if 407 408 switch ( op->get_type() ) { 409 case OperatorNode::Assign: 410 case OperatorNode::MulAssn: 411 case OperatorNode::DivAssn: 412 case OperatorNode::ModAssn: 413 case OperatorNode::PlusAssn: 414 case OperatorNode::MinusAssn: 415 case OperatorNode::LSAssn: 416 case OperatorNode::RSAssn: 417 case OperatorNode::AndAssn: 418 case OperatorNode::ERAssn: 419 case OperatorNode::OrAssn: 420 assert( ! args.empty() ); 421 args.front() = new AddressExpr( args.front() ); 422 case OperatorNode::UnPlus: 423 case OperatorNode::UnMinus: 424 case OperatorNode::PointTo: 425 case OperatorNode::Neg: 426 case OperatorNode::BitNeg: 427 case OperatorNode::LabelAddress: 428 return new UntypedExpr( new NameExpr( opName[ op->get_type() ] ), args ); 429 430 case OperatorNode::Attr: 431 { 432 VarRefNode *var = dynamic_cast<VarRefNode *>( get_args() ); 433 assert( var ); 434 if ( ! get_args()->get_link() ) { 435 return new AttrExpr( maybeBuild<Expression>(var), ( Expression*)0); 436 } else if ( TypeValueNode * arg = dynamic_cast<TypeValueNode *>( get_args()->get_link() ) ) { 437 return new AttrExpr( maybeBuild<Expression>(var), arg->get_decl()->buildType() ); 438 } else { 439 return new AttrExpr( maybeBuild<Expression>(var), args.back() ); 440 } // if 441 } 442 case OperatorNode::Cond: 443 { 444 assert( args.size() == 3); 445 std::list< Expression * >::const_iterator i = args.begin(); 446 Expression *arg1 = notZeroExpr( *i++ ); 447 Expression *arg2 = *i++; 448 Expression *arg3 = *i++; 449 return new ConditionalExpr( arg1, arg2, arg3 ); 450 } 451 case OperatorNode::NCond: 452 throw UnimplementedError( "GNU 2-argument conditional expression" ); 453 // Tuples 454 case OperatorNode::TupleC: 455 { 456 TupleExpr *ret = new TupleExpr(); 457 std::copy( args.begin(), args.end(), back_inserter( ret->get_exprs() ) ); 458 return ret; 459 } 460 default: 461 assert( ((void)"CompositeExprNode::build", false) ); 462 return 0; 463 } // switch 464 } 465 466 void CompositeExprNode::printOneLine( std::ostream &os, int indent ) const { 467 printDesignation( os ); 468 os << "( "; 469 function->printOneLine( os, indent ); 470 for ( ExpressionNode *cur = arguments; cur != 0; cur = dynamic_cast< ExpressionNode* >( cur->get_link() ) ) { 471 cur->printOneLine( os, indent ); 472 } // for 473 os << ") "; 474 } 475 476 void CompositeExprNode::print( std::ostream &os, int indent ) const { 477 printDesignation( os ); 478 os << string( indent, ' ' ) << "Application of: " << endl; 479 function->print( os, indent + ParseNode::indent_by ); 480 481 os << string( indent, ' ' ) ; 482 if ( arguments ) { 483 os << "... on arguments: " << endl; 484 arguments->printList( os, indent + ParseNode::indent_by ); 485 } else 486 os << "... on no arguments: " << endl; 487 } 488 489 void CompositeExprNode::set_function( ExpressionNode *f ) { 490 function = f; 491 } 492 493 void CompositeExprNode::set_args( ExpressionNode *args ) { 494 arguments = args; 495 } 496 497 ExpressionNode *CompositeExprNode::get_function( void ) const { 498 return function; 499 } 500 501 ExpressionNode *CompositeExprNode::get_args( void ) const { 502 return arguments; 503 } 504 505 void CompositeExprNode::add_arg( ExpressionNode *arg ) { 506 if ( arguments ) 507 arguments->set_link( arg ); 508 else 509 set_args( arg ); 440 buildList( expr, args ); 441 return new UntypedExpr( maybeBuild<Expression>(function), args, nullptr ); 442 } 443 444 Expression *build_range( ExpressionNode * low, ExpressionNode *high ) { 445 Expression *low_cexpr = maybeBuild<Expression>( low ); 446 Expression *high_cexpr = maybeBuild<Expression>( high ); 447 return new RangeExpr( low_cexpr, high_cexpr ); 510 448 } 511 449 … … 698 636 } 699 637 700 ExpressionNode *flattenCommas( ExpressionNode *list ) {701 if ( CompositeExprNode *composite = dynamic_cast< CompositeExprNode * >( list ) ) {702 OperatorNode *op;703 if ( ( op = dynamic_cast< OperatorNode * >( composite->get_function() )) && ( op->get_type() == OperatorNode::Comma ) ) {704 if ( ExpressionNode *next = dynamic_cast< ExpressionNode * >( list->get_link() ) )705 composite->add_arg( next );706 return flattenCommas( composite->get_args() );707 } // if708 } // if709 710 if ( ExpressionNode *next = dynamic_cast< ExpressionNode * >( list->get_link() ) )711 list->set_next( flattenCommas( next ) );712 713 return list;714 }715 716 ExpressionNode *tupleContents( ExpressionNode *tuple ) {717 if ( CompositeExprNode *composite = dynamic_cast< CompositeExprNode * >( tuple ) ) {718 OperatorNode *op = 0;719 if ( ( op = dynamic_cast< OperatorNode * >( composite->get_function() )) && ( op->get_type() == OperatorNode::TupleC ) )720 return composite->get_args();721 } // if722 return tuple;723 }724 725 638 // Local Variables: // 726 639 // tab-width: 4 //
Note:
See TracChangeset
for help on using the changeset viewer.