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

Last change on this file since 716 was 716, checked in by dai, 15 years ago

[712]を64bit版にマージ。

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