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
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 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
17ParamImpl::ParamImpl(const char *buffer):
18 returnType()
19{
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
67 types.push_back( Type() );
68
69 if(buffer[i]==',') i++;
70 }
71}
72ParamImpl::ParamImpl(const Parameters &params):
73 returnType()
74{
75 ParmsNum = 0;
76 foreach( Parameter *pParam, params ){
77 Parms[ParmsNum]=0;
78 ParmsNum++;
79
80 types.push_back( *pParam );
81 }
82}
83ParamImpl::~ParamImpl(){
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
94void ParamImpl::SetReturnType( const Type &returnType ){
95 this->returnType = returnType;
96}
97
98bool ParamImpl::_overload_check( int level, const Parameters &targetParms, const Type &targetResultType ){
99 //パラメータを識別してオーバーロードを解決
100
101 //パラメータの個数が不一致の場合
102 int max = (int)targetParms.size();
103
104 if( ParmsNum > max ){
105 // 実引数が駆り引数より多いとき
106 // ※無条件で不一致
107 return false;
108 }
109
110 Type argType;
111 for(int i=0;i<max;i++){
112 Parameter &param = *targetParms[i];
113
114 if( i >= ParmsNum ){
115 // 引数が多いとき
116 if( param.GetInitValue().size() > 0 ){
117 // 初期値が指定されているパラメータを考慮
118 return true;
119 }
120 else{
121 return false;
122 }
123 }
124
125 if(Parms[i]){
126 Type nullParam( DEF_NON );
127
128 NumOpe_GetType(Parms[i],
129 (level==OVERLOAD_LEVEL0 || level == OVERLOAD_LEVEL1)? nullParam : param,
130 argType);
131 }
132 else{
133 argType = types[i];
134 }
135
136 if(argType.GetBasicType()!=param.GetBasicType()){
137 if( level == OVERLOAD_LEVEL0 || level==OVERLOAD_LEVEL2 ){
138 return false;
139 }
140 else if( level == OVERLOAD_LEVEL1 || level==OVERLOAD_LEVEL3){
141 if(!(
142 argType.IsWhole()&&param.IsWhole()||
143 argType.IsReal()&&param.IsReal()
144 )){
145 return false;
146 }
147 }
148 else if(level==OVERLOAD_LEVEL4){
149 if(argType.IsObject()||param.IsObject()) return false;
150 }
151 }
152 else{
153 //if(NATURAL_TYPE(argType.GetBasicType())==DEF_OBJECT || NATURAL_TYPE(argType.GetBasicType())==DEF_STRUCT){
154 if( NATURAL_TYPE(argType.GetBasicType())==DEF_STRUCT){
155 if(argType.GetIndex()!=param.GetIndex()){
156 return false;
157 }
158 }
159 else if( NATURAL_TYPE(argType.GetBasicType())==DEF_OBJECT ){
160 if( !param.GetClass().IsEqualsOrSubClass( &argType.GetClass() ) ){
161 return false;
162 }
163 }
164 }
165 }
166
167 if( !targetResultType.IsNull() ){
168 //戻り値も比較対象にする
169 if( !returnType.Equals( targetResultType ) ){
170 return false;
171 }
172 }
173
174 return true;
175}
176
177UserProc *ParamImpl::OverloadSolutionWithReturnType( const char *name, std::vector<UserProc *> &subs ){
178 int sw=0;
179 UserProc *pUserProc = NULL;
180
181 for( int level=OVERLOAD_MIN_LEVEL; level<=OVERLOAD_MAX_LEVEL; level++ ){
182 foreach( UserProc *pTempUserProc, subs ){
183
184 //エラーチェック
185 if(_overload_check( level, pTempUserProc->Params(), pTempUserProc->ReturnType() )){
186 if(sw){
187 SetError(52,name,cp);
188 return 0;
189 }
190 sw=1;
191
192 pUserProc = pTempUserProc;
193 break;
194 }
195 }
196
197 if( sw ) break;
198 }
199
200 if(!sw){
201 SetError(52,name,cp);
202 return 0;
203 }
204
205 return pUserProc;
206}
207UserProc *ParamImpl::OverloadSolution( const char *name, std::vector<UserProc *> &subs ){
208 int sw=0;
209 UserProc *pUserProc;
210 pUserProc=0;
211
212 for( int level=OVERLOAD_MIN_LEVEL; level<=OVERLOAD_MAX_LEVEL; level++ ){
213
214 foreach( UserProc *pTempUserProc, subs ){
215
216 //エラーチェック
217 if(_overload_check( level, pTempUserProc->Params(), Type() )){
218 if(sw){
219 return OverloadSolutionWithReturnType(name,subs);
220 }
221 sw=1;
222
223 pUserProc = pTempUserProc;
224 }
225 }
226
227 if( sw ) break;
228 }
229
230 if(!sw){
231 foreach( UserProc *pTempUserProc, subs ){
232
233 //エラーチェック
234 if(pTempUserProc->Params().size()==this->ParmsNum){
235 if(sw){
236 sw=0;
237 break;
238 }
239 sw=1;
240
241 pUserProc=pTempUserProc;
242 }
243 }
244 }
245
246 if(!sw){
247 SetError(52,name,cp);
248 return 0;
249 }
250
251 return pUserProc;
252}
253
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
269bool ParamImpl::ErrorCheck( const string &procName, const Parameters &params, int SecondParmNum ){
270 if( SecondParmNum == -1 ) SecondParmNum = (int)params.size();
271
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 }
284
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.