1 | #include "Resolver.h" |
---|
2 | #include "AlternativeFinder.h" |
---|
3 | #include "Alternative.h" |
---|
4 | #include "RenameVars.h" |
---|
5 | #include "ResolveTypeof.h" |
---|
6 | #include "SynTree/Statement.h" |
---|
7 | #include "SynTree/Type.h" |
---|
8 | #include "SynTree/Expression.h" |
---|
9 | #include "SynTree/Initializer.h" |
---|
10 | #include "SymTab/Indexer.h" |
---|
11 | #include "utility.h" |
---|
12 | |
---|
13 | #include <iostream> |
---|
14 | using namespace std; |
---|
15 | |
---|
16 | namespace ResolvExpr { |
---|
17 | class Resolver : public SymTab::Indexer { |
---|
18 | public: |
---|
19 | Resolver() : SymTab::Indexer( false ), switchType( 0 ) {} |
---|
20 | |
---|
21 | virtual void visit( FunctionDecl *functionDecl ); |
---|
22 | virtual void visit( ObjectDecl *functionDecl ); |
---|
23 | virtual void visit( TypeDecl *typeDecl ); |
---|
24 | |
---|
25 | virtual void visit( ExprStmt *exprStmt ); |
---|
26 | virtual void visit( IfStmt *ifStmt ); |
---|
27 | virtual void visit( WhileStmt *whileStmt ); |
---|
28 | virtual void visit( ForStmt *forStmt ); |
---|
29 | virtual void visit( SwitchStmt *switchStmt ); |
---|
30 | virtual void visit( ChooseStmt *switchStmt ); |
---|
31 | virtual void visit( CaseStmt *caseStmt ); |
---|
32 | virtual void visit( ReturnStmt *returnStmt ); |
---|
33 | |
---|
34 | virtual void visit( SingleInit *singleInit ); |
---|
35 | virtual void visit( ListInit *listInit ); |
---|
36 | private: |
---|
37 | std::list< Type * > functionReturn; |
---|
38 | Type *initContext; |
---|
39 | Type *switchType; |
---|
40 | }; |
---|
41 | |
---|
42 | void resolve( std::list< Declaration * > translationUnit ) { |
---|
43 | Resolver resolver; |
---|
44 | acceptAll( translationUnit, resolver ); |
---|
45 | #if 0 |
---|
46 | for ( std::list< Declaration * >::iterator i = translationUnit.begin(); i != translationUnit.end(); ++i ) { |
---|
47 | (*i)->print( std::cerr ); |
---|
48 | (*i)->accept( resolver ); |
---|
49 | } // for |
---|
50 | #endif |
---|
51 | } |
---|
52 | |
---|
53 | Expression *resolveInVoidContext( Expression *expr, const SymTab::Indexer &indexer ) { |
---|
54 | TypeEnvironment env; |
---|
55 | return resolveInVoidContext( expr, indexer, env ); |
---|
56 | } |
---|
57 | |
---|
58 | namespace { |
---|
59 | void finishExpr( Expression *expr, const TypeEnvironment &env ) { |
---|
60 | expr->set_env( new TypeSubstitution ); |
---|
61 | env.makeSubstitution( *expr->get_env() ); |
---|
62 | } |
---|
63 | |
---|
64 | Expression *findVoidExpression( Expression *untyped, const SymTab::Indexer &indexer ) { |
---|
65 | global_renamer.reset(); |
---|
66 | TypeEnvironment env; |
---|
67 | Expression *newExpr = resolveInVoidContext( untyped, indexer, env ); |
---|
68 | finishExpr( newExpr, env ); |
---|
69 | return newExpr; |
---|
70 | } |
---|
71 | |
---|
72 | Expression *findSingleExpression( Expression *untyped, const SymTab::Indexer &indexer ) { |
---|
73 | TypeEnvironment env; |
---|
74 | AlternativeFinder finder( indexer, env ); |
---|
75 | finder.find( untyped ); |
---|
76 | #if 0 |
---|
77 | if ( finder.get_alternatives().size() != 1 ) { |
---|
78 | std::cout << "untyped expr is "; |
---|
79 | untyped->print( std::cout ); |
---|
80 | std::cout << std::endl << "alternatives are:"; |
---|
81 | for ( std::list< Alternative >::const_iterator i = finder.get_alternatives().begin(); i != finder.get_alternatives().end(); ++i ) { |
---|
82 | i->print( std::cout ); |
---|
83 | } // for |
---|
84 | } // if |
---|
85 | #endif |
---|
86 | assert( finder.get_alternatives().size() == 1 ); |
---|
87 | Alternative &choice = finder.get_alternatives().front(); |
---|
88 | Expression *newExpr = choice.expr->clone(); |
---|
89 | finishExpr( newExpr, choice.env ); |
---|
90 | return newExpr; |
---|
91 | } |
---|
92 | |
---|
93 | bool isIntegralType( Type *type ) { |
---|
94 | if ( dynamic_cast< EnumInstType * >( type ) ) { |
---|
95 | return true; |
---|
96 | } else if ( BasicType *bt = dynamic_cast< BasicType * >( type ) ) { |
---|
97 | return bt->isInteger(); |
---|
98 | } else { |
---|
99 | return true; |
---|
100 | } // if |
---|
101 | } |
---|
102 | |
---|
103 | Expression *findIntegralExpression( Expression *untyped, const SymTab::Indexer &indexer ) { |
---|
104 | TypeEnvironment env; |
---|
105 | AlternativeFinder finder( indexer, env ); |
---|
106 | finder.find( untyped ); |
---|
107 | #if 0 |
---|
108 | if ( finder.get_alternatives().size() != 1 ) { |
---|
109 | std::cout << "untyped expr is "; |
---|
110 | untyped->print( std::cout ); |
---|
111 | std::cout << std::endl << "alternatives are:"; |
---|
112 | for ( std::list< Alternative >::const_iterator i = finder.get_alternatives().begin(); i != finder.get_alternatives().end(); ++i ) { |
---|
113 | i->print( std::cout ); |
---|
114 | } // for |
---|
115 | } // if |
---|
116 | #endif |
---|
117 | Expression *newExpr = 0; |
---|
118 | const TypeEnvironment *newEnv = 0; |
---|
119 | for ( AltList::const_iterator i = finder.get_alternatives().begin(); i != finder.get_alternatives().end(); ++i ) { |
---|
120 | if ( i->expr->get_results().size() == 1 && isIntegralType( i->expr->get_results().front() ) ) { |
---|
121 | if ( newExpr ) { |
---|
122 | throw SemanticError( "Too many interpretations for switch control expression", untyped ); |
---|
123 | } else { |
---|
124 | newExpr = i->expr->clone(); |
---|
125 | newEnv = &i->env; |
---|
126 | } // if |
---|
127 | } // if |
---|
128 | } // for |
---|
129 | if ( !newExpr ) { |
---|
130 | throw SemanticError( "Too many interpretations for switch control expression", untyped ); |
---|
131 | } // if |
---|
132 | finishExpr( newExpr, *newEnv ); |
---|
133 | return newExpr; |
---|
134 | } |
---|
135 | |
---|
136 | } |
---|
137 | |
---|
138 | void Resolver::visit( ObjectDecl *objectDecl ) { |
---|
139 | Type *new_type = resolveTypeof( objectDecl->get_type(), *this ); |
---|
140 | objectDecl->set_type( new_type ); |
---|
141 | initContext = new_type; |
---|
142 | SymTab::Indexer::visit( objectDecl ); |
---|
143 | } |
---|
144 | |
---|
145 | void Resolver::visit( TypeDecl *typeDecl ) { |
---|
146 | if ( typeDecl->get_base() ) { |
---|
147 | Type *new_type = resolveTypeof( typeDecl->get_base(), *this ); |
---|
148 | typeDecl->set_base( new_type ); |
---|
149 | } // if |
---|
150 | SymTab::Indexer::visit( typeDecl ); |
---|
151 | } |
---|
152 | |
---|
153 | void Resolver::visit( FunctionDecl *functionDecl ) { |
---|
154 | #if 0 |
---|
155 | std::cout << "resolver visiting functiondecl "; |
---|
156 | functionDecl->print( std::cout ); |
---|
157 | std::cout << std::endl; |
---|
158 | #endif |
---|
159 | Type *new_type = resolveTypeof( functionDecl->get_type(), *this ); |
---|
160 | functionDecl->set_type( new_type ); |
---|
161 | std::list< Type * > oldFunctionReturn = functionReturn; |
---|
162 | functionReturn.clear(); |
---|
163 | for ( std::list< DeclarationWithType * >::const_iterator i = functionDecl->get_functionType()->get_returnVals().begin(); i != functionDecl->get_functionType()->get_returnVals().end(); ++i ) { |
---|
164 | functionReturn.push_back( (*i)->get_type() ); |
---|
165 | } // for |
---|
166 | SymTab::Indexer::visit( functionDecl ); |
---|
167 | functionReturn = oldFunctionReturn; |
---|
168 | } |
---|
169 | |
---|
170 | void Resolver::visit( ExprStmt *exprStmt ) { |
---|
171 | if ( exprStmt->get_expr() ) { |
---|
172 | Expression *newExpr = findVoidExpression( exprStmt->get_expr(), *this ); |
---|
173 | delete exprStmt->get_expr(); |
---|
174 | exprStmt->set_expr( newExpr ); |
---|
175 | } // if |
---|
176 | } |
---|
177 | |
---|
178 | void Resolver::visit( IfStmt *ifStmt ) { |
---|
179 | Expression *newExpr = findSingleExpression( ifStmt->get_condition(), *this ); |
---|
180 | delete ifStmt->get_condition(); |
---|
181 | ifStmt->set_condition( newExpr ); |
---|
182 | Visitor::visit( ifStmt ); |
---|
183 | } |
---|
184 | |
---|
185 | void Resolver::visit( WhileStmt *whileStmt ) { |
---|
186 | Expression *newExpr = findSingleExpression( whileStmt->get_condition(), *this ); |
---|
187 | delete whileStmt->get_condition(); |
---|
188 | whileStmt->set_condition( newExpr ); |
---|
189 | Visitor::visit( whileStmt ); |
---|
190 | } |
---|
191 | |
---|
192 | void Resolver::visit( ForStmt *forStmt ) { |
---|
193 | Expression *newExpr; |
---|
194 | if ( forStmt->get_condition() ) { |
---|
195 | newExpr = findSingleExpression( forStmt->get_condition(), *this ); |
---|
196 | delete forStmt->get_condition(); |
---|
197 | forStmt->set_condition( newExpr ); |
---|
198 | } // if |
---|
199 | |
---|
200 | if ( forStmt->get_increment() ) { |
---|
201 | newExpr = findVoidExpression( forStmt->get_increment(), *this ); |
---|
202 | delete forStmt->get_increment(); |
---|
203 | forStmt->set_increment( newExpr ); |
---|
204 | } // if |
---|
205 | |
---|
206 | Visitor::visit( forStmt ); |
---|
207 | } |
---|
208 | |
---|
209 | template< typename SwitchClass > |
---|
210 | void handleSwitchStmt( SwitchClass *switchStmt, SymTab::Indexer &visitor ) { |
---|
211 | Expression *newExpr; |
---|
212 | newExpr = findIntegralExpression( switchStmt->get_condition(), visitor ); |
---|
213 | delete switchStmt->get_condition(); |
---|
214 | switchStmt->set_condition( newExpr ); |
---|
215 | |
---|
216 | visitor.Visitor::visit( switchStmt ); |
---|
217 | } |
---|
218 | |
---|
219 | void Resolver::visit( SwitchStmt *switchStmt ) { |
---|
220 | handleSwitchStmt( switchStmt, *this ); |
---|
221 | } |
---|
222 | |
---|
223 | void Resolver::visit( ChooseStmt *switchStmt ) { |
---|
224 | handleSwitchStmt( switchStmt, *this ); |
---|
225 | } |
---|
226 | |
---|
227 | void Resolver::visit( CaseStmt *caseStmt ) { |
---|
228 | Visitor::visit( caseStmt ); |
---|
229 | } |
---|
230 | |
---|
231 | void Resolver::visit( ReturnStmt *returnStmt ) { |
---|
232 | if ( returnStmt->get_expr() ) { |
---|
233 | CastExpr *castExpr = new CastExpr( returnStmt->get_expr() ); |
---|
234 | cloneAll( functionReturn, castExpr->get_results() ); |
---|
235 | Expression *newExpr = findSingleExpression( castExpr, *this ); |
---|
236 | delete castExpr; |
---|
237 | returnStmt->set_expr( newExpr ); |
---|
238 | } // if |
---|
239 | } |
---|
240 | |
---|
241 | void Resolver::visit( SingleInit *singleInit ) { |
---|
242 | if ( singleInit->get_value() ) { |
---|
243 | CastExpr *castExpr = new CastExpr( singleInit->get_value(), initContext->clone() ); |
---|
244 | Expression *newExpr = findSingleExpression( castExpr, *this ); |
---|
245 | delete castExpr; |
---|
246 | singleInit->set_value( newExpr ); |
---|
247 | } // if |
---|
248 | singleInit->get_value()->accept( *this ); |
---|
249 | } |
---|
250 | |
---|
251 | void Resolver::visit( ListInit *listInit ) { |
---|
252 | // no cast necessary |
---|
253 | } |
---|
254 | } // namespace ResolvExpr |
---|