source: dev/trunk/abdev/BasicCompiler64/Compile_Calc.cpp@ 183

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