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

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