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

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