Changeset f1ec88a
- Timestamp:
- May 23, 2019, 5:06:37 PM (5 years ago)
- Branches:
- ADT, arm-eh, ast-experimental, cleanup-dtors, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, pthread-emulation, qualifiedEnum
- Children:
- 21a44ca
- Parents:
- f685679 (diff), af1e8f56 (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. - Location:
- src
- Files:
-
- 12 edited
Legend:
- Unmodified
- Added
- Removed
-
src/AST/Convert.cpp
rf685679 rf1ec88a 704 704 } 705 705 706 bool isIntlikeConstantType(const ast::Type *t) {707 if ( const ast::BasicType * basicType = dynamic_cast< const ast::BasicType * >( t ) ) {708 if ( basicType->isInteger() ) {709 return true;710 }711 } else if ( dynamic_cast< const ast::OneType * >( t ) ) {712 return true;713 } else if ( dynamic_cast< const ast::ZeroType * >( t ) ) {714 return true;715 } else if ( dynamic_cast< const ast::PointerType * >( t ) ) {716 // null pointer constants, with zero int-values717 return true;718 }719 return false;720 }721 722 bool isFloatlikeConstantType(const ast::Type *t) {723 if ( const ast::BasicType * bty = dynamic_cast< const ast::BasicType * >( t ) ) {724 if ( ! bty->isInteger() ) {725 return true;726 }727 }728 return false;729 }730 731 bool isStringlikeConstantType(const ast::Type *t) {732 if ( const ast::ArrayType * aty = dynamic_cast< const ast::ArrayType * >( t ) ) {733 if ( const ast::BasicType * bty = aty->base.as<ast::BasicType>() ) {734 if ( bty->kind == ast::BasicType::Kind::Char ) {735 return true;736 }737 }738 }739 return false;740 }741 742 706 const ast::Expr * visit( const ast::ConstantExpr * node ) override final { 743 707 ConstantExpr *rslt = nullptr; 744 if (isIntlikeConstantType(node->result)) { 745 rslt = new ConstantExpr(Constant( 746 get<Type>().accept1(node->result), 708 switch ( node->kind ) { 709 case ast::ConstantExpr::Integer: 710 rslt = new ConstantExpr{Constant{ 711 get<Type>().accept1( node->result ), 747 712 node->rep, 748 713 (unsigned long long) node->intValue() 749 )); 750 } else if (isFloatlikeConstantType(node->result)) { 751 rslt = new ConstantExpr(Constant( 714 }}; 715 break; 716 case ast::ConstantExpr::FloatingPoint: 717 rslt = new ConstantExpr{Constant{ 752 718 get<Type>().accept1(node->result), 753 719 node->rep, 754 720 (double) node->floatValue() 755 ));756 } else if (isStringlikeConstantType(node->result)) {757 rslt = new ConstantExpr(Constant::from_string(758 node->rep759 ));721 }}; 722 break; 723 case ast::ConstantExpr::String: 724 rslt = new ConstantExpr{Constant::from_string( node->rep )}; 725 break; 760 726 } 761 727 assert(rslt); -
src/AST/Decl.cpp
rf685679 rf1ec88a 72 72 // --- EnumDecl 73 73 74 bool EnumDecl::valueOf( Decl* enumerator, long long& value ) const {74 bool EnumDecl::valueOf( const Decl * enumerator, long long& value ) const { 75 75 if ( enumValues.empty() ) { 76 76 long long crntVal = 0; 77 for ( const Decl * member : members ) {77 for ( const Decl * member : members ) { 78 78 const ObjectDecl* field = strict_dynamic_cast< const ObjectDecl* >( member ); 79 79 if ( field->init ) { -
src/AST/Decl.hpp
rf685679 rf1ec88a 287 287 288 288 /// gets the integer value for this enumerator, returning true iff value found 289 bool valueOf( Decl* enumerator, long long& value ) const;289 bool valueOf( const Decl * enumerator, long long& value ) const; 290 290 291 291 const Decl * accept( Visitor & v ) const override { return v.visit( this ); } -
src/AST/Expr.cpp
rf685679 rf1ec88a 241 241 FixedLen, DynamicDim }, 242 242 std::string{"\""} + s + "\"", 243 (unsigned long long)0 }; 243 (unsigned long long)0, 244 ConstantExpr::String }; 244 245 } 245 246 -
src/AST/Expr.hpp
rf685679 rf1ec88a 337 337 public: 338 338 std::string rep; 339 enum Kind { Integer, FloatingPoint, String } kind; 339 340 340 341 ConstantExpr( 341 const CodeLocation & loc, const Type * ty, const std::string & r, unsigned long long v ) 342 : Expr( loc, ty ), val( v ), rep( r ) {} 342 const CodeLocation & loc, const Type * ty, const std::string & r, unsigned long long v, 343 Kind k = Integer ) 344 : Expr( loc, ty ), val( v ), rep( r ), kind( k ) {} 343 345 ConstantExpr( const CodeLocation & loc, const Type * ty, const std::string & r, double v ) 344 : Expr( loc, ty ), val( v ), rep( r ) {}346 : Expr( loc, ty ), val( v ), rep( r ), kind( FloatingPoint ) {} 345 347 346 348 /// Gets the value of this constant as an integer -
src/AST/Pass.proto.hpp
rf685679 rf1ec88a 109 109 }; 110 110 111 /// "Short hand" to check if this is a valid previsit function 112 /// Mostly used to make the static_assert look (and print) prettier 111 113 template<typename pass_t, typename node_t> 112 114 struct is_valid_previsit { … … 117 119 }; 118 120 121 /// Used by previsit implementation 122 /// We need to reassign the result to 'node', unless the function 123 /// returns void, then we just leave 'node' unchanged 119 124 template<bool is_void> 120 125 struct __assign; … … 134 139 node = pass.previsit( node ); 135 140 assertf(node, "Previsit must not return NULL"); 141 } 142 }; 143 144 /// Used by postvisit implementation 145 /// We need to return the result unless the function 146 /// returns void, then we just return the original node 147 template<bool is_void> 148 struct __return; 149 150 template<> 151 struct __return<true> { 152 template<typename pass_t, typename node_t> 153 static inline const node_t * result( pass_t & pass, const node_t * & node ) { 154 pass.postvisit( node ); 155 return node; 156 } 157 }; 158 159 template<> 160 struct __return<false> { 161 template<typename pass_t, typename node_t> 162 static inline auto result( pass_t & pass, const node_t * & node ) { 163 return pass.postvisit( node ); 136 164 } 137 165 }; … … 174 202 decltype( pass.postvisit( node ), node->accept( *(Visitor*)nullptr ) ) 175 203 { 176 return pass.postvisit( node ); 204 return __return< 205 std::is_void< 206 decltype( pass.postvisit( node ) ) 207 >::value 208 >::result( pass, node ); 177 209 } 178 210 -
src/AST/Print.cpp
rf685679 rf1ec88a 59 59 } 60 60 61 /// call if mandatory field is missing 62 void undefined() { 63 os << "UNDEFINED"; 64 } 65 66 /// call for fields that should be mandatory 67 void safe_print( const ast::Node * n ) { 68 if ( n ) n->accept( *this ); 69 else undefined(); 70 } 71 72 /// call to print short form. Incorporates features of safe_print() 73 void short_print( const ast::Node * n ) { 74 if ( ! n ) { undefined(); return; } 75 bool old_short = short_mode; short_mode = true; 76 n->accept( *this ); 77 short_mode = old_short; 78 } 79 61 80 62 81 static const char* Names[]; … … 99 118 } 100 119 120 void print( const ast::Expr::InferUnion & inferred, unsigned level = 0 ) { 121 switch ( inferred.mode ) { 122 case ast::Expr::InferUnion::Empty: return; 123 case ast::Expr::InferUnion::Slots: { 124 os << indent << "with " << inferred.data.resnSlots.size() << " pending inference slots" 125 << std::endl; 126 return; 127 } 128 case ast::Expr::InferUnion::Params: { 129 os << indent << "with inferred parameters " << level << ":" << std::endl; 130 ++indent; 131 for ( const auto & i : inferred.data.inferParams ) { 132 os << indent; 133 short_print( Decl::fromId( i.second.decl ) ); 134 os << std::endl; 135 print( i.second.expr->inferred, level+1 ); 136 } 137 --indent; 138 return; 139 } 140 } 141 } 142 143 void print( const ast::ParameterizedType::ForallList & forall ) { 144 if ( forall.empty() ) return; 145 os << "forall" << std::endl; 146 ++indent; 147 printAll( forall ); 148 os << indent; 149 --indent; 150 } 151 152 void print( const std::vector<ptr<Attribute>> & attrs ) { 153 if ( attrs.empty() ) return; 154 os << "with attributes" << std::endl; 155 ++indent; 156 printAll( attrs ); 157 --indent; 158 } 159 160 void print( const std::vector<ptr<Expr>> & params ) { 161 if ( params.empty() ) return; 162 os << std::endl << indent << "... with parameters" << std::endl; 163 ++indent; 164 printAll( params ); 165 --indent; 166 } 167 101 168 void print( const ast::AggregateDecl * node ) { 102 169 os << node->typeString() << " " << node->name << ":"; … … 155 222 } 156 223 224 void postprint( const ast::Expr * node ) { 225 print( node->inferred ); 226 227 if ( node->env ) { 228 os << std::endl << indent << "... with environment:" << std::endl; 229 ++indent; 230 node->env->accept( *this ); 231 --indent; 232 } 233 234 if ( node->extension ) { 235 os << std::endl << indent << "... with extension"; 236 } 237 } 238 239 void preprint( const ast::Type * node ) { 240 print( node->qualifiers ); 241 } 242 243 void preprint( const ast::ParameterizedType * node ) { 244 print( node->forall ); 245 print( node->qualifiers ); 246 } 247 248 void preprint( const ast::ReferenceToType * node ) { 249 print( node->forall ); 250 print( node->attributes ); 251 print( node->qualifiers ); 252 } 253 157 254 public: 158 255 virtual const ast::DeclWithType * visit( const ast::ObjectDecl * node ) { … … 168 265 node->type->accept( *this ); 169 266 } else { 170 os << " untyped entity";267 os << "untyped entity"; 171 268 } // if 172 269 … … 214 311 node->type->accept( *this ); 215 312 } else { 216 os << "untyped entity 313 os << "untyped entity"; 217 314 } // if 218 315 … … 291 388 ++indent; 292 389 os << "Expression Statement:" << endl << indent; 293 node->expr->accept( *this);390 safe_print( node->expr ); 294 391 --indent; 295 392 return node; … … 326 423 os << indent+1; 327 424 ++indent; 328 node->cond->accept( *this);425 safe_print( node->cond ); 329 426 --indent; 330 427 … … 344 441 ++indent; 345 442 os << indent; 346 node->thenPart->accept( *this);443 safe_print( node->thenPart ); 347 444 --indent; 348 445 … … 418 515 419 516 virtual const ast::Expr * visit( const ast::ApplicationExpr * node ) { 517 ++indent; 518 os << "Application of" << std::endl << indent; 519 safe_print( node->func ); 520 os << std::endl; 521 if ( ! node->args.empty() ) { 522 os << indent << "... to arguments" << std::endl; 523 printAll( node->args ); 524 } 525 --indent; 526 postprint( node ); 527 420 528 return node; 421 529 } 422 530 423 531 virtual const ast::Expr * visit( const ast::UntypedExpr * node ) { 532 ++indent; 533 os << "Applying untyped:" << std::endl; 534 os << indent; 535 safe_print( node->func ); 536 os << std::endl << indent-1 << "...to:" << std::endl; 537 printAll( node->args ); 538 --indent; 539 postprint( node ); 540 424 541 return node; 425 542 } 426 543 427 544 virtual const ast::Expr * visit( const ast::NameExpr * node ) { 545 os << "Name: " << node->name; 546 postprint( node ); 547 428 548 return node; 429 549 } 430 550 431 551 virtual const ast::Expr * visit( const ast::AddressExpr * node ) { 552 os << "Address of:" << std::endl; 553 ++indent; 554 os << indent; 555 safe_print( node->arg ); 556 557 --indent; 558 432 559 return node; 433 560 } 434 561 435 562 virtual const ast::Expr * visit( const ast::LabelAddressExpr * node ) { 563 os << "Address of label:" << node->arg; 564 436 565 return node; 437 566 } 438 567 439 568 virtual const ast::Expr * visit( const ast::CastExpr * node ) { 569 ++indent; 570 os << (node->isGenerated ? "Generated" : "Explicit") << " cast of:" << std::endl << indent; 571 safe_print( node->arg ); 572 os << std::endl << indent-1 << "... to:"; 573 if ( ! node->result ) { 574 os << " "; 575 undefined(); 576 } else if ( node->result->isVoid() ) { 577 os << " nothing"; 578 } else { 579 os << std::endl << indent; 580 node->result->accept( *this ); 581 } // if 582 --indent; 583 postprint( node ); 584 440 585 return node; 441 586 } 442 587 443 588 virtual const ast::Expr * visit( const ast::KeywordCastExpr * node ) { 589 ++indent; 590 os << "Keyword Cast of:" << std::endl << indent; 591 safe_print( node->arg ); 592 --indent; 593 os << std::endl << indent << "... to: " << node->targetString(); 594 postprint( node ); 595 444 596 return node; 445 597 } 446 598 447 599 virtual const ast::Expr * visit( const ast::VirtualCastExpr * node ) { 600 ++indent; 601 os << "Virtual Cast of:" << std::endl << indent; 602 safe_print( node->arg ); 603 os << std::endl << indent-1 << "... to:"; 604 if ( ! node->result ) { 605 os << " unknown"; 606 } else { 607 os << std::endl << indent; 608 node->result->accept( *this ); 609 } 610 --indent; 611 postprint( node ); 612 448 613 return node; 449 614 } 450 615 451 616 virtual const ast::Expr * visit( const ast::UntypedMemberExpr * node ) { 617 ++indent; 618 os << "Untyped Member Expression, with field: " << std::endl << indent; 619 safe_print( node->member ); 620 os << indent-1 << "... from aggregate:" << std::endl << indent; 621 safe_print( node->aggregate ); 622 --indent; 623 postprint( node ); 624 452 625 return node; 453 626 } 454 627 455 628 virtual const ast::Expr * visit( const ast::MemberExpr * node ) { 629 ++indent; 630 os << "Member Expression, with field:" << std::endl << indent; 631 safe_print( node->member ); 632 os << std::endl << indent-1 << "... from aggregate:" << std::endl << indent; 633 safe_print( node->aggregate ); 634 --indent; 635 postprint( node ); 636 456 637 return node; 457 638 } 458 639 459 640 virtual const ast::Expr * visit( const ast::VariableExpr * node ) { 641 os << "Variable Expression: "; 642 short_print( node->var ); 643 postprint( node ); 644 460 645 return node; 461 646 } 462 647 463 648 virtual const ast::Expr * visit( const ast::ConstantExpr * node ) { 649 os << "Constant Expression (" << node->rep; 650 if ( node->result ) { 651 os << ": "; 652 node->result->accept( *this ); 653 } 654 os << ")"; 655 postprint( node ); 656 464 657 return node; 465 658 } … … 566 759 567 760 virtual const ast::Type * visit( const ast::VoidType * node ) { 761 preprint( node ); 762 os << "void"; 568 763 return node; 569 764 } 570 765 571 766 virtual const ast::Type * visit( const ast::BasicType * node ) { 767 preprint( node ); 768 os << ast::BasicType::typeNames[ node->kind ]; 572 769 return node; 573 770 } 574 771 575 772 virtual const ast::Type * visit( const ast::PointerType * node ) { 773 preprint( node ); 774 if ( ! node->isArray() ) { 775 os << "pointer to "; 776 } else { 777 os << "decayed "; 778 if ( node->isStatic ) { 779 os << "static "; 780 } 781 782 if ( node->isVarLen ) { 783 os << "variable length array of "; 784 } else if ( node->dimension ) { 785 os << "array of "; 786 node->dimension->accept( *this ); 787 os << " "; 788 } 789 } 790 safe_print( node->base ); 791 576 792 return node; 577 793 } 578 794 579 795 virtual const ast::Type * visit( const ast::ArrayType * node ) { 796 preprint( node ); 797 if ( node->isStatic ) { 798 os << "static "; 799 } 800 801 if ( node->isVarLen ) { 802 os << "variable length array of "; 803 } else if ( node->dimension ) { 804 os << "array of "; 805 } else { 806 os << "open array of "; 807 } 808 809 safe_print( node->base ); 810 811 if ( node->dimension ) { 812 os << " with dimension of "; 813 node->dimension->accept( *this ); 814 } 815 580 816 return node; 581 817 } 582 818 583 819 virtual const ast::Type * visit( const ast::ReferenceType * node ) { 820 preprint( node ); 821 os << "reference to "; 822 safe_print( node->base ); 823 584 824 return node; 585 825 } 586 826 587 827 virtual const ast::Type * visit( const ast::QualifiedType * node ) { 828 preprint( node ); 829 ++indent; 830 os << "Qualified Type:" << std::endl << indent; 831 safe_print( node->parent ); 832 os << std::endl << indent; 833 safe_print( node->child ); 834 os << std::endl; 835 --indent; 836 588 837 return node; 589 838 } 590 839 591 840 virtual const ast::Type * visit( const ast::FunctionType * node ) { 841 preprint( node ); 842 843 os << "function" << std::endl; 844 if ( ! node->params.empty() ) { 845 os << indent << "... with parameters" << std::endl; 846 ++indent; 847 printAll( node->params ); 848 if ( node->isVarArgs ) { 849 os << indent << "and a variable number of other arguments" << std::endl; 850 } 851 --indent; 852 } else if ( node->isVarArgs ) { 853 os << indent+1 << "accepting unspecified arguments" << std::endl; 854 } 855 856 os << indent << "... returning"; 857 if ( node->returns.empty() ) { 858 os << " nothing" << std::endl; 859 } else { 860 os << std::endl; 861 ++indent; 862 printAll( node->returns ); 863 --indent; 864 } 865 592 866 return node; 593 867 } 594 868 595 869 virtual const ast::Type * visit( const ast::StructInstType * node ) { 870 preprint( node ); 871 os << "instance of struct " << node->name; 872 if ( node->base ) { 873 os << " " << ( node->base->body ? "with" : "without" ) << " body"; 874 } 875 print( node->params ); 876 596 877 return node; 597 878 } 598 879 599 880 virtual const ast::Type * visit( const ast::UnionInstType * node ) { 881 preprint( node ); 882 os << "instance of union " << node->name; 883 if ( node->base ) { 884 os << " " << ( node->base->body ? "with" : "without" ) << " body"; 885 } 886 print( node->params ); 887 600 888 return node; 601 889 } 602 890 603 891 virtual const ast::Type * visit( const ast::EnumInstType * node ) { 892 preprint( node ); 893 os << "instance of enum " << node->name; 894 if ( node->base ) { 895 os << " " << ( node->base->body ? "with" : "without" ) << " body"; 896 } 897 print( node->params ); 898 604 899 return node; 605 900 } 606 901 607 902 virtual const ast::Type * visit( const ast::TraitInstType * node ) { 903 preprint( node ); 904 os << "instance of trait " << node->name; 905 print( node->params ); 906 608 907 return node; 609 908 } 610 909 611 910 virtual const ast::Type * visit( const ast::TypeInstType * node ) { 911 preprint( node ); 912 os << "instance of type " << node->name 913 << " (" << (node->kind == ast::TypeVar::Ftype ? "" : "not ") << "function type)"; 914 print( node->params ); 915 612 916 return node; 613 917 } 614 918 615 919 virtual const ast::Type * visit( const ast::TupleType * node ) { 920 preprint( node ); 921 os << "tuple of types" << std::endl; 922 ++indent; 923 printAll( node->types ); 924 --indent; 925 616 926 return node; 617 927 } 618 928 619 929 virtual const ast::Type * visit( const ast::TypeofType * node ) { 930 preprint( node ); 931 if ( node->kind == ast::TypeofType::Basetypeof ) { os << "base-"; } 932 os << "type-of expression "; 933 safe_print( node->expr ); 934 620 935 return node; 621 936 } 622 937 623 938 virtual const ast::Type * visit( const ast::VarArgsType * node ) { 939 preprint( node ); 940 os << "builtin var args pack"; 624 941 return node; 625 942 } 626 943 627 944 virtual const ast::Type * visit( const ast::ZeroType * node ) { 945 preprint( node ); 946 os << "zero_t"; 628 947 return node; 629 948 } 630 949 631 950 virtual const ast::Type * visit( const ast::OneType * node ) { 951 preprint( node ); 952 os << "one_t"; 632 953 return node; 633 954 } 634 955 635 956 virtual const ast::Type * visit( const ast::GlobalScopeType * node ) { 957 preprint( node ); 958 os << "Global Scope Type"; 636 959 return node; 637 960 } … … 652 975 virtual const ast::Init * visit( const ast::SingleInit * node ) { 653 976 os << "Simple Initializer: "; 654 node->value->accept( *this);977 safe_print( node->value ); 655 978 return node; 656 979 } … … 715 1038 os << indent+1 << i.first << " -> "; 716 1039 indent += 2; 717 i.second->accept( *this);1040 safe_print( i.second ); 718 1041 indent -= 2; 719 1042 os << std::endl; … … 723 1046 os << indent+1 << i->first << " -> "; 724 1047 indent += 2; 725 i->second->accept( *this);1048 safe_print( i->second ); 726 1049 indent -= 2; 727 1050 os << std::endl; -
src/AST/Type.hpp
rf685679 rf1ec88a 308 308 virtual ReferenceToType * clone() const override = 0; 309 309 MUTATE_FRIEND 310 311 protected:312 /// Name for the kind of type this is313 virtual std::string typeString() const = 0;314 310 }; 315 311 … … 333 329 StructInstType * clone() const override { return new StructInstType{ *this }; } 334 330 MUTATE_FRIEND 335 336 std::string typeString() const override { return "struct"; }337 331 }; 338 332 … … 356 350 UnionInstType * clone() const override { return new UnionInstType{ *this }; } 357 351 MUTATE_FRIEND 358 359 std::string typeString() const override { return "union"; }360 352 }; 361 353 … … 379 371 EnumInstType * clone() const override { return new EnumInstType{ *this }; } 380 372 MUTATE_FRIEND 381 382 std::string typeString() const override { return "enum"; }383 373 }; 384 374 … … 403 393 TraitInstType * clone() const override { return new TraitInstType{ *this }; } 404 394 MUTATE_FRIEND 405 406 std::string typeString() const override { return "trait"; }407 395 }; 408 396 … … 432 420 TypeInstType * clone() const override { return new TypeInstType{ *this }; } 433 421 MUTATE_FRIEND 434 435 std::string typeString() const override { return "type"; }436 422 }; 437 423 -
src/Common/Eval.cc
rf685679 rf1ec88a 17 17 18 18 #include "Common/PassVisitor.h" 19 #include "AST/Pass.hpp" 19 20 #include "InitTweak/InitTweak.h" 20 21 #include "SynTree/Expression.h" 21 22 22 struct Eval : public WithShortCircuiting { 23 //------------------------------------------------------------- 24 // Old AST 25 struct EvalOld : public WithShortCircuiting { 23 26 long long int value = 0; 24 27 bool valid = true; … … 80 83 }; 81 84 85 //------------------------------------------------------------- 86 // New AST 87 struct EvalNew : public ast::WithShortCircuiting { 88 long long int value = 0; 89 bool valid = true; 90 91 void previsit( const ast::Node * ) { visit_children = false; } 92 void postvisit( const ast::Node * ) { valid = false; } 93 94 void postvisit( const ast::ConstantExpr * expr ) { 95 value = expr->intValue(); 96 } 97 98 void postvisit( const ast::CastExpr * expr ) { 99 auto arg = eval(expr->arg); 100 valid = arg.second; 101 value = arg.first; 102 // TODO: perform type conversion on value if valid 103 } 104 105 void postvisit( const ast::VariableExpr * expr ) { 106 if ( const ast::EnumInstType * inst = dynamic_cast<const ast::EnumInstType *>(expr->result.get()) ) { 107 if ( const ast::EnumDecl * decl = inst->base ) { 108 if ( decl->valueOf( expr->var, value ) ) { // value filled by valueOf 109 return; 110 } 111 } 112 } 113 valid = false; 114 } 115 116 void postvisit( const ast::ApplicationExpr * expr ) { 117 const ast::DeclWithType * function = InitTweak::getFunction(expr); 118 if ( ! function || function->linkage != ast::Linkage::Intrinsic ) { valid = false; return; } 119 const std::string & fname = function->name; 120 assertf( expr->args.size() == 1 || expr->args.size() == 2, "Intrinsic function with %zd arguments: %s", expr->args.size(), fname.c_str() ); 121 std::pair<long long int, bool> arg1, arg2; 122 arg1 = eval(expr->args.front()); 123 valid = valid && arg1.second; 124 if ( ! valid ) return; 125 if ( expr->args.size() == 2 ) { 126 arg2 = eval(expr->args.back()); 127 valid = valid && arg2.second; 128 if ( ! valid ) return; 129 } 130 if (fname == "?+?") { 131 value = arg1.first + arg2.first; 132 } else if (fname == "?-?") { 133 value = arg1.first - arg2.first; 134 } else if (fname == "?*?") { 135 value = arg1.first * arg2.first; 136 } else if (fname == "?/?") { 137 value = arg1.first / arg2.first; 138 } else if (fname == "?%?") { 139 value = arg1.first % arg2.first; 140 } else { 141 valid = false; 142 } 143 // TODO: implement other intrinsic functions 144 } 145 }; 146 82 147 std::pair<long long int, bool> eval(Expression * expr) { 83 PassVisitor<Eval > ev;148 PassVisitor<EvalOld> ev; 84 149 if (expr) { 85 150 expr->accept(ev); … … 91 156 92 157 std::pair<long long int, bool> eval(const ast::Expr * expr) { 93 #warning not implemented 94 return { 0, false }; 158 ast::Pass<EvalNew> ev; 159 if (expr) { 160 expr->accept(ev); 161 return std::make_pair(ev.pass.value, ev.pass.valid); 162 } else { 163 return std::make_pair(0, false); 164 } 95 165 } 96 166 -
src/Common/PassVisitor.impl.h
rf685679 rf1ec88a 23 23 assert( __return ); \ 24 24 return __return; 25 26 27 #define VISIT_BODY( node ) \28 VISIT_START( node ); \29 if( children_guard ) { \30 Visitor::visit( node ); \31 } \32 VISIT_END( node ); \33 34 35 #define MUTATE_BODY( type, node ) \36 MUTATE_START( node ); \37 if( children_guard ) { \38 Mutator::mutate( node ); \39 } \40 MUTATE_END( type, node ); \41 42 25 43 26 … … 2762 2745 MUTATE_END( TypeSubstitution, node ); 2763 2746 } 2747 2748 #undef VISIT_START 2749 #undef VISIT_END 2750 2751 #undef MUTATE_START 2752 #undef MUTATE_END -
src/InitTweak/InitTweak.cc
rf685679 rf1ec88a 346 346 namespace { 347 347 DeclarationWithType * getCalledFunction( Expression * expr ); 348 const ast::DeclWithType * getCalledFunction( const ast::Expr * expr ); 348 349 349 350 template<typename CallExpr> … … 355 356 return getCalledFunction( expr->get_args().front() ); 356 357 } 358 359 template<typename CallExpr> 360 const ast::DeclWithType * handleDerefCalledFunction( const CallExpr * expr ) { 361 // (*f)(x) => should get "f" 362 std::string name = getFunctionName( expr ); 363 assertf( name == "*?", "Unexpected untyped expression: %s", name.c_str() ); 364 assertf( ! expr->args.empty(), "Cannot get called function from dereference with no arguments" ); 365 return getCalledFunction( expr->args.front() ); 366 } 367 357 368 358 369 DeclarationWithType * getCalledFunction( Expression * expr ) { … … 375 386 return nullptr; 376 387 } 388 389 const ast::DeclWithType * getCalledFunction( const ast::Expr * expr ) { 390 assert( expr ); 391 if ( const ast::VariableExpr * varExpr = dynamic_cast< const ast::VariableExpr * >( expr ) ) { 392 return varExpr->var; 393 } else if ( const ast::MemberExpr * memberExpr = dynamic_cast< const ast::MemberExpr * >( expr ) ) { 394 return memberExpr->member; 395 } else if ( const ast::CastExpr * castExpr = dynamic_cast< const ast::CastExpr * >( expr ) ) { 396 return getCalledFunction( castExpr->arg ); 397 } else if ( const ast::UntypedExpr * untypedExpr = dynamic_cast< const ast::UntypedExpr * >( expr ) ) { 398 return handleDerefCalledFunction( untypedExpr ); 399 } else if ( const ast::ApplicationExpr * appExpr = dynamic_cast< const ast::ApplicationExpr * > ( expr ) ) { 400 return handleDerefCalledFunction( appExpr ); 401 } else if ( const ast::AddressExpr * addrExpr = dynamic_cast< const ast::AddressExpr * >( expr ) ) { 402 return getCalledFunction( addrExpr->arg ); 403 } else if ( const ast::CommaExpr * commaExpr = dynamic_cast< const ast::CommaExpr * >( expr ) ) { 404 return getCalledFunction( commaExpr->arg2 ); 405 } 406 return nullptr; 407 } 377 408 } 378 409 … … 382 413 } else if ( UntypedExpr * untyped = dynamic_cast< UntypedExpr * > ( expr ) ) { 383 414 return getCalledFunction( untyped->get_function() ); 415 } 416 assertf( false, "getFunction received unknown expression: %s", toString( expr ).c_str() ); 417 } 418 419 const ast::DeclWithType * getFunction( const ast::Expr * expr ) { 420 if ( const ast::ApplicationExpr * appExpr = dynamic_cast< const ast::ApplicationExpr * >( expr ) ) { 421 return getCalledFunction( appExpr->func ); 422 } else if ( const ast::UntypedExpr * untyped = dynamic_cast< const ast::UntypedExpr * > ( expr ) ) { 423 return getCalledFunction( untyped->func ); 384 424 } 385 425 assertf( false, "getFunction received unknown expression: %s", toString( expr ).c_str() ); … … 434 474 } 435 475 436 //template<typename CallExpr>437 //const ast::Expr * callArg( const CallExpr * call, unsigned int pos ) {438 //if( pos >= call->args.size() ) {439 //assertf( false, "getCallArg for argument that doesn't exist: (%u); %s.",440 //pos, toString( call ).c_str() );441 //}442 //for ( const ast::Expr * arg : call->args ) {443 //if ( pos == 0 ) return arg;444 //--pos;445 //}446 //assert( false );447 //}476 template<typename CallExpr> 477 const ast::Expr * callArg( const CallExpr * call, unsigned int pos ) { 478 if( pos >= call->args.size() ) { 479 assertf( false, "getCallArg for argument that doesn't exist: (%u); %s.", 480 pos, toString( call ).c_str() ); 481 } 482 for ( const ast::Expr * arg : call->args ) { 483 if ( pos == 0 ) return arg; 484 --pos; 485 } 486 assert( false ); 487 } 448 488 } 449 489 … … 466 506 } 467 507 } 508 468 509 const ast::Expr * getCallArg( const ast::Expr * call, unsigned pos ) { 469 (void)call; 470 (void)pos; 471 #warning unimplemented; needs to build AST/Expr.cpp 472 assertf(false, "unimplemented; needs to build AST/Expr.cpp"); 473 // if ( auto app = dynamic_cast< const ast::ApplicationExpr * >( call ) ) { 474 // return callArg( app, pos ); 475 // } else if ( auto untyped = dynamic_cast< const ast::UntypedExpr * >( call ) ) { 476 // return callArg( untyped, pos ); 477 // } else if ( auto tupleAssn = dynamic_cast< const ast::TupleAssignExpr * >( call ) ) { 478 // const std::list<ast::ptr<ast::Stmt>>& stmts = tupleAssn->stmtExpr->stmts->kids; 479 // assertf( ! stmts.empty(), "TupleAssignExpr missing statements." ); 480 // const ExprStmt * stmt = strict_dynamic_cast< const ast::ExprStmt * >( stmts.back() ); 481 // const TupleExpr * tuple = strict_dynamic_cast< const ast::TupleExpr * >( stmt->expr ); 482 // assertf( ! tuple->exprs.empty(), "TupleAssignExpr has empty tuple expr."); 483 // return getCallArg( tuple->exprs.front(), pos ); 484 // } else if ( auto ctor = dynamic_cast< const ast::ImplicitCopyCtorExpr * >( call ) ) { 485 // return getCallArg( ctor->callExpr, pos ); 486 // } else { 487 // assertf( false, "Unexpected expression type passed to getCallArg: %s", 488 // toString( call ).c_str() ); 489 // } 510 if ( auto app = dynamic_cast< const ast::ApplicationExpr * >( call ) ) { 511 return callArg( app, pos ); 512 } else if ( auto untyped = dynamic_cast< const ast::UntypedExpr * >( call ) ) { 513 return callArg( untyped, pos ); 514 } else if ( auto tupleAssn = dynamic_cast< const ast::TupleAssignExpr * >( call ) ) { 515 const std::list<ast::ptr<ast::Stmt>>& stmts = tupleAssn->stmtExpr->stmts->kids; 516 assertf( ! stmts.empty(), "TupleAssignExpr missing statements." ); 517 auto stmt = strict_dynamic_cast< const ast::ExprStmt * >( stmts.back().get() ); 518 auto tuple = strict_dynamic_cast< const ast::TupleExpr * >( stmt->expr.get() ); 519 assertf( ! tuple->exprs.empty(), "TupleAssignExpr has empty tuple expr."); 520 return getCallArg( tuple->exprs.front(), pos ); 521 } else if ( auto ctor = dynamic_cast< const ast::ImplicitCopyCtorExpr * >( call ) ) { 522 return getCallArg( ctor->callExpr, pos ); 523 } else { 524 assertf( false, "Unexpected expression type passed to getCallArg: %s", 525 toString( call ).c_str() ); 526 } 490 527 } 491 528 492 529 namespace { 493 530 std::string funcName( Expression * func ); 531 std::string funcName( const ast::Expr * func ); 494 532 495 533 template<typename CallExpr> … … 500 538 assertf( ! expr->get_args().empty(), "Cannot get function name from dereference with no arguments" ); 501 539 return funcName( expr->get_args().front() ); 540 } 541 542 template<typename CallExpr> 543 std::string handleDerefName( const CallExpr * expr ) { 544 // (*f)(x) => should get name "f" 545 std::string name = getFunctionName( expr ); 546 assertf( name == "*?", "Unexpected untyped expression: %s", name.c_str() ); 547 assertf( ! expr->args.empty(), "Cannot get function name from dereference with no arguments" ); 548 return funcName( expr->args.front() ); 502 549 } 503 550 … … 523 570 } 524 571 } 572 573 std::string funcName( const ast::Expr * func ) { 574 if ( const ast::NameExpr * nameExpr = dynamic_cast< const ast::NameExpr * >( func ) ) { 575 return nameExpr->name; 576 } else if ( const ast::VariableExpr * varExpr = dynamic_cast< const ast::VariableExpr * >( func ) ) { 577 return varExpr->var->name; 578 } else if ( const ast::CastExpr * castExpr = dynamic_cast< const ast::CastExpr * >( func ) ) { 579 return funcName( castExpr->arg ); 580 } else if ( const ast::MemberExpr * memberExpr = dynamic_cast< const ast::MemberExpr * >( func ) ) { 581 return memberExpr->member->name; 582 } else if ( const ast::UntypedMemberExpr * memberExpr = dynamic_cast< const ast::UntypedMemberExpr * > ( func ) ) { 583 return funcName( memberExpr->member ); 584 } else if ( const ast::UntypedExpr * untypedExpr = dynamic_cast< const ast::UntypedExpr * >( func ) ) { 585 return handleDerefName( untypedExpr ); 586 } else if ( const ast::ApplicationExpr * appExpr = dynamic_cast< const ast::ApplicationExpr * >( func ) ) { 587 return handleDerefName( appExpr ); 588 } else if ( const ast::ConstructorExpr * ctorExpr = dynamic_cast< const ast::ConstructorExpr * >( func ) ) { 589 return funcName( getCallArg( ctorExpr->callExpr, 0 ) ); 590 } else { 591 assertf( false, "Unexpected expression type being called as a function in call expression: %s", toString( func ).c_str() ); 592 } 593 } 525 594 } 526 595 … … 539 608 } 540 609 610 std::string getFunctionName( const ast::Expr * expr ) { 611 // there's some unforunate overlap here with getCalledFunction. Ideally this would be able to use getCalledFunction and 612 // return the name of the DeclarationWithType, but this needs to work for NameExpr and UntypedMemberExpr, where getCalledFunction 613 // can't possibly do anything reasonable. 614 if ( const ast::ApplicationExpr * appExpr = dynamic_cast< const ast::ApplicationExpr * >( expr ) ) { 615 return funcName( appExpr->func ); 616 } else if ( const ast::UntypedExpr * untypedExpr = dynamic_cast< const ast::UntypedExpr * > ( expr ) ) { 617 return funcName( untypedExpr->func ); 618 } else { 619 std::cerr << expr << std::endl; 620 assertf( false, "Unexpected expression type passed to getFunctionName" ); 621 } 622 } 623 541 624 Type * getPointerBase( Type * type ) { 542 625 if ( PointerType * ptrType = dynamic_cast< PointerType * >( type ) ) { … … 551 634 } 552 635 const ast::Type* getPointerBase( const ast::Type* t ) { 553 (void)t; 554 #warning needs to build Type.cpp before inclusion 555 assertf(false, "needs to build Type.cpp before inclusion"); 556 // if ( const auto * p = dynamic_cast< const ast::PointerType * >( t ) ) { 557 // return p->base; 558 // } else if ( const auto * a = dynamic_cast< const ast::ArrayType * >( t ) ) { 559 // return a->base; 560 // } else if ( const auto * r = dynamic_cast< const ast::ReferenceType * >( t ) ) { 561 // return r->base; 562 // } else return nullptr; 636 if ( const auto * p = dynamic_cast< const ast::PointerType * >( t ) ) { 637 return p->base; 638 } else if ( const auto * a = dynamic_cast< const ast::ArrayType * >( t ) ) { 639 return a->base; 640 } else if ( const auto * r = dynamic_cast< const ast::ReferenceType * >( t ) ) { 641 return r->base; 642 } else return nullptr; 563 643 } 564 644 -
src/InitTweak/InitTweak.h
rf685679 rf1ec88a 58 58 /// returns the declaration of the function called by the expr (must be ApplicationExpr or UntypedExpr) 59 59 DeclarationWithType * getFunction( Expression * expr ); 60 const ast::DeclWithType * getFunction( const ast::Expr * expr ); 60 61 61 62 /// Non-Null if expr is a call expression whose target function is intrinsic … … 78 79 /// returns the name of the function being called 79 80 std::string getFunctionName( Expression * expr ); 81 std::string getFunctionName( const ast::Expr * expr ); 80 82 81 83 /// returns the argument to a call expression in position N indexed from 0
Note: See TracChangeset
for help on using the changeset viewer.