source: dev/BasicCompiler_Common/ParamImpl.cpp@ 90

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

実行時型情報の生成にほぼ対応した。

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