Changes in src/Parser/ExpressionNode.cc [658fafe4:e869d663]
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/Parser/ExpressionNode.cc
r658fafe4 re869d663 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // ExpressionNode.cc -- 8 // 7 // ExpressionNode.cc -- 8 // 9 9 // Author : Rodolfo G. Esteves 10 10 // Created On : Sat May 16 13:17:07 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Tue Aug 2 15:10:23 201613 // Update Count : 32214 // 11 // Last Modified By : Rob Schluntz 12 // Last Modified On : Wed Aug 12 13:51:11 2015 13 // Update Count : 254 14 // 15 15 16 16 #include <cassert> … … 19 19 #include <sstream> 20 20 #include <cstdio> 21 #include <climits> 21 22 22 23 #include "ParseNode.h" 23 #include "TypeData.h"24 24 #include "SynTree/Constant.h" 25 25 #include "SynTree/Expression.h" 26 #include "SynTree/Declaration.h" 27 #include "Common/UnimplementedError.h" 26 #include "UnimplementedError.h" 28 27 #include "parseutility.h" 29 #include " Common/utility.h"28 #include "utility.h" 30 29 31 30 using namespace std; 32 31 33 ExpressionNode::ExpressionNode() : ParseNode() {}34 35 ExpressionNode::ExpressionNode( const string *name ) : ParseNode( name ) {}36 37 ExpressionNode::ExpressionNode( const ExpressionNode &other ) : ParseNode( other.name ) , extension( other.extension ){32 ExpressionNode::ExpressionNode() : ParseNode(), argName( 0 ) {} 33 34 ExpressionNode::ExpressionNode( const string *name ) : ParseNode( name ), argName( 0 ) {} 35 36 ExpressionNode::ExpressionNode( const ExpressionNode &other ) : ParseNode( other.name ) { 38 37 if ( other.argName ) { 39 38 argName = other.argName->clone(); … … 83 82 } 84 83 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 ) { 84 CommaExprNode *ExpressionNode::add_to_list( ExpressionNode *exp ) { 85 return new CommaExprNode( this, exp ); 86 } 87 88 //############################################################################## 89 90 static inline bool checkU( char c ) { return c == 'u' || c == 'U'; } 91 static inline bool checkL( char c ) { return c == 'l' || c == 'L'; } 92 static inline bool checkF( char c ) { return c == 'f' || c == 'F'; } 93 static inline bool checkX( char c ) { return c == 'x' || c == 'X'; } 94 95 // Difficult to separate extra parts of constants during lexing because actions are not allow in the middle of patterns: 96 // 97 // prefix action constant action suffix 98 // 99 // Alternatively, breaking a pattern using BEGIN does not work if the following pattern can be empty: 100 // 101 // constant BEGIN CONT ... 102 // <CONT>(...)? BEGIN 0 ... // possible empty suffix 103 // 104 // because the CONT rule is NOT triggered if the pattern is empty. Hence, constants are reparsed here to determine their 105 // type. 106 107 ConstantNode::ConstantNode( Type t, string *inVal ) : type( t ), value( *inVal ) { 108 // lexing divides constants into 4 kinds 109 switch ( type ) { 110 case Integer: 111 { 112 static const BasicType::Kind kind[2][3] = { 113 { BasicType::SignedInt, BasicType::LongSignedInt, BasicType::LongLongSignedInt }, 114 { BasicType::UnsignedInt, BasicType::LongUnsignedInt, BasicType::LongLongUnsignedInt }, 115 }; 116 size_t last = value.length() - 1; // last character of constant 117 unsigned long long v; // converted integral value 118 bool dec = true, Unsigned = false; // decimal, unsigned constant 119 int size; // 0 => int, 1 => long, 2 => long long 120 121 if ( value[0] == '0' ) { // octal constant ? 122 dec = false; 123 if ( last != 0 && checkX( value[1] ) ) { // hex constant ? 124 sscanf( (char *)value.c_str(), "%llx", &v ); 125 //printf( "%llx %llu\n", v, v ); 126 } else { 127 sscanf( (char *)value.c_str(), "%llo", &v ); 128 //printf( "%llo %llu\n", v, v ); 129 } // if 130 } else { // decimal constant ? 131 sscanf( (char *)value.c_str(), "%llu", &v ); 132 //printf( "%llu %llu\n", v, v ); 133 } // if 134 135 if ( v <= INT_MAX ) { // signed int 136 size = 0; 137 } else if ( v <= UINT_MAX && ! dec ) { // unsigned int 138 size = 0; 139 Unsigned = true; // unsigned 140 } else if ( v <= LONG_MAX ) { // signed long int 141 size = 1; 142 } else if ( v <= ULONG_MAX && ( ! dec || LONG_MAX == LLONG_MAX ) ) { // signed long int 143 size = 1; 144 Unsigned = true; // unsigned long int 145 } else if ( v <= LLONG_MAX ) { // signed long long int 146 size = 2; 147 } else { // unsigned long long int 148 size = 2; 149 Unsigned = true; // unsigned long long int 150 } // if 151 152 if ( checkU( value[last] ) ) { // suffix 'u' ? 153 Unsigned = true; 154 if ( last > 0 && checkL( value[ last - 1 ] ) ) { // suffix 'l' ? 155 size = 1; 156 if ( last > 1 && checkL( value[ last - 2 ] ) ) { // suffix 'll' ? 157 size = 2; 158 } // if 159 } // if 160 } else if ( checkL( value[ last ] ) ) { // suffix 'l' ? 161 size = 1; 162 if ( last > 0 && checkL( value[ last - 1 ] ) ) { // suffix 'll' ? 163 size = 2; 164 if ( last > 1 && checkU( value[ last - 2 ] ) ) { // suffix 'u' ? 165 Unsigned = true; 166 } // if 167 } else { 168 if ( last > 0 && checkU( value[ last - 1 ] ) ) { // suffix 'u' ? 169 Unsigned = true; 170 } // if 171 } // if 172 } // if 173 btype = kind[Unsigned][size]; // lookup constant type 174 break; 175 } 176 case Float: 177 { 178 size_t len = value.length() - 1; 179 180 btype = BasicType::Double; // default 181 if ( checkF( value[len] ) ) { // float ? 182 btype = BasicType::Float; 183 } // if 184 if ( checkL( value[len] ) ) { // long double ? 185 btype = BasicType::LongDouble; 186 } // if 187 break; 188 } 189 case Character: 190 btype = BasicType::Char; // default 191 if ( string( "LUu" ).find( value[0] ) != string::npos ) { 192 // ??? 193 } // if 194 break; 195 case String: 196 // array of char 197 if ( string( "LUu" ).find( value[0] ) != string::npos ) { 198 if ( value[0] == 'u' && value[1] == '8' ) { 199 // ??? 200 } else { 201 // ??? 202 } // if 203 } // if 204 break; 205 } // switch 92 206 } // ConstantNode::ConstantNode 93 207 94 208 ConstantNode *ConstantNode::appendstr( const std::string *newValue ) { 95 209 assert( newValue != 0 ); 96 97 string value = expr->get_constant()->get_value(); 210 assert( type == String ); 98 211 99 212 // "abc" "def" "ghi" => "abcdefghi", remove new text from quotes and insert before last quote in old string. 100 213 value.insert( value.length() - 1, newValue->substr( 1, newValue->length() - 2 ) ); 101 expr->get_constant()->set_value( value ); 102 214 103 215 delete newValue; // allocated by lexer 104 216 return this; … … 106 218 107 219 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 //} // switch123 124 //os << ' ';220 os << string( indent, ' ' ); 221 printDesignation( os ); 222 223 switch ( type ) { 224 case Integer: 225 case Float: 226 os << value ; 227 break; 228 case Character: 229 os << "'" << value << "'"; 230 break; 231 case String: 232 os << '"' << value << '"'; 233 break; 234 } // switch 235 236 os << ' '; 125 237 } 126 238 … … 131 243 132 244 Expression *ConstantNode::build() const { 133 return expr->clone(); 245 ::Type::Qualifiers q; // no qualifiers on constants 246 247 switch ( get_type() ) { 248 case String: 249 { 250 // string should probably be a primitive type 251 ArrayType *at = new ArrayType( q, new BasicType( q, BasicType::Char ), 252 new ConstantExpr( 253 Constant( new BasicType( q, BasicType::UnsignedInt ), 254 toString( value.size()+1-2 ) ) ), // +1 for '\0' and -2 for '"' 255 false, false ); 256 return new ConstantExpr( Constant( at, value ), maybeBuild< Expression >( get_argName() ) ); 257 } 258 default: 259 return new ConstantExpr( Constant( new BasicType( q, btype ), get_value() ), maybeBuild< Expression >( get_argName() ) ); 260 } 134 261 } 135 262 … … 198 325 199 326 Expression *DesignatorNode::build() const { 200 Expression * ret = maybeBuild<Expression>(get_argName());327 Expression * ret = get_argName()->build(); 201 328 202 329 if ( isArrayIndex ) { 203 // need to traverse entire structure and change any instances of 0 or 1 to 330 // need to traverse entire structure and change any instances of 0 or 1 to 204 331 // ConstantExpr 205 332 DesignatorFixer fixer; … … 238 365 //############################################################################## 239 366 240 static const char *opName[] = {241 "TupleC", "Comma", "TupleFieldSel", // "TuplePFieldSel", // n-adic242 // triadic243 "Cond", "NCond",244 // diadic245 "SizeOf", "AlignOf", "OffsetOf", "Attr", "?+?", "?-?", "?*?", "?/?", "?%?", "||", "&&",246 "?|?", "?&?", "?^?", "Cast", "?<<?", "?>>?", "?<?", "?>?", "?<=?", "?>=?", "?==?", "?!=?",247 "?=?", "?*=?", "?/=?", "?%=?", "?+=?", "?-=?", "?<<=?", "?>>=?", "?&=?", "?^=?", "?|=?",248 "?[?]", "FieldSel", "PFieldSel", "...",249 // monadic250 "+?", "-?", "AddressOf", "*?", "!?", "~?", "++?", "?++", "--?", "?--", "&&"251 };252 253 367 OperatorNode::OperatorNode( Type t ) : type( t ) {} 254 368 … … 264 378 void OperatorNode::printOneLine( std::ostream &os, int indent ) const { 265 379 printDesignation( os ); 266 os << opName[ type ] << ' ';380 os << OpName[ type ] << ' '; 267 381 } 268 382 269 383 void OperatorNode::print( std::ostream &os, int indent ) const{ 270 384 printDesignation( os ); 271 os << string( indent, ' ' ) << "Operator: " << opName[type] << endl;385 os << string( indent, ' ' ) << "Operator: " << OpName[type] << endl; 272 386 return; 273 387 } 274 388 275 389 const char *OperatorNode::get_typename( void ) const{ 276 return opName[ type ]; 277 } 390 return OpName[ type ]; 391 } 392 393 const char *OperatorNode::OpName[] = { 394 "TupleC", "Comma", "TupleFieldSel",// "TuplePFieldSel", //n-adic 395 // triadic 396 "Cond", "NCond", 397 // diadic 398 "SizeOf", "AlignOf", "Attr", "CompLit", "Plus", "Minus", "Mul", "Div", "Mod", "Or", 399 "And", "BitOr", "BitAnd", "Xor", "Cast", "LShift", "RShift", "LThan", "GThan", 400 "LEThan", "GEThan", "Eq", "Neq", "Assign", "MulAssn", "DivAssn", "ModAssn", "PlusAssn", 401 "MinusAssn", "LSAssn", "RSAssn", "AndAssn", "ERAssn", "OrAssn", "Index", "FieldSel","PFieldSel", 402 "Range", 403 // monadic 404 "UnPlus", "UnMinus", "AddressOf", "PointTo", "Neg", "BitNeg", "Incr", "IncrPost", "Decr", "DecrPost", "LabelAddress" 405 }; 278 406 279 407 //############################################################################## … … 290 418 291 419 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 ){420 function( f ), arguments( arg1) { 421 arguments->set_link( arg2); 422 } 423 424 CompositeExprNode::CompositeExprNode( const CompositeExprNode &other ) : ExpressionNode( other ), function( maybeClone( other.function ) ) { 297 425 ParseNode *cur = other.arguments; 298 426 while ( cur ) { … … 311 439 } 312 440 313 #include "Common/utility.h" 441 // the names that users use to define operator functions 442 static const char *opFuncName[] = { 443 "", "", "", 444 "", "", 445 //diadic 446 "", "", "", "", "?+?", "?-?", "?*?", "?/?", "?%?", "", "", 447 "?|?", "?&?", "?^?", "", "?<<?", "?>>?", "?<?", "?>?", "?<=?", 448 "?>=?", "?==?", "?!=?", "?=?", "?*=?", "?/=?", "?%=?", "?+=?", "?-=?", 449 "?<<=?", "?>>=?", "?&=?", "?^=?", "?|=?", "?[?]", "", "", "Range", 450 //monadic 451 "+?", "-?", "", "*?", "!?", "~?", "++?", "?++", "--?", "?--", "&&" 452 }; 453 454 #include "utility.h" 314 455 315 456 Expression *CompositeExprNode::build() const { … … 320 461 321 462 if ( ! ( op = dynamic_cast<OperatorNode *>( function ) ) ) { // function as opposed to operator 322 return new UntypedExpr( maybeBuild<Expression>(function), args, maybeBuild< Expression >( get_argName() ));463 return new UntypedExpr( function->build(), args, maybeBuild< Expression >( get_argName() )); 323 464 } // if 324 465 … … 343 484 args.front() = new AddressExpr( args.front() ); 344 485 break; 345 default: // do nothing 486 default: 487 /* do nothing */ 346 488 ; 347 } // switch489 } 348 490 349 491 switch ( op->get_type() ) { … … 387 529 case OperatorNode::BitNeg: 388 530 case OperatorNode::LabelAddress: 389 return new UntypedExpr( new NameExpr( op Name[ op->get_type() ] ), args );531 return new UntypedExpr( new NameExpr( opFuncName[ op->get_type() ] ), args ); 390 532 case OperatorNode::AddressOf: 391 533 assert( args.size() == 1 ); … … 404 546 if ( dynamic_cast< VoidType* >( targetType ) ) { 405 547 delete targetType; 406 return new CastExpr( maybeBuild<Expression>(expr_node), maybeBuild< Expression >( get_argName() ) );548 return new CastExpr( expr_node->build(), maybeBuild< Expression >( get_argName() ) ); 407 549 } else { 408 return new CastExpr( maybeBuild<Expression>(expr_node),targetType, maybeBuild< Expression >( get_argName() ) );550 return new CastExpr( expr_node->build(),targetType, maybeBuild< Expression >( get_argName() ) ); 409 551 } // if 410 552 } … … 443 585 return ret; 444 586 } 587 case OperatorNode::AlignOf: 445 588 case OperatorNode::SizeOf: 446 589 { 590 /// bool isSizeOf = ( op->get_type() == OperatorNode::SizeOf ); 591 447 592 if ( TypeValueNode * arg = dynamic_cast<TypeValueNode *>( get_args()) ) { 448 593 return new SizeofExpr( arg->get_decl()->buildType()); … … 451 596 } // if 452 597 } 453 case OperatorNode::AlignOf:454 {455 if ( TypeValueNode * arg = dynamic_cast<TypeValueNode *>( get_args()) ) {456 return new AlignofExpr( arg->get_decl()->buildType());457 } else {458 return new AlignofExpr( args.front());459 } // if460 }461 case OperatorNode::OffsetOf:462 {463 assert( args.size() == 2 );464 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 );471 }472 598 case OperatorNode::Attr: 473 599 { … … 475 601 assert( var ); 476 602 if ( ! get_args()->get_link() ) { 477 return new AttrExpr( maybeBuild<Expression>(var), ( Expression*)0);603 return new AttrExpr( var->build(), ( Expression*)0); 478 604 } else if ( TypeValueNode * arg = dynamic_cast<TypeValueNode *>( get_args()->get_link()) ) { 479 return new AttrExpr( maybeBuild<Expression>(var), arg->get_decl()->buildType());605 return new AttrExpr( var->build(), arg->get_decl()->buildType()); 480 606 } else { 481 return new AttrExpr( maybeBuild<Expression>(var), args.back()); 482 } // if 483 } 607 return new AttrExpr( var->build(), args.back()); 608 } // if 609 } 610 case OperatorNode::CompLit: 611 throw UnimplementedError( "C99 compound literals" ); 612 // the short-circuited operators 484 613 case OperatorNode::Or: 485 614 case OperatorNode::And: … … 516 645 default: 517 646 // shouldn't happen 518 assert( false );519 647 return 0; 520 648 } // switch … … 527 655 for ( ExpressionNode *cur = arguments; cur != 0; cur = dynamic_cast< ExpressionNode* >( cur->get_link() ) ) { 528 656 cur->printOneLine( os, indent ); 529 } // for657 } 530 658 os << ") "; 531 659 } … … 570 698 571 699 Expression *AsmExprNode::build() const { 572 return new AsmExpr( maybeBuild< Expression >( inout ), (ConstantExpr *) maybeBuild<Expression>(constraint), maybeBuild<Expression>(operand) );700 return new AsmExpr( maybeBuild< Expression >( inout ), (ConstantExpr *)constraint->build(), operand->build() ); 573 701 } 574 702 … … 608 736 //############################################################################## 609 737 738 CommaExprNode::CommaExprNode(): CompositeExprNode( new OperatorNode( OperatorNode::Comma )) {} 739 740 CommaExprNode::CommaExprNode( ExpressionNode *exp ) : CompositeExprNode( new OperatorNode( OperatorNode::Comma ), exp ) { 741 } 742 743 CommaExprNode::CommaExprNode( ExpressionNode *exp1, ExpressionNode *exp2) : CompositeExprNode( new OperatorNode( OperatorNode::Comma ), exp1, exp2) { 744 } 745 746 CommaExprNode *CommaExprNode::add_to_list( ExpressionNode *exp ) { 747 add_arg( exp ); 748 749 return this; 750 } 751 752 CommaExprNode::CommaExprNode( const CommaExprNode &other ) : CompositeExprNode( other ) { 753 } 754 755 //############################################################################## 756 610 757 ValofExprNode::ValofExprNode( StatementNode *s ): body( s ) {} 611 758 … … 628 775 629 776 Expression *ValofExprNode::build() const { 630 return new UntypedValofExpr ( maybeBuild<Statement>(get_body()), maybeBuild< Expression >( get_argName() ) );777 return new UntypedValofExpr ( get_body()->build(), maybeBuild< Expression >( get_argName() ) ); 631 778 } 632 779 … … 705 852 get_decl()->print( os, indent + 2); 706 853 } 707 708 709 CompoundLiteralNode::CompoundLiteralNode( DeclarationNode *type, InitializerNode *kids ) : type( type ), kids( kids ) {}710 CompoundLiteralNode::CompoundLiteralNode( const CompoundLiteralNode &other ) : ExpressionNode( other ), type( other.type ), kids( other.kids ) {}711 712 CompoundLiteralNode::~CompoundLiteralNode() {713 delete kids;714 delete type;715 }716 717 CompoundLiteralNode *CompoundLiteralNode::clone() const {718 return new CompoundLiteralNode( *this );719 }720 721 void CompoundLiteralNode::print( std::ostream &os, int indent ) const {722 os << string( indent,' ' ) << "CompoundLiteralNode:" << endl;723 724 os << string( indent + 2, ' ' ) << "type:" << endl;725 if ( type != 0 )726 type->print( os, indent + 4 );727 728 os << string( indent + 2, ' ' ) << "initialization:" << endl;729 if ( kids != 0 )730 kids->printList( os, indent + 4 );731 }732 733 void CompoundLiteralNode::printOneLine( std::ostream &os, int indent ) const {734 os << "( ";735 if ( type ) type->print( os );736 os << ", ";737 if ( kids ) kids->printOneLine( os );738 os << ") ";739 }740 741 Expression *CompoundLiteralNode::build() const {742 Declaration * newDecl = maybeBuild<Declaration>(type); // compound literal type743 if ( DeclarationWithType * newDeclWithType = dynamic_cast< DeclarationWithType * >( newDecl ) ) { // non-sue compound-literal type744 return new CompoundLiteralExpr( newDeclWithType->get_type(), maybeBuild<Initializer>(kids) );745 // these types do not have associated type information746 } else if ( StructDecl * newDeclStructDecl = dynamic_cast< StructDecl * >( newDecl ) ) {747 return new CompoundLiteralExpr( new StructInstType( Type::Qualifiers(), newDeclStructDecl->get_name() ), maybeBuild<Initializer>(kids) );748 } else if ( UnionDecl * newDeclUnionDecl = dynamic_cast< UnionDecl * >( newDecl ) ) {749 return new CompoundLiteralExpr( new UnionInstType( Type::Qualifiers(), newDeclUnionDecl->get_name() ), maybeBuild<Initializer>(kids) );750 } else if ( EnumDecl * newDeclEnumDecl = dynamic_cast< EnumDecl * >( newDecl ) ) {751 return new CompoundLiteralExpr( new EnumInstType( Type::Qualifiers(), newDeclEnumDecl->get_name() ), maybeBuild<Initializer>(kids) );752 } else {753 assert( false );754 } // if755 }756 757 854 758 855 ExpressionNode *flattenCommas( ExpressionNode *list ) {
Note:
See TracChangeset
for help on using the changeset viewer.