- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/CodeTools/ResolvProtoDump.cc
r40cd873 ra4a000d 27 27 28 28 #include "Common/PassVisitor.h" 29 #include "Common/utility.h" 29 30 #include "CodeGen/OperatorTable.h" 30 31 #include "SynTree/Declaration.h" 31 32 #include "SynTree/Expression.h" 33 #include "SynTree/Initializer.h" 32 34 #include "SynTree/Statement.h" 33 35 #include "SynTree/Type.h" … … 37 39 /// Visitor for dumping resolver prototype output 38 40 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 43 47 44 48 public: 45 49 /// Default constructor for root ProtoDump 46 ProtoDump() : decls(), exprs(), subs(), parent(nullptr) {}50 ProtoDump() : decls(), exprs(), subs(), closed(), parent(nullptr), rtnType(nullptr) {} 47 51 48 52 /// 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; 50 75 51 76 private: … … 183 208 /// Visitor for printing types 184 209 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) {} 189 216 190 217 // basic type represented as integer type … … 252 279 void previsit( EnumInstType* ) { ss << (int)BasicType::SignedInt; } 253 280 254 // make sure first letter of TypeInstType is capitalized255 281 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 ); } 257 286 } 258 287 … … 280 309 /// builds description of function 281 310 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 283 313 build( printTy, from_decls( fnTy->returnVals ), ss, terminated ); 314 // print name 284 315 rp_name( name, ss ); 316 // print parameters 285 317 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 } 287 325 } 288 326 … … 304 342 305 343 // print variable declaration as zero-arg function 306 PassVisitor<TypePrinter> printTy{ ss };344 PassVisitor<TypePrinter> printTy{ closed, ss }; 307 345 norefs->accept( printTy ); 308 346 ss << ' '; … … 316 354 317 355 // print access as new field name 318 PassVisitor<TypePrinter> printTy{ ss };356 PassVisitor<TypePrinter> printTy{ closed, ss }; 319 357 norefs->accept( printTy ); 320 358 ss << ' '; … … 337 375 struct ExprPrinter : WithShortCircuiting, WithVisitorRef<ExprPrinter> { 338 376 // 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) {} 343 382 344 383 /// Names handled as nullary function calls … … 379 418 /// Address-of handled as operator 380 419 void previsit( AddressExpr* expr ) { 381 // TODO global function to implement this382 420 ss << "$addr( "; 383 421 expr->arg->accept( *visitor ); … … 389 427 /// TODO put cast target functions in, and add second expression for target 390 428 void previsit( CastExpr* cast ) { 391 PassVisitor<TypePrinter> tyPrinter{ ss };429 PassVisitor<TypePrinter> tyPrinter{ closed, ss }; 392 430 cast->result->accept( tyPrinter ); 393 431 visit_children = false; … … 416 454 /// Constant expression replaced by its type 417 455 void previsit( ConstantExpr* expr ) { 418 PassVisitor<TypePrinter> tyPrinter{ ss };456 PassVisitor<TypePrinter> tyPrinter{ closed, ss }; 419 457 expr->constant.get_type()->accept( tyPrinter ); 420 458 visit_children = false; … … 438 476 /// Logical expressions represented as operators 439 477 void previsit( LogicalExpr* expr ) { 440 // TODO global functions for these441 478 ss << '$' << ( expr->get_isAnd() ? "and" : "or" ) << "( "; 442 479 expr->arg1->accept( *visitor ); … … 449 486 /// Conditional expression represented as operator 450 487 void previsit( ConditionalExpr* expr ) { 451 // TODO global function for this452 488 ss << "$if( "; 453 489 expr->arg1->accept( *visitor ); … … 462 498 /// Comma expression represented as operator 463 499 void previsit( CommaExpr* expr ) { 464 // TODO global function for this465 500 ss << "$seq( "; 466 501 expr->arg1->accept( *visitor ); … … 473 508 // TODO handle ignored ImplicitCopyCtorExpr and below 474 509 }; 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 } 475 543 476 544 /// Adds all named declarations in a list to the local scope … … 507 575 build( obj->name, obj->type, ss ); 508 576 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 } 509 584 } 510 585 … … 517 592 // add body if available 518 593 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 } 520 612 521 613 // add named parameters and returns to local scope 522 614 body.pass.addAll( decl->type->returnVals ); 523 615 body.pass.addAll( decl->type->parameters ); 524 525 // TODO add assertions to local scope526 527 // TODO add set of "closed" types to body so that it can print them as NamedType528 616 529 617 // add contents of function to new scope … … 554 642 } 555 643 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 556 655 void previsit( Expression* expr ) { 557 656 std::stringstream ss; 558 PassVisitor<ExprPrinter> exPrinter{ ss};657 PassVisitor<ExprPrinter> exPrinter{ closed, ss }; 559 658 expr->accept( exPrinter ); 560 659 addExpr( ss.str() ); … … 562 661 } 563 662 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 564 673 public: 565 674 /// Prints this ProtoDump instance 566 675 void print(unsigned indent = 0) const { 676 // print globals at root level 677 if ( ! parent ) printGlobals(); 678 // print decls 567 679 std::string tab( indent, '\t' ); 568 // print decls569 680 for ( const std::string& d : decls ) { 570 681 std::cout << tab << d << std::endl; 571 682 } 572 683 // print divider 573 std::cout << tab << "%%" << std::endl;684 std::cout << '\n' << tab << "%%\n" << std::endl; 574 685 // print top-level expressions 575 686 for ( const std::string& e : exprs ) {
Note: See TracChangeset
for help on using the changeset viewer.