Changes in / [af1e8f56:20a5977]
- Location:
- src
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
src/AST/Decl.cpp
raf1e8f56 r20a5977 72 72 // --- EnumDecl 73 73 74 bool EnumDecl::valueOf( const Decl* enumerator, long long& value ) const {74 bool EnumDecl::valueOf( Decl* enumerator, long long& value ) const { 75 75 if ( enumValues.empty() ) { 76 76 long long crntVal = 0; 77 for ( const Decl 77 for ( const Decl* member : members ) { 78 78 const ObjectDecl* field = strict_dynamic_cast< const ObjectDecl* >( member ); 79 79 if ( field->init ) { -
src/AST/Decl.hpp
raf1e8f56 r20a5977 287 287 288 288 /// 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; 290 290 291 291 const Decl * accept( Visitor & v ) const override { return v.visit( this ); } -
src/AST/Pass.proto.hpp
raf1e8f56 r20a5977 109 109 }; 110 110 111 /// "Short hand" to check if this is a valid previsit function112 /// Mostly used to make the static_assert look (and print) prettier113 111 template<typename pass_t, typename node_t> 114 112 struct is_valid_previsit { … … 119 117 }; 120 118 121 /// Used by previsit implementation122 /// We need to reassign the result to 'node', unless the function123 /// returns void, then we just leave 'node' unchanged124 119 template<bool is_void> 125 120 struct __assign; … … 139 134 node = pass.previsit( node ); 140 135 assertf(node, "Previsit must not return NULL"); 141 }142 };143 144 /// Used by postvisit implementation145 /// We need to return the result unless the function146 /// returns void, then we just return the original node147 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 );164 136 } 165 137 }; … … 202 174 decltype( pass.postvisit( node ), node->accept( *(Visitor*)nullptr ) ) 203 175 { 204 return __return< 205 std::is_void< 206 decltype( pass.postvisit( node ) ) 207 >::value 208 >::result( pass, node ); 176 return pass.postvisit( node ); 209 177 } 210 178 -
src/Common/Eval.cc
raf1e8f56 r20a5977 17 17 18 18 #include "Common/PassVisitor.h" 19 #include "AST/Pass.hpp"20 19 #include "InitTweak/InitTweak.h" 21 20 #include "SynTree/Expression.h" 22 21 23 //------------------------------------------------------------- 24 // Old AST 25 struct EvalOld : public WithShortCircuiting { 22 struct Eval : public WithShortCircuiting { 26 23 long long int value = 0; 27 24 bool valid = true; … … 83 80 }; 84 81 85 //-------------------------------------------------------------86 // New AST87 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 valid103 }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 valueOf109 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 functions144 }145 };146 147 82 std::pair<long long int, bool> eval(Expression * expr) { 148 PassVisitor<Eval Old> ev;83 PassVisitor<Eval> ev; 149 84 if (expr) { 150 85 expr->accept(ev); … … 156 91 157 92 std::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 }; 165 95 } 166 96 -
src/Common/PassVisitor.impl.h
raf1e8f56 r20a5977 23 23 assert( __return ); \ 24 24 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 25 42 26 43 … … 2745 2762 MUTATE_END( TypeSubstitution, node ); 2746 2763 } 2747 2748 #undef VISIT_START2749 #undef VISIT_END2750 2751 #undef MUTATE_START2752 #undef MUTATE_END -
src/InitTweak/InitTweak.cc
raf1e8f56 r20a5977 346 346 namespace { 347 347 DeclarationWithType * getCalledFunction( Expression * expr ); 348 const ast::DeclWithType * getCalledFunction( const ast::Expr * expr );349 348 350 349 template<typename CallExpr> … … 356 355 return getCalledFunction( expr->get_args().front() ); 357 356 } 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 368 357 369 358 DeclarationWithType * getCalledFunction( Expression * expr ) { … … 386 375 return nullptr; 387 376 } 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 }408 377 } 409 378 … … 413 382 } else if ( UntypedExpr * untyped = dynamic_cast< UntypedExpr * > ( expr ) ) { 414 383 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 );424 384 } 425 385 assertf( false, "getFunction received unknown expression: %s", toString( expr ).c_str() ); … … 474 434 } 475 435 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 // } 488 448 } 489 449 … … 506 466 } 507 467 } 508 509 468 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 // } 527 490 } 528 491 529 492 namespace { 530 493 std::string funcName( Expression * func ); 531 std::string funcName( const ast::Expr * func );532 494 533 495 template<typename CallExpr> … … 538 500 assertf( ! expr->get_args().empty(), "Cannot get function name from dereference with no arguments" ); 539 501 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() );549 502 } 550 503 … … 570 523 } 571 524 } 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 }594 525 } 595 526 … … 608 539 } 609 540 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 and612 // return the name of the DeclarationWithType, but this needs to work for NameExpr and UntypedMemberExpr, where getCalledFunction613 // 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 624 541 Type * getPointerBase( Type * type ) { 625 542 if ( PointerType * ptrType = dynamic_cast< PointerType * >( type ) ) { … … 634 551 } 635 552 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; 643 563 } 644 564 -
src/InitTweak/InitTweak.h
raf1e8f56 r20a5977 58 58 /// returns the declaration of the function called by the expr (must be ApplicationExpr or UntypedExpr) 59 59 DeclarationWithType * getFunction( Expression * expr ); 60 const ast::DeclWithType * getFunction( const ast::Expr * expr );61 60 62 61 /// Non-Null if expr is a call expression whose target function is intrinsic … … 79 78 /// returns the name of the function being called 80 79 std::string getFunctionName( Expression * expr ); 81 std::string getFunctionName( const ast::Expr * expr );82 80 83 81 /// returns the argument to a call expression in position N indexed from 0
Note: See TracChangeset
for help on using the changeset viewer.