source: translator/ArgTweak/FunctionFixer.cc @ 51b7345

ADTaaron-thesisarm-ehast-experimentalcleanup-dtorsctordeferred_resndemanglerenumforall-pointer-decaygc_noraiijacob/cs343-translationjenkins-sandboxmemorynew-astnew-ast-unique-exprnew-envno_listpersistent-indexerpthread-emulationqualifiedEnumresolv-newstringwith_gc
Last change on this file since 51b7345 was 51b7345, checked in by Peter A. Buhr <pabuhr@…>, 9 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.