source: dev/trunk/ab5.0/abdev/BasicCompiler_Common/src/DataTableGenerator.cpp@ 745

Last change on this file since 745 was 745, checked in by dai, 16 years ago
  • Compiler::AddStringToDataTableメソッドを実装。
  • ToWStringメソッドの内部予備バッファを増やした。
File size: 7.9 KB
Line 
1#include "stdafx.h"
2
3using namespace ActiveBasic::Compiler;
4
5int DataTableGenerator::lastMadeConstObjectDataTableOffset = 0;
6
7bool DataTableGenerator::MakeConstObjectToProcessStaticBuffer( DataTable &dataTable, const CClass &objClass, const Jenga::Common::Strings &initMemberValues, int &dataTableOffset )
8{
9 // クラスに必要なバッファサイズを取得
10 int size = objClass.GetSize();
11
12 // クラスのバッファイメージを作成
13 BYTE *buffer = (BYTE *)calloc( size, 1 );
14
15 // クラスのバッファイメージをデータ領域へ追加
16 dataTableOffset = dataTable.AddBinary( buffer, size );
17
18 DataTableGenerator::lastMadeConstObjectDataTableOffset = dataTableOffset;
19
20 // com_vtblスケジュール
21 dataTable.schedules.push_back( Schedule( Schedule::ComVtbl, &objClass, dataTableOffset ) );
22
23 // vtblスケジュール
24 dataTable.schedules.push_back( Schedule( Schedule::Vtbl, &objClass, dataTableOffset + PTR_SIZE ) );
25
26 // TypeInfoスケジュール
27 int offsetForTypeInfo = objClass.GetMemberOffset( "_system_object_member_typeInfo" );
28 //dataTable.schedules.push_back( Schedule( Schedule::TypeInfo, &objClass, dataTableOffset + offsetForTypeInfo ) );
29
30 BOOST_FOREACH( const std::string &initMemberValue, initMemberValues )
31 {
32 int i = 0;
33
34 // メンバ名
35 char memberName[VN_SIZE];
36 for( i=0; ; i++ )
37 {
38 if( initMemberValue[i] == '\0' )
39 {
40 // エラー
41 compiler.errorMessenger.OutputFatalError();
42 return false;
43 }
44 if( initMemberValue[i] == '=' )
45 {
46 memberName[i] = 0;
47 break;
48 }
49 memberName[i] = initMemberValue[i];
50 }
51
52 // 初期値
53 const char *initValue = initMemberValue.c_str() + i + 1;
54
55 // メンバを取得
56 const Member *member = objClass.FindDynamicMember( memberName );
57
58 // メンバオフセットを取得
59 int memberOffset = objClass.GetMemberOffset( member->GetName().c_str() );
60
61 if( member->GetType().IsPointer() && initValue[0] == '[' )
62 {
63 // ポインタ型でバッファ指定のとき
64 int memberDataTableOffset;
65 if( !MakeLiteralArrayBuffer( dataTable, initValue, member->GetType(),memberDataTableOffset ) )
66 {
67 return false;
68 }
69
70 dataTable.Overwrite( dataTableOffset + memberOffset, memberDataTableOffset );
71 dataTable.schedules.push_back( Schedule( Schedule::DataTable, dataTableOffset + memberOffset ) );
72 }
73 else if( member->GetType().IsWhole() )
74 {
75 // 整数
76 Type resultType;
77 _int64 i64data;
78 if( !StaticCalculation( true, initValue, member->GetType().GetBasicType(), &i64data, resultType ) ){
79 return false;
80 }
81
82 dataTable.Overwrite( dataTableOffset + memberOffset, static_cast<long>(i64data) );
83 }
84 else if( member->GetType().IsStringClass() )
85 {
86 // 文字列型
87 char temporary[VN_SIZE];
88 lstrcpy( temporary, initValue );
89 RemoveStringQuotes( temporary );
90 int memberDataTableOffset = MakeConstStringObjectToProcessStaticBuffer( dataTable, temporary );
91 dataTable.Overwrite( dataTableOffset + memberOffset, memberDataTableOffset );
92 dataTable.schedules.push_back( Schedule( Schedule::DataTable, dataTableOffset + memberOffset ) );
93 }
94 }
95
96 return true;
97}
98bool DataTableGenerator::MakeConstObjectToProcessStaticBuffer( DataTable &dataTable, const char *expression, Type &resultType, int &dataTableOffset )
99{
100 char CreateParameter[VN_SIZE];
101 int i,i2;
102
103 i=0;
104
105 // クラス名を取得
106 char typeName[VN_SIZE];
107 for(i2=0;;i++,i2++){
108 if(expression[i]=='['){
109 typeName[i2]=0;
110
111 // メンバの初期値を取得
112 i2=GetStringInBracket(CreateParameter,expression+i);
113 RemoveStringBracket(CreateParameter);
114 i+=i2;
115 if(expression[i]!='\0'){
116 compiler.errorMessenger.Output(42,NULL,cp);
117 return false;
118 }
119 break;
120 }
121 typeName[i2]=expression[i];
122 if(expression[i]=='\0'){
123 CreateParameter[0]=0;
124 break;
125 }
126 }
127
128 // パラメータを取得
129 Jenga::Common::Strings initMemberValues;
130 SplitParameter( CreateParameter, initMemberValues );
131
132 if( !compiler.StringToType( typeName, resultType ) ){
133 compiler.errorMessenger.Output(3,typeName,cp);
134 return false;
135 }
136
137 if( !resultType.IsObject() ){
138 ////////////////////////
139 // 通常のデータ型の場合
140 ////////////////////////
141
142 compiler.errorMessenger.Output(121,NULL,cp);
143 return false;
144 }
145
146 return MakeConstObjectToProcessStaticBuffer( dataTable, resultType.GetClass(), initMemberValues, dataTableOffset );
147}
148
149int DataTableGenerator::MakeConstStringObjectToProcessStaticBuffer( DataTable &dataTable, const char *str )
150{
151 const CClass &strClass = *compiler.GetObjectModule().meta.GetClasses().GetStringClassPtr();
152 const CClass &objClass = strClass.GetSuperClass();
153
154 // クラスに必要なバッファサイズを取得
155 int size = strClass.GetSize();
156
157 // メンバ位置を取得
158 int offsetForTypeInfo = strClass.GetMemberOffset( "_system_object_member_typeInfo" );
159 int offsetForLength = strClass.GetMemberOffset( "m_Length" );
160 int offsetForChars = strClass.GetMemberOffset( "Chars" );
161
162 // 現在のデータ領域のヘッダ位置を取得
163 int headOffset = dataTable.GetSize();
164
165 // クラスのバッファイメージを作成
166 BYTE *buffer = (BYTE *)calloc( size, 1 );
167 *(long *)(buffer + offsetForLength) = lstrlen( str );
168 *(LONG_PTR *)(buffer + offsetForChars) = headOffset + size;
169
170 // クラスのバッファイメージをデータ領域へ追加
171 int dataTableOffset = dataTable.AddBinary( buffer, size );
172
173 // スケジューリング
174 dataTable.schedules.push_back( Schedule( Schedule::ComVtbl, &strClass, headOffset ) );
175 dataTable.schedules.push_back( Schedule( Schedule::Vtbl, &strClass, headOffset + PTR_SIZE ) );
176 dataTable.schedules.push_back( Schedule( Schedule::TypeInfo, &strClass, headOffset + offsetForTypeInfo ) );
177 dataTable.schedules.push_back( Schedule( Schedule::DataTable, headOffset + offsetForChars ) );
178
179 // 文字列バッファをデータ領域へ追加
180 compiler.AddStringToDataTable( str );
181
182 return dataTableOffset;
183}
184
185bool DataTableGenerator::MakeLiteralArrayBuffer( DataTable &dataTable, const char *expression, const Type &baseType, int &dataTableOffset )
186{
187 if( !baseType.IsPointer() ){
188 compiler.errorMessenger.Output(1,NULL,cp);
189 return false;
190 }
191 Type tempBaseType( baseType );
192 tempBaseType.PtrLevelDown();
193
194 char *buffer = (char *)malloc( lstrlen( expression ) + 1 );
195 lstrcpy( buffer, expression );
196 RemoveStringBracket( buffer );
197
198 Jenga::Common::Strings parameters;
199 SplitParameter( buffer, parameters );
200
201 // アラインメント
202 dataTable.AddAlignment( tempBaseType.GetSize() );
203
204 // データテーブルに空間を確保
205 dataTableOffset = dataTable.AddSpace( static_cast<int>(tempBaseType.GetSize() * parameters.size()) );
206
207 bool isSuccessful = true;
208 int i = 0;
209 BOOST_FOREACH( const std::string &paramStr, parameters )
210 {
211 if( paramStr.size() == 0 )
212 {
213 throw;
214 }
215 if( paramStr[0] == '\"' )
216 {
217 // 文字列
218 std::string tempParamStr = paramStr;
219 if( !RemoveStringQuotes( tempParamStr ) )
220 {
221 compiler.errorMessenger.OutputFatalError();
222 }
223
224 // 文字列を追加
225 _int64 strOffset;
226 if( tempBaseType.IsStringClass() )
227 {
228 // Stringクラス
229 strOffset = MakeConstStringObjectToProcessStaticBuffer( dataTable, tempParamStr.c_str() );
230 }
231 else
232 {
233 // Charポインタ
234 strOffset = compiler.AddStringToDataTable( tempParamStr );
235 }
236
237 // ポインタ値を上書き
238 int tempOffset = dataTableOffset + i * tempBaseType.GetSize();
239 dataTable.OverwriteBinary( tempOffset, &strOffset, tempBaseType.GetSize() );
240
241 // DataTableスケジュール
242 dataTable.schedules.push_back( Schedule( Schedule::DataTable, tempOffset ) );
243 }
244 else
245 {
246 // 数値
247 Type resultType;
248 _int64 i64data;
249 if( !StaticCalculation( true, paramStr.c_str(), tempBaseType.GetBasicType(), &i64data, resultType ) ){
250 isSuccessful = false;
251 break;
252 }
253 if( !resultType.IsWhole() ){
254 // TODO: 実数に未対応
255 compiler.errorMessenger.OutputFatalError();
256 isSuccessful = false;
257 break;
258 }
259
260 // 上書き
261 dataTable.OverwriteBinary( dataTableOffset + i * tempBaseType.GetSize(), &i64data, tempBaseType.GetSize() );
262 }
263
264 i++;
265 }
266
267 free( buffer );
268
269 return isSuccessful;
270}
Note: See TracBrowser for help on using the repository browser.