Changes in / [f1ec88a:f685679]


Ignore:
Location:
src
Files:
12 edited

Legend:

Unmodified
Added
Removed
  • src/AST/Convert.cpp

    rf1ec88a rf685679  
    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
    706742        const ast::Expr * visit( const ast::ConstantExpr * node ) override final {
    707743                ConstantExpr *rslt = nullptr;
    708                 switch ( node->kind ) {
    709                 case ast::ConstantExpr::Integer:
    710                         rslt = new ConstantExpr{Constant{
    711                                 get<Type>().accept1( node->result ),
     744                if (isIntlikeConstantType(node->result)) {
     745                        rslt = new ConstantExpr(Constant(
     746                                get<Type>().accept1(node->result),
    712747                                node->rep,
    713748                                (unsigned long long) node->intValue()
    714                         }};
    715                         break;
    716                 case ast::ConstantExpr::FloatingPoint:
    717                         rslt = new ConstantExpr{Constant{
     749                        ));
     750                } else if (isFloatlikeConstantType(node->result)) {
     751                        rslt = new ConstantExpr(Constant(
    718752                                get<Type>().accept1(node->result),
    719753                                node->rep,
    720754                                (double) node->floatValue()
    721                         }};
    722                         break;
    723                 case ast::ConstantExpr::String:
    724                         rslt = new ConstantExpr{Constant::from_string( node->rep )};
    725                         break;
     755                        ));
     756                } else if (isStringlikeConstantType(node->result)) {
     757                        rslt = new ConstantExpr(Constant::from_string(
     758                                node->rep
     759                        ));
    726760                }
    727761                assert(rslt);
  • src/AST/Decl.cpp

    rf1ec88a rf685679  
    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

    rf1ec88a rf685679  
    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/Expr.cpp

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

    rf1ec88a rf685679  
    337337public:
    338338        std::string rep;
    339         enum Kind { Integer, FloatingPoint, String } kind;
    340339
    341340        ConstantExpr(
    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 ) {}
     341                const CodeLocation & loc, const Type * ty, const std::string & r, unsigned long long v )
     342        : Expr( loc, ty ), val( v ), rep( r ) {}
    345343        ConstantExpr( const CodeLocation & loc, const Type * ty, const std::string & r, double v )
    346         : Expr( loc, ty ), val( v ), rep( r ), kind( FloatingPoint ) {}
     344        : Expr( loc, ty ), val( v ), rep( r ) {}
    347345
    348346        /// Gets the value of this constant as an integer
  • src/AST/Pass.proto.hpp

    rf1ec88a rf685679  
    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/AST/Print.cpp

    rf1ec88a rf685679  
    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 
    8061
    8162        static const char* Names[];
     
    11899        }
    119100
    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 
    168101        void print( const ast::AggregateDecl * node ) {
    169102                os << node->typeString() << " " << node->name << ":";
     
    222155        }
    223156
    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 
    254157public:
    255158        virtual const ast::DeclWithType * visit( const ast::ObjectDecl * node ) {
     
    265168                        node->type->accept( *this );
    266169                } else {
    267                         os << "untyped entity";
     170                        os << " untyped entity ";
    268171                } // if
    269172
     
    311214                        node->type->accept( *this );
    312215                } else {
    313                         os << "untyped entity";
     216                        os << "untyped entity ";
    314217                } // if
    315218
     
    388291                ++indent;
    389292                os << "Expression Statement:" << endl << indent;
    390                 safe_print( node->expr );
     293                node->expr->accept( *this );
    391294                --indent;
    392295                return node;
     
    423326                os << indent+1;
    424327                ++indent;
    425                 safe_print( node->cond );
     328                node->cond->accept( *this );
    426329                --indent;
    427330
     
    441344                ++indent;
    442345                os << indent;
    443                 safe_print( node->thenPart );
     346                node->thenPart->accept( *this );
    444347                --indent;
    445348
     
    515418
    516419        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 
    528420                return node;
    529421        }
    530422
    531423        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 
    541424                return node;
    542425        }
    543426
    544427        virtual const ast::Expr * visit( const ast::NameExpr * node ) {
    545                 os << "Name: " << node->name;
    546                 postprint( node );
    547                
    548428                return node;
    549429        }
    550430
    551431        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 
    559432                return node;
    560433        }
    561434
    562435        virtual const ast::Expr * visit( const ast::LabelAddressExpr * node ) {
    563                 os << "Address of label:" << node->arg;
    564 
    565436                return node;
    566437        }
    567438
    568439        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 
    585440                return node;
    586441        }
    587442
    588443        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 
    596444                return node;
    597445        }
    598446
    599447        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 
    613448                return node;
    614449        }
    615450
    616451        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 
    625452                return node;
    626453        }
    627454
    628455        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 
    637456                return node;
    638457        }
    639458
    640459        virtual const ast::Expr * visit( const ast::VariableExpr * node ) {
    641                 os << "Variable Expression: ";
    642                 short_print( node->var );
    643                 postprint( node );
    644 
    645460                return node;
    646461        }
    647462
    648463        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 
    657464                return node;
    658465        }
     
    759566
    760567        virtual const ast::Type * visit( const ast::VoidType * node ) {
    761                 preprint( node );
    762                 os << "void";
    763568                return node;
    764569        }
    765570
    766571        virtual const ast::Type * visit( const ast::BasicType * node ) {
    767                 preprint( node );
    768                 os << ast::BasicType::typeNames[ node->kind ];
    769572                return node;
    770573        }
    771574
    772575        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 
    792576                return node;
    793577        }
    794578
    795579        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 
    816580                return node;
    817581        }
    818582
    819583        virtual const ast::Type * visit( const ast::ReferenceType * node ) {
    820                 preprint( node );
    821                 os << "reference to ";
    822                 safe_print( node->base );
    823 
    824584                return node;
    825585        }
    826586
    827587        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 
    837588                return node;
    838589        }
    839590
    840591        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 
    866592                return node;
    867593        }
    868594
    869595        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 
    877596                return node;
    878597        }
    879598
    880599        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 
    888600                return node;
    889601        }
    890602
    891603        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 
    899604                return node;
    900605        }
    901606
    902607        virtual const ast::Type * visit( const ast::TraitInstType * node ) {
    903                 preprint( node );
    904                 os << "instance of trait " << node->name;
    905                 print( node->params );
    906 
    907608                return node;
    908609        }
    909610
    910611        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 
    916612                return node;
    917613        }
    918614
    919615        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 
    926616                return node;
    927617        }
    928618
    929619        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 
    935620                return node;
    936621        }
    937622
    938623        virtual const ast::Type * visit( const ast::VarArgsType * node ) {
    939                 preprint( node );
    940                 os << "builtin var args pack";
    941624                return node;
    942625        }
    943626
    944627        virtual const ast::Type * visit( const ast::ZeroType * node ) {
    945                 preprint( node );
    946                 os << "zero_t";
    947628                return node;
    948629        }
    949630
    950631        virtual const ast::Type * visit( const ast::OneType * node ) {
    951                 preprint( node );
    952                 os << "one_t";
    953632                return node;
    954633        }
    955634
    956635        virtual const ast::Type * visit( const ast::GlobalScopeType * node ) {
    957                 preprint( node );
    958                 os << "Global Scope Type";
    959636                return node;
    960637        }
     
    975652        virtual const ast::Init * visit( const ast::SingleInit * node ) {
    976653                os << "Simple Initializer: ";
    977                 safe_print( node->value );
     654                node->value->accept( *this );
    978655                return node;
    979656        }
     
    1038715                        os << indent+1 << i.first << " -> ";
    1039716                        indent += 2;
    1040                         safe_print( i.second );
     717                        i.second->accept( *this );
    1041718                        indent -= 2;
    1042719                        os << std::endl;
     
    1046723                        os << indent+1 << i->first << " -> ";
    1047724                        indent += 2;
    1048                         safe_print( i->second );
     725                        i->second->accept( *this );
    1049726                        indent -= 2;
    1050727                        os << std::endl;
  • src/AST/Type.hpp

    rf1ec88a rf685679  
    308308        virtual ReferenceToType * clone() const override = 0;
    309309        MUTATE_FRIEND
     310
     311protected:
     312        /// Name for the kind of type this is
     313        virtual std::string typeString() const = 0;
    310314};
    311315
     
    329333        StructInstType * clone() const override { return new StructInstType{ *this }; }
    330334        MUTATE_FRIEND
     335
     336        std::string typeString() const override { return "struct"; }
    331337};
    332338
     
    350356        UnionInstType * clone() const override { return new UnionInstType{ *this }; }
    351357        MUTATE_FRIEND
     358
     359        std::string typeString() const override { return "union"; }
    352360};
    353361
     
    371379        EnumInstType * clone() const override { return new EnumInstType{ *this }; }
    372380        MUTATE_FRIEND
     381
     382        std::string typeString() const override { return "enum"; }
    373383};
    374384
     
    393403        TraitInstType * clone() const override { return new TraitInstType{ *this }; }
    394404        MUTATE_FRIEND
     405
     406        std::string typeString() const override { return "trait"; }
    395407};
    396408
     
    420432        TypeInstType * clone() const override { return new TypeInstType{ *this }; }
    421433        MUTATE_FRIEND
     434
     435        std::string typeString() const override { return "type"; }
    422436};
    423437
  • src/Common/Eval.cc

    rf1ec88a rf685679  
    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

    rf1ec88a rf685679  
    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

    rf1ec88a rf685679  
    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

    rf1ec88a rf685679  
    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.