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

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

解釈不可能なステートメントでコンパイルエラーにならなくなっていたので修正。

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