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
Line 
1#include "common.h"
2
3#ifdef _AMD64_
4#include "../BasicCompiler64/opcode.h"
5#else
6#include "../BasicCompiler32/opcode.h"
7#endif
8
9#define OVERLOAD_MIN_LEVEL 0
10#define OVERLOAD_MAX_LEVEL 6
11#define OVERLOAD_LEVEL0 0 // 型調整なし。厳密に等しい
12#define OVERLOAD_LEVEL1 1 // 型調整なし。レベル1以上はオブジェクトの場合は派生関係を考慮
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 // 型調整あり。数値型/クラス型レベルでの同一性チェック
18
19ParamImpl::ParamImpl(const char *buffer):
20 returnType()
21{
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
69 types.push_back( Type() );
70
71 if(buffer[i]==',') i++;
72 }
73}
74ParamImpl::ParamImpl(const Parameters &params):
75 returnType()
76{
77 ParmsNum = 0;
78 foreach( Parameter *pParam, params ){
79 Parms[ParmsNum]=0;
80 ParmsNum++;
81
82 types.push_back( *pParam );
83 }
84}
85ParamImpl::~ParamImpl(){
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
96void ParamImpl::SetReturnType( const Type &returnType ){
97 this->returnType = returnType;
98}
99
100bool ParamImpl::_overload_check( int level, const Parameters &targetParms, const Type &targetResultType ){
101 //パラメータを識別してオーバーロードを解決
102
103 //パラメータの個数が不一致の場合
104 int max = (int)targetParms.size();
105
106 if( ParmsNum > max ){
107 // 実引数が駆り引数より多いとき
108 // ※無条件で不一致
109 return false;
110 }
111
112 Type argType;
113 for(int i=0;i<max;i++){
114 Parameter &param = *targetParms[i];
115
116 if( i >= ParmsNum ){
117 // 引数が多いとき
118 if( param.GetInitValue().size() > 0 ){
119 // 初期値が指定されているパラメータを考慮
120 return true;
121 }
122 else{
123 return false;
124 }
125 }
126
127 if(Parms[i]){
128 Type nullParam( DEF_NON );
129
130 NumOpe_GetType(Parms[i],
131 ( level <= OVERLOAD_LEVEL3 )? nullParam : param,
132 argType);
133 }
134 else{
135 argType = types[i];
136 }
137
138 if(argType.GetBasicType()!=param.GetBasicType()){
139 if( level == OVERLOAD_LEVEL0 || level == OVERLOAD_LEVEL1 || level==OVERLOAD_LEVEL4 ){
140 return false;
141 }
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){
149 if(!(
150 argType.IsWhole()&&param.IsWhole()||
151 argType.IsReal()&&param.IsReal()
152 )){
153 return false;
154 }
155 }
156 else if(level==OVERLOAD_LEVEL6){
157 if(argType.IsObject()||param.IsObject()) return false;
158 }
159 }
160 else{
161 //if(NATURAL_TYPE(argType.GetBasicType())==DEF_OBJECT || NATURAL_TYPE(argType.GetBasicType())==DEF_STRUCT){
162 if( NATURAL_TYPE(argType.GetBasicType())==DEF_STRUCT){
163 if(argType.GetIndex()!=param.GetIndex()){
164 return false;
165 }
166 }
167 else if( NATURAL_TYPE(argType.GetBasicType())==DEF_OBJECT ){
168 if( level == OVERLOAD_LEVEL0 ){
169 if( !param.GetClass().IsEquals( &argType.GetClass() ) ){
170 return false;
171 }
172 }
173 else{
174 if( !param.GetClass().IsEqualsOrSubClass( &argType.GetClass() ) ){
175 return false;
176 }
177 }
178 }
179 }
180 }
181
182 if( !targetResultType.IsNull() ){
183 //戻り値も比較対象にする
184 if( !returnType.Equals( targetResultType ) ){
185 return false;
186 }
187 }
188
189 return true;
190}
191
192UserProc *ParamImpl::OverloadSolutionWithReturnType( const char *name, std::vector<UserProc *> &subs ){
193 int sw=0;
194 UserProc *pUserProc = NULL;
195
196 for( int level=OVERLOAD_MIN_LEVEL; level<=OVERLOAD_MAX_LEVEL; level++ ){
197 foreach( UserProc *pTempUserProc, subs ){
198
199 //エラーチェック
200 if(_overload_check( level, pTempUserProc->Params(), pTempUserProc->ReturnType() )){
201 if(sw){
202 SetError(52,name,cp);
203 return 0;
204 }
205 sw=1;
206
207 pUserProc = pTempUserProc;
208 }
209 }
210
211 if( sw ) break;
212 }
213
214 if(!sw){
215 SetError(52,name,cp);
216 return 0;
217 }
218
219 return pUserProc;
220}
221UserProc *ParamImpl::OverloadSolution( const char *name, std::vector<UserProc *> &subs ){
222 int sw=0;
223 UserProc *pUserProc;
224 pUserProc=0;
225
226 for( int level=OVERLOAD_MIN_LEVEL; level<=OVERLOAD_MAX_LEVEL; level++ ){
227
228 foreach( UserProc *pTempUserProc, subs ){
229
230 //エラーチェック
231 if(_overload_check( level, pTempUserProc->Params(), Type() )){
232 if(sw){
233 return OverloadSolutionWithReturnType(name,subs);
234 }
235 sw=1;
236
237 pUserProc = pTempUserProc;
238 }
239 }
240
241 if( sw ) break;
242 }
243
244 if(!sw){
245 foreach( UserProc *pTempUserProc, subs ){
246
247 //エラーチェック
248 if(pTempUserProc->Params().size()==this->ParmsNum){
249 if(sw){
250 sw=0;
251 break;
252 }
253 sw=1;
254
255 pUserProc=pTempUserProc;
256 }
257 }
258 }
259
260 if(!sw){
261 SetError(52,name,cp);
262 return 0;
263 }
264
265 return pUserProc;
266}
267
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
283bool ParamImpl::ErrorCheck( const string &procName, const Parameters &params, int SecondParmNum ){
284 if( SecondParmNum == -1 ) SecondParmNum = (int)params.size();
285
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 }
298
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.