source: dev/trunk/ab5.0/abdev/BasicCompiler_Common/ParamImpl.cpp@ 612

Last change on this file since 612 was 527, checked in by dai_9181, 17 years ago

ヘッダファイルを整理中

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