Changeset b87a5ed for translator/ArgTweak
- Timestamp:
- May 16, 2015, 3:36:19 PM (9 years ago)
- Branches:
- ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, ctor, deferred_resn, demangler, enum, forall-pointer-decay, gc_noraii, jacob/cs343-translation, jenkins-sandbox, master, memory, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, string, with_gc
- Children:
- a32b204
- Parents:
- b8508a2
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
translator/ArgTweak/FunctionFixer.cc
rb8508a2 rb87a5ed 1 // 2 // Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo 3 // 4 // The contents of this file are covered under the licence agreement in the 5 // file "LICENCE" distributed with Cforall. 6 // 7 // FunctionFixer.cc -- 8 // 9 // Author : Peter A. Buhr 10 // Created On : Sat May 16 08:12:38 2015 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sat May 16 08:17:07 2015 13 // Update Count : 5 14 // 15 1 16 #include <list> 2 17 #include <vector> … … 10 25 11 26 namespace ArgTweak { 27 FunctionFixer::FunctionFixer( SymTab::Indexer *ind ) : index( ind ) { 28 if ( index == 0 ) index = new SymTab::Indexer(); 29 } 12 30 31 FunctionFixer::~FunctionFixer() { 32 delete index; 33 } 13 34 14 FunctionFixer::FunctionFixer( SymTab::Indexer *ind ) : index( ind ) 15 { 16 if ( index == 0 ) index = new SymTab::Indexer(); 17 } 35 DeclarationWithType *FunctionFixer::mutate( FunctionDecl *functionDecl ) { 36 index->visit( functionDecl ); 37 /* check for duplicate named parameters here? It might not be an error if they're never used, on the other hand, it 38 might be to costly to check for duplicates every time we try a match */ 39 return Parent::mutate( functionDecl ); 40 } 18 41 19 FunctionFixer::~FunctionFixer() 20 { 21 delete index; 22 } 42 Expression *FunctionFixer::mutate( UntypedExpr *untypedExpr ) throw ( SemanticError ) { 43 assert( untypedExpr != 0 ); 44 NameExpr *function; 23 45 24 DeclarationWithType *FunctionFixer::mutate( FunctionDecl *functionDecl ) 25 { 26 index->visit( functionDecl ); 27 /* check for duplicate named parameters here? It might not be an 28 error if they're never used, on the other hand, it might be to 29 costly to check for duplicates every time we try a match */ 30 return Parent::mutate( functionDecl ); 31 } 46 if ( ( function = dynamic_cast< NameExpr *>(untypedExpr->get_function()) ) != 0 ) { 47 std::list < DeclarationWithType * > options; 48 index->lookupId ( function->get_name(), options ); 49 for ( std::list < DeclarationWithType * >::iterator i = options.begin(); i != options.end(); i++ ) { 50 FunctionType *f; 51 if ( ( f = dynamic_cast< FunctionType * > ( (*i)->get_type() ) ) != 0 ) { 52 std::list < DeclarationWithType * > &pars = f->get_parameters(); 32 53 33 Expression *FunctionFixer::mutate( UntypedExpr *untypedExpr ) 34 throw ( SemanticError ) 35 { 36 assert( untypedExpr != 0 ); 37 NameExpr *function; 54 bool candidateExists ; 55 for ( std::list < DeclarationWithType * >::iterator p = pars.begin(); p != pars.end(); p++ ) 56 if ( ( candidateExists = align( f->get_parameters(), untypedExpr->get_args(), Matcher() ) ) ) break; 38 57 39 if ( ( function = dynamic_cast< NameExpr *>(untypedExpr->get_function()) ) != 0 ) 40 { 41 std::list < DeclarationWithType * > options; 42 index->lookupId ( function->get_name(), options ); 43 for ( std::list < DeclarationWithType * >::iterator i = options.begin(); i != options.end(); i++ ) 44 { 45 FunctionType *f; 46 if ( ( f = dynamic_cast< FunctionType * > ( (*i)->get_type() ) ) != 0 ) 47 { 48 std::list < DeclarationWithType * > &pars = f->get_parameters(); 58 if ( !candidateExists ) throw SemanticError("Error in function call"); 59 } // if 60 } // for 61 } // if 62 return untypedExpr; 63 } 49 64 50 bool candidateExists ; 51 for( std::list < DeclarationWithType * >::iterator p = pars.begin(); p != pars.end(); p++ ) 52 if ( ( candidateExists = align( f->get_parameters(), untypedExpr->get_args(), Matcher() ) ) ) break; 65 template < class L1, class L2, class Helper > 66 bool align( L1 &pattern, L2 &possible_permutation, Helper help ) { 67 std::map < typename Helper::key, int > positions; 68 int p = 0; 53 69 54 if ( !candidateExists ) throw SemanticError("Error in function call"); 55 } 56 } 57 } 58 return untypedExpr; 59 } 70 for ( typename L1::iterator i = pattern.begin(); i != pattern.end(); i++, p++ ) 71 if ( help.extract_key( *i ) != Helper::null_key ) 72 positions[ help.extract_key( *i ) ] = p; 60 73 61 template < class L1, class L2, class Helper > 62 bool align( L1 &pattern, L2 &possible_permutation, Helper help ) 63 { 64 std::map < typename Helper::key, int > positions; 65 int p = 0; 74 L2 copy_pp( possible_permutation ); 66 75 67 for ( typename L1::iterator i = pattern.begin(); i != pattern.end(); i++, p++ ) 68 if ( help.extract_key( *i ) != Helper::null_key ) 69 positions[ help.extract_key( *i ) ] = p; 76 std::vector< typename L2::value_type > temp(copy_pp.size(), Helper::null_value ); 77 for ( typename L2::iterator i = copy_pp.begin(); i != copy_pp.end(); i++ ) 78 if ( positions.find( help.extract_key( *i ) ) != positions.end() ) { 79 temp [ positions [ help.extract_key( *i ) ] ] = *i; 80 *i = Helper::null_value; 81 } // if 70 82 71 L2 copy_pp( possible_permutation ); 83 // rest of the arguments 84 int a = 0; 85 bool goAhead = true; // go ahead and change the list 86 for ( typename L2::iterator i = copy_pp.begin(); i != copy_pp.end(); i++, a++ ) { 87 if ( *i != Helper::null_value ) 88 if ( temp[a] == Helper::null_value ) 89 temp[a] = *i; 90 else 91 { goAhead = false; /* there's something there already */; break; } 92 else 93 if ( temp[a] == Helper::null_value ) 94 { goAhead = false; /* can't leave empty spaces */ break; } 95 else 96 ; // all good, this was filled during the first pass 97 assert ( temp[a] != Helper::null_value ); 98 } // for 72 99 73 std::vector< typename L2::value_type > temp(copy_pp.size(), Helper::null_value ); 74 for ( typename L2::iterator i = copy_pp.begin(); i != copy_pp.end(); i++ ) 75 if ( positions.find( help.extract_key( *i ) ) != positions.end() ) { 76 temp [ positions [ help.extract_key( *i ) ] ] = *i; 77 *i = Helper::null_value; 78 } 100 // Change the original list 101 if ( goAhead ) std::copy( temp.begin(), temp.end(), possible_permutation.begin() ); 79 102 80 // rest of the arguments 81 int a = 0; 82 bool goAhead = true; // go ahead and change the list 83 for ( typename L2::iterator i = copy_pp.begin(); i != copy_pp.end(); i++, a++ ) { 84 if ( *i != Helper::null_value ) 85 if ( temp[a] == Helper::null_value ) 86 temp[a] = *i; 87 else 88 { goAhead = false; /* there's something there already */; break; } 89 else 90 if ( temp[a] == Helper::null_value ) 91 { goAhead = false; /* can't leave empty spaces */ break; } 92 else 93 ; // all good, this was filled during the first pass 94 assert ( temp[a] != Helper::null_value ); 95 } 103 return goAhead; 104 } 96 105 97 // Change the original list 98 if ( goAhead ) std::copy( temp.begin(), temp.end(), possible_permutation.begin() );106 std::string FunctionFixer::Matcher::null_key(""); 107 Expression *FunctionFixer::Matcher::null_value = 0; 99 108 100 return goAhead; 101 } 109 std::string FunctionFixer::Matcher::extract_key ( DeclarationWithType *decl ) { 110 return decl->get_name(); 111 } 102 112 103 std::string FunctionFixer::Matcher::null_key(""); 104 Expression *FunctionFixer::Matcher::null_value = 0; 113 std::string FunctionFixer::Matcher::extract_key ( Expression *expression ) { 114 if ( expression->get_argName() == 0 ) 115 return std::string(""); 116 else 117 return *(expression->get_argName()); 118 } 119 } // namespace ArgTweak 105 120 106 std::string FunctionFixer::Matcher::extract_key ( DeclarationWithType *decl ) { 107 return decl->get_name(); 108 } 109 110 std::string FunctionFixer::Matcher::extract_key ( Expression *expression ) { 111 if ( expression->get_argName() == 0 ) 112 return std::string(""); 113 else 114 return *(expression->get_argName()); 115 } 116 117 } // namespace ArgTweak 121 // Local Variables: // 122 // tab-width: 4 // 123 // mode: c++ // 124 // compile-command: "make install" // 125 // End: //
Note: See TracChangeset
for help on using the changeset viewer.