Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/CodeTools/ResolvProtoDump.cc

    ra4a000d r40cd873  
    2727
    2828#include "Common/PassVisitor.h"
    29 #include "Common/utility.h"
    3029#include "CodeGen/OperatorTable.h"
    3130#include "SynTree/Declaration.h"
    3231#include "SynTree/Expression.h"
    33 #include "SynTree/Initializer.h"
    3432#include "SynTree/Statement.h"
    3533#include "SynTree/Type.h"
     
    3937        /// Visitor for dumping resolver prototype output
    4038        class ProtoDump : public WithShortCircuiting, public WithVisitorRef<ProtoDump> {
    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
     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
    4743
    4844        public:
    4945                /// Default constructor for root ProtoDump
    50                 ProtoDump() : decls(), exprs(), subs(), closed(), parent(nullptr), rtnType(nullptr) {}
     46                ProtoDump() : decls(), exprs(), subs(), parent(nullptr) {}
    5147
    5248                /// Child constructor
    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;
     49                ProtoDump(const ProtoDump* p) : decls(), exprs(), subs(), parent(p) {}
    7550
    7651        private:
     
    208183                /// Visitor for printing types
    209184                struct TypePrinter : public WithShortCircuiting, WithVisitorRef<TypePrinter>, WithGuards {
    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) {}
     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) {}
    216189
    217190                        // basic type represented as integer type
     
    279252                        void previsit( EnumInstType* ) { ss << (int)BasicType::SignedInt; }
    280253
     254                        // make sure first letter of TypeInstType is capitalized
    281255                        void previsit( TypeInstType* vt ) {
    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 ); }
     256                                ti_name( vt->name, ss );
    286257                        }
    287258
     
    309280                /// builds description of function
    310281                void build( const std::string& name, FunctionType* fnTy, std::stringstream& ss ) {
    311                         PassVisitor<TypePrinter> printTy{ closed, ss };
    312                         // print return values
     282                        PassVisitor<TypePrinter> printTy{ ss };
    313283                        build( printTy, from_decls( fnTy->returnVals ), ss, terminated );
    314                         // print name
    315284                        rp_name( name, ss );
    316                         // print parameters
    317285                        build( printTy, from_decls( fnTy->parameters ), ss, preceded );
    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                         }
     286                        // TODO handle assertions
    325287                }
    326288
     
    342304
    343305                        // print variable declaration as zero-arg function
    344                         PassVisitor<TypePrinter> printTy{ closed, ss };
     306                        PassVisitor<TypePrinter> printTy{ ss };
    345307                        norefs->accept( printTy );
    346308                        ss << ' ';
     
    354316
    355317                        // print access as new field name
    356                         PassVisitor<TypePrinter> printTy{ closed, ss };
     318                        PassVisitor<TypePrinter> printTy{ ss };
    357319                        norefs->accept( printTy );
    358320                        ss << ' ';
     
    375337                struct ExprPrinter : WithShortCircuiting, WithVisitorRef<ExprPrinter> {
    376338                        // TODO change interface to generate multiple expression candidates
    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) {}
     339
     340                        std::stringstream& ss;  ///< Output to print to
     341
     342                        ExprPrinter( std::stringstream& ss ) : ss(ss) {}
    382343
    383344                        /// Names handled as nullary function calls
     
    418379                        /// Address-of handled as operator
    419380                        void previsit( AddressExpr* expr ) {
     381                                // TODO global function to implement this
    420382                                ss << "$addr( ";
    421383                                expr->arg->accept( *visitor );
     
    427389                        /// TODO put cast target functions in, and add second expression for target
    428390                        void previsit( CastExpr* cast ) {
    429                                 PassVisitor<TypePrinter> tyPrinter{ closed, ss };
     391                                PassVisitor<TypePrinter> tyPrinter{ ss };
    430392                                cast->result->accept( tyPrinter );
    431393                                visit_children = false;
     
    454416                        /// Constant expression replaced by its type
    455417                        void previsit( ConstantExpr* expr ) {
    456                                 PassVisitor<TypePrinter> tyPrinter{ closed, ss };
     418                                PassVisitor<TypePrinter> tyPrinter{ ss };
    457419                                expr->constant.get_type()->accept( tyPrinter );
    458420                                visit_children = false;
     
    476438                        /// Logical expressions represented as operators
    477439                        void previsit( LogicalExpr* expr ) {
     440                                // TODO global functions for these
    478441                                ss << '$' << ( expr->get_isAnd() ? "and" : "or" ) << "( ";
    479442                                expr->arg1->accept( *visitor );
     
    486449                        /// Conditional expression represented as operator
    487450                        void previsit( ConditionalExpr* expr ) {
     451                                // TODO global function for this
    488452                                ss << "$if( ";
    489453                                expr->arg1->accept( *visitor );
     
    498462                        /// Comma expression represented as operator
    499463                        void previsit( CommaExpr* expr ) {
     464                                // TODO global function for this
    500465                                ss << "$seq( ";
    501466                                expr->arg1->accept( *visitor );
     
    508473                        // TODO handle ignored ImplicitCopyCtorExpr and below
    509474                };
    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                 }
    543475
    544476                /// Adds all named declarations in a list to the local scope
     
    575507                        build( obj->name, obj->type, ss );
    576508                        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                         }
    584509                }
    585510
     
    592517                        // add body if available
    593518                        if ( decl->statements ) {
    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                                 }
     519                                PassVisitor<ProtoDump> body{ this };
    612520                               
    613521                                // add named parameters and returns to local scope
    614522                                body.pass.addAll( decl->type->returnVals );
    615523                                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
    616528
    617529                                // add contents of function to new scope
     
    642554                }
    643555
    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 
    655556                void previsit( Expression* expr ) {
    656557                        std::stringstream ss;
    657                         PassVisitor<ExprPrinter> exPrinter{ closed, ss };
     558                        PassVisitor<ExprPrinter> exPrinter{ss};
    658559                        expr->accept( exPrinter );
    659560                        addExpr( ss.str() );
     
    661562                }
    662563
    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 
    673564        public:
    674565                /// Prints this ProtoDump instance
    675566                void print(unsigned indent = 0) const {
    676                         // print globals at root level
    677                         if ( ! parent ) printGlobals();
     567                        std::string tab( indent, '\t' );
    678568                        // print decls
    679                         std::string tab( indent, '\t' );
    680569                        for ( const std::string& d : decls ) {
    681570                                std::cout << tab << d << std::endl;
    682571                        }
    683572                        // print divider
    684                         std::cout << '\n' << tab << "%%\n" << std::endl;
     573                        std::cout << tab << "%%" << std::endl;
    685574                        // print top-level expressions
    686575                        for ( const std::string& e : exprs ) {
Note: See TracChangeset for help on using the changeset viewer.