source: dev/BasicCompiler64/Compile_Calc.cpp@ 62

Last change on this file since 62 was 62, checked in by dai_9181, 17 years ago

グローバル変数に対してByRefを指定できるようにした

File size: 7.8 KB
Line 
1#include "../BasicCompiler_Common/common.h"
2#include "Opcode.h"
3
4void SetVariableFromRax(int VarType,int CalcType,RELATIVE_VAR *pRelativeVar){
5 /////////////////////////////////////////////////
6 // raxの内容を変数にコピーするコードを抽出
7 /////////////////////////////////////////////////
8
9 if(VarType==DEF_BOOLEAN){
10 //bool
11 SetBooleanVariable(CalcType,pRelativeVar);
12 }
13 else if(VarType==DEF_SBYTE||VarType==DEF_BYTE || (isUnicode==false&&VarType==DEF_CHAR)){
14 //8ビット変数へalレジスタの内容を格納する
15 SetWholeVariable(sizeof(char),CalcType,pRelativeVar);
16 }
17 else if(VarType==DEF_INTEGER||VarType==DEF_WORD || (isUnicode&&VarType==DEF_CHAR)){
18 //16ビット変数へaxレジスタの内容を格納する
19 SetWholeVariable(sizeof(short),CalcType,pRelativeVar);
20 }
21 else if(VarType==DEF_LONG||VarType==DEF_DWORD){
22 //32ビット変数へeaxレジスタの内容を格納する
23 SetWholeVariable(sizeof(long),CalcType,pRelativeVar);
24 }
25 else if(VarType==DEF_INT64||VarType==DEF_QWORD||IsPtrType(VarType)){
26 //64ビット変数へraxレジスタの内容を格納する
27 SetWholeVariable(sizeof(_int64),CalcType,pRelativeVar);
28 }
29 else if(VarType==DEF_DOUBLE){
30 //Double型変数へスタックの内容を格納する
31 SetDoubleVariable(CalcType,pRelativeVar);
32 }
33 else if(VarType==DEF_SINGLE){
34 //Single型変数へスタックの内容を格納する
35 SetSingleVariable(CalcType,pRelativeVar);
36 }
37 else{
38 SetError(300,NULL,cp);
39 }
40}
41void OpcodeCalc(char *Command){
42 int i,i2,i3;
43 char variable[VN_SIZE];
44
45
46
47 //////////////////////////////////////
48 // インクリメント・デクリメント
49 //////////////////////////////////////
50
51 for(i=0;;i++){
52 if(Command[i]=='\"'){
53 //ダブルクォートは不正なのでエラー扱い
54 variable[i]=0;
55 SetError(3,variable,cp);
56 return;
57 }
58
59 if(Command[i]=='('){
60 i2=GetStringInPare(variable+i,Command+i);
61 i+=i2-1;
62 continue;
63 }
64 if(Command[i]=='['){
65 i2=GetStringInBracket(variable+i,Command+i);
66 i+=i2-1;
67 continue;
68 }
69 if(Command[i]=='\0'){
70
71 ///////////////////////////////////
72 // インクリメント・デクリメント
73 ///////////////////////////////////
74
75 if(i>2){
76 if(Command[i-2]=='+'&&Command[i-1]=='+'){
77 //インクリメント
78 variable[i-2]=0;
79 IncDec(CALC_ADDITION,variable,"1");
80 return;
81 }
82 else if(Command[i-2]=='-'&&Command[i-1]=='-'){
83 //デクリメント
84 variable[i-2]=0;
85 IncDec(CALC_SUBTRACTION,variable,"1");
86 return;
87 }
88 }
89
90
91 //先端部分の識別子をエラーキーワードにする
92 for(i=0;;i++){
93 if(!IsVariableChar(Command[i])){
94 variable[i]=0;
95 break;
96 }
97 variable[i]=Command[i];
98 }
99
100 LONG_PTR lp;
101 if(GetVarType(variable,&lp,0)!=-1){
102 //変数リストに該当したとき
103 SetError(1,NULL,cp);
104 }
105 else{
106 if(GetConstHash(variable)){
107 //定数リストに該当したとき
108 SetError(1,NULL,cp);
109 }
110 else{
111 //変数リスト、定数リストに該当しないとき
112 SetError(3,variable,cp);
113 }
114 }
115 return;
116 }
117
118 i2=GetCalcId(Command+i,&i3);
119 if(i2){
120 variable[i]=0;
121
122 if(Command[i]=='=') break;
123
124 if(Command[i+1+i3]=='='){
125 IncDec(i2,variable,Command+i+1+i3+1);
126 return;
127 }
128 }
129
130 variable[i]=Command[i];
131 }
132
133 if(Command[i+1]=='\0'){
134 SetError(1,NULL,cp);
135 return;
136 }
137
138
139
140 ///////////////////////////////////////////////////////////////
141 // インデクサのsetアクセサ([]=演算子のオーバーロードに対応)
142 ///////////////////////////////////////////////////////////////
143
144 char ObjName[VN_SIZE],array_element[VN_SIZE];
145 CClass *pobj_c;
146 GetArrayElement(variable,ObjName,array_element);
147 if(array_element[0]){
148 i2=GetVarType(ObjName,(LONG_PTR *)&pobj_c,0);
149 if(i2==DEF_OBJECT){
150 char temporary[VN_SIZE];
151 sprintf(temporary,"%s.%c%c%c",ObjName,1,ESC_OPERATOR,CALC_ARRAY_SET);
152
153 char temp2[VN_SIZE];
154 sprintf(temp2,"%s,%s",array_element,Command+i+1);
155
156 int idProc;
157 void *pInfo;
158 idProc=GetProc(temporary,&pInfo);
159 if(idProc){
160 CallProc(idProc,pInfo,temporary,temp2,NULL);
161 return;
162 }
163 }
164 }
165
166
167
168 ////////////////////////////////////////
169 // 変数のタイプ型を識別して、演算を行う
170 ////////////////////////////////////////
171
172 int VarType,CalcType;
173 LONG_PTR lpVarIndex,lpCalcIndex;
174 BOOL bCalcUseHeap;
175
176 //型を識別
177 VarType=GetVarType(variable,&lpVarIndex,0);
178 if(VarType==-1){
179
180 // プロパティ用のメソッドを呼び出す
181 if(!CallPropertyMethod(variable,Command+i+1,NULL)){
182 //エラーを表示
183 GetVarType(variable,&lpVarIndex,1);
184 }
185
186 return;
187 }
188
189 extern LONG_PTR ProcPtr_BaseIndex;
190 if(VarType==DEF_PTR_PROC) ProcPtr_BaseIndex=lpVarIndex;
191 else ProcPtr_BaseIndex=-1;
192
193 //NumOpe...(rax、またはxmm0に答えが格納される)
194 int reg=REG_RAX;
195 CalcType=NumOpe(&reg,Command+i+1,VarType,lpVarIndex,&lpCalcIndex,&bCalcUseHeap);
196
197 //結果を格納しているレジスタをブロッキング
198 pobj_BlockReg->lock(reg);
199
200 if(VarType==-1||CalcType==-1) return;
201
202 //変数アドレスを取得
203 RELATIVE_VAR VarRelativeVar;
204 if(!GetVarOffsetReadWrite(
205 variable,
206 &VarType,
207 &VarRelativeVar,
208 &lpVarIndex)) return;
209
210 //レジスタのブロッキングを解除
211 pobj_BlockReg->clear();
212
213 if(VarType&FLAG_PTR){
214 SetError(14,variable,cp);
215 return;
216 }
217
218 if(VarType==DEF_OBJECT){
219 //オブジェクトインスタンスへの代入
220 SetObjectVariableFromRax(lpVarIndex,CalcType,lpCalcIndex,&VarRelativeVar,bCalcUseHeap);
221 return;
222 }
223
224 if(CalcType==DEF_OBJECT){
225 //キャスト演算子のオーバーロードに対応する
226 CallCastOperatorProc(REG_RAX,CalcType,lpCalcIndex,bCalcUseHeap,VarType,lpVarIndex);
227 }
228
229
230 /////////////////////////////////
231 // 右辺、左辺の型チェックを行う
232 /////////////////////////////////
233
234 CheckDifferentType(VarType,lpVarIndex,CalcType,lpCalcIndex,0,0);
235
236
237 /////////////////////////////////////////////////
238 // rax(実数はxmm0)の内容を変数にコピー
239 /////////////////////////////////////////////////
240 SetVariableFromRax(VarType,CalcType,&VarRelativeVar);
241}
242
243void SetRefVariable( const char *varname, const char *expression ){
244 ////////////////////////////////////////
245 // 変数のタイプ型を識別して、演算を行う
246 ////////////////////////////////////////
247
248 int VarType,CalcType;
249 LONG_PTR lpVarIndex,lpCalcIndex;
250 BOOL bCalcUseHeap;
251
252 //型を識別
253 VarType=GetVarType(varname,&lpVarIndex,0);
254 if(VarType==-1){
255 SetError(300,NULL,cp);
256 return;
257 }
258
259 extern LONG_PTR ProcPtr_BaseIndex;
260 if(VarType==DEF_PTR_PROC) ProcPtr_BaseIndex=lpVarIndex;
261 else ProcPtr_BaseIndex=-1;
262
263 //NumOpe...(rax、またはxmm0に答えが格納される)
264 int reg=REG_RAX;
265 CalcType=NumOpe(&reg,expression,VarType,lpVarIndex,&lpCalcIndex,&bCalcUseHeap);
266
267 //結果を格納しているレジスタをブロッキング
268 pobj_BlockReg->lock(reg);
269
270 if(VarType==-1||CalcType==-1) return;
271
272 //変数アドレスを取得
273 RELATIVE_VAR VarRelativeVar;
274 if(!GetVarOffsetReadWrite(
275 varname,
276 &VarType,
277 &VarRelativeVar,
278 &lpVarIndex)) return;
279
280 //レジスタのブロッキングを解除
281 pobj_BlockReg->clear();
282
283 if(VarType&FLAG_PTR){
284 SetError(14,varname,cp);
285 return;
286 }
287
288 if( VarType == DEF_OBJECT
289 && (VarRelativeVar.dwKind == VAR_REFLOCAL || VarRelativeVar.dwKind == VAR_REFGLOBAL ) ){
290 // 参照型オブジェクトへの代入(初期化)はポインタ変数と同様の処理に値する
291 PTR_LEVEL_UP( VarType );
292
293 if( VarRelativeVar.dwKind == VAR_REFGLOBAL ){
294 VarRelativeVar.dwKind = VAR_GLOBAL;
295 }
296 else if( VarRelativeVar.dwKind == VAR_REFLOCAL ){
297 VarRelativeVar.dwKind = VAR_LOCAL;
298 }
299
300 if( CalcType == DEF_OBJECT ){
301 //右辺値が実体オブジェクトのときは、参照をコピー
302 PTR_LEVEL_UP( CalcType );
303 }
304 }
305 else{
306 SetError(300,NULL,cp);
307 }
308
309
310 /////////////////////////////////
311 // 右辺、左辺の型チェックを行う
312 /////////////////////////////////
313
314 CheckDifferentType(VarType,lpVarIndex,CalcType,lpCalcIndex,0,0);
315
316
317 /////////////////////////////////////////////////
318 // rax(実数はxmm0)の内容を変数にコピー
319 /////////////////////////////////////////////////
320 SetVariableFromRax(VarType,CalcType,&VarRelativeVar);
321}
Note: See TracBrowser for help on using the repository browser.