source: dev/trunk/ab5.0/abdev/compiler_x86/Compile_Statement.cpp@ 750

Last change on this file since 750 was 750, checked in by イグトランス (egtra), 16 years ago

BOOST_FOREACHを可能なものはVC++ 2005 for eachへ置換(やや速くなる)。

File size: 34.9 KB
RevLine 
[206]1#include "stdafx.h"
2
[248]3#include <LexicalScope.h>
[183]4#include <Compiler.h>
5
[3]6#include "../BasicCompiler_Common/common.h"
7#include "Opcode.h"
8
[129]9void OpcodeOthers( const char *Command ){
[3]10 int i,i2;
11
[122]12 char leftTerm[8192];
13 int lastParePos = 0;
[3]14 for(i=0;;i++){
[122]15 if(Command[i]=='\"'){
16 //ダブルクォートは不正なのでエラー扱い
17 leftTerm[i]=0;
[465]18 compiler.errorMessenger.Output(3,leftTerm,cp);
[122]19 return;
20 }
21
22 if(Command[i]=='('){
23 lastParePos = i;
24 i2=GetStringInPare(leftTerm+i,Command+i);
[3]25 i+=i2-1;
26 continue;
27 }
[122]28 if(Command[i]=='['){
29 i2=GetStringInBracket(leftTerm+i,Command+i);
30 i+=i2-1;
[3]31 continue;
32 }
[122]33 if(Command[i]=='\0'){
34 leftTerm[i] = 0;
[3]35 break;
36 }
[122]37
38 if( IsNumCalcMark( Command, i ) ){
39 leftTerm[i] = 0;
40 break;
41 }
42
43 leftTerm[i]=Command[i];
[3]44 }
45 if(!(
[122]46 IsVariableTopChar(leftTerm[0])||
47 leftTerm[0]=='.'||
48 (leftTerm[0]==1&&leftTerm[1]==ESC_PSMEM)
[3]49 )){
[465]50 compiler.errorMessenger.Output(1,NULL,cp);
[3]51 return;
52 }
53
54
[122]55 if(Command[i]=='\0' && lastParePos == 0){
[3]56 //////////////////////////////
57 // パラメータ無しのマクロ検索
58 //////////////////////////////
59
[206]60 const UserProc *pUserProc = GetSubHash(Command);
[3]61
62 //GetSubHash内でエラー提示が行われた場合
[75]63 if(pUserProc==(UserProc *)-1) return;
[3]64
[75]65 if(pUserProc==0){
[3]66 char temporary[VN_SIZE];
67 lstrcpy(temporary,Command);
68
69 CharUpper(temporary);
[75]70 pUserProc=GetSubHash(temporary);
[3]71
72 //GetSubHash内でエラー提示が行われた場合
[75]73 if(pUserProc==(UserProc *)-1) return;
[3]74 }
75
[75]76 if(pUserProc){
[122]77 if( !pUserProc->IsMacro() ){
[465]78 compiler.errorMessenger.Output(10,Command,cp);
[122]79 }
[3]80
[290]81 Opcode_CallProc("",pUserProc,0,"");
[3]82
83 return;
84 }
85 }
86 else if(IsNumCalcMark(Command,i)){
87 //代入演算
88 OpcodeCalc(Command);
89 return;
90 }
91
[122]92 Type resultType;
[435]93 bool isLiteral, isNeedHeapFreeStructure = false;
94 bool result = TermOpe( leftTerm, Type(), resultType, isLiteral, isNeedHeapFreeStructure, NULL, true );
[122]95 if( result ){
[3]96
97 /////////////////////
98 // 戻り値の処理
99 /////////////////////
100
[76]101 if( resultType.IsReal() ){
[3]102 //fstp st(0)
[236]103 compiler.codeGenerator.PutOld(
104 (char)0xDD,
105 (char)0xD8
106 );
[3]107 }
[76]108 else if( resultType.IsStruct() ){
[51]109 //mov ebx,eax
[225]110 compiler.codeGenerator.op_mov_RR(REG_EBX,REG_EAX);
[3]111
[76]112 FreeTempObject(REG_EBX,&resultType.GetClass());
[3]113 }
[386]114
115 return;
[3]116 }
[386]117
118 // どこにも当てはまらなかったため、失敗
[465]119 compiler.errorMessenger.Output(1,NULL,cp);
[3]120}
121
122void OpcodeIf(char *Parameter){
[241]123 int i,i2;
[76]124 Type tempType;
[3]125
126 for(i=0;;i++){
127 if(Parameter[i]=='\0'){
[465]128 compiler.errorMessenger.Output(21,NULL,cp);
[3]129 return;
130 }
131 if(Parameter[i]==1&&Parameter[i+1]==ESC_THEN){
132 Parameter[i]=0;
133 break;
134 }
135 }
136
[248]137 const PertialSchedule *pIfPertialSchedule = NULL;
[676]138 bool isNeedHeapFreeStructure;
139 if( NumOpe( Parameter, Type(DEF_BOOLEAN), tempType, &isNeedHeapFreeStructure ) )
140 {
141 if( tempType.IsObject() )
142 {
143 // Boolean型にキャストする
144 Type booleanType( DEF_BOOLEAN );
145 CallCastOperatorProc( tempType, isNeedHeapFreeStructure, booleanType );
146 tempType = booleanType;
147 }
[3]148
[676]149 if( tempType.IsDouble() ){
150 //fld qword ptr[esp]
151 compiler.codeGenerator.op_fld_ptr_esp(DEF_DOUBLE);
[3]152
[676]153 //push 0
154 compiler.codeGenerator.op_push_V(0);
[3]155
[676]156 //fild dword ptr[esp]
157 compiler.codeGenerator.op_fld_ptr_esp(DEF_LONG);
[3]158
[676]159 //add esp,sizeof(double)+sizeof(long)
160 compiler.codeGenerator.op_add_esp(sizeof(double)+sizeof(long));
[3]161
[676]162 //fcompp
163 compiler.codeGenerator.op_fcompp();
[3]164
[676]165 //fnstsw ax
166 compiler.codeGenerator.op_fnstsw_ax();
[3]167
[676]168 //test ah,40
169 compiler.codeGenerator.op_test_ah( (char)0x40 );
[3]170
[676]171 //jne (endif、または else まで)
172 pIfPertialSchedule = compiler.codeGenerator.op_jne( 0, sizeof(long), true );
173 }
174 else if( tempType.IsSingle() ){
175 //fld dword ptr[esp]
176 compiler.codeGenerator.op_fld_ptr_esp(DEF_SINGLE);
[3]177
[676]178 //push 0
179 compiler.codeGenerator.op_push_V(0);
[3]180
[676]181 //fild dword ptr[esp]
182 compiler.codeGenerator.op_fld_ptr_esp(DEF_LONG);
[3]183
[676]184 //add esp,sizeof(float)+sizeof(long)
185 compiler.codeGenerator.op_add_esp(sizeof(float)+sizeof(long));
[3]186
[676]187 //fcompp
188 compiler.codeGenerator.op_fcompp();
[3]189
[676]190 //fnstsw ax
191 compiler.codeGenerator.op_fnstsw_ax();
[3]192
[676]193 //test ah,40
194 compiler.codeGenerator.op_test_ah( (char)0x40 );
[3]195
[676]196 //jne (endif、または else まで)
197 pIfPertialSchedule = compiler.codeGenerator.op_jne( 0, sizeof(long), true );
198 }
199 else if( tempType.Is64() ){
200 //64ビット型
[3]201
[676]202 //pop eax
203 compiler.codeGenerator.op_pop(REG_EAX);
[3]204
[676]205 //pop ebx
206 compiler.codeGenerator.op_pop(REG_EBX);
[3]207
[676]208 //cmp eax,0
209 compiler.codeGenerator.op_cmp_value( sizeof(long), REG_EAX, 0 );
[3]210
[676]211 //jne
212 const PertialSchedule *pTempPertialSchedule1 = compiler.codeGenerator.op_jne( 0, sizeof(char), true );
[3]213
[676]214 //cmp ebx,0
215 compiler.codeGenerator.op_cmp_value( sizeof(long), REG_EBX, 0 );
[3]216
[676]217 //jne
218 const PertialSchedule *pTempPertialSchedule2 = compiler.codeGenerator.op_jne( 0, sizeof(char), true );
[3]219
[676]220 //jmp (endif、または else までジャンプ)
221 pIfPertialSchedule = compiler.codeGenerator.op_jmp( 0, sizeof(long), true );
[3]222
[676]223 compiler.codeGenerator.opfix_JmpPertialSchedule( pTempPertialSchedule1 );
224 compiler.codeGenerator.opfix_JmpPertialSchedule( pTempPertialSchedule2 );
225 }
226 else{
227 //32ビット型
[3]228
[676]229 //pop eax
230 compiler.codeGenerator.op_pop(REG_EAX);
[3]231
[676]232 //cmp eax,0
233 compiler.codeGenerator.op_cmp_value( sizeof(long), REG_EAX, 0 );
234
235 //je (endif、または else まで条件ジャンプ)
236 pIfPertialSchedule = compiler.codeGenerator.op_je( 0, sizeof(long), true );
237 }
[3]238 }
239
240
241 /////////////////////////
242 // If内をコード化
243 /////////////////////////
244
245 //レキシカルスコープをレベルアップ
[276]246 compiler.codeGenerator.lexicalScopes.Start(
247 compiler.codeGenerator.GetNativeCodeSize(),
248 LexicalScope::SCOPE_TYPE_IF
249 );
[3]250
251 i2=CompileBuffer(ESC_ENDIF,0);
252
253 //レキシカルスコープをレベルダウン
[248]254 compiler.codeGenerator.lexicalScopes.End();
[3]255
256
[241]257 if( pIfPertialSchedule == NULL ) return;
[3]258
259 if(i2==ESC_ELSE){
260 //jmp (endifまで)
[248]261 const PertialSchedule *pTempPertialSchedule = compiler.codeGenerator.op_jmp( 0, sizeof(long), true );
[3]262
[241]263 compiler.codeGenerator.opfix_JmpPertialSchedule( pIfPertialSchedule );
[3]264
265
266 /////////////////////////
267 // Else内をコード化
268 /////////////////////////
269
270 //レキシカルスコープをレベルアップ
[276]271 compiler.codeGenerator.lexicalScopes.Start(
272 compiler.codeGenerator.GetNativeCodeSize(),
273 LexicalScope::SCOPE_TYPE_IF
274 );
[3]275
276 CompileBuffer(ESC_ENDIF,0);
277
278 //レキシカルスコープをレベルダウン
[248]279 compiler.codeGenerator.lexicalScopes.End();
[3]280
281
[241]282 compiler.codeGenerator.opfix_JmpPertialSchedule( pTempPertialSchedule );
[3]283 }
284 else{
[241]285 compiler.codeGenerator.opfix_JmpPertialSchedule( pIfPertialSchedule );
[3]286 }
287}
288
289int GetLabelAddress(char *LabelName,int LineNum){
290 if(LabelName){
[750]291 foreach( const GotoLabel &label, compiler.codeGenerator.gotoLabels )
[260]292 {
293 if( label.name.size() > 0 )
294 {
295 if( label.name == LabelName )
296 {
297 return label.address;
298 }
[3]299 }
300 }
301 }
302 else{
[750]303 foreach( const GotoLabel &label, compiler.codeGenerator.gotoLabels )
[260]304 {
305 if( label.name.size() == 0 )
306 {
307 if( label.line == LineNum )
308 {
309 return label.address;
310 }
[3]311 }
312 }
313 }
314 return -1;
315}
316void OpcodeGoto(char *Parameter){
317 extern HANDLE hHeap;
318 int i,LineNum;
319
320 if(Parameter[0]=='*'){
321 i=GetLabelAddress(Parameter+1,0);
322
[246]323 if( i == -1 )
324 {
325 //jmp ...(schedule)
[253]326 compiler.codeGenerator.op_jmp_goto_schedule( (const std::string)(Parameter + 1), 0, cp );
[3]327 }
[246]328 else
329 {
330 //jmp ...
[276]331 compiler.codeGenerator.op_jmp(
332 i-compiler.codeGenerator.GetNativeCodeSize(),
333 sizeof(long),
334 false,
335 true
336 );
[246]337 }
[3]338 }
339 else{
340 LineNum=atoi(Parameter);
341 i=GetLabelAddress(0,LineNum);
342
[246]343 if( i == -1 )
344 {
345 //jmp ...(schedule)
[253]346 compiler.codeGenerator.op_jmp_goto_schedule( "", LineNum, cp );
[3]347 }
[246]348 else
349 {
350 //jmp ...
[276]351 compiler.codeGenerator.op_jmp(
352 i-compiler.codeGenerator.GetNativeCodeSize(),
353 sizeof(long),
354 false,
355 true
356 );
[246]357 }
[3]358 }
359}
360void OpcodeWhile(char *Parameter){
361 extern HANDLE hHeap;
362
363 //Continueアドレスのバックアップとセット
[241]364 compiler.codeGenerator.ContinueAreaBegin();
[3]365
[465]366 if(!Parameter[0]) compiler.errorMessenger.Output(10,"While",cp);
[3]367
[248]368 const PertialSchedule *pWhilePertialSchedule = NULL;
[76]369 Type tempType;
[676]370 bool isNeedHeapFreeStructure;
371 if( NumOpe( Parameter, Type(), tempType, &isNeedHeapFreeStructure ) )
372 {
373 if( tempType.IsObject() )
374 {
375 // Boolean型にキャストする
376 Type booleanType( DEF_BOOLEAN );
377 CallCastOperatorProc( tempType, isNeedHeapFreeStructure, booleanType );
378 tempType = booleanType;
379 }
[3]380
[676]381 if( tempType.IsDouble() ){
382 //fld qword ptr[esp]
383 compiler.codeGenerator.op_fld_ptr_esp(DEF_DOUBLE);
[3]384
[676]385 //push 0
386 compiler.codeGenerator.op_push_V(0);
[3]387
[676]388 //fild dword ptr[esp]
389 compiler.codeGenerator.op_fld_ptr_esp(DEF_LONG);
[3]390
[676]391 //add esp,sizeof(double)+sizeof(long)
392 compiler.codeGenerator.op_add_esp(sizeof(double)+sizeof(long));
[3]393
[676]394 //fcompp
395 compiler.codeGenerator.op_fcompp();
[3]396
[676]397 //fnstsw ax
398 compiler.codeGenerator.op_fnstsw_ax();
[3]399
[676]400 //test ah,40
401 compiler.codeGenerator.op_test_ah( (char)0x40 );
[3]402
[676]403 //jne (Wend まで)
404 pWhilePertialSchedule = compiler.codeGenerator.op_jne( 0, sizeof(long), true );
405 }
406 else if( tempType.IsSingle() ){
407 //fld dword ptr[esp]
408 compiler.codeGenerator.op_fld_ptr_esp(DEF_SINGLE);
[3]409
[676]410 //push 0
411 compiler.codeGenerator.op_push_V(0);
[3]412
[676]413 //fild dword ptr[esp]
414 compiler.codeGenerator.op_fld_ptr_esp(DEF_LONG);
[3]415
[676]416 //add esp,sizeof(float)+sizeof(long)
417 compiler.codeGenerator.op_add_esp(sizeof(float)+sizeof(long));
[3]418
[676]419 //fcompp
420 compiler.codeGenerator.op_fcompp();
[3]421
[676]422 //fnstsw ax
423 compiler.codeGenerator.op_fnstsw_ax();
[3]424
[676]425 //test ah,40h
426 compiler.codeGenerator.op_test_ah( (char)0x40 );
[3]427
[676]428 //jne (Wend まで)
429 pWhilePertialSchedule = compiler.codeGenerator.op_jne( 0, sizeof(long), true );
430 }
431 else if( tempType.Is64() ){
432 //64ビット型
[3]433
[676]434 //pop eax
435 compiler.codeGenerator.op_pop(REG_EAX);
[3]436
[676]437 //pop ebx
438 compiler.codeGenerator.op_pop(REG_EBX);
[3]439
[676]440 //cmp eax,0
441 compiler.codeGenerator.op_cmp_value( sizeof(long), REG_EAX, 0 );
[3]442
[676]443 //jne
444 const PertialSchedule *pTempPertialSchedule1 = compiler.codeGenerator.op_jne( 0, sizeof(char), true );
[3]445
[676]446 //cmp ebx,0
447 compiler.codeGenerator.op_cmp_value( sizeof(long), REG_EBX, 0 );
[3]448
[676]449 //jne
450 const PertialSchedule *pTempPertialSchedule2 = compiler.codeGenerator.op_jne( 0, sizeof(char), true );
[3]451
[676]452 //jmp (Wendまでジャンプ)
453 pWhilePertialSchedule = compiler.codeGenerator.op_jmp( 0, sizeof(long), true );
[3]454
[676]455 compiler.codeGenerator.opfix_JmpPertialSchedule( pTempPertialSchedule1 );
456 compiler.codeGenerator.opfix_JmpPertialSchedule( pTempPertialSchedule2 );
457 }
458 else{
459 //その他整数型
[3]460
[676]461 //pop eax
462 compiler.codeGenerator.op_pop(REG_EAX);
[3]463
[676]464 //cmp eax,0
465 compiler.codeGenerator.op_cmp_value( sizeof(long), REG_EAX, 0 );
466
467 //je (Wend まで)
468 pWhilePertialSchedule = compiler.codeGenerator.op_je( 0, sizeof(long), true );
469 }
[3]470 }
471
472 //レキシカルスコープをレベルアップ
[276]473 compiler.codeGenerator.lexicalScopes.Start( compiler.codeGenerator.GetNativeCodeSize(), LexicalScope::SCOPE_TYPE_WHILE );
[3]474
475 //While内をコンパイル
476 CompileBuffer(0,COM_WEND);
477
[248]478 compiler.codeGenerator.lexicalScopes.CallDestructorsOfScopeEnd();
[3]479
480 //jmp ...
[241]481 compiler.codeGenerator.op_jmp_continue();
[3]482
483 //レキシカルスコープをレベルダウン
[248]484 compiler.codeGenerator.lexicalScopes.End();
[3]485
[241]486 if( pWhilePertialSchedule )
487 {
488 compiler.codeGenerator.opfix_JmpPertialSchedule( pWhilePertialSchedule );
489 }
[3]490
[241]491 compiler.codeGenerator.ContinueAreaEnd();
[3]492}
493
494char szNextVariable[VN_SIZE];
495void OpcodeFor(char *Parameter){
496 extern HANDLE hHeap;
[241]497 int i,i2;
[3]498 char temporary[VN_SIZE],variable[VN_SIZE],JudgeNum[VN_SIZE],StepNum[VN_SIZE];
499
500 //第1パラメータを取得
501 i=GetOneParameter(Parameter,0,temporary);
502 if(!Parameter[i]){
[465]503 compiler.errorMessenger.Output(12,"For",cp);
[3]504 goto ErrorStep;
505 }
506
507 for(i2=0;;i2++){
508 if(temporary[i2]=='='){
509 variable[i2]=0;
510
511 //カウンタ初期化
512 OpcodeCalc(temporary);
513 break;
514 }
515 if(temporary[i2]=='\0'){
[465]516 compiler.errorMessenger.Output(12,"For",cp);
[3]517 goto ErrorStep;
518 }
519 variable[i2]=temporary[i2];
520 }
521
522 //jmp ...
[248]523 const PertialSchedule *pTempPertialSchedule = compiler.codeGenerator.op_jmp( 0, sizeof(long), true );
[3]524
525 //Continueアドレスのバックアップとセット
[241]526 compiler.codeGenerator.ContinueAreaBegin();
[3]527
528 //第2パラメータを取得(to~)
529 i=GetOneParameter(Parameter,i,JudgeNum);
530
531 //第3パラメータを取得(step~)
532 if(Parameter[i]){
533 i=GetOneParameter(Parameter,i,StepNum);
[465]534 if(Parameter[i]) compiler.errorMessenger.Output(12,"For",cp);
[3]535 }
536 else lstrcpy(StepNum,"1");
537
538 //カウンタを増加させる
539 sprintf(temporary,"%s=(%s)+(%s)",variable,variable,StepNum);
540 OpcodeCalc(temporary);
541
[241]542 compiler.codeGenerator.opfix_JmpPertialSchedule( pTempPertialSchedule );
[3]543
544 //増加か減少かを区別する
545 sprintf(temporary,"(%s)>=0",StepNum);
[76]546 NumOpe(temporary,Type(),Type());
[3]547
548 //pop eax
[225]549 compiler.codeGenerator.op_pop(REG_EAX);
[3]550
551 //cmp eax,0
[236]552 compiler.codeGenerator.op_cmp_value( sizeof(long), REG_EAX, 0 );
[3]553
554 //je [カウンタ減少の場合の判定]
[241]555 pTempPertialSchedule = compiler.codeGenerator.op_je( 0, sizeof(long), true );
[3]556
557 //判定(カウンタ増加の場合)
558 sprintf(temporary,"%s<=(%s)",variable,JudgeNum);
[76]559 NumOpe(temporary,Type(),Type());
[3]560
561 //pop eax
[225]562 compiler.codeGenerator.op_pop(REG_EAX);
[3]563
564 //jmp [カウンタ減少の場合の判定を飛び越す]
[248]565 const PertialSchedule *pTempPertialSchedule2 = compiler.codeGenerator.op_jmp( 0, sizeof(long), true );
[3]566
[241]567 //jeジャンプ先のオフセット値
568 compiler.codeGenerator.opfix_JmpPertialSchedule( pTempPertialSchedule );
[3]569
570 //判定(カウンタ減少の場合)
571 sprintf(temporary,"%s>=(%s)",variable,JudgeNum);
[76]572 NumOpe(temporary,Type(),Type());
[3]573
574 //pop eax
[225]575 compiler.codeGenerator.op_pop(REG_EAX);
[3]576
[241]577 //jmpジャンプ先のオフセット値
578 compiler.codeGenerator.opfix_JmpPertialSchedule( pTempPertialSchedule2 );
[3]579
580 //cmp eax,0
[236]581 compiler.codeGenerator.op_cmp_value( sizeof(long), REG_EAX, 0 );
[3]582
583ErrorStep:
584
585 //je ...
[241]586 pTempPertialSchedule = compiler.codeGenerator.op_je( 0, sizeof(long), true );
[3]587
588 //レキシカルスコープをレベルアップ
[276]589 compiler.codeGenerator.lexicalScopes.Start( compiler.codeGenerator.GetNativeCodeSize(), LexicalScope::SCOPE_TYPE_FOR );
[3]590
591 //For内をコンパイル
592 CompileBuffer(0,COM_NEXT);
593
[248]594 compiler.codeGenerator.lexicalScopes.CallDestructorsOfScopeEnd();
[3]595
596 if(szNextVariable[0]){
597 if(lstrcmp(szNextVariable,variable)!=0){
[465]598 compiler.errorMessenger.Output(55,szNextVariable,cp);
[3]599 }
600 }
601
602 //jmp ...
[241]603 compiler.codeGenerator.op_jmp_continue();
[3]604
605 //レキシカルスコープをレベルダウン
[248]606 compiler.codeGenerator.lexicalScopes.End();
[3]607
[241]608 //jeジャンプ先のオフセット値
609 compiler.codeGenerator.opfix_JmpPertialSchedule( pTempPertialSchedule );
[3]610
611 //Continueアドレスを復元
[241]612 compiler.codeGenerator.ContinueAreaEnd();
[3]613}
614
[372]615void OpcodeForeach( const char *Parameter )
616{
617 Type resultType;
[381]618 char temporary[VN_SIZE],variable[VN_SIZE],collectionVar[VN_SIZE];
[372]619 bool isError = false;
[712]620 std::string elementTypeName;
[372]621
622 //第1パラメータを取得
[381]623 int i = 0;
624 GetCustomToken( variable, Parameter, i, ESC_IN, true );
[372]625 if(!Parameter[i]){
[465]626 compiler.errorMessenger.Output(12,"Foreach",cp);
[372]627 isError = true;
628 goto ErrorStep;
629 }
[381]630 i++;
[372]631
632 //第2パラメータを取得(in~)
[381]633 lstrcpy( collectionVar, Parameter + i );
[374]634
[712]635
636 Exception::TryCommand(); //Finallyで_System_ForeachEnumerator.Disposeするため
637
638 //Enumeratorの取得
639 sprintf(temporary,"_System_ForeachEnumerator=%s.GetEnumerator()", collectionVar );
640 OpcodeDim(temporary,DIMFLAG_INITDEBUGVAR);
641
642 //レキシカルスコープをレベルアップ
643 compiler.codeGenerator.lexicalScopes.Start( compiler.codeGenerator.GetNativeCodeSize(), LexicalScope::SCOPE_TYPE_FOR );
644
[373]645 {
646 Type collectionType;
[374]647 if( !NumOpe_GetType( collectionVar, Type(), collectionType ) )
[373]648 {
649 isError = true;
650 goto ErrorStep;
651 }
[720]652
653 Type elementType;
654 if( collectionType.GetClass().IsExpanded() )
655 {
656 // テンプレート展開されたジェネリッククラス
657 elementType = collectionType.GetClass().expandedClassActualTypeParameters[0];
658 }
659 else
660 {
661 // 通常のジェネリッククラス
662 elementType = collectionType.GetActualGenericType(0);
663 }
664
665 elementTypeName = compiler.TypeToString( elementType );
[712]666 }
[372]667
[712]668 if( !GetVarType( variable, resultType, false ) )
669 {
670
[373]671 // 未定義の場合は自動的に定義する
[712]672 sprintf(temporary,"%s=Nothing%c%c%s", variable, 1, ESC_AS, elementTypeName.c_str() );
[373]673 OpcodeDim(temporary,DIMFLAG_INITDEBUGVAR);
674 }
675
[372]676 //Continueアドレスのバックアップとセット
677 compiler.codeGenerator.ContinueAreaBegin();
678
679 // MoveNextメソッドを呼び出す
[712]680 NumOpe("_System_ForeachEnumerator.MoveNext()",Type(),Type());
[372]681
682 //pop eax
683 compiler.codeGenerator.op_pop(REG_EAX);
684
685 //cmp eax,0
686 compiler.codeGenerator.op_cmp_value( sizeof(long), REG_EAX, 0 );
687
688ErrorStep:
689
690 //je ...
691 const PertialSchedule *pTempPertialSchedule = compiler.codeGenerator.op_je( 0, sizeof(long), true );
692
[381]693 if( !isError )
694 {
695 // Currentプロパティから現在の値を取得
[712]696 sprintf( temporary, "%s=_System_ForeachEnumerator.Current%c%c%s", variable, 1, ESC_AS, elementTypeName.c_str() );
[381]697 Compile( temporary );
698 }
[372]699
700 //For内をコンパイル
701 CompileBuffer(0,COM_NEXT);
702
703 compiler.codeGenerator.lexicalScopes.CallDestructorsOfScopeEnd();
704
705 if(szNextVariable[0]){
706 if(lstrcmp(szNextVariable,variable)!=0){
[465]707 compiler.errorMessenger.Output(55,szNextVariable,cp);
[372]708 }
709 }
710
[381]711 if( !isError )
712 {
713 //jmp ...
714 compiler.codeGenerator.op_jmp_continue();
715 }
[372]716
717 //レキシカルスコープをレベルダウン
718 compiler.codeGenerator.lexicalScopes.End();
719
720 //jeジャンプ先のオフセット値
721 compiler.codeGenerator.opfix_JmpPertialSchedule( pTempPertialSchedule );
722
[712]723 //Disposeを呼んでTryスコープを終える
724 Exception::FinallyCommand();
725 Compile( "_System_ForeachEnumerator.Dispose()" );
726 Exception::EndTryCommand();
727
[372]728 //Continueアドレスを復元
729 compiler.codeGenerator.ContinueAreaEnd();
730}
731
[3]732void OpcodeDo(char *Parameter){
733 extern HANDLE hHeap;
[247]734 int i,i2,i3;
[3]735
[465]736 if(Parameter[0]) compiler.errorMessenger.Output(10,"Do",cp);
[3]737
738 //Continueアドレスのバックアップとセット
[241]739 compiler.codeGenerator.ContinueAreaBegin();
[3]740
741 //レキシカルスコープをレベルアップ
[276]742 compiler.codeGenerator.lexicalScopes.Start( compiler.codeGenerator.GetNativeCodeSize(), LexicalScope::SCOPE_TYPE_DO );
[3]743
744 //Do内をコンパイル
745 CompileBuffer(0,COM_LOOP);
746
[248]747 compiler.codeGenerator.lexicalScopes.CallDestructorsOfScopeEnd();
[3]748
[248]749 const PertialSchedule *pDoPertialSchedule = NULL;
[241]750
[3]751 extern char *basbuf;
752 char temporary[VN_SIZE];
753 for(i=cp-1;;i--){
754 if(IsCommandDelimitation(basbuf[i])){
755 i+=3;
756 if(!(basbuf[i]=='0'||basbuf[i]=='1')){
757 //無条件ループ
758 break;
759 }
760 i3=i;
761
762 for(i+=2,i2=0;;i++,i2++){
763 if(IsCommandDelimitation(basbuf[i])){
764 temporary[i2]=0;
765 break;
766 }
767 temporary[i2]=basbuf[i];
768 }
769
[76]770 Type tempType;
[676]771 bool isNeedHeapFreeStructure;
772 NumOpe( temporary, Type(), tempType, &isNeedHeapFreeStructure );
[3]773
[676]774 if( tempType.IsObject() )
775 {
776 // Boolean型にキャストする
777 Type booleanType( DEF_BOOLEAN );
778 CallCastOperatorProc( tempType, isNeedHeapFreeStructure, booleanType );
779 tempType = booleanType;
780 }
781
[76]782 if( tempType.IsDouble() ){
[3]783 //fld qword ptr[esp]
[225]784 compiler.codeGenerator.op_fld_ptr_esp(DEF_DOUBLE);
[3]785
786 //push 0
[225]787 compiler.codeGenerator.op_push_V(0);
[3]788
789 //fild dword ptr[esp]
[225]790 compiler.codeGenerator.op_fld_ptr_esp(DEF_LONG);
[3]791
792 //add esp,sizeof(double)+sizeof(long)
[225]793 compiler.codeGenerator.op_add_esp(sizeof(double)+sizeof(long));
[3]794
795 //fcompp
[225]796 compiler.codeGenerator.op_fcompp();
[3]797
798 //fnstsw ax
[225]799 compiler.codeGenerator.op_fnstsw_ax();
[3]800
801 //test ah,40
[225]802 compiler.codeGenerator.op_test_ah( (char)0x40 );
[3]803
804 if(basbuf[i3]=='0'){
805 //While
806
807 //jne 5(ループ終了)
[241]808 pDoPertialSchedule = compiler.codeGenerator.op_jne( 0, sizeof(char), true );
[3]809 }
810 else if(basbuf[i3]=='1'){
811 //Until
812
813 //je 5(ループ終了)
[241]814 pDoPertialSchedule = compiler.codeGenerator.op_je( 0, sizeof(char), true );
[3]815 }
816 }
[76]817 else if( tempType.IsSingle() ){
[3]818 //fld dword ptr[esp]
[225]819 compiler.codeGenerator.op_fld_ptr_esp(DEF_SINGLE);
[3]820
821 //push 0
[225]822 compiler.codeGenerator.op_push_V(0);
[3]823
824 //fild dword ptr[esp]
[225]825 compiler.codeGenerator.op_fld_ptr_esp(DEF_LONG);
[3]826
827 //add esp,sizeof(float)+sizeof(long)
[225]828 compiler.codeGenerator.op_add_esp(sizeof(float)+sizeof(long));
[3]829
830 //fcompp
[225]831 compiler.codeGenerator.op_fcompp();
[3]832
833 //fnstsw ax
[225]834 compiler.codeGenerator.op_fnstsw_ax();
[3]835
836 //test ah,40
[225]837 compiler.codeGenerator.op_test_ah( (char)0x40 );
[3]838
839 if(basbuf[i3]=='0'){
840 //While
841
842 //jne 5(ループ終了)
[241]843 pDoPertialSchedule = compiler.codeGenerator.op_jne( 0, sizeof(char), true );
[3]844 }
845 else if(basbuf[i3]=='1'){
846 //Until
847
848 //je 5(ループ終了)
[241]849 pDoPertialSchedule = compiler.codeGenerator.op_je( 0, sizeof(char), true );
[3]850 }
851 }
[76]852 else if( tempType.Is64() ){
[3]853 //64ビット型
854
855 //pop eax
[225]856 compiler.codeGenerator.op_pop(REG_EAX);
[3]857
858 //pop ebx
[225]859 compiler.codeGenerator.op_pop(REG_EBX);
[3]860
861 //cmp eax,0
[236]862 compiler.codeGenerator.op_cmp_value( sizeof(long), REG_EAX, 0 );
[3]863
864 //jne
[248]865 const PertialSchedule *pTempPertialSchedule1 = compiler.codeGenerator.op_jne( 0, sizeof(char), true );
[3]866
867 //cmp ebx,0
[236]868 compiler.codeGenerator.op_cmp_value( sizeof(long), REG_EBX, 0 );
[3]869
870 //jne
[248]871 const PertialSchedule *pTempPertialSchedule2 = compiler.codeGenerator.op_jne( 0, sizeof(char), true );
[3]872
873 if(basbuf[i3]=='0'){
874 //While
875
876 //jmp 5(ループ終了)
[241]877 pDoPertialSchedule = compiler.codeGenerator.op_jmp( 0, sizeof(char), true );
[3]878
[247]879 compiler.codeGenerator.opfix_JmpPertialSchedule( pTempPertialSchedule1 );
880 compiler.codeGenerator.opfix_JmpPertialSchedule( pTempPertialSchedule2 );
[3]881 }
882 else if(basbuf[i3]=='1'){
883 //Until
884
885 //jmp 2(ループを続ける)
[248]886 const PertialSchedule *pTempPertialSchedule3 = compiler.codeGenerator.op_jmp( 0, sizeof(char), true );
[3]887
[247]888 compiler.codeGenerator.opfix_JmpPertialSchedule( pTempPertialSchedule1 );
889 compiler.codeGenerator.opfix_JmpPertialSchedule( pTempPertialSchedule2 );
[3]890
891 //jmp 5(ループ終了)
[241]892 pDoPertialSchedule = compiler.codeGenerator.op_jmp( 0, sizeof(char), true );
[247]893
894 compiler.codeGenerator.opfix_JmpPertialSchedule( pTempPertialSchedule3 );
[3]895 }
896 }
897 else{
898 //pop eax
[225]899 compiler.codeGenerator.op_pop(REG_EAX);
[3]900
901 //cmp eax,0
[236]902 compiler.codeGenerator.op_cmp_value( sizeof(long), REG_EAX, 0 );
[3]903
904 if(basbuf[i3]=='0'){
905 //While
906
907 //je 5(ループ終了)
[241]908 pDoPertialSchedule = compiler.codeGenerator.op_je( 0, sizeof(char), true );
[3]909 }
910 else if(basbuf[i3]=='1'){
911 //Until
912
913 //jne 5(ループ終了)
[241]914 pDoPertialSchedule = compiler.codeGenerator.op_jne( 0, sizeof(char), true );
[3]915 }
916 }
917 break;
918 }
919 }
920
921 //jmp ...
[241]922 compiler.codeGenerator.op_jmp_continue();
[3]923
[241]924 if( pDoPertialSchedule )
925 {
926 compiler.codeGenerator.opfix_JmpPertialSchedule( pDoPertialSchedule );
927 }
928
[3]929 //jmp ...
[248]930 const PertialSchedule *pTempPertialSchedule = compiler.codeGenerator.op_jmp( 0, sizeof(long), true );
[3]931
932 //レキシカルスコープをレベルダウン
[248]933 compiler.codeGenerator.lexicalScopes.End();
[3]934
[243]935 //jmpジャンプ先のオフセット値
936 compiler.codeGenerator.opfix_JmpPertialSchedule( pTempPertialSchedule );
[3]937
938 //Continueアドレスを復元
[241]939 compiler.codeGenerator.ContinueAreaEnd();
[3]940}
941void OpcodeContinue(void){
942 //jmp ...(Continue addr)
[241]943 compiler.codeGenerator.op_jmp_continue();
[3]944}
945
946void OpcodeExitSub(void){
[537]947 if( compiler.IsGlobalAreaCompiling() ){
[465]948 compiler.errorMessenger.Output(12,"Exit Sub/Function",cp);
[3]949 return;
950 }
951
[34]952 //未解放のローカルオブジェクトのデストラクタを呼び出す
[248]953 compiler.codeGenerator.lexicalScopes.CallDestructorsOfReturn();
[34]954
[3]955 //jmp ...(End Sub/Function)
[247]956 compiler.codeGenerator.op_jmp_exitsub();
[3]957}
958
[250]959//Caseスケジュール
960class SelectSchedule
961{
962public:
963 SelectSchedule( int typeSize )
964 : typeSize( typeSize )
965 , nowCaseSchedule( 0 )
966 {
967 }
[3]968
[250]969 PertialSchedules casePertialSchedules;
970 int typeSize;
971 int nowCaseSchedule;
972};
973std::vector<SelectSchedule> selectSchedules;
[3]974
[408]975void OpcodeSelect(const char *lpszParms)
976{
[3]977 extern HANDLE hHeap;
978 extern char *basbuf;
[76]979 int i,i2,i3,sw,NowCaseCp;
[3]980 char temporary[VN_SIZE];
[250]981
[76]982 Type type1;
[408]983 bool result = NumOpe(lpszParms,Type(), type1 );
[3]984
[250]985 selectSchedules.push_back( SelectSchedule( type1.GetSize() ) );
986
[408]987 if( result )
988 {
989 if( selectSchedules.back().typeSize < sizeof(long) ){
990 selectSchedules.back().typeSize = sizeof(long);
991 }
[76]992
[408]993 for(i=cp,sw=0;;i++){
994 if(basbuf[i]=='\0'){
995 selectSchedules.pop_back();
[465]996 compiler.errorMessenger.Output(22,"Select",cp);
[408]997 return;
998 }
999 if(basbuf[i]==1&&basbuf[i+1]==ESC_SELECTCASE){
1000 for(i2=0;;i++){
1001 if(basbuf[i]==1&&basbuf[i+1]==ESC_SELECTCASE) i2++;
1002 if(basbuf[i]==1&&basbuf[i+1]==ESC_ENDSELECT){
1003 i2--;
1004 if(i2==0) break;
1005 }
[3]1006 }
[408]1007 continue;
[3]1008 }
[408]1009 if(basbuf[i]==1&&basbuf[i+1]==ESC_ENDSELECT){
1010 if(sw==0){
1011 //add esp,CaseTypeSize
1012 compiler.codeGenerator.op_add_esp( selectSchedules.back().typeSize );
1013 }
1014 break;
[3]1015 }
[408]1016 if(basbuf[i]==1&&basbuf[i+1]==ESC_CASE){
1017 NowCaseCp=i;
[3]1018
[408]1019 i++;
1020 while(1){
1021 for(i++,i2=0;;i++,i2++){
1022 if(basbuf[i]=='\"'){
1023 i3=GetStringInQuotation(temporary+i2,basbuf+i);
1024 i+=i3-1;
1025 i2+=i3-1;
1026 continue;
1027 }
1028 if(basbuf[i]=='('){
1029 i3=GetStringInPare(temporary+i2,basbuf+i);
1030 i+=i3-1;
1031 i2+=i3-1;
1032 continue;
1033 }
1034 if(basbuf[i]=='['){
1035 i3=GetStringInBracket(temporary+i2,basbuf+i);
1036 i+=i3-1;
1037 i2+=i3-1;
1038 continue;
1039 }
[3]1040
[408]1041 if(IsCommandDelimitation(basbuf[i])){
1042 temporary[i2]=0;
1043 break;
1044 }
1045 if(basbuf[i]==','){
1046 temporary[i2]=0;
1047 break;
1048 }
1049
1050 temporary[i2]=basbuf[i];
[3]1051 }
1052
[408]1053 //エラー用
1054 i2=cp;
1055 cp=NowCaseCp;
[3]1056
[408]1057 Type type2;
1058 if( !NumOpe(temporary,type1,type2) ){
1059 return;
1060 }
[3]1061
[408]1062 cp=i2;
[3]1063
[408]1064 if(type1.IsObject()){
1065 std::vector<const UserProc *> subs;
1066 type1.GetClass().GetDynamicMethods().Enum( CALC_EQUAL, subs );
1067 if( subs.size() == 0 ){
1068 return;
1069 }
[3]1070
[408]1071 Parameters params;
1072 params.push_back( new Parameter( "", Type( type2 ) ) );
[3]1073
[408]1074 //オーバーロードを解決
[424]1075 const UserProc *pUserProc = OverloadSolution( "==", subs, params, Type( DEF_BOOLEAN ), type1 );
[3]1076
[408]1077 delete params[0];
[3]1078
[408]1079 if(!pUserProc){
1080 //エラー
1081 return;
1082 }
[75]1083
[3]1084
[408]1085 //pop edx
1086 compiler.codeGenerator.op_pop(REG_EDX);
[3]1087
[408]1088 //mov ecx,dword ptr[esp]
1089 compiler.codeGenerator.op_mov_RM(sizeof(long),REG_ECX,REG_ESP,0,MOD_BASE);
[3]1090
[408]1091 //push edx
1092 compiler.codeGenerator.op_push(REG_EDX);
[3]1093
[408]1094 //push ecx
1095 compiler.codeGenerator.op_push(REG_ECX);
[3]1096
[408]1097 //call operator_proc ※ ==演算子
1098 compiler.codeGenerator.op_call(pUserProc);
[3]1099
[408]1100 //test eax,eax
1101 compiler.codeGenerator.op_test(REG_EAX,REG_EAX);
[3]1102
[408]1103 //jne ...
1104 selectSchedules.back().casePertialSchedules.push_back(
1105 compiler.codeGenerator.op_jne( 0, sizeof(long), true )
1106 );
1107 }
1108 else if(type1.IsDouble()){
1109 ChangeTypeToDouble(type2.GetBasicType());
[3]1110
[408]1111 //fld qword ptr[esp]
1112 compiler.codeGenerator.op_fld_ptr_esp(DEF_DOUBLE);
[3]1113
[408]1114 //add esp,CaseTypeSize
1115 compiler.codeGenerator.op_add_esp(selectSchedules.back().typeSize);
[3]1116
[408]1117 //fld qword ptr[esp]
1118 compiler.codeGenerator.op_fld_ptr_esp(DEF_DOUBLE);
[3]1119
[408]1120 //fcompp
1121 compiler.codeGenerator.op_fcompp();
[3]1122
[408]1123 //fnstsw ax
1124 compiler.codeGenerator.op_fnstsw_ax();
[3]1125
[408]1126 //test ah,40
1127 compiler.codeGenerator.op_test_ah( (char)0x40 );
[3]1128
[408]1129 //jne ...
1130 selectSchedules.back().casePertialSchedules.push_back(
1131 compiler.codeGenerator.op_jne( 0, sizeof(long), true )
1132 );
1133 }
1134 else if(type1.IsSingle()){
1135 ChangeTypeToSingle(type2.GetBasicType());
[3]1136
[408]1137 //fld dword ptr[esp]
1138 compiler.codeGenerator.op_fld_ptr_esp(DEF_SINGLE);
[3]1139
[408]1140 //add esp,CaseTypeSize
1141 compiler.codeGenerator.op_add_esp(selectSchedules.back().typeSize);
[3]1142
[408]1143 //fld dword ptr[esp]
1144 compiler.codeGenerator.op_fld_ptr_esp(DEF_SINGLE);
[3]1145
[408]1146 //fcompp
1147 compiler.codeGenerator.op_fcompp();
[3]1148
[408]1149 //fnstsw ax
1150 compiler.codeGenerator.op_fnstsw_ax();
[3]1151
[408]1152 //test ah,40
1153 compiler.codeGenerator.op_test_ah( (char)0x40 );
[3]1154
[408]1155 //jne ...
1156 selectSchedules.back().casePertialSchedules.push_back(
1157 compiler.codeGenerator.op_jne( 0, sizeof(long), true )
1158 );
1159 }
1160 else{
1161 //その他整数型
[3]1162
[408]1163 //pop ebx
1164 compiler.codeGenerator.op_pop(REG_EBX);
[3]1165
[408]1166 //mov eax,dword ptr[esp]
1167 compiler.codeGenerator.op_mov_RM( sizeof(long), REG_EAX, REG_ESP, 0, MOD_BASE );
[3]1168
[408]1169 //cmp eax,ebx
1170 compiler.codeGenerator.op_cmp_RR( REG_EAX, REG_EBX );
[3]1171
[408]1172 //je ...
1173 selectSchedules.back().casePertialSchedules.push_back(
1174 compiler.codeGenerator.op_je( 0, sizeof(long), true )
1175 );
1176 }
[3]1177
[408]1178 if(basbuf[i]!=',') break;
[3]1179 }
[408]1180 }
1181 if(basbuf[i]==1&&basbuf[i+1]==ESC_CASEELSE){
1182 sw=1;
[3]1183
[408]1184 //jmp ...
1185 selectSchedules.back().casePertialSchedules.push_back(
1186 compiler.codeGenerator.op_jmp( 0, sizeof(long), true )
1187 );
[3]1188 }
1189 }
1190 }
1191
1192 //レキシカルスコープをレベルアップ
[276]1193 compiler.codeGenerator.lexicalScopes.Start( compiler.codeGenerator.GetNativeCodeSize(), LexicalScope::SCOPE_TYPE_SELECT );
[3]1194
1195 //Select Case内をコンパイル
1196 CompileBuffer(ESC_ENDSELECT,0);
1197
1198 //jmp EndSelect
[250]1199 selectSchedules.back().casePertialSchedules.push_back(
1200 compiler.codeGenerator.op_jmp( 0, sizeof(long), true )
1201 );
[3]1202
1203 //最終スケジュール
[250]1204 for(i=selectSchedules.back().nowCaseSchedule;i<(int)selectSchedules.back().casePertialSchedules.size();i++){
1205 compiler.codeGenerator.opfix_JmpPertialSchedule( selectSchedules.back().casePertialSchedules[i] );
[3]1206 }
1207
1208 //レキシカルスコープをレベルダウン
[248]1209 compiler.codeGenerator.lexicalScopes.End();
[3]1210
[250]1211 selectSchedules.pop_back();
[3]1212}
1213void OpcodeCase(char *Parameter){
1214 int i;
1215
[250]1216 if(selectSchedules.back().typeSize==-1){
[465]1217 compiler.errorMessenger.Output(30,"Case",cp);
[3]1218 return;
1219 }
1220
1221 //jmp EndSelect
[250]1222 selectSchedules.back().casePertialSchedules.push_back(
1223 compiler.codeGenerator.op_jmp( 0, sizeof(long), true )
1224 );
[3]1225
1226 i=0;
1227 while(1){
1228 //Caseスケジュール
[250]1229 compiler.codeGenerator.opfix_JmpPertialSchedule( selectSchedules.back().casePertialSchedules[selectSchedules.back().nowCaseSchedule] );
1230 selectSchedules.back().nowCaseSchedule++;
[3]1231
1232 i=JumpOneParameter(Parameter,i);
1233 if(Parameter[i]=='\0') break;
1234 }
1235
1236 //add esp,CaseTypeSize
[250]1237 compiler.codeGenerator.op_add_esp(selectSchedules.back().typeSize);
[3]1238}
1239
1240void OpcodeGosub(char *Parameter){
1241 extern HANDLE hHeap;
1242 int i,LineNum;
1243
1244 if(Parameter[0]=='*'){
1245 i=GetLabelAddress(Parameter+1,0);
1246
[246]1247 if( i == -1 )
1248 {
1249 //jmp ...(schedule)
[253]1250 compiler.codeGenerator.op_jmp_goto_schedule( (const std::string)(Parameter + 1), 0, cp );
[3]1251 }
[246]1252 else
1253 {
1254 //jmp ...
[276]1255 compiler.codeGenerator.op_jmp(
1256 i-compiler.codeGenerator.GetNativeCodeSize(),
1257 sizeof(long),
1258 false,
1259 true
1260 );
[246]1261 }
[3]1262 }
1263 else{
1264 LineNum=atoi(Parameter);
1265 i=GetLabelAddress(0,LineNum);
1266
[246]1267 if( i == -1 )
1268 {
1269 //jmp ...(schedule)
[253]1270 compiler.codeGenerator.op_jmp_goto_schedule( "", LineNum, cp );
[3]1271 }
[246]1272 else
1273 {
1274 //jmp ...
[276]1275 compiler.codeGenerator.op_jmp(
1276 i-compiler.codeGenerator.GetNativeCodeSize(),
1277 sizeof(long),
1278 false,
1279 true
1280 );
[246]1281 }
[3]1282 }
1283}
1284void OpcodeReturn(char *Parameter){
[537]1285 if( compiler.IsGlobalAreaCompiling() ){
[3]1286 //Gosub~Returnとして扱う
1287
1288 //ret
[225]1289 compiler.codeGenerator.op_ret();
[3]1290 }
1291 else{
1292 //戻り値をセット
1293 if(Parameter[0]){
[537]1294 const UserProc &proc = compiler.GetCompilingUserProc();
[76]1295
[75]1296 const char *temp = "_System_ReturnValue";
[76]1297 if(proc.GetName()[0]==1&&proc.GetName()[1]==ESC_OPERATOR)
[75]1298 {
1299 }
[76]1300 else{
1301 temp=proc.GetName().c_str();
1302 }
[3]1303
[75]1304 char temporary[VN_SIZE];
1305 sprintf(temporary,"%s=%s",temp,Parameter);
1306 OpcodeCalc(temporary);
[3]1307 }
1308
1309 //プロシージャを抜け出す(C言語のreturnと同様の処理を行う)
1310 OpcodeExitSub();
1311 }
1312}
1313
1314
1315////////////
1316// ポインタ
1317
1318void OpcodeSetPtrData(char *Parameter,int type){
[76]1319 int i;
[3]1320 char temporary[VN_SIZE];
1321
1322 if(Parameter[0]=='('){
1323 i=JumpStringInPare(Parameter,1);
1324 if(Parameter[i+1]=='\0'){
1325 for(i=0;;i++){
1326 Parameter[i]=Parameter[i+1];
1327 if(Parameter[i]=='\0') break;
1328 }
1329 Parameter[i-1]=0;
1330 }
1331 }
1332
1333 //第1パラメータを取得
1334 i=GetOneParameter(Parameter,0,temporary);
1335 if(!Parameter[i]){
[465]1336 compiler.errorMessenger.Output(1,NULL,cp);
[3]1337 return;
1338 }
1339
[76]1340 Type resultType;
1341 if( !NumOpe(temporary,Type(),resultType) ){
1342 return;
1343 }
1344 if(!resultType.IsWhole()){
[465]1345 compiler.errorMessenger.Output(11,Parameter,cp);
[76]1346 return;
1347 }
[3]1348
[76]1349 ChangeTypeToLong( resultType.GetBasicType() );
1350
[3]1351 //第2パラメータを取得
1352 i=GetOneParameter(Parameter,i,temporary);
1353 if(Parameter[i]){
[465]1354 compiler.errorMessenger.Output(1,NULL,cp);
[3]1355 return;
1356 }
1357
[76]1358 if( !NumOpe(temporary,Type(),resultType) ){
1359 return;
1360 }
1361
[3]1362 if(type==DEF_DOUBLE){
[76]1363 ChangeTypeToDouble_ToFpuReg( resultType.GetBasicType() );
[3]1364
1365 //pop eax
[225]1366 compiler.codeGenerator.op_pop(REG_EAX);
[3]1367
1368 //fstp qword ptr[eax]
[236]1369 compiler.codeGenerator.PutOld(
1370 (char)0xDD,
1371 (char)0x18
1372 );
[3]1373 }
1374 else if(type==DEF_SINGLE){
[76]1375 ChangeTypeToSingle( resultType.GetBasicType() );
[3]1376
1377 //pop ebx
[225]1378 compiler.codeGenerator.op_pop(REG_EBX);
[3]1379
1380 //pop eax
[225]1381 compiler.codeGenerator.op_pop(REG_EAX);
[3]1382
1383 //mov dword ptr[eax],ebx
[225]1384 compiler.codeGenerator.op_mov_MR( sizeof(long), REG_EBX, REG_EAX, 0, MOD_BASE );
[3]1385 }
1386 else if(type==DEF_QWORD){
[76]1387 ChangeTypeToInt64( resultType.GetBasicType() );
[3]1388
1389 //pop ecx
[225]1390 compiler.codeGenerator.op_pop(REG_ECX);
[3]1391
1392 //pop ebx
[225]1393 compiler.codeGenerator.op_pop(REG_EBX);
[3]1394
1395 //pop eax
[225]1396 compiler.codeGenerator.op_pop(REG_EAX);
[3]1397
1398 //mov dword ptr[eax],ecx
[225]1399 compiler.codeGenerator.op_mov_MR( sizeof(long), REG_ECX, REG_EAX, 0, MOD_BASE );
[3]1400
1401 //mov dword ptr[eax+sizeof(long)],ebx
[225]1402 compiler.codeGenerator.op_mov_MR( sizeof(long), REG_EBX, REG_EAX, 0x04, MOD_BASE_DISP8 );
[3]1403 }
1404 else if(type==DEF_DWORD){
[76]1405 ChangeTypeToLong( resultType.GetBasicType() );
[3]1406
1407 //pop ebx
[225]1408 compiler.codeGenerator.op_pop(REG_EBX);
[3]1409
1410 //pop eax
[225]1411 compiler.codeGenerator.op_pop(REG_EAX);
[3]1412
1413 //mov dword ptr[eax],ebx
[225]1414 compiler.codeGenerator.op_mov_MR( sizeof(long), REG_EBX, REG_EAX, 0, MOD_BASE );
[3]1415 }
1416 else if(type==DEF_WORD){
[76]1417 ChangeTypeToLong( resultType.GetBasicType() );
[3]1418
1419 //pop ebx
[225]1420 compiler.codeGenerator.op_pop(REG_EBX);
[3]1421
1422 //pop eax
[225]1423 compiler.codeGenerator.op_pop(REG_EAX);
[3]1424
1425 //mov word ptr[eax],bx
[236]1426 compiler.codeGenerator.op_mov_MR( sizeof(short), REG_EBX, REG_EAX, 0, MOD_BASE );
[3]1427 }
1428 else if(type==DEF_BYTE){
[76]1429 ChangeTypeToLong( resultType.GetBasicType() );
[3]1430
1431 //pop ebx
[225]1432 compiler.codeGenerator.op_pop(REG_EBX);
[3]1433
1434 //pop eax
[225]1435 compiler.codeGenerator.op_pop(REG_EAX);
[3]1436
1437 //mov byte ptr[eax],bl
[236]1438 compiler.codeGenerator.op_mov_MR( sizeof(char), REG_EBX, REG_EAX, 0, MOD_BASE );
[3]1439 }
1440}
Note: See TracBrowser for help on using the repository browser.