source: dev/trunk/abdev/BasicCompiler_Common/ParamImpl.cpp@ 182

Last change on this file since 182 was 182, checked in by dai_9181, 17 years ago
File size: 8.2 KB
Line 
1#include <Program.h>
2
3#include "common.h"
4
5#ifdef _AMD64_
6#include "../BasicCompiler64/opcode.h"
7#else
8#include "../BasicCompiler32/opcode.h"
9#endif
10
11#define OVERLOAD_MIN_LEVEL 0
12#define OVERLOAD_MAX_LEVEL 6
13#define OVERLOAD_LEVEL0 0 // 型調整なし。厳密に等しい
14#define OVERLOAD_LEVEL1 1 // 型調整なし。レベル1以上はオブジェクトの場合は派生関係を考慮
15#define OVERLOAD_LEVEL2 2 // 型調整なし。整数型/実数型レベルでの同一性チェック(サイズ照合あり)
16#define OVERLOAD_LEVEL3 3 // 型調整なし。整数型/実数型レベルでの同一性チェック
17#define OVERLOAD_LEVEL4 4 // 型調整あり。厳密に等しい
18#define OVERLOAD_LEVEL5 5 // 型調整あり。整数型/実数型レベルでの同一性チェック
19#define OVERLOAD_LEVEL6 6 // 型調整あり。数値型/クラス型レベルでの同一性チェック
20
21ParamImpl::ParamImpl(const char *buffer):
22 returnType()
23{
24 ///////////////////////////
25 // パラメータ文字列を整理
26 ///////////////////////////
27
28 extern HANDLE hHeap;
29 int i,i2,i3;
30 char temporary[VN_SIZE];
31
32 i=0;
33 ParmsNum=0;
34 while(1){
35 if(buffer[i]=='\0') break;
36
37 for(i2=0;;i2++,i++){
38 if(buffer[i]=='\"'){
39 temporary[i2]=buffer[i];
40 for(i++,i2++;;i++,i2++){
41 temporary[i2]=buffer[i];
42 if(buffer[i]=='\"') break;
43 }
44 continue;
45 }
46
47 if(buffer[i]=='('){
48 i3=GetStringInPare(temporary+i2,buffer+i);
49 i2+=i3-1;
50 i+=i3-1;
51 continue;
52 }
53 if(buffer[i]=='['){
54 i3=GetStringInBracket(temporary+i2,buffer+i);
55 i2+=i3-1;
56 i+=i3-1;
57 continue;
58 }
59
60 if(buffer[i]==','||buffer[i]=='\0'){
61 temporary[i2]=0;
62 break;
63 }
64 temporary[i2]=buffer[i];
65 }
66
67 Parms[ParmsNum]=(char *)HeapAlloc(hHeap,0,lstrlen(temporary)+1);
68 lstrcpy(Parms[ParmsNum],temporary);
69 ParmsNum++;
70
71 types.push_back( Type() );
72
73 if(buffer[i]==',') i++;
74 }
75}
76ParamImpl::ParamImpl(const Parameters &params):
77 returnType()
78{
79 ParmsNum = 0;
80 BOOST_FOREACH( Parameter *pParam, params ){
81 Parms[ParmsNum]=0;
82 ParmsNum++;
83
84 types.push_back( *pParam );
85 }
86}
87ParamImpl::~ParamImpl(){
88 int i2;
89
90 //パラメータ文字列を解放
91 for(i2=0;i2<ParmsNum;i2++){
92 if(Parms[i2]==(char *)-1) continue;
93
94 if(Parms[i2]) HeapDefaultFree(Parms[i2]);
95 }
96}
97
98void ParamImpl::SetReturnType( const Type &returnType ){
99 this->returnType = returnType;
100}
101
102bool ParamImpl::EvaluateOverloadScore( int level, const Parameters &targetParms, const Type &targetResultType ){
103 //パラメータを識別してオーバーロードを解決
104
105 //パラメータの個数が不一致の場合
106 int max = (int)targetParms.size();
107
108 if( ParmsNum > max ){
109 // 実引数が駆り引数より多いとき
110 // ※無条件で不一致
111 return false;
112 }
113
114 Type argType;
115 for(int i=0;i<max;i++){
116 Parameter &param = *targetParms[i];
117
118 if( i >= ParmsNum ){
119 // 引数が多いとき
120 if( param.GetInitValue().size() > 0 ){
121 // 初期値が指定されているパラメータを考慮
122 return true;
123 }
124 else{
125 return false;
126 }
127 }
128
129 if(Parms[i]){
130 Type nullParam( DEF_NON );
131
132 NumOpe_GetType(Parms[i],
133 ( level <= OVERLOAD_LEVEL3 )? nullParam : param,
134 argType);
135 }
136 else{
137 argType = types[i];
138 }
139
140 if(argType.GetBasicType()!=param.GetBasicType()){
141 if( level == OVERLOAD_LEVEL0 || level == OVERLOAD_LEVEL1 || level==OVERLOAD_LEVEL4 ){
142 return false;
143 }
144 else if( level == OVERLOAD_LEVEL2 ){
145 if( !(argType.IsWhole() && param.IsWhole() && argType.GetBasicSize() == param.GetBasicSize() ) ){
146 // サイズ違い
147 return false;
148 }
149 }
150 else if( level == OVERLOAD_LEVEL3 || level==OVERLOAD_LEVEL5){
151 if(!(
152 argType.IsWhole()&&param.IsWhole()||
153 argType.IsReal()&&param.IsReal()
154 )){
155 return false;
156 }
157 if( argType.IsPointer() || param.IsPointer() )
158 {
159 // ポインタ型の不整合は認めない
160 return false;
161 }
162 }
163 else if(level==OVERLOAD_LEVEL6){
164 if(argType.IsObject()||param.IsObject()) return false;
165 }
166 }
167 else{
168 //if(NATURAL_TYPE(argType.GetBasicType())==DEF_OBJECT || NATURAL_TYPE(argType.GetBasicType())==DEF_STRUCT){
169 if( NATURAL_TYPE(argType.GetBasicType())==DEF_STRUCT){
170 if(argType.GetIndex()!=param.GetIndex()){
171 return false;
172 }
173 }
174 else if( NATURAL_TYPE(argType.GetBasicType())==DEF_OBJECT ){
175 if( level == OVERLOAD_LEVEL0 ){
176 if( !param.GetClass().IsEquals( &argType.GetClass() ) ){
177 return false;
178 }
179 }
180 else{
181 if( !param.GetClass().IsEqualsOrSubClass( &argType.GetClass() ) ){
182 return false;
183 }
184 }
185 }
186 }
187 }
188
189 if( !targetResultType.IsNull() ){
190 //戻り値も比較対象にする
191 if( !returnType.Equals( targetResultType ) ){
192 return false;
193 }
194 }
195
196 return true;
197}
198
199UserProc *ParamImpl::_OverloadSolution( const char *name, std::vector<UserProc *> &subs, bool isEnabledReturnType ){
200 int sw=0;
201 UserProc *pUserProc;
202 pUserProc=0;
203
204 for( int level=OVERLOAD_MIN_LEVEL; level<=OVERLOAD_MAX_LEVEL; level++ ){
205
206 BOOST_FOREACH( UserProc *pTempUserProc, subs ){
207
208 if(EvaluateOverloadScore( level, pTempUserProc->Params(), isEnabledReturnType?pTempUserProc->ReturnType():Type() )){
209 trace_for_overload( "レベル" << level << " ○適合..." << pTempUserProc->_paramStr );
210
211 if(sw){
212 if( isEnabledReturnType ){
213 SetError(52,name,cp);
214
215 return 0;
216 }
217 else{
218 // 戻り値も比較するモードにして再びオーバーロード解決を試みる
219
220 trace_for_overload( "戻り値も比較するモードに切り替えてオーバーロード解決を試みる" );
221
222 return OverloadSolution(name,subs, true);
223 }
224 }
225 sw=1;
226
227 pUserProc = pTempUserProc;
228 }
229 else
230 {
231 trace_for_overload( "レベル" << level << " ×不適合..." << pTempUserProc->_paramStr );
232 }
233 }
234
235 if( sw ) break;
236 }
237
238 if(!sw){
239 BOOST_FOREACH( UserProc *pTempUserProc, subs ){
240
241 //エラーチェック
242 if(pTempUserProc->Params().size()==this->ParmsNum){
243 if(sw){
244 sw=0;
245 break;
246 }
247 sw=1;
248
249 pUserProc=pTempUserProc;
250 }
251 }
252 }
253
254 if(!sw){
255 SetError(52,name,cp);
256
257 return 0;
258 }
259
260
261 return pUserProc;
262}
263UserProc *ParamImpl::OverloadSolution( const char *name, std::vector<UserProc *> &subs, bool isEnabledReturnType ){
264 trace_for_overload( "" );
265 trace_for_overload( "■■■■■■■■■■■■■■■■■■" );
266 trace_for_overload( "■■■ オーバーロード解決(" << name << ")" );
267
268 UserProc *result = _OverloadSolution( name, subs, isEnabledReturnType );
269
270 trace_for_overload( "■■■ ここまで" );
271 trace_for_overload( "■■■■■■■■■■■■■■■■■■" );
272 trace_for_overload( "" );
273
274 return result;
275}
276
277void ParamImpl::ApplyDefaultParameters( const Parameters &params ){
278 if( ParmsNum == (int)params.size() ){
279 // デフォルト引数の適用が不必要なとき
280 return;
281 }
282
283 while( ParmsNum < (int)params.size() ){
284 Parameter &param = *params[ParmsNum];
285
286 Parms[ParmsNum]=(char *)HeapAlloc(hHeap,0,param.GetInitValue().size() + 1 );
287 lstrcpy(Parms[ParmsNum],param.GetInitValue().c_str() );
288 ParmsNum++;
289 }
290}
291
292bool ParamImpl::ErrorCheck( const string &procName, const Parameters &params, int SecondParmNum ){
293 if( SecondParmNum == -1 ) SecondParmNum = (int)params.size();
294
295 if(ParmsNum>(int)params.size() && params.size() != 0){
296 if(params[params.size()-1]->GetBasicType()!=DEF_ELLIPSE){
297 //パラメータが多すぎるとき
298 SetError(10,procName,cp);
299 return false;
300 }
301 }
302 else if(ParmsNum<(int)params.size()){
303 if(ParmsNum<SecondParmNum){
304 if(params[ParmsNum]->GetBasicType()==DEF_ELLIPSE){
305 return true;
306 }
307
308 //パラメータが少なすぎるとき
309 SetError(10,procName,cp);
310 return false;
311 }
312
313 //省略パラメータに "0" を指定する
314 for(;ParmsNum < (int)params.size();ParmsNum++){
315 extern HANDLE hHeap;
316 char temporary[64];
317 if(params[ParmsNum]->IsRef() == false) lstrcpy(temporary,"0");
318 else sprintf(temporary,"%c%c0",1,ESC_BYVAL);
319 Parms[ParmsNum]=(char *)HeapAlloc(hHeap,0,lstrlen(temporary)+1);
320 lstrcpy(Parms[ParmsNum],temporary);
321 }
322 }
323
324 return true;
325}
326
327void ParamImpl::MacroParameterSupport( const Parameters &params ){
328 for(int i=0;i<ParmsNum;i++){
329 if(Parms[i][0]=='\0'){
330 extern HANDLE hHeap;
331 char temporary[64];
332 if( params[i]->IsRef() == false ) lstrcpy(temporary,"0");
333 else sprintf(temporary,"%c%c0",1,ESC_BYVAL);
334 HeapDefaultFree(Parms[i]);
335 Parms[i]=(char *)HeapAlloc(hHeap,0,lstrlen(temporary)+1);
336 lstrcpy(Parms[i],temporary);
337 }
338 }
339}
Note: See TracBrowser for help on using the repository browser.