Changes in / [af1e8f56:20a5977]


Ignore:
Location:
src
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • src/AST/Decl.cpp

    raf1e8f56 r20a5977  
    7272// --- EnumDecl
    7373
    74 bool EnumDecl::valueOf( const Decl * enumerator, long long& value ) const {
     74bool EnumDecl::valueOf( 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

    raf1e8f56 r20a5977  
    287287
    288288        /// gets the integer value for this enumerator, returning true iff value found
    289         bool valueOf( const Decl * enumerator, long long& value ) const;
     289        bool valueOf( Decl* enumerator, long long& value ) const;
    290290
    291291        const Decl * accept( Visitor & v ) const override { return v.visit( this ); }
  • src/AST/Pass.proto.hpp

    raf1e8f56 r20a5977  
    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
    113111        template<typename pass_t, typename node_t>
    114112        struct is_valid_previsit {
     
    119117        };
    120118
    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
    124119        template<bool is_void>
    125120        struct __assign;
     
    139134                        node = pass.previsit( node );
    140135                        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 );
    164136                }
    165137        };
     
    202174                decltype( pass.postvisit( node ), node->accept( *(Visitor*)nullptr ) )
    203175        {
    204                 return __return<
    205                         std::is_void<
    206                                 decltype( pass.postvisit( node ) )
    207                         >::value
    208                 >::result( pass, node );
     176                return pass.postvisit( node );
    209177        }
    210178
  • src/Common/Eval.cc

    raf1e8f56 r20a5977  
    1717
    1818#include "Common/PassVisitor.h"
    19 #include "AST/Pass.hpp"
    2019#include "InitTweak/InitTweak.h"
    2120#include "SynTree/Expression.h"
    2221
    23 //-------------------------------------------------------------
    24 // Old AST
    25 struct EvalOld : public WithShortCircuiting {
     22struct Eval : public WithShortCircuiting {
    2623        long long int value = 0;
    2724        bool valid = true;
     
    8380};
    8481
    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 
    14782std::pair<long long int, bool> eval(Expression * expr) {
    148         PassVisitor<EvalOld> ev;
     83        PassVisitor<Eval> ev;
    14984        if (expr) {
    15085                expr->accept(ev);
     
    15691
    15792std::pair<long long int, bool> eval(const ast::Expr * expr) {
    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         }
     93        #warning not implemented
     94        return { 0, false };
    16595}
    16696
  • src/Common/PassVisitor.impl.h

    raf1e8f56 r20a5977  
    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
    2542
    2643
     
    27452762        MUTATE_END( TypeSubstitution, node );
    27462763}
    2747 
    2748 #undef VISIT_START
    2749 #undef VISIT_END
    2750 
    2751 #undef MUTATE_START
    2752 #undef MUTATE_END
  • src/InitTweak/InitTweak.cc

    raf1e8f56 r20a5977  
    346346        namespace {
    347347                DeclarationWithType * getCalledFunction( Expression * expr );
    348                 const ast::DeclWithType * getCalledFunction( const ast::Expr * expr );
    349348
    350349                template<typename CallExpr>
     
    356355                        return getCalledFunction( expr->get_args().front() );
    357356                }
    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 
    368357
    369358                DeclarationWithType * getCalledFunction( Expression * expr ) {
     
    386375                        return nullptr;
    387376                }
    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                 }
    408377        }
    409378
     
    413382                } else if ( UntypedExpr * untyped = dynamic_cast< UntypedExpr * > ( expr ) ) {
    414383                        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 );
    424384                }
    425385                assertf( false, "getFunction received unknown expression: %s", toString( expr ).c_str() );
     
    474434                }
    475435
    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                 }
     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                // }
    488448        }
    489449
     
    506466                }
    507467        }
    508 
    509468        const ast::Expr * getCallArg( const ast::Expr * call, unsigned pos ) {
    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                 }
     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                // }
    527490        }
    528491
    529492        namespace {
    530493                std::string funcName( Expression * func );
    531                 std::string funcName( const ast::Expr * func );
    532494
    533495                template<typename CallExpr>
     
    538500                        assertf( ! expr->get_args().empty(), "Cannot get function name from dereference with no arguments" );
    539501                        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() );
    549502                }
    550503
     
    570523                        }
    571524                }
    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                 }
    594525        }
    595526
     
    608539        }
    609540
    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 
    624541        Type * getPointerBase( Type * type ) {
    625542                if ( PointerType * ptrType = dynamic_cast< PointerType * >( type ) ) {
     
    634551        }
    635552        const ast::Type* getPointerBase( const ast::Type* t ) {
    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;
     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;
    643563        }
    644564
  • src/InitTweak/InitTweak.h

    raf1e8f56 r20a5977  
    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 );
    6160
    6261        /// Non-Null if expr is a call expression whose target function is intrinsic
     
    7978        /// returns the name of the function being called
    8079        std::string getFunctionName( Expression * expr );
    81         std::string getFunctionName( const ast::Expr * expr );
    8280
    8381        /// returns the argument to a call expression in position N indexed from 0
Note: See TracChangeset for help on using the changeset viewer.