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

Last change on this file since 225 was 206, checked in by dai_9181, 17 years ago

コード全体のリファクタリングを実施

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