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, 16 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.