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

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