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

Last change on this file since 584 was 584, checked in by dai_9181, 15 years ago

[530][583]を64bit版にマージ。

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.