Main Page   Namespace List   Class Hierarchy   Compound List   File List   Compound Members   File Members  

mop.cc

Go to the documentation of this file.
00001 /*
00002   Copyright (C) 1997-2001 Shigeru Chiba, Tokyo Institute of Technology.
00003 
00004   Permission to use, copy, distribute and modify this software and   
00005   its documentation for any purpose is hereby granted without fee,        
00006   provided that the above copyright notice appear in all copies and that 
00007   both that copyright notice and this permission notice appear in 
00008   supporting documentation.
00009 
00010   Shigeru Chiba makes no representations about the suitability of this 
00011   software for any purpose.  It is provided "as is" without express or
00012   implied warranty.
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 // class Class
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();        // if coming with a user keyword
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 // introspection
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();           // skip : or ,
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();           // skip : or ,
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();           // skip : or ,
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();           // skip : or ,
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 // translation of classes
00344 
00345 void Class::TranslateClass(Environment* e)
00346 {
00347 }
00348 
00349 /*
00350   The class specifier is inserted between the class keyword and
00351   the class name.  This is meaningless unless the compiler is MSVC++.
00352   e.g.
00353       class __declspec(dllexport) X { ... };
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;    // list should include ':'
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 // TranslateMemberFunction() is invoked only if the function is
00462 // implemented out of the class declaration (not inlined.)
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 // translation of expressions
00477 
00478 /*
00479   init is either "= <expression>" or "( <expression> )".
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    TranslateFunctionCall() is for the overloaded function call operator ().
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     // Note: If this function is invoked, TranslateAssign() on the
00618     // member does not work.  Suppose that the expression is p->m = 3.
00619     // Although TranslateMemberWrite() is invoked on p's class,
00620     // TranslateAssign() is not invoked on m's class.  This is a sort
00621     // of bug, but I don't know how to fix.
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 // utilities for translation
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 // others
00761 
00762 void Class::SetEnvironment(Environment* e)
00763 {
00764     class_environment = e;
00765     e->SetMetaobject(this);
00766 }
00767 
00768 // This metaobject cannot handle templates
00769 
00770 bool Class::AcceptTemplate()
00771 {
00772     return FALSE;       // Only the subclasses of TemplateClass can
00773                         // return true.
00774 }
00775 
00776 /*
00777   At the beginning, Initialize() is once called on each metaclass.
00778   The subclasses of Class may define their own Initialize().
00779   Initialize() returns FALSE if the initialization fails.
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   *Obsolete*
00811 
00812   Finalize() is called on each metaobject at the end.  The returned
00813   code is appended to the resulting file.  Note that Initialize()
00814   is called on each metaclass although Finalize() is on each metaobject.
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 // class TemplateClass
01063 
01064 void TemplateClass::InitializeInstance(Ptree* def, Ptree* margs)
01065 {
01066     Class::InitializeInstance(GetClassInTemplate(def), margs);
01067     template_definition = def;
01068 }
01069 
01070 /*
01071   This is needed because TemplateClass may be instantiated for a class.
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   Translate a template instantiation.
01108 */
01109 Ptree* TemplateClass::TranslateInstantiation(Environment*, Ptree* spec)
01110 {
01111     return spec;
01112 }
01113 
01114 // class ClassArray
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 // class opcxx_ListOfMetaclass  --- not documented class
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;         // the metaclass is not loaded.
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;         // the metaclass is not loaded.
01236 }
01237 
01238 // FinalizeAll() calls all FinalizeClass()s.
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 }

Generated on Mon Feb 10 17:32:51 2003 for VFiasco Semantics Compiler by doxygen1.2.15