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

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