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

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