source: dev/trunk/ab5.0/abdev/compiler_x64/Compile_Calc.cpp@ 528

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

[522][527]を64bit版にマージ。

File size: 6.6 KB
RevLine 
[206]1#include "stdafx.h"
2
[198]3#include <Compiler.h>
4
[3]5#include "../BasicCompiler_Common/common.h"
6#include "Opcode.h"
7
[308]8void SetVariableFromRax( const Type &varType, int CalcType,RELATIVE_VAR *pRelativeVar){
[3]9 /////////////////////////////////////////////////
10 // raxの内容を変数にコピーするコードを抽出
11 /////////////////////////////////////////////////
12
[308]13 if( varType.IsBoolean() )
14 {
[36]15 //bool
16 SetBooleanVariable(CalcType,pRelativeVar);
17 }
[308]18 else if( varType.IsReal() )
19 {
[64]20 // Double/Single型変数へレジスタの値を代入
[308]21 SetRealVariable(varType.GetBasicType(), CalcType, pRelativeVar);
[3]22 }
[308]23 else if( varType.IsWhole() || varType.IsObject() )
24 {
[64]25 //整数変数へraxの値を格納する
[308]26 SetWholeVariable( varType.GetSize(), CalcType, pRelativeVar );
[3]27 }
[55]28 else{
[468]29 compiler.errorMessenger.Output(300,NULL,cp);
[55]30 }
[3]31}
[129]32void OpcodeCalc(const char *Command){
[3]33 int i,i2,i3;
34 char variable[VN_SIZE];
35
36
37 //////////////////////////////////////
38 // インクリメント・デクリメント
39 //////////////////////////////////////
40
41 for(i=0;;i++){
42 if(Command[i]=='\"'){
43 //ダブルクォートは不正なのでエラー扱い
44 variable[i]=0;
[468]45 compiler.errorMessenger.Output(3,variable,cp);
[3]46 return;
47 }
48
49 if(Command[i]=='('){
50 i2=GetStringInPare(variable+i,Command+i);
51 i+=i2-1;
52 continue;
53 }
54 if(Command[i]=='['){
55 i2=GetStringInBracket(variable+i,Command+i);
56 i+=i2-1;
57 continue;
58 }
59 if(Command[i]=='\0'){
60
61 ///////////////////////////////////
62 // インクリメント・デクリメント
63 ///////////////////////////////////
64
65 if(i>2){
66 if(Command[i-2]=='+'&&Command[i-1]=='+'){
67 //インクリメント
68 variable[i-2]=0;
69 IncDec(CALC_ADDITION,variable,"1");
70 return;
71 }
72 else if(Command[i-2]=='-'&&Command[i-1]=='-'){
73 //デクリメント
74 variable[i-2]=0;
75 IncDec(CALC_SUBTRACTION,variable,"1");
76 return;
77 }
78 }
79
80
81 //先端部分の識別子をエラーキーワードにする
82 for(i=0;;i++){
83 if(!IsVariableChar(Command[i])){
84 variable[i]=0;
85 break;
86 }
87 variable[i]=Command[i];
88 }
89
[75]90 if(GetVarType(variable,Type(),0)){
[3]91 //変数リストに該当したとき
[468]92 compiler.errorMessenger.Output(1,NULL,cp);
[3]93 }
94 else{
[266]95 if( compiler.GetObjectModule().meta.GetGlobalConsts().IsExist(variable)
96 || compiler.GetObjectModule().meta.GetGlobalConstMacros().IsExist(variable) )
[206]97 {
[3]98 //定数リストに該当したとき
[468]99 compiler.errorMessenger.Output(1,NULL,cp);
[3]100 }
101 else{
102 //変数リスト、定数リストに該当しないとき
[468]103 compiler.errorMessenger.Output(3,variable,cp);
[3]104 }
105 }
106 return;
107 }
108
109 i2=GetCalcId(Command+i,&i3);
110 if(i2){
111 variable[i]=0;
112
113 if(Command[i]=='=') break;
114
115 if(Command[i+1+i3]=='='){
116 IncDec(i2,variable,Command+i+1+i3+1);
117 return;
118 }
119 }
120
121 variable[i]=Command[i];
122 }
123
124 if(Command[i+1]=='\0'){
[468]125 compiler.errorMessenger.Output(1,NULL,cp);
[3]126 return;
127 }
128
129
130
131 ///////////////////////////////////////////////////////////////
132 // インデクサのsetアクセサ([]=演算子のオーバーロードに対応)
133 ///////////////////////////////////////////////////////////////
134
135 char ObjName[VN_SIZE],array_element[VN_SIZE];
136 GetArrayElement(variable,ObjName,array_element);
137 if(array_element[0]){
[75]138 Type varType;
139 if( GetVarType(ObjName,varType,0) && varType.IsObject() ){
[3]140 char temporary[VN_SIZE];
141 sprintf(temporary,"%s.%c%c%c",ObjName,1,ESC_OPERATOR,CALC_ARRAY_SET);
142
143 char temp2[VN_SIZE];
144 sprintf(temp2,"%s,%s",array_element,Command+i+1);
145
146 int idProc;
[75]147 void *pProc;
148 idProc=GetProc(temporary,(void **)&pProc);
[331]149 if( idProc )
150 {
151 CallProc(
152 idProc,
153 pProc,
154 temporary,
155 temp2,
156 Type(), // ベースタイプはなし
157 Type()
158 );
[3]159 return;
160 }
161 }
162 }
163
164
[64]165 if( lstrcmpi( variable, "This" ) == 0 ){
[468]166 compiler.errorMessenger.Output(133,NULL,cp);
[64]167 return;
168 }
[3]169
[64]170
[3]171 ////////////////////////////////////////
172 // 変数のタイプ型を識別して、演算を行う
173 ////////////////////////////////////////
174
[75]175 Type varType;
[3]176
177 //型を識別
[416]178 if( !GetTermTypeOnlyVariable(variable,varType) ){
[3]179
180 // プロパティ用のメソッドを呼び出す
[75]181 if(!CallPropertyMethod( variable, Command+i+1, Type() )){
[3]182 //エラーを表示
[75]183 GetVarType(variable,varType,true);
[3]184 }
185
186 return;
187 }
188
189 //NumOpe...(rax、またはxmm0に答えが格納される)
190 int reg=REG_RAX;
[75]191 Type calcType;
[436]192 bool isNeedHeapFreeStructure;
193 if( !NumOpe(&reg,Command+i+1,varType,calcType,&isNeedHeapFreeStructure) ){
[75]194 return;
195 }
[3]196
[75]197 if(reg!=REG_RAX&&calcType.IsWhole()||
198 varType.IsNull()||calcType.IsNull()){
[468]199 compiler.errorMessenger.Output(300,NULL,cp);
[64]200 }
201
[3]202 //結果を格納しているレジスタをブロッキング
203 pobj_BlockReg->lock(reg);
204
205 //変数アドレスを取得
[417]206 RELATIVE_VAR VarRelativeVar;
[416]207 if( !TermOpeOnlyVariable( variable, varType, VarRelativeVar, true ) )
208 {
[468]209 compiler.errorMessenger.OutputFatalError();
[416]210 return;
211 }
[3]212
213 //レジスタのブロッキングを解除
214 pobj_BlockReg->clear();
215
[75]216 if(varType.GetBasicType()&FLAG_PTR){
[468]217 compiler.errorMessenger.Output(14,variable,cp);
[3]218 return;
219 }
220
[75]221 if( varType.IsStruct() ){
[64]222 //構造体インスタンスへの代入
[436]223 SetStructVariableFromRax(varType,calcType,&VarRelativeVar,isNeedHeapFreeStructure);
[3]224 return;
225 }
226
[75]227 if( calcType.IsObject() && !calcType.Equals( varType ) ){
[116]228 bool isUpCast = false;
229 if( varType.IsObject() ){
230 if( varType.GetClass().IsEqualsOrSubClass( &calcType.GetClass() ) ){
231 isUpCast = true;
232 }
233 }
234 if( !isUpCast ){
235 //キャスト演算子のオーバーロードに対応する
[436]236 CallCastOperatorProc(REG_RAX,calcType,isNeedHeapFreeStructure,varType);
[116]237 }
[3]238 }
239
[266]240 if( varType.IsObject() && compiler.GetObjectModule().meta.GetBlittableTypes().IsExist( calcType ) ){
[128]241 // Blittable型をオブジェクトとして扱う
[528]242 std::vector<const UserProc *> userProcs;
[266]243 compiler.GetObjectModule().meta.GetBlittableTypes().GetClass( calcType ).GetStaticMethods().Enum( "_Create", userProcs );
[128]244 if( userProcs.size() != 1 ){
[468]245 compiler.errorMessenger.OutputFatalError();
[128]246 return;
247 }
[206]248 const UserProc *pUserProc = userProcs[0];
[3]249
[128]250 // mov rcx, rax
[226]251 compiler.codeGenerator.op_mov_RR( REG_RCX, REG_RAX );
[128]252
253 // call System.[TypeClass]._Create
[226]254 compiler.codeGenerator.op_call( pUserProc );
[128]255
256 calcType = pUserProc->ReturnType();
257 }
258
[3]259 /////////////////////////////////
260 // 右辺、左辺の型チェックを行う
261 /////////////////////////////////
262
[75]263 CheckDifferentType(varType,calcType,0,0);
[3]264
265
266 /////////////////////////////////////////////////
267 // rax(実数はxmm0)の内容を変数にコピー
268 /////////////////////////////////////////////////
[308]269 SetVariableFromRax(varType,calcType.GetBasicType(),&VarRelativeVar);
[436]270
271
272 // コード生成過程で発生した構造体の一時メモリを破棄する
273 compiler.codeGenerator.op_FreeTempStructure();
[3]274}
Note: See TracBrowser for help on using the repository browser.