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
Line 
1#include "stdafx.h"
2
3#include <Compiler.h>
4
5#include "../BasicCompiler_Common/common.h"
6#include "Opcode.h"
7
8void SetVariableFromRax( const Type &varType, int CalcType,RELATIVE_VAR *pRelativeVar){
9 /////////////////////////////////////////////////
10 // raxの内容を変数にコピーするコードを抽出
11 /////////////////////////////////////////////////
12
13 if( varType.IsBoolean() )
14 {
15 //bool
16 SetBooleanVariable(CalcType,pRelativeVar);
17 }
18 else if( varType.IsReal() )
19 {
20 // Double/Single型変数へレジスタの値を代入
21 SetRealVariable(varType.GetBasicType(), CalcType, pRelativeVar);
22 }
23 else if( varType.IsWhole() || varType.IsObject() )
24 {
25 //整数変数へraxの値を格納する
26 SetWholeVariable( varType.GetSize(), CalcType, pRelativeVar );
27 }
28 else{
29 compiler.errorMessenger.Output(300,NULL,cp);
30 }
31}
32void OpcodeCalc(const char *Command){
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;
45 compiler.errorMessenger.Output(3,variable,cp);
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
90 if(GetVarType(variable,Type(),0)){
91 //変数リストに該当したとき
92 compiler.errorMessenger.Output(1,NULL,cp);
93 }
94 else{
95 if( compiler.GetObjectModule().meta.GetGlobalConsts().IsExist(variable)
96 || compiler.GetObjectModule().meta.GetGlobalConstMacros().IsExist(variable) )
97 {
98 //定数リストに該当したとき
99 compiler.errorMessenger.Output(1,NULL,cp);
100 }
101 else{
102 //変数リスト、定数リストに該当しないとき
103 compiler.errorMessenger.Output(3,variable,cp);
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'){
125 compiler.errorMessenger.Output(1,NULL,cp);
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]){
138 Type varType;
139 if( GetVarType(ObjName,varType,0) && varType.IsObject() ){
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;
147 void *pProc;
148 idProc=GetProc(temporary,(void **)&pProc);
149 if( idProc )
150 {
151 CallProc(
152 idProc,
153 pProc,
154 temporary,
155 temp2,
156 Type(), // ベースタイプはなし
157 Type()
158 );
159 return;
160 }
161 }
162 }
163
164
165 if( lstrcmpi( variable, "This" ) == 0 ){
166 compiler.errorMessenger.Output(133,NULL,cp);
167 return;
168 }
169
170
171 ////////////////////////////////////////
172 // 変数のタイプ型を識別して、演算を行う
173 ////////////////////////////////////////
174
175 Type varType;
176
177 //型を識別
178 if( !GetTermTypeOnlyVariable(variable,varType) ){
179
180 // プロパティ用のメソッドを呼び出す
181 if(!CallPropertyMethod( variable, Command+i+1, Type() )){
182 //エラーを表示
183 GetVarType(variable,varType,true);
184 }
185
186 return;
187 }
188
189 //NumOpe...(rax、またはxmm0に答えが格納される)
190 int reg=REG_RAX;
191 Type calcType;
192 bool isNeedHeapFreeStructure;
193 if( !NumOpe(&reg,Command+i+1,varType,calcType,&isNeedHeapFreeStructure) ){
194 return;
195 }
196
197 if(reg!=REG_RAX&&calcType.IsWhole()||
198 varType.IsNull()||calcType.IsNull()){
199 compiler.errorMessenger.Output(300,NULL,cp);
200 }
201
202 //結果を格納しているレジスタをブロッキング
203 pobj_BlockReg->lock(reg);
204
205 //変数アドレスを取得
206 RELATIVE_VAR VarRelativeVar;
207 if( !TermOpeOnlyVariable( variable, varType, VarRelativeVar, true ) )
208 {
209 compiler.errorMessenger.OutputFatalError();
210 return;
211 }
212
213 //レジスタのブロッキングを解除
214 pobj_BlockReg->clear();
215
216 if(varType.GetBasicType()&FLAG_PTR){
217 compiler.errorMessenger.Output(14,variable,cp);
218 return;
219 }
220
221 if( varType.IsStruct() ){
222 //構造体インスタンスへの代入
223 SetStructVariableFromRax(varType,calcType,&VarRelativeVar,isNeedHeapFreeStructure);
224 return;
225 }
226
227 if( calcType.IsObject() && !calcType.Equals( varType ) ){
228 bool isUpCast = false;
229 if( varType.IsObject() ){
230 if( varType.GetClass().IsEqualsOrSubClass( &calcType.GetClass() ) ){
231 isUpCast = true;
232 }
233 }
234 if( !isUpCast ){
235 //キャスト演算子のオーバーロードに対応する
236 CallCastOperatorProc(REG_RAX,calcType,isNeedHeapFreeStructure,varType);
237 }
238 }
239
240 if( varType.IsObject() && compiler.GetObjectModule().meta.GetBlittableTypes().IsExist( calcType ) ){
241 // Blittable型をオブジェクトとして扱う
242 std::vector<const UserProc *> userProcs;
243 compiler.GetObjectModule().meta.GetBlittableTypes().GetClass( calcType ).GetStaticMethods().Enum( "_Create", userProcs );
244 if( userProcs.size() != 1 ){
245 compiler.errorMessenger.OutputFatalError();
246 return;
247 }
248 const UserProc *pUserProc = userProcs[0];
249
250 // mov rcx, rax
251 compiler.codeGenerator.op_mov_RR( REG_RCX, REG_RAX );
252
253 // call System.[TypeClass]._Create
254 compiler.codeGenerator.op_call( pUserProc );
255
256 calcType = pUserProc->ReturnType();
257 }
258
259 /////////////////////////////////
260 // 右辺、左辺の型チェックを行う
261 /////////////////////////////////
262
263 CheckDifferentType(varType,calcType,0,0);
264
265
266 /////////////////////////////////////////////////
267 // rax(実数はxmm0)の内容を変数にコピー
268 /////////////////////////////////////////////////
269 SetVariableFromRax(varType,calcType.GetBasicType(),&VarRelativeVar);
270
271
272 // コード生成過程で発生した構造体の一時メモリを破棄する
273 compiler.codeGenerator.op_FreeTempStructure();
274}
Note: See TracBrowser for help on using the repository browser.