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

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

Select Caseに指定された値でエラーが起こったとき、スコープ処理に不具合が生じてしまう問題を修正。

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