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

Last change on this file since 270 was 270, checked in by dai_9181, 17 years ago
File size: 39.9 KB
Line 
1#include "stdafx.h"
2
3#include <jenga/include/smoothie/Smoothie.h>
4#include <jenga/include/smoothie/SmoothieException.h>
5#include <jenga/include/smoothie/LexicalAnalysis.h>
6
7#include <Source.h>
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.GetObjectModule().meta.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.GetObjectModule().meta.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.GetObjectModule().meta.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.GetObjectModule().meta.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.GetObjectModule().meta.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.GetObjectModule().meta.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 = 1;
584 if( GetFixedAlignment() )
585 {
586 alignment = GetFixedAlignment();
587 }
588
589 int iMaxAlign=0;
590 int i = -1;
591 BOOST_FOREACH( CMember *pMember, dynamicMembers ){
592 i++;
593
594 i2 = pMember->GetType().GetSize();
595
596 //アラインメントを算出
597 int member_size;
598 if( pMember->GetType().IsStruct() ){
599 //メンバクラスのアラインメントを取得
600 member_size=pMember->GetType().GetClass().GetAlignment();
601 }
602 else{
603 //メンバサイズを取得
604 member_size=i2;
605 }
606 if(iMaxAlign<member_size) iMaxAlign=member_size;
607
608 //アラインメントを考慮
609 if(GetFixedAlignment()&&GetFixedAlignment()<member_size){
610 if(offset%alignment) offset+=alignment-(offset%alignment);
611 }
612 else{
613 if(alignment<member_size) alignment=member_size;
614
615 if(member_size==0){
616 //メンバを持たないクラス
617 //※何もしない(オフセットの計算をしない)
618 }
619 else{
620 if(offset%member_size) offset+=member_size-(offset%member_size);
621 }
622 }
623
624 if(memberName){
625 //メンバ指定がある場合は、オフセットを返す
626 if( pMember->GetName() == memberName ){
627 if(pMemberNum) *pMemberNum=i;
628 return offset;
629 }
630 }
631
632 //配列を考慮したメンバサイズを取得
633 member_size = i2 * Variable::GetSubScriptCounts( pMember->GetSubscripts() );
634
635 //メンバサイズを加算
636 offset+= member_size;
637 }
638
639 if(iMaxAlign<alignment) alignment=iMaxAlign;
640
641 //アラインメントを考慮
642 if(alignment){
643 if(offset%alignment) offset+=alignment-(offset%alignment);
644 }
645
646 if(pMemberNum) *pMemberNum=i;
647 return offset;
648}
649int CClass::GetAlignment() const
650{
651 //仮想関数が存在する場合は関数リストへのポインタのサイズを追加
652 int alignment = IsExistVirtualFunctions() ? PTR_SIZE : 0;
653
654 BOOST_FOREACH( CMember *pMember, dynamicMembers ){
655 int member_size;
656 if(pMember->GetType().IsStruct()){
657 //メンバクラスのアラインメントを取得
658 member_size=pMember->GetType().GetClass().GetAlignment();
659 }
660 else{
661 //メンバサイズを取得
662 member_size = pMember->GetType().GetSize();
663 }
664
665 //アラインメントをセット
666 if(alignment<member_size) alignment=member_size;
667 }
668
669 if(alignment==0) return 0;
670
671 if(GetFixedAlignment()) alignment=GetFixedAlignment();
672
673 return alignment;
674}
675int CClass::GetFuncNumInVtbl( const UserProc *pUserProc ) const
676{
677 int n = 0;
678 BOOST_FOREACH( const CMethod *pMethod, methods ){
679 if( &pMethod->GetUserProc() == pUserProc ) break;
680 if( pMethod->IsVirtual() ) n++;
681 }
682 return n;
683}
684LONG_PTR CClass::GetVtblGlobalOffset(void) const
685{
686
687 //既に存在する場合はそれを返す
688 if(vtbl_offset!=-1) return vtbl_offset;
689
690
691
692 //////////////////////////////////////
693 // 存在しないときは新たに生成する
694 //////////////////////////////////////
695
696 const UserProc **ppsi;
697 ppsi=(const UserProc **)malloc(GetVtblNum()*sizeof(UserProc *));
698
699 //関数テーブルに値をセット
700 int i2 = 0;
701 BOOST_FOREACH( const CMethod *pMethod, methods ){
702 if(pMethod->IsVirtual()){
703 pMethod->GetUserProc().Using();
704
705 if(pMethod->IsAbstract()){
706 extern int cp;
707 SmoothieException::Throw(300,NULL,cp);
708
709 ppsi[i2]=0;
710 }
711 else{
712 ppsi[i2]=&pMethod->GetUserProc();
713 }
714 i2++;
715 }
716 }
717
718 vtbl_offset=compiler.GetObjectModule().dataTable.AddBinary((void *)ppsi,GetVtblNum()*sizeof(LONG_PTR));
719
720 for( int i=0; i < GetVtblNum(); i++ ){
721 pobj_Reloc->AddSchedule_DataSection(vtbl_offset+i*sizeof(LONG_PTR));
722 }
723
724 free(ppsi);
725
726 return vtbl_offset;
727}
728void CClass::ActionVtblSchedule(LONG_PTR ImageBase, LONG_PTR MemPos_CodeSection){
729 if(vtbl_offset==-1) return;
730
731 LONG_PTR *pVtbl;
732 pVtbl=(LONG_PTR *)((char *)compiler.GetObjectModule().dataTable.GetPtr()+vtbl_offset);
733
734 int i;
735 for(i=0;i<GetVtblNum();i++){
736 UserProc *pUserProc;
737 pUserProc=(UserProc *)pVtbl[i];
738 if(!pUserProc) continue;
739
740 // 古いOpBufferを利用する場合は_beginOpAddressOldでないとダメ
741 //pVtbl[i]=pUserProc->_beginOpAddressOld+ImageBase+MemPos_CodeSection;
742 pVtbl[i]=pUserProc->GetBeginOpAddress()+ImageBase+MemPos_CodeSection;
743 }
744}
745bool CClass::IsAbstract() const
746{
747 // 未実装(abstract)の仮想関数を持つ場合はtrueを返す
748
749 BOOST_FOREACH( const CMethod *pMethod, methods ){
750 if(pMethod->IsVirtual()){
751 if(pMethod->IsAbstract()){
752 return true;
753 }
754 }
755 }
756
757 return false;
758}
759
760CClass *Classes::Create( const NamespaceScopes &namespaceScopes, const NamespaceScopesCollection &importedNamespaces, const char *name){
761 return new CClass(namespaceScopes, importedNamespaces, name);
762}
763bool Classes::Insert( CClass *pClass )
764{
765 // キャッシュしておくクラス
766 if( pClass->GetName() == "String" )
767 {
768 pStringClass=pClass;
769 }
770 else if( pClass->GetName() == "Object" )
771 {
772 pObjectClass = pClass;
773 }
774
775 /////////////////////////////////
776 // ハッシュデータに追加
777 /////////////////////////////////
778
779 if( !Put( pClass ) )
780 {
781 SetError(15,pClass->GetName(), cp);
782 return false;
783 }
784 return true;
785}
786CClass *Classes::Add( const NamespaceScopes &namespaceScopes, const NamespaceScopesCollection &importedNamespaces, const char *name,int nowLine){
787 //////////////////////////////////////////////////////////////////////////
788 // クラスを追加
789 // ※名前のみを登録。その他の情報はSetClassメソッドで!
790 //////////////////////////////////////////////////////////////////////////
791
792 CClass *pClass = Create(namespaceScopes, importedNamespaces, name);
793
794 if( !Insert( pClass ) )
795 {
796 return NULL;
797 }
798
799 return pClass;
800}
801
802void Classes::CollectClassesForNameOnly( const BasicSource &source )
803{
804 int i, i2;
805 char temporary[VN_SIZE];
806
807 // Blittable型管理オブジェクトを初期化
808 compiler.GetObjectModule().meta.GetBlittableTypes().clear();
809
810 // 名前空間管理
811 NamespaceScopes &namespaceScopes = compiler.GetNamespaceSupporter().GetLivingNamespaceScopes();
812 namespaceScopes.clear();
813
814 // Importsされた名前空間の管理
815 NamespaceScopesCollection &importedNamespaces = compiler.GetNamespaceSupporter().GetImportedNamespaces();
816 importedNamespaces.clear();
817
818 for(i=0;;i++){
819 if(source[i]=='\0') break;
820
821 if( source[i] == 1 && source[i+1] == ESC_NAMESPACE ){
822 for(i+=2,i2=0;;i2++,i++){
823 if( IsCommandDelimitation( source[i] ) ){
824 temporary[i2]=0;
825 break;
826 }
827 temporary[i2]=source[i];
828 }
829 namespaceScopes.push_back( temporary );
830
831 continue;
832 }
833 else if( source[i] == 1 && source[i+1] == ESC_ENDNAMESPACE ){
834 if( namespaceScopes.size() <= 0 ){
835 SmoothieException::Throw(12, "End Namespace", i );
836 }
837 else{
838 namespaceScopes.pop_back();
839 }
840
841 i += 2;
842 continue;
843 }
844 else if( source[i] == 1 && source[i+1] == ESC_IMPORTS ){
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 if( !compiler.GetNamespaceSupporter().ImportsNamespace( temporary ) )
853 {
854 SmoothieException::Throw(64,temporary,i );
855 }
856
857 continue;
858 }
859 else if( source[i] == 1 && source[i+1] == ESC_CLEARNAMESPACEIMPORTED ){
860 importedNamespaces.clear();
861 continue;
862 }
863
864 if(source[i]==1&&(
865 source[i+1]==ESC_CLASS||
866 source[i+1]==ESC_TYPE||
867 source[i+1]==ESC_INTERFACE
868 )){
869 int nowLine;
870 nowLine=i;
871
872 i+=2;
873 Type blittableType;
874 if(memicmp(source.GetBuffer()+i,"Align(",6)==0){
875 //アラインメント修飾子
876 i+=6;
877 i=JumpStringInPare(source.GetBuffer(),i)+1;
878 }
879 else if( memicmp( source.GetBuffer() + i, "Blittable(", 10 ) == 0 ){
880 // Blittable修飾子
881 i+=10;
882 i+=GetStringInPare_RemovePare(temporary,source.GetBuffer()+i)+1;
883 compiler.StringToType( temporary, blittableType );
884 }
885
886 bool isEnum = false;
887 if( source[i] == 1 && source[i+1] == ESC_ENUM ){
888 // 列挙型の場合
889 isEnum = true;
890
891 i+=2;
892 }
893
894 int i2;
895 char temporary[VN_SIZE];
896 for(i2=0;;i++,i2++){
897 if(!IsVariableChar(source[i])){
898 temporary[i2]=0;
899 break;
900 }
901 temporary[i2]=source[i];
902 }
903
904 //クラスを追加
905 CClass *pClass = this->Add(namespaceScopes, importedNamespaces, temporary,nowLine);
906 if( pClass ){
907 if( source[nowLine+1] == ESC_CLASS ){
908 if( isEnum ){
909 pClass->SetClassType( CClass::Enum );
910 }
911 else{
912 pClass->SetClassType( CClass::Class );
913 }
914 }
915 else if( source[nowLine+1] == ESC_INTERFACE ){
916 pClass->SetClassType( CClass::Interface );
917 }
918 else{
919 pClass->SetClassType( CClass::Structure );
920 }
921 }
922
923 // Blittable型の場合
924 if( !blittableType.IsNull() ){
925 pClass->SetBlittableType( blittableType );
926
927 // Blittable型として登録
928 compiler.GetObjectModule().meta.GetBlittableTypes().push_back( BlittableType( blittableType, pClass ) );
929 }
930 }
931 }
932}
933
934void Classes::ActionVtblSchedule(LONG_PTR ImageBase, LONG_PTR MemPos_CodeSection){
935 Iterator_Reset();
936 while( Iterator_HasNext() )
937 {
938 CClass *pClass = Iterator_GetNext();
939 pClass->ActionVtblSchedule(ImageBase,MemPos_CodeSection);
940 }
941}
942
943
944void Classes::InitStaticMember(){
945 //静的メンバをグローバル領域に作成
946
947 //イテレータをリセット
948
949 extern int cp;
950 int back_cp=cp;
951
952 this->Iterator_Reset();
953 while(this->Iterator_HasNext()){
954 CClass &objClass = *this->Iterator_GetNext();
955
956 // 名前空間をセット
957 compiler.GetNamespaceSupporter().GetLivingNamespaceScopes() = objClass.GetNamespaceScopes();
958
959 int i=0;
960 BOOST_FOREACH( CMember *member, objClass.GetStaticMembers() ){
961 char temporary[VN_SIZE];
962 sprintf(temporary,"%s.%s",objClass.GetName().c_str(),member->GetName().c_str());
963 dim(
964 temporary,
965 member->GetSubscripts(),
966 member->GetType(),
967 member->GetInitializeExpression().c_str(),
968 member->GetConstructParameter().c_str(),
969 0);
970
971 //ネイティブコードバッファの再確保
972 ReallocNativeCodeBuffer();
973
974 i++;
975 }
976 }
977
978 compiler.GetNamespaceSupporter().GetLivingNamespaceScopes().clear();
979
980 cp=back_cp;
981}
982bool Classes::MemberVar_LoopRefCheck(const CClass &objClass){
983 bool result = true;
984 BOOST_FOREACH( CMember *pMember, objClass.GetDynamicMembers() ){
985 if(pMember->GetType().IsStruct()){
986 //循環参照でないかをチェック
987 if(pobj_LoopRefCheck->check(pMember->GetType().GetClass())){
988 extern int cp;
989 SetError(124,pMember->GetType().GetClass().GetName(),cp);
990 return false;
991 }
992
993 pobj_LoopRefCheck->add(objClass.GetName().c_str());
994
995 bool tempResult = MemberVar_LoopRefCheck(pMember->GetType().GetClass());
996 if( result )
997 {
998 result = tempResult;
999 }
1000
1001 pobj_LoopRefCheck->del(objClass.GetName().c_str());
1002 }
1003 }
1004
1005 return result;
1006}
1007void Classes::GetClass_recur(const char *lpszInheritsClass){
1008 extern char *basbuf;
1009 int i,i2,i3,sub_address,top_pos;
1010 char temporary[8192];
1011
1012 // 名前空間管理
1013 NamespaceScopes backupNamespaceScopes = compiler.GetNamespaceSupporter().GetLivingNamespaceScopes();
1014 NamespaceScopes &namespaceScopes = compiler.GetNamespaceSupporter().GetLivingNamespaceScopes();
1015 namespaceScopes.clear();
1016
1017 for(i=0;;i++){
1018 if(basbuf[i]=='\0') break;
1019
1020
1021 // 名前空間
1022 if( basbuf[i] == 1 && basbuf[i+1] == ESC_NAMESPACE ){
1023 for(i+=2,i2=0;;i2++,i++){
1024 if( IsCommandDelimitation( basbuf[i] ) ){
1025 temporary[i2]=0;
1026 break;
1027 }
1028 temporary[i2]=basbuf[i];
1029 }
1030 namespaceScopes.push_back( temporary );
1031
1032 continue;
1033 }
1034 else if( basbuf[i] == 1 && basbuf[i+1] == ESC_ENDNAMESPACE ){
1035 if( namespaceScopes.size() <= 0 ){
1036 SetError(12, "End Namespace", i );
1037 }
1038 else{
1039 namespaceScopes.pop_back();
1040 }
1041
1042 i += 2;
1043 continue;
1044 }
1045
1046
1047
1048 if(basbuf[i]==1&&basbuf[i+1]==ESC_INTERFACE){
1049 //////////////////////////
1050 // インターフェイス
1051 //////////////////////////
1052
1053 top_pos=i;
1054
1055 i+=2;
1056
1057 //インターフェイス名を取得
1058 GetIdentifierToken( temporary, basbuf, i );
1059
1060 CClass *pobj_c = const_cast<CClass *>( this->Find(namespaceScopes, temporary) );
1061 if(!pobj_c) continue;
1062
1063 if(lpszInheritsClass){
1064 if(lstrcmp(lpszInheritsClass,pobj_c->GetName().c_str())!=0){
1065 //継承先先読み用
1066 continue;
1067 }
1068 }
1069
1070 if(pobj_c->IsReady()){
1071 //既に先読みされているとき
1072 continue;
1073 }
1074
1075 pobj_c->Readed();
1076
1077 pobj_c->SetConstructorMemberSubIndex( -1 );
1078 pobj_c->SetDestructorMemberSubIndex( -1 );
1079
1080 if(basbuf[i+1]==1&&basbuf[i+2]==ESC_INHERITS){
1081 //継承を行う場合
1082 for(i+=3,i2=0;;i++,i2++){
1083 if(IsCommandDelimitation(basbuf[i])){
1084 temporary[i2]=0;
1085 break;
1086 }
1087 temporary[i2]=basbuf[i];
1088 }
1089
1090 if(lstrcmpi(temporary,pobj_c->GetName().c_str())==0){
1091 SetError(105,temporary,i);
1092 goto Interface_InheritsError;
1093 }
1094
1095 //継承元クラスを取得
1096 const Classes &classes = *this;
1097 const CClass *pInheritsClass = classes.Find(temporary);
1098 if( !pInheritsClass ){
1099 SetError(106,temporary,i);
1100 goto Interface_InheritsError;
1101 }
1102
1103 //継承させる
1104 if( !pobj_c->InheritsClass( *pInheritsClass, i ) ){
1105 goto Interface_InheritsError;
1106 }
1107 }
1108 else{
1109 //継承無し
1110 if( &pobj_c->GetSuperClass() || pobj_c->GetVtblNum() )
1111 {
1112 // TODO: ここに来ないことが実証できたらこの分岐は消す
1113 Jenga::Throw( "GetClass_recur内の例外" );
1114 }
1115 }
1116Interface_InheritsError:
1117
1118 //メンバ変数、関数を取得
1119 while(1){
1120 i++;
1121
1122 //エラー
1123 if(basbuf[i]==1&&(basbuf[i+1]==ESC_CLASS||basbuf[i+1]==ESC_TYPE||basbuf[i+1]==ESC_INTERFACE)){
1124 SetError(22,"Interface",i);
1125 i--;
1126 break;
1127 }
1128
1129 if(basbuf[i]==1&&basbuf[i+1]==ESC_INHERITS){
1130 SetError(111,NULL,i);
1131 break;
1132 }
1133
1134 sub_address=i;
1135
1136 for(i2=0;;i++,i2++){
1137 if(IsCommandDelimitation(basbuf[i])){
1138 temporary[i2]=0;
1139 break;
1140 }
1141 temporary[i2]=basbuf[i];
1142 }
1143 if(temporary[0]=='\0'){
1144 if(basbuf[i]=='\0'){
1145 i--;
1146 SetError(22,"Interface",top_pos);
1147 break;
1148 }
1149 continue;
1150 }
1151
1152 //End Interface記述の場合
1153 if(temporary[0]==1&&temporary[1]==ESC_ENDINTERFACE) break;
1154
1155 if(!(temporary[0]==1&&(
1156 temporary[1]==ESC_SUB||temporary[1]==ESC_FUNCTION
1157 ))){
1158 SetError(1,NULL,i);
1159 break;
1160 }
1161
1162 //メンバ関数を追加
1163 pobj_c->AddMethod(pobj_c,
1164 Prototype::Public, //Publicアクセス権
1165 0, //Static指定なし
1166 false, //Constではない
1167 1, //Abstract
1168 1, //Virtual
1169 0,
1170 temporary,
1171 sub_address
1172 );
1173 }
1174 }
1175
1176 if(basbuf[i]==1&&(basbuf[i+1]==ESC_CLASS||basbuf[i+1]==ESC_TYPE)){
1177 //////////////////////////
1178 // クラス
1179 //////////////////////////
1180
1181 top_pos=i;
1182
1183 const DWORD dwClassType=basbuf[i+1];
1184
1185 i+=2;
1186
1187 int iAlign=0;
1188 if(memicmp(basbuf+i,"Align(",6)==0){
1189 //アラインメント修飾子
1190 i+=6;
1191 i+=GetStringInPare_RemovePare(temporary,basbuf+i)+1;
1192 iAlign=atoi(temporary);
1193
1194 if(!(iAlign==1||iAlign==2||iAlign==4||iAlign==8||iAlign==16))
1195 SetError(51,NULL,i);
1196 }
1197 else if( memicmp( basbuf + i, "Blittable(", 10 ) == 0 ){
1198 // Blittable修飾子
1199 i+=10;
1200 i=JumpStringInPare(basbuf,i)+1;
1201 }
1202
1203 if( basbuf[i] == 1 && basbuf[i+1] == ESC_ENUM ){
1204 // 列挙型の場合
1205 i+=2;
1206 }
1207
1208 //クラス名を取得
1209 GetIdentifierToken( temporary, basbuf, i );
1210
1211 CClass *pobj_c = const_cast<CClass *>( this->Find(namespaceScopes, temporary) );
1212 if(!pobj_c) continue;
1213
1214 if(lpszInheritsClass){
1215 if( pobj_c->GetName() != lpszInheritsClass ){
1216 //継承先先読み用
1217 continue;
1218 }
1219 }
1220
1221 if(pobj_c->IsReady()){
1222 //既に先読みされているとき
1223 continue;
1224 }
1225
1226 pobj_c->SetFixedAlignment( iAlign );
1227
1228 pobj_c->Readed();
1229
1230 pobj_c->SetConstructorMemberSubIndex( -1 );
1231 pobj_c->SetDestructorMemberSubIndex( -1 );
1232
1233 //アクセス制限の初期値をセット
1234 Prototype::Accessibility accessibility;
1235 if(dwClassType==ESC_CLASS){
1236 accessibility = Prototype::Private;
1237 }
1238 else{
1239 accessibility = Prototype::Public;
1240 }
1241
1242 if( pobj_c->GetName() == "Object" || dwClassType == ESC_TYPE ){
1243 if( &pobj_c->GetSuperClass() || pobj_c->GetVtblNum() )
1244 {
1245 // TODO: ここに来ないことが実証できたらこの分岐は消す
1246 Jenga::Throw( "GetClass_recur内の例外" );
1247 }
1248 }
1249 else{
1250 bool isInherits = false;
1251 if(basbuf[i+1]==1&&basbuf[i+2]==ESC_INHERITS){
1252 //継承を行う場合
1253 isInherits = true;
1254
1255 for(i+=3,i2=0;;i++,i2++){
1256 if(IsCommandDelimitation(basbuf[i])){
1257 temporary[i2]=0;
1258 break;
1259 }
1260 temporary[i2]=basbuf[i];
1261 }
1262
1263 if(lstrcmpi(temporary,pobj_c->GetName().c_str())==0){
1264 SetError(105,temporary,i);
1265 goto InheritsError;
1266 }
1267 }
1268
1269 if( !isInherits ){
1270 //Objectを継承する
1271 lstrcpy( temporary, "Object" );
1272 }
1273
1274 pobj_c->Inherits( temporary, i );
1275 }
1276InheritsError:
1277
1278 //メンバとメソッドを取得
1279 while(1){
1280 i++;
1281
1282 //エラー
1283 if(basbuf[i]==1&&(basbuf[i+1]==ESC_CLASS||basbuf[i+1]==ESC_TYPE)){
1284 SetError(22,"Class",i);
1285 i--;
1286 break;
1287 }
1288
1289 if(basbuf[i]==1&&basbuf[i+1]==ESC_INHERITS){
1290 SetError(111,NULL,i);
1291 break;
1292 }
1293
1294 //Static修飾子
1295 BOOL bStatic;
1296 if(basbuf[i]==1&&basbuf[i+1]==ESC_STATIC){
1297 bStatic=1;
1298 i+=2;
1299 }
1300 else bStatic=0;
1301
1302 //Const修飾子
1303 bool isConst = false;
1304 if( basbuf[i] == 1 && basbuf[i + 1] == ESC_CONST ){
1305 isConst = true;
1306 i += 2;
1307 }
1308
1309 if(basbuf[i]==1&&(
1310 basbuf[i+1]==ESC_ABSTRACT||basbuf[i+1]==ESC_VIRTUAL||basbuf[i+1]==ESC_OVERRIDE||
1311 basbuf[i+1]==ESC_SUB||basbuf[i+1]==ESC_FUNCTION
1312 )){
1313 i3=basbuf[i+1];
1314 sub_address=i;
1315 }
1316 else i3=0;
1317
1318 bool isVirtual = false, isAbstract = false, isOverride = false;
1319 if(i3==ESC_ABSTRACT){
1320 isAbstract=1;
1321 isVirtual=1;
1322 i+=2;
1323
1324 i3=basbuf[i+1];
1325 }
1326 else if(i3==ESC_VIRTUAL){
1327 isAbstract=0;
1328 isVirtual=1;
1329 i+=2;
1330
1331 i3=basbuf[i+1];
1332 }
1333 else if(i3==ESC_OVERRIDE){
1334 isOverride=1;
1335 isVirtual=1;
1336
1337 i+=2;
1338
1339 i3=basbuf[i+1];
1340 }
1341
1342 for(i2=0;;i++,i2++){
1343 if(IsCommandDelimitation(basbuf[i])){
1344 temporary[i2]=0;
1345 break;
1346 }
1347 temporary[i2]=basbuf[i];
1348 }
1349 if(temporary[0]=='\0'){
1350 if(basbuf[i]=='\0'){
1351
1352 if(dwClassType==ESC_CLASS)
1353 SetError(22,"Class",top_pos);
1354 else
1355 SetError(22,"Type",top_pos);
1356
1357 i--;
1358 break;
1359 }
1360 continue;
1361 }
1362
1363 //End Class記述の場合
1364 if(temporary[0]==1&&temporary[1]==ESC_ENDCLASS&&dwClassType==ESC_CLASS) break;
1365 if(temporary[0]==1&&temporary[1]==ESC_ENDTYPE&&dwClassType==ESC_TYPE) break;
1366
1367 //アクセスを変更
1368 if(lstrcmpi(temporary,"Private")==0){
1369 accessibility = Prototype::Private;
1370 continue;
1371 }
1372 if(lstrcmpi(temporary,"Public")==0){
1373 accessibility = Prototype::Public;
1374 continue;
1375 }
1376 if(lstrcmpi(temporary,"Protected")==0){
1377 accessibility = Prototype::Protected;
1378 continue;
1379 }
1380
1381 extern int cp;
1382 if(i3==0){
1383 if(bStatic){
1384 //静的メンバを追加
1385 cp=i; //エラー用
1386 pobj_c->AddStaticMember( accessibility, isConst, false, temporary, i);
1387 }
1388 else{
1389 //メンバを追加
1390 cp=i; //エラー用
1391 pobj_c->AddMember( accessibility, isConst, false, temporary, i );
1392
1393
1394 if(pobj_c->GetDynamicMembers()[pobj_c->GetDynamicMembers().size()-1]->GetType().IsStruct()){
1395 if( !pobj_c->GetDynamicMembers()[pobj_c->GetDynamicMembers().size()-1]->GetType().GetClass().IsReady() ){
1396 //参照先が読み取られていないとき
1397 GetClass_recur(pobj_c->GetDynamicMembers()[pobj_c->GetDynamicMembers().size()-1]->GetType().GetClass().GetName().c_str());
1398 }
1399 }
1400
1401
1402 if(pobj_c->GetDynamicMembers()[pobj_c->GetDynamicMembers().size()-1]->GetType().IsStruct()){
1403 //循環参照のチェック
1404 pobj_LoopRefCheck->add(pobj_c->GetName().c_str());
1405 if(!MemberVar_LoopRefCheck(pobj_c->GetDynamicMembers()[pobj_c->GetDynamicMembers().size()-1]->GetType().GetClass())){
1406 //エラー回避
1407 pobj_c->GetDynamicMembers()[pobj_c->GetDynamicMembers().size()-1]->GetType().SetBasicType( DEF_PTR_VOID );
1408 }
1409 pobj_LoopRefCheck->del(pobj_c->GetName().c_str());
1410 }
1411 }
1412 }
1413 else{
1414 //メソッドを追加
1415 cp=i; //エラー用
1416 pobj_c->AddMethod(pobj_c,
1417 accessibility,
1418 bStatic,
1419 isConst,
1420 isAbstract,
1421 isVirtual,
1422 isOverride,
1423 temporary,
1424 sub_address);
1425
1426 if( isAbstract ) continue;
1427
1428 for(;;i++){
1429 if(basbuf[i]=='\0'){
1430 i--;
1431 break;
1432 }
1433 if(basbuf[i-1]!='*'&&
1434 basbuf[i]==1&&(
1435 basbuf[i+1]==ESC_SUB||
1436 basbuf[i+1]==ESC_FUNCTION||
1437 basbuf[i+1]==ESC_MACRO||
1438 basbuf[i+1]==ESC_TYPE||
1439 basbuf[i+1]==ESC_CLASS||
1440 basbuf[i+1]==ESC_INTERFACE||
1441 basbuf[i+1]==ESC_ENUM)){
1442 GetDefaultNameFromES(i3,temporary);
1443 SetError(22,temporary,i);
1444 }
1445 if(basbuf[i]==1&&basbuf[i+1]==GetEndXXXCommand((char)i3)){
1446 i+=2;
1447 break;
1448 }
1449 }
1450 }
1451 }
1452 }
1453 }
1454
1455
1456 // 名前空間を元に戻す
1457 compiler.GetNamespaceSupporter().GetLivingNamespaceScopes() = backupNamespaceScopes;
1458}
1459void Classes::GetAllClassInfo(void){
1460 //ループ継承チェック用のクラス
1461 pobj_LoopRefCheck=new CLoopRefCheck();
1462
1463 //クラスを取得
1464 GetClass_recur(0);
1465
1466 delete pobj_LoopRefCheck;
1467 pobj_LoopRefCheck=0;
1468
1469 // イテレータの準備
1470 this->Iterator_Init();
1471}
1472void Classes::Compile_System_InitializeUserTypes(){
1473 char temporary[VN_SIZE];
1474
1475 ////////////////////////////////////////////////////////////////////
1476 // クラス登録
1477 ////////////////////////////////////////////////////////////////////
1478
1479 // イテレータをリセット
1480 Iterator_Reset();
1481
1482 while( Iterator_HasNext() ){
1483 const CClass &objClass = *Iterator_GetNext();
1484
1485 if( !objClass.IsUsing() ){
1486 // 未使用のクラスは無視する
1487 continue;
1488 }
1489
1490 char referenceOffsetsBuffer[1024] = "";
1491 int numOfReference = 0;
1492 BOOST_FOREACH( CMember *pMember, objClass.GetDynamicMembers() ){
1493 if( pMember->GetType().IsObject() || pMember->GetType().IsPointer() ){
1494 if( referenceOffsetsBuffer[0] ){
1495 lstrcat( referenceOffsetsBuffer, "," );
1496 }
1497
1498 sprintf( referenceOffsetsBuffer + lstrlen( referenceOffsetsBuffer ),
1499 "%d",
1500 objClass.GetMemberOffset( pMember->GetName().c_str() ) );
1501
1502 numOfReference++;
1503 }
1504 }
1505
1506 sprintf( temporary
1507 , "Add(%c%c_System_TypeForClass(\"%s\",\"%s\",[%s],%d))"
1508 , 1
1509 , ESC_NEW
1510 , "" // 名前空間 (TODO: 実装)
1511 , objClass.GetName().c_str() // クラス名
1512 , referenceOffsetsBuffer // 参照メンバオフセット配列
1513 , numOfReference // 参照メンバの個数
1514 );
1515
1516 // コンパイル
1517 ChangeOpcode( temporary );
1518
1519 // ネイティブコードバッファの再確保
1520 ReallocNativeCodeBuffer();
1521 }
1522
1523
1524 ////////////////////////////////////////////////////////////////////
1525 // 基底クラスを登録
1526 ////////////////////////////////////////////////////////////////////
1527
1528 sprintf(temporary, "%c%ctempType=Nothing%c%cTypeBaseImpl"
1529 , HIBYTE( COM_DIM )
1530 , LOBYTE( COM_DIM )
1531 , 1
1532 , ESC_AS
1533 );
1534 ChangeOpcode( temporary );
1535
1536 // イテレータをリセット
1537 Iterator_Reset();
1538
1539 while( Iterator_HasNext() ){
1540 const CClass &objClass = *Iterator_GetNext();
1541
1542 if( !objClass.IsUsing() ){
1543 // 未使用のクラスは無視する
1544 continue;
1545 }
1546
1547 if( objClass.HasSuperClass() ){
1548 sprintf( temporary
1549 , "tempType=Search(\"%s\",\"%s\")"
1550 , "" // 名前空間 (TODO: 実装)
1551 , objClass.GetName().c_str() // クラス名
1552 );
1553
1554 // コンパイル
1555 ChangeOpcode( temporary );
1556
1557 sprintf( temporary
1558 , "tempType.SetBaseType(Search(\"%s\",\"%s\"))"
1559 , "" // 名前空間 (TODO: 実装)
1560 , objClass.GetSuperClass().GetName().c_str() // 基底クラス名
1561 );
1562
1563 // コンパイル
1564 ChangeOpcode( temporary );
1565 }
1566
1567 // ネイティブコードバッファの再確保
1568 ReallocNativeCodeBuffer();
1569 }
1570
1571
1572
1573 ////////////////////////////////////////////////////////////////////
1574 // 継承関係登録
1575 ////////////////////////////////////////////////////////////////////
1576 // TODO: 未完成
1577 /*
1578
1579 // イテレータをリセット
1580 Iterator_Reset();
1581
1582 while( Iterator_HasNext() ){
1583 CClass *pClass = Iterator_GetNext();
1584
1585 sprintf( genBuffer + length
1586 , "obj.Search( \"%s\" ).SetBaseType( Search( \"%s\" ) ):"
1587 , "" // クラス名
1588 , pClass->name // クラス名
1589 );
1590 length += lstrlen( genBuffer + length );
1591
1592 while( length + 8192 > max ){
1593 max += 8192;
1594 genBuffer = (char *)realloc( genBuffer, max );
1595 }
1596 }*/
1597}
1598
1599const CClass *Classes::Find( const NamespaceScopes &namespaceScopes, const string &name ) const
1600{
1601 if( namespaceScopes.size() == 0 && name == "Object" ){
1602 return GetObjectClassPtr();
1603 }
1604 else if( namespaceScopes.size() == 0 && name == "String" ){
1605 return GetStringClassPtr();
1606 }
1607
1608 const CClass *pClass = GetHashArrayElement( name.c_str() );
1609 while( pClass )
1610 {
1611 if( pClass->IsEqualSymbol( namespaceScopes, name ) ){
1612 //名前空間とクラス名が一致した
1613 return pClass;
1614 }
1615 pClass = pClass->GetChainNext();
1616 }
1617
1618 // TypeDefも見る
1619 int index = compiler.GetObjectModule().meta.GetTypeDefs().GetIndex( namespaceScopes, name );
1620 if( index != -1 ){
1621 Type type = compiler.GetObjectModule().meta.GetTypeDefs()[index].GetBaseType();
1622 if( type.IsObject() ){
1623 return &type.GetClass();
1624 }
1625 }
1626
1627 return NULL;
1628}
1629const CClass *Classes::Find( const string &fullName ) const
1630{
1631 char AreaName[VN_SIZE] = ""; //オブジェクト変数
1632 char NestName[VN_SIZE] = ""; //入れ子メンバ
1633 bool isNest = SplitMemberName( fullName.c_str(), AreaName, NestName );
1634
1635 return Find( NamespaceScopes( AreaName ), NestName );
1636}
1637void Classes::StartCompile( const UserProc *pUserProc ){
1638 const CClass *pParentClass = pUserProc->GetParentClassPtr();
1639 if( pParentClass ){
1640 pParentClass->Using();
1641
1642 pCompilingMethod = pParentClass->GetMethods().GetMethodPtr( pUserProc );
1643 if( !pCompilingMethod ){
1644 pCompilingMethod = pParentClass->GetStaticMethods().GetMethodPtr( pUserProc );
1645 if( !pCompilingMethod ){
1646 SmoothieException::Throw(300);
1647 }
1648 }
1649 }
1650 else{
1651 pCompilingMethod = NULL;
1652 }
1653}
1654
1655CClass *Classes::GetStringClassPtr() const
1656{
1657 if( !pStringClass ){
1658 SmoothieException::Throw();
1659 return NULL;
1660 }
1661 return pStringClass;
1662}
1663CClass *Classes::GetObjectClassPtr() const
1664{
1665 if( !pObjectClass ){
1666 SmoothieException::Throw();
1667 return NULL;
1668 }
1669 return pObjectClass;
1670}
Note: See TracBrowser for help on using the repository browser.