source: dev/trunk/ab5.0/abdev/BasicCompiler_Common/src/LexicalAnalyzer_Class.cpp@ 566

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

・Classes::Find→Classes::FindExにリネームして、TypeDefサポートを排除した。
・Meta::FindClassSupportedTypeDefメソッドを実装。従来のClasses::Findの実装内容を受け継ぐ。

File size: 33.9 KB
Line 
1#include "stdafx.h"
2
3#include <Source.h>
4#include <Class.h>
5#include <Compiler.h>
6
7#include "../common.h"
8#ifdef _AMD64_
9#include "../../compiler_x64/opcode.h"
10#else
11#include "../../compiler_x86/opcode.h"
12#endif
13
14using namespace ActiveBasic::Compiler;
15
16
17void LexicalAnalyzer::CollectClassesForNameOnly( const char *source, Classes &classes )
18{
19 int i, i2;
20 char temporary[VN_SIZE];
21
22 // 名前空間管理
23 NamespaceScopes &namespaceScopes = compiler.GetNamespaceSupporter().GetLivingNamespaceScopes();
24 namespaceScopes.clear();
25
26 // Importsされた名前空間の管理
27 NamespaceScopesCollection &importedNamespaces = compiler.GetNamespaceSupporter().GetImportedNamespaces();
28 importedNamespaces.clear();
29
30 for(i=0;;i++){
31 if(source[i]=='\0') break;
32
33 if( source[i] == 1 && source[i+1] == ESC_NAMESPACE ){
34 for(i+=2,i2=0;;i2++,i++){
35 if( IsCommandDelimitation( source[i] ) ){
36 temporary[i2]=0;
37 break;
38 }
39 temporary[i2]=source[i];
40 }
41 namespaceScopes.push_back( temporary );
42
43 continue;
44 }
45 else if( source[i] == 1 && source[i+1] == ESC_ENDNAMESPACE ){
46 if( namespaceScopes.size() <= 0 ){
47 compiler.errorMessenger.Output(12, "End Namespace", i );
48 }
49 else{
50 namespaceScopes.pop_back();
51 }
52
53 i += 2;
54 continue;
55 }
56 else if( source[i] == 1 && source[i+1] == ESC_IMPORTS ){
57 for(i+=2,i2=0;;i2++,i++){
58 if( IsCommandDelimitation( source[i] ) ){
59 temporary[i2]=0;
60 break;
61 }
62 temporary[i2]=source[i];
63 }
64 if( !compiler.GetNamespaceSupporter().ImportsNamespace( temporary ) )
65 {
66 compiler.errorMessenger.Output(64,temporary,i );
67 }
68
69 continue;
70 }
71 else if( source[i] == 1 && source[i+1] == ESC_CLEARNAMESPACEIMPORTED ){
72 importedNamespaces.clear();
73 continue;
74 }
75
76 if(source[i]==1&&(
77 source[i+1]==ESC_CLASS||
78 source[i+1]==ESC_TYPE||
79 source[i+1]==ESC_INTERFACE
80 ))
81 {
82 int nowLine = i;
83 i += 2;
84
85 Type blittableType;
86 if(memicmp(source+i,"Align(",6)==0){
87 //アラインメント修飾子
88 i+=6;
89 i=JumpStringInPare(source,i)+1;
90 }
91 else if( memicmp( source + i, "Blittable(", 10 ) == 0 ){
92 // Blittable修飾子
93 i+=10;
94 i+=GetStringInPare_RemovePare(temporary,source+i)+1;
95 compiler.StringToType( temporary, blittableType );
96 }
97
98 bool isEnum = false;
99 bool isDelegate = false;
100 if( source[i] == 1 && source[i+1] == ESC_ENUM ){
101 // 列挙型の場合
102 isEnum = true;
103
104 i += 2;
105 }
106 else if( source[i] == 1 && source[i+1] == ESC_DELEGATE )
107 {
108 // デリゲートの場合
109 isDelegate = true;
110
111 i += 2;
112 }
113
114 for(i2=0;;i++,i2++){
115 if(!IsVariableChar(source[i])){
116 temporary[i2]=0;
117 break;
118 }
119 temporary[i2]=source[i];
120 }
121
122 //クラスを追加
123 CClass *pClass = new CClass( namespaceScopes, importedNamespaces, temporary );
124 if( classes.IsExist( pClass ) )
125 {
126 // 既に存在している
127 compiler.errorMessenger.Output(15,pClass->GetName(), nowLine);
128
129 delete pClass;
130
131 continue;
132 }
133
134 classes.Put( pClass );
135
136 if( source[nowLine+1] == ESC_CLASS )
137 {
138 if( isEnum )
139 {
140 pClass->SetClassType( CClass::Enum );
141 }
142 else if( isDelegate )
143 {
144 pClass->SetClassType( CClass::Delegate );
145 }
146 else{
147 pClass->SetClassType( CClass::Class );
148 }
149 }
150 else if( source[nowLine+1] == ESC_INTERFACE )
151 {
152 pClass->SetClassType( CClass::Interface );
153 }
154 else
155 {
156 pClass->SetClassType( CClass::Structure );
157 }
158
159 // Blittable型の場合
160 if( !blittableType.IsNull() ){
161 pClass->SetBlittableType( blittableType );
162
163 // Blittable型として登録
164 compiler.GetObjectModule().meta.GetBlittableTypes().push_back( BlittableType( blittableType, pClass ) );
165 }
166 }
167 }
168}
169
170
171class CLoopRefCheck{
172 char **names;
173 int num;
174 void init(){
175 int i;
176 for(i=0;i<num;i++){
177 free(names[i]);
178 }
179 free(names);
180 }
181public:
182 CLoopRefCheck()
183 {
184 names=(char **)malloc(1);
185 num=0;
186 }
187 ~CLoopRefCheck()
188 {
189 init();
190 }
191 void add(const char *lpszInheritsClass)
192 {
193 names=(char **)realloc(names,(num+1)*sizeof(char *));
194 names[num]=(char *)malloc(lstrlen(lpszInheritsClass)+1);
195 lstrcpy(names[num],lpszInheritsClass);
196 num++;
197 }
198 void del(const char *lpszInheritsClass)
199 {
200 int i;
201 for(i=0;i<num;i++){
202 if(lstrcmp(names[i],lpszInheritsClass)==0){
203 free(names[i]);
204 break;
205 }
206 }
207 if(i!=num){
208 num--;
209 for(;i<num;i++){
210 names[i]=names[i+1];
211 }
212 }
213 }
214 BOOL check(const CClass &inheritsClass) const
215 {
216 //ループ継承チェック
217 int i;
218 for(i=0;i<num;i++){
219 if( inheritsClass.GetName() == names[i] ){
220 return 1;
221 }
222 }
223 return 0;
224 }
225};
226CLoopRefCheck *pobj_LoopRefCheck;
227
228bool MemberVar_LoopRefCheck(const CClass &objClass){
229 if( objClass.HasSuperClass() )
230 {
231 // 基底クラスをチェック
232 if( MemberVar_LoopRefCheck( objClass.GetSuperClass() ) == false )
233 {
234 return false;
235 }
236 }
237
238 bool result = true;
239 BOOST_FOREACH( Member *pMember, objClass.GetDynamicMembers() ){
240 if(pMember->GetType().IsStruct()){
241 //循環参照でないかをチェック
242 if(pobj_LoopRefCheck->check(pMember->GetType().GetClass())){
243 extern int cp;
244 compiler.errorMessenger.Output(124,pMember->GetType().GetClass().GetName(),cp);
245 return false;
246 }
247
248 pobj_LoopRefCheck->add(objClass.GetName().c_str());
249
250 bool tempResult = MemberVar_LoopRefCheck(pMember->GetType().GetClass());
251 if( result )
252 {
253 result = tempResult;
254 }
255
256 pobj_LoopRefCheck->del(objClass.GetName().c_str());
257 }
258 }
259
260 return result;
261}
262
263void OverrideErrorCheck( const DynamicMethod::OverrideResult &result )
264{
265 switch( result.enumType )
266 {
267 case DynamicMethod::OverrideResult::Successful:
268 break;
269 case DynamicMethod::OverrideResult::NotVirtual:
270 compiler.errorMessenger.Output(136, result.pMethod->GetUserProc().GetName(), cp);
271 break;
272 case DynamicMethod::OverrideResult::NotUseOverrideModifier:
273 compiler.errorMessenger.Output(127, result.pMethod->GetUserProc().GetName(), cp);
274 break;
275 case DynamicMethod::OverrideResult::DifferentAccesibility:
276 compiler.errorMessenger.Output(128, result.pMethod->GetUserProc().GetName(), cp);
277 break;
278 default:
279 throw;
280 }
281}
282
283Member *LexicalAnalyzer::CreateMember( const CClass &_class, Prototype::Accessibility accessibility, bool isConst, bool isRef, char *buffer, int nowLine )
284{
285 extern int cp;
286
287 //構文を解析
288 char VarName[VN_SIZE];
289 char initBuffer[VN_SIZE];
290 char lpszConstructParameter[VN_SIZE];
291 Subscripts subscripts;
292 Type type;
293 GetDimentionFormat(buffer,VarName,subscripts,type,initBuffer,lpszConstructParameter);
294
295 //重複チェック
296 if( _class.DupliCheckAll( VarName ) ){
297 compiler.errorMessenger.Output(15,VarName,cp);
298 }
299
300 Member *pMember = new Member( accessibility, VarName, type, isConst, subscripts, initBuffer, lpszConstructParameter );
301 pMember->source_code_address = nowLine;
302 return pMember;
303}
304
305void LexicalAnalyzer::AddMethod(CClass *pobj_c, UserProc *pUserProc, Prototype::Accessibility accessibility, BOOL bStatic, bool isConst, bool isAbstract,
306 bool isVirtual, bool isOverride, const char *interfaceName, bool isAutoGeneration, int nowLine)
307{
308 if( isAutoGeneration )
309 {
310 // コード自動生成
311 pUserProc->ThisIsAutoGenerationProc();
312 }
313
314
315 ////////////////////////////////////////////////////////////
316 // コンストラクタ、デストラクタの場合の処理
317 ////////////////////////////////////////////////////////////
318 BOOL fConstructor=0,bDestructor=0;
319
320 if( pUserProc->GetName() == pobj_c->GetName() ){
321 //コンストラクタの場合
322
323 //標準コンストラクタ(引数なし)
324 if(pUserProc->Params().size()==0) fConstructor=1;
325
326 //強制的にConst修飾子をつける
327 isConst = true;
328 }
329 else if(pUserProc->GetName()[0]=='~'){
330 //デストラクタの場合はその名前が正しいかチェックを行う
331 if(lstrcmp(pUserProc->GetName().c_str()+1,pobj_c->GetName().c_str())!=0)
332 compiler.errorMessenger.Output(117,NULL,nowLine);
333 else
334 bDestructor=1;
335 }
336 if(fConstructor||bDestructor){
337 // コンストラクタ、デストラクタのアクセシビリティをチェック
338
339 //強制的にConst修飾子をつける
340 isConst = true;
341 }
342
343 if( fConstructor == 1 )
344 pobj_c->SetConstructorMemberSubIndex( (int)pobj_c->GetDynamicMethods().size() );
345 else if( bDestructor )
346 pobj_c->SetDestructorMemberSubIndex( (int)pobj_c->GetDynamicMethods().size() );
347
348
349
350 //////////////////
351 // 重複チェック
352 //////////////////
353
354 if(pobj_c->DupliCheckMember( pUserProc->GetName().c_str() )){
355 compiler.errorMessenger.Output(15,pUserProc->GetName(),nowLine);
356 return;
357 }
358
359 //メソッド
360 BOOST_FOREACH( const CMethod *pMethod, pobj_c->GetDynamicMethods() )
361 {
362 //基底クラスと重複する場合はオーバーライドを行う
363 if( pMethod->GetInheritsClassPtr() ) continue;
364
365 if( pMethod->GetUserProc().IsEqualForOverride( pobj_c->GetSuperClassActualTypeParameters(), pUserProc ) )
366 {
367 //関数名、パラメータ、戻り値が合致したとき
368 compiler.errorMessenger.Output(15,pUserProc->GetName().c_str(),nowLine);
369 return;
370 }
371 }
372
373 //仮想関数の場合
374 if( isAbstract ) pUserProc->CompleteCompile();
375
376 // メソッドのオーバーライド
377 DynamicMethod *pMethodForOverride = pobj_c->GetDynamicMethods().FindForOverride( pobj_c->GetSuperClassActualTypeParameters(), pUserProc );
378 if( pMethodForOverride )
379 {
380 DynamicMethod::OverrideResult result;
381 result.enumType = pMethodForOverride->Override( pUserProc, accessibility, isOverride );
382 result.pMethod = pMethodForOverride;
383 OverrideErrorCheck( result );
384
385 pUserProc->SetMethod( pMethodForOverride );
386 return;
387 }
388 else
389 {
390 // インターフェイス メソッドのオーバーライド
391 BOOST_FOREACH( ::Interface *pInterface, pobj_c->GetInterfaces() )
392 {
393 if( interfaceName[0] )
394 {
395 if( pInterface->GetClass().GetName() != interfaceName )
396 {
397 // 指定されたインターフェイス名と整合しないとき
398 continue;
399 }
400 }
401
402 if( !pInterface->GetClass().IsReady() ){
403 // インターフェイスが未解析のとき
404 LexicalAnalyzer::LookaheadClass(
405 pInterface->GetClass().GetName().c_str(),
406 compiler.GetObjectModule().meta.GetClasses()
407 );
408 }
409
410 DynamicMethod *pMethodForOverride = pInterface->GetDynamicMethods().FindForOverride( pInterface->GetActualTypeParameters(), pUserProc );
411 if( pMethodForOverride )
412 {
413 DynamicMethod::OverrideResult result;
414 result.enumType = pMethodForOverride->Override( pUserProc, accessibility, isOverride );
415 result.pMethod = pMethodForOverride;
416 OverrideErrorCheck( result );
417
418 pUserProc->SetMethod( pMethodForOverride );
419 return;
420 }
421 }
422 }
423
424 if( interfaceName[0] )
425 {
426 compiler.errorMessenger.Output(139,interfaceName,nowLine);
427 }
428
429 if( isVirtual ){
430 pobj_c->AddVtblNum( 1 );
431 }
432
433 if( isOverride ){
434 compiler.errorMessenger.Output(12,"Override",nowLine);
435 }
436
437 if(bStatic){
438 pobj_c->GetStaticMethods().AddStatic( pUserProc, accessibility );
439 }
440 else{
441 pobj_c->GetDynamicMethods().Add(pUserProc, accessibility, isConst, isAbstract, isVirtual);
442 }
443}
444
445bool LexicalAnalyzer::Inherits( CClass &_class, const char *inheritNames, int nowLine ){
446 int i = 0;
447 bool isInheritsClass = false;
448 while( true ){
449
450 char temporary[VN_SIZE];
451 for( int i2=0;; i++, i2++ ){
452 if( inheritNames[i] == '\0' || inheritNames[i] == ',' ){
453 temporary[i2] = 0;
454 break;
455 }
456 temporary[i2] = inheritNames[i];
457 }
458
459 // ジェネリクス構文を分解
460 char className[VN_SIZE];
461 Jenga::Common::Strings typeParameterStrings;
462 SplitGenericClassInstance( temporary, className, typeParameterStrings );
463
464 // 型パラメータ文字列から型データを取得
465 Types actualTypeParameters;
466 BOOST_FOREACH( const std::string &typeParameterStr, typeParameterStrings )
467 {
468 Type type;
469 compiler.StringToType( typeParameterStr, type );
470 actualTypeParameters.push_back( type );
471 }
472
473 //継承元クラスを取得
474 const CClass *pInheritsClass = compiler.GetObjectModule().meta.FindClassSupportedTypeDef(className);
475 if( !pInheritsClass ){
476 compiler.errorMessenger.Output(106,className,nowLine);
477 return false;
478 }
479
480 if( pInheritsClass->IsClass() ){
481 // クラスを継承する
482 isInheritsClass = true;
483
484 //ループ継承でないかをチェック
485 if( !LexicalAnalyzer::LoopRefCheck(*pInheritsClass) )
486 {
487 compiler.errorMessenger.Output(123,pInheritsClass->GetName(),nowLine);
488 return false;
489 }
490
491 if( !pInheritsClass->IsReady() ){
492 //継承先が読み取られていないとき
493 LexicalAnalyzer::LookaheadClass(
494 pInheritsClass->GetName().c_str(),
495 compiler.GetObjectModule().meta.GetClasses()
496 );
497 }
498
499 if( !_class.InheritsClass( *pInheritsClass, actualTypeParameters, nowLine ) ){
500 return false;
501 }
502 }
503 else{
504 compiler.errorMessenger.Output(135,pInheritsClass->GetFullName().c_str(),nowLine);
505 return false;
506 }
507
508 if( inheritNames[i] == '\0' ){
509 break;
510 }
511 i++;
512 }
513
514 if( !isInheritsClass ){
515 const CClass *pObjectClass = compiler.GetObjectModule().meta.GetClasses().GetObjectClassPtr();
516 //ループ継承でないかをチェック
517 if( !LexicalAnalyzer::LoopRefCheck( *pObjectClass ) )
518 {
519 compiler.errorMessenger.Output(123,pObjectClass->GetName(),nowLine);
520 return false;
521 }
522
523 if( !pObjectClass->IsReady() ){
524 //継承先が読み取られていないとき
525 LexicalAnalyzer::LookaheadClass(
526 pObjectClass->GetName().c_str(),
527 compiler.GetObjectModule().meta.GetClasses()
528 );
529 }
530
531 // クラスを一つも継承していないとき
532 if( !_class.InheritsClass( *pObjectClass, Types(), nowLine ) ){
533 return false;
534 }
535 }
536
537 return true;
538}
539
540void LexicalAnalyzer::Implements( CClass &_class, Interface *pInterface, std::vector<DynamicMethod::OverrideResult> &overrideResults )
541{
542 _class.AddInterface( pInterface );
543
544
545 /////////////////////////////////////////////////////////////////
546 // 基底クラスのメソッドからインターフェイスメソッドを再実装する
547 /////////////////////////////////////////////////////////////////
548 BOOST_FOREACH( CMethod *pMethod, _class.GetDynamicMethods() )
549 {
550 DynamicMethod *pMethodForOverride = pInterface->GetDynamicMethods().FindForOverride( pInterface->GetActualTypeParameters(), &pMethod->GetUserProc() );
551 if( pMethodForOverride )
552 {
553 DynamicMethod::OverrideResult result;
554 result.enumType = pMethodForOverride->Override( &pMethod->GetUserProc(), pMethod->GetAccessibility(), false );
555 result.pMethod = pMethod;
556 overrideResults.push_back( result );
557
558 // 実装元になるメソッドは呼び出し不可にしておく(オーバーロードの解決から除外する)
559 pMethod->SetNotUseMark( true );
560 }
561 }
562
563
564 /////////////////////////////////////////////////////////////////
565 // キャストメソッドを追加(内部コードは自動生成すること)
566 // ※COMインターフェイスは除外すること
567 /////////////////////////////////////////////////////////////////
568 if( pInterface->GetClass().IsInterface() )
569 {
570 // Function Operator() As ITest
571
572 char methodName[255] = { 1, ESC_OPERATOR, CALC_AS, '\0' };
573
574 //関数ハッシュへ登録
575 UserProc *pUserProc = new UserProc(
576 NamespaceScopes(),
577 NamespaceScopesCollection(),
578 methodName,
579 Procedure::Function,
580 false,
581 false,
582 false );
583 pUserProc->SetParentClass( &_class );
584
585 Parameters params;
586 params.push_back( new Parameter( "_System_LocalThis", Type( DEF_PTR_VOID ) ) );
587 pUserProc->SetRealParams( params );
588
589 pUserProc->SetReturnType( Type( DEF_OBJECT, pInterface->GetClass() ) );
590 pUserProc->_paramStr = "";
591 pUserProc->Using();
592 compiler.GetObjectModule().meta.GetUserProcs().Insert( pUserProc, -1 );
593
594 LexicalAnalyzer::AddMethod(
595 &_class,
596 pUserProc,
597 Prototype::Public,
598 0,
599 false, // isConst
600 false, // isAbstract
601 false, // isVirtual
602 false, // isOverride
603 "",
604 true, // isAutoGeneration
605 -1
606 );
607 }
608}
609
610bool LexicalAnalyzer::Implements( CClass &_class, const char *interfaceNames, int nowLine )
611{
612 Jenga::Common::Strings paramStrs;
613 SplitParameter( interfaceNames, paramStrs );
614
615 BOOST_FOREACH( const std::string &paramStr, paramStrs )
616 {
617 char className[VN_SIZE];
618 Jenga::Common::Strings typeParameterStrings;
619 SplitGenericClassInstance( paramStr.c_str(), className, typeParameterStrings );
620
621 Types actualTypeParameters;
622 BOOST_FOREACH( const std::string &typeParameterStr, typeParameterStrings )
623 {
624 Type type;
625 compiler.StringToType( typeParameterStr, type );
626 actualTypeParameters.push_back( type );
627 }
628
629 //継承元クラスを取得
630 const CClass *pInterfaceClass = compiler.GetObjectModule().meta.FindClassSupportedTypeDef( className );
631 if( !pInterfaceClass ){
632 compiler.errorMessenger.Output(106,paramStr.c_str(),nowLine);
633 continue;
634 }
635
636 if( !pInterfaceClass->IsReady() ){
637 // インターフェイスが未解析のとき
638 LexicalAnalyzer::LookaheadClass(
639 pInterfaceClass->GetName().c_str(),
640 compiler.GetObjectModule().meta.GetClasses()
641 );
642 }
643
644 if( pInterfaceClass->IsInterface() || pInterfaceClass->IsComInterface() )
645 {
646 // インターフェイスを継承する
647 std::vector<DynamicMethod::OverrideResult> overrideResults;
648 Implements(
649 _class,
650 new ::Interface( pInterfaceClass, actualTypeParameters ),
651 overrideResults
652 );
653
654 // エラーチェック
655 BOOST_FOREACH( const DynamicMethod::OverrideResult result, overrideResults )
656 {
657 OverrideErrorCheck( result );
658 }
659 }
660 else
661 {
662 // インターフェイスではないとき
663 compiler.errorMessenger.Output(138,pInterfaceClass->GetName().c_str(),nowLine );
664 }
665 }
666
667 return true;
668}
669
670void GetClass_recur( const char *lpszInheritsClass, Classes &classes )
671{
672 extern char *basbuf;
673 int i,i2,i3,sub_address,top_pos;
674 char temporary[8192];
675
676 // 名前空間管理
677 NamespaceScopes backupNamespaceScopes = compiler.GetNamespaceSupporter().GetLivingNamespaceScopes();
678 NamespaceScopes &namespaceScopes = compiler.GetNamespaceSupporter().GetLivingNamespaceScopes();
679 namespaceScopes.clear();
680
681 // Importsされた名前空間の管理
682 NamespaceScopesCollection backupImportedNamespaces = compiler.GetNamespaceSupporter().GetImportedNamespaces();
683 compiler.GetNamespaceSupporter().GetImportedNamespaces().clear();
684
685 // 呼び出し元でコンパイル中のクラスポインタをバックアップ
686 const CClass *pBackCompilingClass = compiler.IsCompilingClass()
687 ? &compiler.GetCompilingClass()
688 : NULL;
689
690 for(i=0;;i++){
691 if(basbuf[i]=='\0') break;
692
693
694 // 名前空間
695 if( basbuf[i] == 1 && basbuf[i+1] == ESC_NAMESPACE ){
696 for(i+=2,i2=0;;i2++,i++){
697 if( IsCommandDelimitation( basbuf[i] ) ){
698 temporary[i2]=0;
699 break;
700 }
701 temporary[i2]=basbuf[i];
702 }
703 namespaceScopes.push_back( temporary );
704
705 continue;
706 }
707 else if( basbuf[i] == 1 && basbuf[i+1] == ESC_ENDNAMESPACE ){
708 if( namespaceScopes.size() <= 0 ){
709 compiler.errorMessenger.Output(12, "End Namespace", i );
710 }
711 else{
712 namespaceScopes.pop_back();
713 }
714
715 i += 2;
716 continue;
717 }
718
719 else if( basbuf[i] == 1 && basbuf[i+1] == ESC_IMPORTS ){
720 for(i+=2,i2=0;;i2++,i++){
721 if( IsCommandDelimitation( basbuf[i] ) ){
722 temporary[i2]=0;
723 break;
724 }
725 temporary[i2]=basbuf[i];
726 }
727 if( !compiler.GetNamespaceSupporter().ImportsNamespace( temporary ) )
728 {
729 compiler.errorMessenger.Output(64,temporary,i );
730 }
731
732 continue;
733 }
734 else if( basbuf[i] == 1 && basbuf[i+1] == ESC_CLEARNAMESPACEIMPORTED ){
735 compiler.GetNamespaceSupporter().GetImportedNamespaces().clear();
736 continue;
737 }
738
739
740
741 if(basbuf[i]==1&&basbuf[i+1]==ESC_INTERFACE){
742 //////////////////////////
743 // インターフェイス
744 //////////////////////////
745
746 top_pos=i;
747
748 i+=2;
749
750 //インターフェイス名を取得
751 GetCommandToken( temporary, basbuf, i );
752
753 char className[VN_SIZE];
754 Jenga::Common::Strings typeParameters;
755 Jenga::Common::Strings typeParameterBaseClassNames;
756 SplitGenericClassInstance( temporary, className, typeParameters, true, &typeParameterBaseClassNames );
757
758 CClass *pobj_c = const_cast<CClass *>( classes.FindEx(namespaceScopes, className) );
759 if(!pobj_c) continue;
760
761 compiler.SetCompilingClass( pobj_c );
762
763 if(lpszInheritsClass){
764 if(lstrcmp(lpszInheritsClass,pobj_c->GetName().c_str())!=0){
765 //継承先先読み用
766 continue;
767 }
768 }
769
770 if(pobj_c->IsReady()){
771 //既に先読みされているとき
772 continue;
773 }
774
775 /////////////////////////////////////////////////////////
776 // ☆★☆ ジェネリクスサポート ☆★☆
777 for( i2=0; i2<static_cast<int>(typeParameters.size()); i2++ )
778 {
779 Type baseType( DEF_OBJECT, *classes.GetObjectClassPtr() );
780 if( typeParameterBaseClassNames[i2].size() )
781 {
782 if( !compiler.StringToType( typeParameterBaseClassNames[i2], baseType ) )
783 {
784 compiler.errorMessenger.Output(106,typeParameterBaseClassNames[i2],i);
785 }
786 else if( !baseType.IsObject() )
787 {
788 compiler.errorMessenger.Output(106,typeParameterBaseClassNames[i2],i);
789 }
790 }
791
792 pobj_c->AddFormalGenericType( GenericType( typeParameters[i2], baseType ) );
793 }
794 /////////////////////////////////////////////////////////
795
796 pobj_c->Readed();
797
798 pobj_c->SetConstructorMemberSubIndex( -1 );
799 pobj_c->SetDestructorMemberSubIndex( -1 );
800
801 if( memcmp( basbuf+i+1, "__COM", 5 ) == 0 && IsCommandDelimitation( basbuf[i+1+5] ) )
802 {
803 // COMインターフェイス
804 pobj_c->SetClassType( CClass::ComInterface );
805
806 i += 6;
807 }
808
809 if(basbuf[i+1]==1&&basbuf[i+2]==ESC_INHERITS){
810 //継承を行う場合
811 for(i+=3,i2=0;;i++,i2++){
812 if(IsCommandDelimitation(basbuf[i])){
813 temporary[i2]=0;
814 break;
815 }
816 temporary[i2]=basbuf[i];
817 }
818
819 if(lstrcmpi(temporary,pobj_c->GetName().c_str())==0){
820 compiler.errorMessenger.Output(105,temporary,i);
821 goto Interface_InheritsError;
822 }
823
824 //継承元クラスを取得
825 const CClass *pInheritsClass = compiler.GetObjectModule().meta.FindClassSupportedTypeDef( temporary );
826 if( !pInheritsClass ){
827 compiler.errorMessenger.Output(106,temporary,i);
828 goto Interface_InheritsError;
829 }
830
831 //ループ継承でないかをチェック
832 if( !LexicalAnalyzer::LoopRefCheck( *pInheritsClass ) )
833 {
834 compiler.errorMessenger.Output(123,pInheritsClass->GetName(),i);
835 goto Interface_InheritsError;
836 }
837
838 //継承させる
839 if( !pobj_c->InheritsClass( *pInheritsClass, Types(), i ) ){
840 goto Interface_InheritsError;
841 }
842 }
843 else{
844 //継承無し
845 if( &pobj_c->GetSuperClass() || pobj_c->GetVtblNum() )
846 {
847 // TODO: ここに来ないことが実証できたらこの分岐は消す
848 Jenga::Throw( "GetClass_recur内の例外" );
849 }
850 }
851Interface_InheritsError:
852
853 //メンバ変数、関数を取得
854 while(1){
855 i++;
856
857 //エラー
858 if(basbuf[i]==1&&(basbuf[i+1]==ESC_CLASS||basbuf[i+1]==ESC_TYPE||basbuf[i+1]==ESC_INTERFACE)){
859 compiler.errorMessenger.Output(22,"Interface",i);
860 i--;
861 break;
862 }
863
864 if(basbuf[i]==1&&basbuf[i+1]==ESC_INHERITS){
865 compiler.errorMessenger.Output(111,NULL,i);
866 break;
867 }
868 else if( basbuf[i] == 1 && basbuf[i+1] == ESC_IMPLEMENTS )
869 {
870 compiler.errorMessenger.Output(137, NULL, i );
871 break;
872 }
873
874 sub_address=i;
875
876 for(i2=0;;i++,i2++){
877 if(IsCommandDelimitation(basbuf[i])){
878 temporary[i2]=0;
879 break;
880 }
881 temporary[i2]=basbuf[i];
882 }
883 if(temporary[0]=='\0'){
884 if(basbuf[i]=='\0'){
885 i--;
886 compiler.errorMessenger.Output(22,"Interface",top_pos);
887 break;
888 }
889 continue;
890 }
891
892 //End Interface記述の場合
893 if(temporary[0]==1&&temporary[1]==ESC_ENDINTERFACE) break;
894
895 if(!(temporary[0]==1&&(
896 temporary[1]==ESC_SUB||temporary[1]==ESC_FUNCTION
897 ))){
898 compiler.errorMessenger.Output(1,NULL,i);
899 break;
900 }
901
902 //関数ハッシュへ登録
903 char interfaceName[VN_SIZE] = "";
904 UserProc *pUserProc = LexicalAnalyzer::ParseUserProc( NamespaceScopes(), NamespaceScopesCollection(), temporary,sub_address,true,pobj_c, false, interfaceName );
905 if( pUserProc )
906 {
907 compiler.GetObjectModule().meta.GetUserProcs().Insert( pUserProc, i );
908
909 //メンバ関数を追加
910 LexicalAnalyzer::AddMethod(pobj_c,
911 pUserProc,
912 Prototype::Public, //Publicアクセス権
913 0, // bStatic
914 false, // isConst
915 true, // isAbstract
916 true, // isVirtual
917 false, // isOverride
918 interfaceName,
919 false, // isAutoGeneration
920 sub_address
921 );
922 }
923 }
924 }
925
926 if(basbuf[i]==1&&(basbuf[i+1]==ESC_CLASS||basbuf[i+1]==ESC_TYPE)){
927 //////////////////////////
928 // クラス
929 //////////////////////////
930
931 top_pos=i;
932
933 const DWORD dwClassType=basbuf[i+1];
934
935 i+=2;
936
937 int iAlign=0;
938 if(memicmp(basbuf+i,"Align(",6)==0){
939 //アラインメント修飾子
940 i+=6;
941 i+=GetStringInPare_RemovePare(temporary,basbuf+i)+1;
942 iAlign=atoi(temporary);
943
944 if( dwClassType != ESC_TYPE )
945 {
946 compiler.errorMessenger.Output(140,NULL,i);
947 }
948
949 if(!(iAlign==1||iAlign==2||iAlign==4||iAlign==8||iAlign==16))
950 compiler.errorMessenger.Output(51,NULL,i);
951 }
952 else if( memicmp( basbuf + i, "Blittable(", 10 ) == 0 ){
953 // Blittable修飾子
954 i+=10;
955 i=JumpStringInPare(basbuf,i)+1;
956
957 if( dwClassType != ESC_CLASS )
958 {
959 compiler.errorMessenger.Output(141,NULL,i);
960 }
961 }
962
963 if( basbuf[i] == 1 && basbuf[i+1] == ESC_ENUM )
964 {
965 // 列挙型の場合
966 i += 2;
967 }
968 else if( basbuf[i] == 1 && basbuf[i+1] == ESC_DELEGATE )
969 {
970 // デリゲートの場合
971 i += 2;
972 }
973
974 //クラス名を取得
975 GetCommandToken( temporary, basbuf, i );
976
977 char className[VN_SIZE];
978 Jenga::Common::Strings typeParameters;
979 Jenga::Common::Strings typeParameterBaseClassNames;
980 SplitGenericClassInstance( temporary, className, typeParameters, true, &typeParameterBaseClassNames );
981
982 CClass *pobj_c = const_cast<CClass *>( classes.FindEx(namespaceScopes, className) );
983 if(!pobj_c) continue;
984
985 compiler.SetCompilingClass( pobj_c );
986
987 if(lpszInheritsClass){
988 if( pobj_c->GetName() != lpszInheritsClass ){
989 //継承先先読み用
990 continue;
991 }
992 }
993
994 if( lstrcmp(className,"Control")==0)
995 {
996 int test=0;
997 }
998
999 if(pobj_c->IsReady()){
1000 //既に先読みされているとき
1001 continue;
1002 }
1003
1004
1005 /////////////////////////////////////////////////////////
1006 // ☆★☆ ジェネリクスサポート ☆★☆
1007 for( i2=0; i2<static_cast<int>(typeParameters.size()); i2++ )
1008 {
1009 Type baseType( DEF_OBJECT, *classes.GetObjectClassPtr() );
1010 if( typeParameterBaseClassNames[i2].size() )
1011 {
1012 if( !compiler.StringToType( typeParameterBaseClassNames[i2], baseType ) )
1013 {
1014 compiler.errorMessenger.Output(106,typeParameterBaseClassNames[i2],i);
1015 }
1016 else if( !baseType.IsObject() )
1017 {
1018 compiler.errorMessenger.Output(106,typeParameterBaseClassNames[i2],i);
1019 }
1020 }
1021
1022 pobj_c->AddFormalGenericType( GenericType( typeParameters[i2], baseType ) );
1023 }
1024 /////////////////////////////////////////////////////////
1025
1026
1027 pobj_c->SetFixedAlignment( iAlign );
1028
1029 pobj_c->Readed();
1030
1031 pobj_c->SetConstructorMemberSubIndex( -1 );
1032 pobj_c->SetDestructorMemberSubIndex( -1 );
1033
1034 //アクセス制限の初期値をセット
1035 Prototype::Accessibility accessibility;
1036 if(dwClassType==ESC_CLASS){
1037 accessibility = Prototype::Private;
1038 }
1039 else{
1040 accessibility = Prototype::Public;
1041 }
1042
1043 if( pobj_c->GetName() == "Object"
1044 || dwClassType == ESC_TYPE )
1045 {
1046 // 何も継承しない
1047
1048 if( &pobj_c->GetSuperClass() || pobj_c->GetVtblNum() )
1049 {
1050 // TODO: ここに来ないことが実証できたらこの分岐は消す
1051 Jenga::Throw( "GetClass_recur内の例外" );
1052 }
1053 }
1054 else{
1055 if(basbuf[i+1]==1&&basbuf[i+2]==ESC_INHERITS)
1056 {
1057 // クラス継承先が指定されているとき
1058 i += 3;
1059 GetCommandToken( temporary, basbuf, i );
1060
1061 if(lstrcmpi(temporary,pobj_c->GetName().c_str())==0){
1062 compiler.errorMessenger.Output(105,temporary,i);
1063 goto InheritsError;
1064 }
1065 }
1066 else
1067 {
1068 // 何の指定もないときはObjectクラスを継承する
1069 lstrcpy( temporary, "Object" );
1070 }
1071 LexicalAnalyzer::Inherits( *pobj_c, temporary, i );
1072
1073 if( basbuf[i+1] == 1 && basbuf[i+2] == ESC_IMPLEMENTS )
1074 {
1075 // インターフェイス実装を行う場合
1076 i += 3;
1077 GetCommandToken( temporary, basbuf, i );
1078
1079 LexicalAnalyzer::Implements( *pobj_c, temporary, i );
1080 }
1081 }
1082InheritsError:
1083
1084 //メンバとメソッドを取得
1085 while(1){
1086 i++;
1087
1088 //エラー
1089 if(basbuf[i]==1&&(basbuf[i+1]==ESC_CLASS||basbuf[i+1]==ESC_TYPE)){
1090 compiler.errorMessenger.Output(22,"Class",i);
1091 i--;
1092 break;
1093 }
1094
1095 if(basbuf[i]==1&&basbuf[i+1]==ESC_INHERITS){
1096 compiler.errorMessenger.Output(111,NULL,i);
1097 break;
1098 }
1099 else if( basbuf[i] == 1 && basbuf[i+1] == ESC_IMPLEMENTS )
1100 {
1101 compiler.errorMessenger.Output(137, NULL, i );
1102 break;
1103 }
1104
1105 //Static修飾子
1106 BOOL bStatic;
1107 if(basbuf[i]==1&&basbuf[i+1]==ESC_STATIC){
1108 bStatic=1;
1109 i+=2;
1110 }
1111 else bStatic=0;
1112
1113 //Const修飾子
1114 bool isConst = false;
1115 if( basbuf[i] == 1 && basbuf[i + 1] == ESC_CONST ){
1116 isConst = true;
1117 i += 2;
1118 }
1119
1120 if(basbuf[i]==1&&(
1121 basbuf[i+1]==ESC_ABSTRACT||basbuf[i+1]==ESC_VIRTUAL||basbuf[i+1]==ESC_OVERRIDE||
1122 basbuf[i+1]==ESC_SUB||basbuf[i+1]==ESC_FUNCTION
1123 )){
1124 i3=basbuf[i+1];
1125 sub_address=i;
1126 }
1127 else i3=0;
1128
1129 bool isVirtual = false, isAbstract = false, isOverride = false;
1130 if(i3==ESC_ABSTRACT){
1131 isAbstract=1;
1132 isVirtual=1;
1133 i+=2;
1134
1135 i3=basbuf[i+1];
1136 }
1137 else if(i3==ESC_VIRTUAL){
1138 isAbstract=0;
1139 isVirtual=1;
1140 i+=2;
1141
1142 i3=basbuf[i+1];
1143 }
1144 else if(i3==ESC_OVERRIDE){
1145 isOverride=1;
1146 isVirtual=1;
1147
1148 i+=2;
1149
1150 i3=basbuf[i+1];
1151 }
1152
1153 for(i2=0;;i++,i2++){
1154 if(IsCommandDelimitation(basbuf[i])){
1155 temporary[i2]=0;
1156 break;
1157 }
1158 temporary[i2]=basbuf[i];
1159 }
1160 if(temporary[0]=='\0'){
1161 if(basbuf[i]=='\0'){
1162
1163 if(dwClassType==ESC_CLASS)
1164 compiler.errorMessenger.Output(22,"Class",top_pos);
1165 else
1166 compiler.errorMessenger.Output(22,"Type",top_pos);
1167
1168 i--;
1169 break;
1170 }
1171 continue;
1172 }
1173
1174 //End Class記述の場合
1175 if(temporary[0]==1&&temporary[1]==ESC_ENDCLASS&&dwClassType==ESC_CLASS) break;
1176 if(temporary[0]==1&&temporary[1]==ESC_ENDTYPE&&dwClassType==ESC_TYPE) break;
1177
1178 //アクセスを変更
1179 if(lstrcmpi(temporary,"Private")==0){
1180 accessibility = Prototype::Private;
1181 continue;
1182 }
1183 if(lstrcmpi(temporary,"Public")==0){
1184 accessibility = Prototype::Public;
1185 continue;
1186 }
1187 if(lstrcmpi(temporary,"Protected")==0){
1188 accessibility = Prototype::Protected;
1189 continue;
1190 }
1191
1192 extern int cp;
1193 if(i3==0){
1194 if(bStatic){
1195 //静的メンバを追加
1196 cp=i; //エラー用
1197 pobj_c->AddStaticMember(
1198 LexicalAnalyzer::CreateMember( *pobj_c, accessibility, isConst, false, temporary, i )
1199 );
1200 }
1201 else{
1202 //メンバを追加
1203 cp=i; //エラー用
1204 pobj_c->AddDynamicMember(
1205 LexicalAnalyzer::CreateMember( *pobj_c, accessibility, isConst, false, temporary, i )
1206 );
1207
1208
1209 if(pobj_c->GetDynamicMembers().back()->GetType().IsStruct()){
1210 if( !pobj_c->GetDynamicMembers().back()->GetType().GetClass().IsReady() ){
1211 //参照先が読み取られていないとき
1212 GetClass_recur( pobj_c->GetDynamicMembers().back()->GetType().GetClass().GetName().c_str(), classes );
1213 }
1214 }
1215
1216
1217 if(pobj_c->GetDynamicMembers().back()->GetType().IsStruct()){
1218 //循環参照のチェック
1219 pobj_LoopRefCheck->add(pobj_c->GetName().c_str());
1220 if(!MemberVar_LoopRefCheck(pobj_c->GetDynamicMembers().back()->GetType().GetClass())){
1221 //エラー回避
1222 Type &type = const_cast<Type &>(pobj_c->GetDynamicMembers().back()->GetType());
1223 type.SetBasicType( DEF_PTR_VOID );
1224 }
1225 pobj_LoopRefCheck->del(pobj_c->GetName().c_str());
1226 }
1227 }
1228 }
1229 else{
1230 //関数ハッシュへ登録
1231 char interfaceName[VN_SIZE] = "";
1232 UserProc *pUserProc = LexicalAnalyzer::ParseUserProc( NamespaceScopes(), NamespaceScopesCollection(), temporary,sub_address,isVirtual,pobj_c, (bStatic!=0), interfaceName );
1233 if( pUserProc )
1234 {
1235 compiler.GetObjectModule().meta.GetUserProcs().Insert( pUserProc, i );
1236
1237 //メソッドを追加
1238 cp=i; //エラー用
1239 LexicalAnalyzer::AddMethod(pobj_c,
1240 pUserProc,
1241 accessibility,
1242 bStatic,
1243 isConst,
1244 isAbstract,
1245 isVirtual,
1246 isOverride,
1247 interfaceName,
1248 false,
1249 sub_address);
1250 }
1251
1252 if( isAbstract ) continue;
1253
1254 for(;;i++){
1255 if(basbuf[i]=='\0'){
1256 i--;
1257 break;
1258 }
1259 if(basbuf[i-1]!='*'&&
1260 basbuf[i]==1&&(
1261 basbuf[i+1]==ESC_SUB||
1262 basbuf[i+1]==ESC_FUNCTION||
1263 basbuf[i+1]==ESC_MACRO||
1264 basbuf[i+1]==ESC_TYPE||
1265 basbuf[i+1]==ESC_CLASS||
1266 basbuf[i+1]==ESC_INTERFACE||
1267 basbuf[i+1]==ESC_ENUM)){
1268 GetDefaultNameFromES(i3,temporary);
1269 compiler.errorMessenger.Output(22,temporary,i);
1270 }
1271 if(basbuf[i]==1&&basbuf[i+1]==GetEndXXXCommand((char)i3)){
1272 i+=2;
1273 break;
1274 }
1275 }
1276 }
1277 }
1278 }
1279 }
1280
1281 // 呼び出し元でコンパイル中のクラスポインタを元に戻す
1282 compiler.SetCompilingClass( pBackCompilingClass );
1283
1284 // 名前空間を元に戻す
1285 compiler.GetNamespaceSupporter().GetLivingNamespaceScopes() = backupNamespaceScopes;
1286
1287 // インポートされた名前空間を元に戻す
1288 compiler.GetNamespaceSupporter().GetImportedNamespaces() = backupImportedNamespaces;
1289}
1290
1291void LexicalAnalyzer::LookaheadClass( const char *className, Classes &classes )
1292{
1293 pobj_LoopRefCheck->add( className );
1294 GetClass_recur( className, classes );
1295 pobj_LoopRefCheck->del( className );
1296}
1297
1298bool LexicalAnalyzer::LoopRefCheck( const CClass &objClass )
1299{
1300 if( pobj_LoopRefCheck->check( objClass ) )
1301 {
1302 return false;
1303 }
1304
1305 return true;
1306}
1307
1308void LexicalAnalyzer::CollectClasses( const char *source, Classes &classes ){
1309 //ループ継承チェック用のクラス
1310 pobj_LoopRefCheck=new CLoopRefCheck();
1311
1312 //クラスを取得
1313 GetClass_recur( 0, classes );
1314
1315 delete pobj_LoopRefCheck;
1316 pobj_LoopRefCheck=0;
1317
1318 // イテレータの準備
1319 classes.Iterator_Init();
1320}
Note: See TracBrowser for help on using the repository browser.