00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include <iostream.h>
00016 #include <string.h>
00017 #include "token.h"
00018 #include "mop.h"
00019 #include "env.h"
00020 #include "ptree.h"
00021 #include "walker.h"
00022 #include "classwalk.h"
00023 #include "typeinfo.h"
00024 #include "encoding.h"
00025
00026 ClassArray* Class::class_list = nil;
00027 int Class::num_of_cmd_options = 0;
00028 char* Class::cmd_options[];
00029
00030 char* Class::metaclass_for_c_functions = nil;
00031 Class* Class::for_c_functions = nil;
00032
00033 Ptree* Class::class_t = new LeafReserved("class", 5);
00034 Ptree* Class::empty_block_t = new PtreeClassBody(new Leaf("{", 1),
00035 nil,
00036 new Leaf("}", 1));
00037 Ptree* Class::public_t = new LeafPUBLIC("public", 6);
00038 Ptree* Class::protected_t = new LeafPROTECTED("protected", 9);
00039 Ptree* Class::private_t = new LeafPRIVATE("private", 7);
00040 Ptree* Class::virtual_t = new LeafVIRTUAL("virtual", 7);
00041 Ptree* Class::colon_t = new Leaf(":", 1);
00042 Ptree* Class::comma_t = new Leaf(",", 1);
00043 Ptree* Class::semicolon_t = new Leaf(";", 1);
00044
00045
00046
00047 void Class::Construct(Environment* e, Ptree* name)
00048 {
00049 Ptree* def;
00050 Encoding encode;
00051
00052 encode.SimpleName(name);
00053 def = Ptree::List(name, nil, empty_block_t);
00054 def = new PtreeClassSpec(class_t, def, nil, encode.Get());
00055
00056 full_definition = def;
00057 definition = def;
00058 class_environment = nil;
00059 member_list = nil;
00060 done_decl_translation = FALSE;
00061 removed = FALSE;
00062 changed_member_list = nil;
00063 appended_member_list = nil;
00064 appended_code = nil;
00065 new_base_classes = def->Third();
00066 new_class_specifier = nil;
00067
00068 SetEnvironment(new Environment(e));
00069 }
00070
00071 void Class::InitializeInstance(Ptree* def, Ptree*)
00072 {
00073 full_definition = def;
00074 if(def->Car()->IsLeaf())
00075 definition = def;
00076 else
00077 definition = def->Cdr();
00078
00079 class_environment = nil;
00080 member_list = nil;
00081
00082 if(class_list == nil)
00083 class_list = new ClassArray;
00084
00085 class_list->Append(this);
00086
00087 done_decl_translation = FALSE;
00088 removed = FALSE;
00089 changed_member_list = nil;
00090 appended_member_list = nil;
00091 appended_code = nil;
00092 new_base_classes = definition->Third();
00093 new_class_specifier = nil;
00094 new_class_name = nil;
00095 }
00096
00097 Class::~Class() {}
00098
00099
00100
00101 char* Class::MetaclassName()
00102 {
00103 return "Class";
00104 }
00105
00106 Ptree* Class::Comments()
00107 {
00108 if (definition->IsA(ntClassSpec))
00109 return ((PtreeClassSpec*)definition)->GetComments();
00110 else
00111 return nil;
00112 }
00113
00114 Ptree* Class::Name()
00115 {
00116 return definition->Second();
00117 }
00118
00119 Ptree* Class::BaseClasses()
00120 {
00121 return definition->Third();
00122 }
00123
00124 Ptree* Class::Members()
00125 {
00126 return definition->Nth(3)->Second();
00127 }
00128
00129 Class* Class::NthBaseClass(int n)
00130 {
00131 Ptree* bases = definition->Third();
00132 while(bases != nil){
00133 bases = bases->Cdr();
00134 if(n-- == 0){
00135 Ptree* base_class = bases->Car()->Last()->Car();
00136 return class_environment->LookupClassMetaobject(base_class);
00137 }
00138
00139 bases = bases->Cdr();
00140 }
00141
00142 return nil;
00143 }
00144
00145 bool Class::IsSubclassOf(Ptree* name)
00146 {
00147 Ptree* bases = definition->Third();
00148 while(bases != nil){
00149 bases = bases->Cdr();
00150 Ptree* base_class = bases->Car()->Last()->Car();
00151 if(base_class->Eq(name))
00152 return TRUE;
00153 else{
00154 Class* metaobject
00155 = class_environment->LookupClassMetaobject(base_class);
00156 if(metaobject != nil && metaobject->IsSubclassOf(name))
00157 return TRUE;
00158 }
00159
00160 bases = bases->Cdr();
00161 }
00162
00163 return FALSE;
00164 }
00165
00166 bool Class::IsImmediateSubclassOf(Ptree* name)
00167 {
00168 Ptree* bases = definition->Third();
00169 while(bases != nil){
00170 bases = bases->Cdr();
00171 Ptree* base_class = bases->Car()->Last()->Car();
00172 if(base_class->Eq(name))
00173 return TRUE;
00174
00175 bases = bases->Cdr();
00176 }
00177
00178 return FALSE;
00179 }
00180
00181 Ptree* Class::NthBaseClassName(int n)
00182 {
00183 Ptree* bases = definition->Third();
00184 while(bases != nil){
00185 bases = bases->Cdr();
00186 if(n-- == 0)
00187 return bases->Car()->Last()->Car();
00188
00189 bases = bases->Cdr();
00190 }
00191
00192 return nil;
00193 }
00194
00195 bool Class::NthMember(int nth, Member& mem)
00196 {
00197 MemberList* mlist = GetMemberList();
00198 if(mlist == nil || nth >= mlist->Number())
00199 return FALSE;
00200
00201 mem.Set(this, mlist->Ref(nth)->declarator, nth);
00202 return TRUE;
00203 }
00204
00205 bool Class::LookupMember(Ptree* name)
00206 {
00207 Member m;
00208 return LookupMember(name, m);
00209 }
00210
00211 bool Class::LookupMember(Ptree* name, Member& mem, int index)
00212 {
00213 MemberList* mlist = GetMemberList();
00214 if(mlist == nil)
00215 return FALSE;
00216
00217 int nth = mlist->Lookup(class_environment, name, index);
00218 if(nth < 0)
00219 return FALSE;
00220
00221 mem.Set(this, mlist->Ref(nth)->declarator, nth);
00222 return TRUE;
00223 }
00224
00225 bool Class::LookupMember(char* name)
00226 {
00227 Member m;
00228 return LookupMember(name, m);
00229 }
00230
00231 bool Class::LookupMember(char* name, Member& mem, int index)
00232 {
00233 MemberList* mlist = GetMemberList();
00234 if(mlist == nil)
00235 return FALSE;
00236
00237 int nth = mlist->Lookup(class_environment, name, index);
00238 if(nth < 0)
00239 return FALSE;
00240
00241 mem.Set(this, mlist->Ref(nth)->declarator, nth);
00242 return TRUE;
00243 }
00244
00245 MemberList* Class::GetMemberList()
00246 {
00247 if(member_list == nil){
00248 member_list = new MemberList;
00249 member_list->Make(this);
00250 }
00251
00252 return member_list;
00253 }
00254
00255 ClassArray& Class::AllClasses()
00256 {
00257 return *class_list;
00258 }
00259
00260 int Class::Subclasses(ClassArray& subclasses)
00261 {
00262 return Subclasses(Name(), subclasses);
00263 }
00264
00265 int Class::Subclasses(Ptree* name, ClassArray& subclasses)
00266 {
00267 subclasses.Clear();
00268 if(class_list == nil)
00269 return 0;
00270
00271 uint n = class_list->Number();
00272 for(uint i = 0; i < n; ++i){
00273 Class* c = class_list->Ref(i);
00274 if(c->IsSubclassOf(name))
00275 subclasses.Append(c);
00276 }
00277
00278 return subclasses.Number();
00279 }
00280
00281 int Class::ImmediateSubclasses(ClassArray& subclasses)
00282 {
00283 return ImmediateSubclasses(Name(), subclasses);
00284 }
00285
00286 int Class::ImmediateSubclasses(Ptree* name, ClassArray& subclasses)
00287 {
00288 subclasses.Clear();
00289 if(class_list == nil)
00290 return 0;
00291
00292 uint n = class_list->Number();
00293 for(uint i = 0; i < n; ++i){
00294 Class* c = class_list->Ref(i);
00295 if(c->IsImmediateSubclassOf(name))
00296 subclasses.Append(c);
00297 }
00298
00299 return subclasses.Number();
00300 }
00301
00302 int Class::InstancesOf(char* name, ClassArray& classes)
00303 {
00304 classes.Clear();
00305 if(class_list == nil)
00306 return 0;
00307
00308 uint n = class_list->Number();
00309 for(uint i = 0; i < n; ++i){
00310 Class* c = class_list->Ref(i);
00311 if(strcmp(name, c->MetaclassName()) == 0)
00312 classes.Append(c);
00313 }
00314
00315 return classes.Number();
00316 }
00317
00318 Ptree* Class::NthMemberName(int nth)
00319 {
00320 Member m;
00321
00322 if(NthMember(nth, m))
00323 return m.Name();
00324 else
00325 return nil;
00326 }
00327
00328 int Class::IsMember(Ptree* name)
00329 {
00330 Member mem;
00331 if(LookupMember(name, mem, 0))
00332 return mem.Nth();
00333 else
00334 return -1;
00335 }
00336
00337 bool Class::LookupMemberType(Ptree* name, TypeInfo& mem_type)
00338 {
00339 return class_environment->Lookup(name, mem_type);
00340 }
00341
00342
00343
00344
00345 void Class::TranslateClass(Environment* e)
00346 {
00347 }
00348
00349
00350
00351
00352
00353
00354
00355 void Class::AddClassSpecifier(Ptree* spec)
00356 {
00357 new_class_specifier = spec;
00358 }
00359
00360 void Class::ChangeName(Ptree* name)
00361 {
00362 new_class_name = name;
00363 }
00364
00365 void Class::ChangeBaseClasses(Ptree* list)
00366 {
00367 CheckValidity("ChangeBaseClasses()");
00368 if(list->IsLeaf())
00369 list = Ptree::List(list);
00370
00371 new_base_classes = list;
00372 }
00373
00374 void Class::RemoveBaseClasses()
00375 {
00376 CheckValidity("RemoveBaseClasses()");
00377 new_base_classes = nil;
00378 }
00379
00380 void Class::AppendBaseClass(Class* c, int specifier, bool is_virtual)
00381 {
00382 AppendBaseClass(c->Name(), specifier, is_virtual);
00383 }
00384
00385 void Class::AppendBaseClass(char* name, int specifier, bool is_virtual)
00386 {
00387 AppendBaseClass(new Leaf(name, strlen(name)), specifier, is_virtual);
00388 }
00389
00390 void Class::AppendBaseClass(Ptree* name, int specifier, bool is_virtual)
00391 {
00392 CheckValidity("AppendBaseClass()");
00393
00394 Ptree* lf;
00395 switch(specifier){
00396 case Public :
00397 lf = public_t;
00398 break;
00399 case Protected :
00400 lf = protected_t;
00401 break;
00402 case Private :
00403 lf = private_t;
00404 break;
00405 default :
00406 MopErrorMessage("Class::AppendBaseClass()", "bad specifier");
00407 lf = nil;
00408 break;
00409 }
00410
00411 Ptree* super = Ptree::List(lf, name);
00412
00413 if(is_virtual)
00414 super = Ptree::Cons(virtual_t, super);
00415
00416 if(new_base_classes == nil)
00417 new_base_classes = Ptree::List(colon_t, super);
00418 else
00419 new_base_classes = Ptree::Append(new_base_classes,
00420 Ptree::List(comma_t, super));
00421 }
00422
00423 void Class::ChangeMember(Member& m)
00424 {
00425 CheckValidity("ChangeMember()");
00426
00427 if(changed_member_list == nil)
00428 changed_member_list = new ChangedMemberList;
00429
00430 changed_member_list->Append(&m, Undefined);
00431 }
00432
00433 void Class::AppendMember(Member& m, int access)
00434 {
00435 CheckValidity("AppendMember()");
00436 if(appended_member_list == nil)
00437 appended_member_list = new ChangedMemberList;
00438
00439 appended_member_list->Append(&m, access);
00440 }
00441
00442 void Class::AppendMember(Ptree* p)
00443 {
00444 CheckValidity("AppendMember()");
00445 appended_code = Ptree::Snoc(appended_code, p);
00446 }
00447
00448 void Class::RemoveMember(Member& m)
00449 {
00450 CheckValidity("RemoveMember()");
00451 m.Remove();
00452 ChangeMember(m);
00453 }
00454
00455 void Class::CheckValidity(char* name)
00456 {
00457 if(done_decl_translation)
00458 MopWarningMessage2(name, " is available only in TranslateClass().");
00459 }
00460
00461
00462
00463
00464 void Class::TranslateMemberFunction(Environment*, Member& m)
00465 {
00466 }
00467
00468 ChangedMemberList::Cmem* Class::GetChangedMember(Ptree* decl)
00469 {
00470 if(changed_member_list == nil)
00471 return nil;
00472 else
00473 return changed_member_list->Lookup(decl);
00474 }
00475
00476
00477
00478
00479
00480
00481 Ptree* Class::TranslateInitializer(Environment* env, Ptree*,
00482 Ptree* init)
00483 {
00484 if(init->Car()->Eq('('))
00485 return TranslateArguments(env, init);
00486 else{
00487 Ptree* exp = init->Second();
00488 Ptree* exp2 = TranslateExpression(env, exp);
00489 if(exp == exp2)
00490 return init;
00491 else
00492 return Ptree::List(init->Car(), exp2);
00493 }
00494 }
00495
00496 Ptree* Class::TranslateNew(Environment* env, Ptree* header,
00497 Ptree* op, Ptree* placement, Ptree* tname,
00498 Ptree* arglist)
00499 {
00500 Ptree* exp2;
00501
00502 if(header != nil && !header->Eq("::"))
00503 ErrorMessage(env, "unsupported user keyword: ", header, op);
00504
00505 Ptree* tname2 = TranslateNewType(env, tname);
00506 if(arglist == nil)
00507 exp2 = Ptree::List(TranslateArguments(env, placement), tname2);
00508 else
00509 exp2 = Ptree::List(TranslateArguments(env, placement), tname2,
00510 TranslateArguments(env, arglist));
00511
00512 if(header == nil)
00513 return new PtreeNewExpr(op, exp2);
00514 else
00515 return new PtreeNewExpr(header, Ptree::Cons(op, exp2));
00516 }
00517
00518 Ptree* Class::TranslateDelete(Environment* env, Ptree* op, Ptree* obj)
00519 {
00520 Ptree* obj2 = TranslateExpression(env, obj);
00521 return new PtreeDeleteExpr(op, Ptree::List(obj2));
00522 }
00523
00524 Ptree* Class::TranslateAssign(Environment* env, Ptree* left, Ptree* op,
00525 Ptree* right)
00526 {
00527 Ptree* left2 = TranslateExpression(env, left);
00528 Ptree* right2 = TranslateExpression(env, right);
00529 return new PtreeAssignExpr(left2, Ptree::List(op, right2));
00530 }
00531
00532 Ptree* Class::TranslateBinary(Environment* env, Ptree* lexpr, Ptree* op,
00533 Ptree* rexpr)
00534 {
00535 return new PtreeInfixExpr(TranslateExpression(env, lexpr),
00536 Ptree::List(op, TranslateExpression(env, rexpr)));
00537 }
00538
00539 Ptree* Class::TranslateUnary(Environment* env, Ptree* op, Ptree* object)
00540 {
00541 return new PtreeUnaryExpr(op, Ptree::List(TranslateExpression(env,
00542 object)));
00543 }
00544
00545 Ptree* Class::TranslateSubscript(Environment* env, Ptree* object,
00546 Ptree* index)
00547 {
00548 Ptree* object2 = TranslateExpression(env, object);
00549 Ptree* exp = index->Second();
00550 Ptree* exp2 = TranslateExpression(env, exp);
00551 if(exp == exp2)
00552 return new PtreeArrayExpr(object2, index);
00553 else
00554 return new PtreeArrayExpr(object2,
00555 Ptree::ShallowSubst(exp2, exp, index));
00556 }
00557
00558 Ptree* Class::TranslatePostfix(Environment* env, Ptree* object,
00559 Ptree* op)
00560 {
00561 return new PtreePostfixExpr(TranslateExpression(env, object),
00562 Ptree::List(op));
00563 }
00564
00565
00566
00567
00568 Ptree* Class::TranslateFunctionCall(Environment* env, Ptree* object,
00569 Ptree* arglist)
00570 {
00571 return new PtreeFuncallExpr(TranslateExpression(env, object),
00572 TranslateArguments(env, arglist));
00573 }
00574
00575 Ptree* Class::TranslateMemberCall(Environment* env, Ptree* object,
00576 Ptree* op, Ptree* member, Ptree* arglist)
00577 {
00578 Ptree* func;
00579
00580 object = TranslateExpression(env, object);
00581 func = Ptree::List(op, member);
00582 if(op->Eq('.'))
00583 func = new PtreeDotMemberExpr(object, func);
00584 else
00585 func = new PtreeArrowMemberExpr(object, func);
00586
00587 arglist = TranslateArguments(env, arglist);
00588 return new PtreeFuncallExpr(func, arglist);
00589 }
00590
00591 Ptree* Class::TranslateMemberCall(Environment* env,
00592 Ptree* member, Ptree* arglist)
00593 {
00594 return new PtreeFuncallExpr(member, TranslateArguments(env, arglist));
00595 }
00596
00597 Ptree* Class::TranslateMemberRead(Environment* env, Ptree* object,
00598 Ptree* op, Ptree* member)
00599 {
00600 object = TranslateExpression(env, object);
00601 Ptree* rest = Ptree::List(op, member);
00602 if(op->Eq('.'))
00603 return new PtreeDotMemberExpr(object, rest);
00604 else
00605 return new PtreeArrowMemberExpr(object, rest);
00606 }
00607
00608 Ptree* Class::TranslateMemberRead(Environment*, Ptree* member)
00609 {
00610 return member;
00611 }
00612
00613 Ptree* Class::TranslateMemberWrite(Environment* env, Ptree* object,
00614 Ptree* op, Ptree* member, Ptree* assign_op,
00615 Ptree* expr)
00616 {
00617
00618
00619
00620
00621
00622
00623 Ptree* left;
00624 object = TranslateExpression(env, object),
00625 left = Ptree::List(op, member);
00626 if(op->Eq('.'))
00627 left = new PtreeDotMemberExpr(object, left);
00628 else
00629 left = new PtreeArrowMemberExpr(object, left);
00630
00631 expr = TranslateExpression(env, expr);
00632 return new PtreeAssignExpr(left, Ptree::List(assign_op, expr));
00633 }
00634
00635 Ptree* Class::TranslateMemberWrite(Environment* env, Ptree* member,
00636 Ptree* assign_op, Ptree* expr)
00637 {
00638 return new PtreeAssignExpr(member,
00639 Ptree::List(assign_op,
00640 TranslateExpression(env, expr)));
00641 }
00642
00643 Ptree* Class::TranslateUnaryOnMember(Environment* env, Ptree* unary_op,
00644 Ptree* object, Ptree* access_op,
00645 Ptree* member_name)
00646 {
00647 Ptree* right;
00648 object = TranslateExpression(env, object),
00649 right = Ptree::List(access_op, member_name);
00650 if(access_op->Eq('.'))
00651 right = new PtreeDotMemberExpr(object, right);
00652 else
00653 right = new PtreeArrowMemberExpr(object, right);
00654
00655 return new PtreeUnaryExpr(unary_op, Ptree::List(right));
00656 }
00657
00658 Ptree* Class::TranslateUnaryOnMember(Environment*, Ptree* unary_op,
00659 Ptree* member_name)
00660 {
00661 return new PtreeUnaryExpr(unary_op, Ptree::List(member_name));
00662 }
00663
00664 Ptree* Class::TranslatePostfixOnMember(Environment* env,
00665 Ptree* object, Ptree* access_op,
00666 Ptree* member_name, Ptree* postfix_op)
00667 {
00668 Ptree* left;
00669 object = TranslateExpression(env, object),
00670 left = Ptree::List(access_op, member_name);
00671 if(access_op->Eq('.'))
00672 left = new PtreeDotMemberExpr(object, left);
00673 else
00674 left = new PtreeArrowMemberExpr(object, left);
00675
00676 return new PtreePostfixExpr(left, Ptree::List(postfix_op));
00677 }
00678
00679 Ptree* Class::TranslatePostfixOnMember(Environment*,
00680 Ptree* member_name, Ptree* postfix_op)
00681 {
00682 return new PtreePostfixExpr(member_name, Ptree::List(postfix_op));
00683 }
00684
00685 Ptree* Class::TranslatePointer(Environment*, Ptree* var_name)
00686 {
00687 return var_name;
00688 }
00689
00690 Ptree* Class::TranslateUserStatement(Environment* env, Ptree*,
00691 Ptree*,
00692 Ptree* keyword, Ptree*)
00693 {
00694 ErrorMessage(env, "unsupported user statement: ", keyword, keyword);
00695 return nil;
00696 }
00697
00698 Ptree* Class::TranslateStaticUserStatement(Environment* env,
00699 Ptree* keyword, Ptree*)
00700 {
00701 ErrorMessage(env, "unsupported user statement: ", keyword, keyword);
00702 return nil;
00703 }
00704
00705 Ptree* Class::StripClassQualifier(Ptree* qualified_name)
00706 {
00707 if(qualified_name->IsLeaf())
00708 return qualified_name;
00709 else
00710 return Ptree::First(Ptree::Last(qualified_name));
00711 }
00712
00713
00714
00715
00716 Ptree* Class::TranslateExpression(Environment* env, Ptree* exp)
00717 {
00718 if(exp == nil)
00719 return exp;
00720 else
00721 return env->GetWalker()->Translate(exp);
00722 }
00723
00724 Ptree* Class::TranslateExpression(Environment* env, Ptree* exp,
00725 TypeInfo& type)
00726 {
00727 if(exp == nil){
00728 type.Unknown();
00729 return exp;
00730 }
00731 else{
00732 env->GetWalker()->Typeof(exp, type);
00733 return env->GetWalker()->Translate(exp);
00734 }
00735 }
00736
00737 Ptree* Class::TranslateStatement(Environment* env, Ptree* exp)
00738 {
00739 WarnObsoleteness("Class::TranslateStatement()",
00740 "Class::TranslateExpression()");
00741 return TranslateExpression(env, exp);
00742 }
00743
00744 Ptree* Class::TranslateNewType(Environment* env, Ptree* type)
00745 {
00746 return env->GetWalker()->TranslateNew3(type);
00747 }
00748
00749 Ptree* Class::TranslateArguments(Environment* env, Ptree* arglist)
00750 {
00751 return env->GetWalker()->TranslateArguments(arglist);
00752 }
00753
00754 Ptree* Class::TranslateFunctionBody(Environment* env, Member& m, Ptree* body)
00755 {
00756 Walker* w = env->GetWalker();
00757 return w->RecordArgsAndTranslateFbody(this, m.ArgumentList(), body);
00758 }
00759
00760
00761
00762 void Class::SetEnvironment(Environment* e)
00763 {
00764 class_environment = e;
00765 e->SetMetaobject(this);
00766 }
00767
00768
00769
00770 bool Class::AcceptTemplate()
00771 {
00772 return FALSE;
00773
00774 }
00775
00776
00777
00778
00779
00780
00781 bool Class::Initialize()
00782 {
00783 return TRUE;
00784 }
00785
00786 void Class::FinalizeAll(ostream& out)
00787 {
00788 if(class_list == nil)
00789 return;
00790
00791 int n = class_list->Number();
00792 for(int i = 0; i < n; ++i){
00793 Class* c = class_list->Ref(i);
00794 if(c != nil){
00795 Ptree* p = c->FinalizeInstance();
00796 if(p != nil){
00797 p->Write(out);
00798 out << '\n';
00799 }
00800 }
00801 }
00802 }
00803
00804 Ptree* Class::FinalizeInstance()
00805 {
00806 return Finalize();
00807 }
00808
00809
00810
00811
00812
00813
00814
00815
00816 Ptree* Class::Finalize()
00817 {
00818 return nil;
00819 }
00820
00821 Ptree* Class::FinalizeClass()
00822 {
00823 return nil;
00824 }
00825
00826 void Class::RegisterNewModifier(char* str)
00827 {
00828 if(!Lex::RecordKeyword(str, UserKeyword))
00829 MopErrorMessage("Class::RegisterNewModifier()",
00830 "the keyword is already used.");
00831 }
00832
00833 void Class::RegisterNewAccessSpecifier(char* str)
00834 {
00835 if(!Lex::RecordKeyword(str, UserKeyword4))
00836 MopErrorMessage("Class::RegisterNewAccessSpecifier()",
00837 "the keyword is already used.");
00838 }
00839
00840 void Class::RegisterNewMemberModifier(char* str)
00841 {
00842 if(!Lex::RecordKeyword(str, UserKeyword5))
00843 MopErrorMessage("Class::RegisterNewMemberModifier()",
00844 "the keyword is already used.");
00845 }
00846
00847 void Class::RegisterNewWhileStatement(char* str)
00848 {
00849 if(!Lex::RecordKeyword(str, UserKeyword))
00850 MopErrorMessage("Class::RegisterNewWhileStatement()",
00851 "the keyword is already used.");
00852 }
00853
00854 void Class::RegisterNewForStatement(char* str)
00855 {
00856 if(!Lex::RecordKeyword(str, UserKeyword3))
00857 MopErrorMessage("Class::RegisterNewForStatement()",
00858 "the keyword is already used.");
00859 }
00860
00861 void Class::RegisterNewClosureStatement(char* str)
00862 {
00863 if(!Lex::RecordKeyword(str, UserKeyword2))
00864 MopErrorMessage("Class::RegisterNewClosureStatement()",
00865 "the keyword is already used.");
00866 }
00867
00868 void Class::RegisterMetaclass(char* keyword, char* class_name)
00869 {
00870 if(Lex::RecordKeyword(keyword, UserKeyword))
00871 if(Environment::RecordClasskeyword(keyword, class_name))
00872 return;
00873
00874 MopErrorMessage("Class::RegisterMetaclass()",
00875 "the keyword is already used.");
00876 }
00877
00878 void Class::ChangeDefaultMetaclass(char* name)
00879 {
00880 Walker::ChangeDefaultMetaclass(name);
00881 }
00882
00883 void Class::SetMetaclassForFunctions(char* name)
00884 {
00885 metaclass_for_c_functions = name;
00886 }
00887
00888 void Class::InsertBeforeStatement(Environment* env, Ptree* p)
00889 {
00890 Walker* w = env->GetWalker();
00891 if(w->IsClassWalker())
00892 ((ClassWalker*)w)->InsertBeforeStatement(p);
00893 else
00894 MopWarningMessage("Class::InsertBeforeStatement()",
00895 "cannot insert");
00896 }
00897
00898 void Class::AppendAfterStatement(Environment* env, Ptree* p)
00899 {
00900 Walker* w = env->GetWalker();
00901 if(w->IsClassWalker())
00902 ((ClassWalker*)w)->AppendAfterStatement(p);
00903 else
00904 MopWarningMessage("Class::AppendAfterStatement()",
00905 "cannot append");
00906 }
00907
00908 void Class::InsertBeforeToplevel(Environment* env, Class* c)
00909 {
00910 Walker* w = env->GetWalker();
00911 if(w->IsClassWalker())
00912 InsertBeforeToplevel(env, ((ClassWalker*)w)->ConstructClass(c));
00913 else
00914 MopWarningMessage("Class::InsertBeforeToplevel()",
00915 "cannot insert");
00916 }
00917
00918 void Class::InsertBeforeToplevel(Environment* env, Member& mem)
00919 {
00920 Walker* w = env->GetWalker();
00921 if(w->IsClassWalker()){
00922 ChangedMemberList::Cmem cmem;
00923 Member::Copy(&mem, &cmem);
00924 InsertBeforeToplevel(env, ((ClassWalker*)w)->ConstructMember(&cmem));
00925 }
00926 else
00927 MopWarningMessage("Class::InsertBeforeToplevel()",
00928 "cannot insert");
00929 }
00930
00931 void Class::InsertBeforeToplevel(Environment* env, Ptree* p)
00932 {
00933 Walker* w = env->GetWalker();
00934 if(w->IsClassWalker())
00935 ((ClassWalker*)w)->InsertBeforeToplevel(p);
00936 else
00937 MopWarningMessage("Class::InsertBeforeToplevel()",
00938 "cannot insert");
00939 }
00940
00941 void Class::AppendAfterToplevel(Environment* env, Class* c)
00942 {
00943 Walker* w = env->GetWalker();
00944 if(w->IsClassWalker())
00945 AppendAfterToplevel(env, ((ClassWalker*)w)->ConstructClass(c));
00946 else
00947 MopWarningMessage("Class::AppendAfterToplevel()",
00948 "cannot insert");
00949 }
00950
00951 void Class::AppendAfterToplevel(Environment* env, Member& mem)
00952 {
00953 Walker* w = env->GetWalker();
00954 if(w->IsClassWalker()){
00955 ChangedMemberList::Cmem cmem;
00956 Member::Copy(&mem, &cmem);
00957 AppendAfterToplevel(env, ((ClassWalker*)w)->ConstructMember(&cmem));
00958 }
00959 else
00960 MopWarningMessage("Class::AppendAfterToplevel()",
00961 "cannot insert");
00962 }
00963
00964 void Class::AppendAfterToplevel(Environment* env, Ptree* p)
00965 {
00966 Walker* w = env->GetWalker();
00967 if(w->IsClassWalker())
00968 ((ClassWalker*)w)->AppendAfterToplevel(p);
00969 else
00970 MopWarningMessage("Class::AppendAfterToplevel()",
00971 "cannot append");
00972 }
00973
00974 bool Class::InsertDeclaration(Environment* env, Ptree* decl)
00975 {
00976 return InsertDeclaration(env, decl, nil, nil);
00977 }
00978
00979 bool Class::InsertDeclaration(Environment* env, Ptree* decl,
00980 Ptree* key, void* client_data)
00981 {
00982 Walker* w = env->GetWalker();
00983 if(w->IsClassWalker())
00984 return ((ClassWalker*)w)->InsertDeclaration(decl, this, key,
00985 client_data);
00986 else{
00987 MopWarningMessage("Class::InsertDeclaration()",
00988 "cannot insert");
00989 return FALSE;
00990 }
00991 }
00992
00993 void* Class::LookupClientData(Environment* env, Ptree* key)
00994 {
00995 Walker* w = env->GetWalker();
00996 if(w->IsClassWalker())
00997 return ((ClassWalker*)w)->LookupClientData(this, key);
00998 else{
00999 MopWarningMessage("Class::LookupClientData()",
01000 "cannot lookup");
01001 return nil;
01002 }
01003 }
01004
01005 void Class::ErrorMessage(Environment* env, char* msg,
01006 Ptree* name, Ptree* where)
01007 {
01008 env->GetWalker()->ErrorMessage(msg, name, where);
01009 }
01010
01011 void Class::WarningMessage(Environment* env, char* msg,
01012 Ptree* name, Ptree* where)
01013 {
01014 env->GetWalker()->WarningMessage(msg, name, where);
01015 }
01016
01017 void Class::ErrorMessage(char* msg, Ptree* name, Ptree* where)
01018 {
01019 Walker::InaccurateErrorMessage(msg, name, where);
01020 }
01021
01022 void Class::WarningMessage(char* msg, Ptree* name, Ptree* where)
01023 {
01024 Walker::InaccurateWarningMessage(msg, name, where);
01025 }
01026
01027 bool Class::RecordCmdLineOption(char* key, char* value)
01028 {
01029 if(num_of_cmd_options < MaxOptions * 2){
01030 cmd_options[num_of_cmd_options++] = key;
01031 cmd_options[num_of_cmd_options++] = value;
01032 return TRUE;
01033 }
01034 else
01035 return FALSE;
01036 }
01037
01038 bool Class::LookupCmdLineOption(char* key)
01039 {
01040 char* value;
01041 return LookupCmdLineOption(key, value);
01042 }
01043
01044 bool Class::LookupCmdLineOption(char* key, char*& value)
01045 {
01046 for(int i = 0; i < num_of_cmd_options; i += 2)
01047 if(strcmp(key, cmd_options[i]) == 0){
01048 value = cmd_options[i + 1];
01049 return TRUE;
01050 }
01051
01052 return FALSE;
01053 }
01054
01055 void Class::WarnObsoleteness(char* func, char* alt)
01056 {
01057 MopWarningMessage2(func, " is obsolete.");
01058 MopMoreWarningMessage("use ", alt);
01059 }
01060
01061
01062
01063
01064 void TemplateClass::InitializeInstance(Ptree* def, Ptree* margs)
01065 {
01066 Class::InitializeInstance(GetClassInTemplate(def), margs);
01067 template_definition = def;
01068 }
01069
01070
01071
01072
01073 Ptree* TemplateClass::GetClassInTemplate(Ptree* def)
01074 {
01075 Ptree* decl = def->Ptree::Nth(4);
01076 if(decl == nil)
01077 return def;
01078
01079 Ptree* cdef = Walker::GetClassTemplateSpec(decl);
01080 if(cdef == nil)
01081 return def;
01082 else
01083 return cdef;
01084 }
01085
01086 bool TemplateClass::Initialize()
01087 {
01088 return TRUE;
01089 }
01090
01091 char* TemplateClass::MetaclassName()
01092 {
01093 return "TemplateClass";
01094 }
01095
01096 Ptree* TemplateClass::TemplateArguments()
01097 {
01098 return template_definition->Third();
01099 }
01100
01101 bool TemplateClass::AcceptTemplate()
01102 {
01103 return TRUE;
01104 }
01105
01106
01107
01108
01109 Ptree* TemplateClass::TranslateInstantiation(Environment*, Ptree* spec)
01110 {
01111 return spec;
01112 }
01113
01114
01115
01116 ClassArray::ClassArray(int s)
01117 {
01118 num = 0;
01119 if(s < 1)
01120 s = 1;
01121
01122 size = s;
01123 array = new (GC) Class*[s];
01124 }
01125
01126 void ClassArray::Append(Class* p)
01127 {
01128 if(num >= size){
01129 size += 16;
01130 Class** a = new (GC) Class*[size];
01131 memmove(a, array, size_t(num * sizeof(Class*)));
01132 array = a;
01133 }
01134
01135 array[num++] = p;
01136 }
01137
01138 Class*& ClassArray::Ref(uint i)
01139 {
01140 if(i < num)
01141 return array[i];
01142 else{
01143 MopErrorMessage("ClassArray", "out of range");
01144 return array[0];
01145 }
01146 }
01147
01148
01149
01150
01151
01152
01153 opcxx_ListOfMetaclass* opcxx_ListOfMetaclass::head = nil;
01154
01155 static Class* CreateClass(Ptree* def, Ptree* marg)
01156 {
01157 Class* metaobject = new Class;
01158 metaobject->InitializeInstance(def, marg);
01159 return metaobject;
01160 }
01161
01162 static opcxx_ListOfMetaclass classCreator("Class", CreateClass,
01163 Class::Initialize, nil);
01164
01165 opcxx_ListOfMetaclass* opcxx_init_Class()
01166 {
01167 return new opcxx_ListOfMetaclass("Class", CreateClass, Class::Initialize,
01168 nil);
01169 }
01170
01171 static Class* CreateTemplateClass(Ptree* def, Ptree* marg)
01172 {
01173 Class* metaobject = new TemplateClass;
01174 metaobject->InitializeInstance(def, marg);
01175 return metaobject;
01176 }
01177
01178 static opcxx_ListOfMetaclass templateCreator("TemplateClass",
01179 CreateTemplateClass,
01180 TemplateClass::Initialize,
01181 nil);
01182
01183 opcxx_ListOfMetaclass* opcxx_init_TemplateClass()
01184 {
01185 return new opcxx_ListOfMetaclass("TemplateClass", CreateTemplateClass,
01186 TemplateClass::Initialize, nil);
01187 }
01188
01189 opcxx_ListOfMetaclass::opcxx_ListOfMetaclass(char* n,
01190 opcxx_MetaclassCreator c,
01191 bool (*initialize)(),
01192 Ptree* (*fin)())
01193 {
01194 proc = c;
01195 name = n;
01196 if(AlreadyRecorded(n))
01197 next = nil;
01198 else{
01199 next = head;
01200 head = this;
01201 finalizer = fin;
01202 if(!initialize())
01203 MopErrorMessage("Initialize()",
01204 "the initialization process failed.");
01205 }
01206 }
01207
01208 Class* opcxx_ListOfMetaclass::New(Ptree* name, Ptree* def, Ptree* marg)
01209 {
01210 if(name != nil){
01211 opcxx_ListOfMetaclass* p = head;
01212 while(p != nil){
01213 if(name->Eq(p->name))
01214 return (*p->proc)(def, marg);
01215 else
01216 p = p->next;
01217 }
01218 }
01219
01220 return nil;
01221 }
01222
01223 Class* opcxx_ListOfMetaclass::New(char* name, Ptree* def, Ptree* marg)
01224 {
01225 if(name != nil){
01226 opcxx_ListOfMetaclass* p = head;
01227 while(p != nil){
01228 if(strcmp(name, p->name) == 0)
01229 return (*p->proc)(def, marg);
01230 else
01231 p = p->next;
01232 }
01233 }
01234
01235 return nil;
01236 }
01237
01238
01239
01240 void opcxx_ListOfMetaclass::FinalizeAll(ostream& out)
01241 {
01242 for(opcxx_ListOfMetaclass* p = head; p != nil; p = p->next)
01243 if(p->finalizer != nil){
01244 Ptree* code = (*p->finalizer)();
01245 if(code != nil){
01246 code->Write(out);
01247 out << '\n';
01248 }
01249 }
01250 }
01251
01252 bool opcxx_ListOfMetaclass::AlreadyRecorded(char* name)
01253 {
01254 for(opcxx_ListOfMetaclass* p = head; p != nil; p = p->next)
01255 if(strcmp(name, p->name) == 0)
01256 return TRUE;
01257
01258 return FALSE;
01259 }
01260
01261 bool opcxx_ListOfMetaclass::AlreadyRecorded(Ptree* name)
01262 {
01263 for(opcxx_ListOfMetaclass* p = head; p != nil; p = p->next)
01264 if(name->Eq(p->name))
01265 return TRUE;
01266
01267 return FALSE;
01268 }
01269
01270 void opcxx_ListOfMetaclass::PrintAllMetaclasses()
01271 {
01272 for(opcxx_ListOfMetaclass* p = head; p != nil; p = p->next)
01273 cout << p->name << '\n';
01274 }