source: dev/trunk/ab5.0/abdev/compiler_x64/Compile_Statement.cpp@ 673

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

[585][586]をリバース。NativeCodeクラスとMetaクラスは依存関係があるので分離しない方針とする。

File size: 24.0 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 compiler.errorMessenger.Output(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 compiler.errorMessenger.Output(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 compiler.errorMessenger.Output(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 compiler.errorMessenger.OutputFatalError();
93 }
94 pobj_reg=new CRegister(REG_RAX);
95
96 Type resultType;
97 bool isLiteral, isNeedHeapFreeStructure = false;
98 bool result = TermOpe( leftTerm, Type(), resultType, isLiteral, isNeedHeapFreeStructure, NULL, true );
99
100 delete pobj_reg;
101 pobj_reg = NULL;
102
103 if( result ){
104
105 /////////////////////
106 // 戻り値の処理
107 /////////////////////
108
109 if( resultType.IsStruct() ){
110 //mov r14,rax
111 compiler.codeGenerator.op_mov_RR(REG_R14,REG_RAX);
112
113 FreeTempObject(REG_R14,&resultType.GetClass());
114 }
115
116 return;
117 }
118
119 // どこにも当てはまらなかったため、失敗
120 compiler.errorMessenger.Output(1,NULL,cp);
121}
122
123void Judgment(char *buffer){
124 int reg=REG_RAX;
125 Type resultType;
126 if( !NumOpe(&reg,buffer,Type(DEF_BOOLEAN),resultType) ){
127 return;
128 }
129
130 int offset;
131
132 if(resultType.IsDouble()){
133 double dbl=0;
134 offset=compiler.GetObjectModule().dataTable.Add( dbl );
135
136 //comisd xmm0,qword ptr[data table offset]
137 compiler.codeGenerator.PutOld(
138 (char)0x66,
139 (char)0x0F,
140 (char)0x2F,
141 (char)0x04,
142 (char)0x25
143 );
144 compiler.codeGenerator.PutOld(
145 (long)offset,
146 Schedule::DataTable
147 );
148 }
149 else if(resultType.IsSingle()){
150 float flt=0;
151 offset=compiler.GetObjectModule().dataTable.Add( flt );
152
153 //comiss xmm0,dword ptr[data table offset]
154 compiler.codeGenerator.PutOld(
155 (char)0x0F,
156 (char)0x2F,
157 (char)0x04,
158 (char)0x25
159 );
160 compiler.codeGenerator.PutOld(
161 (long)offset,
162 Schedule::DataTable
163 );
164 }
165 else{
166 //整数型
167
168 //cmp rax,0
169 compiler.codeGenerator.op_cmp_value(resultType.GetSize(),REG_RAX,0);
170 }
171}
172
173void OpcodeIf(char *Parameter){
174 for(int i=0;;i++){
175 if(Parameter[i]=='\0'){
176 compiler.errorMessenger.Output(21,NULL,cp);
177 return;
178 }
179 if(Parameter[i]==1&&Parameter[i+1]==ESC_THEN){
180 Parameter[i]=0;
181 break;
182 }
183 }
184
185 //条件式を実行してフラグをセット
186 Judgment(Parameter);
187
188 //je (endif、または else まで条件ジャンプ)
189 const PertialSchedule *pIfPertialSchedule = compiler.codeGenerator.op_je( 0, sizeof(long), true );
190
191
192 /////////////////////////
193 // If内をコード化
194 /////////////////////////
195
196 //レキシカルスコープをレベルアップ
197 compiler.codeGenerator.lexicalScopes.Start(
198 compiler.codeGenerator.GetNativeCodeSize(),
199 LexicalScope::SCOPE_TYPE_IF
200 );
201
202 int i2=CompileBuffer(ESC_ENDIF,0);
203
204 //レキシカルスコープをレベルダウン
205 compiler.codeGenerator.lexicalScopes.End();
206
207
208 if(i2==ESC_ELSE){
209 //jmp (endifまで)
210 const PertialSchedule *pTempPertialSchedule = compiler.codeGenerator.op_jmp( 0, sizeof(long), true );
211
212 compiler.codeGenerator.opfix_JmpPertialSchedule( pIfPertialSchedule );
213
214
215
216 /////////////////////////
217 // Else内をコード化
218 /////////////////////////
219
220 //レキシカルスコープをレベルアップ
221 compiler.codeGenerator.lexicalScopes.Start(
222 compiler.codeGenerator.GetNativeCodeSize(),
223 LexicalScope::SCOPE_TYPE_IF
224 );
225
226 CompileBuffer(ESC_ENDIF,0);
227
228 //レキシカルスコープをレベルダウン
229 compiler.codeGenerator.lexicalScopes.End();
230
231
232 compiler.codeGenerator.opfix_JmpPertialSchedule( pTempPertialSchedule );
233 }
234 else{
235 compiler.codeGenerator.opfix_JmpPertialSchedule( pIfPertialSchedule );
236 }
237}
238
239int GetLabelAddress(char *LabelName,int LineNum){
240 if(LabelName){
241 BOOST_FOREACH( const GotoLabel &label, compiler.codeGenerator.gotoLabels )
242 {
243 if( label.name.size() > 0 )
244 {
245 if( label.name == LabelName )
246 {
247 return label.address;
248 }
249 }
250 }
251 }
252 else{
253 BOOST_FOREACH( const GotoLabel &label, compiler.codeGenerator.gotoLabels )
254 {
255 if( label.name.size() == 0 )
256 {
257 if( label.line == LineNum )
258 {
259 return label.address;
260 }
261 }
262 }
263 }
264 return -1;
265}
266void OpcodeGoto(char *Parameter){
267 extern HANDLE hHeap;
268 int i,LineNum;
269
270 if(Parameter[0]=='*'){
271 i=GetLabelAddress(Parameter+1,0);
272
273 if( i == -1 )
274 {
275 //jmp ...(schedule)
276 compiler.codeGenerator.op_jmp_goto_schedule( (const std::string)(Parameter + 1), 0, cp );
277 }
278 else
279 {
280 //jmp ...
281 compiler.codeGenerator.op_jmp(
282 i-compiler.codeGenerator.GetNativeCodeSize(),
283 sizeof(long),
284 false,
285 true
286 );
287 }
288 }
289 else{
290 LineNum=atoi(Parameter);
291 i=GetLabelAddress(0,LineNum);
292
293 if( i == -1 )
294 {
295 //jmp ...(schedule)
296 compiler.codeGenerator.op_jmp_goto_schedule( "", LineNum, cp );
297 }
298 else
299 {
300 //jmp ...
301 compiler.codeGenerator.op_jmp(
302 i-compiler.codeGenerator.GetNativeCodeSize(),
303 sizeof(long),
304 false,
305 true
306 );
307 }
308 }
309}
310void OpcodeWhile(char *Parameter){
311 extern HANDLE hHeap;
312
313 //Continueアドレスのバックアップとセット
314 compiler.codeGenerator.ContinueAreaBegin();
315
316 if(!Parameter[0]) compiler.errorMessenger.Output(10,"While",cp);
317
318 //条件式を実行してフラグをセット
319 Judgment(Parameter);
320
321 //je (Wend まで)
322 const PertialSchedule *pWhilePertialSchedule = compiler.codeGenerator.op_je( 0, sizeof(long), true );
323
324 //レキシカルスコープをレベルアップ
325 compiler.codeGenerator.lexicalScopes.Start( compiler.codeGenerator.GetNativeCodeSize(), LexicalScope::SCOPE_TYPE_WHILE );
326
327 //While内をコンパイル
328 CompileBuffer(0,COM_WEND);
329
330 compiler.codeGenerator.lexicalScopes.CallDestructorsOfScopeEnd();
331
332 //jmp ...
333 compiler.codeGenerator.op_jmp_continue();
334
335 //レキシカルスコープをレベルダウン
336 compiler.codeGenerator.lexicalScopes.End();
337
338 compiler.codeGenerator.opfix_JmpPertialSchedule( pWhilePertialSchedule );
339
340 //Continueアドレスを復元
341 compiler.codeGenerator.ContinueAreaEnd();
342}
343
344char szNextVariable[VN_SIZE];
345void OpcodeFor(char *Parameter){
346 extern HANDLE hHeap;
347 Type resultType;
348 int i,i2;
349 char temporary[VN_SIZE],variable[VN_SIZE],JudgeNum[VN_SIZE],StepNum[VN_SIZE];
350 bool isError = false;
351
352 //第1パラメータを取得
353 i=GetOneParameter(Parameter,0,temporary);
354 if(!Parameter[i]){
355 compiler.errorMessenger.Output(12,"For",cp);
356 isError = true;
357 goto ErrorStep;
358 }
359
360 for(i2=0;;i2++){
361 if(temporary[i2]=='='){
362 variable[i2]=0;
363
364 //カウンタ初期化
365 OpcodeCalc(temporary);
366 break;
367 }
368 if(temporary[i2]=='\0'){
369 compiler.errorMessenger.Output(12,"For",cp);
370 isError = true;
371 goto ErrorStep;
372 }
373 variable[i2]=temporary[i2];
374 }
375
376 //jmp ...
377 const PertialSchedule *pTempPertialSchedule = compiler.codeGenerator.op_jmp( 0, sizeof(long), true );
378
379 //Continueアドレスのバックアップとセット
380 compiler.codeGenerator.ContinueAreaBegin();
381
382 //第2パラメータを取得(to~)
383 i=GetOneParameter(Parameter,i,JudgeNum);
384
385 //第3パラメータを取得(step~)
386 if(Parameter[i]){
387 i=GetOneParameter(Parameter,i,StepNum);
388 if(Parameter[i]) compiler.errorMessenger.Output(12,"For",cp);
389 }
390 else lstrcpy(StepNum,"1");
391
392 //カウンタを増加させる
393 sprintf(temporary,"%s=(%s)+(%s)",variable,variable,StepNum);
394 OpcodeCalc(temporary);
395
396 compiler.codeGenerator.opfix_JmpPertialSchedule( pTempPertialSchedule );
397
398 //増加か減少かを区別する
399 sprintf(temporary,"(%s)>=0",StepNum);
400
401 int reg;
402 reg=REG_RAX;
403 if( !NumOpe(&reg,temporary,Type(),resultType) ){
404 return;
405 }
406
407 //cmp rax,0
408 compiler.codeGenerator.op_cmp_value(resultType.GetSize(),REG_RAX,0);
409
410 //je [カウンタ減少の場合の判定]
411 pTempPertialSchedule = compiler.codeGenerator.op_je( 0, sizeof(long), true );
412
413 //判定(カウンタ増加の場合)
414 sprintf(temporary,"%s<=(%s)",variable,JudgeNum);
415
416 reg=REG_RAX;
417 NumOpe(&reg,temporary,Type(),Type());
418
419 //jmp [カウンタ減少の場合の判定を飛び越す]
420 const PertialSchedule *pTempPertialSchedule2 = compiler.codeGenerator.op_jmp( 0, sizeof(long), true );
421
422 //jeジャンプ先のオフセット値
423 compiler.codeGenerator.opfix_JmpPertialSchedule( pTempPertialSchedule );
424
425 //判定(カウンタ減少の場合)
426 sprintf(temporary,"%s>=(%s)",variable,JudgeNum);
427
428 reg=REG_RAX;
429 NumOpe(&reg,temporary,Type(),resultType);
430
431 //jmpジャンプ先のオフセット値
432 compiler.codeGenerator.opfix_JmpPertialSchedule( pTempPertialSchedule2 );
433
434 //cmp rax,0
435 compiler.codeGenerator.op_cmp_value(resultType.GetSize(),REG_RAX,0);
436
437ErrorStep:
438
439 //je ...
440 pTempPertialSchedule = compiler.codeGenerator.op_je( 0, sizeof(long), true );
441
442 //レキシカルスコープをレベルアップ
443 compiler.codeGenerator.lexicalScopes.Start( compiler.codeGenerator.GetNativeCodeSize(), LexicalScope::SCOPE_TYPE_FOR );
444
445 //For内をコンパイル
446 CompileBuffer(0,COM_NEXT);
447
448 compiler.codeGenerator.lexicalScopes.CallDestructorsOfScopeEnd();
449
450 if(szNextVariable[0]){
451 if(lstrcmp(szNextVariable,variable)!=0){
452 compiler.errorMessenger.Output(55,szNextVariable,cp);
453 }
454 }
455
456 //jmp ...
457 compiler.codeGenerator.op_jmp_continue();
458
459 //レキシカルスコープをレベルダウン
460 compiler.codeGenerator.lexicalScopes.End();
461
462 //jeジャンプ先のオフセット値
463 compiler.codeGenerator.opfix_JmpPertialSchedule( pTempPertialSchedule );
464
465 //Continueアドレスを復元
466 compiler.codeGenerator.ContinueAreaEnd();
467}
468
469void OpcodeForeach( const char *Parameter )
470{
471 Type resultType;
472 char temporary[VN_SIZE],variable[VN_SIZE],collectionVar[VN_SIZE];
473 bool isError = false;
474
475 //レキシカルスコープをレベルアップ
476 compiler.codeGenerator.lexicalScopes.Start( compiler.codeGenerator.GetNativeCodeSize(), LexicalScope::SCOPE_TYPE_FOR );
477
478 //第1パラメータを取得
479 int i = 0;
480 GetCustomToken( variable, Parameter, i, ESC_IN, true );
481 if(!Parameter[i]){
482 compiler.errorMessenger.Output(12,"Foreach",cp);
483 isError = true;
484 goto ErrorStep;
485 }
486 i++;
487
488 //第2パラメータを取得(in~)
489 lstrcpy( collectionVar, Parameter + i );
490
491 if( !GetVarType( variable, resultType, false ) )
492 {
493 Type collectionType;
494 if( !NumOpe_GetType( collectionVar, Type(), collectionType ) )
495 {
496 isError = true;
497 goto ErrorStep;
498 }
499
500 // 未定義の場合は自動的に定義する
501 sprintf(temporary,"%s=Nothing%c%c%s", variable, 1, ESC_AS, collectionType.GetActualGenericType(0).GetClass().GetFullName().c_str() );
502 OpcodeDim(temporary,DIMFLAG_INITDEBUGVAR);
503 }
504
505 // Resetメソッドを呼び出す
506 sprintf( temporary, "%s.Reset()", collectionVar );
507 Compile( temporary );
508
509 //Continueアドレスのバックアップとセット
510 compiler.codeGenerator.ContinueAreaBegin();
511
512 // MoveNextメソッドを呼び出す
513 sprintf( temporary, "%s.MoveNext()", collectionVar );
514 int reg = REG_RAX;
515 NumOpe(&reg,temporary,Type(),resultType);
516
517 //cmp rax,0
518 compiler.codeGenerator.op_cmp_value(resultType.GetSize(),REG_RAX,0);
519
520ErrorStep:
521
522 //je ...
523 const PertialSchedule *pTempPertialSchedule = compiler.codeGenerator.op_je( 0, sizeof(long), true );
524
525 if( !isError )
526 {
527 // Currentプロパティから現在の値を取得
528 sprintf( temporary, "%s=%s.Current", variable, collectionVar );
529 Compile( temporary );
530 }
531
532 //For内をコンパイル
533 CompileBuffer(0,COM_NEXT);
534
535 compiler.codeGenerator.lexicalScopes.CallDestructorsOfScopeEnd();
536
537 if(szNextVariable[0]){
538 if(lstrcmp(szNextVariable,variable)!=0){
539 compiler.errorMessenger.Output(55,szNextVariable,cp);
540 }
541 }
542
543 if( !isError )
544 {
545 //jmp ...
546 compiler.codeGenerator.op_jmp_continue();
547 }
548
549 //レキシカルスコープをレベルダウン
550 compiler.codeGenerator.lexicalScopes.End();
551
552 //jeジャンプ先のオフセット値
553 compiler.codeGenerator.opfix_JmpPertialSchedule( pTempPertialSchedule );
554
555 //Continueアドレスを復元
556 compiler.codeGenerator.ContinueAreaEnd();
557}
558
559void OpcodeDo(char *Parameter){
560 extern HANDLE hHeap;
561 int i,i2,i3;
562
563 if(Parameter[0]) compiler.errorMessenger.Output(10,"Do",cp);
564
565 //Continueアドレスのバックアップとセット
566 compiler.codeGenerator.ContinueAreaBegin();
567
568 //レキシカルスコープをレベルアップ
569 compiler.codeGenerator.lexicalScopes.Start( compiler.codeGenerator.GetNativeCodeSize(), LexicalScope::SCOPE_TYPE_DO );
570
571 //Do内をコンパイル
572 CompileBuffer(0,COM_LOOP);
573
574 compiler.codeGenerator.lexicalScopes.CallDestructorsOfScopeEnd();
575
576 const PertialSchedule *pDoPertialSchedule = NULL;
577
578 extern char *basbuf;
579 char temporary[VN_SIZE];
580 for(i=cp-1;;i--){
581 if(IsCommandDelimitation(basbuf[i])){
582 i+=3;
583 if(!(basbuf[i]=='0'||basbuf[i]=='1')){
584 //無条件ループ
585 break;
586 }
587 i3=i;
588
589 for(i+=2,i2=0;;i++,i2++){
590 if(IsCommandDelimitation(basbuf[i])){
591 temporary[i2]=0;
592 break;
593 }
594 temporary[i2]=basbuf[i];
595 }
596
597 //条件式を実行してフラグをセット
598 Judgment(temporary);
599
600 if(basbuf[i3]=='0'){
601 //While
602
603 //je 5(ループ終了)
604 pDoPertialSchedule = compiler.codeGenerator.op_je( 0, sizeof(char), true );
605 }
606 else if(basbuf[i3]=='1'){
607 //Until
608
609 //jne 5(ループ終了)
610 pDoPertialSchedule = compiler.codeGenerator.op_jne( 0, sizeof(char), true );
611 }
612 break;
613 }
614 }
615
616 //jmp ...
617 compiler.codeGenerator.op_jmp_continue();
618
619 if( pDoPertialSchedule )
620 {
621 compiler.codeGenerator.opfix_JmpPertialSchedule( pDoPertialSchedule );
622 }
623
624 //jmp ...
625 const PertialSchedule *pTempPertialSchedule = compiler.codeGenerator.op_jmp( 0, sizeof(long), true );
626
627 //レキシカルスコープをレベルダウン
628 compiler.codeGenerator.lexicalScopes.End();
629
630 //jmpジャンプ先のオフセット値
631 compiler.codeGenerator.opfix_JmpPertialSchedule( pTempPertialSchedule );
632
633 //Continueアドレスを復元
634 compiler.codeGenerator.ContinueAreaEnd();
635}
636void OpcodeContinue(void){
637 //jmp ...(Continue addr)
638 compiler.codeGenerator.op_jmp_continue();
639}
640
641void OpcodeExitSub(void){
642 if( compiler.IsGlobalAreaCompiling() ){
643 compiler.errorMessenger.Output(12,"Exit Sub/Function",cp);
644 return;
645 }
646
647 //未解放のローカルオブジェクトのデストラクタを呼び出す
648 compiler.codeGenerator.lexicalScopes.CallDestructorsOfReturn();
649
650 //jmp ...(End Sub/Function)
651 compiler.codeGenerator.op_jmp_exitsub();
652}
653
654//Caseスケジュール
655class SelectSchedule
656{
657public:
658 SelectSchedule( int typeSize )
659 : typeSize( typeSize )
660 , nowCaseSchedule( 0 )
661 {
662 }
663
664 PertialSchedules casePertialSchedules;
665 int typeSize;
666 int nowCaseSchedule;
667};
668std::vector<SelectSchedule> selectSchedules;
669
670void OpcodeSelect( const char *lpszParms )
671{
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 bool result = NumOpe(&reg1,lpszParms,Type(), type1 );
680
681 selectSchedules.push_back( SelectSchedule( type1.GetSize() ) );
682
683 if( result )
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 compiler.errorMessenger.Output(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, Type( DEF_BOOLEAN ), type1 );
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 //レキシカルスコープをレベルアップ
871 compiler.codeGenerator.lexicalScopes.Start( compiler.codeGenerator.GetNativeCodeSize(), LexicalScope::SCOPE_TYPE_SELECT );
872
873 //Select Case内をコンパイル
874 CompileBuffer(ESC_ENDSELECT,0);
875
876 //jmp EndSelect
877 selectSchedules.back().casePertialSchedules.push_back(
878 compiler.codeGenerator.op_jmp( 0, sizeof(long), true )
879 );
880
881 //最終スケジュール
882 for(i=selectSchedules.back().nowCaseSchedule;i<(int)selectSchedules.back().casePertialSchedules.size();i++){
883 compiler.codeGenerator.opfix_JmpPertialSchedule( selectSchedules.back().casePertialSchedules[i] );
884 }
885
886 //レキシカルスコープをレベルダウン
887 compiler.codeGenerator.lexicalScopes.End();
888
889 selectSchedules.pop_back();
890}
891void OpcodeCase(char *Parameter){
892 int i;
893
894 if(selectSchedules.back().typeSize==-1){
895 compiler.errorMessenger.Output(30,"Case",cp);
896 return;
897 }
898
899 //jmp EndSelect
900 selectSchedules.back().casePertialSchedules.push_back(
901 compiler.codeGenerator.op_jmp( 0, sizeof(long), true )
902 );
903
904 i=0;
905 while(1){
906 //Caseスケジュール
907 compiler.codeGenerator.opfix_JmpPertialSchedule( selectSchedules.back().casePertialSchedules[selectSchedules.back().nowCaseSchedule] );
908 selectSchedules.back().nowCaseSchedule++;
909
910 i=JumpOneParameter(Parameter,i);
911 if(Parameter[i]=='\0') break;
912 }
913}
914
915void OpcodeGosub(char *Parameter){
916 compiler.errorMessenger.Output(-1,"Gosub ~ Returnステートメントは64ビットコンパイラで利用することはできません。",cp);
917}
918void OpcodeReturn(char *Parameter){
919 if( compiler.IsGlobalAreaCompiling() ){
920 compiler.errorMessenger.Output(62,NULL,cp);
921 }
922 else{
923 //戻り値をセット
924 if(Parameter[0]){
925 const UserProc &proc = compiler.GetCompilingUserProc();
926
927 const char *temp = "_System_ReturnValue";
928 if(proc.GetName()[0]==1&&proc.GetName()[1]==ESC_OPERATOR)
929 {
930 }
931 else{
932 temp=proc.GetName().c_str();
933 }
934
935 char temporary[VN_SIZE];
936 sprintf(temporary,"%s=%s",temp,Parameter);
937 OpcodeCalc(temporary);
938 }
939
940 //プロシージャを抜け出す(C言語のreturnと同様の処理を行う)
941 OpcodeExitSub();
942 }
943}
944
945
946////////////
947// ポインタ
948////////////
949
950void OpcodeSetPtrData(char *Parameter,int type){
951 int i;
952 char temporary[VN_SIZE];
953
954 if(Parameter[0]=='('){
955 i=JumpStringInPare(Parameter,1);
956 if(Parameter[i+1]=='\0'){
957 for(i=0;;i++){
958 Parameter[i]=Parameter[i+1];
959 if(Parameter[i]=='\0') break;
960 }
961 Parameter[i-1]=0;
962 }
963 }
964
965 //第1パラメータを取得
966 i=GetOneParameter(Parameter,0,temporary);
967 if(!Parameter[i]){
968 compiler.errorMessenger.Output(1,NULL,cp);
969 return;
970 }
971
972 int reg_ptr=REG_RAX;
973 Type resultType;
974 if( !NumOpe(&reg_ptr,temporary,Type(),resultType) ){
975 return;
976 }
977 if(!resultType.IsWhole()){
978 compiler.errorMessenger.Output(11,Parameter,cp);
979 return;
980 }
981
982 //結果を格納しているレジスタをブロッキング
983 pobj_BlockReg->lock(reg_ptr);
984
985 //第2パラメータを取得
986 i=GetOneParameter(Parameter,i,temporary);
987 if(Parameter[i]){
988 compiler.errorMessenger.Output(1,NULL,cp);
989 return;
990 }
991
992 int temp_reg=REG_NON;
993 if( !NumOpe(&temp_reg,temporary,Type(),resultType) ){
994 return;
995 }
996
997 //レジスタのブロッキングを解除
998 pobj_BlockReg->clear();
999
1000 if(type==DEF_DOUBLE){
1001 ChangeTypeToXmm_Double(resultType.GetBasicType(),REG_XMM0,temp_reg);
1002
1003 //movsd qword ptr[reg_ptr],xmm0
1004 compiler.codeGenerator.op_movsd_MR(REG_XMM0,reg_ptr,0,MOD_BASE);
1005 }
1006 else if(type==DEF_SINGLE){
1007 ChangeTypeToXmm_Single(resultType.GetBasicType(),REG_XMM0,temp_reg);
1008
1009 //movss dword ptr[reg_ptr],xmm0
1010 compiler.codeGenerator.op_movss_MR(REG_XMM0,reg_ptr,0,MOD_BASE);
1011 }
1012 else{
1013 ChangeTypeToWhole(resultType,Type(type),REG_RCX,temp_reg);
1014
1015 //mov ptr[reg_ptr],rcx
1016 compiler.codeGenerator.op_mov_MR(Type(type).GetSize(),REG_RCX,reg_ptr,0,MOD_BASE);
1017 }
1018}
Note: See TracBrowser for help on using the repository browser.