Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/CodeTools/ResolvProtoDump.cc

    r40cd873 ra4a000d  
    2727
    2828#include "Common/PassVisitor.h"
     29#include "Common/utility.h"
    2930#include "CodeGen/OperatorTable.h"
    3031#include "SynTree/Declaration.h"
    3132#include "SynTree/Expression.h"
     33#include "SynTree/Initializer.h"
    3234#include "SynTree/Statement.h"
    3335#include "SynTree/Type.h"
     
    3739        /// Visitor for dumping resolver prototype output
    3840        class ProtoDump : public WithShortCircuiting, public WithVisitorRef<ProtoDump> {
    39                 std::set<std::string> decls;     ///< Declarations in this scope
    40                 std::vector<std::string> exprs;  ///< Expressions in this scope
    41                 std::vector<ProtoDump> subs;     ///< Sub-scopes
    42                 const ProtoDump* parent;         ///< Outer lexical scope
     41                std::set<std::string> decls;             ///< Declarations in this scope
     42                std::vector<std::string> exprs;          ///< Expressions in this scope
     43                std::vector<ProtoDump> subs;             ///< Sub-scopes
     44                std::unordered_set<std::string> closed;  ///< Closed type variables
     45                const ProtoDump* parent;                 ///< Outer lexical scope
     46                std::unique_ptr<Type> rtnType;           ///< Return type for this scope
    4347
    4448        public:
    4549                /// Default constructor for root ProtoDump
    46                 ProtoDump() : decls(), exprs(), subs(), parent(nullptr) {}
     50                ProtoDump() : decls(), exprs(), subs(), closed(), parent(nullptr), rtnType(nullptr) {}
    4751
    4852                /// Child constructor
    49                 ProtoDump(const ProtoDump* p) : decls(), exprs(), subs(), parent(p) {}
     53                ProtoDump(const ProtoDump* p, Type* r)
     54                        : decls(), exprs(), subs(), closed(p->closed), parent(p), rtnType(r) {}
     55
     56                // Fix copy issues
     57                ProtoDump(const ProtoDump& o)
     58                        : decls(o.decls), exprs(o.exprs), subs(o.subs), closed(o.closed), parent(o.parent),
     59                          rtnType(maybeClone(o.rtnType.get())) {}
     60                ProtoDump( ProtoDump&& ) = default;
     61
     62                ProtoDump& operator= (const ProtoDump& o) {
     63                        if ( this == &o ) return *this;
     64
     65                        decls = o.decls;
     66                        exprs = o.exprs;
     67                        subs = o.subs;
     68                        closed = o.closed;
     69                        parent = o.parent;
     70                        rtnType.reset( maybeClone(o.rtnType.get()) );
     71                       
     72                        return *this;
     73                }
     74                ProtoDump& operator= (ProtoDump&&) = default;
    5075
    5176        private:
     
    183208                /// Visitor for printing types
    184209                struct TypePrinter : public WithShortCircuiting, WithVisitorRef<TypePrinter>, WithGuards {
    185                         std::stringstream& ss;  ///< Output to print to
    186                         unsigned depth;         ///< Depth of nesting from root type
    187 
    188                         TypePrinter( std::stringstream& ss ) : ss(ss), depth(0) {}
     210                        std::stringstream& ss;                          ///< Output to print to
     211                        const std::unordered_set<std::string>& closed;  ///< Closed type variables
     212                        unsigned depth;                                 ///< Depth of nesting from root type
     213
     214                        TypePrinter( const std::unordered_set<std::string>& closed, std::stringstream& ss )
     215                                : ss(ss), closed(closed), depth(0) {}
    189216
    190217                        // basic type represented as integer type
     
    252279                        void previsit( EnumInstType* ) { ss << (int)BasicType::SignedInt; }
    253280
    254                         // make sure first letter of TypeInstType is capitalized
    255281                        void previsit( TypeInstType* vt ) {
    256                                 ti_name( vt->name, ss );
     282                                // print closed variables as named types
     283                                if ( closed.count( vt->name ) ) { ss << '#' << vt->name; }
     284                                // otherwise make sure first letter is capitalized
     285                                else { ti_name( vt->name, ss ); }
    257286                        }
    258287
     
    280309                /// builds description of function
    281310                void build( const std::string& name, FunctionType* fnTy, std::stringstream& ss ) {
    282                         PassVisitor<TypePrinter> printTy{ ss };
     311                        PassVisitor<TypePrinter> printTy{ closed, ss };
     312                        // print return values
    283313                        build( printTy, from_decls( fnTy->returnVals ), ss, terminated );
     314                        // print name
    284315                        rp_name( name, ss );
     316                        // print parameters
    285317                        build( printTy, from_decls( fnTy->parameters ), ss, preceded );
    286                         // TODO handle assertions
     318                        // print assertions
     319                        for ( TypeDecl* tyvar : fnTy->forall ) {
     320                                for ( DeclarationWithType* assn : tyvar->assertions ) {
     321                                        ss << " | ";
     322                                        build( assn->name, assn->get_type(), ss );
     323                                }
     324                        }
    287325                }
    288326
     
    304342
    305343                        // print variable declaration as zero-arg function
    306                         PassVisitor<TypePrinter> printTy{ ss };
     344                        PassVisitor<TypePrinter> printTy{ closed, ss };
    307345                        norefs->accept( printTy );
    308346                        ss << ' ';
     
    316354
    317355                        // print access as new field name
    318                         PassVisitor<TypePrinter> printTy{ ss };
     356                        PassVisitor<TypePrinter> printTy{ closed, ss };
    319357                        norefs->accept( printTy );
    320358                        ss << ' ';
     
    337375                struct ExprPrinter : WithShortCircuiting, WithVisitorRef<ExprPrinter> {
    338376                        // TODO change interface to generate multiple expression candidates
    339 
    340                         std::stringstream& ss;  ///< Output to print to
    341 
    342                         ExprPrinter( std::stringstream& ss ) : ss(ss) {}
     377                        const std::unordered_set<std::string>& closed;  ///< set of closed type vars
     378                        std::stringstream& ss;                          ///< Output to print to
     379
     380                        ExprPrinter( const std::unordered_set<std::string>& closed, std::stringstream& ss )
     381                                : closed(closed), ss(ss) {}
    343382
    344383                        /// Names handled as nullary function calls
     
    379418                        /// Address-of handled as operator
    380419                        void previsit( AddressExpr* expr ) {
    381                                 // TODO global function to implement this
    382420                                ss << "$addr( ";
    383421                                expr->arg->accept( *visitor );
     
    389427                        /// TODO put cast target functions in, and add second expression for target
    390428                        void previsit( CastExpr* cast ) {
    391                                 PassVisitor<TypePrinter> tyPrinter{ ss };
     429                                PassVisitor<TypePrinter> tyPrinter{ closed, ss };
    392430                                cast->result->accept( tyPrinter );
    393431                                visit_children = false;
     
    416454                        /// Constant expression replaced by its type
    417455                        void previsit( ConstantExpr* expr ) {
    418                                 PassVisitor<TypePrinter> tyPrinter{ ss };
     456                                PassVisitor<TypePrinter> tyPrinter{ closed, ss };
    419457                                expr->constant.get_type()->accept( tyPrinter );
    420458                                visit_children = false;
     
    438476                        /// Logical expressions represented as operators
    439477                        void previsit( LogicalExpr* expr ) {
    440                                 // TODO global functions for these
    441478                                ss << '$' << ( expr->get_isAnd() ? "and" : "or" ) << "( ";
    442479                                expr->arg1->accept( *visitor );
     
    449486                        /// Conditional expression represented as operator
    450487                        void previsit( ConditionalExpr* expr ) {
    451                                 // TODO global function for this
    452488                                ss << "$if( ";
    453489                                expr->arg1->accept( *visitor );
     
    462498                        /// Comma expression represented as operator
    463499                        void previsit( CommaExpr* expr ) {
    464                                 // TODO global function for this
    465500                                ss << "$seq( ";
    466501                                expr->arg1->accept( *visitor );
     
    473508                        // TODO handle ignored ImplicitCopyCtorExpr and below
    474509                };
     510
     511                void build( Initializer* init, std::stringstream& ss ) {
     512                        if ( SingleInit* si = dynamic_cast<SingleInit*>(init) ) {
     513                                PassVisitor<ExprPrinter> exprPrinter{ closed, ss };
     514                                si->value->accept( exprPrinter );
     515                                ss << ' ';
     516                        } else if ( ListInit* li = dynamic_cast<ListInit*>(init) ) {
     517                                for ( Initializer* it : li->initializers ) {
     518                                        build( it, ss );
     519                                        ss << ' ';
     520                                }
     521                        }
     522                }
     523
     524                /// Adds an object initializer to the list of expressions
     525                void build( const std::string& name, Initializer* init, std::stringstream& ss ) {
     526                        ss << "$constructor( ";
     527                        rp_name( name, ss );
     528                        ss << "() ";
     529                        build( init, ss );
     530                        ss << ')';
     531                }
     532
     533                /// Adds a return expression to the list of expressions
     534                void build( Type* rtnType, Expression* expr, std::stringstream& ss ) {
     535                        ss << "$constructor( ";
     536                        PassVisitor<TypePrinter> tyPrinter{ closed, ss };
     537                        rtnType->accept( tyPrinter );
     538                        ss << ' ';
     539                        PassVisitor<ExprPrinter> exprPrinter{ closed, ss };
     540                        expr->accept( exprPrinter );
     541                        ss << " )";
     542                }
    475543
    476544                /// Adds all named declarations in a list to the local scope
     
    507575                        build( obj->name, obj->type, ss );
    508576                        addDecl( ss.str() );
     577
     578                        // add initializer as expression if applicable
     579                        if ( obj->init ) {
     580                                std::stringstream ss;
     581                                build( obj->name, obj->init, ss );
     582                                addExpr( ss.str() );
     583                        }
    509584                }
    510585
     
    517592                        // add body if available
    518593                        if ( decl->statements ) {
    519                                 PassVisitor<ProtoDump> body{ this };
     594                                std::list<Type*> rtns = from_decls( decl->type->returnVals );
     595                                Type* rtn = nullptr;
     596                                if ( rtns.size() == 1 ) {
     597                                        if ( ! dynamic_cast<VoidType*>(rtns.front()) ) rtn = rtns.front()->clone();
     598                                } else if ( rtns.size() > 1 ) {
     599                                        rtn = new TupleType{ Type::Qualifiers{}, rtns };
     600                                }
     601                                PassVisitor<ProtoDump> body{ this, rtn };
     602
     603                                for ( TypeDecl* tyvar : decl->type->forall ) {
     604                                        // add set of "closed" types to body so that it can print them as NamedType
     605                                        body.pass.closed.insert( tyvar->name );
     606
     607                                        // add assertions to local scope as declarations as well
     608                                        for ( DeclarationWithType* assn : tyvar->assertions ) {
     609                                                assn->accept( body );
     610                                        }
     611                                }
    520612                               
    521613                                // add named parameters and returns to local scope
    522614                                body.pass.addAll( decl->type->returnVals );
    523615                                body.pass.addAll( decl->type->parameters );
    524                                
    525                                 // TODO add assertions to local scope
    526 
    527                                 // TODO add set of "closed" types to body so that it can print them as NamedType
    528616
    529617                                // add contents of function to new scope
     
    554642                }
    555643
     644                void previsit( ReturnStmt* stmt ) {
     645                        // do nothing for void-returning functions or statements returning nothing
     646                        if ( ! rtnType || ! stmt->expr ) return;
     647
     648                        // otherwise construct the return type from the expression
     649                        std::stringstream ss;
     650                        build( rtnType.get(), stmt->expr, ss );
     651                        addExpr( ss.str() );
     652                        visit_children = false;
     653                }
     654
    556655                void previsit( Expression* expr ) {
    557656                        std::stringstream ss;
    558                         PassVisitor<ExprPrinter> exPrinter{ss};
     657                        PassVisitor<ExprPrinter> exPrinter{ closed, ss };
    559658                        expr->accept( exPrinter );
    560659                        addExpr( ss.str() );
     
    562661                }
    563662
     663                /// Print non-prelude global declarations for resolv proto
     664                void printGlobals() const {
     665                        std::cout << "#ptr<T> $addr T" << std::endl;  // &?
     666                        int i = (int)BasicType::SignedInt;
     667                        std::cout << i << " $and " << i << ' ' << i << std::endl;  // ?&&?
     668                        std::cout << i << " $or " << i << ' ' << i << std::endl;  // ?||?
     669                        std::cout << "T $if " << i << " T T" << std::endl; // ternary operator
     670                        std::cout << "T $seq X T" << std::endl;  // ?,?
     671                }
     672
    564673        public:
    565674                /// Prints this ProtoDump instance
    566675                void print(unsigned indent = 0) const {
     676                        // print globals at root level
     677                        if ( ! parent ) printGlobals();
     678                        // print decls
    567679                        std::string tab( indent, '\t' );
    568                         // print decls
    569680                        for ( const std::string& d : decls ) {
    570681                                std::cout << tab << d << std::endl;
    571682                        }
    572683                        // print divider
    573                         std::cout << tab << "%%" << std::endl;
     684                        std::cout << '\n' << tab << "%%\n" << std::endl;
    574685                        // print top-level expressions
    575686                        for ( const std::string& e : exprs ) {
Note: See TracChangeset for help on using the changeset viewer.