source: dev/trunk/abdev/BasicCompiler_Common/src/ClassImpl.cpp@ 204

Last change on this file since 204 was 204, checked in by dai_9181, 17 years ago

pobj_InheritsClassメンバをprivateにした

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