source: dev/BasicCompiler_Common/ParamImpl.cpp@ 111

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

ObjPtr(This)がエラーになるバグを修正。
オーバーロードのチェックレベルを一つ増やした(整数型のサイズ照合によるオーバーロードチェックを可能にした)。

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