source: dev/BasicCompiler32/CParameter.cpp@ 8

Last change on this file since 8 was 3, checked in by dai_9181, 18 years ago
File size: 13.0 KB
Line 
1#include "../BasicCompiler_Common/common.h"
2#include "opcode.h"
3
4CParameter::CParameter(char *buffer){
5 ///////////////////////////
6 // パラメータ文字列を整理
7 ///////////////////////////
8
9 extern HANDLE hHeap;
10 int i,i2,i3;
11 char temporary[VN_SIZE];
12
13 i=0;
14 ParmsNum=0;
15 while(1){
16 if(buffer[i]=='\0') break;
17
18 for(i2=0;;i2++,i++){
19 if(buffer[i]=='\"'){
20 temporary[i2]=buffer[i];
21 for(i++,i2++;;i++,i2++){
22 temporary[i2]=buffer[i];
23 if(buffer[i]=='\"') break;
24 }
25 continue;
26 }
27
28 if(buffer[i]=='('){
29 i3=GetStringInPare(temporary+i2,buffer+i);
30 i2+=i3-1;
31 i+=i3-1;
32 continue;
33 }
34 if(buffer[i]=='['){
35 i3=GetStringInBracket(temporary+i2,buffer+i);
36 i2+=i3-1;
37 i+=i3-1;
38 continue;
39 }
40
41 if(buffer[i]==','||buffer[i]=='\0'){
42 temporary[i2]=0;
43 break;
44 }
45 temporary[i2]=buffer[i];
46 }
47
48 Parms[ParmsNum]=(char *)HeapAlloc(hHeap,0,lstrlen(temporary)+1);
49 lstrcpy(Parms[ParmsNum],temporary);
50 ParmsNum++;
51
52 if(buffer[i]==',') i++;
53 }
54
55 ReturnTypeInfo.type=0;
56 ReturnTypeInfo.u.lpIndex=0;
57}
58CParameter::CParameter(PARAMETER_INFO *pParamInfo,int ParmNum){
59 int i;
60 for(i=0;i<ParmNum;i++){
61 Parms[i]=0;
62 types[i].type=pParamInfo[i].type;
63 types[i].u.lpIndex=pParamInfo[i].u.index;
64 }
65 this->ParmsNum=ParmNum;
66
67 ReturnTypeInfo.type=0;
68 ReturnTypeInfo.u.lpIndex=0;
69}
70CParameter::~CParameter(){
71 int i2;
72
73 //パラメータ文字列を解放
74 for(i2=0;i2<ParmsNum;i2++){
75 if(Parms[i2]==(char *)-1) continue;
76
77 if(Parms[i2]) HeapDefaultFree(Parms[i2]);
78 }
79}
80
81
82void CParameter::SetReturnType(TYPEINFO *pTypeInfo){
83 ReturnTypeInfo=*pTypeInfo;
84}
85
86BOOL CParameter::_overload_check(PARAMETER_INFO *ppi,int pi_num,TYPEINFO *pReturnTypeInfo,int overload_level){
87 //パラメータを識別してオーバーロードを解決
88
89 //パラメータの個数が不一致の場合
90 if(pi_num!=ParmsNum) return 0;
91
92 int i,type;
93 LONG_PTR lpIndex;
94 for(i=0;i<pi_num;i++){
95 if(Parms[i]){
96 TYPEINFO BaseType={ppi[i].type,ppi[i].u.index};
97 if(Parms[i][0]==1&&Parms[i][1]==ESC_BYVAL){
98 type=NumOpe_GetType(Parms[i]+2,&BaseType,&lpIndex);
99 type=MAKE_PTR_TYPE(NATURAL_TYPE(type),PTR_LEVEL(type)-1);
100 }
101 else{
102 type=NumOpe_GetType(Parms[i],&BaseType,&lpIndex);
103 }
104 }
105 else{
106 type=types[i].type;
107 lpIndex=types[i].u.lpIndex;
108 }
109
110 if(type!=ppi[i].type){
111 if(overload_level==OVERLOAD_LEVEL1){
112 return 0;
113 }
114 else if(overload_level==OVERLOAD_LEVEL2){
115 if(!(
116 IsWholeNumberType(type)&&IsWholeNumberType(ppi[i].type)||
117 IsRealNumberType(type)&&IsRealNumberType(ppi[i].type)
118 )) return 0;
119 }
120 else if(overload_level==OVERLOAD_LEVEL3){
121 if(type==DEF_OBJECT||ppi[i].type==DEF_OBJECT) return 0;
122 }
123 }
124 else{
125 if(NATURAL_TYPE(type)==DEF_OBJECT){
126 if(lpIndex!=ppi[i].u.index) return 0;
127 }
128 }
129 }
130
131 if(pReturnTypeInfo){
132 //戻り値も比較対象にする
133 if(ReturnTypeInfo.type==pReturnTypeInfo->type){
134 if(NATURAL_TYPE(ReturnTypeInfo.type)==DEF_OBJECT){
135 if(ReturnTypeInfo.u.lpIndex != pReturnTypeInfo->u.lpIndex) return 0;
136 }
137 }
138 else return 0;
139 }
140
141 return 1;
142}
143SUBINFO *CParameter::OverloadSolutionWithReturnType(char *name,SUBINFO **ppsi,int num){
144 int i,sw=0;
145 SUBINFO *psi;
146 psi=0;
147 for(i=0;i<num;i++){
148 psi=ppsi[i];
149
150 TYPEINFO ReturnTypeInfo;
151 ReturnTypeInfo.type=psi->ReturnType;
152 ReturnTypeInfo.u.lpIndex=psi->u.ReturnIndex;
153
154 //エラーチェック
155 if(_overload_check(psi->pParmInfo,psi->ParmNum,&ReturnTypeInfo,OVERLOAD_LEVEL1)){
156 if(sw){
157 SetError(52,name,cp);
158 return 0;
159 }
160 sw=1;
161 break;
162 }
163 }
164
165 if(!sw){
166 for(i=0;i<num;i++){
167 psi=ppsi[i];
168
169 TYPEINFO ReturnTypeInfo;
170 ReturnTypeInfo.type=psi->ReturnType;
171 ReturnTypeInfo.u.lpIndex=psi->u.ReturnIndex;
172
173 //エラーチェック
174 if(_overload_check(psi->pParmInfo,psi->ParmNum,&ReturnTypeInfo,OVERLOAD_LEVEL2)){
175 if(sw){
176 SetError(52,name,cp);
177 return 0;
178 }
179 sw=1;
180 break;
181 }
182 }
183 }
184
185 if(!sw){
186 for(i=0;i<num;i++){
187 psi=ppsi[i];
188
189 TYPEINFO ReturnTypeInfo;
190 ReturnTypeInfo.type=psi->ReturnType;
191 ReturnTypeInfo.u.lpIndex=psi->u.ReturnIndex;
192
193 //エラーチェック
194 if(_overload_check(psi->pParmInfo,psi->ParmNum,&ReturnTypeInfo,OVERLOAD_LEVEL3)){
195 if(sw){
196 SetError(52,name,cp);
197 return 0;
198 }
199 sw=1;
200 break;
201 }
202 }
203 }
204
205 if(!sw){
206 SetError(52,name,cp);
207 return 0;
208 }
209
210 return psi;
211}
212
213SUBINFO *CParameter::OverloadSolution(char *name,SUBINFO **ppsi,int num){
214 int i,sw=0;
215 SUBINFO *psi;
216 psi=0;
217 for(i=0;i<num;i++){
218 psi=ppsi[i];
219
220 //エラーチェック
221 if(_overload_check(psi->pParmInfo,psi->ParmNum,NULL,OVERLOAD_LEVEL1)){
222 if(sw){
223 return OverloadSolutionWithReturnType(name,ppsi,num);
224 }
225 sw=1;
226 break;
227 }
228 }
229
230 if(!sw){
231 for(i=0;i<num;i++){
232 psi=ppsi[i];
233
234 //エラーチェック
235 if(_overload_check(psi->pParmInfo,psi->ParmNum,NULL,OVERLOAD_LEVEL2)){
236 if(sw){
237 return OverloadSolutionWithReturnType(name,ppsi,num);
238 }
239 sw=1;
240 break;
241 }
242 }
243 }
244
245 if(!sw){
246 for(i=0;i<num;i++){
247 psi=ppsi[i];
248
249 //エラーチェック
250 if(_overload_check(psi->pParmInfo,psi->ParmNum,NULL,OVERLOAD_LEVEL3)){
251 if(sw){
252 return OverloadSolutionWithReturnType(name,ppsi,num);
253 }
254 sw=1;
255 break;
256 }
257 }
258 }
259
260 if(!sw){
261 SUBINFO *temp_psi;
262 for(i=0;i<num;i++){
263 temp_psi=ppsi[i];
264
265 //エラーチェック
266 if(temp_psi->ParmNum==this->ParmsNum){
267 if(sw){
268 sw=0;
269 break;
270 }
271 sw=1;
272
273 psi=temp_psi;
274 }
275 }
276 }
277
278 if(!sw){
279 SetError(52,name,cp);
280 return 0;
281 }
282
283 return psi;
284}
285
286BOOL CParameter::ErrorCheck(char *FuncName,PARAMETER_INFO *ppi,int pi_num,int SecondParmNum){
287 if(ParmsNum>pi_num){
288 if(ppi[pi_num-1].type!=DEF_ELLIPSE){
289 //パラメータが多すぎるとき
290 SetError(10,FuncName,cp);
291 return 0;
292 }
293 }
294 else if(ParmsNum<pi_num){
295 if(ParmsNum<SecondParmNum){
296 if(ppi[ParmsNum].type==DEF_ELLIPSE){
297 return 1;
298 }
299
300 //パラメータが少なすぎるとき
301 SetError(10,FuncName,cp);
302 return 0;
303 }
304
305 //省略パラメータに "0" を指定する
306 for(;ParmsNum < pi_num;ParmsNum++){
307 extern HANDLE hHeap;
308 char temporary[64];
309 if(ppi[ParmsNum].bByVal) lstrcpy(temporary,"0");
310 else sprintf(temporary,"%c%c0",1,ESC_BYVAL);
311 Parms[ParmsNum]=(char *)HeapAlloc(hHeap,0,lstrlen(temporary)+1);
312 lstrcpy(Parms[ParmsNum],temporary);
313 }
314 }
315
316 return 1;
317}
318void CParameter::MacroParameterSupport(PARAMETER_INFO *ppi){
319 int i;
320 for(i=0;i<ParmsNum;i++){
321 if(Parms[i][0]=='\0'){
322 extern HANDLE hHeap;
323 char temporary[64];
324 if(ppi[i].bByVal) lstrcpy(temporary,"0");
325 else sprintf(temporary,"%c%c0",1,ESC_BYVAL);
326 HeapDefaultFree(Parms[i]);
327 Parms[i]=(char *)HeapAlloc(hHeap,0,lstrlen(temporary)+1);
328 lstrcpy(Parms[i],temporary);
329 }
330 }
331}
332
333void CParameter::SetObjectParameter(CClass *pobj_Class,LPSTR Parameter){
334 int object_size;
335 object_size=GetSizeOfClass(pobj_Class);
336
337 //push object_size
338 op_push_value(object_size);
339
340 //call calloc
341 extern SUBINFO *pSub_calloc;
342 op_call(pSub_calloc);
343
344 //push eax
345 op_push(REG_EAX);
346
347
348 TYPEINFO BaseType={DEF_OBJECT,(LONG_PTR)pobj_Class};
349 TYPEINFO CalcType;
350 CalcType.type=NumOpe_GetType(Parameter,&BaseType,&CalcType.u.lpIndex);
351
352 if(pobj_Class->CopyConstructorMemberSubIndex!=-1&&
353 CalcType.type==DEF_OBJECT&&CalcType.u.pobj_Class==pobj_Class){
354 ////////////////////////////////////
355 // コピーコンストラクタを呼び出す
356 ////////////////////////////////////
357
358 //push eax
359 op_push(REG_EAX);
360
361 BOOL bUseHeap;
362 CalcType.type=NumOpe(Parameter,DEF_OBJECT,(LONG_PTR)pobj_Class,&CalcType.u.lpIndex,&bUseHeap);
363
364 //pop ecx
365 op_pop(REG_ECX);
366
367 //pop eax
368 op_pop(REG_EAX);
369
370 if(bUseHeap){
371 //※解放用に退避
372 //mov esi,ecx
373 op_mov_RR(REG_ESI,REG_ECX);
374 }
375
376 //push ecx
377 op_push(REG_ECX);
378
379 //push eax
380 op_push(REG_EAX);
381
382 //call constructor
383 op_call(pobj_Class->ppobj_Method[pobj_Class->CopyConstructorMemberSubIndex]->psi);
384
385
386 if(bUseHeap){
387 FreeTempObject(REG_ESI,pobj_Class);
388 }
389 }
390 else{
391 //push eax
392 op_push(REG_EAX);
393
394
395 if(pobj_Class->ConstructorMemberSubIndex!=-1){
396 ////////////////////////////////
397 // コンストラクタを呼び出す
398 ////////////////////////////////
399
400 //push this
401 op_push(REG_EAX);
402
403 //call constructor
404 op_call(pobj_Class->ppobj_Method[pobj_Class->ConstructorMemberSubIndex]->psi);
405 }
406
407
408 TYPEINFO CalcType;
409 BOOL bUseHeap;
410 CalcType.type=NumOpe(Parameter,DEF_OBJECT,(LONG_PTR)pobj_Class,&CalcType.u.lpIndex,&bUseHeap);
411
412
413
414 SetObjectVariable((LONG_PTR)pobj_Class,CalcType.type,CalcType.u.lpIndex,bUseHeap);
415 }
416}
417
418int CParameter::SetParameter(char *FuncName,PARAMETER_INFO *ppi,int pi_num,int SecondParmNum){
419 ///////////////////////////////////////////////////////////
420 // パラメータをレジスタ及びスタックフレームにセット
421 ///////////////////////////////////////////////////////////
422 int i2,i3;
423
424 BOOL bEllipse;
425 if(pi_num){
426 if(ppi[pi_num-1].type==DEF_ELLIPSE) bEllipse=1;
427 else bEllipse=0;
428 }
429 else bEllipse=0;
430
431 BOOL bHas_System_LocalThis=0;
432 if(ParmsNum>=1){
433 if(lstrcmp(ppi[0].name,"_System_LocalThis")==0)
434 bHas_System_LocalThis=1;
435 }
436
437 //パラメータをレジスタとスタックに格納
438 int CalcType;
439 LONG_PTR lpCalcIndex;
440 BOOL bCalcUseHeap;
441 int ParmSize=0;
442 RELATIVE_VAR RelativeVar;
443 for(i2=ParmsNum-1;i2>=0;i2--){
444 if(bEllipse&&i2<=pi_num-2) bEllipse=0;
445
446 if(i2==0&&ppi[i2].name){
447 if(lstrcmp(ppi[i2].name,"_System_LocalThis")==0){
448 //オブジェクトメンバの第一パラメータのThisポインタ
449 continue;
450 }
451 }
452 if((i2==0||i2==1)&&ppi[i2].name){
453 if(lstrcmp(ppi[i2].name,FuncName)==0){
454 //オブジェクトメンバの第一または第二パラメータの戻り値用オブジェクト
455 continue;
456 }
457 }
458
459 TYPEINFO DummyTypeInfo;
460 BOOL bByVal;
461 if(bEllipse){
462 DummyTypeInfo.type=NumOpe_GetType(Parms[i2],NULL,&DummyTypeInfo.u.lpIndex);
463 bByVal=1;
464 }
465 else{
466 DummyTypeInfo.type=ppi[i2].type;
467 DummyTypeInfo.u.lpIndex=ppi[i2].u.index;
468 bByVal=ppi[i2].bByVal;
469 }
470
471 if(bByVal==1){
472 //値参照
473
474 if(Parms[i2][0]==1&&Parms[i2][1]==ESC_BYVAL){
475 char temp2[255];
476 sprintf(temp2,"%s関数の第%dパラメータ",FuncName,i2+1);
477 SetError(19,temp2,cp);
478 continue;
479 }
480
481 if(DummyTypeInfo.type==DEF_OBJECT){
482 SetObjectParameter(DummyTypeInfo.u.pobj_Class,Parms[i2]);
483 goto next;
484 }
485
486
487 extern LONG_PTR ProcPtr_BaseIndex;
488 LONG_PTR back_ProcPtr_BaseIndex;
489 back_ProcPtr_BaseIndex=ProcPtr_BaseIndex;
490 if(DummyTypeInfo.type==DEF_PTR_PROC) ProcPtr_BaseIndex=DummyTypeInfo.u.lpIndex;
491 else ProcPtr_BaseIndex=-1;
492
493 CalcType=NumOpe(Parms[i2],DummyTypeInfo.type,DummyTypeInfo.u.lpIndex,&lpCalcIndex,&bCalcUseHeap);
494
495 ProcPtr_BaseIndex=back_ProcPtr_BaseIndex;
496
497 if(CalcType==-1) break;
498
499 if(CalcType==DEF_OBJECT){
500 //キャスト演算子のオーバーロードに対応する
501 CallCastOperatorProc(CalcType,lpCalcIndex,bCalcUseHeap,DummyTypeInfo.type,DummyTypeInfo.u.lpIndex);
502 }
503
504 if(!bEllipse){
505 //型チェック
506 if(bHas_System_LocalThis) i3=i2-1;
507 else i3=i2;
508 CheckDifferentType(
509 DummyTypeInfo.type,
510 DummyTypeInfo.u.lpIndex,
511 CalcType,
512 lpCalcIndex,
513 FuncName,
514 i3);
515 }
516
517 if(DummyTypeInfo.type==DEF_DOUBLE){
518 ChangeTypeToDouble(CalcType);
519 ParmSize+=sizeof(long)*2;
520 }
521 else if(DummyTypeInfo.type==DEF_SINGLE){
522 ChangeTypeToSingle(CalcType);
523 ParmSize+=sizeof(long);
524 }
525 else if(DummyTypeInfo.type==DEF_INT64||DummyTypeInfo.type==DEF_QWORD){
526 ChangeTypeToInt64(CalcType);
527 ParmSize+=sizeof(long)*2;
528 }
529 else if(DummyTypeInfo.type==DEF_LONG||DummyTypeInfo.type==DEF_DWORD||
530 (IsPtrType(DummyTypeInfo.type)/*&&DummyTypeInfo.type!=DEF_PTR_VOID&&DummyTypeInfo.type!=DEF_PTR_BYTE*/)){
531 ChangeTypeToLong(CalcType);
532 ParmSize+=sizeof(long);
533 }
534 else if(DummyTypeInfo.type==DEF_INTEGER||DummyTypeInfo.type==DEF_WORD){
535 ChangeTypeToInteger(CalcType);
536 ParmSize+=sizeof(long);
537 }
538 else if(DummyTypeInfo.type==DEF_CHAR||DummyTypeInfo.type==DEF_BYTE){
539 ChangeTypeToByte(CalcType);
540 ParmSize+=sizeof(long);
541 }
542 else{
543 SetError(300,NULL,cp);
544 }
545 }
546 else{
547 //ポインタ参照
548 if(Parms[i2][0]==1&&Parms[i2][1]==ESC_BYVAL){
549 //ポインタ指定
550 i3=NumOpe(Parms[i2]+2,0,0,0);
551
552 ChangeTypeToLong(i3);
553 }
554 else{
555 //変数のアドレスを取得
556 int VarType;
557 LONG_PTR lpVarIndex;
558 if(!GetVarOffset(1,Parms[i2],&VarType,&RelativeVar,&lpVarIndex)) continue;
559
560 if(DummyTypeInfo.type!=DEF_ANY){
561 //型チェックを行う
562 if(DummyTypeInfo.type==VarType){
563 if(DummyTypeInfo.type==DEF_OBJECT){
564 if(DummyTypeInfo.u.lpIndex!=lpVarIndex){
565 SetError(11,Parms[i2],cp);
566 }
567 }
568 }
569 else if((VarType&FLAG_PTR)&&((int)(VarType^FLAG_PTR)==DummyTypeInfo.type)){
570 //仮引数がポインタ参照で、実引数が配列の先頭ポインタのとき
571 }
572 else{
573 SetError(11,Parms[i2],cp);
574 }
575 }
576
577 //変数アドレスをレジスタにセット
578 SetVarPtrToEax(&RelativeVar);
579
580 //push eax
581 op_push(REG_EAX);
582 }
583
584 ParmSize+=PTR_SIZE;
585 }
586
587next:;
588 }
589
590 return ParmSize;
591}
Note: See TracBrowser for help on using the repository browser.