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

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

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

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