source: dev/BasicCompiler_Common/ParamImpl.cpp@ 78

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

CTypeDef → TypeDef
Houseクラスを追加。
オーバーロードレベルの種類を追加(レベル1に挿入)

File size: 6.8 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(argType.GetIndex()!=param.GetIndex()){
155 return false;
156 }
157 }
158 }
159 }
160
161 if( !targetResultType.IsNull() ){
162 //戻り値も比較対象にする
163 if( !returnType.Equals( targetResultType ) ){
164 return false;
165 }
166 }
167
168 return true;
169}
170
171UserProc *ParamImpl::OverloadSolutionWithReturnType( const char *name, std::vector<UserProc *> &subs ){
172 int sw=0;
173 UserProc *pUserProc = NULL;
174
175 for( int level=OVERLOAD_MIN_LEVEL; level<=OVERLOAD_MAX_LEVEL; level++ ){
176 foreach( UserProc *pTempUserProc, subs ){
177
178 //エラーチェック
179 if(_overload_check( level, pTempUserProc->Params(), pTempUserProc->ReturnType() )){
180 if(sw){
181 SetError(52,name,cp);
182 return 0;
183 }
184 sw=1;
185
186 pUserProc = pTempUserProc;
187 break;
188 }
189 }
190
191 if( sw ) break;
192 }
193
194 if(!sw){
195 SetError(52,name,cp);
196 return 0;
197 }
198
199 return pUserProc;
200}
201UserProc *ParamImpl::OverloadSolution( const char *name, std::vector<UserProc *> &subs ){
202 int sw=0;
203 UserProc *pUserProc;
204 pUserProc=0;
205
206 for( int level=OVERLOAD_MIN_LEVEL; level<=OVERLOAD_MAX_LEVEL; level++ ){
207
208 foreach( UserProc *pTempUserProc, subs ){
209
210 //エラーチェック
211 if(_overload_check( level, pTempUserProc->Params(), Type() )){
212 if(sw){
213 return OverloadSolutionWithReturnType(name,subs);
214 }
215 sw=1;
216
217 pUserProc = pTempUserProc;
218 }
219 }
220
221 if( sw ) break;
222 }
223
224 if(!sw){
225 foreach( UserProc *pTempUserProc, subs ){
226
227 //エラーチェック
228 if(pTempUserProc->Params().size()==this->ParmsNum){
229 if(sw){
230 sw=0;
231 break;
232 }
233 sw=1;
234
235 pUserProc=pTempUserProc;
236 }
237 }
238 }
239
240 if(!sw){
241 SetError(52,name,cp);
242 return 0;
243 }
244
245 return pUserProc;
246}
247
248void ParamImpl::ApplyDefaultParameters( const Parameters &params ){
249 if( ParmsNum == (int)params.size() ){
250 // デフォルト引数の適用が不必要なとき
251 return;
252 }
253
254 while( ParmsNum < (int)params.size() ){
255 Parameter &param = *params[ParmsNum];
256
257 Parms[ParmsNum]=(char *)HeapAlloc(hHeap,0,param.GetInitValue().size() + 1 );
258 lstrcpy(Parms[ParmsNum],param.GetInitValue().c_str() );
259 ParmsNum++;
260 }
261}
262
263bool ParamImpl::ErrorCheck( const string &procName, const Parameters &params, int SecondParmNum ){
264 if( SecondParmNum == -1 ) SecondParmNum = (int)params.size();
265
266 if(ParmsNum>(int)params.size()){
267 if(params[params.size()-1]->GetBasicType()!=DEF_ELLIPSE){
268 //パラメータが多すぎるとき
269 SetError(10,procName,cp);
270 return false;
271 }
272 }
273 else if(ParmsNum<(int)params.size()){
274 if(ParmsNum<SecondParmNum){
275 if(params[ParmsNum]->GetBasicType()==DEF_ELLIPSE){
276 return true;
277 }
278
279 //パラメータが少なすぎるとき
280 SetError(10,procName,cp);
281 return false;
282 }
283
284 //省略パラメータに "0" を指定する
285 for(;ParmsNum < (int)params.size();ParmsNum++){
286 extern HANDLE hHeap;
287 char temporary[64];
288 if(params[ParmsNum]->IsRef() == false) lstrcpy(temporary,"0");
289 else sprintf(temporary,"%c%c0",1,ESC_BYVAL);
290 Parms[ParmsNum]=(char *)HeapAlloc(hHeap,0,lstrlen(temporary)+1);
291 lstrcpy(Parms[ParmsNum],temporary);
292 }
293 }
294
295 return true;
296}
297
298void ParamImpl::MacroParameterSupport( const Parameters &params ){
299 for(int i=0;i<ParmsNum;i++){
300 if(Parms[i][0]=='\0'){
301 extern HANDLE hHeap;
302 char temporary[64];
303 if( params[i]->IsRef() == false ) lstrcpy(temporary,"0");
304 else sprintf(temporary,"%c%c0",1,ESC_BYVAL);
305 HeapDefaultFree(Parms[i]);
306 Parms[i]=(char *)HeapAlloc(hHeap,0,lstrlen(temporary)+1);
307 lstrcpy(Parms[i],temporary);
308 }
309 }
310}
Note: See TracBrowser for help on using the repository browser.