Changeset f1ec88a


Ignore:
Timestamp:
May 23, 2019, 5:06:37 PM (5 years ago)
Author:
Andrew Beach <ajbeach@…>
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.
Message:

Merge branch 'master' of plg.uwaterloo.ca:software/cfa/cfa-cc

Location:
src
Files:
12 edited

Legend:

Unmodified
Added
Removed
  • src/AST/Convert.cpp

    rf685679 rf1ec88a  
    704704        }
    705705
    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-values
    717                         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 
    742706        const ast::Expr * visit( const ast::ConstantExpr * node ) override final {
    743707                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 ),
    747712                                node->rep,
    748713                                (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{
    752718                                get<Type>().accept1(node->result),
    753719                                node->rep,
    754720                                (double) node->floatValue()
    755                         ));
    756                 } else if (isStringlikeConstantType(node->result)) {
    757                         rslt = new ConstantExpr(Constant::from_string(
    758                                 node->rep
    759                         ));
     721                        }};
     722                        break;
     723                case ast::ConstantExpr::String:
     724                        rslt = new ConstantExpr{Constant::from_string( node->rep )};
     725                        break;
    760726                }
    761727                assert(rslt);
  • src/AST/Decl.cpp

    rf685679 rf1ec88a  
    7272// --- EnumDecl
    7373
    74 bool EnumDecl::valueOf( Decl* enumerator, long long& value ) const {
     74bool EnumDecl::valueOf( const Decl * enumerator, long long& value ) const {
    7575        if ( enumValues.empty() ) {
    7676                long long crntVal = 0;
    77                 for ( const Decl* member : members ) {
     77                for ( const Decl * member : members ) {
    7878                        const ObjectDecl* field = strict_dynamic_cast< const ObjectDecl* >( member );
    7979                        if ( field->init ) {
  • src/AST/Decl.hpp

    rf685679 rf1ec88a  
    287287
    288288        /// 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;
    290290
    291291        const Decl * accept( Visitor & v ) const override { return v.visit( this ); }
  • src/AST/Expr.cpp

    rf685679 rf1ec88a  
    241241                        FixedLen, DynamicDim },
    242242                std::string{"\""} + s + "\"",
    243                 (unsigned long long)0 };
     243                (unsigned long long)0,
     244                ConstantExpr::String };
    244245}
    245246
  • src/AST/Expr.hpp

    rf685679 rf1ec88a  
    337337public:
    338338        std::string rep;
     339        enum Kind { Integer, FloatingPoint, String } kind;
    339340
    340341        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 ) {}
    343345        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 ) {}
    345347
    346348        /// Gets the value of this constant as an integer
  • src/AST/Pass.proto.hpp

    rf685679 rf1ec88a  
    109109        };
    110110
     111        /// "Short hand" to check if this is a valid previsit function
     112        /// Mostly used to make the static_assert look (and print) prettier
    111113        template<typename pass_t, typename node_t>
    112114        struct is_valid_previsit {
     
    117119        };
    118120
     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
    119124        template<bool is_void>
    120125        struct __assign;
     
    134139                        node = pass.previsit( node );
    135140                        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 );
    136164                }
    137165        };
     
    174202                decltype( pass.postvisit( node ), node->accept( *(Visitor*)nullptr ) )
    175203        {
    176                 return pass.postvisit( node );
     204                return __return<
     205                        std::is_void<
     206                                decltype( pass.postvisit( node ) )
     207                        >::value
     208                >::result( pass, node );
    177209        }
    178210
  • src/AST/Print.cpp

    rf685679 rf1ec88a  
    5959        }
    6060
     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
    6180
    6281        static const char* Names[];
     
    99118        }
    100119
     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
    101168        void print( const ast::AggregateDecl * node ) {
    102169                os << node->typeString() << " " << node->name << ":";
     
    155222        }
    156223
     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
    157254public:
    158255        virtual const ast::DeclWithType * visit( const ast::ObjectDecl * node ) {
     
    168265                        node->type->accept( *this );
    169266                } else {
    170                         os << " untyped entity ";
     267                        os << "untyped entity";
    171268                } // if
    172269
     
    214311                        node->type->accept( *this );
    215312                } else {
    216                         os << "untyped entity ";
     313                        os << "untyped entity";
    217314                } // if
    218315
     
    291388                ++indent;
    292389                os << "Expression Statement:" << endl << indent;
    293                 node->expr->accept( *this );
     390                safe_print( node->expr );
    294391                --indent;
    295392                return node;
     
    326423                os << indent+1;
    327424                ++indent;
    328                 node->cond->accept( *this );
     425                safe_print( node->cond );
    329426                --indent;
    330427
     
    344441                ++indent;
    345442                os << indent;
    346                 node->thenPart->accept( *this );
     443                safe_print( node->thenPart );
    347444                --indent;
    348445
     
    418515
    419516        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
    420528                return node;
    421529        }
    422530
    423531        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
    424541                return node;
    425542        }
    426543
    427544        virtual const ast::Expr * visit( const ast::NameExpr * node ) {
     545                os << "Name: " << node->name;
     546                postprint( node );
     547               
    428548                return node;
    429549        }
    430550
    431551        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
    432559                return node;
    433560        }
    434561
    435562        virtual const ast::Expr * visit( const ast::LabelAddressExpr * node ) {
     563                os << "Address of label:" << node->arg;
     564
    436565                return node;
    437566        }
    438567
    439568        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
    440585                return node;
    441586        }
    442587
    443588        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
    444596                return node;
    445597        }
    446598
    447599        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
    448613                return node;
    449614        }
    450615
    451616        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
    452625                return node;
    453626        }
    454627
    455628        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
    456637                return node;
    457638        }
    458639
    459640        virtual const ast::Expr * visit( const ast::VariableExpr * node ) {
     641                os << "Variable Expression: ";
     642                short_print( node->var );
     643                postprint( node );
     644
    460645                return node;
    461646        }
    462647
    463648        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
    464657                return node;
    465658        }
     
    566759
    567760        virtual const ast::Type * visit( const ast::VoidType * node ) {
     761                preprint( node );
     762                os << "void";
    568763                return node;
    569764        }
    570765
    571766        virtual const ast::Type * visit( const ast::BasicType * node ) {
     767                preprint( node );
     768                os << ast::BasicType::typeNames[ node->kind ];
    572769                return node;
    573770        }
    574771
    575772        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
    576792                return node;
    577793        }
    578794
    579795        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
    580816                return node;
    581817        }
    582818
    583819        virtual const ast::Type * visit( const ast::ReferenceType * node ) {
     820                preprint( node );
     821                os << "reference to ";
     822                safe_print( node->base );
     823
    584824                return node;
    585825        }
    586826
    587827        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
    588837                return node;
    589838        }
    590839
    591840        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
    592866                return node;
    593867        }
    594868
    595869        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
    596877                return node;
    597878        }
    598879
    599880        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
    600888                return node;
    601889        }
    602890
    603891        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
    604899                return node;
    605900        }
    606901
    607902        virtual const ast::Type * visit( const ast::TraitInstType * node ) {
     903                preprint( node );
     904                os << "instance of trait " << node->name;
     905                print( node->params );
     906
    608907                return node;
    609908        }
    610909
    611910        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
    612916                return node;
    613917        }
    614918
    615919        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
    616926                return node;
    617927        }
    618928
    619929        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
    620935                return node;
    621936        }
    622937
    623938        virtual const ast::Type * visit( const ast::VarArgsType * node ) {
     939                preprint( node );
     940                os << "builtin var args pack";
    624941                return node;
    625942        }
    626943
    627944        virtual const ast::Type * visit( const ast::ZeroType * node ) {
     945                preprint( node );
     946                os << "zero_t";
    628947                return node;
    629948        }
    630949
    631950        virtual const ast::Type * visit( const ast::OneType * node ) {
     951                preprint( node );
     952                os << "one_t";
    632953                return node;
    633954        }
    634955
    635956        virtual const ast::Type * visit( const ast::GlobalScopeType * node ) {
     957                preprint( node );
     958                os << "Global Scope Type";
    636959                return node;
    637960        }
     
    652975        virtual const ast::Init * visit( const ast::SingleInit * node ) {
    653976                os << "Simple Initializer: ";
    654                 node->value->accept( *this );
     977                safe_print( node->value );
    655978                return node;
    656979        }
     
    7151038                        os << indent+1 << i.first << " -> ";
    7161039                        indent += 2;
    717                         i.second->accept( *this );
     1040                        safe_print( i.second );
    7181041                        indent -= 2;
    7191042                        os << std::endl;
     
    7231046                        os << indent+1 << i->first << " -> ";
    7241047                        indent += 2;
    725                         i->second->accept( *this );
     1048                        safe_print( i->second );
    7261049                        indent -= 2;
    7271050                        os << std::endl;
  • src/AST/Type.hpp

    rf685679 rf1ec88a  
    308308        virtual ReferenceToType * clone() const override = 0;
    309309        MUTATE_FRIEND
    310 
    311 protected:
    312         /// Name for the kind of type this is
    313         virtual std::string typeString() const = 0;
    314310};
    315311
     
    333329        StructInstType * clone() const override { return new StructInstType{ *this }; }
    334330        MUTATE_FRIEND
    335 
    336         std::string typeString() const override { return "struct"; }
    337331};
    338332
     
    356350        UnionInstType * clone() const override { return new UnionInstType{ *this }; }
    357351        MUTATE_FRIEND
    358 
    359         std::string typeString() const override { return "union"; }
    360352};
    361353
     
    379371        EnumInstType * clone() const override { return new EnumInstType{ *this }; }
    380372        MUTATE_FRIEND
    381 
    382         std::string typeString() const override { return "enum"; }
    383373};
    384374
     
    403393        TraitInstType * clone() const override { return new TraitInstType{ *this }; }
    404394        MUTATE_FRIEND
    405 
    406         std::string typeString() const override { return "trait"; }
    407395};
    408396
     
    432420        TypeInstType * clone() const override { return new TypeInstType{ *this }; }
    433421        MUTATE_FRIEND
    434 
    435         std::string typeString() const override { return "type"; }
    436422};
    437423
  • src/Common/Eval.cc

    rf685679 rf1ec88a  
    1717
    1818#include "Common/PassVisitor.h"
     19#include "AST/Pass.hpp"
    1920#include "InitTweak/InitTweak.h"
    2021#include "SynTree/Expression.h"
    2122
    22 struct Eval : public WithShortCircuiting {
     23//-------------------------------------------------------------
     24// Old AST
     25struct EvalOld : public WithShortCircuiting {
    2326        long long int value = 0;
    2427        bool valid = true;
     
    8083};
    8184
     85//-------------------------------------------------------------
     86// New AST
     87struct 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
    82147std::pair<long long int, bool> eval(Expression * expr) {
    83         PassVisitor<Eval> ev;
     148        PassVisitor<EvalOld> ev;
    84149        if (expr) {
    85150                expr->accept(ev);
     
    91156
    92157std::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        }
    95165}
    96166
  • src/Common/PassVisitor.impl.h

    rf685679 rf1ec88a  
    2323        assert( __return ); \
    2424        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 
    4225
    4326
     
    27622745        MUTATE_END( TypeSubstitution, node );
    27632746}
     2747
     2748#undef VISIT_START
     2749#undef VISIT_END
     2750
     2751#undef MUTATE_START
     2752#undef MUTATE_END
  • src/InitTweak/InitTweak.cc

    rf685679 rf1ec88a  
    346346        namespace {
    347347                DeclarationWithType * getCalledFunction( Expression * expr );
     348                const ast::DeclWithType * getCalledFunction( const ast::Expr * expr );
    348349
    349350                template<typename CallExpr>
     
    355356                        return getCalledFunction( expr->get_args().front() );
    356357                }
     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
    357368
    358369                DeclarationWithType * getCalledFunction( Expression * expr ) {
     
    375386                        return nullptr;
    376387                }
     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                }
    377408        }
    378409
     
    382413                } else if ( UntypedExpr * untyped = dynamic_cast< UntypedExpr * > ( expr ) ) {
    383414                        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 );
    384424                }
    385425                assertf( false, "getFunction received unknown expression: %s", toString( expr ).c_str() );
     
    434474                }
    435475
    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                }
    448488        }
    449489
     
    466506                }
    467507        }
     508
    468509        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                }
    490527        }
    491528
    492529        namespace {
    493530                std::string funcName( Expression * func );
     531                std::string funcName( const ast::Expr * func );
    494532
    495533                template<typename CallExpr>
     
    500538                        assertf( ! expr->get_args().empty(), "Cannot get function name from dereference with no arguments" );
    501539                        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() );
    502549                }
    503550
     
    523570                        }
    524571                }
     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                }
    525594        }
    526595
     
    539608        }
    540609
     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
    541624        Type * getPointerBase( Type * type ) {
    542625                if ( PointerType * ptrType = dynamic_cast< PointerType * >( type ) ) {
     
    551634        }
    552635        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;
    563643        }
    564644
  • src/InitTweak/InitTweak.h

    rf685679 rf1ec88a  
    5858        /// returns the declaration of the function called by the expr (must be ApplicationExpr or UntypedExpr)
    5959        DeclarationWithType * getFunction( Expression * expr );
     60        const ast::DeclWithType * getFunction( const ast::Expr * expr );
    6061
    6162        /// Non-Null if expr is a call expression whose target function is intrinsic
     
    7879        /// returns the name of the function being called
    7980        std::string getFunctionName( Expression * expr );
     81        std::string getFunctionName( const ast::Expr * expr );
    8082
    8183        /// returns the argument to a call expression in position N indexed from 0
Note: See TracChangeset for help on using the changeset viewer.