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

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

エラーコード138をLexicalAnalyzer_Class.cppで表示するようにした。

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