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

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

UserProcs::Insertメソッドを排除。

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