source: dev/BasicCompiler64/Compile_Calc.cpp@ 42

Last change on this file since 42 was 40, checked in by dai_9181, 18 years ago

ByRef修飾子を関数戻り値とDimステートメントで指定可能にした。

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