source: translator/ArgTweak/FunctionFixer.cc@ 643a2e1

ADT aaron-thesis arm-eh ast-experimental cleanup-dtors ctor deferred_resn demangler enum forall-pointer-decay gc_noraii jacob/cs343-translation jenkins-sandbox memory new-ast new-ast-unique-expr new-env no_list persistent-indexer pthread-emulation qualifiedEnum resolv-new string with_gc
Last change on this file since 643a2e1 was 51b73452, checked in by Peter A. Buhr <pabuhr@…>, 11 years ago

initial commit

  • Property mode set to 100644
File size: 3.6 KB
Line 
1#include <list>
2#include <vector>
3#include <cassert>
4#include <algorithm>
5
6#include "FunctionFixer.h"
7#include "SynTree/Expression.h"
8#include "SynTree/Declaration.h"
9#include "SynTree/Type.h"
10
11namespace ArgTweak {
12
13
14 FunctionFixer::FunctionFixer( SymTab::Indexer *ind ) : index( ind )
15 {
16 if ( index == 0 ) index = new SymTab::Indexer();
17 }
18
19 FunctionFixer::~FunctionFixer()
20 {
21 delete index;
22 }
23
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 }
32
33 Expression *FunctionFixer::mutate( UntypedExpr *untypedExpr )
34 throw ( SemanticError )
35 {
36 assert( untypedExpr != 0 );
37 NameExpr *function;
38
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();
49
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;
53
54 if ( !candidateExists ) throw SemanticError("Error in function call");
55 }
56 }
57 }
58 return untypedExpr;
59 }
60
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;
66
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;
70
71 L2 copy_pp( possible_permutation );
72
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 }
79
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 }
96
97 // Change the original list
98 if ( goAhead ) std::copy( temp.begin(), temp.end(), possible_permutation.begin() );
99
100 return goAhead;
101 }
102
103 std::string FunctionFixer::Matcher::null_key("");
104 Expression *FunctionFixer::Matcher::null_value = 0;
105
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
Note: See TracBrowser for help on using the repository browser.