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

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

[416]のコミットによって発生した64bit版での不具合を修正。

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