source: dev/trunk/abdev/BasicCompiler64/Compile_Statement.cpp@ 248

Last change on this file since 248 was 243, checked in by dai_9181, 17 years ago
File size: 23.2 KB
RevLine 
[206]1#include "stdafx.h"
2
[183]3#include <jenga/include/smoothie/LexicalAnalysis.h>
4
5#include <LexicalScopingImpl.h>
6#include <Compiler.h>
7
[3]8#include "../BasicCompiler_Common/common.h"
9#include "Opcode.h"
10
[129]11void OpcodeOthers(const char *Command){
[3]12 int i,i2;
13
[122]14 char leftTerm[8192];
15 int lastParePos = 0;
[3]16 for(i=0;;i++){
[122]17 if(Command[i]=='\"'){
18 //ダブルクォートは不正なのでエラー扱い
19 leftTerm[i]=0;
20 SetError(3,leftTerm,cp);
21 return;
22 }
23
24 if(Command[i]=='('){
25 lastParePos = i;
26 i2=GetStringInPare(leftTerm+i,Command+i);
[3]27 i+=i2-1;
28 continue;
29 }
[122]30 if(Command[i]=='['){
31 i2=GetStringInBracket(leftTerm+i,Command+i);
32 i+=i2-1;
[3]33 continue;
34 }
[122]35 if(Command[i]=='\0'){
36 leftTerm[i] = 0;
[3]37 break;
38 }
[122]39
40 if( IsNumCalcMark( Command, i ) ){
41 leftTerm[i] = 0;
42 break;
43 }
44
45 leftTerm[i]=Command[i];
[3]46 }
47 if(!(
[122]48 IsVariableTopChar(leftTerm[0])||
49 leftTerm[0]=='.'||
50 (leftTerm[0]==1&&leftTerm[1]==ESC_PSMEM)
[3]51 )){
52 SetError(1,NULL,cp);
53 return;
54 }
55
56
[122]57 if(Command[i]=='\0' && lastParePos == 0){
[3]58 //////////////////////////////
59 // パラメータ無しのマクロ検索
60 //////////////////////////////
61
[206]62 const UserProc *pUserProc=GetSubHash(Command);
[3]63
64 //GetSubHash内でエラー提示が行われた場合
[75]65 if(pUserProc==(UserProc *)-1) return;
[3]66
[75]67 if(pUserProc==0){
[3]68 char temporary[VN_SIZE];
69 lstrcpy(temporary,Command);
70
71 CharUpper(temporary);
[75]72 pUserProc=GetSubHash(temporary);
[3]73
74 //GetSubHash内でエラー提示が行われた場合
[75]75 if(pUserProc==(UserProc *)-1) return;
[3]76 }
77
[75]78 if(pUserProc){
[97]79 if( !pUserProc->IsMacro() ){
80 SetError(10,Command,cp);
81 }
[3]82
[75]83 Opcode_CallProc("",pUserProc,0,"",0);
[3]84
85 return;
86 }
87 }
88 else if(IsNumCalcMark(Command,i)){
89 //代入演算
90 OpcodeCalc(Command);
91 return;
92 }
93
[122]94 if( pobj_reg ){
95 SetError();
96 }
97 pobj_reg=new CRegister(REG_RAX);
[3]98
[122]99 Type resultType;
100 bool isLiteral;
101 BOOL bUseHeap;
[128]102 bool result = TermOpe( leftTerm, Type(), resultType, isLiteral, &bUseHeap, false, NULL, true );
[3]103
[122]104 delete pobj_reg;
105 pobj_reg = NULL;
[3]106
[122]107 if( result ){
[3]108
109 /////////////////////
110 // 戻り値の処理
111 /////////////////////
112
[75]113 if( resultType.IsStruct() ){
[3]114 //mov r14,rax
[226]115 compiler.codeGenerator.op_mov_RR(REG_R14,REG_RAX);
[3]116
[75]117 FreeTempObject(REG_R14,&resultType.GetClass());
[3]118 }
[122]119
120 //成功
[3]121 return;
122 }
123
[122]124 // 失敗
125 SetError(1, NULL,cp);
[3]126}
127
128void Judgment(char *buffer){
[75]129 int reg=REG_RAX;
130 Type resultType;
131 if( !NumOpe(&reg,buffer,Type(),resultType) ){
132 return;
133 }
[3]134
135 int offset;
136
[75]137 if(resultType.IsDouble()){
[3]138 double dbl=0;
[224]139 offset=compiler.GetDataTable().Add( dbl );
[3]140
141 //comisd xmm0,qword ptr[data table offset]
[242]142 compiler.codeGenerator.PutOld(
143 (char)0x66,
144 (char)0x0F,
145 (char)0x2F,
146 (char)0x04,
147 (char)0x25
148 );
149 compiler.codeGenerator.PutOld(
150 (long)offset,
151 Schedule::DataTable
152 );
[3]153 }
[75]154 else if(resultType.IsSingle()){
[3]155 float flt=0;
[224]156 offset=compiler.GetDataTable().Add( flt );
[3]157
158 //comiss xmm0,dword ptr[data table offset]
[242]159 compiler.codeGenerator.PutOld(
160 (char)0x0F,
161 (char)0x2F,
162 (char)0x04,
163 (char)0x25
164 );
165 compiler.codeGenerator.PutOld(
166 (long)offset,
167 Schedule::DataTable
168 );
[3]169 }
170 else{
171 //整数型
172
173 //cmp rax,0
[226]174 compiler.codeGenerator.op_cmp_value(resultType.GetSize(),REG_RAX,0);
[3]175 }
176}
177
178void OpcodeIf(char *Parameter){
[242]179 for(int i=0;;i++){
[3]180 if(Parameter[i]=='\0'){
181 SetError(21,NULL,cp);
182 return;
183 }
184 if(Parameter[i]==1&&Parameter[i+1]==ESC_THEN){
185 Parameter[i]=0;
186 break;
187 }
188 }
189
190 //条件式を実行してフラグをセット
191 Judgment(Parameter);
192
193 //je (endif、または else まで条件ジャンプ)
[242]194 CodeGenerator::PertialSchedule *pIfPertialSchedule = compiler.codeGenerator.op_je( 0, sizeof(long), true );
[3]195
196
197 /////////////////////////
198 // If内をコード化
199 /////////////////////////
200
201 //レキシカルスコープをレベルアップ
[183]202 GetLexicalScopes().Start( obp, SCOPE_TYPE_IF );
[3]203
[242]204 int i2=CompileBuffer(ESC_ENDIF,0);
[3]205
206 //レキシカルスコープをレベルダウン
[183]207 GetLexicalScopes().End();
[3]208
209
210 if(i2==ESC_ELSE){
211 //jmp (endifまで)
[242]212 CodeGenerator::PertialSchedule *pTempPertialSchedule = compiler.codeGenerator.op_jmp( 0, sizeof(long), true );
[3]213
[242]214 compiler.codeGenerator.opfix_JmpPertialSchedule( pIfPertialSchedule );
[3]215
216
217
218 /////////////////////////
219 // Else内をコード化
220 /////////////////////////
221
222 //レキシカルスコープをレベルアップ
[183]223 GetLexicalScopes().Start( obp, SCOPE_TYPE_IF );
[3]224
225 CompileBuffer(ESC_ENDIF,0);
226
227 //レキシカルスコープをレベルダウン
[183]228 GetLexicalScopes().End();
[3]229
230
[242]231 compiler.codeGenerator.opfix_JmpPertialSchedule( pTempPertialSchedule );
[3]232 }
233 else{
[242]234 compiler.codeGenerator.opfix_JmpPertialSchedule( pIfPertialSchedule );
[3]235 }
236}
237
238int GetLabelAddress(char *LabelName,int LineNum){
239 extern int MaxLabelNum;
240 extern LABEL *pLabelNames;
241 int i;
242
243 if(LabelName){
244 for(i=0;i<MaxLabelNum;i++){
245 if(pLabelNames[i].pName){
246 if(lstrcmp(LabelName,pLabelNames[i].pName)==0) return pLabelNames[i].address;
247 }
248 }
249 }
250 else{
251 for(i=0;i<MaxLabelNum;i++){
252 if(pLabelNames[i].pName==0){
253 if(LineNum==pLabelNames[i].line) return pLabelNames[i].address;
254 }
255 }
256 }
257 return -1;
258}
259void OpcodeGoto(char *Parameter){
260 extern HANDLE hHeap;
261 extern GOTOLABELSCHEDULE *pGotoLabelSchedule;
262 extern int GotoLabelScheduleNum;
263 int i,LineNum;
264
265 if(Parameter[0]=='*'){
266 i=GetLabelAddress(Parameter+1,0);
267
268 //jmp ...
269 OpBuffer[obp++]=(char)0xE9;
270 if(i==-1){
271 pGotoLabelSchedule=(GOTOLABELSCHEDULE *)HeapReAlloc(hHeap,0,pGotoLabelSchedule,(GotoLabelScheduleNum+1)*sizeof(GOTOLABELSCHEDULE));
272 pGotoLabelSchedule[GotoLabelScheduleNum].pName=(char *)HeapAlloc(hHeap,0,lstrlen(Parameter+1)+1);
273 lstrcpy(pGotoLabelSchedule[GotoLabelScheduleNum].pName,Parameter+1);
274 pGotoLabelSchedule[GotoLabelScheduleNum].pos=obp;
275 pGotoLabelSchedule[GotoLabelScheduleNum].now_cp=cp;
276 GotoLabelScheduleNum++;
277 }
278 *((long *)(OpBuffer+obp))=i-(obp+sizeof(long));
279 obp+=sizeof(long);
280 }
281 else{
282 LineNum=atoi(Parameter);
283 i=GetLabelAddress(0,LineNum);
284
285 //jmp ...
286 OpBuffer[obp++]=(char)0xE9;
287 if(i==-1){
288 pGotoLabelSchedule=(GOTOLABELSCHEDULE *)HeapReAlloc(hHeap,0,pGotoLabelSchedule,(GotoLabelScheduleNum+1)*sizeof(GOTOLABELSCHEDULE));
289 pGotoLabelSchedule[GotoLabelScheduleNum].pName=0;
290 pGotoLabelSchedule[GotoLabelScheduleNum].line=LineNum;
291 pGotoLabelSchedule[GotoLabelScheduleNum].pos=obp;
292 pGotoLabelSchedule[GotoLabelScheduleNum].now_cp=cp;
293 GotoLabelScheduleNum++;
294 }
295 *((long *)(OpBuffer+obp))=i-(obp+sizeof(long));
296 obp+=sizeof(long);
297 }
298}
299void OpcodeWhile(char *Parameter){
300 extern HANDLE hHeap;
301
302 //Continueアドレスのバックアップとセット
[242]303 compiler.codeGenerator.ContinueAreaBegin();
[3]304
305 if(!Parameter[0]) SetError(10,"While",cp);
306
307 //条件式を実行してフラグをセット
308 Judgment(Parameter);
309
310 //je (Wend まで)
[242]311 CodeGenerator::PertialSchedule *pWhilePertialSchedule = compiler.codeGenerator.op_je( 0, sizeof(long), true );
[3]312
313 //レキシカルスコープをレベルアップ
[183]314 GetLexicalScopes().Start( obp, SCOPE_TYPE_WHILE );
[3]315
316 //While内をコンパイル
317 CompileBuffer(0,COM_WEND);
318
[183]319 GetLexicalScopes().CallDestructorsOfScopeEnd();
[3]320
321 //jmp ...
[242]322 compiler.codeGenerator.op_jmp_continue();
[3]323
324 //レキシカルスコープをレベルダウン
[183]325 GetLexicalScopes().End();
[3]326
[242]327 compiler.codeGenerator.opfix_JmpPertialSchedule( pWhilePertialSchedule );
[3]328
329 //Continueアドレスを復元
[242]330 compiler.codeGenerator.ContinueAreaEnd();
[3]331}
332
333char szNextVariable[VN_SIZE];
334void OpcodeFor(char *Parameter){
335 extern HANDLE hHeap;
[75]336 Type resultType;
[242]337 int i,i2;
[3]338 char temporary[VN_SIZE],variable[VN_SIZE],JudgeNum[VN_SIZE],StepNum[VN_SIZE];
[34]339 bool isError = false;
[3]340
341 //第1パラメータを取得
342 i=GetOneParameter(Parameter,0,temporary);
343 if(!Parameter[i]){
344 SetError(12,"For",cp);
[34]345 isError = true;
[3]346 goto ErrorStep;
347 }
348
349 for(i2=0;;i2++){
350 if(temporary[i2]=='='){
351 variable[i2]=0;
352
353 //カウンタ初期化
354 OpcodeCalc(temporary);
355 break;
356 }
357 if(temporary[i2]=='\0'){
358 SetError(12,"For",cp);
[34]359 isError = true;
[3]360 goto ErrorStep;
361 }
362 variable[i2]=temporary[i2];
363 }
364
365 //jmp ...
[242]366 CodeGenerator::PertialSchedule *pTempPertialSchedule = compiler.codeGenerator.op_jmp( 0, sizeof(long), true );
[3]367
368 //Continueアドレスのバックアップとセット
[242]369 compiler.codeGenerator.ContinueAreaBegin();
[3]370
371 //第2パラメータを取得(to~)
372 i=GetOneParameter(Parameter,i,JudgeNum);
373
374 //第3パラメータを取得(step~)
375 if(Parameter[i]){
376 i=GetOneParameter(Parameter,i,StepNum);
377 if(Parameter[i]) SetError(12,"For",cp);
378 }
379 else lstrcpy(StepNum,"1");
380
381 //カウンタを増加させる
382 sprintf(temporary,"%s=(%s)+(%s)",variable,variable,StepNum);
383 OpcodeCalc(temporary);
384
[242]385 compiler.codeGenerator.opfix_JmpPertialSchedule( pTempPertialSchedule );
[3]386
387 //増加か減少かを区別する
388 sprintf(temporary,"(%s)>=0",StepNum);
389
[75]390 int reg;
[3]391 reg=REG_RAX;
[75]392 if( !NumOpe(&reg,temporary,Type(),resultType) ){
393 return;
394 }
[3]395
396 //cmp rax,0
[226]397 compiler.codeGenerator.op_cmp_value(resultType.GetSize(),REG_RAX,0);
[3]398
399 //je [カウンタ減少の場合の判定]
[242]400 pTempPertialSchedule = compiler.codeGenerator.op_je( 0, sizeof(long), true );
[3]401
402 //判定(カウンタ増加の場合)
403 sprintf(temporary,"%s<=(%s)",variable,JudgeNum);
404
405 reg=REG_RAX;
[75]406 NumOpe(&reg,temporary,Type(),Type());
[3]407
408 //jmp [カウンタ減少の場合の判定を飛び越す]
[242]409 CodeGenerator::PertialSchedule *pTempPertialSchedule2 = compiler.codeGenerator.op_jmp( 0, sizeof(long), true );
[3]410
[242]411 //jeジャンプ先のオフセット値
412 compiler.codeGenerator.opfix_JmpPertialSchedule( pTempPertialSchedule );
[3]413
414 //判定(カウンタ減少の場合)
415 sprintf(temporary,"%s>=(%s)",variable,JudgeNum);
416
417 reg=REG_RAX;
[75]418 NumOpe(&reg,temporary,Type(),resultType);
[3]419
[242]420 //jmpジャンプ先のオフセット値
421 compiler.codeGenerator.opfix_JmpPertialSchedule( pTempPertialSchedule2 );
[3]422
423 //cmp rax,0
[226]424 compiler.codeGenerator.op_cmp_value(resultType.GetSize(),REG_RAX,0);
[3]425
426ErrorStep:
427
428 //je ...
[242]429 pTempPertialSchedule = compiler.codeGenerator.op_je( 0, sizeof(long), true );
[3]430
431 //レキシカルスコープをレベルアップ
[183]432 GetLexicalScopes().Start( obp, SCOPE_TYPE_FOR );
[3]433
434 //For内をコンパイル
435 CompileBuffer(0,COM_NEXT);
436
[183]437 GetLexicalScopes().CallDestructorsOfScopeEnd();
[3]438
439 if(szNextVariable[0]){
440 if(lstrcmp(szNextVariable,variable)!=0){
441 SetError(55,szNextVariable,cp);
442 }
443 }
444
445 //jmp ...
[242]446 compiler.codeGenerator.op_jmp_continue();
[3]447
448 //レキシカルスコープをレベルダウン
[183]449 GetLexicalScopes().End();
[3]450
[242]451 //jeジャンプ先のオフセット値
452 compiler.codeGenerator.opfix_JmpPertialSchedule( pTempPertialSchedule );
[3]453
454 //Continueアドレスを復元
[242]455 compiler.codeGenerator.ContinueAreaEnd();
[3]456}
457
458void OpcodeDo(char *Parameter){
459 extern HANDLE hHeap;
460 int i,i2,i3;
461
462 if(Parameter[0]) SetError(10,"Do",cp);
463
464 //Continueアドレスのバックアップとセット
[242]465 compiler.codeGenerator.ContinueAreaBegin();
[3]466
467 //レキシカルスコープをレベルアップ
[183]468 GetLexicalScopes().Start( obp, SCOPE_TYPE_DO );
[3]469
470 //Do内をコンパイル
471 CompileBuffer(0,COM_LOOP);
472
[183]473 GetLexicalScopes().CallDestructorsOfScopeEnd();
[3]474
[242]475 CodeGenerator::PertialSchedule *pDoPertialSchedule = NULL;
476
[3]477 extern char *basbuf;
478 char temporary[VN_SIZE];
479 for(i=cp-1;;i--){
480 if(IsCommandDelimitation(basbuf[i])){
481 i+=3;
482 if(!(basbuf[i]=='0'||basbuf[i]=='1')){
483 //無条件ループ
484 break;
485 }
486 i3=i;
487
488 for(i+=2,i2=0;;i++,i2++){
489 if(IsCommandDelimitation(basbuf[i])){
490 temporary[i2]=0;
491 break;
492 }
493 temporary[i2]=basbuf[i];
494 }
495
496 //条件式を実行してフラグをセット
497 Judgment(temporary);
498
499 if(basbuf[i3]=='0'){
500 //While
501
502 //je 5(ループ終了)
[242]503 pDoPertialSchedule = compiler.codeGenerator.op_je( 0, sizeof(char), true );
[3]504 }
505 else if(basbuf[i3]=='1'){
506 //Until
507
508 //jne 5(ループ終了)
[242]509 pDoPertialSchedule = compiler.codeGenerator.op_jne( 0, sizeof(char), true );
[3]510 }
511 break;
512 }
513 }
514
515 //jmp ...
[242]516 compiler.codeGenerator.op_jmp_continue();
[3]517
[242]518 if( pDoPertialSchedule )
519 {
520 compiler.codeGenerator.opfix_JmpPertialSchedule( pDoPertialSchedule );
521 }
522
[3]523 //jmp ...
[243]524 CodeGenerator::PertialSchedule *pTempPertialSchedule = compiler.codeGenerator.op_jmp( 0, sizeof(long), true );
[3]525
526 //レキシカルスコープをレベルダウン
[183]527 GetLexicalScopes().End();
[3]528
[243]529 //jmpジャンプ先のオフセット値
530 compiler.codeGenerator.opfix_JmpPertialSchedule( pTempPertialSchedule );
[3]531
532 //Continueアドレスを復元
[242]533 compiler.codeGenerator.ContinueAreaEnd();
[3]534}
535void OpcodeContinue(void){
536 //jmp ...(Continue addr)
[242]537 compiler.codeGenerator.op_jmp_continue();
[3]538}
539
540void OpcodeExitSub(void){
541 extern DWORD *pExitSubSchedule;
542 extern int ExitSubScheduleNum;
543 extern HANDLE hHeap;
544
[75]545 if( UserProc::IsGlobalAreaCompiling() ){
[3]546 SetError(12,"Exit Sub/Function",cp);
547 return;
548 }
549
[34]550 //未解放のローカルオブジェクトのデストラクタを呼び出す
[183]551 GetLexicalScopes().CallDestructorsOfReturn();
[34]552
[3]553 //jmp ...(End Sub/Function)
554 OpBuffer[obp++]=(char)0xE9;
555
556 pExitSubSchedule=(DWORD *)HeapReAlloc(hHeap,0,pExitSubSchedule,(ExitSubScheduleNum+1)*sizeof(DWORD));
557 pExitSubSchedule[ExitSubScheduleNum]=obp;
558 ExitSubScheduleNum++;
559
560 obp+=sizeof(long);
561}
562
563void AddCaseSchedule(void){
564 extern DWORD *pCaseSchedule;
565 extern int CaseScheduleNum;
566 extern HANDLE hHeap;
567
568 pCaseSchedule=(DWORD *)HeapReAlloc(hHeap,0,pCaseSchedule,(CaseScheduleNum+1)*sizeof(DWORD));
569 pCaseSchedule[CaseScheduleNum]=obp;
570 CaseScheduleNum++;
571}
[75]572void OpcodeSelect( const char *lpszParms ){
[3]573 extern DWORD *pCaseSchedule;
574 extern int CaseScheduleNum;
575 extern int NowCaseSchedule;
576 extern HANDLE hHeap;
577 extern char *basbuf;
578 int i,i2,i3,NowCaseCp;
579 char temporary[VN_SIZE];
580
581 DWORD *temp_pCaseSchedule;
582 int temp_CaseScheduleNum;
583 int temp_NowCaseSchedule;
584
585 temp_pCaseSchedule=pCaseSchedule;
586 temp_CaseScheduleNum=CaseScheduleNum;
587 temp_NowCaseSchedule=NowCaseSchedule;
588 pCaseSchedule=(DWORD *)HeapAlloc(hHeap,0,1);
589 CaseScheduleNum=0;
590 NowCaseSchedule=0;
591
[75]592 int reg1=REG_RAX;
593 Type type1;
594 if( !NumOpe(&reg1,lpszParms,Type(), type1 ) ){
595 return;
596 }
[3]597
[75]598 if(type1.IsDouble()){
[3]599 //movsd qword ptr[rsp+offset],xmm_reg ※スタックフレームを利用
600 pobj_sf->push(reg1,sizeof(double));
601 }
[75]602 else if(type1.IsSingle()){
[3]603 //movss dword ptr[rsp+offset],xmm_reg ※スタックフレームを利用
604 pobj_sf->push(reg1,sizeof(float));
605 }
606 else{
[75]607 ExtendTypeTo64(type1.GetBasicType(),reg1);
[3]608
609 //mov qword ptr[rsp+offset],reg ※スタックフレームを利用
610 pobj_sf->push(reg1);
611 }
612
613 for(i=cp;;i++){
614 if(basbuf[i]=='\0'){
615 HeapDefaultFree(pCaseSchedule);
616 pCaseSchedule=temp_pCaseSchedule;
617 CaseScheduleNum=temp_CaseScheduleNum;
618 NowCaseSchedule=temp_NowCaseSchedule;
619 SetError(22,"Select",cp);
620 return;
621 }
622 if(basbuf[i]==1&&basbuf[i+1]==ESC_SELECTCASE){
623 for(i2=0;;i++){
624 if(basbuf[i]==1&&basbuf[i+1]==ESC_SELECTCASE) i2++;
625 if(basbuf[i]==1&&basbuf[i+1]==ESC_ENDSELECT){
626 i2--;
627 if(i2==0) break;
628 }
629 }
630 continue;
631 }
632 if(basbuf[i]==1&&basbuf[i+1]==ESC_ENDSELECT) break;
633
634 if(basbuf[i]==1&&basbuf[i+1]==ESC_CASE){
635 NowCaseCp=i;
636
637 i++;
638 while(1){
639 for(i++,i2=0;;i++,i2++){
640 if(basbuf[i]=='\"'){
641 i3=GetStringInQuotation(temporary+i2,basbuf+i);
642 i+=i3-1;
643 i2+=i3-1;
644 continue;
645 }
646 if(basbuf[i]=='('){
647 i3=GetStringInPare(temporary+i2,basbuf+i);
648 i+=i3-1;
649 i2+=i3-1;
650 continue;
651 }
652 if(basbuf[i]=='['){
653 i3=GetStringInBracket(temporary+i2,basbuf+i);
654 i+=i3-1;
655 i2+=i3-1;
656 continue;
657 }
658
659 if(IsCommandDelimitation(basbuf[i])){
660 temporary[i2]=0;
661 break;
662 }
663 if(basbuf[i]==','){
664 temporary[i2]=0;
665 break;
666 }
667
668 temporary[i2]=basbuf[i];
669 }
670
671 //エラー用
672 i2=cp;
673 cp=NowCaseCp;
674
[75]675 int reg2=REG_RDX;
676 Type type2;
677 if( !NumOpe(&reg2,temporary,type1,type2) ){
678 return;
679 }
[3]680
681 cp=i2;
682
[75]683 if(type1.IsObject()){
[206]684 std::vector<const UserProc *> subs;
[135]685 type1.GetClass().GetMethods().Enum( CALC_EQUAL, subs );
[50]686 if( subs.size() == 0 ){
[3]687 return;
688 }
689
[75]690 Parameters params;
691 params.push_back( new Parameter( "", Type( type2 ) ) );
[3]692
693 //オーバーロードを解決
[206]694 const UserProc *pUserProc = OverloadSolution("==",subs, params, NULL);
[3]695
[75]696 delete params[0];
697
698 if(!pUserProc){
[3]699 //エラー
700 return;
701 }
702
703
704 //実体オブジェクト
705 if(reg2!=REG_RDX){
706 //mov rdx,reg2
[226]707 compiler.codeGenerator.op_mov_RR(REG_RDX,reg2);
[3]708 }
709
710 //mov rcx,qword ptr[rsp+offset] ※スタックフレームから参照
711 pobj_sf->ref(REG_RCX);
712
713 //call operator_proc ※ ==演算子
[226]714 compiler.codeGenerator.op_call(pUserProc);
[3]715
716 //test rax,rax
[226]717 compiler.codeGenerator.op_test(REG_RAX,REG_RAX);
[3]718
719 //jne ...
720 OpBuffer[obp++]=(char)0x0F;
721 OpBuffer[obp++]=(char)0x85;
722 }
723 else{
[75]724 if(type1.IsDouble()){
[3]725 int xmm_reg;
726 if(IsXmmReg(reg2)) xmm_reg=reg2;
727 else xmm_reg=REG_XMM5;
[75]728 ChangeTypeToXmm_Double(type2.GetBasicType(),xmm_reg,reg2);
[3]729
730 //movsd xmm4,qword ptr[rsp+offset] ※スタックフレームから参照
731 pobj_sf->ref(REG_XMM4,sizeof(double));
732
733 //comiss xmm_reg1,xmm_reg2
[226]734 compiler.codeGenerator.op_comisd(xmm_reg,REG_XMM4);
[3]735 }
[75]736 else if(type1.IsSingle()){
[3]737 int xmm_reg;
738 if(IsXmmReg(reg2)) xmm_reg=reg2;
739 else xmm_reg=REG_XMM5;
[75]740 ChangeTypeToXmm_Single(type2.GetBasicType(),xmm_reg,reg2);
[3]741
742 //movss xmm4,dword ptr[rsp+offset] ※スタックフレームから参照
743 pobj_sf->ref(REG_XMM4,sizeof(float));
744
745 //comiss xmm_reg1,xmm_reg2
[226]746 compiler.codeGenerator.op_comiss(xmm_reg,REG_XMM4);
[3]747 }
748 else{
749 //その他整数型
750
[75]751 i2=NeutralizationType(type1.GetBasicType(),-1,type2.GetBasicType(),-1);
[3]752
753 //mov r14,qword ptr[rsp+offset] ※スタックフレームから参照
754 pobj_sf->ref(REG_R14);
755
756 //cmp reg2,r14
[226]757 compiler.codeGenerator.op_cmp_reg(GetTypeSize(i2,-1),reg2,REG_R14);
[3]758 }
759
760 //je ...
761 OpBuffer[obp++]=(char)0x0F;
762 OpBuffer[obp++]=(char)0x84;
763 }
764 AddCaseSchedule();
765 obp+=sizeof(long);
766
767 if(basbuf[i]!=',') break;
768 }
769 }
770 if(basbuf[i]==1&&basbuf[i+1]==ESC_CASEELSE){
771 //jmp ...
772 OpBuffer[obp++]=(char)0xE9;
773 AddCaseSchedule();
774 obp+=sizeof(long);
775 }
776 }
777
778 //スタックフレームを1スペースだけ解除
779 pobj_sf->pop(REG_NON);
780
781 //レキシカルスコープをレベルアップ
[183]782 GetLexicalScopes().Start( obp, SCOPE_TYPE_SELECT );
[3]783
784 //Select Case内をコンパイル
785 CompileBuffer(ESC_ENDSELECT,0);
786
787 //jmp EndSelect
788 OpBuffer[obp++]=(char)0xE9;
789 AddCaseSchedule();
790 obp+=sizeof(long);
791
792 //最終スケジュール
793 for(i=NowCaseSchedule;i<CaseScheduleNum;i++){
794 *(long *)(OpBuffer+pCaseSchedule[i])=obp-(pCaseSchedule[i]+sizeof(long));
795 }
796 HeapDefaultFree(pCaseSchedule);
797
798 //レキシカルスコープをレベルダウン
[183]799 GetLexicalScopes().End();
[3]800
801 pCaseSchedule=temp_pCaseSchedule;
802 CaseScheduleNum=temp_CaseScheduleNum;
803 NowCaseSchedule=temp_NowCaseSchedule;
804}
805void OpcodeCase(char *Parameter){
806 extern DWORD *pCaseSchedule;
807 extern int NowCaseSchedule;
808 int i;
809
810 if(!pCaseSchedule){
811 SetError(30,"Case",cp);
812 return;
813 }
814
815 //jmp EndSelect
816 OpBuffer[obp++]=(char)0xE9;
817 AddCaseSchedule();
818 obp+=sizeof(long);
819
820 i=0;
821 while(1){
822 //Caseスケジュール
823 *(long *)(OpBuffer+pCaseSchedule[NowCaseSchedule])=obp-(pCaseSchedule[NowCaseSchedule]+sizeof(long));
824 NowCaseSchedule++;
825
826 i=JumpOneParameter(Parameter,i);
827 if(Parameter[i]=='\0') break;
828 }
829}
830
831void OpcodeGosub(char *Parameter){
832 extern HANDLE hHeap;
833 extern GOTOLABELSCHEDULE *pGotoLabelSchedule;
834 extern int GotoLabelScheduleNum;
835 int i,LineNum;
836
837 //call _System_GetEip
[206]838 extern const UserProc *pSub_System_GetEip;
[226]839 compiler.codeGenerator.op_call(pSub_System_GetEip);
[3]840
841 //add rax,offset(Gosubステートメントの最終ポイント)
842 int schedule=obp,schedule2;
[226]843 compiler.codeGenerator.op_add_RV(REG_RAX,0);
[3]844 schedule2=obp-sizeof(long);
845
846 //※戻り先用のrip
847 //mov qword ptr[rsp+offset],rax ※スタックフレームを利用
848 pobj_sf->push(REG_RAX);
849
850
851 if(Parameter[0]=='*'){
852 i=GetLabelAddress(Parameter+1,0);
853
854 //jmp ...
855 OpBuffer[obp++]=(char)0xE9;
856 if(i==-1){
857 pGotoLabelSchedule=(GOTOLABELSCHEDULE *)HeapReAlloc(hHeap,0,pGotoLabelSchedule,(GotoLabelScheduleNum+1)*sizeof(GOTOLABELSCHEDULE));
858 pGotoLabelSchedule[GotoLabelScheduleNum].pName=(char *)HeapAlloc(hHeap,0,lstrlen(Parameter+1)+1);
859 lstrcpy(pGotoLabelSchedule[GotoLabelScheduleNum].pName,Parameter+1);
860 pGotoLabelSchedule[GotoLabelScheduleNum].pos=obp;
861 pGotoLabelSchedule[GotoLabelScheduleNum].now_cp=cp;
862 GotoLabelScheduleNum++;
863 }
864 *((long *)(OpBuffer+obp))=i-(obp+sizeof(long));
865 obp+=sizeof(long);
866 }
867 else{
868 LineNum=atoi(Parameter);
869 i=GetLabelAddress(0,LineNum);
870
871 //jmp ...
872 OpBuffer[obp++]=(char)0xE9;
873 if(i==-1){
874 pGotoLabelSchedule=(GOTOLABELSCHEDULE *)HeapReAlloc(hHeap,0,pGotoLabelSchedule,(GotoLabelScheduleNum+1)*sizeof(GOTOLABELSCHEDULE));
875 pGotoLabelSchedule[GotoLabelScheduleNum].pName=0;
876 pGotoLabelSchedule[GotoLabelScheduleNum].line=LineNum;
877 pGotoLabelSchedule[GotoLabelScheduleNum].pos=obp;
878 pGotoLabelSchedule[GotoLabelScheduleNum].now_cp=cp;
879 GotoLabelScheduleNum++;
880 }
881 *((long *)(OpBuffer+obp))=i-(obp+sizeof(long));
882 obp+=sizeof(long);
883 }
884
885 *((long *)(OpBuffer+schedule2))=obp-schedule;
886
887 //※スタックフレームを元に戻す
888 pobj_sf->pop(REG_NON);
889
890 SetError(-1,"Gosub ~ Returnステートメントは64ビットコンパイラで利用することはできません。",cp);
891}
892void OpcodeReturn(char *Parameter){
[75]893 if( UserProc::IsGlobalAreaCompiling() ){
[34]894 SetError(62,NULL,cp);
[3]895 }
896 else{
897 //戻り値をセット
898 if(Parameter[0]){
[206]899 const UserProc &proc = UserProc::CompilingUserProc();
[3]900
[75]901 const char *temp = "_System_ReturnValue";
902 if(proc.GetName()[0]==1&&proc.GetName()[1]==ESC_OPERATOR)
903 {
[40]904 }
905 else{
[75]906 temp=proc.GetName().c_str();
907 }
908
909 char temporary[VN_SIZE];
910 sprintf(temporary,"%s=%s",temp,Parameter);
911 OpcodeCalc(temporary);
[3]912 }
913
914 //プロシージャを抜け出す(C言語のreturnと同様の処理を行う)
915 OpcodeExitSub();
916 }
917}
918
919
920////////////
921// ポインタ
922////////////
923
924void OpcodeSetPtrData(char *Parameter,int type){
[75]925 int i;
[3]926 char temporary[VN_SIZE];
927
928 if(Parameter[0]=='('){
929 i=JumpStringInPare(Parameter,1);
930 if(Parameter[i+1]=='\0'){
931 for(i=0;;i++){
932 Parameter[i]=Parameter[i+1];
933 if(Parameter[i]=='\0') break;
934 }
935 Parameter[i-1]=0;
936 }
937 }
938
939 //第1パラメータを取得
940 i=GetOneParameter(Parameter,0,temporary);
941 if(!Parameter[i]){
942 SetError(1,NULL,cp);
943 return;
944 }
945
946 int reg_ptr=REG_RAX;
[75]947 Type resultType;
948 if( !NumOpe(&reg_ptr,temporary,Type(),resultType) ){
949 return;
950 }
951 if(!resultType.IsWhole()){
[3]952 SetError(11,Parameter,cp);
953 return;
954 }
955
956 //結果を格納しているレジスタをブロッキング
957 pobj_BlockReg->lock(reg_ptr);
958
959 //第2パラメータを取得
960 i=GetOneParameter(Parameter,i,temporary);
961 if(Parameter[i]){
962 SetError(1,NULL,cp);
963 return;
964 }
965
966 int temp_reg=REG_NON;
[75]967 if( !NumOpe(&temp_reg,temporary,Type(),resultType) ){
968 return;
969 }
[3]970
971 //レジスタのブロッキングを解除
972 pobj_BlockReg->clear();
973
974 if(type==DEF_DOUBLE){
[75]975 ChangeTypeToXmm_Double(resultType.GetBasicType(),REG_XMM0,temp_reg);
[3]976
977 //movsd qword ptr[reg_ptr],xmm0
[226]978 compiler.codeGenerator.op_movsd_MR(REG_XMM0,reg_ptr,0,MOD_BASE);
[3]979 }
980 else if(type==DEF_SINGLE){
[75]981 ChangeTypeToXmm_Single(resultType.GetBasicType(),REG_XMM0,temp_reg);
[3]982
983 //movss dword ptr[reg_ptr],xmm0
[226]984 compiler.codeGenerator.op_movss_MR(REG_XMM0,reg_ptr,0,MOD_BASE);
[3]985 }
986 else{
[75]987 ChangeTypeToWhole(resultType.GetBasicType(),type,REG_RCX,temp_reg);
[3]988
989 //mov ptr[reg_ptr],rcx
[226]990 compiler.codeGenerator.op_mov_MR(GetTypeSize(type,-1),REG_RCX,reg_ptr,0,MOD_BASE);
[3]991 }
992}
Note: See TracBrowser for help on using the repository browser.