source: dev/trunk/abdev/BasicCompiler_Common/src/Class.cpp@ 218

Last change on this file since 218 was 218, checked in by dai_9181, 17 years ago
File size: 41.4 KB
Line 
1#include "stdafx.h"
2
3#include <jenga/include/smoothie/Smoothie.h>
4#include <jenga/include/smoothie/Source.h>
5#include <jenga/include/smoothie/SmoothieException.h>
6#include <jenga/include/smoothie/LexicalAnalysis.h>
7
8#include <Class.h>
9#include <Compiler.h>
10#include <NamespaceSupporter.h>
11
12#include "../common.h"
13#ifdef _AMD64_
14#include "../../BasicCompiler64/opcode.h"
15#else
16#include "../../BasicCompiler32/opcode.h"
17#endif
18
19
20class CLoopRefCheck{
21 char **names;
22 int num;
23 void init(){
24 int i;
25 for(i=0;i<num;i++){
26 free(names[i]);
27 }
28 free(names);
29 }
30public:
31 CLoopRefCheck()
32 {
33 names=(char **)malloc(1);
34 num=0;
35 }
36 ~CLoopRefCheck()
37 {
38 init();
39 }
40 void add(const char *lpszInheritsClass)
41 {
42 names=(char **)realloc(names,(num+1)*sizeof(char *));
43 names[num]=(char *)malloc(lstrlen(lpszInheritsClass)+1);
44 lstrcpy(names[num],lpszInheritsClass);
45 num++;
46 }
47 void del(const char *lpszInheritsClass)
48 {
49 int i;
50 for(i=0;i<num;i++){
51 if(lstrcmp(names[i],lpszInheritsClass)==0){
52 free(names[i]);
53 break;
54 }
55 }
56 if(i!=num){
57 num--;
58 for(;i<num;i++){
59 names[i]=names[i+1];
60 }
61 }
62 }
63 BOOL check(const CClass &inheritsClass) const
64 {
65 //ループ継承チェック
66 int i;
67 for(i=0;i<num;i++){
68 if( inheritsClass.GetName() == names[i] ){
69 return 1;
70 }
71 }
72 return 0;
73 }
74};
75CLoopRefCheck *pobj_LoopRefCheck;
76
77
78bool CClass::IsClass() const
79{
80 return classType == CClass::Class;
81}
82bool CClass::IsInterface() const
83{
84 return classType == CClass::Interface;
85}
86bool CClass::IsEnum() const
87{
88 return classType == CClass::Enum;
89}
90bool CClass::IsDelegate() const
91{
92 return classType == CClass::Delegate;
93}
94bool CClass::IsStructure() const
95{
96 return classType == CClass::Structure;
97}
98
99
100// コンストラクタのコンパイルを開始
101void CClass::NotifyStartConstructorCompile() const
102{
103 isCompilingConstructor = true;
104}
105
106//コンストラクタのコンパイルを終了
107void CClass::NotifyFinishConstructorCompile() const
108{
109 isCompilingConstructor = false;
110}
111
112//コンストラクタをコンパイル中かどうかを判別
113bool CClass::IsCompilingConstructor() const
114{
115 return isCompilingConstructor;
116}
117
118//デストラクタのコンパイルを開始
119void CClass::NotifyStartDestructorCompile() const{
120 isCompilingDestructor = true;
121}
122
123//デストラクタのコンパイルを終了
124void CClass::NotifyFinishDestructorCompile() const{
125 isCompilingDestructor = false;
126}
127
128//デストラクタをコンパイル中かどうかを判別
129bool CClass::IsCompilingDestructor() const
130{
131 return isCompilingDestructor;
132}
133
134//自身の派生クラスかどうかを確認
135bool CClass::IsSubClass( const CClass *pClass ) const
136{
137 if( !pClass->HasSuperClass() )
138 {
139 return false;
140 }
141
142 const CClass *pTempClass = &pClass->GetSuperClass();
143 while( pTempClass ){
144 if( this == pTempClass ) return true;
145 pTempClass = &pTempClass->GetSuperClass();
146 }
147 return false;
148}
149
150//自身と等しいまたは派生クラスかどうかを確認
151bool CClass::IsEqualsOrSubClass( const CClass *pClass ) const
152{
153 if( IsEquals( pClass ) ) return true;
154 return IsSubClass( pClass );
155}
156
157// 自身と等しいまたは派生クラス、基底クラスかどうかを確認
158bool CClass::IsEqualsOrSubClassOrSuperClass( const CClass &objClass ) const
159{
160 if( IsEquals( &objClass ) ) return true;
161 if( IsSubClass( &objClass ) ) return true;
162 if( objClass.IsSubClass( this ) ) return true;
163 return false;
164}
165
166bool CClass::IsInheritsInterface( const CClass *pInterfaceClass ) const
167{
168 BOOST_FOREACH( const InheritedInterface &objInterface, interfaces ){
169 if( pInterfaceClass == &objInterface.GetInterfaceClass() ){
170 return true;
171 }
172 }
173 return false;
174}
175
176bool CClass::Inherits( const char *inheritNames, int nowLine ){
177 int i = 0;
178 bool isInheritsClass = false;
179 while( true ){
180
181 char temporary[VN_SIZE];
182 for( int i2=0;; i++, i2++ ){
183 if( inheritNames[i] == '\0' || inheritNames[i] == ',' ){
184 temporary[i2] = 0;
185 break;
186 }
187 temporary[i2] = inheritNames[i];
188 }
189
190 //継承元クラスを取得
191 const CClass *pInheritsClass = compiler.GetMeta().GetClasses().Find(temporary);
192 if( !pInheritsClass ){
193 SmoothieException::Throw(106,temporary,nowLine);
194 return false;
195 }
196
197 if( pInheritsClass->IsInterface() ){
198 // インターフェイスはあとで継承する
199 }
200 else if( pInheritsClass->IsClass() ){
201 // クラスを継承する
202 isInheritsClass = true;
203
204 if( !InheritsClass( *pInheritsClass, nowLine ) ){
205 return false;
206 }
207 }
208 else{
209 SmoothieException::Throw(135,NULL,nowLine);
210 return false;
211 }
212
213 if( inheritNames[i] == '\0' ){
214 break;
215 }
216 i++;
217 }
218
219 if( !isInheritsClass ){
220 // クラスを一つも継承していないとき
221 const CClass *pObjectClass = compiler.GetMeta().GetClasses().Find("Object");
222 if( !pObjectClass ){
223 SmoothieException::Throw(106,"Object",i);
224 return false;
225 }
226
227 if( !InheritsClass( *pObjectClass, nowLine ) ){
228 return false;
229 }
230 }
231
232 i=0;
233 while( true ){
234
235 char temporary[VN_SIZE];
236 for( int i2=0;; i++, i2++ ){
237 if( inheritNames[i] == '\0' || inheritNames[i] == ',' ){
238 temporary[i2] = 0;
239 break;
240 }
241 temporary[i2] = inheritNames[i];
242 }
243
244 //継承元クラスを取得
245 const CClass *pInheritsClass = compiler.GetMeta().GetClasses().Find(temporary);
246 if( !pInheritsClass ){
247 SmoothieException::Throw(106,temporary,nowLine);
248 return false;
249 }
250
251 if( pInheritsClass->IsInterface() ){
252 // インターフェイスを継承する
253 if( !InheritsInterface( *pInheritsClass, nowLine ) ){
254 return false;
255 }
256 }
257 else if( pInheritsClass->IsClass() ){
258 // クラスはさっき継承した
259 }
260 else{
261 SmoothieException::Throw(135,NULL,nowLine);
262 return false;
263 }
264
265 if( inheritNames[i] == '\0' ){
266 break;
267 }
268 i++;
269 }
270
271 return true;
272}
273bool CClass::InheritsClass( const CClass &inheritsClass, int nowLine ){
274
275 //ループ継承でないかをチェック
276 if(pobj_LoopRefCheck->check(inheritsClass)){
277 SmoothieException::Throw(123,inheritsClass.GetName(),nowLine);
278 return false;
279 }
280
281 if( !inheritsClass.IsReady() ){
282 //継承先が読み取られていないとき
283 pobj_LoopRefCheck->add(this->GetName().c_str());
284 compiler.GetMeta().GetClasses().GetClass_recur(inheritsClass.GetName().c_str());
285 pobj_LoopRefCheck->del(this->GetName().c_str());
286 }
287
288 //メンバをコピー
289 BOOST_FOREACH( CMember *inheritsClassDynamicMember, inheritsClass.GetDynamicMembers() ){
290 CMember *pMember = new CMember( *inheritsClassDynamicMember );
291
292 // アクセシビリティ
293 if( inheritsClassDynamicMember->IsPrivate() ){
294 pMember->SetAccessibility( Prototype::None );
295 }
296 else{
297 pMember->SetAccessibility( inheritsClassDynamicMember->GetAccessibility() );
298 }
299
300 dynamicMembers.push_back( pMember );
301 }
302
303 //メソッドをコピー
304 BOOST_FOREACH( const CMethod *pBaseMethod, inheritsClass.GetMethods() ){
305 CMethod *pMethod = new DynamicMethod( *pBaseMethod );
306
307 // アクセシビリティ
308 if(pBaseMethod->GetAccessibility() == Prototype::Private){
309 pMethod->SetAccessibility( Prototype::None );
310 }
311 else{
312 pMethod->SetAccessibility( pBaseMethod->GetAccessibility() );
313 }
314
315 //pobj_Inherits
316 // ※継承元のClassIndexをセット(入れ子継承を考慮する)
317 if(pBaseMethod->GetInheritsClassPtr()==0){
318 pMethod->SetInheritsClassPtr( &inheritsClass );
319 }
320 else{
321 pMethod->SetInheritsClassPtr( pBaseMethod->GetInheritsClassPtr() );
322 }
323
324 methods.push_back( pMethod );
325 }
326
327 //仮想関数の数
328 AddVtblNum( inheritsClass.GetVtblNum() );
329
330 //継承先のクラスをメンバとして保持する
331 SetSuperClass( &inheritsClass );
332
333 return true;
334}
335bool CClass::InheritsInterface( const CClass &inheritsInterface, int nowLine ){
336
337 //ループ継承でないかをチェック
338 if(pobj_LoopRefCheck->check(inheritsInterface)){
339 SmoothieException::Throw(123,inheritsInterface.GetName(),nowLine);
340 return false;
341 }
342
343 if( !inheritsInterface.IsReady() ){
344 //継承先が読み取られていないとき
345 pobj_LoopRefCheck->add(this->GetName().c_str());
346 compiler.GetMeta().GetClasses().GetClass_recur(inheritsInterface.GetName().c_str());
347 pobj_LoopRefCheck->del(this->GetName().c_str());
348 }
349
350 //メソッドをコピー
351 BOOST_FOREACH( const CMethod *pBaseMethod, inheritsInterface.GetMethods() ){
352 CMethod *pMethod = new DynamicMethod( *pBaseMethod );
353
354 // アクセシビリティ
355 if(pBaseMethod->GetAccessibility() == Prototype::Private){
356 pMethod->SetAccessibility( Prototype::None );
357 }
358 else{
359 pMethod->SetAccessibility( pBaseMethod->GetAccessibility() );
360 }
361
362 //pobj_Inherits
363 // ※継承元のClassIndexをセット(入れ子継承を考慮する)
364 if(pBaseMethod->GetInheritsClassPtr()==0){
365 pMethod->SetInheritsClassPtr( &inheritsInterface );
366 }
367 else{
368 pMethod->SetInheritsClassPtr( pBaseMethod->GetInheritsClassPtr() );
369 }
370
371 methods.push_back( pMethod );
372 }
373
374 interfaces.push_back( InheritedInterface( const_cast<CClass *>(&inheritsInterface), vtblNum ) );
375
376 //仮想関数の数
377 AddVtblNum( inheritsInterface.GetVtblNum() );
378
379 return true;
380}
381CMember *CClass::CreateMember( Prototype::Accessibility accessibility, bool isConst, bool isRef, char *buffer, int nowLine )
382{
383 extern int cp;
384
385 //構文を解析
386 char VarName[VN_SIZE];
387 char initBuffer[VN_SIZE];
388 char lpszConstructParameter[VN_SIZE];
389 Subscripts subscripts;
390 Type type;
391 GetDimentionFormat(buffer,VarName,subscripts,type,initBuffer,lpszConstructParameter);
392
393 //重複チェック
394 if(this->DupliCheckAll(VarName)){
395 SetError(15,VarName,cp);
396 }
397
398 CMember *pMember = new CMember( accessibility, VarName, type, isConst, subscripts, initBuffer, lpszConstructParameter );
399 pMember->source_code_address = nowLine;
400 return pMember;
401}
402void CClass::AddMember( Prototype::Accessibility accessibility, bool isConst, bool isRef, char *buffer, int nowLine ){
403 dynamicMembers.push_back(
404 CreateMember( accessibility, isConst, isRef, buffer, nowLine )
405 );
406}
407void CClass::AddStaticMember( Prototype::Accessibility accessibility, bool isConst, bool isRef, char *buffer, int nowLine ){
408 staticMembers.push_back(
409 CreateMember( accessibility, isConst, isRef, buffer, nowLine )
410 );
411}
412
413void CClass::AddMethod(CClass *pobj_c, Prototype::Accessibility accessibility, BOOL bStatic, bool isConst, bool isAbstract,
414 bool isVirtual, bool isOverride, char *buffer, int nowLine){
415 int i,i2;
416 char temporary[VN_SIZE];
417
418 i=2;
419 for(i2=0;;i++,i2++){
420 if(buffer[i]=='('||buffer[i]=='\0'){
421 temporary[i2]=0;
422 break;
423 }
424 temporary[i2]=buffer[i];
425 }
426
427
428 //関数ハッシュへ登録
429 UserProc *pUserProc = compiler.GetMeta().GetUserProcs().Add( NamespaceScopes(), NamespaceScopesCollection(), buffer,nowLine,isVirtual,pobj_c, (bStatic!=0) );
430 if(!pUserProc) return;
431
432
433 ////////////////////////////////////////////////////////////
434 // コンストラクタ、デストラクタの場合の処理
435 ////////////////////////////////////////////////////////////
436 BOOL fConstructor=0,bDestructor=0;
437
438 if(lstrcmp(temporary,pobj_c->GetName().c_str())==0){
439 //コンストラクタの場合
440
441 //標準コンストラクタ(引数なし)
442 if(pUserProc->Params().size()==0) fConstructor=1;
443
444 //強制的にConst修飾子をつける
445 isConst = true;
446 }
447 else if(temporary[0]=='~'){
448 //デストラクタの場合はその名前が正しいかチェックを行う
449 if(lstrcmp(temporary+1,pobj_c->GetName().c_str())!=0)
450 SetError(117,NULL,nowLine);
451 else
452 bDestructor=1;
453 }
454 if(fConstructor||bDestructor){
455 // コンストラクタ、デストラクタのアクセシビリティをチェック
456
457 //強制的にConst修飾子をつける
458 isConst = true;
459 }
460
461 if( fConstructor == 1 )
462 pobj_c->SetConstructorMemberSubIndex( (int)pobj_c->GetMethods().size() );
463 else if( bDestructor )
464 pobj_c->SetDestructorMemberSubIndex( (int)pobj_c->GetMethods().size() );
465
466
467
468 //////////////////
469 // 重複チェック
470 //////////////////
471
472 if(pobj_c->DupliCheckMember(temporary)){
473 SetError(15,temporary,nowLine);
474 return;
475 }
476
477 //メソッド
478 BOOST_FOREACH( const CMethod *pMethod, pobj_c->GetMethods() ){
479 //基底クラスと重複する場合はオーバーライドを行う
480 if( pMethod->GetInheritsClassPtr() ) continue;
481
482 if( pMethod->GetUserProc().GetName() == temporary ){
483 if( pMethod->GetUserProc().Params().Equals( pUserProc->Params() ) ){
484 //関数名、パラメータ属性が合致したとき
485 SetError(15,pUserProc->GetName().c_str(),nowLine);
486 return;
487 }
488 }
489 }
490
491 //仮想関数の場合
492 if( isAbstract ) pUserProc->CompleteCompile();
493
494 //メソッドのオーバーライド
495 BOOST_FOREACH( CMethod *pMethod, pobj_c->GetMethods() ){
496 if( pMethod->GetUserProc().GetName() == temporary ){
497 if( pMethod->GetUserProc().Params().Equals( pUserProc->Params() ) ){
498
499 if(pMethod->IsVirtual()){
500 //メンバ関数を上書き
501 pMethod->SetUserProcPtr( pUserProc );
502 pMethod->Override();
503
504 if( !isOverride ){
505 SetError(127,NULL,nowLine);
506 }
507 if(pMethod->GetAccessibility() != accessibility ){
508 SetError(128,NULL,nowLine);
509 }
510
511 pUserProc->SetMethod( pMethod );
512 return;
513 }
514 }
515 }
516 }
517
518 if( isVirtual ){
519 pobj_c->AddVtblNum( 1 );
520 }
521
522 if( isOverride ){
523 SetError(12,"Override",nowLine);
524 }
525
526 if(bStatic){
527 pobj_c->GetStaticMethods().AddStatic( pUserProc, accessibility );
528 }
529 else{
530 pobj_c->GetMethods().Add(pUserProc, accessibility, isConst, isAbstract, isVirtual);
531 }
532}
533
534bool CClass::DupliCheckAll(const char *name){
535 //重複チェック
536
537 //メンバ
538 if(DupliCheckMember(name)) return 1;
539
540 //メソッド
541 BOOST_FOREACH( const CMethod *pMethod, methods ){
542 if( lstrcmp( name, pMethod->GetUserProc().GetName().c_str() ) == 0 ){
543 return 1;
544 }
545 }
546
547 return 0;
548}
549bool CClass::DupliCheckMember(const char *name){
550 //重複チェック
551
552 // 動的メンバ
553 BOOST_FOREACH( CMember *pMember, dynamicMembers ){
554 if( GetName() == pMember->GetName() ){
555 return 1;
556 }
557 }
558
559 // 静的メンバ
560 BOOST_FOREACH( CMember *pMember, staticMembers ){
561 if( GetName() == pMember->GetName() ){
562 return 1;
563 }
564 }
565
566 return 0;
567}
568
569//サイズを取得
570int CClass::GetSize() const
571{
572 return GetMemberOffset( NULL, NULL );
573}
574
575//メンバのオフセットを取得
576int CClass::GetMemberOffset( const char *memberName, int *pMemberNum ) const
577{
578 int i2;
579
580 //仮想関数が存在する場合は関数リストへのポインタのサイズを追加
581 int offset = IsExistVirtualFunctions() ? PTR_SIZE : 0;
582
583 int alignment;
584 if(iAlign) alignment=iAlign;
585 else alignment=1;
586
587 int iMaxAlign=0;
588 int i = -1;
589 BOOST_FOREACH( CMember *pMember, dynamicMembers ){
590 i++;
591
592 i2 = pMember->GetType().GetSize();
593
594 //アラインメントを算出
595 int member_size;
596 if( pMember->GetType().IsStruct() ){
597 //メンバクラスのアラインメントを取得
598 member_size=pMember->GetType().GetClass().GetAlignment();
599 }
600 else{
601 //メンバサイズを取得
602 member_size=i2;
603 }
604 if(iMaxAlign<member_size) iMaxAlign=member_size;
605
606 //アラインメントを考慮
607 if(iAlign&&iAlign<member_size){
608 if(offset%alignment) offset+=alignment-(offset%alignment);
609 }
610 else{
611 if(alignment<member_size) alignment=member_size;
612
613 if(member_size==0){
614 //メンバを持たないクラス
615 //※何もしない(オフセットの計算をしない)
616 }
617 else{
618 if(offset%member_size) offset+=member_size-(offset%member_size);
619 }
620 }
621
622 if(memberName){
623 //メンバ指定がある場合は、オフセットを返す
624 if( pMember->GetName() == memberName ){
625 if(pMemberNum) *pMemberNum=i;
626 return offset;
627 }
628 }
629
630 //配列を考慮したメンバサイズを取得
631 member_size = i2 * Variable::GetSubScriptCounts( pMember->GetSubscripts() );
632
633 //メンバサイズを加算
634 offset+= member_size;
635 }
636
637 if(iMaxAlign<alignment) alignment=iMaxAlign;
638
639 //アラインメントを考慮
640 if(alignment){
641 if(offset%alignment) offset+=alignment-(offset%alignment);
642 }
643
644 if(pMemberNum) *pMemberNum=i;
645 return offset;
646}
647int CClass::GetAlignment() const
648{
649 //仮想関数が存在する場合は関数リストへのポインタのサイズを追加
650 int alignment = IsExistVirtualFunctions() ? PTR_SIZE : 0;
651
652 BOOST_FOREACH( CMember *pMember, dynamicMembers ){
653 int member_size;
654 if(pMember->GetType().IsStruct()){
655 //メンバクラスのアラインメントを取得
656 member_size=pMember->GetType().GetClass().GetAlignment();
657 }
658 else{
659 //メンバサイズを取得
660 member_size = pMember->GetType().GetSize();
661 }
662
663 //アラインメントをセット
664 if(alignment<member_size) alignment=member_size;
665 }
666
667 if(alignment==0) return 0;
668
669 if(iAlign) alignment=iAlign;
670
671 return alignment;
672}
673int CClass::GetFuncNumInVtbl( const UserProc *pUserProc ) const
674{
675 int n = 0;
676 BOOST_FOREACH( const CMethod *pMethod, methods ){
677 if( &pMethod->GetUserProc() == pUserProc ) break;
678 if( pMethod->IsVirtual() ) n++;
679 }
680 return n;
681}
682LONG_PTR CClass::GetVtblGlobalOffset(void) const
683{
684
685 //既に存在する場合はそれを返す
686 if(vtbl_offset!=-1) return vtbl_offset;
687
688
689
690 //////////////////////////////////////
691 // 存在しないときは新たに生成する
692 //////////////////////////////////////
693
694 const UserProc **ppsi;
695 ppsi=(const UserProc **)malloc(GetVtblNum()*sizeof(UserProc *));
696
697 //関数テーブルに値をセット
698 int i2 = 0;
699 BOOST_FOREACH( const CMethod *pMethod, methods ){
700 if(pMethod->IsVirtual()){
701 pMethod->GetUserProc().Using();
702
703 if(pMethod->IsAbstract()){
704 extern int cp;
705 SmoothieException::Throw(300,NULL,cp);
706
707 ppsi[i2]=0;
708 }
709 else{
710 ppsi[i2]=&pMethod->GetUserProc();
711 }
712 i2++;
713 }
714 }
715
716 vtbl_offset=compiler.GetNativeCode().GetDataTable().AddBinary((void *)ppsi,GetVtblNum()*sizeof(LONG_PTR));
717
718 for( int i=0; i < GetVtblNum(); i++ ){
719 pobj_Reloc->AddSchedule_DataSection(vtbl_offset+i*sizeof(LONG_PTR));
720 }
721
722 free(ppsi);
723
724 return vtbl_offset;
725}
726void CClass::ActionVtblSchedule(LONG_PTR ImageBase, LONG_PTR MemPos_CodeSection){
727 if(vtbl_offset==-1) return;
728
729 LONG_PTR *pVtbl;
730 pVtbl=(LONG_PTR *)((char *)compiler.GetNativeCode().GetDataTable().GetPtr()+vtbl_offset);
731
732 int i;
733 for(i=0;i<GetVtblNum();i++){
734 UserProc *pUserProc;
735 pUserProc=(UserProc *)pVtbl[i];
736 if(!pUserProc) continue;
737 pVtbl[i]=pUserProc->GetBeginOpAddress()+ImageBase+MemPos_CodeSection;
738 }
739}
740bool CClass::IsAbstract() const
741{
742 // 未実装(abstract)の仮想関数を持つ場合はtrueを返す
743
744 BOOST_FOREACH( const CMethod *pMethod, methods ){
745 if(pMethod->IsVirtual()){
746 if(pMethod->IsAbstract()){
747 return true;
748 }
749 }
750 }
751
752 return false;
753}
754
755
756int Classes::GetHashCode(const char *name) const
757{
758 int key;
759
760 for(key=0;*name!='\0';name++){
761 key=((key<<8)+ *name )%MAX_CLASS_HASH;
762 }
763
764 return key;
765}
766
767CClass *Classes::Create( const NamespaceScopes &namespaceScopes, const NamespaceScopesCollection &importedNamespaces, const char *name){
768 return new CClass(namespaceScopes, importedNamespaces, name);
769}
770bool Classes::Insert( CClass *pClass )
771{
772 // キャッシュしておくクラス
773 if( pClass->GetName() == "String" )
774 {
775 pStringClass=pClass;
776 }
777 else if( pClass->GetName() == "Object" )
778 {
779 pObjectClass = pClass;
780 }
781
782 /////////////////////////////////
783 // ハッシュデータに追加
784 /////////////////////////////////
785
786 int key;
787 key=GetHashCode( pClass->GetName().c_str() );
788
789 if(pobj_ClassHash[key]){
790 CClass *pobj_c2;
791 pobj_c2=pobj_ClassHash[key];
792 while(1){
793 if( ((const Prototype *)pobj_c2)->IsEqualSymbol( *(const Prototype *)pClass ) ){
794 //名前空間及びクラス名が重複した場合
795 SmoothieException::Throw(15,pClass->GetName());
796 return false;
797 }
798
799 if(pobj_c2->pobj_NextClass==0) break;
800 pobj_c2=pobj_c2->pobj_NextClass;
801 }
802 pobj_c2->pobj_NextClass=pClass;
803 }
804 else{
805 pobj_ClassHash[key]=pClass;
806 }
807 return true;
808}
809CClass *Classes::Add( const NamespaceScopes &namespaceScopes, const NamespaceScopesCollection &importedNamespaces, const char *name,int nowLine){
810 //////////////////////////////////////////////////////////////////////////
811 // クラスを追加
812 // ※名前のみを登録。その他の情報はSetClassメソッドで!
813 //////////////////////////////////////////////////////////////////////////
814
815 CClass *pClass = Create(namespaceScopes, importedNamespaces, name);
816
817 if( !Insert( pClass ) )
818 {
819 return NULL;
820 }
821
822 return pClass;
823}
824
825void Classes::CollectClassesForNameOnly( const BasicSource &source )
826{
827 int i, i2;
828 char temporary[VN_SIZE];
829
830 // Blittable型管理オブジェクトを初期化
831 compiler.GetMeta().GetBlittableTypes().clear();
832
833 // 名前空間管理
834 NamespaceScopes &namespaceScopes = compiler.GetNamespaceSupporter().GetLivingNamespaceScopes();
835 namespaceScopes.clear();
836
837 // Importsされた名前空間の管理
838 NamespaceScopesCollection &importedNamespaces = compiler.GetNamespaceSupporter().GetImportedNamespaces();
839 importedNamespaces.clear();
840
841 for(i=0;;i++){
842 if(source[i]=='\0') break;
843
844 if( source[i] == 1 && source[i+1] == ESC_NAMESPACE ){
845 for(i+=2,i2=0;;i2++,i++){
846 if( IsCommandDelimitation( source[i] ) ){
847 temporary[i2]=0;
848 break;
849 }
850 temporary[i2]=source[i];
851 }
852 namespaceScopes.push_back( temporary );
853
854 continue;
855 }
856 else if( source[i] == 1 && source[i+1] == ESC_ENDNAMESPACE ){
857 if( namespaceScopes.size() <= 0 ){
858 SmoothieException::Throw(12, "End Namespace", i );
859 }
860 else{
861 namespaceScopes.pop_back();
862 }
863
864 i += 2;
865 continue;
866 }
867 else if( source[i] == 1 && source[i+1] == ESC_IMPORTS ){
868 for(i+=2,i2=0;;i2++,i++){
869 if( IsCommandDelimitation( source[i] ) ){
870 temporary[i2]=0;
871 break;
872 }
873 temporary[i2]=source[i];
874 }
875 if( !compiler.GetNamespaceSupporter().ImportsNamespace( temporary ) )
876 {
877 SmoothieException::Throw(64,temporary,i );
878 }
879
880 continue;
881 }
882 else if( source[i] == 1 && source[i+1] == ESC_CLEARNAMESPACEIMPORTED ){
883 importedNamespaces.clear();
884 continue;
885 }
886
887 if(source[i]==1&&(
888 source[i+1]==ESC_CLASS||
889 source[i+1]==ESC_TYPE||
890 source[i+1]==ESC_INTERFACE
891 )){
892 int nowLine;
893 nowLine=i;
894
895 i+=2;
896 Type blittableType;
897 if(memicmp(source.GetBuffer()+i,"Align(",6)==0){
898 //アラインメント修飾子
899 i+=6;
900 i=JumpStringInPare(source.GetBuffer(),i)+1;
901 }
902 else if( memicmp( source.GetBuffer() + i, "Blittable(", 10 ) == 0 ){
903 // Blittable修飾子
904 i+=10;
905 i+=GetStringInPare_RemovePare(temporary,source.GetBuffer()+i)+1;
906 compiler.StringToType( temporary, blittableType );
907 }
908
909 bool isEnum = false;
910 if( source[i] == 1 && source[i+1] == ESC_ENUM ){
911 // 列挙型の場合
912 isEnum = true;
913
914 i+=2;
915 }
916
917 int i2;
918 char temporary[VN_SIZE];
919 for(i2=0;;i++,i2++){
920 if(!IsVariableChar(source[i])){
921 temporary[i2]=0;
922 break;
923 }
924 temporary[i2]=source[i];
925 }
926
927 //クラスを追加
928 CClass *pClass = this->Add(namespaceScopes, importedNamespaces, temporary,nowLine);
929 if( pClass ){
930 if( source[nowLine+1] == ESC_CLASS ){
931 if( isEnum ){
932 pClass->SetClassType( CClass::Enum );
933 }
934 else{
935 pClass->SetClassType( CClass::Class );
936 }
937 }
938 else if( source[nowLine+1] == ESC_INTERFACE ){
939 pClass->SetClassType( CClass::Interface );
940 }
941 else{
942 pClass->SetClassType( CClass::Structure );
943 }
944 }
945
946 // Blittable型の場合
947 if( !blittableType.IsNull() ){
948 pClass->SetBlittableType( blittableType );
949
950 // Blittable型として登録
951 compiler.GetMeta().GetBlittableTypes().push_back( BlittableType( blittableType, pClass ) );
952 }
953 }
954 }
955}
956
957void Classes::ActionVtblSchedule(LONG_PTR ImageBase, LONG_PTR MemPos_CodeSection){
958 int i;
959 for(i=0;i<MAX_CLASS_HASH;i++){
960 if(pobj_ClassHash[i]){
961 CClass *pobj_c;
962 pobj_c=pobj_ClassHash[i];
963 while(1){
964 pobj_c->ActionVtblSchedule(ImageBase,MemPos_CodeSection);
965
966 if(pobj_c->pobj_NextClass==0) break;
967 pobj_c=pobj_c->pobj_NextClass;
968 }
969 }
970 }
971}
972
973
974void Classes::InitStaticMember(){
975 //静的メンバをグローバル領域に作成
976
977 //イテレータをリセット
978 this->Iterator_Reset();
979
980 extern int cp;
981 int back_cp=cp;
982
983 while(this->Iterator_HasNext()){
984 CClass &objClass = *this->Iterator_GetNext();
985
986 // 名前空間をセット
987 compiler.GetNamespaceSupporter().GetLivingNamespaceScopes() = objClass.GetNamespaceScopes();
988
989 int i=0;
990 BOOST_FOREACH( CMember *member, objClass.GetStaticMembers() ){
991 char temporary[VN_SIZE];
992 sprintf(temporary,"%s.%s",objClass.GetName().c_str(),member->GetName().c_str());
993 dim(
994 temporary,
995 member->GetSubscripts(),
996 member->GetType(),
997 member->GetInitializeExpression().c_str(),
998 member->GetConstructParameter().c_str(),
999 0);
1000
1001 //ネイティブコードバッファの再確保
1002 ReallocNativeCodeBuffer();
1003
1004 i++;
1005 }
1006 }
1007
1008 compiler.GetNamespaceSupporter().GetLivingNamespaceScopes().clear();
1009
1010 cp=back_cp;
1011}
1012bool Classes::MemberVar_LoopRefCheck(const CClass &objClass){
1013 bool result = true;
1014 BOOST_FOREACH( CMember *pMember, objClass.GetDynamicMembers() ){
1015 if(pMember->GetType().IsStruct()){
1016 //循環参照でないかをチェック
1017 if(pobj_LoopRefCheck->check(pMember->GetType().GetClass())){
1018 extern int cp;
1019 SetError(124,pMember->GetType().GetClass().GetName(),cp);
1020 return false;
1021 }
1022
1023 pobj_LoopRefCheck->add(objClass.GetName().c_str());
1024
1025 bool tempResult = MemberVar_LoopRefCheck(pMember->GetType().GetClass());
1026 if( result )
1027 {
1028 result = tempResult;
1029 }
1030
1031 pobj_LoopRefCheck->del(objClass.GetName().c_str());
1032 }
1033 }
1034
1035 return result;
1036}
1037void Classes::GetClass_recur(const char *lpszInheritsClass){
1038 extern char *basbuf;
1039 int i,i2,i3,sub_address,top_pos;
1040 char temporary[8192];
1041
1042 // 名前空間管理
1043 NamespaceScopes backupNamespaceScopes = compiler.GetNamespaceSupporter().GetLivingNamespaceScopes();
1044 NamespaceScopes &namespaceScopes = compiler.GetNamespaceSupporter().GetLivingNamespaceScopes();
1045 namespaceScopes.clear();
1046
1047 for(i=0;;i++){
1048 if(basbuf[i]=='\0') break;
1049
1050
1051 // 名前空間
1052 if( basbuf[i] == 1 && basbuf[i+1] == ESC_NAMESPACE ){
1053 for(i+=2,i2=0;;i2++,i++){
1054 if( IsCommandDelimitation( basbuf[i] ) ){
1055 temporary[i2]=0;
1056 break;
1057 }
1058 temporary[i2]=basbuf[i];
1059 }
1060 namespaceScopes.push_back( temporary );
1061
1062 continue;
1063 }
1064 else if( basbuf[i] == 1 && basbuf[i+1] == ESC_ENDNAMESPACE ){
1065 if( namespaceScopes.size() <= 0 ){
1066 SetError(12, "End Namespace", i );
1067 }
1068 else{
1069 namespaceScopes.pop_back();
1070 }
1071
1072 i += 2;
1073 continue;
1074 }
1075
1076
1077
1078 if(basbuf[i]==1&&basbuf[i+1]==ESC_INTERFACE){
1079 //////////////////////////
1080 // インターフェイス
1081 //////////////////////////
1082
1083 top_pos=i;
1084
1085 i+=2;
1086
1087 //インターフェイス名を取得
1088 GetIdentifierToken( temporary, basbuf, i );
1089
1090 CClass *pobj_c = const_cast<CClass *>( this->Find(namespaceScopes, temporary) );
1091 if(!pobj_c) continue;
1092
1093 if(lpszInheritsClass){
1094 if(lstrcmp(lpszInheritsClass,pobj_c->GetName().c_str())!=0){
1095 //継承先先読み用
1096 continue;
1097 }
1098 }
1099
1100 if(pobj_c->IsReady()){
1101 //既に先読みされているとき
1102 continue;
1103 }
1104
1105 pobj_c->Readed();
1106
1107 pobj_c->SetConstructorMemberSubIndex( -1 );
1108 pobj_c->SetDestructorMemberSubIndex( -1 );
1109
1110 if(basbuf[i+1]==1&&basbuf[i+2]==ESC_INHERITS){
1111 //継承を行う場合
1112 for(i+=3,i2=0;;i++,i2++){
1113 if(IsCommandDelimitation(basbuf[i])){
1114 temporary[i2]=0;
1115 break;
1116 }
1117 temporary[i2]=basbuf[i];
1118 }
1119
1120 if(lstrcmpi(temporary,pobj_c->GetName().c_str())==0){
1121 SetError(105,temporary,i);
1122 goto Interface_InheritsError;
1123 }
1124
1125 //継承元クラスを取得
1126 const Classes &classes = *this;
1127 const CClass *pInheritsClass = classes.Find(temporary);
1128 if( !pInheritsClass ){
1129 SetError(106,temporary,i);
1130 goto Interface_InheritsError;
1131 }
1132
1133 //継承させる
1134 if( !pobj_c->InheritsClass( *pInheritsClass, i ) ){
1135 goto Interface_InheritsError;
1136 }
1137 }
1138 else{
1139 //継承無し
1140 if( &pobj_c->GetSuperClass() || pobj_c->GetVtblNum() )
1141 {
1142 // TODO: ここに来ないことが実証できたらこの分岐は消す
1143 Jenga::Throw( "GetClass_recur内の例外" );
1144 }
1145 }
1146Interface_InheritsError:
1147
1148 //メンバ変数、関数を取得
1149 while(1){
1150 i++;
1151
1152 //エラー
1153 if(basbuf[i]==1&&(basbuf[i+1]==ESC_CLASS||basbuf[i+1]==ESC_TYPE||basbuf[i+1]==ESC_INTERFACE)){
1154 SetError(22,"Interface",i);
1155 i--;
1156 break;
1157 }
1158
1159 if(basbuf[i]==1&&basbuf[i+1]==ESC_INHERITS){
1160 SetError(111,NULL,i);
1161 break;
1162 }
1163
1164 sub_address=i;
1165
1166 for(i2=0;;i++,i2++){
1167 if(IsCommandDelimitation(basbuf[i])){
1168 temporary[i2]=0;
1169 break;
1170 }
1171 temporary[i2]=basbuf[i];
1172 }
1173 if(temporary[0]=='\0'){
1174 if(basbuf[i]=='\0'){
1175 i--;
1176 SetError(22,"Interface",top_pos);
1177 break;
1178 }
1179 continue;
1180 }
1181
1182 //End Interface記述の場合
1183 if(temporary[0]==1&&temporary[1]==ESC_ENDINTERFACE) break;
1184
1185 if(!(temporary[0]==1&&(
1186 temporary[1]==ESC_SUB||temporary[1]==ESC_FUNCTION
1187 ))){
1188 SetError(1,NULL,i);
1189 break;
1190 }
1191
1192 //メンバ関数を追加
1193 pobj_c->AddMethod(pobj_c,
1194 Prototype::Public, //Publicアクセス権
1195 0, //Static指定なし
1196 false, //Constではない
1197 1, //Abstract
1198 1, //Virtual
1199 0,
1200 temporary,
1201 sub_address
1202 );
1203 }
1204 }
1205
1206 if(basbuf[i]==1&&(basbuf[i+1]==ESC_CLASS||basbuf[i+1]==ESC_TYPE)){
1207 //////////////////////////
1208 // クラス
1209 //////////////////////////
1210
1211 top_pos=i;
1212
1213 const DWORD dwClassType=basbuf[i+1];
1214
1215 i+=2;
1216
1217 int iAlign=0;
1218 if(memicmp(basbuf+i,"Align(",6)==0){
1219 //アラインメント修飾子
1220 i+=6;
1221 i+=GetStringInPare_RemovePare(temporary,basbuf+i)+1;
1222 iAlign=atoi(temporary);
1223
1224 if(!(iAlign==1||iAlign==2||iAlign==4||iAlign==8||iAlign==16))
1225 SetError(51,NULL,i);
1226 }
1227 else if( memicmp( basbuf + i, "Blittable(", 10 ) == 0 ){
1228 // Blittable修飾子
1229 i+=10;
1230 i=JumpStringInPare(basbuf,i)+1;
1231 }
1232
1233 if( basbuf[i] == 1 && basbuf[i+1] == ESC_ENUM ){
1234 // 列挙型の場合
1235 i+=2;
1236 }
1237
1238 //クラス名を取得
1239 GetIdentifierToken( temporary, basbuf, i );
1240
1241 CClass *pobj_c = const_cast<CClass *>( this->Find(namespaceScopes, temporary) );
1242 if(!pobj_c) continue;
1243
1244 if(lpszInheritsClass){
1245 if( pobj_c->GetName() != lpszInheritsClass ){
1246 //継承先先読み用
1247 continue;
1248 }
1249 }
1250
1251 if(pobj_c->IsReady()){
1252 //既に先読みされているとき
1253 continue;
1254 }
1255
1256 pobj_c->iAlign=iAlign;
1257
1258 pobj_c->Readed();
1259
1260 pobj_c->SetConstructorMemberSubIndex( -1 );
1261 pobj_c->SetDestructorMemberSubIndex( -1 );
1262
1263 //アクセス制限の初期値をセット
1264 Prototype::Accessibility accessibility;
1265 if(dwClassType==ESC_CLASS){
1266 accessibility = Prototype::Private;
1267 }
1268 else{
1269 accessibility = Prototype::Public;
1270 }
1271
1272 if( pobj_c->GetName() == "Object" || dwClassType == ESC_TYPE ){
1273 if( &pobj_c->GetSuperClass() || pobj_c->GetVtblNum() )
1274 {
1275 // TODO: ここに来ないことが実証できたらこの分岐は消す
1276 Jenga::Throw( "GetClass_recur内の例外" );
1277 }
1278 }
1279 else{
1280 bool isInherits = false;
1281 if(basbuf[i+1]==1&&basbuf[i+2]==ESC_INHERITS){
1282 //継承を行う場合
1283 isInherits = true;
1284
1285 for(i+=3,i2=0;;i++,i2++){
1286 if(IsCommandDelimitation(basbuf[i])){
1287 temporary[i2]=0;
1288 break;
1289 }
1290 temporary[i2]=basbuf[i];
1291 }
1292
1293 if(lstrcmpi(temporary,pobj_c->GetName().c_str())==0){
1294 SetError(105,temporary,i);
1295 goto InheritsError;
1296 }
1297 }
1298
1299 if( !isInherits ){
1300 //Objectを継承する
1301 lstrcpy( temporary, "Object" );
1302 }
1303
1304 pobj_c->Inherits( temporary, i );
1305 }
1306InheritsError:
1307
1308 //メンバとメソッドを取得
1309 while(1){
1310 i++;
1311
1312 //エラー
1313 if(basbuf[i]==1&&(basbuf[i+1]==ESC_CLASS||basbuf[i+1]==ESC_TYPE)){
1314 SetError(22,"Class",i);
1315 i--;
1316 break;
1317 }
1318
1319 if(basbuf[i]==1&&basbuf[i+1]==ESC_INHERITS){
1320 SetError(111,NULL,i);
1321 break;
1322 }
1323
1324 //Static修飾子
1325 BOOL bStatic;
1326 if(basbuf[i]==1&&basbuf[i+1]==ESC_STATIC){
1327 bStatic=1;
1328 i+=2;
1329 }
1330 else bStatic=0;
1331
1332 //Const修飾子
1333 bool isConst = false;
1334 if( basbuf[i] == 1 && basbuf[i + 1] == ESC_CONST ){
1335 isConst = true;
1336 i += 2;
1337 }
1338
1339 if(basbuf[i]==1&&(
1340 basbuf[i+1]==ESC_ABSTRACT||basbuf[i+1]==ESC_VIRTUAL||basbuf[i+1]==ESC_OVERRIDE||
1341 basbuf[i+1]==ESC_SUB||basbuf[i+1]==ESC_FUNCTION
1342 )){
1343 i3=basbuf[i+1];
1344 sub_address=i;
1345 }
1346 else i3=0;
1347
1348 bool isVirtual = false, isAbstract = false, isOverride = false;
1349 if(i3==ESC_ABSTRACT){
1350 isAbstract=1;
1351 isVirtual=1;
1352 i+=2;
1353
1354 i3=basbuf[i+1];
1355 }
1356 else if(i3==ESC_VIRTUAL){
1357 isAbstract=0;
1358 isVirtual=1;
1359 i+=2;
1360
1361 i3=basbuf[i+1];
1362 }
1363 else if(i3==ESC_OVERRIDE){
1364 isOverride=1;
1365 isVirtual=1;
1366
1367 i+=2;
1368
1369 i3=basbuf[i+1];
1370 }
1371
1372 for(i2=0;;i++,i2++){
1373 if(IsCommandDelimitation(basbuf[i])){
1374 temporary[i2]=0;
1375 break;
1376 }
1377 temporary[i2]=basbuf[i];
1378 }
1379 if(temporary[0]=='\0'){
1380 if(basbuf[i]=='\0'){
1381
1382 if(dwClassType==ESC_CLASS)
1383 SetError(22,"Class",top_pos);
1384 else
1385 SetError(22,"Type",top_pos);
1386
1387 i--;
1388 break;
1389 }
1390 continue;
1391 }
1392
1393 //End Class記述の場合
1394 if(temporary[0]==1&&temporary[1]==ESC_ENDCLASS&&dwClassType==ESC_CLASS) break;
1395 if(temporary[0]==1&&temporary[1]==ESC_ENDTYPE&&dwClassType==ESC_TYPE) break;
1396
1397 //アクセスを変更
1398 if(lstrcmpi(temporary,"Private")==0){
1399 accessibility = Prototype::Private;
1400 continue;
1401 }
1402 if(lstrcmpi(temporary,"Public")==0){
1403 accessibility = Prototype::Public;
1404 continue;
1405 }
1406 if(lstrcmpi(temporary,"Protected")==0){
1407 accessibility = Prototype::Protected;
1408 continue;
1409 }
1410
1411 extern int cp;
1412 if(i3==0){
1413 if(bStatic){
1414 //静的メンバを追加
1415 cp=i; //エラー用
1416 pobj_c->AddStaticMember( accessibility, isConst, false, temporary, i);
1417 }
1418 else{
1419 //メンバを追加
1420 cp=i; //エラー用
1421 pobj_c->AddMember( accessibility, isConst, false, temporary, i );
1422
1423
1424 if(pobj_c->GetDynamicMembers()[pobj_c->GetDynamicMembers().size()-1]->GetType().IsStruct()){
1425 if( !pobj_c->GetDynamicMembers()[pobj_c->GetDynamicMembers().size()-1]->GetType().GetClass().IsReady() ){
1426 //参照先が読み取られていないとき
1427 GetClass_recur(pobj_c->GetDynamicMembers()[pobj_c->GetDynamicMembers().size()-1]->GetType().GetClass().GetName().c_str());
1428 }
1429 }
1430
1431
1432 if(pobj_c->GetDynamicMembers()[pobj_c->GetDynamicMembers().size()-1]->GetType().IsStruct()){
1433 //循環参照のチェック
1434 pobj_LoopRefCheck->add(pobj_c->GetName().c_str());
1435 if(!MemberVar_LoopRefCheck(pobj_c->GetDynamicMembers()[pobj_c->GetDynamicMembers().size()-1]->GetType().GetClass())){
1436 //エラー回避
1437 pobj_c->GetDynamicMembers()[pobj_c->GetDynamicMembers().size()-1]->GetType().SetBasicType( DEF_PTR_VOID );
1438 }
1439 pobj_LoopRefCheck->del(pobj_c->GetName().c_str());
1440 }
1441 }
1442 }
1443 else{
1444 //メソッドを追加
1445 cp=i; //エラー用
1446 pobj_c->AddMethod(pobj_c,
1447 accessibility,
1448 bStatic,
1449 isConst,
1450 isAbstract,
1451 isVirtual,
1452 isOverride,
1453 temporary,
1454 sub_address);
1455
1456 if( isAbstract ) continue;
1457
1458 for(;;i++){
1459 if(basbuf[i]=='\0'){
1460 i--;
1461 break;
1462 }
1463 if(basbuf[i-1]!='*'&&
1464 basbuf[i]==1&&(
1465 basbuf[i+1]==ESC_SUB||
1466 basbuf[i+1]==ESC_FUNCTION||
1467 basbuf[i+1]==ESC_MACRO||
1468 basbuf[i+1]==ESC_TYPE||
1469 basbuf[i+1]==ESC_CLASS||
1470 basbuf[i+1]==ESC_INTERFACE||
1471 basbuf[i+1]==ESC_ENUM)){
1472 GetDefaultNameFromES(i3,temporary);
1473 SetError(22,temporary,i);
1474 }
1475 if(basbuf[i]==1&&basbuf[i+1]==GetEndXXXCommand((char)i3)){
1476 i+=2;
1477 break;
1478 }
1479 }
1480 }
1481 }
1482 }
1483 }
1484
1485
1486 // 名前空間を元に戻す
1487 compiler.GetNamespaceSupporter().GetLivingNamespaceScopes() = backupNamespaceScopes;
1488}
1489void Classes::GetAllClassInfo(void){
1490 //ループ継承チェック用のクラス
1491 pobj_LoopRefCheck=new CLoopRefCheck();
1492
1493 //クラスを取得
1494 GetClass_recur(0);
1495
1496 delete pobj_LoopRefCheck;
1497 pobj_LoopRefCheck=0;
1498
1499 // イテレータの準備
1500 this->Iterator_Init();
1501}
1502void Classes::Compile_System_InitializeUserTypes(){
1503 char temporary[VN_SIZE];
1504
1505 ////////////////////////////////////////////////////////////////////
1506 // クラス登録
1507 ////////////////////////////////////////////////////////////////////
1508
1509 // イテレータをリセット
1510 Iterator_Reset();
1511
1512 while( Iterator_HasNext() ){
1513 const CClass &objClass = *Iterator_GetNext();
1514
1515 if( !objClass.IsUsing() ){
1516 // 未使用のクラスは無視する
1517 continue;
1518 }
1519
1520 char referenceOffsetsBuffer[1024] = "";
1521 int numOfReference = 0;
1522 BOOST_FOREACH( CMember *pMember, objClass.GetDynamicMembers() ){
1523 if( pMember->GetType().IsObject() || pMember->GetType().IsPointer() ){
1524 if( referenceOffsetsBuffer[0] ){
1525 lstrcat( referenceOffsetsBuffer, "," );
1526 }
1527
1528 sprintf( referenceOffsetsBuffer + lstrlen( referenceOffsetsBuffer ),
1529 "%d",
1530 objClass.GetMemberOffset( pMember->GetName().c_str() ) );
1531
1532 numOfReference++;
1533 }
1534 }
1535
1536 sprintf( temporary
1537 , "Add(%c%c_System_TypeForClass(\"%s\",\"%s\",[%s],%d))"
1538 , 1
1539 , ESC_NEW
1540 , "" // 名前空間 (TODO: 実装)
1541 , objClass.GetName().c_str() // クラス名
1542 , referenceOffsetsBuffer // 参照メンバオフセット配列
1543 , numOfReference // 参照メンバの個数
1544 );
1545
1546 // コンパイル
1547 ChangeOpcode( temporary );
1548
1549 // ネイティブコードバッファの再確保
1550 ReallocNativeCodeBuffer();
1551 }
1552
1553
1554 ////////////////////////////////////////////////////////////////////
1555 // 基底クラスを登録
1556 ////////////////////////////////////////////////////////////////////
1557
1558 sprintf(temporary, "%c%ctempType=Nothing%c%cTypeBaseImpl"
1559 , HIBYTE( COM_DIM )
1560 , LOBYTE( COM_DIM )
1561 , 1
1562 , ESC_AS
1563 );
1564 ChangeOpcode( temporary );
1565
1566 // イテレータをリセット
1567 Iterator_Reset();
1568
1569 while( Iterator_HasNext() ){
1570 const CClass &objClass = *Iterator_GetNext();
1571
1572 if( !objClass.IsUsing() ){
1573 // 未使用のクラスは無視する
1574 continue;
1575 }
1576
1577 if( objClass.HasSuperClass() ){
1578 sprintf( temporary
1579 , "tempType=Search(\"%s\",\"%s\")"
1580 , "" // 名前空間 (TODO: 実装)
1581 , objClass.GetName().c_str() // クラス名
1582 );
1583
1584 // コンパイル
1585 ChangeOpcode( temporary );
1586
1587 sprintf( temporary
1588 , "tempType.SetBaseType(Search(\"%s\",\"%s\"))"
1589 , "" // 名前空間 (TODO: 実装)
1590 , objClass.GetSuperClass().GetName().c_str() // 基底クラス名
1591 );
1592
1593 // コンパイル
1594 ChangeOpcode( temporary );
1595 }
1596
1597 // ネイティブコードバッファの再確保
1598 ReallocNativeCodeBuffer();
1599 }
1600
1601
1602
1603 ////////////////////////////////////////////////////////////////////
1604 // 継承関係登録
1605 ////////////////////////////////////////////////////////////////////
1606 // TODO: 未完成
1607 /*
1608
1609 // イテレータをリセット
1610 Iterator_Reset();
1611
1612 while( Iterator_HasNext() ){
1613 CClass *pClass = Iterator_GetNext();
1614
1615 sprintf( genBuffer + length
1616 , "obj.Search( \"%s\" ).SetBaseType( Search( \"%s\" ) ):"
1617 , "" // クラス名
1618 , pClass->name // クラス名
1619 );
1620 length += lstrlen( genBuffer + length );
1621
1622 while( length + 8192 > max ){
1623 max += 8192;
1624 genBuffer = (char *)realloc( genBuffer, max );
1625 }
1626 }*/
1627}
1628
1629const CClass *Classes::Find( const NamespaceScopes &namespaceScopes, const string &name ) const
1630{
1631 int key;
1632 key=GetHashCode(name.c_str());
1633
1634 if( namespaceScopes.size() == 0 && name == "Object" ){
1635 return GetObjectClassPtr();
1636 }
1637 else if( namespaceScopes.size() == 0 && name == "String" ){
1638 return GetStringClassPtr();
1639 }
1640
1641 if(pobj_ClassHash[key]){
1642 CClass *pobj_c;
1643 pobj_c=pobj_ClassHash[key];
1644 while(1){
1645 if( pobj_c->IsEqualSymbol( namespaceScopes, name ) ){
1646 //名前空間とクラス名が一致した
1647 return pobj_c;
1648 }
1649
1650 if(pobj_c->pobj_NextClass==0) break;
1651 pobj_c=pobj_c->pobj_NextClass;
1652 }
1653 }
1654
1655 // TypeDefも見る
1656 int index = compiler.GetMeta().GetTypeDefs().GetIndex( namespaceScopes, name );
1657 if( index != -1 ){
1658 Type type = compiler.GetMeta().GetTypeDefs()[index].GetBaseType();
1659 if( type.IsObject() ){
1660 return &type.GetClass();
1661 }
1662 }
1663
1664 return NULL;
1665}
1666const CClass *Classes::Find( const string &fullName ) const
1667{
1668 char AreaName[VN_SIZE] = ""; //オブジェクト変数
1669 char NestName[VN_SIZE] = ""; //入れ子メンバ
1670 bool isNest = SplitMemberName( fullName.c_str(), AreaName, NestName );
1671
1672 return Find( NamespaceScopes( AreaName ), NestName );
1673}
1674void Classes::StartCompile( const UserProc *pUserProc ){
1675 const CClass *pParentClass = pUserProc->GetParentClassPtr();
1676 if( pParentClass ){
1677 pParentClass->Using();
1678
1679 pCompilingMethod = pParentClass->GetMethods().GetMethodPtr( pUserProc );
1680 if( !pCompilingMethod ){
1681 pCompilingMethod = pParentClass->GetStaticMethods().GetMethodPtr( pUserProc );
1682 if( !pCompilingMethod ){
1683 SmoothieException::Throw(300);
1684 }
1685 }
1686 }
1687 else{
1688 pCompilingMethod = NULL;
1689 }
1690}
1691
1692CClass *Classes::GetStringClassPtr() const
1693{
1694 if( !pStringClass ){
1695 SmoothieException::Throw();
1696 return NULL;
1697 }
1698 return pStringClass;
1699}
1700CClass *Classes::GetObjectClassPtr() const
1701{
1702 if( !pObjectClass ){
1703 SmoothieException::Throw();
1704 return NULL;
1705 }
1706 return pObjectClass;
1707}
1708
1709
1710//////////////////////
1711// イテレータ
1712//////////////////////
1713
1714void Classes::Iterator_Init() const
1715{
1716 if(ppobj_IteClass) free(ppobj_IteClass);
1717
1718 iIteMaxNum=0;
1719 iIteNextNum=0;
1720 ppobj_IteClass=(CClass **)malloc(1);
1721
1722 int i;
1723 for(i=0;i<MAX_CLASS_HASH;i++){
1724 if(pobj_ClassHash[i]){
1725 CClass *pobj_c;
1726 pobj_c=pobj_ClassHash[i];
1727 while(1){
1728 ppobj_IteClass=(CClass **)realloc(ppobj_IteClass,(iIteMaxNum+1)*sizeof(CClass *));
1729 ppobj_IteClass[iIteMaxNum]=pobj_c;
1730 iIteMaxNum++;
1731
1732 if(pobj_c->pobj_NextClass==0) break;
1733 pobj_c=pobj_c->pobj_NextClass;
1734 }
1735 }
1736 }
1737}
1738void Classes::Iterator_Reset() const
1739{
1740 iIteNextNum = 0;
1741}
1742BOOL Classes::Iterator_HasNext() const
1743{
1744 if(iIteNextNum<iIteMaxNum) return 1;
1745 return 0;
1746}
1747CClass *Classes::Iterator_GetNext() const
1748{
1749 CClass *pobj_c = ppobj_IteClass[iIteNextNum];
1750 iIteNextNum++;
1751 return pobj_c;
1752}
1753int Classes::Iterator_GetMaxCount() const
1754{
1755 return iIteMaxNum;
1756}
Note: See TracBrowser for help on using the repository browser.