source: dev/BasicCompiler_Common/ParamImpl.cpp@ 84

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