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

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

ImplementsメソッドをLexicalAnalyzerクラスに移動した。

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