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

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

AddMemberAddDynamicMethod
・CMember→Member
・CreateMemberメソッドをCClassクラスからLexicalAnalyzerクラスへ移動した。

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