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

Last change on this file since 195 was 195, checked in by dai_9181, 17 years ago
File size: 31.9 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 namespaceSupporter.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 pobj_InheritsClass = &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 = namespaceSupporter.GetLivingNamespaceScopes();
521 namespaceScopes.clear();
522
523 // Importsされた名前空間の管理
524 NamespaceScopesCollection &importedNamespaces = namespaceSupporter.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( !namespaceSupporter.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 namespaceSupporter.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 namespaceSupporter.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 = namespaceSupporter.GetLivingNamespaceScopes();
713 NamespaceScopes &namespaceScopes = namespaceSupporter.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 pobj_c->pobj_InheritsClass=0;
810
811 //仮想関数の数を初期化
812 pobj_c->SetVtblNum( 0 );
813 }
814Interface_InheritsError:
815
816 //メンバ変数、関数を取得
817 while(1){
818 i++;
819
820 //エラー
821 if(basbuf[i]==1&&(basbuf[i+1]==ESC_CLASS||basbuf[i+1]==ESC_TYPE||basbuf[i+1]==ESC_INTERFACE)){
822 SetError(22,"Interface",i);
823 i--;
824 break;
825 }
826
827 if(basbuf[i]==1&&basbuf[i+1]==ESC_INHERITS){
828 SetError(111,NULL,i);
829 break;
830 }
831
832 sub_address=i;
833
834 for(i2=0;;i++,i2++){
835 if(IsCommandDelimitation(basbuf[i])){
836 temporary[i2]=0;
837 break;
838 }
839 temporary[i2]=basbuf[i];
840 }
841 if(temporary[0]=='\0'){
842 if(basbuf[i]=='\0'){
843 i--;
844 SetError(22,"Interface",top_pos);
845 break;
846 }
847 continue;
848 }
849
850 //End Interface記述の場合
851 if(temporary[0]==1&&temporary[1]==ESC_ENDINTERFACE) break;
852
853 if(!(temporary[0]==1&&(
854 temporary[1]==ESC_SUB||temporary[1]==ESC_FUNCTION
855 ))){
856 SetError(1,NULL,i);
857 break;
858 }
859
860 //メンバ関数を追加
861 pobj_c->AddMethod(pobj_c,
862 Prototype::Public, //Publicアクセス権
863 0, //Static指定なし
864 false, //Constではない
865 1, //Abstract
866 1, //Virtual
867 0,
868 temporary,
869 sub_address
870 );
871 }
872 }
873
874 if(basbuf[i]==1&&(basbuf[i+1]==ESC_CLASS||basbuf[i+1]==ESC_TYPE)){
875 //////////////////////////
876 // クラス
877 //////////////////////////
878
879 top_pos=i;
880
881 const DWORD dwClassType=basbuf[i+1];
882
883 i+=2;
884
885 int iAlign=0;
886 if(memicmp(basbuf+i,"Align(",6)==0){
887 //アラインメント修飾子
888 i+=6;
889 i+=GetStringInPare_RemovePare(temporary,basbuf+i)+1;
890 iAlign=atoi(temporary);
891
892 if(!(iAlign==1||iAlign==2||iAlign==4||iAlign==8||iAlign==16))
893 SetError(51,NULL,i);
894 }
895 else if( memicmp( basbuf + i, "Blittable(", 10 ) == 0 ){
896 // Blittable修飾子
897 i+=10;
898 i=JumpStringInPare(basbuf,i)+1;
899 }
900
901 if( basbuf[i] == 1 && basbuf[i+1] == ESC_ENUM ){
902 // 列挙型の場合
903 i+=2;
904 }
905
906 //クラス名を取得
907 GetIdentifierToken( temporary, basbuf, i );
908
909 CClass *pobj_c = const_cast<CClass *>( this->Find(namespaceScopes, temporary) );
910 if(!pobj_c) continue;
911
912 if(lpszInheritsClass){
913 if( pobj_c->GetName() != lpszInheritsClass ){
914 //継承先先読み用
915 continue;
916 }
917 }
918
919 if(pobj_c->IsReady()){
920 //既に先読みされているとき
921 continue;
922 }
923
924 pobj_c->iAlign=iAlign;
925
926 pobj_c->Readed();
927
928 pobj_c->SetConstructorMemberSubIndex( -1 );
929 pobj_c->SetDestructorMemberSubIndex( -1 );
930
931 //アクセス制限の初期値をセット
932 Prototype::Accessibility accessibility;
933 if(dwClassType==ESC_CLASS){
934 accessibility = Prototype::Private;
935 }
936 else{
937 accessibility = Prototype::Public;
938 }
939
940 if( pobj_c->GetName() == "Object" || dwClassType == ESC_TYPE ){
941 // 継承無し
942 pobj_c->pobj_InheritsClass = NULL;
943
944 // 仮想関数の数を初期化
945 pobj_c->SetVtblNum( 0 );
946 }
947 else{
948 bool isInherits = false;
949 if(basbuf[i+1]==1&&basbuf[i+2]==ESC_INHERITS){
950 //継承を行う場合
951 isInherits = true;
952
953 for(i+=3,i2=0;;i++,i2++){
954 if(IsCommandDelimitation(basbuf[i])){
955 temporary[i2]=0;
956 break;
957 }
958 temporary[i2]=basbuf[i];
959 }
960
961 if(lstrcmpi(temporary,pobj_c->GetName().c_str())==0){
962 SetError(105,temporary,i);
963 goto InheritsError;
964 }
965 }
966
967 if( !isInherits ){
968 //Objectを継承する
969 lstrcpy( temporary, "Object" );
970 }
971
972 pobj_c->Inherits( temporary, i );
973 }
974InheritsError:
975
976 //メンバとメソッドを取得
977 while(1){
978 i++;
979
980 //エラー
981 if(basbuf[i]==1&&(basbuf[i+1]==ESC_CLASS||basbuf[i+1]==ESC_TYPE)){
982 SetError(22,"Class",i);
983 i--;
984 break;
985 }
986
987 if(basbuf[i]==1&&basbuf[i+1]==ESC_INHERITS){
988 SetError(111,NULL,i);
989 break;
990 }
991
992 //Static修飾子
993 BOOL bStatic;
994 if(basbuf[i]==1&&basbuf[i+1]==ESC_STATIC){
995 bStatic=1;
996 i+=2;
997 }
998 else bStatic=0;
999
1000 //Const修飾子
1001 bool isConst = false;
1002 if( basbuf[i] == 1 && basbuf[i + 1] == ESC_CONST ){
1003 isConst = true;
1004 i += 2;
1005 }
1006
1007 if(basbuf[i]==1&&(
1008 basbuf[i+1]==ESC_ABSTRACT||basbuf[i+1]==ESC_VIRTUAL||basbuf[i+1]==ESC_OVERRIDE||
1009 basbuf[i+1]==ESC_SUB||basbuf[i+1]==ESC_FUNCTION
1010 )){
1011 i3=basbuf[i+1];
1012 sub_address=i;
1013 }
1014 else i3=0;
1015
1016 bool isVirtual = false, isAbstract = false, isOverride = false;
1017 if(i3==ESC_ABSTRACT){
1018 isAbstract=1;
1019 isVirtual=1;
1020 i+=2;
1021
1022 i3=basbuf[i+1];
1023 }
1024 else if(i3==ESC_VIRTUAL){
1025 isAbstract=0;
1026 isVirtual=1;
1027 i+=2;
1028
1029 i3=basbuf[i+1];
1030 }
1031 else if(i3==ESC_OVERRIDE){
1032 isOverride=1;
1033 isVirtual=1;
1034
1035 i+=2;
1036
1037 i3=basbuf[i+1];
1038 }
1039
1040 for(i2=0;;i++,i2++){
1041 if(IsCommandDelimitation(basbuf[i])){
1042 temporary[i2]=0;
1043 break;
1044 }
1045 temporary[i2]=basbuf[i];
1046 }
1047 if(temporary[0]=='\0'){
1048 if(basbuf[i]=='\0'){
1049
1050 if(dwClassType==ESC_CLASS)
1051 SetError(22,"Class",top_pos);
1052 else
1053 SetError(22,"Type",top_pos);
1054
1055 i--;
1056 break;
1057 }
1058 continue;
1059 }
1060
1061 //End Class記述の場合
1062 if(temporary[0]==1&&temporary[1]==ESC_ENDCLASS&&dwClassType==ESC_CLASS) break;
1063 if(temporary[0]==1&&temporary[1]==ESC_ENDTYPE&&dwClassType==ESC_TYPE) break;
1064
1065 //アクセスを変更
1066 if(lstrcmpi(temporary,"Private")==0){
1067 accessibility = Prototype::Private;
1068 continue;
1069 }
1070 if(lstrcmpi(temporary,"Public")==0){
1071 accessibility = Prototype::Public;
1072 continue;
1073 }
1074 if(lstrcmpi(temporary,"Protected")==0){
1075 accessibility = Prototype::Protected;
1076 continue;
1077 }
1078
1079 extern int cp;
1080 if(i3==0){
1081 if(bStatic){
1082 //静的メンバを追加
1083 cp=i; //エラー用
1084 pobj_c->AddStaticMember( accessibility, isConst, false, temporary, i);
1085 }
1086 else{
1087 //メンバを追加
1088 cp=i; //エラー用
1089 pobj_c->AddMember( accessibility, isConst, false, temporary, i );
1090
1091
1092 if(pobj_c->GetDynamicMembers()[pobj_c->GetDynamicMembers().size()-1]->GetType().IsStruct()){
1093 if( !pobj_c->GetDynamicMembers()[pobj_c->GetDynamicMembers().size()-1]->GetType().GetClass().IsReady() ){
1094 //参照先が読み取られていないとき
1095 GetClass_recur(pobj_c->GetDynamicMembers()[pobj_c->GetDynamicMembers().size()-1]->GetType().GetClass().GetName().c_str());
1096 }
1097 }
1098
1099
1100 if(pobj_c->GetDynamicMembers()[pobj_c->GetDynamicMembers().size()-1]->GetType().IsStruct()){
1101 //循環参照のチェック
1102 pobj_LoopRefCheck->add(pobj_c->GetName().c_str());
1103 if(!MemberVar_LoopRefCheck(pobj_c->GetDynamicMembers()[pobj_c->GetDynamicMembers().size()-1]->GetType().GetClass())){
1104 //エラー回避
1105 pobj_c->GetDynamicMembers()[pobj_c->GetDynamicMembers().size()-1]->GetType().SetBasicType( DEF_PTR_VOID );
1106 }
1107 pobj_LoopRefCheck->del(pobj_c->GetName().c_str());
1108 }
1109 }
1110 }
1111 else{
1112 //メソッドを追加
1113 cp=i; //エラー用
1114 pobj_c->AddMethod(pobj_c,
1115 accessibility,
1116 bStatic,
1117 isConst,
1118 isAbstract,
1119 isVirtual,
1120 isOverride,
1121 temporary,
1122 sub_address);
1123
1124 if( isAbstract ) continue;
1125
1126 for(;;i++){
1127 if(basbuf[i]=='\0'){
1128 i--;
1129 break;
1130 }
1131 if(basbuf[i-1]!='*'&&
1132 basbuf[i]==1&&(
1133 basbuf[i+1]==ESC_SUB||
1134 basbuf[i+1]==ESC_FUNCTION||
1135 basbuf[i+1]==ESC_MACRO||
1136 basbuf[i+1]==ESC_TYPE||
1137 basbuf[i+1]==ESC_CLASS||
1138 basbuf[i+1]==ESC_INTERFACE||
1139 basbuf[i+1]==ESC_ENUM)){
1140 GetDefaultNameFromES(i3,temporary);
1141 SetError(22,temporary,i);
1142 }
1143 if(basbuf[i]==1&&basbuf[i+1]==GetEndXXXCommand((char)i3)){
1144 i+=2;
1145 break;
1146 }
1147 }
1148 }
1149 }
1150 }
1151 }
1152
1153
1154 // 名前空間を元に戻す
1155 namespaceSupporter.GetLivingNamespaceScopes() = backupNamespaceScopes;
1156}
1157void ClassesImpl::GetAllClassInfo(void){
1158 //ループ継承チェック用のクラス
1159 pobj_LoopRefCheck=new CLoopRefCheck();
1160
1161 //クラスを取得
1162 GetClass_recur(0);
1163
1164 delete pobj_LoopRefCheck;
1165 pobj_LoopRefCheck=0;
1166
1167 // イテレータ用のデータを作る
1168 this->Iterator_Init();
1169}
1170void ClassesImpl::Compile_System_InitializeUserTypes(){
1171 char temporary[VN_SIZE];
1172
1173 ////////////////////////////////////////////////////////////////////
1174 // クラス登録
1175 ////////////////////////////////////////////////////////////////////
1176
1177 // イテレータをリセット
1178 Iterator_Reset();
1179
1180 while( Iterator_HasNext() ){
1181 const CClass &objClass = *Iterator_GetNext();
1182
1183 if( !objClass.IsUsing() ){
1184 // 未使用のクラスは無視する
1185 continue;
1186 }
1187
1188 char referenceOffsetsBuffer[1024] = "";
1189 int numOfReference = 0;
1190 BOOST_FOREACH( CMember *pMember, objClass.GetDynamicMembers() ){
1191 if( pMember->GetType().IsObject() || pMember->GetType().IsPointer() ){
1192 if( referenceOffsetsBuffer[0] ){
1193 lstrcat( referenceOffsetsBuffer, "," );
1194 }
1195
1196 sprintf( referenceOffsetsBuffer + lstrlen( referenceOffsetsBuffer ),
1197 "%d",
1198 objClass.GetMemberOffset( pMember->GetName().c_str() ) );
1199
1200 numOfReference++;
1201 }
1202 }
1203
1204 sprintf( temporary
1205 , "Add(%c%c_System_TypeForClass(\"%s\",\"%s\",[%s],%d))"
1206 , 1
1207 , ESC_NEW
1208 , "" // 名前空間 (TODO: 実装)
1209 , objClass.GetName().c_str() // クラス名
1210 , referenceOffsetsBuffer // 参照メンバオフセット配列
1211 , numOfReference // 参照メンバの個数
1212 );
1213
1214 // コンパイル
1215 ChangeOpcode( temporary );
1216
1217 // ネイティブコードバッファの再確保
1218 ReallocNativeCodeBuffer();
1219 }
1220
1221
1222 ////////////////////////////////////////////////////////////////////
1223 // 基底クラスを登録
1224 ////////////////////////////////////////////////////////////////////
1225
1226 sprintf(temporary, "%c%ctempType=Nothing%c%cTypeBaseImpl"
1227 , HIBYTE( COM_DIM )
1228 , LOBYTE( COM_DIM )
1229 , 1
1230 , ESC_AS
1231 );
1232 ChangeOpcode( temporary );
1233
1234 // イテレータをリセット
1235 Iterator_Reset();
1236
1237 while( Iterator_HasNext() ){
1238 const CClass &objClass = *Iterator_GetNext();
1239
1240 if( !objClass.IsUsing() ){
1241 // 未使用のクラスは無視する
1242 continue;
1243 }
1244
1245 if( objClass.pobj_InheritsClass ){
1246 sprintf( temporary
1247 , "tempType=Search(\"%s\",\"%s\")"
1248 , "" // 名前空間 (TODO: 実装)
1249 , objClass.GetName().c_str() // クラス名
1250 );
1251
1252 // コンパイル
1253 ChangeOpcode( temporary );
1254
1255 sprintf( temporary
1256 , "tempType.SetBaseType(Search(\"%s\",\"%s\"))"
1257 , "" // 名前空間 (TODO: 実装)
1258 , objClass.pobj_InheritsClass->GetName().c_str() // 基底クラス名
1259 );
1260
1261 // コンパイル
1262 ChangeOpcode( temporary );
1263 }
1264
1265 // ネイティブコードバッファの再確保
1266 ReallocNativeCodeBuffer();
1267 }
1268
1269
1270
1271 ////////////////////////////////////////////////////////////////////
1272 // 継承関係登録
1273 ////////////////////////////////////////////////////////////////////
1274 // TODO: 未完成
1275 /*
1276
1277 // イテレータをリセット
1278 Iterator_Reset();
1279
1280 while( Iterator_HasNext() ){
1281 CClass *pClass = Iterator_GetNext();
1282
1283 sprintf( genBuffer + length
1284 , "obj.Search( \"%s\" ).SetBaseType( Search( \"%s\" ) ):"
1285 , "" // クラス名
1286 , pClass->name // クラス名
1287 );
1288 length += lstrlen( genBuffer + length );
1289
1290 while( length + 8192 > max ){
1291 max += 8192;
1292 genBuffer = (char *)realloc( genBuffer, max );
1293 }
1294 }*/
1295}
1296
1297const CClass *ClassesImpl::Find( const NamespaceScopes &namespaceScopes, const string &name ) const
1298{
1299 int key;
1300 key=GetHashCode(name.c_str());
1301
1302 if( namespaceScopes.size() == 0 && name == "Object" ){
1303 return GetObjectClassPtr();
1304 }
1305 else if( namespaceScopes.size() == 0 && name == "String" ){
1306 return GetStringClassPtr();
1307 }
1308
1309 if(pobj_ClassHash[key]){
1310 CClass *pobj_c;
1311 pobj_c=pobj_ClassHash[key];
1312 while(1){
1313 if( pobj_c->IsEqualSymbol( namespaceScopes, name ) ){
1314 //名前空間とクラス名が一致した
1315 return pobj_c;
1316 }
1317
1318 if(pobj_c->pobj_NextClass==0) break;
1319 pobj_c=pobj_c->pobj_NextClass;
1320 }
1321 }
1322
1323 // TypeDefも見る
1324 int index = compiler.GetMeta().GetTypeDefs().GetIndex( namespaceScopes, name );
1325 if( index != -1 ){
1326 Type type = compiler.GetMeta().GetTypeDefs()[index].GetBaseType();
1327 if( type.IsObject() ){
1328 return &type.GetClass();
1329 }
1330 }
1331
1332 return NULL;
1333}
Note: See TracBrowser for help on using the repository browser.