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

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