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

Last change on this file since 242 was 242, 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 ...
524 OpBuffer[obp++]=(char)0xE9;
525 int je_schedule=obp;
526 obp+=sizeof(long);
527
528 //レキシカルスコープをレベルダウン
[183]529 GetLexicalScopes().End();
[3]530
531 *((long *)(OpBuffer+je_schedule))=obp-(je_schedule+sizeof(long)); //jmpジャンプ先のオフセット値
532
533 //Continueアドレスを復元
[242]534 compiler.codeGenerator.ContinueAreaEnd();
[3]535}
536void OpcodeContinue(void){
537 //jmp ...(Continue addr)
[242]538 compiler.codeGenerator.op_jmp_continue();
[3]539}
540
541void OpcodeExitSub(void){
542 extern DWORD *pExitSubSchedule;
543 extern int ExitSubScheduleNum;
544 extern HANDLE hHeap;
545
[75]546 if( UserProc::IsGlobalAreaCompiling() ){
[3]547 SetError(12,"Exit Sub/Function",cp);
548 return;
549 }
550
[34]551 //未解放のローカルオブジェクトのデストラクタを呼び出す
[183]552 GetLexicalScopes().CallDestructorsOfReturn();
[34]553
[3]554 //jmp ...(End Sub/Function)
555 OpBuffer[obp++]=(char)0xE9;
556
557 pExitSubSchedule=(DWORD *)HeapReAlloc(hHeap,0,pExitSubSchedule,(ExitSubScheduleNum+1)*sizeof(DWORD));
558 pExitSubSchedule[ExitSubScheduleNum]=obp;
559 ExitSubScheduleNum++;
560
561 obp+=sizeof(long);
562}
563
564void AddCaseSchedule(void){
565 extern DWORD *pCaseSchedule;
566 extern int CaseScheduleNum;
567 extern HANDLE hHeap;
568
569 pCaseSchedule=(DWORD *)HeapReAlloc(hHeap,0,pCaseSchedule,(CaseScheduleNum+1)*sizeof(DWORD));
570 pCaseSchedule[CaseScheduleNum]=obp;
571 CaseScheduleNum++;
572}
[75]573void OpcodeSelect( const char *lpszParms ){
[3]574 extern DWORD *pCaseSchedule;
575 extern int CaseScheduleNum;
576 extern int NowCaseSchedule;
577 extern HANDLE hHeap;
578 extern char *basbuf;
579 int i,i2,i3,NowCaseCp;
580 char temporary[VN_SIZE];
581
582 DWORD *temp_pCaseSchedule;
583 int temp_CaseScheduleNum;
584 int temp_NowCaseSchedule;
585
586 temp_pCaseSchedule=pCaseSchedule;
587 temp_CaseScheduleNum=CaseScheduleNum;
588 temp_NowCaseSchedule=NowCaseSchedule;
589 pCaseSchedule=(DWORD *)HeapAlloc(hHeap,0,1);
590 CaseScheduleNum=0;
591 NowCaseSchedule=0;
592
[75]593 int reg1=REG_RAX;
594 Type type1;
595 if( !NumOpe(&reg1,lpszParms,Type(), type1 ) ){
596 return;
597 }
[3]598
[75]599 if(type1.IsDouble()){
[3]600 //movsd qword ptr[rsp+offset],xmm_reg ※スタックフレームを利用
601 pobj_sf->push(reg1,sizeof(double));
602 }
[75]603 else if(type1.IsSingle()){
[3]604 //movss dword ptr[rsp+offset],xmm_reg ※スタックフレームを利用
605 pobj_sf->push(reg1,sizeof(float));
606 }
607 else{
[75]608 ExtendTypeTo64(type1.GetBasicType(),reg1);
[3]609
610 //mov qword ptr[rsp+offset],reg ※スタックフレームを利用
611 pobj_sf->push(reg1);
612 }
613
614 for(i=cp;;i++){
615 if(basbuf[i]=='\0'){
616 HeapDefaultFree(pCaseSchedule);
617 pCaseSchedule=temp_pCaseSchedule;
618 CaseScheduleNum=temp_CaseScheduleNum;
619 NowCaseSchedule=temp_NowCaseSchedule;
620 SetError(22,"Select",cp);
621 return;
622 }
623 if(basbuf[i]==1&&basbuf[i+1]==ESC_SELECTCASE){
624 for(i2=0;;i++){
625 if(basbuf[i]==1&&basbuf[i+1]==ESC_SELECTCASE) i2++;
626 if(basbuf[i]==1&&basbuf[i+1]==ESC_ENDSELECT){
627 i2--;
628 if(i2==0) break;
629 }
630 }
631 continue;
632 }
633 if(basbuf[i]==1&&basbuf[i+1]==ESC_ENDSELECT) break;
634
635 if(basbuf[i]==1&&basbuf[i+1]==ESC_CASE){
636 NowCaseCp=i;
637
638 i++;
639 while(1){
640 for(i++,i2=0;;i++,i2++){
641 if(basbuf[i]=='\"'){
642 i3=GetStringInQuotation(temporary+i2,basbuf+i);
643 i+=i3-1;
644 i2+=i3-1;
645 continue;
646 }
647 if(basbuf[i]=='('){
648 i3=GetStringInPare(temporary+i2,basbuf+i);
649 i+=i3-1;
650 i2+=i3-1;
651 continue;
652 }
653 if(basbuf[i]=='['){
654 i3=GetStringInBracket(temporary+i2,basbuf+i);
655 i+=i3-1;
656 i2+=i3-1;
657 continue;
658 }
659
660 if(IsCommandDelimitation(basbuf[i])){
661 temporary[i2]=0;
662 break;
663 }
664 if(basbuf[i]==','){
665 temporary[i2]=0;
666 break;
667 }
668
669 temporary[i2]=basbuf[i];
670 }
671
672 //エラー用
673 i2=cp;
674 cp=NowCaseCp;
675
[75]676 int reg2=REG_RDX;
677 Type type2;
678 if( !NumOpe(&reg2,temporary,type1,type2) ){
679 return;
680 }
[3]681
682 cp=i2;
683
[75]684 if(type1.IsObject()){
[206]685 std::vector<const UserProc *> subs;
[135]686 type1.GetClass().GetMethods().Enum( CALC_EQUAL, subs );
[50]687 if( subs.size() == 0 ){
[3]688 return;
689 }
690
[75]691 Parameters params;
692 params.push_back( new Parameter( "", Type( type2 ) ) );
[3]693
694 //オーバーロードを解決
[206]695 const UserProc *pUserProc = OverloadSolution("==",subs, params, NULL);
[3]696
[75]697 delete params[0];
698
699 if(!pUserProc){
[3]700 //エラー
701 return;
702 }
703
704
705 //実体オブジェクト
706 if(reg2!=REG_RDX){
707 //mov rdx,reg2
[226]708 compiler.codeGenerator.op_mov_RR(REG_RDX,reg2);
[3]709 }
710
711 //mov rcx,qword ptr[rsp+offset] ※スタックフレームから参照
712 pobj_sf->ref(REG_RCX);
713
714 //call operator_proc ※ ==演算子
[226]715 compiler.codeGenerator.op_call(pUserProc);
[3]716
717 //test rax,rax
[226]718 compiler.codeGenerator.op_test(REG_RAX,REG_RAX);
[3]719
720 //jne ...
721 OpBuffer[obp++]=(char)0x0F;
722 OpBuffer[obp++]=(char)0x85;
723 }
724 else{
[75]725 if(type1.IsDouble()){
[3]726 int xmm_reg;
727 if(IsXmmReg(reg2)) xmm_reg=reg2;
728 else xmm_reg=REG_XMM5;
[75]729 ChangeTypeToXmm_Double(type2.GetBasicType(),xmm_reg,reg2);
[3]730
731 //movsd xmm4,qword ptr[rsp+offset] ※スタックフレームから参照
732 pobj_sf->ref(REG_XMM4,sizeof(double));
733
734 //comiss xmm_reg1,xmm_reg2
[226]735 compiler.codeGenerator.op_comisd(xmm_reg,REG_XMM4);
[3]736 }
[75]737 else if(type1.IsSingle()){
[3]738 int xmm_reg;
739 if(IsXmmReg(reg2)) xmm_reg=reg2;
740 else xmm_reg=REG_XMM5;
[75]741 ChangeTypeToXmm_Single(type2.GetBasicType(),xmm_reg,reg2);
[3]742
743 //movss xmm4,dword ptr[rsp+offset] ※スタックフレームから参照
744 pobj_sf->ref(REG_XMM4,sizeof(float));
745
746 //comiss xmm_reg1,xmm_reg2
[226]747 compiler.codeGenerator.op_comiss(xmm_reg,REG_XMM4);
[3]748 }
749 else{
750 //その他整数型
751
[75]752 i2=NeutralizationType(type1.GetBasicType(),-1,type2.GetBasicType(),-1);
[3]753
754 //mov r14,qword ptr[rsp+offset] ※スタックフレームから参照
755 pobj_sf->ref(REG_R14);
756
757 //cmp reg2,r14
[226]758 compiler.codeGenerator.op_cmp_reg(GetTypeSize(i2,-1),reg2,REG_R14);
[3]759 }
760
761 //je ...
762 OpBuffer[obp++]=(char)0x0F;
763 OpBuffer[obp++]=(char)0x84;
764 }
765 AddCaseSchedule();
766 obp+=sizeof(long);
767
768 if(basbuf[i]!=',') break;
769 }
770 }
771 if(basbuf[i]==1&&basbuf[i+1]==ESC_CASEELSE){
772 //jmp ...
773 OpBuffer[obp++]=(char)0xE9;
774 AddCaseSchedule();
775 obp+=sizeof(long);
776 }
777 }
778
779 //スタックフレームを1スペースだけ解除
780 pobj_sf->pop(REG_NON);
781
782 //レキシカルスコープをレベルアップ
[183]783 GetLexicalScopes().Start( obp, SCOPE_TYPE_SELECT );
[3]784
785 //Select Case内をコンパイル
786 CompileBuffer(ESC_ENDSELECT,0);
787
788 //jmp EndSelect
789 OpBuffer[obp++]=(char)0xE9;
790 AddCaseSchedule();
791 obp+=sizeof(long);
792
793 //最終スケジュール
794 for(i=NowCaseSchedule;i<CaseScheduleNum;i++){
795 *(long *)(OpBuffer+pCaseSchedule[i])=obp-(pCaseSchedule[i]+sizeof(long));
796 }
797 HeapDefaultFree(pCaseSchedule);
798
799 //レキシカルスコープをレベルダウン
[183]800 GetLexicalScopes().End();
[3]801
802 pCaseSchedule=temp_pCaseSchedule;
803 CaseScheduleNum=temp_CaseScheduleNum;
804 NowCaseSchedule=temp_NowCaseSchedule;
805}
806void OpcodeCase(char *Parameter){
807 extern DWORD *pCaseSchedule;
808 extern int NowCaseSchedule;
809 int i;
810
811 if(!pCaseSchedule){
812 SetError(30,"Case",cp);
813 return;
814 }
815
816 //jmp EndSelect
817 OpBuffer[obp++]=(char)0xE9;
818 AddCaseSchedule();
819 obp+=sizeof(long);
820
821 i=0;
822 while(1){
823 //Caseスケジュール
824 *(long *)(OpBuffer+pCaseSchedule[NowCaseSchedule])=obp-(pCaseSchedule[NowCaseSchedule]+sizeof(long));
825 NowCaseSchedule++;
826
827 i=JumpOneParameter(Parameter,i);
828 if(Parameter[i]=='\0') break;
829 }
830}
831
832void OpcodeGosub(char *Parameter){
833 extern HANDLE hHeap;
834 extern GOTOLABELSCHEDULE *pGotoLabelSchedule;
835 extern int GotoLabelScheduleNum;
836 int i,LineNum;
837
838 //call _System_GetEip
[206]839 extern const UserProc *pSub_System_GetEip;
[226]840 compiler.codeGenerator.op_call(pSub_System_GetEip);
[3]841
842 //add rax,offset(Gosubステートメントの最終ポイント)
843 int schedule=obp,schedule2;
[226]844 compiler.codeGenerator.op_add_RV(REG_RAX,0);
[3]845 schedule2=obp-sizeof(long);
846
847 //※戻り先用のrip
848 //mov qword ptr[rsp+offset],rax ※スタックフレームを利用
849 pobj_sf->push(REG_RAX);
850
851
852 if(Parameter[0]=='*'){
853 i=GetLabelAddress(Parameter+1,0);
854
855 //jmp ...
856 OpBuffer[obp++]=(char)0xE9;
857 if(i==-1){
858 pGotoLabelSchedule=(GOTOLABELSCHEDULE *)HeapReAlloc(hHeap,0,pGotoLabelSchedule,(GotoLabelScheduleNum+1)*sizeof(GOTOLABELSCHEDULE));
859 pGotoLabelSchedule[GotoLabelScheduleNum].pName=(char *)HeapAlloc(hHeap,0,lstrlen(Parameter+1)+1);
860 lstrcpy(pGotoLabelSchedule[GotoLabelScheduleNum].pName,Parameter+1);
861 pGotoLabelSchedule[GotoLabelScheduleNum].pos=obp;
862 pGotoLabelSchedule[GotoLabelScheduleNum].now_cp=cp;
863 GotoLabelScheduleNum++;
864 }
865 *((long *)(OpBuffer+obp))=i-(obp+sizeof(long));
866 obp+=sizeof(long);
867 }
868 else{
869 LineNum=atoi(Parameter);
870 i=GetLabelAddress(0,LineNum);
871
872 //jmp ...
873 OpBuffer[obp++]=(char)0xE9;
874 if(i==-1){
875 pGotoLabelSchedule=(GOTOLABELSCHEDULE *)HeapReAlloc(hHeap,0,pGotoLabelSchedule,(GotoLabelScheduleNum+1)*sizeof(GOTOLABELSCHEDULE));
876 pGotoLabelSchedule[GotoLabelScheduleNum].pName=0;
877 pGotoLabelSchedule[GotoLabelScheduleNum].line=LineNum;
878 pGotoLabelSchedule[GotoLabelScheduleNum].pos=obp;
879 pGotoLabelSchedule[GotoLabelScheduleNum].now_cp=cp;
880 GotoLabelScheduleNum++;
881 }
882 *((long *)(OpBuffer+obp))=i-(obp+sizeof(long));
883 obp+=sizeof(long);
884 }
885
886 *((long *)(OpBuffer+schedule2))=obp-schedule;
887
888 //※スタックフレームを元に戻す
889 pobj_sf->pop(REG_NON);
890
891 SetError(-1,"Gosub ~ Returnステートメントは64ビットコンパイラで利用することはできません。",cp);
892}
893void OpcodeReturn(char *Parameter){
[75]894 if( UserProc::IsGlobalAreaCompiling() ){
[34]895 SetError(62,NULL,cp);
[3]896 }
897 else{
898 //戻り値をセット
899 if(Parameter[0]){
[206]900 const UserProc &proc = UserProc::CompilingUserProc();
[3]901
[75]902 const char *temp = "_System_ReturnValue";
903 if(proc.GetName()[0]==1&&proc.GetName()[1]==ESC_OPERATOR)
904 {
[40]905 }
906 else{
[75]907 temp=proc.GetName().c_str();
908 }
909
910 char temporary[VN_SIZE];
911 sprintf(temporary,"%s=%s",temp,Parameter);
912 OpcodeCalc(temporary);
[3]913 }
914
915 //プロシージャを抜け出す(C言語のreturnと同様の処理を行う)
916 OpcodeExitSub();
917 }
918}
919
920
921////////////
922// ポインタ
923////////////
924
925void OpcodeSetPtrData(char *Parameter,int type){
[75]926 int i;
[3]927 char temporary[VN_SIZE];
928
929 if(Parameter[0]=='('){
930 i=JumpStringInPare(Parameter,1);
931 if(Parameter[i+1]=='\0'){
932 for(i=0;;i++){
933 Parameter[i]=Parameter[i+1];
934 if(Parameter[i]=='\0') break;
935 }
936 Parameter[i-1]=0;
937 }
938 }
939
940 //第1パラメータを取得
941 i=GetOneParameter(Parameter,0,temporary);
942 if(!Parameter[i]){
943 SetError(1,NULL,cp);
944 return;
945 }
946
947 int reg_ptr=REG_RAX;
[75]948 Type resultType;
949 if( !NumOpe(&reg_ptr,temporary,Type(),resultType) ){
950 return;
951 }
952 if(!resultType.IsWhole()){
[3]953 SetError(11,Parameter,cp);
954 return;
955 }
956
957 //結果を格納しているレジスタをブロッキング
958 pobj_BlockReg->lock(reg_ptr);
959
960 //第2パラメータを取得
961 i=GetOneParameter(Parameter,i,temporary);
962 if(Parameter[i]){
963 SetError(1,NULL,cp);
964 return;
965 }
966
967 int temp_reg=REG_NON;
[75]968 if( !NumOpe(&temp_reg,temporary,Type(),resultType) ){
969 return;
970 }
[3]971
972 //レジスタのブロッキングを解除
973 pobj_BlockReg->clear();
974
975 if(type==DEF_DOUBLE){
[75]976 ChangeTypeToXmm_Double(resultType.GetBasicType(),REG_XMM0,temp_reg);
[3]977
978 //movsd qword ptr[reg_ptr],xmm0
[226]979 compiler.codeGenerator.op_movsd_MR(REG_XMM0,reg_ptr,0,MOD_BASE);
[3]980 }
981 else if(type==DEF_SINGLE){
[75]982 ChangeTypeToXmm_Single(resultType.GetBasicType(),REG_XMM0,temp_reg);
[3]983
984 //movss dword ptr[reg_ptr],xmm0
[226]985 compiler.codeGenerator.op_movss_MR(REG_XMM0,reg_ptr,0,MOD_BASE);
[3]986 }
987 else{
[75]988 ChangeTypeToWhole(resultType.GetBasicType(),type,REG_RCX,temp_reg);
[3]989
990 //mov ptr[reg_ptr],rcx
[226]991 compiler.codeGenerator.op_mov_MR(GetTypeSize(type,-1),REG_RCX,reg_ptr,0,MOD_BASE);
[3]992 }
993}
Note: See TracBrowser for help on using the repository browser.