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

Last change on this file since 402 was 402, checked in by dai_9181, 16 years ago

UserProc::SetParamsAndReturnTypeメソッドをリファクタリング
LexicalAnalysis.hのインクルードを除去した

File size: 23.3 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 extern HANDLE hHeap;
673 extern char *basbuf;
674 int i,i2,i3,NowCaseCp;
675 char temporary[VN_SIZE];
676
677 int reg1=REG_RAX;
678 Type type1;
679 if( !NumOpe(&reg1,lpszParms,Type(), type1 ) ){
680 return;
681 }
682
683 selectSchedules.push_back( SelectSchedule( type1.GetSize() ) );
684
685 if( selectSchedules.back().typeSize < sizeof(long) ){
686 selectSchedules.back().typeSize = sizeof(long);
687 }
688
689 if(type1.IsDouble()){
690 //movsd qword ptr[rsp+offset],xmm_reg ※スタックフレームを利用
691 pobj_sf->push(reg1,sizeof(double));
692 }
693 else if(type1.IsSingle()){
694 //movss dword ptr[rsp+offset],xmm_reg ※スタックフレームを利用
695 pobj_sf->push(reg1,sizeof(float));
696 }
697 else{
698 ExtendTypeTo64(type1.GetBasicType(),reg1);
699
700 //mov qword ptr[rsp+offset],reg ※スタックフレームを利用
701 pobj_sf->push(reg1);
702 }
703
704 for(i=cp;;i++){
705 if(basbuf[i]=='\0'){
706 selectSchedules.pop_back();
707 SetError(22,"Select",cp);
708 return;
709 }
710 if(basbuf[i]==1&&basbuf[i+1]==ESC_SELECTCASE){
711 for(i2=0;;i++){
712 if(basbuf[i]==1&&basbuf[i+1]==ESC_SELECTCASE) i2++;
713 if(basbuf[i]==1&&basbuf[i+1]==ESC_ENDSELECT){
714 i2--;
715 if(i2==0) break;
716 }
717 }
718 continue;
719 }
720 if(basbuf[i]==1&&basbuf[i+1]==ESC_ENDSELECT) break;
721
722 if(basbuf[i]==1&&basbuf[i+1]==ESC_CASE){
723 NowCaseCp=i;
724
725 i++;
726 while(1){
727 for(i++,i2=0;;i++,i2++){
728 if(basbuf[i]=='\"'){
729 i3=GetStringInQuotation(temporary+i2,basbuf+i);
730 i+=i3-1;
731 i2+=i3-1;
732 continue;
733 }
734 if(basbuf[i]=='('){
735 i3=GetStringInPare(temporary+i2,basbuf+i);
736 i+=i3-1;
737 i2+=i3-1;
738 continue;
739 }
740 if(basbuf[i]=='['){
741 i3=GetStringInBracket(temporary+i2,basbuf+i);
742 i+=i3-1;
743 i2+=i3-1;
744 continue;
745 }
746
747 if(IsCommandDelimitation(basbuf[i])){
748 temporary[i2]=0;
749 break;
750 }
751 if(basbuf[i]==','){
752 temporary[i2]=0;
753 break;
754 }
755
756 temporary[i2]=basbuf[i];
757 }
758
759 //エラー用
760 i2=cp;
761 cp=NowCaseCp;
762
763 int reg2=REG_RDX;
764 Type type2;
765 if( !NumOpe(&reg2,temporary,type1,type2) ){
766 return;
767 }
768
769 cp=i2;
770
771 if(type1.IsObject()){
772 std::vector<const UserProc *> subs;
773 type1.GetClass().GetDynamicMethods().Enum( CALC_EQUAL, subs );
774 if( subs.size() == 0 ){
775 return;
776 }
777
778 Parameters params;
779 params.push_back( new Parameter( "", Type( type2 ) ) );
780
781 //オーバーロードを解決
782 const UserProc *pUserProc = OverloadSolution("==",subs, params, NULL);
783
784 delete params[0];
785
786 if(!pUserProc){
787 //エラー
788 return;
789 }
790
791
792 //実体オブジェクト
793 if(reg2!=REG_RDX){
794 //mov rdx,reg2
795 compiler.codeGenerator.op_mov_RR(REG_RDX,reg2);
796 }
797
798 //mov rcx,qword ptr[rsp+offset] ※スタックフレームから参照
799 pobj_sf->ref(REG_RCX);
800
801 //call operator_proc ※ ==演算子
802 compiler.codeGenerator.op_call(pUserProc);
803
804 //test rax,rax
805 compiler.codeGenerator.op_test(REG_RAX,REG_RAX);
806
807 //jne ...
808 selectSchedules.back().casePertialSchedules.push_back(
809 compiler.codeGenerator.op_jne( 0, sizeof(long), true )
810 );
811 }
812 else{
813 if(type1.IsDouble()){
814 int xmm_reg;
815 if(IsXmmReg(reg2)) xmm_reg=reg2;
816 else xmm_reg=REG_XMM5;
817 ChangeTypeToXmm_Double(type2.GetBasicType(),xmm_reg,reg2);
818
819 //movsd xmm4,qword ptr[rsp+offset] ※スタックフレームから参照
820 pobj_sf->ref(REG_XMM4,sizeof(double));
821
822 //comiss xmm_reg1,xmm_reg2
823 compiler.codeGenerator.op_comisd(xmm_reg,REG_XMM4);
824 }
825 else if(type1.IsSingle()){
826 int xmm_reg;
827 if(IsXmmReg(reg2)) xmm_reg=reg2;
828 else xmm_reg=REG_XMM5;
829 ChangeTypeToXmm_Single(type2.GetBasicType(),xmm_reg,reg2);
830
831 //movss xmm4,dword ptr[rsp+offset] ※スタックフレームから参照
832 pobj_sf->ref(REG_XMM4,sizeof(float));
833
834 //comiss xmm_reg1,xmm_reg2
835 compiler.codeGenerator.op_comiss(xmm_reg,REG_XMM4);
836 }
837 else{
838 //その他整数型
839
840 i2=NeutralizationType(type1.GetBasicType(),-1,type2.GetBasicType(),-1);
841
842 //mov r14,qword ptr[rsp+offset] ※スタックフレームから参照
843 pobj_sf->ref(REG_R14);
844
845 //cmp reg2,r14
846 compiler.codeGenerator.op_cmp_reg(Type(i2).GetSize(),reg2,REG_R14);
847 }
848
849 //je ...
850 selectSchedules.back().casePertialSchedules.push_back(
851 compiler.codeGenerator.op_je( 0, sizeof(long), true )
852 );
853 }
854
855 if(basbuf[i]!=',') break;
856 }
857 }
858 if(basbuf[i]==1&&basbuf[i+1]==ESC_CASEELSE){
859 //jmp ...
860 selectSchedules.back().casePertialSchedules.push_back(
861 compiler.codeGenerator.op_jmp( 0, sizeof(long), true )
862 );
863 }
864 }
865
866 //スタックフレームを1スペースだけ解除
867 pobj_sf->pop(REG_NON);
868
869 //レキシカルスコープをレベルアップ
870 compiler.codeGenerator.lexicalScopes.Start( compiler.codeGenerator.GetNativeCodeSize(), LexicalScope::SCOPE_TYPE_SELECT );
871
872 //Select Case内をコンパイル
873 CompileBuffer(ESC_ENDSELECT,0);
874
875 //jmp EndSelect
876 selectSchedules.back().casePertialSchedules.push_back(
877 compiler.codeGenerator.op_jmp( 0, sizeof(long), true )
878 );
879
880 //最終スケジュール
881 for(i=selectSchedules.back().nowCaseSchedule;i<(int)selectSchedules.back().casePertialSchedules.size();i++){
882 compiler.codeGenerator.opfix_JmpPertialSchedule( selectSchedules.back().casePertialSchedules[i] );
883 }
884
885 //レキシカルスコープをレベルダウン
886 compiler.codeGenerator.lexicalScopes.End();
887
888 selectSchedules.pop_back();
889}
890void OpcodeCase(char *Parameter){
891 int i;
892
893 if(selectSchedules.back().typeSize==-1){
894 SetError(30,"Case",cp);
895 return;
896 }
897
898 //jmp EndSelect
899 selectSchedules.back().casePertialSchedules.push_back(
900 compiler.codeGenerator.op_jmp( 0, sizeof(long), true )
901 );
902
903 i=0;
904 while(1){
905 //Caseスケジュール
906 compiler.codeGenerator.opfix_JmpPertialSchedule( selectSchedules.back().casePertialSchedules[selectSchedules.back().nowCaseSchedule] );
907 selectSchedules.back().nowCaseSchedule++;
908
909 i=JumpOneParameter(Parameter,i);
910 if(Parameter[i]=='\0') break;
911 }
912}
913
914void OpcodeGosub(char *Parameter){
915 SetError(-1,"Gosub ~ Returnステートメントは64ビットコンパイラで利用することはできません。",cp);
916}
917void OpcodeReturn(char *Parameter){
918 if( UserProc::IsGlobalAreaCompiling() ){
919 SetError(62,NULL,cp);
920 }
921 else{
922 //戻り値をセット
923 if(Parameter[0]){
924 const UserProc &proc = UserProc::CompilingUserProc();
925
926 const char *temp = "_System_ReturnValue";
927 if(proc.GetName()[0]==1&&proc.GetName()[1]==ESC_OPERATOR)
928 {
929 }
930 else{
931 temp=proc.GetName().c_str();
932 }
933
934 char temporary[VN_SIZE];
935 sprintf(temporary,"%s=%s",temp,Parameter);
936 OpcodeCalc(temporary);
937 }
938
939 //プロシージャを抜け出す(C言語のreturnと同様の処理を行う)
940 OpcodeExitSub();
941 }
942}
943
944
945////////////
946// ポインタ
947////////////
948
949void OpcodeSetPtrData(char *Parameter,int type){
950 int i;
951 char temporary[VN_SIZE];
952
953 if(Parameter[0]=='('){
954 i=JumpStringInPare(Parameter,1);
955 if(Parameter[i+1]=='\0'){
956 for(i=0;;i++){
957 Parameter[i]=Parameter[i+1];
958 if(Parameter[i]=='\0') break;
959 }
960 Parameter[i-1]=0;
961 }
962 }
963
964 //第1パラメータを取得
965 i=GetOneParameter(Parameter,0,temporary);
966 if(!Parameter[i]){
967 SetError(1,NULL,cp);
968 return;
969 }
970
971 int reg_ptr=REG_RAX;
972 Type resultType;
973 if( !NumOpe(&reg_ptr,temporary,Type(),resultType) ){
974 return;
975 }
976 if(!resultType.IsWhole()){
977 SetError(11,Parameter,cp);
978 return;
979 }
980
981 //結果を格納しているレジスタをブロッキング
982 pobj_BlockReg->lock(reg_ptr);
983
984 //第2パラメータを取得
985 i=GetOneParameter(Parameter,i,temporary);
986 if(Parameter[i]){
987 SetError(1,NULL,cp);
988 return;
989 }
990
991 int temp_reg=REG_NON;
992 if( !NumOpe(&temp_reg,temporary,Type(),resultType) ){
993 return;
994 }
995
996 //レジスタのブロッキングを解除
997 pobj_BlockReg->clear();
998
999 if(type==DEF_DOUBLE){
1000 ChangeTypeToXmm_Double(resultType.GetBasicType(),REG_XMM0,temp_reg);
1001
1002 //movsd qword ptr[reg_ptr],xmm0
1003 compiler.codeGenerator.op_movsd_MR(REG_XMM0,reg_ptr,0,MOD_BASE);
1004 }
1005 else if(type==DEF_SINGLE){
1006 ChangeTypeToXmm_Single(resultType.GetBasicType(),REG_XMM0,temp_reg);
1007
1008 //movss dword ptr[reg_ptr],xmm0
1009 compiler.codeGenerator.op_movss_MR(REG_XMM0,reg_ptr,0,MOD_BASE);
1010 }
1011 else{
1012 ChangeTypeToWhole(resultType,Type(type),REG_RCX,temp_reg);
1013
1014 //mov ptr[reg_ptr],rcx
1015 compiler.codeGenerator.op_mov_MR(Type(type).GetSize(),REG_RCX,reg_ptr,0,MOD_BASE);
1016 }
1017}
Note: See TracBrowser for help on using the repository browser.