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

Last change on this file since 750 was 750, checked in by イグトランス (egtra), 16 years ago

BOOST_FOREACHを可能なものはVC++ 2005 for eachへ置換(やや速くなる)。

File size: 13.5 KB
RevLine 
[206]1#include "stdafx.h"
2
[598]3using namespace ActiveBasic::Compiler;
4
[195]5Compiler compiler;
[193]6
[636]7Compiler::Compiler()
8 : isBuildSuccessful( false )
9 , targetModuleType( ActiveBasic::Common::TargetModuleType::Exe )
10 , isDebug( false )
11 , isUnicode( false )
12 , isCore( false )
13 , currentRelationalObjectModuleIndexForSource( 0 )
14{
15 // 生成先のオブジェクトモジュールを登録
16 ObjectModule *pObjectModule = new ObjectModule();
17 staticLibraries.push_back( pObjectModule );
18 SelectObjectModule( pObjectModule );
19
20 namespaceSupporter.RegistAllNamespaceScopesCollection( &GetObjectModule().meta.GetNamespaces() );
21
22 Symbol::RegistNamespaceSupporter( &namespaceSupporter );
23}
24Compiler::~Compiler()
25{
[750]26 foreach( ObjectModule *pStaticLibrary, staticLibraries )
[636]27 {
28 delete pStaticLibrary;
29 }
30 staticLibraries.clear();
31}
32
33void Compiler::PreStaticLink( const ObjectModules &staticLibraries )
34{
[750]35 foreach( const ObjectModule *pStaticLibrary, staticLibraries )
[636]36 {
37 // 関連オブジェクトモジュールの名前リスト
38 this->GetObjectModule().relationalObjectModuleNames.push_back( pStaticLibrary->GetName() );
39 }
40}
[270]41void Compiler::StaticLink( ObjectModules &staticLibraries )
42{
[750]43 foreach( ObjectModule *pStaticLibrary, staticLibraries )
[270]44 {
[636]45 if( &this->GetObjectModule() == pStaticLibrary )
46 {
47 // 自分自身の場合はリンクしない
48 continue;
49 }
50
[270]51 // メタ情報
[637]52 this->GetObjectModule().StaticLink( *pStaticLibrary, this->IsSll() );
[270]53 }
54}
55
[710]56const std::string &Compiler::GetGlobalAreaProcName() const
57{
58 static std::string globalAreaProcName;
59
60 if( globalAreaProcName.empty() )
61 {
62 // 初期化
63 _ASSERTE( !this->GetModuleName().empty() );
64
65 std::string originalName = this->GetModuleName();
66
67 // モジュール名がシンボル名として使えない場合があるので、16進数文字列に変換する
68 char temporary[VN_SIZE*2] = "";
[720]69 for( int i=0; i<static_cast<int>(originalName.size()); i++ )
[710]70 {
71 sprintf( temporary + strlen(temporary), "%2x", originalName[i] );
72 }
73
74 globalAreaProcName = (std::string)"_GlobalArea_" + temporary;
75 }
76
77 return globalAreaProcName;
78}
79
[745]80int Compiler::AddStringToDataTable( const std::string &text )
81{
82 if( this->IsUnicode() )
83 {
84 return this->GetObjectModule().dataTable.AddWString( Jenga::Common::ToWString( text ) );
85 }
86 else
87 {
88 return this->GetObjectModule().dataTable.AddString( text );
89 }
90}
91
[632]92ActiveBasic::Compiler::Error::StringToTypeErrorCode::EnumType Compiler::StringToGenericTypeEx( const std::string &typeName, Type &type )
[628]93{
[632]94 // ジェネリッククラスをインスタンス化した型の場合
95 int i = 0;
96 char className[VN_SIZE];
97 GetIdentifierToken( className, typeName.c_str(), i );
[193]98
[632]99 // ジェネリクスクラスを取得
100 const CClass *pGenericClass = this->GetObjectModule().meta.FindClassSupportedTypeDef(
101 LexicalAnalyzer::FullNameToSymbol( className )
102 );
[290]103
[632]104 if( !pGenericClass )
105 {
106 return ActiveBasic::Compiler::Error::StringToTypeErrorCode::NotfoundGenericClass;
107 }
[290]108
[632]109 if( typeName[i] != '<' )
[290]110 {
[632]111 Jenga::Throw( "StringToType内でジェネリクス構文の解析に失敗" );
112 }
[290]113
[632]114 GenericTypes genericTypes;
115 bool isValueType = false;
116 while( true )
117 {
118 i++;
[290]119
[632]120 char typeParameterStr[VN_SIZE];
121 GetIdentifierToken( typeParameterStr, typeName.c_str(), i );
122
123 // 型パラメータの型情報を取得
124 Type typeParameterType;
125 StringToType( typeParameterStr, typeParameterType );
126
[720]127 if( this->IsCompilingClass() )
128 {
129 if( this->pCompilingClass->IsExpanded() && typeParameterType.IsTypeParameter() )
130 {
131 // 現在コンパイル中のクラスがテンプレート展開済みのクラスで、
132 // 尚且つターゲットとなる型が型パラメータだったとき
133
134 // テンプレート展開情報を用いて型解決を行う
135 this->pCompilingClass->ResolveExpandedClassActualTypeParameter( typeParameterType );
136 }
137 }
138
[632]139 genericTypes.push_back( GenericType( "(non support)", typeParameterType ) );
140
141 if( typeParameterType.IsValueType() )
[301]142 {
[632]143 // 値型の場合
144 isValueType = true;
[301]145 }
[290]146
[632]147 if( typeName[i] != ',' )
[301]148 {
[632]149 break;
[301]150 }
[632]151 }
[301]152
[632]153 // 基本型をセット
154 type.SetBasicType( DEF_OBJECT );
[290]155
[632]156 if( isValueType )
157 {
158 // 型パラメータに値型が指定された場合
[301]159
[632]160 // 仮型パラメータを実型パラメータに変換
161 Types actualTypes;
[750]162 foreach( const GenericType &genericType, genericTypes )
[632]163 {
164 actualTypes.push_back( genericType.GetType() );
165 }
[301]166
[632]167 // テンプレートとしてクラスを展開する
168 const CClass *pExpandedClass = LexicalAnalyzer::TemplateExpand( *const_cast<CClass *>(pGenericClass), actualTypes );
[301]169
[632]170 if( pExpandedClass )
171 {
172 // 拡張情報をセット
173 type.SetClassPtr( pExpandedClass );
[301]174 }
[632]175 else
176 {
177 // TODO: 消す
178 goto Generic;
179 }
180 }
181 else
182 {
183Generic:
184 // 型パラメータにクラス型が指定された場合
[301]185
[632]186 // ジェネリック クラスとして利用する
[290]187
188 // 拡張情報をセット
189 type.SetClassPtr( pGenericClass );
190 type.SetActualGenericTypes( genericTypes );
[632]191 }
[290]192
[632]193 return ActiveBasic::Compiler::Error::StringToTypeErrorCode::Successful;
194}
195ActiveBasic::Compiler::Error::StringToTypeErrorCode::EnumType Compiler::StringToTypeEx( const std::string &typeName, Type &type, bool isResolveGenerics )
196{
197 type.SetIndex( -1 );
198
199
200 /////////////////////////////////////////////////////////
201 // ☆★☆ ジェネリクスサポート ☆★☆
202
203 if( strstr( typeName.c_str(), "<" ) )
204 {
205 return StringToGenericTypeEx( typeName, type );
[290]206 }
207
208 //
209 /////////////////////////////////////////////////////////
210
211
[193]212 if( typeName[0] == '*' ){
213 if( typeName.size() >= 3
[575]214 && typeName[1] == 1 && ( typeName[2] == ESC_FUNCTION || typeName[2] == ESC_SUB ) )
215 {
216 // 関数ポインタを追加する
217 {
218 DWORD dwProcType = (DWORD)typeName[2];
219 const std::string &paramStr = typeName.substr( 3 );
220
221 Procedure::Kind kind = ( dwProcType == ESC_FUNCTION )
222 ? Procedure::Function
223 : Procedure::Sub;
224
225 ProcPointer *pProcPointer = new ProcPointer( kind );
226
227 //buffer[0]は'('となっている
228 extern int cp;
229 ActiveBasic::Compiler::LexicalAnalyzer::SetParamsAndReturnType( pProcPointer, paramStr.c_str(), false, cp );
230
231 this->GetObjectModule().meta.GetProcPointers().push_back( pProcPointer );
232 }
233
234 //関数ポインタ(*Function)
235 type.SetBasicType( DEF_PTR_PROC );
236 type.SetIndex( this->GetObjectModule().meta.GetProcPointers().size() - 1 );
[628]237 return ActiveBasic::Compiler::Error::StringToTypeErrorCode::Successful;
[193]238 }
239
[523]240 const std::string &nextTypeName = typeName.substr( 1 );
[193]241
[628]242 ActiveBasic::Compiler::Error::StringToTypeErrorCode::EnumType result = StringToTypeEx( nextTypeName, type, isResolveGenerics );
243 if( result != ActiveBasic::Compiler::Error::StringToTypeErrorCode::Successful )
244 {
245 return result;
[193]246 }
247
248 type.PtrLevelUp();
249
[628]250 return ActiveBasic::Compiler::Error::StringToTypeErrorCode::Successful;
[193]251 }
252
253 {
254 int basicType;
[628]255 if( Type::StringToBasicType( typeName, basicType ) )
256 {
[193]257 // 基本型だったとき
258 type.SetBasicType( basicType );
[628]259 return ActiveBasic::Compiler::Error::StringToTypeErrorCode::Successful;
[193]260 }
261 }
262
263 // Object型だったとき
[628]264 if( typeName == "Object" )
265 {
[299]266 type.SetType( DEF_OBJECT, this->GetObjectModule().meta.GetClasses().GetObjectClassPtr() );
[628]267 return ActiveBasic::Compiler::Error::StringToTypeErrorCode::Successful;
[193]268 }
269
270 // String型だったとき
[628]271 if( typeName == "String" )
272 {
[299]273 type.SetType( DEF_OBJECT, this->GetObjectModule().meta.GetClasses().GetStringClassPtr() );
[628]274 return ActiveBasic::Compiler::Error::StringToTypeErrorCode::Successful;
[193]275 }
276
277
278 ////////////////////
279 // TypeDefされた型
280 ////////////////////
[632]281 const TypeDef *pTypeDef = this->GetObjectModule().meta.GetTypeDefs().Find( LexicalAnalyzer::FullNameToSymbol( typeName ) );
282 if( pTypeDef )
[628]283 {
[632]284 type = pTypeDef->GetBaseType();
285
286 if( type.IsObject() )
287 {
[693]288 if( isResolveGenerics && type.GetClass().IsGeneric() && !type.HasActualGenericType() )
[632]289 {
290 // ジェネリッククラスの場合
291 trace( "型解決されていない" );
292 return ActiveBasic::Compiler::Error::StringToTypeErrorCode::FailedResolveGenericType;
293 }
294 }
295
[628]296 return ActiveBasic::Compiler::Error::StringToTypeErrorCode::Successful;
[193]297 }
298
299 //クラス
[632]300 const CClass *pobj_c = this->GetObjectModule().meta.FindClassSupportedTypeDef( LexicalAnalyzer::FullNameToSymbol( typeName ) );
[628]301 if(pobj_c)
302 {
[693]303 if( isResolveGenerics && pobj_c->IsGeneric() )
[628]304 {
[693]305 // ジェネリッククラスの場合
306 trace( "型解決されていない" );
307 return ActiveBasic::Compiler::Error::StringToTypeErrorCode::FailedResolveGenericType;
[628]308 }
309
310 if( pobj_c->IsStructure() )
311 {
[193]312 type.SetBasicType( DEF_STRUCT );
313 }
[628]314 else
315 {
[193]316 type.SetBasicType( DEF_OBJECT );
317 }
[290]318 type.SetClassPtr( pobj_c );
[628]319 return ActiveBasic::Compiler::Error::StringToTypeErrorCode::Successful;
[193]320 }
321
[290]322
323 /////////////////////////////////////////////////////////
324 // ☆★☆ ジェネリクスサポート ☆★☆
325
326 // 型パラメータ
[536]327 if( this->IsCompilingClass() )
[290]328 {
329 // クラスに属するメソッドをコンパイルしているとき
[536]330 int formalTypeIndex = this->GetCompilingClass().GetFormalGenericTypeParameterIndex( typeName );
[299]331 if( formalTypeIndex != -1 )
[290]332 {
333 // コンパイル中クラスにおけるジェネリクス用の型パラメータのとき
334 type.SetBasicType( DEF_TYPE_PARAMETER );
[536]335 type.SetClassPtr( &this->GetCompilingClass().GetFormalGenericTypes()[formalTypeIndex].GetType().GetClass() );
[299]336 type.SetFormalTypeName( typeName );
337 type.SetFormalTypeIndex( formalTypeIndex );
[628]338 return ActiveBasic::Compiler::Error::StringToTypeErrorCode::Successful;
[290]339 }
340 }
341
342 //
343 /////////////////////////////////////////////////////////
344
[628]345 return ActiveBasic::Compiler::Error::StringToTypeErrorCode::NotfoundType;
[193]346}
347
[628]348bool Compiler::StringToType( const std::string &typeName, Type &type )
349{
350 return ( StringToTypeEx( typeName, type, false ) == ActiveBasic::Compiler::Error::StringToTypeErrorCode::Successful );
351}
352
[523]353const std::string Compiler::TypeToString( const Type &type )
[193]354{
355 if( PTR_LEVEL( type.GetBasicType() ) ){
356 //ポインタレベルが1以上の場合
357 Type tempType( type );
358 tempType.PtrLevelDown();
359
[735]360 return '*' + TypeToString( tempType );
[193]361 }
[683]362 else if( type.IsObject() || type.IsStruct() )
363 {
[193]364 //オブジェクトまたは構造体
365
[683]366 if( !( type.GetIndex() == 0 || type.GetIndex() == -1 ) )
367 {
368 std::string result = type.GetClass().GetName();
[193]369 if( type.GetClass().GetNamespaceScopes().size() >= 1 )
370 {
[683]371 result = type.GetClass().GetNamespaceScopes().ToString()
372 + "."
373 + result;
[193]374 }
[683]375
376 if( type.GetClass().IsExpanded() )
377 {
378 // テンプレート展開済みのクラスの場合
379 std::string actualGenericTypesName;
[750]380 foreach( const Type &typeParameter, type.GetClass().expandedClassActualTypeParameters )
[683]381 {
382 if( actualGenericTypesName.size() )
383 {
[735]384 actualGenericTypesName += ',';
[683]385 }
386 actualGenericTypesName += typeParameter.ToString();
387 }
388
[735]389 result += '<' + actualGenericTypesName + '>';
[683]390 }
391
392 return result;
[193]393 }
394 }
395 else if( type.IsProcPtr() ){
396 if( type.GetIndex() == 0 || type.GetIndex() == -1 ){
397 return "VoidPtr";
398 }
399 else{
[299]400 if( this->GetObjectModule().meta.GetProcPointers()[type.GetIndex()]->ReturnType().IsNull() ){
[193]401 return "*Sub";
402 }
403 return "*Function";
404 }
405 }
406 else{
407 // 基本型
408 const char *lpszTypeName = Type::BasicTypeToCharPtr( type );
409 if( lpszTypeName )
410 {
[523]411 return (const std::string)lpszTypeName;
[193]412 }
413 }
414
[465]415 compiler.errorMessenger.Output(1, NULL, cp);
[193]416
[523]417 return (std::string)"(null)";
[193]418}
[533]419
[672]420int Compiler::SizeOf( const Type &type )
421{
422 Type tempType( type );
423 if( this->IsCompilingClass() )
424 {
425 if( this->pCompilingClass->IsExpanded() && tempType.IsTypeParameter() )
426 {
427 // 現在コンパイル中のクラスがテンプレート展開済みのクラスで、
428 // 尚且つターゲットとなる型が型パラメータだったとき
429
430 // テンプレート展開情報を用いて型解決を行う
431 this->pCompilingClass->ResolveExpandedClassActualTypeParameter( tempType );
432 }
433 }
434 return tempType.GetSize();
435}
436
[536]437void Compiler::ClearCompilingUserProcAndClass()
438{
439 this->pCompilingUserProc = NULL;
440 this->pCompilingClass = NULL;
441}
442
443void Compiler::SetCompilingClass( const CClass *pClass )
444{
445 this->pCompilingClass = pClass;
446}
447
[537]448void Compiler::SetCompilingUserProc( const UserProc *pUserProc )
[533]449{
[536]450 this->pCompilingUserProc = pUserProc;
451
452 this->SetCompilingClass( pUserProc->GetParentClassPtr() );
[537]453}
[533]454
[537]455void Compiler::StartGlobalAreaCompile()
456{
457 ClearCompilingUserProcAndClass();
458}
459
460void Compiler::StartProcedureCompile( const UserProc *pUserProc )
461{
462 //コンパイル中の関数
463 this->SetCompilingUserProc( pUserProc );
464
[540]465 if( pUserProc->HasParentClass() )
466 {
467 // クラスの使用チェック
468 pUserProc->GetParentClass().Using();
469 }
[533]470
471 // コンパイル中の関数が属する名前空間
472 this->GetNamespaceSupporter().SetLivingNamespaceScopes( pUserProc->GetNamespaceScopes() );
473
474 // コンパイル中の関数でImportsされている名前空間
475 this->GetNamespaceSupporter().SetImportedNamespaces( pUserProc->GetImportedNamespaces() );
476
477 // コード生成対象を選択
478 this->codeGenerator.Select( (const_cast<UserProc *>(pUserProc))->GetNativeCode() );
479}
480void Compiler::FinishProcedureCompile()
481{
[536]482 this->pCompilingUserProc = NULL;
483 this->pCompilingClass = NULL;
[533]484}
[536]485
486bool Compiler::IsGlobalAreaCompiling()
487{
[641]488 if( pCompilingUserProc == NULL )
489 {
490 return true;
491 }
[710]492 return ( pCompilingUserProc->GetName() == this->GetGlobalAreaProcName() );
[536]493}
[537]494bool Compiler::IsLocalAreaCompiling()
495{
[641]496 return !IsGlobalAreaCompiling();
[537]497}
[536]498const UserProc &Compiler::GetCompilingUserProc()
499{
[641]500 if( pCompilingUserProc == NULL )
[536]501 {
[641]502 _ASSERTE( false );
503 throw;
[536]504 }
[641]505 return *pCompilingUserProc;
[536]506}
507
508bool Compiler::IsCompilingClass()
509{
510 return ( pCompilingClass != NULL );
511}
512const CClass &Compiler::GetCompilingClass()
513{
514 if( this->IsCompilingClass() )
515 {
516 return *pCompilingClass;
517 }
518
519 throw;
520}
Note: See TracBrowser for help on using the repository browser.