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

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

Class_Collect.cppからLexicalAnalyzer_Class.cppへリネーム

File size: 26.0 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
17class CLoopRefCheck{
18 char **names;
19 int num;
20 void init(){
21 int i;
22 for(i=0;i<num;i++){
23 free(names[i]);
24 }
25 free(names);
26 }
27public:
28 CLoopRefCheck()
29 {
30 names=(char **)malloc(1);
31 num=0;
32 }
33 ~CLoopRefCheck()
34 {
35 init();
36 }
37 void add(const char *lpszInheritsClass)
38 {
39 names=(char **)realloc(names,(num+1)*sizeof(char *));
40 names[num]=(char *)malloc(lstrlen(lpszInheritsClass)+1);
41 lstrcpy(names[num],lpszInheritsClass);
42 num++;
43 }
44 void del(const char *lpszInheritsClass)
45 {
46 int i;
47 for(i=0;i<num;i++){
48 if(lstrcmp(names[i],lpszInheritsClass)==0){
49 free(names[i]);
50 break;
51 }
52 }
53 if(i!=num){
54 num--;
55 for(;i<num;i++){
56 names[i]=names[i+1];
57 }
58 }
59 }
60 BOOL check(const CClass &inheritsClass) const
61 {
62 //ループ継承チェック
63 int i;
64 for(i=0;i<num;i++){
65 if( inheritsClass.GetName() == names[i] ){
66 return 1;
67 }
68 }
69 return 0;
70 }
71};
72CLoopRefCheck *pobj_LoopRefCheck;
73
74bool MemberVar_LoopRefCheck(const CClass &objClass){
75 if( objClass.HasSuperClass() )
76 {
77 // 基底クラスをチェック
78 if( MemberVar_LoopRefCheck( objClass.GetSuperClass() ) == false )
79 {
80 return false;
81 }
82 }
83
84 bool result = true;
85 BOOST_FOREACH( CMember *pMember, objClass.GetDynamicMembers() ){
86 if(pMember->GetType().IsStruct()){
87 //循環参照でないかをチェック
88 if(pobj_LoopRefCheck->check(pMember->GetType().GetClass())){
89 extern int cp;
90 compiler.errorMessenger.Output(124,pMember->GetType().GetClass().GetName(),cp);
91 return false;
92 }
93
94 pobj_LoopRefCheck->add(objClass.GetName().c_str());
95
96 bool tempResult = MemberVar_LoopRefCheck(pMember->GetType().GetClass());
97 if( result )
98 {
99 result = tempResult;
100 }
101
102 pobj_LoopRefCheck->del(objClass.GetName().c_str());
103 }
104 }
105
106 return result;
107}
108
109void LexicalAnalyzer::AddMethod(CClass *pobj_c, UserProc *pUserProc, Prototype::Accessibility accessibility, BOOL bStatic, bool isConst, bool isAbstract,
110 bool isVirtual, bool isOverride, const char *interfaceName, bool isAutoGeneration, int nowLine)
111{
112 if( isAutoGeneration )
113 {
114 // コード自動生成
115 pUserProc->ThisIsAutoGenerationProc();
116 }
117
118
119 ////////////////////////////////////////////////////////////
120 // コンストラクタ、デストラクタの場合の処理
121 ////////////////////////////////////////////////////////////
122 BOOL fConstructor=0,bDestructor=0;
123
124 if( pUserProc->GetName() == pobj_c->GetName() ){
125 //コンストラクタの場合
126
127 //標準コンストラクタ(引数なし)
128 if(pUserProc->Params().size()==0) fConstructor=1;
129
130 //強制的にConst修飾子をつける
131 isConst = true;
132 }
133 else if(pUserProc->GetName()[0]=='~'){
134 //デストラクタの場合はその名前が正しいかチェックを行う
135 if(lstrcmp(pUserProc->GetName().c_str()+1,pobj_c->GetName().c_str())!=0)
136 compiler.errorMessenger.Output(117,NULL,nowLine);
137 else
138 bDestructor=1;
139 }
140 if(fConstructor||bDestructor){
141 // コンストラクタ、デストラクタのアクセシビリティをチェック
142
143 //強制的にConst修飾子をつける
144 isConst = true;
145 }
146
147 if( fConstructor == 1 )
148 pobj_c->SetConstructorMemberSubIndex( (int)pobj_c->GetDynamicMethods().size() );
149 else if( bDestructor )
150 pobj_c->SetDestructorMemberSubIndex( (int)pobj_c->GetDynamicMethods().size() );
151
152
153
154 //////////////////
155 // 重複チェック
156 //////////////////
157
158 if(pobj_c->DupliCheckMember( pUserProc->GetName().c_str() )){
159 compiler.errorMessenger.Output(15,pUserProc->GetName(),nowLine);
160 return;
161 }
162
163 //メソッド
164 BOOST_FOREACH( const CMethod *pMethod, pobj_c->GetDynamicMethods() )
165 {
166 //基底クラスと重複する場合はオーバーライドを行う
167 if( pMethod->GetInheritsClassPtr() ) continue;
168
169 if( pMethod->GetUserProc().IsEqualForOverride( pobj_c->GetSuperClassActualTypeParameters(), pUserProc ) )
170 {
171 //関数名、パラメータ、戻り値が合致したとき
172 compiler.errorMessenger.Output(15,pUserProc->GetName().c_str(),nowLine);
173 return;
174 }
175 }
176
177 //仮想関数の場合
178 if( isAbstract ) pUserProc->CompleteCompile();
179
180 // メソッドのオーバーライド
181 CMethod *pMethodForOverride = pobj_c->GetDynamicMethods().FindForOverride( pobj_c->GetSuperClassActualTypeParameters(), pUserProc );
182 if( pMethodForOverride )
183 {
184 pMethodForOverride->Override( pUserProc, accessibility, isOverride );
185 pUserProc->SetMethod( pMethodForOverride );
186 return;
187 }
188 else
189 {
190 // インターフェイス メソッドのオーバーライド
191 BOOST_FOREACH( ::Interface *pInterface, pobj_c->GetInterfaces() )
192 {
193 if( interfaceName[0] )
194 {
195 if( pInterface->GetClass().GetName() != interfaceName )
196 {
197 // 指定されたインターフェイス名と整合しないとき
198 continue;
199 }
200 }
201
202 if( !pInterface->GetClass().IsReady() ){
203 // インターフェイスが未解析のとき
204 LexicalAnalyzer::LookaheadClass(
205 pInterface->GetClass().GetName().c_str(),
206 compiler.GetObjectModule().meta.GetClasses()
207 );
208 }
209
210 CMethod *pMethodForOverride = pInterface->GetDynamicMethods().FindForOverride( pInterface->GetActualTypeParameters(), pUserProc );
211 if( pMethodForOverride )
212 {
213 pMethodForOverride->Override( pUserProc, accessibility, isOverride );
214 pUserProc->SetMethod( pMethodForOverride );
215 return;
216 }
217 }
218 }
219
220 if( interfaceName[0] )
221 {
222 compiler.errorMessenger.Output(139,interfaceName,nowLine);
223 }
224
225 if( isVirtual ){
226 pobj_c->AddVtblNum( 1 );
227 }
228
229 if( isOverride ){
230 compiler.errorMessenger.Output(12,"Override",nowLine);
231 }
232
233 if(bStatic){
234 pobj_c->GetStaticMethods().AddStatic( pUserProc, accessibility );
235 }
236 else{
237 pobj_c->GetDynamicMethods().Add(pUserProc, accessibility, isConst, isAbstract, isVirtual);
238 }
239}
240
241bool LexicalAnalyzer::Inherits( CClass &currentClass, const char *inheritNames, int nowLine ){
242 int i = 0;
243 bool isInheritsClass = false;
244 while( true ){
245
246 char temporary[VN_SIZE];
247 for( int i2=0;; i++, i2++ ){
248 if( inheritNames[i] == '\0' || inheritNames[i] == ',' ){
249 temporary[i2] = 0;
250 break;
251 }
252 temporary[i2] = inheritNames[i];
253 }
254
255 // ジェネリクス構文を分解
256 char className[VN_SIZE];
257 Jenga::Common::Strings typeParameterStrings;
258 SplitGenericClassInstance( temporary, className, typeParameterStrings );
259
260 // 型パラメータ文字列から型データを取得
261 Types actualTypeParameters;
262 BOOST_FOREACH( const std::string &typeParameterStr, typeParameterStrings )
263 {
264 Type type;
265 compiler.StringToType( typeParameterStr, type );
266 actualTypeParameters.push_back( type );
267 }
268
269 //継承元クラスを取得
270 const CClass *pInheritsClass = compiler.GetObjectModule().meta.GetClasses().Find(className);
271 if( !pInheritsClass ){
272 compiler.errorMessenger.Output(106,className,nowLine);
273 return false;
274 }
275
276 if( pInheritsClass->IsClass() ){
277 // クラスを継承する
278 isInheritsClass = true;
279
280 //ループ継承でないかをチェック
281 if( !LexicalAnalyzer::LoopRefCheck(*pInheritsClass) )
282 {
283 compiler.errorMessenger.Output(123,pInheritsClass->GetName(),nowLine);
284 return false;
285 }
286
287 if( !pInheritsClass->IsReady() ){
288 //継承先が読み取られていないとき
289 LexicalAnalyzer::LookaheadClass(
290 pInheritsClass->GetName().c_str(),
291 compiler.GetObjectModule().meta.GetClasses()
292 );
293 }
294
295 if( !currentClass.InheritsClass( *pInheritsClass, actualTypeParameters, nowLine ) ){
296 return false;
297 }
298 }
299 else{
300 compiler.errorMessenger.Output(135,pInheritsClass->GetFullName().c_str(),nowLine);
301 return false;
302 }
303
304 if( inheritNames[i] == '\0' ){
305 break;
306 }
307 i++;
308 }
309
310 if( !isInheritsClass ){
311 const CClass *pObjectClass = compiler.GetObjectModule().meta.GetClasses().GetObjectClassPtr();
312 //ループ継承でないかをチェック
313 if( !LexicalAnalyzer::LoopRefCheck( *pObjectClass ) )
314 {
315 compiler.errorMessenger.Output(123,pObjectClass->GetName(),nowLine);
316 return false;
317 }
318
319 if( !pObjectClass->IsReady() ){
320 //継承先が読み取られていないとき
321 LexicalAnalyzer::LookaheadClass(
322 pObjectClass->GetName().c_str(),
323 compiler.GetObjectModule().meta.GetClasses()
324 );
325 }
326
327 // クラスを一つも継承していないとき
328 if( !currentClass.InheritsClass( *pObjectClass, Types(), nowLine ) ){
329 return false;
330 }
331 }
332
333 return true;
334}
335
336bool LexicalAnalyzer::Implements( CClass &currentClass, const char *interfaceNames, int nowLine )
337{
338 Jenga::Common::Strings paramStrs;
339 SplitParameter( interfaceNames, paramStrs );
340
341 BOOST_FOREACH( const std::string &paramStr, paramStrs )
342 {
343 char className[VN_SIZE];
344 Jenga::Common::Strings typeParameterStrings;
345 SplitGenericClassInstance( paramStr.c_str(), className, typeParameterStrings );
346
347 Types actualTypeParameters;
348 BOOST_FOREACH( const std::string &typeParameterStr, typeParameterStrings )
349 {
350 Type type;
351 compiler.StringToType( typeParameterStr, type );
352 actualTypeParameters.push_back( type );
353 }
354
355 //継承元クラスを取得
356 const CClass *pInterfaceClass = compiler.GetObjectModule().meta.GetClasses().Find( className );
357 if( !pInterfaceClass ){
358 compiler.errorMessenger.Output(106,paramStr.c_str(),nowLine);
359 continue;
360 }
361
362 if( !pInterfaceClass->IsReady() ){
363 // インターフェイスが未解析のとき
364 LexicalAnalyzer::LookaheadClass(
365 pInterfaceClass->GetName().c_str(),
366 compiler.GetObjectModule().meta.GetClasses()
367 );
368 }
369
370 // インターフェイスを継承する
371 currentClass.Implements( *pInterfaceClass, actualTypeParameters, nowLine );
372 }
373
374 return true;
375}
376
377void GetClass_recur( const char *lpszInheritsClass, Classes &classes )
378{
379 extern char *basbuf;
380 int i,i2,i3,sub_address,top_pos;
381 char temporary[8192];
382
383 // 名前空間管理
384 NamespaceScopes backupNamespaceScopes = compiler.GetNamespaceSupporter().GetLivingNamespaceScopes();
385 NamespaceScopes &namespaceScopes = compiler.GetNamespaceSupporter().GetLivingNamespaceScopes();
386 namespaceScopes.clear();
387
388 // Importsされた名前空間の管理
389 NamespaceScopesCollection backupImportedNamespaces = compiler.GetNamespaceSupporter().GetImportedNamespaces();
390 compiler.GetNamespaceSupporter().GetImportedNamespaces().clear();
391
392 // 呼び出し元でコンパイル中のクラスポインタをバックアップ
393 const CClass *pBackCompilingClass = compiler.pCompilingClass;
394
395 for(i=0;;i++){
396 if(basbuf[i]=='\0') break;
397
398
399 // 名前空間
400 if( basbuf[i] == 1 && basbuf[i+1] == ESC_NAMESPACE ){
401 for(i+=2,i2=0;;i2++,i++){
402 if( IsCommandDelimitation( basbuf[i] ) ){
403 temporary[i2]=0;
404 break;
405 }
406 temporary[i2]=basbuf[i];
407 }
408 namespaceScopes.push_back( temporary );
409
410 continue;
411 }
412 else if( basbuf[i] == 1 && basbuf[i+1] == ESC_ENDNAMESPACE ){
413 if( namespaceScopes.size() <= 0 ){
414 compiler.errorMessenger.Output(12, "End Namespace", i );
415 }
416 else{
417 namespaceScopes.pop_back();
418 }
419
420 i += 2;
421 continue;
422 }
423
424 else if( basbuf[i] == 1 && basbuf[i+1] == ESC_IMPORTS ){
425 for(i+=2,i2=0;;i2++,i++){
426 if( IsCommandDelimitation( basbuf[i] ) ){
427 temporary[i2]=0;
428 break;
429 }
430 temporary[i2]=basbuf[i];
431 }
432 if( !compiler.GetNamespaceSupporter().ImportsNamespace( temporary ) )
433 {
434 compiler.errorMessenger.Output(64,temporary,i );
435 }
436
437 continue;
438 }
439 else if( basbuf[i] == 1 && basbuf[i+1] == ESC_CLEARNAMESPACEIMPORTED ){
440 compiler.GetNamespaceSupporter().GetImportedNamespaces().clear();
441 continue;
442 }
443
444
445
446 if(basbuf[i]==1&&basbuf[i+1]==ESC_INTERFACE){
447 //////////////////////////
448 // インターフェイス
449 //////////////////////////
450
451 top_pos=i;
452
453 i+=2;
454
455 //インターフェイス名を取得
456 GetCommandToken( temporary, basbuf, i );
457
458 char className[VN_SIZE];
459 Jenga::Common::Strings typeParameters;
460 Jenga::Common::Strings typeParameterBaseClassNames;
461 SplitGenericClassInstance( temporary, className, typeParameters, true, &typeParameterBaseClassNames );
462
463 CClass *pobj_c = const_cast<CClass *>( classes.Find(namespaceScopes, className) );
464 if(!pobj_c) continue;
465
466 compiler.pCompilingClass = pobj_c;
467
468 if(lpszInheritsClass){
469 if(lstrcmp(lpszInheritsClass,pobj_c->GetName().c_str())!=0){
470 //継承先先読み用
471 continue;
472 }
473 }
474
475 if(pobj_c->IsReady()){
476 //既に先読みされているとき
477 continue;
478 }
479
480 /////////////////////////////////////////////////////////
481 // ☆★☆ ジェネリクスサポート ☆★☆
482 for( i2=0; i2<static_cast<int>(typeParameters.size()); i2++ )
483 {
484 Type baseType( DEF_OBJECT, *classes.GetObjectClassPtr() );
485 if( typeParameterBaseClassNames[i2].size() )
486 {
487 if( !compiler.StringToType( typeParameterBaseClassNames[i2], baseType ) )
488 {
489 compiler.errorMessenger.Output(106,typeParameterBaseClassNames[i2],i);
490 }
491 else if( !baseType.IsObject() )
492 {
493 compiler.errorMessenger.Output(106,typeParameterBaseClassNames[i2],i);
494 }
495 }
496
497 pobj_c->AddFormalGenericType( GenericType( typeParameters[i2], baseType ) );
498 }
499 /////////////////////////////////////////////////////////
500
501 pobj_c->Readed();
502
503 pobj_c->SetConstructorMemberSubIndex( -1 );
504 pobj_c->SetDestructorMemberSubIndex( -1 );
505
506 if( memcmp( basbuf+i+1, "__COM", 5 ) == 0 && IsCommandDelimitation( basbuf[i+1+5] ) )
507 {
508 // COMインターフェイス
509 pobj_c->SetClassType( CClass::ComInterface );
510
511 i += 6;
512 }
513
514 if(basbuf[i+1]==1&&basbuf[i+2]==ESC_INHERITS){
515 //継承を行う場合
516 for(i+=3,i2=0;;i++,i2++){
517 if(IsCommandDelimitation(basbuf[i])){
518 temporary[i2]=0;
519 break;
520 }
521 temporary[i2]=basbuf[i];
522 }
523
524 if(lstrcmpi(temporary,pobj_c->GetName().c_str())==0){
525 compiler.errorMessenger.Output(105,temporary,i);
526 goto Interface_InheritsError;
527 }
528
529 //継承元クラスを取得
530 const CClass *pInheritsClass = classes.Find(temporary);
531 if( !pInheritsClass ){
532 compiler.errorMessenger.Output(106,temporary,i);
533 goto Interface_InheritsError;
534 }
535
536 //ループ継承でないかをチェック
537 if( !LexicalAnalyzer::LoopRefCheck( *pInheritsClass ) )
538 {
539 compiler.errorMessenger.Output(123,pInheritsClass->GetName(),i);
540 goto Interface_InheritsError;
541 }
542
543 //継承させる
544 if( !pobj_c->InheritsClass( *pInheritsClass, Types(), i ) ){
545 goto Interface_InheritsError;
546 }
547 }
548 else{
549 //継承無し
550 if( &pobj_c->GetSuperClass() || pobj_c->GetVtblNum() )
551 {
552 // TODO: ここに来ないことが実証できたらこの分岐は消す
553 Jenga::Throw( "GetClass_recur内の例外" );
554 }
555 }
556Interface_InheritsError:
557
558 //メンバ変数、関数を取得
559 while(1){
560 i++;
561
562 //エラー
563 if(basbuf[i]==1&&(basbuf[i+1]==ESC_CLASS||basbuf[i+1]==ESC_TYPE||basbuf[i+1]==ESC_INTERFACE)){
564 compiler.errorMessenger.Output(22,"Interface",i);
565 i--;
566 break;
567 }
568
569 if(basbuf[i]==1&&basbuf[i+1]==ESC_INHERITS){
570 compiler.errorMessenger.Output(111,NULL,i);
571 break;
572 }
573 else if( basbuf[i] == 1 && basbuf[i+1] == ESC_IMPLEMENTS )
574 {
575 compiler.errorMessenger.Output(137, NULL, i );
576 break;
577 }
578
579 sub_address=i;
580
581 for(i2=0;;i++,i2++){
582 if(IsCommandDelimitation(basbuf[i])){
583 temporary[i2]=0;
584 break;
585 }
586 temporary[i2]=basbuf[i];
587 }
588 if(temporary[0]=='\0'){
589 if(basbuf[i]=='\0'){
590 i--;
591 compiler.errorMessenger.Output(22,"Interface",top_pos);
592 break;
593 }
594 continue;
595 }
596
597 //End Interface記述の場合
598 if(temporary[0]==1&&temporary[1]==ESC_ENDINTERFACE) break;
599
600 if(!(temporary[0]==1&&(
601 temporary[1]==ESC_SUB||temporary[1]==ESC_FUNCTION
602 ))){
603 compiler.errorMessenger.Output(1,NULL,i);
604 break;
605 }
606
607 //関数ハッシュへ登録
608 char interfaceName[VN_SIZE] = "";
609 UserProc *pUserProc = LexicalAnalyzer::ParseUserProc( NamespaceScopes(), NamespaceScopesCollection(), temporary,sub_address,true,pobj_c, false, interfaceName );
610 if( pUserProc )
611 {
612 compiler.GetObjectModule().meta.GetUserProcs().Insert( pUserProc, i );
613
614 //メンバ関数を追加
615 LexicalAnalyzer::AddMethod(pobj_c,
616 pUserProc,
617 Prototype::Public, //Publicアクセス権
618 0, // bStatic
619 false, // isConst
620 true, // isAbstract
621 true, // isVirtual
622 false, // isOverride
623 interfaceName,
624 false, // isAutoGeneration
625 sub_address
626 );
627 }
628 }
629 }
630
631 if(basbuf[i]==1&&(basbuf[i+1]==ESC_CLASS||basbuf[i+1]==ESC_TYPE)){
632 //////////////////////////
633 // クラス
634 //////////////////////////
635
636 top_pos=i;
637
638 const DWORD dwClassType=basbuf[i+1];
639
640 i+=2;
641
642 int iAlign=0;
643 if(memicmp(basbuf+i,"Align(",6)==0){
644 //アラインメント修飾子
645 i+=6;
646 i+=GetStringInPare_RemovePare(temporary,basbuf+i)+1;
647 iAlign=atoi(temporary);
648
649 if( dwClassType != ESC_TYPE )
650 {
651 compiler.errorMessenger.Output(140,NULL,i);
652 }
653
654 if(!(iAlign==1||iAlign==2||iAlign==4||iAlign==8||iAlign==16))
655 compiler.errorMessenger.Output(51,NULL,i);
656 }
657 else if( memicmp( basbuf + i, "Blittable(", 10 ) == 0 ){
658 // Blittable修飾子
659 i+=10;
660 i=JumpStringInPare(basbuf,i)+1;
661
662 if( dwClassType != ESC_CLASS )
663 {
664 compiler.errorMessenger.Output(141,NULL,i);
665 }
666 }
667
668 if( basbuf[i] == 1 && basbuf[i+1] == ESC_ENUM )
669 {
670 // 列挙型の場合
671 i += 2;
672 }
673 else if( basbuf[i] == 1 && basbuf[i+1] == ESC_DELEGATE )
674 {
675 // デリゲートの場合
676 i += 2;
677 }
678
679 //クラス名を取得
680 GetCommandToken( temporary, basbuf, i );
681
682 char className[VN_SIZE];
683 Jenga::Common::Strings typeParameters;
684 Jenga::Common::Strings typeParameterBaseClassNames;
685 SplitGenericClassInstance( temporary, className, typeParameters, true, &typeParameterBaseClassNames );
686
687 CClass *pobj_c = const_cast<CClass *>( classes.Find(namespaceScopes, className) );
688 if(!pobj_c) continue;
689
690 compiler.pCompilingClass = pobj_c;
691
692 if(lpszInheritsClass){
693 if( pobj_c->GetName() != lpszInheritsClass ){
694 //継承先先読み用
695 continue;
696 }
697 }
698
699 if( lstrcmp(className,"Control")==0)
700 {
701 int test=0;
702 }
703
704 if(pobj_c->IsReady()){
705 //既に先読みされているとき
706 continue;
707 }
708
709
710 /////////////////////////////////////////////////////////
711 // ☆★☆ ジェネリクスサポート ☆★☆
712 for( i2=0; i2<static_cast<int>(typeParameters.size()); i2++ )
713 {
714 Type baseType( DEF_OBJECT, *classes.GetObjectClassPtr() );
715 if( typeParameterBaseClassNames[i2].size() )
716 {
717 if( !compiler.StringToType( typeParameterBaseClassNames[i2], baseType ) )
718 {
719 compiler.errorMessenger.Output(106,typeParameterBaseClassNames[i2],i);
720 }
721 else if( !baseType.IsObject() )
722 {
723 compiler.errorMessenger.Output(106,typeParameterBaseClassNames[i2],i);
724 }
725 }
726
727 pobj_c->AddFormalGenericType( GenericType( typeParameters[i2], baseType ) );
728 }
729 /////////////////////////////////////////////////////////
730
731
732 pobj_c->SetFixedAlignment( iAlign );
733
734 pobj_c->Readed();
735
736 pobj_c->SetConstructorMemberSubIndex( -1 );
737 pobj_c->SetDestructorMemberSubIndex( -1 );
738
739 //アクセス制限の初期値をセット
740 Prototype::Accessibility accessibility;
741 if(dwClassType==ESC_CLASS){
742 accessibility = Prototype::Private;
743 }
744 else{
745 accessibility = Prototype::Public;
746 }
747
748 if( pobj_c->GetName() == "Object"
749 || dwClassType == ESC_TYPE )
750 {
751 // 何も継承しない
752
753 if( &pobj_c->GetSuperClass() || pobj_c->GetVtblNum() )
754 {
755 // TODO: ここに来ないことが実証できたらこの分岐は消す
756 Jenga::Throw( "GetClass_recur内の例外" );
757 }
758 }
759 else{
760 if(basbuf[i+1]==1&&basbuf[i+2]==ESC_INHERITS)
761 {
762 // クラス継承先が指定されているとき
763 i += 3;
764 GetCommandToken( temporary, basbuf, i );
765
766 if(lstrcmpi(temporary,pobj_c->GetName().c_str())==0){
767 compiler.errorMessenger.Output(105,temporary,i);
768 goto InheritsError;
769 }
770 }
771 else
772 {
773 // 何の指定もないときはObjectクラスを継承する
774 lstrcpy( temporary, "Object" );
775 }
776 LexicalAnalyzer::Inherits( *pobj_c, temporary, i );
777
778 if( basbuf[i+1] == 1 && basbuf[i+2] == ESC_IMPLEMENTS )
779 {
780 // インターフェイス実装を行う場合
781 i += 3;
782 GetCommandToken( temporary, basbuf, i );
783
784 LexicalAnalyzer::Implements( *pobj_c, temporary, i );
785 }
786 }
787InheritsError:
788
789 //メンバとメソッドを取得
790 while(1){
791 i++;
792
793 //エラー
794 if(basbuf[i]==1&&(basbuf[i+1]==ESC_CLASS||basbuf[i+1]==ESC_TYPE)){
795 compiler.errorMessenger.Output(22,"Class",i);
796 i--;
797 break;
798 }
799
800 if(basbuf[i]==1&&basbuf[i+1]==ESC_INHERITS){
801 compiler.errorMessenger.Output(111,NULL,i);
802 break;
803 }
804 else if( basbuf[i] == 1 && basbuf[i+1] == ESC_IMPLEMENTS )
805 {
806 compiler.errorMessenger.Output(137, NULL, i );
807 break;
808 }
809
810 //Static修飾子
811 BOOL bStatic;
812 if(basbuf[i]==1&&basbuf[i+1]==ESC_STATIC){
813 bStatic=1;
814 i+=2;
815 }
816 else bStatic=0;
817
818 //Const修飾子
819 bool isConst = false;
820 if( basbuf[i] == 1 && basbuf[i + 1] == ESC_CONST ){
821 isConst = true;
822 i += 2;
823 }
824
825 if(basbuf[i]==1&&(
826 basbuf[i+1]==ESC_ABSTRACT||basbuf[i+1]==ESC_VIRTUAL||basbuf[i+1]==ESC_OVERRIDE||
827 basbuf[i+1]==ESC_SUB||basbuf[i+1]==ESC_FUNCTION
828 )){
829 i3=basbuf[i+1];
830 sub_address=i;
831 }
832 else i3=0;
833
834 bool isVirtual = false, isAbstract = false, isOverride = false;
835 if(i3==ESC_ABSTRACT){
836 isAbstract=1;
837 isVirtual=1;
838 i+=2;
839
840 i3=basbuf[i+1];
841 }
842 else if(i3==ESC_VIRTUAL){
843 isAbstract=0;
844 isVirtual=1;
845 i+=2;
846
847 i3=basbuf[i+1];
848 }
849 else if(i3==ESC_OVERRIDE){
850 isOverride=1;
851 isVirtual=1;
852
853 i+=2;
854
855 i3=basbuf[i+1];
856 }
857
858 for(i2=0;;i++,i2++){
859 if(IsCommandDelimitation(basbuf[i])){
860 temporary[i2]=0;
861 break;
862 }
863 temporary[i2]=basbuf[i];
864 }
865 if(temporary[0]=='\0'){
866 if(basbuf[i]=='\0'){
867
868 if(dwClassType==ESC_CLASS)
869 compiler.errorMessenger.Output(22,"Class",top_pos);
870 else
871 compiler.errorMessenger.Output(22,"Type",top_pos);
872
873 i--;
874 break;
875 }
876 continue;
877 }
878
879 //End Class記述の場合
880 if(temporary[0]==1&&temporary[1]==ESC_ENDCLASS&&dwClassType==ESC_CLASS) break;
881 if(temporary[0]==1&&temporary[1]==ESC_ENDTYPE&&dwClassType==ESC_TYPE) break;
882
883 //アクセスを変更
884 if(lstrcmpi(temporary,"Private")==0){
885 accessibility = Prototype::Private;
886 continue;
887 }
888 if(lstrcmpi(temporary,"Public")==0){
889 accessibility = Prototype::Public;
890 continue;
891 }
892 if(lstrcmpi(temporary,"Protected")==0){
893 accessibility = Prototype::Protected;
894 continue;
895 }
896
897 extern int cp;
898 if(i3==0){
899 if(bStatic){
900 //静的メンバを追加
901 cp=i; //エラー用
902 pobj_c->AddStaticMember( accessibility, isConst, false, temporary, i);
903 }
904 else{
905 //メンバを追加
906 cp=i; //エラー用
907 pobj_c->AddMember( accessibility, isConst, false, temporary, i );
908
909
910 if(pobj_c->GetDynamicMembers().back()->GetType().IsStruct()){
911 if( !pobj_c->GetDynamicMembers().back()->GetType().GetClass().IsReady() ){
912 //参照先が読み取られていないとき
913 GetClass_recur( pobj_c->GetDynamicMembers().back()->GetType().GetClass().GetName().c_str(), classes );
914 }
915 }
916
917
918 if(pobj_c->GetDynamicMembers().back()->GetType().IsStruct()){
919 //循環参照のチェック
920 pobj_LoopRefCheck->add(pobj_c->GetName().c_str());
921 if(!MemberVar_LoopRefCheck(pobj_c->GetDynamicMembers().back()->GetType().GetClass())){
922 //エラー回避
923 Type &type = const_cast<Type &>(pobj_c->GetDynamicMembers().back()->GetType());
924 type.SetBasicType( DEF_PTR_VOID );
925 }
926 pobj_LoopRefCheck->del(pobj_c->GetName().c_str());
927 }
928 }
929 }
930 else{
931 //関数ハッシュへ登録
932 char interfaceName[VN_SIZE] = "";
933 UserProc *pUserProc = LexicalAnalyzer::ParseUserProc( NamespaceScopes(), NamespaceScopesCollection(), temporary,sub_address,isVirtual,pobj_c, (bStatic!=0), interfaceName );
934 if( pUserProc )
935 {
936 compiler.GetObjectModule().meta.GetUserProcs().Insert( pUserProc, i );
937
938 //メソッドを追加
939 cp=i; //エラー用
940 LexicalAnalyzer::AddMethod(pobj_c,
941 pUserProc,
942 accessibility,
943 bStatic,
944 isConst,
945 isAbstract,
946 isVirtual,
947 isOverride,
948 interfaceName,
949 false,
950 sub_address);
951 }
952
953 if( isAbstract ) continue;
954
955 for(;;i++){
956 if(basbuf[i]=='\0'){
957 i--;
958 break;
959 }
960 if(basbuf[i-1]!='*'&&
961 basbuf[i]==1&&(
962 basbuf[i+1]==ESC_SUB||
963 basbuf[i+1]==ESC_FUNCTION||
964 basbuf[i+1]==ESC_MACRO||
965 basbuf[i+1]==ESC_TYPE||
966 basbuf[i+1]==ESC_CLASS||
967 basbuf[i+1]==ESC_INTERFACE||
968 basbuf[i+1]==ESC_ENUM)){
969 GetDefaultNameFromES(i3,temporary);
970 compiler.errorMessenger.Output(22,temporary,i);
971 }
972 if(basbuf[i]==1&&basbuf[i+1]==GetEndXXXCommand((char)i3)){
973 i+=2;
974 break;
975 }
976 }
977 }
978 }
979 }
980 }
981
982 // 呼び出し元でコンパイル中のクラスポインタを元に戻す
983 compiler.pCompilingClass = pBackCompilingClass;
984
985 // 名前空間を元に戻す
986 compiler.GetNamespaceSupporter().GetLivingNamespaceScopes() = backupNamespaceScopes;
987
988 // インポートされた名前空間を元に戻す
989 compiler.GetNamespaceSupporter().GetImportedNamespaces() = backupImportedNamespaces;
990}
991
992void LexicalAnalyzer::LookaheadClass( const char *className, Classes &classes )
993{
994 pobj_LoopRefCheck->add( className );
995 GetClass_recur( className, classes );
996 pobj_LoopRefCheck->del( className );
997}
998
999bool LexicalAnalyzer::LoopRefCheck( const CClass &objClass )
1000{
1001 if( pobj_LoopRefCheck->check( objClass ) )
1002 {
1003 return false;
1004 }
1005
1006 return true;
1007}
1008
1009void LexicalAnalyzer::CollectClasses( const char *source, Classes &classes ){
1010 //ループ継承チェック用のクラス
1011 pobj_LoopRefCheck=new CLoopRefCheck();
1012
1013 //クラスを取得
1014 GetClass_recur( 0, classes );
1015
1016 delete pobj_LoopRefCheck;
1017 pobj_LoopRefCheck=0;
1018
1019 // イテレータの準備
1020 classes.Iterator_Init();
1021}
Note: See TracBrowser for help on using the repository browser.