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

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

SplitMemberNameの依存関係を排除。

File size: 34.8 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(
475 LexicalAnalyzer::FullNameToSymbol( className )
476 );
477 if( !pInheritsClass ){
478 compiler.errorMessenger.Output(106,className,nowLine);
479 return false;
480 }
481
482 if( pInheritsClass->IsClass() ){
483 // クラスを継承する
484 isInheritsClass = true;
485
486 //ループ継承でないかをチェック
487 if( !LexicalAnalyzer::LoopRefCheck(*pInheritsClass) )
488 {
489 compiler.errorMessenger.Output(123,pInheritsClass->GetName(),nowLine);
490 return false;
491 }
492
493 if( !pInheritsClass->IsReady() ){
494 //継承先が読み取られていないとき
495 LexicalAnalyzer::LookaheadClass(
496 pInheritsClass->GetName().c_str(),
497 compiler.GetObjectModule().meta.GetClasses()
498 );
499 }
500
501 if( !_class.InheritsClass( *pInheritsClass, actualTypeParameters, nowLine ) ){
502 return false;
503 }
504 }
505 else{
506 compiler.errorMessenger.Output(135,pInheritsClass->GetFullName().c_str(),nowLine);
507 return false;
508 }
509
510 if( inheritNames[i] == '\0' ){
511 break;
512 }
513 i++;
514 }
515
516 if( !isInheritsClass ){
517 const CClass *pObjectClass = compiler.GetObjectModule().meta.GetClasses().GetObjectClassPtr();
518 //ループ継承でないかをチェック
519 if( !LexicalAnalyzer::LoopRefCheck( *pObjectClass ) )
520 {
521 compiler.errorMessenger.Output(123,pObjectClass->GetName(),nowLine);
522 return false;
523 }
524
525 if( !pObjectClass->IsReady() ){
526 //継承先が読み取られていないとき
527 LexicalAnalyzer::LookaheadClass(
528 pObjectClass->GetName().c_str(),
529 compiler.GetObjectModule().meta.GetClasses()
530 );
531 }
532
533 // クラスを一つも継承していないとき
534 if( !_class.InheritsClass( *pObjectClass, Types(), nowLine ) ){
535 return false;
536 }
537 }
538
539 return true;
540}
541
542void LexicalAnalyzer::Implements( CClass &_class, Interface *pInterface, std::vector<DynamicMethod::OverrideResult> &overrideResults )
543{
544 _class.AddInterface( pInterface );
545
546
547 /////////////////////////////////////////////////////////////////
548 // 基底クラスのメソッドからインターフェイスメソッドを再実装する
549 /////////////////////////////////////////////////////////////////
550 BOOST_FOREACH( CMethod *pMethod, _class.GetDynamicMethods() )
551 {
552 DynamicMethod *pMethodForOverride = pInterface->GetDynamicMethods().FindForOverride( pInterface->GetActualTypeParameters(), &pMethod->GetUserProc() );
553 if( pMethodForOverride )
554 {
555 DynamicMethod::OverrideResult result;
556 result.enumType = pMethodForOverride->Override( &pMethod->GetUserProc(), pMethod->GetAccessibility(), false );
557 result.pMethod = pMethod;
558 overrideResults.push_back( result );
559
560 // 実装元になるメソッドは呼び出し不可にしておく(オーバーロードの解決から除外する)
561 pMethod->SetNotUseMark( true );
562 }
563 }
564
565
566 /////////////////////////////////////////////////////////////////
567 // キャストメソッドを追加(内部コードは自動生成すること)
568 // ※COMインターフェイスは除外すること
569 /////////////////////////////////////////////////////////////////
570 if( pInterface->GetClass().IsInterface() )
571 {
572 // Function Operator() As ITest
573
574 char methodName[255] = { 1, ESC_OPERATOR, CALC_AS, '\0' };
575
576 //関数ハッシュへ登録
577 UserProc *pUserProc = new UserProc(
578 NamespaceScopes(),
579 NamespaceScopesCollection(),
580 methodName,
581 Procedure::Function,
582 false,
583 false,
584 false );
585 pUserProc->SetParentClass( &_class );
586
587 Parameters params;
588 params.push_back( new Parameter( "_System_LocalThis", Type( DEF_PTR_VOID ) ) );
589 pUserProc->SetRealParams( params );
590
591 pUserProc->SetReturnType( Type( DEF_OBJECT, pInterface->GetClass() ) );
592 pUserProc->_paramStr = "";
593 pUserProc->Using();
594
595 // 関数を追加
596 if( compiler.GetObjectModule().meta.GetUserProcs().IsExist( pUserProc ) )
597 {
598 // 既に存在している
599 compiler.errorMessenger.Output(15,pUserProc->GetName(),-1);
600
601 delete pUserProc;
602 }
603 else
604 {
605 compiler.GetObjectModule().meta.GetUserProcs().Put( pUserProc );
606 }
607
608 LexicalAnalyzer::AddMethod(
609 &_class,
610 pUserProc,
611 Prototype::Public,
612 0,
613 false, // isConst
614 false, // isAbstract
615 false, // isVirtual
616 false, // isOverride
617 "",
618 true, // isAutoGeneration
619 -1
620 );
621 }
622}
623
624bool LexicalAnalyzer::Implements( CClass &_class, const char *interfaceNames, int nowLine )
625{
626 Jenga::Common::Strings paramStrs;
627 SplitParameter( interfaceNames, paramStrs );
628
629 BOOST_FOREACH( const std::string &paramStr, paramStrs )
630 {
631 char className[VN_SIZE];
632 Jenga::Common::Strings typeParameterStrings;
633 SplitGenericClassInstance( paramStr.c_str(), className, typeParameterStrings );
634
635 Types actualTypeParameters;
636 BOOST_FOREACH( const std::string &typeParameterStr, typeParameterStrings )
637 {
638 Type type;
639 compiler.StringToType( typeParameterStr, type );
640 actualTypeParameters.push_back( type );
641 }
642
643 //継承元クラスを取得
644 const CClass *pInterfaceClass = compiler.GetObjectModule().meta.FindClassSupportedTypeDef(
645 LexicalAnalyzer::FullNameToSymbol( className )
646 );
647 if( !pInterfaceClass ){
648 compiler.errorMessenger.Output(106,paramStr.c_str(),nowLine);
649 continue;
650 }
651
652 if( !pInterfaceClass->IsReady() ){
653 // インターフェイスが未解析のとき
654 LexicalAnalyzer::LookaheadClass(
655 pInterfaceClass->GetName().c_str(),
656 compiler.GetObjectModule().meta.GetClasses()
657 );
658 }
659
660 if( pInterfaceClass->IsInterface() || pInterfaceClass->IsComInterface() )
661 {
662 // インターフェイスを継承する
663 std::vector<DynamicMethod::OverrideResult> overrideResults;
664 Implements(
665 _class,
666 new ::Interface( pInterfaceClass, actualTypeParameters ),
667 overrideResults
668 );
669
670 // エラーチェック
671 BOOST_FOREACH( const DynamicMethod::OverrideResult result, overrideResults )
672 {
673 OverrideErrorCheck( result );
674 }
675 }
676 else
677 {
678 // インターフェイスではないとき
679 compiler.errorMessenger.Output(138,pInterfaceClass->GetName().c_str(),nowLine );
680 }
681 }
682
683 return true;
684}
685
686void GetClass_recur( const char *lpszInheritsClass, Classes &classes )
687{
688 extern char *basbuf;
689 int i,i2,i3,sub_address,top_pos;
690 char temporary[8192];
691
692 // 名前空間管理
693 NamespaceScopes backupNamespaceScopes = compiler.GetNamespaceSupporter().GetLivingNamespaceScopes();
694 NamespaceScopes &namespaceScopes = compiler.GetNamespaceSupporter().GetLivingNamespaceScopes();
695 namespaceScopes.clear();
696
697 // Importsされた名前空間の管理
698 NamespaceScopesCollection backupImportedNamespaces = compiler.GetNamespaceSupporter().GetImportedNamespaces();
699 compiler.GetNamespaceSupporter().GetImportedNamespaces().clear();
700
701 // 呼び出し元でコンパイル中のクラスポインタをバックアップ
702 const CClass *pBackCompilingClass = compiler.IsCompilingClass()
703 ? &compiler.GetCompilingClass()
704 : NULL;
705
706 for(i=0;;i++){
707 if(basbuf[i]=='\0') break;
708
709
710 // 名前空間
711 if( basbuf[i] == 1 && basbuf[i+1] == ESC_NAMESPACE ){
712 for(i+=2,i2=0;;i2++,i++){
713 if( IsCommandDelimitation( basbuf[i] ) ){
714 temporary[i2]=0;
715 break;
716 }
717 temporary[i2]=basbuf[i];
718 }
719 namespaceScopes.push_back( temporary );
720
721 continue;
722 }
723 else if( basbuf[i] == 1 && basbuf[i+1] == ESC_ENDNAMESPACE ){
724 if( namespaceScopes.size() <= 0 ){
725 compiler.errorMessenger.Output(12, "End Namespace", i );
726 }
727 else{
728 namespaceScopes.pop_back();
729 }
730
731 i += 2;
732 continue;
733 }
734
735 else if( basbuf[i] == 1 && basbuf[i+1] == ESC_IMPORTS ){
736 for(i+=2,i2=0;;i2++,i++){
737 if( IsCommandDelimitation( basbuf[i] ) ){
738 temporary[i2]=0;
739 break;
740 }
741 temporary[i2]=basbuf[i];
742 }
743 if( !compiler.GetNamespaceSupporter().ImportsNamespace( temporary ) )
744 {
745 compiler.errorMessenger.Output(64,temporary,i );
746 }
747
748 continue;
749 }
750 else if( basbuf[i] == 1 && basbuf[i+1] == ESC_CLEARNAMESPACEIMPORTED ){
751 compiler.GetNamespaceSupporter().GetImportedNamespaces().clear();
752 continue;
753 }
754
755
756
757 if(basbuf[i]==1&&basbuf[i+1]==ESC_INTERFACE){
758 //////////////////////////
759 // インターフェイス
760 //////////////////////////
761
762 top_pos=i;
763
764 i+=2;
765
766 //インターフェイス名を取得
767 GetCommandToken( temporary, basbuf, i );
768
769 char className[VN_SIZE];
770 Jenga::Common::Strings typeParameters;
771 Jenga::Common::Strings typeParameterBaseClassNames;
772 SplitGenericClassInstance( temporary, className, typeParameters, true, &typeParameterBaseClassNames );
773
774 CClass *pobj_c = const_cast<CClass *>( classes.FindEx( Symbol( namespaceScopes, className ) ) );
775 if(!pobj_c) continue;
776
777 compiler.SetCompilingClass( pobj_c );
778
779 if(lpszInheritsClass){
780 if(lstrcmp(lpszInheritsClass,pobj_c->GetName().c_str())!=0){
781 //継承先先読み用
782 continue;
783 }
784 }
785
786 if(pobj_c->IsReady()){
787 //既に先読みされているとき
788 continue;
789 }
790
791 /////////////////////////////////////////////////////////
792 // ☆★☆ ジェネリクスサポート ☆★☆
793 for( i2=0; i2<static_cast<int>(typeParameters.size()); i2++ )
794 {
795 Type baseType( DEF_OBJECT, *classes.GetObjectClassPtr() );
796 if( typeParameterBaseClassNames[i2].size() )
797 {
798 if( !compiler.StringToType( typeParameterBaseClassNames[i2], baseType ) )
799 {
800 compiler.errorMessenger.Output(106,typeParameterBaseClassNames[i2],i);
801 }
802 else if( !baseType.IsObject() )
803 {
804 compiler.errorMessenger.Output(106,typeParameterBaseClassNames[i2],i);
805 }
806 }
807
808 pobj_c->AddFormalGenericType( GenericType( typeParameters[i2], baseType ) );
809 }
810 /////////////////////////////////////////////////////////
811
812 pobj_c->Readed();
813
814 pobj_c->SetConstructorMemberSubIndex( -1 );
815 pobj_c->SetDestructorMemberSubIndex( -1 );
816
817 if( memcmp( basbuf+i+1, "__COM", 5 ) == 0 && IsCommandDelimitation( basbuf[i+1+5] ) )
818 {
819 // COMインターフェイス
820 pobj_c->SetClassType( CClass::ComInterface );
821
822 i += 6;
823 }
824
825 if(basbuf[i+1]==1&&basbuf[i+2]==ESC_INHERITS){
826 //継承を行う場合
827 for(i+=3,i2=0;;i++,i2++){
828 if(IsCommandDelimitation(basbuf[i])){
829 temporary[i2]=0;
830 break;
831 }
832 temporary[i2]=basbuf[i];
833 }
834
835 if(lstrcmpi(temporary,pobj_c->GetName().c_str())==0){
836 compiler.errorMessenger.Output(105,temporary,i);
837 goto Interface_InheritsError;
838 }
839
840 //継承元クラスを取得
841 const CClass *pInheritsClass = compiler.GetObjectModule().meta.FindClassSupportedTypeDef(
842 LexicalAnalyzer::FullNameToSymbol( temporary )
843 );
844 if( !pInheritsClass ){
845 compiler.errorMessenger.Output(106,temporary,i);
846 goto Interface_InheritsError;
847 }
848
849 //ループ継承でないかをチェック
850 if( !LexicalAnalyzer::LoopRefCheck( *pInheritsClass ) )
851 {
852 compiler.errorMessenger.Output(123,pInheritsClass->GetName(),i);
853 goto Interface_InheritsError;
854 }
855
856 //継承させる
857 if( !pobj_c->InheritsClass( *pInheritsClass, Types(), i ) ){
858 goto Interface_InheritsError;
859 }
860 }
861 else{
862 //継承無し
863 if( &pobj_c->GetSuperClass() || pobj_c->GetVtblNum() )
864 {
865 // TODO: ここに来ないことが実証できたらこの分岐は消す
866 Jenga::Throw( "GetClass_recur内の例外" );
867 }
868 }
869Interface_InheritsError:
870
871 //メンバ変数、関数を取得
872 while(1){
873 i++;
874
875 //エラー
876 if(basbuf[i]==1&&(basbuf[i+1]==ESC_CLASS||basbuf[i+1]==ESC_TYPE||basbuf[i+1]==ESC_INTERFACE)){
877 compiler.errorMessenger.Output(22,"Interface",i);
878 i--;
879 break;
880 }
881
882 if(basbuf[i]==1&&basbuf[i+1]==ESC_INHERITS){
883 compiler.errorMessenger.Output(111,NULL,i);
884 break;
885 }
886 else if( basbuf[i] == 1 && basbuf[i+1] == ESC_IMPLEMENTS )
887 {
888 compiler.errorMessenger.Output(137, NULL, i );
889 break;
890 }
891
892 sub_address=i;
893
894 for(i2=0;;i++,i2++){
895 if(IsCommandDelimitation(basbuf[i])){
896 temporary[i2]=0;
897 break;
898 }
899 temporary[i2]=basbuf[i];
900 }
901 if(temporary[0]=='\0'){
902 if(basbuf[i]=='\0'){
903 i--;
904 compiler.errorMessenger.Output(22,"Interface",top_pos);
905 break;
906 }
907 continue;
908 }
909
910 //End Interface記述の場合
911 if(temporary[0]==1&&temporary[1]==ESC_ENDINTERFACE) break;
912
913 if(!(temporary[0]==1&&(
914 temporary[1]==ESC_SUB||temporary[1]==ESC_FUNCTION
915 ))){
916 compiler.errorMessenger.Output(1,NULL,i);
917 break;
918 }
919
920 //関数ハッシュへ登録
921 char interfaceName[VN_SIZE] = "";
922 UserProc *pUserProc = LexicalAnalyzer::ParseUserProc( NamespaceScopes(), NamespaceScopesCollection(), temporary,sub_address,true,pobj_c, false, interfaceName );
923 if( pUserProc )
924 {
925 // 関数を追加
926 if( compiler.GetObjectModule().meta.GetUserProcs().IsExist( pUserProc ) )
927 {
928 // 既に存在している
929 compiler.errorMessenger.Output(15,pUserProc->GetName(),i);
930
931 delete pUserProc;
932 }
933 else
934 {
935 compiler.GetObjectModule().meta.GetUserProcs().Put( pUserProc );
936 }
937
938 //メンバ関数を追加
939 LexicalAnalyzer::AddMethod(pobj_c,
940 pUserProc,
941 Prototype::Public, //Publicアクセス権
942 0, // bStatic
943 false, // isConst
944 true, // isAbstract
945 true, // isVirtual
946 false, // isOverride
947 interfaceName,
948 false, // isAutoGeneration
949 sub_address
950 );
951 }
952 }
953 }
954
955 if(basbuf[i]==1&&(basbuf[i+1]==ESC_CLASS||basbuf[i+1]==ESC_TYPE)){
956 //////////////////////////
957 // クラス
958 //////////////////////////
959
960 top_pos=i;
961
962 const DWORD dwClassType=basbuf[i+1];
963
964 i+=2;
965
966 int iAlign=0;
967 if(memicmp(basbuf+i,"Align(",6)==0){
968 //アラインメント修飾子
969 i+=6;
970 i+=GetStringInPare_RemovePare(temporary,basbuf+i)+1;
971 iAlign=atoi(temporary);
972
973 if( dwClassType != ESC_TYPE )
974 {
975 compiler.errorMessenger.Output(140,NULL,i);
976 }
977
978 if(!(iAlign==1||iAlign==2||iAlign==4||iAlign==8||iAlign==16))
979 compiler.errorMessenger.Output(51,NULL,i);
980 }
981 else if( memicmp( basbuf + i, "Blittable(", 10 ) == 0 ){
982 // Blittable修飾子
983 i+=10;
984 i=JumpStringInPare(basbuf,i)+1;
985
986 if( dwClassType != ESC_CLASS )
987 {
988 compiler.errorMessenger.Output(141,NULL,i);
989 }
990 }
991
992 if( basbuf[i] == 1 && basbuf[i+1] == ESC_ENUM )
993 {
994 // 列挙型の場合
995 i += 2;
996 }
997 else if( basbuf[i] == 1 && basbuf[i+1] == ESC_DELEGATE )
998 {
999 // デリゲートの場合
1000 i += 2;
1001 }
1002
1003 //クラス名を取得
1004 GetCommandToken( temporary, basbuf, i );
1005
1006 char className[VN_SIZE];
1007 Jenga::Common::Strings typeParameters;
1008 Jenga::Common::Strings typeParameterBaseClassNames;
1009 SplitGenericClassInstance( temporary, className, typeParameters, true, &typeParameterBaseClassNames );
1010
1011 CClass *pobj_c = const_cast<CClass *>( classes.FindEx( Symbol( namespaceScopes, className ) ) );
1012 if(!pobj_c) continue;
1013
1014 compiler.SetCompilingClass( pobj_c );
1015
1016 if(lpszInheritsClass){
1017 if( pobj_c->GetName() != lpszInheritsClass ){
1018 //継承先先読み用
1019 continue;
1020 }
1021 }
1022
1023 if( lstrcmp(className,"Control")==0)
1024 {
1025 int test=0;
1026 }
1027
1028 if(pobj_c->IsReady()){
1029 //既に先読みされているとき
1030 continue;
1031 }
1032
1033
1034 /////////////////////////////////////////////////////////
1035 // ☆★☆ ジェネリクスサポート ☆★☆
1036 for( i2=0; i2<static_cast<int>(typeParameters.size()); i2++ )
1037 {
1038 Type baseType( DEF_OBJECT, *classes.GetObjectClassPtr() );
1039 if( typeParameterBaseClassNames[i2].size() )
1040 {
1041 if( !compiler.StringToType( typeParameterBaseClassNames[i2], baseType ) )
1042 {
1043 compiler.errorMessenger.Output(106,typeParameterBaseClassNames[i2],i);
1044 }
1045 else if( !baseType.IsObject() )
1046 {
1047 compiler.errorMessenger.Output(106,typeParameterBaseClassNames[i2],i);
1048 }
1049 }
1050
1051 pobj_c->AddFormalGenericType( GenericType( typeParameters[i2], baseType ) );
1052 }
1053 /////////////////////////////////////////////////////////
1054
1055
1056 pobj_c->SetFixedAlignment( iAlign );
1057
1058 pobj_c->Readed();
1059
1060 pobj_c->SetConstructorMemberSubIndex( -1 );
1061 pobj_c->SetDestructorMemberSubIndex( -1 );
1062
1063 //アクセス制限の初期値をセット
1064 Prototype::Accessibility accessibility;
1065 if(dwClassType==ESC_CLASS){
1066 accessibility = Prototype::Private;
1067 }
1068 else{
1069 accessibility = Prototype::Public;
1070 }
1071
1072 if( pobj_c->GetName() == "Object"
1073 || dwClassType == ESC_TYPE )
1074 {
1075 // 何も継承しない
1076
1077 if( &pobj_c->GetSuperClass() || pobj_c->GetVtblNum() )
1078 {
1079 // TODO: ここに来ないことが実証できたらこの分岐は消す
1080 Jenga::Throw( "GetClass_recur内の例外" );
1081 }
1082 }
1083 else{
1084 if(basbuf[i+1]==1&&basbuf[i+2]==ESC_INHERITS)
1085 {
1086 // クラス継承先が指定されているとき
1087 i += 3;
1088 GetCommandToken( temporary, basbuf, i );
1089
1090 if(lstrcmpi(temporary,pobj_c->GetName().c_str())==0){
1091 compiler.errorMessenger.Output(105,temporary,i);
1092 goto InheritsError;
1093 }
1094 }
1095 else
1096 {
1097 // 何の指定もないときはObjectクラスを継承する
1098 lstrcpy( temporary, "Object" );
1099 }
1100 LexicalAnalyzer::Inherits( *pobj_c, temporary, i );
1101
1102 if( basbuf[i+1] == 1 && basbuf[i+2] == ESC_IMPLEMENTS )
1103 {
1104 // インターフェイス実装を行う場合
1105 i += 3;
1106 GetCommandToken( temporary, basbuf, i );
1107
1108 LexicalAnalyzer::Implements( *pobj_c, temporary, i );
1109 }
1110 }
1111InheritsError:
1112
1113 //メンバとメソッドを取得
1114 while(1){
1115 i++;
1116
1117 //エラー
1118 if(basbuf[i]==1&&(basbuf[i+1]==ESC_CLASS||basbuf[i+1]==ESC_TYPE)){
1119 compiler.errorMessenger.Output(22,"Class",i);
1120 i--;
1121 break;
1122 }
1123
1124 if(basbuf[i]==1&&basbuf[i+1]==ESC_INHERITS){
1125 compiler.errorMessenger.Output(111,NULL,i);
1126 break;
1127 }
1128 else if( basbuf[i] == 1 && basbuf[i+1] == ESC_IMPLEMENTS )
1129 {
1130 compiler.errorMessenger.Output(137, NULL, i );
1131 break;
1132 }
1133
1134 //Static修飾子
1135 BOOL bStatic;
1136 if(basbuf[i]==1&&basbuf[i+1]==ESC_STATIC){
1137 bStatic=1;
1138 i+=2;
1139 }
1140 else bStatic=0;
1141
1142 //Const修飾子
1143 bool isConst = false;
1144 if( basbuf[i] == 1 && basbuf[i + 1] == ESC_CONST ){
1145 isConst = true;
1146 i += 2;
1147 }
1148
1149 if(basbuf[i]==1&&(
1150 basbuf[i+1]==ESC_ABSTRACT||basbuf[i+1]==ESC_VIRTUAL||basbuf[i+1]==ESC_OVERRIDE||
1151 basbuf[i+1]==ESC_SUB||basbuf[i+1]==ESC_FUNCTION
1152 )){
1153 i3=basbuf[i+1];
1154 sub_address=i;
1155 }
1156 else i3=0;
1157
1158 bool isVirtual = false, isAbstract = false, isOverride = false;
1159 if(i3==ESC_ABSTRACT){
1160 isAbstract=1;
1161 isVirtual=1;
1162 i+=2;
1163
1164 i3=basbuf[i+1];
1165 }
1166 else if(i3==ESC_VIRTUAL){
1167 isAbstract=0;
1168 isVirtual=1;
1169 i+=2;
1170
1171 i3=basbuf[i+1];
1172 }
1173 else if(i3==ESC_OVERRIDE){
1174 isOverride=1;
1175 isVirtual=1;
1176
1177 i+=2;
1178
1179 i3=basbuf[i+1];
1180 }
1181
1182 for(i2=0;;i++,i2++){
1183 if(IsCommandDelimitation(basbuf[i])){
1184 temporary[i2]=0;
1185 break;
1186 }
1187 temporary[i2]=basbuf[i];
1188 }
1189 if(temporary[0]=='\0'){
1190 if(basbuf[i]=='\0'){
1191
1192 if(dwClassType==ESC_CLASS)
1193 compiler.errorMessenger.Output(22,"Class",top_pos);
1194 else
1195 compiler.errorMessenger.Output(22,"Type",top_pos);
1196
1197 i--;
1198 break;
1199 }
1200 continue;
1201 }
1202
1203 //End Class記述の場合
1204 if(temporary[0]==1&&temporary[1]==ESC_ENDCLASS&&dwClassType==ESC_CLASS) break;
1205 if(temporary[0]==1&&temporary[1]==ESC_ENDTYPE&&dwClassType==ESC_TYPE) break;
1206
1207 //アクセスを変更
1208 if(lstrcmpi(temporary,"Private")==0){
1209 accessibility = Prototype::Private;
1210 continue;
1211 }
1212 if(lstrcmpi(temporary,"Public")==0){
1213 accessibility = Prototype::Public;
1214 continue;
1215 }
1216 if(lstrcmpi(temporary,"Protected")==0){
1217 accessibility = Prototype::Protected;
1218 continue;
1219 }
1220
1221 extern int cp;
1222 if(i3==0){
1223 if(bStatic){
1224 //静的メンバを追加
1225 cp=i; //エラー用
1226 pobj_c->AddStaticMember(
1227 LexicalAnalyzer::CreateMember( *pobj_c, accessibility, isConst, false, temporary, i )
1228 );
1229 }
1230 else{
1231 //メンバを追加
1232 cp=i; //エラー用
1233 pobj_c->AddDynamicMember(
1234 LexicalAnalyzer::CreateMember( *pobj_c, accessibility, isConst, false, temporary, i )
1235 );
1236
1237
1238 if(pobj_c->GetDynamicMembers().back()->GetType().IsStruct()){
1239 if( !pobj_c->GetDynamicMembers().back()->GetType().GetClass().IsReady() ){
1240 //参照先が読み取られていないとき
1241 GetClass_recur( pobj_c->GetDynamicMembers().back()->GetType().GetClass().GetName().c_str(), classes );
1242 }
1243 }
1244
1245
1246 if(pobj_c->GetDynamicMembers().back()->GetType().IsStruct()){
1247 //循環参照のチェック
1248 pobj_LoopRefCheck->add(pobj_c->GetName().c_str());
1249 if(!MemberVar_LoopRefCheck(pobj_c->GetDynamicMembers().back()->GetType().GetClass())){
1250 //エラー回避
1251 Type &type = const_cast<Type &>(pobj_c->GetDynamicMembers().back()->GetType());
1252 type.SetBasicType( DEF_PTR_VOID );
1253 }
1254 pobj_LoopRefCheck->del(pobj_c->GetName().c_str());
1255 }
1256 }
1257 }
1258 else{
1259 //関数ハッシュへ登録
1260 char interfaceName[VN_SIZE] = "";
1261 UserProc *pUserProc = LexicalAnalyzer::ParseUserProc( NamespaceScopes(), NamespaceScopesCollection(), temporary,sub_address,isVirtual,pobj_c, (bStatic!=0), interfaceName );
1262 if( pUserProc )
1263 {
1264 // 関数を追加
1265 if( compiler.GetObjectModule().meta.GetUserProcs().IsExist( pUserProc ) )
1266 {
1267 // 既に存在している
1268 compiler.errorMessenger.Output(15,pUserProc->GetName(),i);
1269
1270 delete pUserProc;
1271 }
1272 else
1273 {
1274 compiler.GetObjectModule().meta.GetUserProcs().Put( pUserProc );
1275 }
1276
1277 //メソッドを追加
1278 cp=i; //エラー用
1279 LexicalAnalyzer::AddMethod(pobj_c,
1280 pUserProc,
1281 accessibility,
1282 bStatic,
1283 isConst,
1284 isAbstract,
1285 isVirtual,
1286 isOverride,
1287 interfaceName,
1288 false,
1289 sub_address);
1290 }
1291
1292 if( isAbstract ) continue;
1293
1294 for(;;i++){
1295 if(basbuf[i]=='\0'){
1296 i--;
1297 break;
1298 }
1299 if(basbuf[i-1]!='*'&&
1300 basbuf[i]==1&&(
1301 basbuf[i+1]==ESC_SUB||
1302 basbuf[i+1]==ESC_FUNCTION||
1303 basbuf[i+1]==ESC_MACRO||
1304 basbuf[i+1]==ESC_TYPE||
1305 basbuf[i+1]==ESC_CLASS||
1306 basbuf[i+1]==ESC_INTERFACE||
1307 basbuf[i+1]==ESC_ENUM)){
1308 GetDefaultNameFromES(i3,temporary);
1309 compiler.errorMessenger.Output(22,temporary,i);
1310 }
1311 if(basbuf[i]==1&&basbuf[i+1]==GetEndXXXCommand((char)i3)){
1312 i+=2;
1313 break;
1314 }
1315 }
1316 }
1317 }
1318 }
1319 }
1320
1321 // 呼び出し元でコンパイル中のクラスポインタを元に戻す
1322 compiler.SetCompilingClass( pBackCompilingClass );
1323
1324 // 名前空間を元に戻す
1325 compiler.GetNamespaceSupporter().GetLivingNamespaceScopes() = backupNamespaceScopes;
1326
1327 // インポートされた名前空間を元に戻す
1328 compiler.GetNamespaceSupporter().GetImportedNamespaces() = backupImportedNamespaces;
1329}
1330
1331void LexicalAnalyzer::LookaheadClass( const char *className, Classes &classes )
1332{
1333 pobj_LoopRefCheck->add( className );
1334 GetClass_recur( className, classes );
1335 pobj_LoopRefCheck->del( className );
1336}
1337
1338bool LexicalAnalyzer::LoopRefCheck( const CClass &objClass )
1339{
1340 if( pobj_LoopRefCheck->check( objClass ) )
1341 {
1342 return false;
1343 }
1344
1345 return true;
1346}
1347
1348void LexicalAnalyzer::CollectClasses( const char *source, Classes &classes ){
1349 //ループ継承チェック用のクラス
1350 pobj_LoopRefCheck=new CLoopRefCheck();
1351
1352 //クラスを取得
1353 GetClass_recur( 0, classes );
1354
1355 delete pobj_LoopRefCheck;
1356 pobj_LoopRefCheck=0;
1357
1358 // イテレータの準備
1359 classes.Iterator_Init();
1360}
Note: See TracBrowser for help on using the repository browser.