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

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

コード全体のリファクタリングを実施

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