source: dev/trunk/ab5.0/abdev/BasicCompiler_Common/src/Compiler.cpp@ 632

Last change on this file since 632 was 632, checked in by dai_9181, 16 years ago

ジェネリッククラスの型パラメータに値型が指定されたときに限り、テンプレート展開を行うようにした。

TODO: libファイルを跨ってテンプレート展開ができていないため、ソースコード管理部分に手を加える必要あり。

File size: 10.0 KB
Line 
1#include "stdafx.h"
2
3using namespace ActiveBasic::Compiler;
4
5Compiler compiler;
6
7void Compiler::StaticLink( ObjectModules &staticLibraries )
8{
9 BOOST_FOREACH( ObjectModule *pStaticLibrary, staticLibraries )
10 {
11 // メタ情報
12 pNowObjectModule->StaticLink( *pStaticLibrary );
13 }
14}
15
16ActiveBasic::Compiler::Error::StringToTypeErrorCode::EnumType Compiler::StringToGenericTypeEx( const std::string &typeName, Type &type )
17{
18 // ジェネリッククラスをインスタンス化した型の場合
19 int i = 0;
20 char className[VN_SIZE];
21 GetIdentifierToken( className, typeName.c_str(), i );
22
23 // ジェネリクスクラスを取得
24 const CClass *pGenericClass = this->GetObjectModule().meta.FindClassSupportedTypeDef(
25 LexicalAnalyzer::FullNameToSymbol( className )
26 );
27
28 if( !pGenericClass )
29 {
30 return ActiveBasic::Compiler::Error::StringToTypeErrorCode::NotfoundGenericClass;
31 }
32
33 if( typeName[i] != '<' )
34 {
35 Jenga::Throw( "StringToType内でジェネリクス構文の解析に失敗" );
36 }
37
38 GenericTypes genericTypes;
39 bool isValueType = false;
40 while( true )
41 {
42 i++;
43
44 char typeParameterStr[VN_SIZE];
45 GetIdentifierToken( typeParameterStr, typeName.c_str(), i );
46
47 // 型パラメータの型情報を取得
48 Type typeParameterType;
49 StringToType( typeParameterStr, typeParameterType );
50
51 genericTypes.push_back( GenericType( "(non support)", typeParameterType ) );
52
53 if( typeParameterType.IsValueType() )
54 {
55 // 値型の場合
56 isValueType = true;
57 }
58
59 if( typeName[i] != ',' )
60 {
61 break;
62 }
63 }
64
65 // 基本型をセット
66 type.SetBasicType( DEF_OBJECT );
67
68 if( isValueType )
69 {
70 // 型パラメータに値型が指定された場合
71
72 // 仮型パラメータを実型パラメータに変換
73 Types actualTypes;
74 BOOST_FOREACH( const GenericType &genericType, genericTypes )
75 {
76 actualTypes.push_back( genericType.GetType() );
77 }
78
79 // テンプレートとしてクラスを展開する
80 const CClass *pExpandedClass = LexicalAnalyzer::TemplateExpand( *const_cast<CClass *>(pGenericClass), actualTypes );
81
82 if( pExpandedClass )
83 {
84 // 拡張情報をセット
85 type.SetClassPtr( pExpandedClass );
86 }
87 else
88 {
89 // TODO: 消す
90 goto Generic;
91 }
92 }
93 else
94 {
95Generic:
96 // 型パラメータにクラス型が指定された場合
97
98 // ジェネリック クラスとして利用する
99
100 // 拡張情報をセット
101 type.SetClassPtr( pGenericClass );
102 type.SetActualGenericTypes( genericTypes );
103 }
104
105 return ActiveBasic::Compiler::Error::StringToTypeErrorCode::Successful;
106}
107ActiveBasic::Compiler::Error::StringToTypeErrorCode::EnumType Compiler::StringToTypeEx( const std::string &typeName, Type &type, bool isResolveGenerics )
108{
109 type.SetIndex( -1 );
110
111
112 /////////////////////////////////////////////////////////
113 // ☆★☆ ジェネリクスサポート ☆★☆
114
115 if( strstr( typeName.c_str(), "<" ) )
116 {
117 return StringToGenericTypeEx( typeName, type );
118 }
119
120 //
121 /////////////////////////////////////////////////////////
122
123
124 if( typeName[0] == '*' ){
125 if( typeName.size() >= 3
126 && typeName[1] == 1 && ( typeName[2] == ESC_FUNCTION || typeName[2] == ESC_SUB ) )
127 {
128 // 関数ポインタを追加する
129 {
130 DWORD dwProcType = (DWORD)typeName[2];
131 const std::string &paramStr = typeName.substr( 3 );
132
133 Procedure::Kind kind = ( dwProcType == ESC_FUNCTION )
134 ? Procedure::Function
135 : Procedure::Sub;
136
137 ProcPointer *pProcPointer = new ProcPointer( kind );
138
139 //buffer[0]は'('となっている
140 extern int cp;
141 ActiveBasic::Compiler::LexicalAnalyzer::SetParamsAndReturnType( pProcPointer, paramStr.c_str(), false, cp );
142
143 this->GetObjectModule().meta.GetProcPointers().push_back( pProcPointer );
144 }
145
146 //関数ポインタ(*Function)
147 type.SetBasicType( DEF_PTR_PROC );
148 type.SetIndex( this->GetObjectModule().meta.GetProcPointers().size() - 1 );
149 return ActiveBasic::Compiler::Error::StringToTypeErrorCode::Successful;
150 }
151
152 const std::string &nextTypeName = typeName.substr( 1 );
153
154 ActiveBasic::Compiler::Error::StringToTypeErrorCode::EnumType result = StringToTypeEx( nextTypeName, type, isResolveGenerics );
155 if( result != ActiveBasic::Compiler::Error::StringToTypeErrorCode::Successful )
156 {
157 return result;
158 }
159
160 type.PtrLevelUp();
161
162 return ActiveBasic::Compiler::Error::StringToTypeErrorCode::Successful;
163 }
164
165 {
166 int basicType;
167 if( Type::StringToBasicType( typeName, basicType ) )
168 {
169 // 基本型だったとき
170 type.SetBasicType( basicType );
171 return ActiveBasic::Compiler::Error::StringToTypeErrorCode::Successful;
172 }
173 }
174
175 // Object型だったとき
176 if( typeName == "Object" )
177 {
178 type.SetType( DEF_OBJECT, this->GetObjectModule().meta.GetClasses().GetObjectClassPtr() );
179 return ActiveBasic::Compiler::Error::StringToTypeErrorCode::Successful;
180 }
181
182 // String型だったとき
183 if( typeName == "String" )
184 {
185 type.SetType( DEF_OBJECT, this->GetObjectModule().meta.GetClasses().GetStringClassPtr() );
186 return ActiveBasic::Compiler::Error::StringToTypeErrorCode::Successful;
187 }
188
189
190 ////////////////////
191 // TypeDefされた型
192 ////////////////////
193 const TypeDef *pTypeDef = this->GetObjectModule().meta.GetTypeDefs().Find( LexicalAnalyzer::FullNameToSymbol( typeName ) );
194 if( pTypeDef )
195 {
196 type = pTypeDef->GetBaseType();
197
198 if( type.IsObject() )
199 {
200 if( isResolveGenerics && !type.HasActualGenericType() )
201 {
202 // ジェネリッククラスの場合
203 trace( "型解決されていない" );
204 return ActiveBasic::Compiler::Error::StringToTypeErrorCode::FailedResolveGenericType;
205 }
206 }
207
208 return ActiveBasic::Compiler::Error::StringToTypeErrorCode::Successful;
209 }
210
211 //クラス
212 const CClass *pobj_c = this->GetObjectModule().meta.FindClassSupportedTypeDef( LexicalAnalyzer::FullNameToSymbol( typeName ) );
213 if(pobj_c)
214 {
215 if( isResolveGenerics )
216 {
217 if( pobj_c->IsGeneric() )
218 {
219 // ジェネリッククラスの場合
220 trace( "型解決されていない" );
221 return ActiveBasic::Compiler::Error::StringToTypeErrorCode::FailedResolveGenericType;
222 }
223 }
224
225 if( pobj_c->IsStructure() )
226 {
227 type.SetBasicType( DEF_STRUCT );
228 }
229 else
230 {
231 type.SetBasicType( DEF_OBJECT );
232 }
233 type.SetClassPtr( pobj_c );
234 return ActiveBasic::Compiler::Error::StringToTypeErrorCode::Successful;
235 }
236
237
238 /////////////////////////////////////////////////////////
239 // ☆★☆ ジェネリクスサポート ☆★☆
240
241 // 型パラメータ
242 if( this->IsCompilingClass() )
243 {
244 // クラスに属するメソッドをコンパイルしているとき
245 int formalTypeIndex = this->GetCompilingClass().GetFormalGenericTypeParameterIndex( typeName );
246 if( formalTypeIndex != -1 )
247 {
248 // コンパイル中クラスにおけるジェネリクス用の型パラメータのとき
249 type.SetBasicType( DEF_TYPE_PARAMETER );
250 type.SetClassPtr( &this->GetCompilingClass().GetFormalGenericTypes()[formalTypeIndex].GetType().GetClass() );
251 type.SetFormalTypeName( typeName );
252 type.SetFormalTypeIndex( formalTypeIndex );
253 return ActiveBasic::Compiler::Error::StringToTypeErrorCode::Successful;
254 }
255 }
256
257 //
258 /////////////////////////////////////////////////////////
259
260 return ActiveBasic::Compiler::Error::StringToTypeErrorCode::NotfoundType;
261}
262
263bool Compiler::StringToType( const std::string &typeName, Type &type )
264{
265 return ( StringToTypeEx( typeName, type, false ) == ActiveBasic::Compiler::Error::StringToTypeErrorCode::Successful );
266}
267
268const std::string Compiler::TypeToString( const Type &type )
269{
270 if( PTR_LEVEL( type.GetBasicType() ) ){
271 //ポインタレベルが1以上の場合
272 Type tempType( type );
273 tempType.PtrLevelDown();
274
275 return (std::string)"*" + TypeToString( tempType );
276 }
277 else if( type.IsObject() || type.IsStruct() ){
278 //オブジェクトまたは構造体
279
280 if( !( type.GetIndex() == 0 || type.GetIndex() == -1 ) ){
281 if( type.GetClass().GetNamespaceScopes().size() >= 1 )
282 {
283 return type.GetClass().GetNamespaceScopes().ToString() + "." + type.GetClass().GetName();
284 }
285 return type.GetClass().GetName();
286 }
287 }
288 else if( type.IsProcPtr() ){
289 if( type.GetIndex() == 0 || type.GetIndex() == -1 ){
290 return "VoidPtr";
291 }
292 else{
293 if( this->GetObjectModule().meta.GetProcPointers()[type.GetIndex()]->ReturnType().IsNull() ){
294 return "*Sub";
295 }
296 return "*Function";
297 }
298 }
299 else{
300 // 基本型
301 const char *lpszTypeName = Type::BasicTypeToCharPtr( type );
302 if( lpszTypeName )
303 {
304 return (const std::string)lpszTypeName;
305 }
306 }
307
308 compiler.errorMessenger.Output(1, NULL, cp);
309
310 return (std::string)"(null)";
311}
312
313void Compiler::ClearCompilingUserProcAndClass()
314{
315 this->pCompilingUserProc = NULL;
316 this->pCompilingClass = NULL;
317}
318
319void Compiler::SetCompilingClass( const CClass *pClass )
320{
321 this->pCompilingClass = pClass;
322}
323
324void Compiler::SetCompilingUserProc( const UserProc *pUserProc )
325{
326 this->pCompilingUserProc = pUserProc;
327
328 this->SetCompilingClass( pUserProc->GetParentClassPtr() );
329}
330
331void Compiler::StartGlobalAreaCompile()
332{
333 ClearCompilingUserProcAndClass();
334}
335
336void Compiler::StartProcedureCompile( const UserProc *pUserProc )
337{
338 //コンパイル中の関数
339 this->SetCompilingUserProc( pUserProc );
340
341 if( pUserProc->HasParentClass() )
342 {
343 // クラスの使用チェック
344 pUserProc->GetParentClass().Using();
345 }
346
347 // コンパイル中の関数が属する名前空間
348 this->GetNamespaceSupporter().SetLivingNamespaceScopes( pUserProc->GetNamespaceScopes() );
349
350 // コンパイル中の関数でImportsされている名前空間
351 this->GetNamespaceSupporter().SetImportedNamespaces( pUserProc->GetImportedNamespaces() );
352
353 // コード生成対象を選択
354 this->codeGenerator.Select( (const_cast<UserProc *>(pUserProc))->GetNativeCode() );
355}
356void Compiler::FinishProcedureCompile()
357{
358 this->pCompilingUserProc = NULL;
359 this->pCompilingClass = NULL;
360}
361
362bool Compiler::IsGlobalAreaCompiling()
363{
364 return ( pCompilingUserProc == NULL );
365}
366bool Compiler::IsLocalAreaCompiling()
367{
368 return ( pCompilingUserProc != NULL );
369}
370const UserProc &Compiler::GetCompilingUserProc()
371{
372 if( !this->IsGlobalAreaCompiling() )
373 {
374 return *pCompilingUserProc;
375 }
376
377 throw;
378}
379
380bool Compiler::IsCompilingClass()
381{
382 return ( pCompilingClass != NULL );
383}
384const CClass &Compiler::GetCompilingClass()
385{
386 if( this->IsCompilingClass() )
387 {
388 return *pCompilingClass;
389 }
390
391 throw;
392}
Note: See TracBrowser for help on using the repository browser.