00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "ptree.h"
00016 #include "classwalk.h"
00017 #include "cbodywalk.h"
00018 #include "mop.h"
00019 #include "env.h"
00020 #include "typeinfo.h"
00021 #include "member.h"
00022 #include "encoding.h"
00023
00024 Class* ClassWalker::GetClassMetaobject(TypeInfo& tinfo)
00025 {
00026 Class* c;
00027 if(tinfo.IsClass(c))
00028 return c;
00029 else if(tinfo.IsReferenceType()){
00030 tinfo.Dereference();
00031 if(tinfo.IsClass(c))
00032 return c;
00033 }
00034
00035 return nil;
00036 }
00037
00038 bool ClassWalker::IsClassWalker()
00039 {
00040 return TRUE;
00041 }
00042
00043 void ClassWalker::InsertBeforeStatement(Ptree* p)
00044 {
00045 before_statement.Append(p);
00046 }
00047
00048 void ClassWalker::AppendAfterStatement(Ptree* p)
00049 {
00050 after_statement.Append(p);
00051 }
00052
00053 void ClassWalker::InsertBeforeToplevel(Ptree* p)
00054 {
00055 before_toplevel.Append(p);
00056 }
00057
00058 void ClassWalker::AppendAfterToplevel(Ptree* p)
00059 {
00060 after_toplevel.Append(p);
00061 }
00062
00063 bool ClassWalker::InsertDeclaration(Ptree* d, Class* metaobject, Ptree* key,
00064 void* data)
00065 {
00066 inserted_declarations.Append(d);
00067 if(metaobject == nil || key == nil)
00068 return TRUE;
00069 else if(LookupClientData(metaobject, key))
00070 return FALSE;
00071 else{
00072 ClientDataLink* entry = new ClientDataLink;
00073 entry->next = client_data;
00074 entry->metaobject = metaobject;
00075 entry->key = key;
00076 entry->data = data;
00077 client_data = entry;
00078 return TRUE;
00079 }
00080 }
00081
00082 void* ClassWalker::LookupClientData(Class* metaobject, Ptree* key)
00083 {
00084 for(ClientDataLink* c = client_data; c != nil; c = c->next)
00085 if(c->metaobject == metaobject && Ptree::Eq(key, c->key))
00086 return c->data;
00087
00088 return nil;
00089 }
00090
00091 Ptree* ClassWalker::GetInsertedPtree()
00092 {
00093 Ptree* result = nil;
00094 if(before_toplevel.Number() > 0)
00095 result = Ptree::Nconc(result, before_toplevel.All());
00096
00097 if(inserted_declarations.Number() > 0)
00098 result = Ptree::Nconc(result, inserted_declarations.All());
00099
00100 if(before_statement.Number() > 0)
00101 result = Ptree::Nconc(result, before_statement.All());
00102
00103 before_statement.Clear();
00104 inserted_declarations.Clear();
00105 client_data = nil;
00106 before_toplevel.Clear();
00107 return result;
00108 }
00109
00110 Ptree* ClassWalker::GetAppendedPtree()
00111 {
00112 Ptree* result = nil;
00113 if(after_statement.Number() > 0)
00114 result = Ptree::Nconc(result, after_statement.All());
00115
00116 if(after_toplevel.Number() > 0)
00117 result = Ptree::Nconc(result, after_toplevel.All());
00118
00119 after_statement.Clear();
00120 after_toplevel.Clear();
00121 return result;
00122 }
00123
00124 Ptree* ClassWalker::TranslateMetaclassDecl(Ptree* decl)
00125 {
00126 env->RecordMetaclassName(decl);
00127 return nil;
00128 }
00129
00130 Ptree* ClassWalker::TranslateClassSpec(Ptree* spec, Ptree* userkey,
00131 Ptree* class_def, Class* metaobject)
00132 {
00133 if(metaobject != nil){
00134
00135 Ptree* bases = class_def->Third();
00136 PtreeArray* tspec_list = RecordMembers(class_def, bases, metaobject);
00137 metaobject->TranslateClass(env);
00138 metaobject->TranslateClassHasFinished();
00139 if(metaobject->removed)
00140 return nil;
00141
00142 ClassBodyWalker w(this, tspec_list);
00143 Ptree* body = class_def->Nth(3);
00144 Ptree* body2 = w.TranslateClassBody(body, class_def->Third(),
00145 metaobject);
00146 Ptree* bases2 = metaobject->GetBaseClasses();
00147 Ptree* cspec = metaobject->GetClassSpecifier();
00148 Ptree* name2 = metaobject->GetNewName();
00149 if(bases != bases2 || body != body2 || cspec != nil || name2 != nil){
00150 if(name2 == nil)
00151 name2 = class_def->Second();
00152
00153 Ptree* rest = Ptree::List(name2, bases2, body2);
00154 if(cspec != nil)
00155 rest = Ptree::Cons(cspec, rest);
00156 return new PtreeClassSpec(class_def->Car(), rest, nil,
00157 spec->GetEncodedName());
00158 }
00159 }
00160
00161 if(userkey == nil)
00162 return spec;
00163 else
00164 return new PtreeClassSpec(class_def->Car(), class_def->Cdr(),
00165 nil, spec->GetEncodedName());
00166 }
00167
00168 Ptree* ClassWalker::TranslateTemplateInstantiation(Ptree* inst_spec,
00169 Ptree* userkey, Ptree* class_spec, Class* metaobject)
00170 {
00171 Ptree* class_spec2;
00172 if (metaobject != nil && metaobject->AcceptTemplate()) {
00173 TemplateClass* tmetaobj = (TemplateClass*)metaobject;
00174 class_spec2 = tmetaobj->TranslateInstantiation(env, class_spec);
00175 if (class_spec != class_spec2)
00176 return class_spec2;
00177 }
00178 else
00179 class_spec2 = class_spec;
00180
00181 if(userkey == nil)
00182 return inst_spec;
00183 else if (class_spec == class_spec2)
00184 return inst_spec;
00185 else
00186 return new PtreeTemplateInstantiation(class_spec);
00187 }
00188
00189 Ptree* ClassWalker::ConstructClass(Class* metaobject)
00190 {
00191 Ptree* def = metaobject->Definition();
00192 Ptree* def2;
00193
00194 metaobject->TranslateClassHasFinished();
00195 ClassBodyWalker w(this, nil);
00196 Ptree* body = def->Nth(3);
00197 Ptree* body2 = w.TranslateClassBody(body, nil, metaobject);
00198 Ptree* bases2 = metaobject->GetBaseClasses();
00199 Ptree* cspec2 = metaobject->GetClassSpecifier();
00200 Ptree* name2 = metaobject->GetNewName();
00201 if(body == body2 && bases2 == nil && cspec2 == nil && name2 == nil)
00202 def2 = def;
00203 else{
00204 if(name2 == nil)
00205 name2 = def->Second();
00206
00207 Ptree* rest = Ptree::List(name2, bases2, body2);
00208 if(cspec2 != nil)
00209 rest = Ptree::Cons(cspec2, rest);
00210
00211 def2 = new PtreeClassSpec(def->Car(), rest,
00212 nil, def->GetEncodedName());
00213 }
00214
00215 return new PtreeDeclaration(nil, Ptree::List(def2, Class::semicolon_t));
00216 }
00217
00218 PtreeArray* ClassWalker::RecordMembers(Ptree* class_def, Ptree* bases,
00219 Class* metaobject)
00220 {
00221 Ptree *tspec, *tspec2;
00222
00223 NewScope(metaobject);
00224 RecordBaseclassEnv(bases);
00225
00226 PtreeArray* tspec_list = new PtreeArray();
00227
00228 Ptree* rest = class_def->Nth(3)->Second();
00229 while(rest != nil){
00230 Ptree* mem = rest->Car();
00231 switch(mem->What()){
00232 case ntTypedef :
00233 tspec = mem->Second();
00234 tspec2 = TranslateTypespecifier(tspec);
00235 env->RecordTypedefName(mem->Third());
00236 if(tspec != tspec2){
00237 tspec_list->Append(tspec);
00238 tspec_list->Append(tspec2);
00239 }
00240
00241 break;
00242 case ntMetaclassDecl :
00243 env->RecordMetaclassName(mem);
00244 break;
00245 case ntDeclaration :
00246 RecordMemberDeclaration(mem, tspec_list);
00247 break;
00248 case ntTemplateDecl :
00249 case ntTemplateInstantiation :
00250 case ntUsing :
00251 default :
00252 break;
00253 }
00254
00255 rest = rest->Cdr();
00256 }
00257
00258 if(tspec_list->Number() == 0){
00259 delete tspec_list;
00260 tspec_list = nil;
00261 }
00262
00263 ExitScope();
00264 return tspec_list;
00265 }
00266
00267
00268
00269 void ClassWalker::RecordMemberDeclaration(Ptree* mem,
00270 PtreeArray* tspec_list)
00271 {
00272 Ptree *tspec, *tspec2, *decls;
00273
00274 tspec = mem->Second();
00275 tspec2 = TranslateTypespecifier(tspec);
00276 decls = mem->Third();
00277 if(decls->IsA(ntDeclarator))
00278 env->RecordDeclarator(decls);
00279 else if(!decls->IsLeaf())
00280 while(decls != nil){
00281 Ptree* d = decls->Car();
00282 if(d->IsA(ntDeclarator))
00283 env->RecordDeclarator(d);
00284
00285 decls = decls->Cdr();
00286 if(decls != nil)
00287 decls = decls->Cdr();
00288 }
00289
00290 if(tspec != tspec2){
00291 tspec_list->Append(tspec);
00292 tspec_list->Append(tspec2);
00293 }
00294 }
00295
00296 Ptree* ClassWalker::ConstructAccessSpecifier(int access)
00297 {
00298 Ptree* lf;
00299 switch(access){
00300 case Class::Protected :
00301 lf = Class::protected_t;
00302 break;
00303 case Class::Private :
00304 lf = Class::private_t;
00305 break;
00306 case Class::Public :
00307 default :
00308 lf = Class::public_t;
00309 break;
00310 }
00311
00312 return new PtreeAccessSpec(lf, Ptree::List(Class::colon_t));
00313 }
00314
00315 Ptree* ClassWalker::ConstructMember(void* ptr)
00316 {
00317 ChangedMemberList::Cmem* m = (ChangedMemberList::Cmem*)ptr;
00318 Ptree* def = m->def;
00319 Ptree* def2;
00320
00321 if(def->Third()->IsA(ntDeclarator)){
00322
00323 if(m->body == nil){
00324 NameScope old_env;
00325 Environment* fenv = env->DontRecordDeclarator(m->declarator);
00326 if(fenv != nil)
00327 old_env = ChangeScope(fenv);
00328
00329 NewScope();
00330 def2 = MakeMemberDeclarator(TRUE, m,
00331 (PtreeDeclarator*)m->declarator);
00332 def2 = Ptree::List(def2,
00333 TranslateFunctionBody(def->Nth(3)));
00334 ExitScope();
00335 if(fenv != nil)
00336 RestoreScope(old_env);
00337 }
00338 else{
00339 def2 = MakeMemberDeclarator(FALSE, m,
00340 (PtreeDeclarator*)m->declarator);
00341 def2 = Ptree::List(def2, m->body);
00342 }
00343 }
00344 else{
00345
00346 def2 = MakeMemberDeclarator(FALSE, m,
00347 (PtreeDeclarator*)m->declarator);
00348 if(m->body == nil)
00349 def2 = Ptree::List(Ptree::List(def2), Class::semicolon_t);
00350 else
00351 def2 = Ptree::List(def2, m->body);
00352 }
00353
00354 def2 = new PtreeDeclaration(
00355 TranslateStorageSpecifiers(def->First()),
00356 Ptree::Cons(TranslateTypespecifier(def->Second()),
00357 def2));
00358 return def2;
00359 }
00360
00361 Ptree* ClassWalker::TranslateStorageSpecifiers(Ptree* spec)
00362 {
00363 return TranslateStorageSpecifiers2(spec);
00364 }
00365
00366 Ptree* ClassWalker::TranslateStorageSpecifiers2(Ptree* rest)
00367 {
00368 if(rest == nil)
00369 return nil;
00370 else{
00371 Ptree* h = rest->Car();
00372 Ptree* t = rest->Cdr();
00373 Ptree* t2 = TranslateStorageSpecifiers2(t);
00374 if(h->IsA(ntUserdefKeyword))
00375 return t2;
00376 else if(t == t2)
00377 return rest;
00378 else
00379 return Ptree::Cons(h, t2);
00380 }
00381 }
00382
00383 Ptree* ClassWalker::TranslateTemplateFunction(Ptree* temp_def, Ptree* impl)
00384 {
00385 Environment* fenv = env->RecordTemplateFunction(temp_def, impl);
00386 if (fenv != nil) {
00387 Class* metaobject = fenv->IsClassEnvironment();
00388 if(metaobject != nil){
00389 NameScope old_env = ChangeScope(fenv);
00390 NewScope();
00391
00392 ChangedMemberList::Cmem m;
00393 Ptree* decl = impl->Third();
00394 MemberFunction mem(metaobject, impl, decl);
00395 metaobject->TranslateMemberFunction(env, mem);
00396 ChangedMemberList::Copy(&mem, &m, Class::Undefined);
00397 Ptree* decl2
00398 = MakeMemberDeclarator(TRUE, &m, (PtreeDeclarator*)decl);
00399
00400 ExitScope();
00401 RestoreScope(old_env);
00402 if(decl != decl2) {
00403 Ptree* pt = Ptree::List(impl->Second(), decl2, impl->Nth(3));
00404 pt = new PtreeDeclaration(impl->First(), pt);
00405 pt = Ptree::List(temp_def->Second(), temp_def->Third(),
00406 temp_def->Nth(3), pt);
00407 return new PtreeTemplateDecl(temp_def->First(), pt);
00408 }
00409 }
00410 }
00411
00412 return temp_def;
00413 }
00414
00415 Ptree* ClassWalker::TranslateFunctionImplementation(Ptree* impl)
00416 {
00417 Ptree* sspec = impl->First();
00418 Ptree* sspec2 = TranslateStorageSpecifiers(sspec);
00419 Ptree* tspec = impl->Second();
00420 Ptree* decl = impl->Third();
00421 Ptree* body = impl->Nth(3);
00422 Ptree* decl2;
00423 Ptree *body2;
00424
00425 Ptree* tspec2 = TranslateTypespecifier(tspec);
00426 Environment* fenv = env->RecordDeclarator(decl);
00427
00428 if(fenv == nil){
00429
00430 NewScope();
00431 decl2 = TranslateDeclarator(TRUE, (PtreeDeclarator*)decl);
00432 body2 = TranslateFunctionBody(body);
00433 ExitScope();
00434 }
00435 else{
00436 Class* metaobject = fenv->IsClassEnvironment();
00437 NameScope old_env = ChangeScope(fenv);
00438 NewScope();
00439
00440 if (metaobject == nil && Class::metaclass_for_c_functions != nil)
00441 metaobject = MakeMetaobjectForCfunctions();
00442
00443 if(metaobject == nil){
00444 decl2 = TranslateDeclarator(TRUE, (PtreeDeclarator*)decl);
00445 body2 = TranslateFunctionBody(body);
00446 }
00447 else{
00448 ChangedMemberList::Cmem m;
00449 MemberFunction mem(metaobject, impl, decl);
00450 metaobject->TranslateMemberFunction(env, mem);
00451 ChangedMemberList::Copy(&mem, &m, Class::Undefined);
00452 decl2 = MakeMemberDeclarator(TRUE, &m, (PtreeDeclarator*)decl);
00453 if(m.body != nil)
00454 body2 = m.body;
00455 else
00456 body2 = TranslateFunctionBody(body);
00457 }
00458
00459 ExitScope();
00460 RestoreScope(old_env);
00461 }
00462
00463 if(sspec == sspec2 && tspec == tspec2 && decl == decl2 && body == body2)
00464 return impl;
00465 else
00466 return new PtreeDeclaration(sspec2,
00467 Ptree::List(tspec2, decl2, body2));
00468 }
00469
00470 Class* ClassWalker::MakeMetaobjectForCfunctions() {
00471 if (Class::for_c_functions == nil) {
00472 Encoding encode;
00473 Ptree* name = new Leaf("<C>", 3);
00474 encode.SimpleName(name);
00475 Ptree* class_def
00476 = new PtreeClassSpec(Class::class_t,
00477 Ptree::List(name, nil,
00478 Class::empty_block_t),
00479 nil, encode.Get());
00480
00481 Class* metaobject = opcxx_ListOfMetaclass::New(
00482 Class::metaclass_for_c_functions,
00483 class_def, nil);
00484 if(metaobject == nil)
00485 MopErrorMessage2(
00486 "the metaclass for C functions cannot be loaded: ",
00487 Class::metaclass_for_c_functions);
00488
00489 metaobject->SetEnvironment(env);
00490 Class::for_c_functions = metaobject;
00491 }
00492
00493 return Class::for_c_functions;
00494 }
00495
00496 Ptree* ClassWalker::MakeMemberDeclarator(bool record, void* ptr,
00497 PtreeDeclarator* decl)
00498 {
00499 Ptree *args, *args2, *name, *name2, *init, *init2;
00500
00501
00502
00503
00504
00505 ChangedMemberList::Cmem* m = (ChangedMemberList::Cmem*)ptr;
00506
00507 if(m->removed)
00508 return nil;
00509
00510 if(GetArgDeclList(decl, args))
00511 if(m->args == nil)
00512 args2 = TranslateArgDeclList2(record, env, TRUE,
00513 m->arg_name_filled, 0, args);
00514 else{
00515 args2 = m->args;
00516
00517 TranslateArgDeclList2(record, env, FALSE, FALSE, 0, args);
00518 }
00519 else
00520 args = args2 = nil;
00521
00522 name = decl->Name();
00523 if(m->name != nil)
00524 name2 = m->name;
00525 else
00526 name2 = name;
00527
00528 if(m->init == nil)
00529 init = init2 = nil;
00530 else{
00531 init2 = m->init;
00532 init = decl->Last()->Car();
00533 if(init->IsLeaf() || !init->Car()->Eq(':'))
00534 init = nil;
00535 }
00536
00537 if(args == args2 && name == name2 && init == init2)
00538 return decl;
00539 else{
00540 Ptree* rest;
00541 if(init == nil && init2 != nil){
00542 rest = Ptree::Subst(args2, args, name2, name, decl->Cdr());
00543 rest = Ptree::Append(rest, init2);
00544 }
00545 else
00546 rest = Ptree::Subst(args2, args, name2, name,
00547 init2, init, decl->Cdr());
00548
00549 if(decl->Car() == name)
00550 return new PtreeDeclarator(decl, name2, rest);
00551 else
00552 return new PtreeDeclarator(decl, decl->Car(), rest);
00553 }
00554 }
00555
00556 Ptree* ClassWalker::RecordArgsAndTranslateFbody(Class* c, Ptree* args,
00557 Ptree* body)
00558 {
00559 NameScope old_env;
00560 Environment* fenv = c->GetEnvironment();
00561
00562 if(fenv != nil)
00563 old_env = ChangeScope(fenv);
00564
00565 NewScope();
00566 TranslateArgDeclList2(TRUE, env, FALSE, FALSE, 0, args);
00567 Ptree* body2 = TranslateFunctionBody(body);
00568 ExitScope();
00569
00570 if(fenv != nil)
00571 RestoreScope(old_env);
00572
00573 return body2;
00574 }
00575
00576 Ptree* ClassWalker::TranslateFunctionBody(Ptree* body)
00577 {
00578 Ptree* body2;
00579
00580 inserted_declarations.Clear();
00581 client_data = nil;
00582 body = Translate(body);
00583 if(body == nil || body->IsLeaf() || inserted_declarations.Number() <= 0)
00584 body2 = body;
00585 else{
00586 Ptree* decls = inserted_declarations.All();
00587 body2 = new PtreeBlock(Ptree::First(body),
00588 Ptree::Nconc(decls, Ptree::Second(body)),
00589 Ptree::Third(body));
00590 }
00591
00592 inserted_declarations.Clear();
00593 client_data = nil;
00594 return body2;
00595 }
00596
00597 Ptree* ClassWalker::TranslateBlock(Ptree* block)
00598 {
00599 Ptree* block2;
00600
00601 NewScope();
00602
00603 PtreeArray array;
00604 bool changed = FALSE;
00605 Ptree* body = Ptree::Second(block);
00606 Ptree* rest = body;
00607 while(rest != nil){
00608 uint i, n;
00609 Ptree* p = rest->Car();
00610 Ptree* q = Translate(p);
00611
00612 n = before_statement.Number();
00613 if(n > 0){
00614 changed = TRUE;
00615 for(i = 0; i < n; ++i)
00616 array.Append(before_statement[i]);
00617 }
00618
00619 array.Append(q);
00620 if(p != q)
00621 changed = TRUE;
00622
00623 n = after_statement.Number();
00624 if(n > 0){
00625 changed = TRUE;
00626 for(i = 0; i < n; ++i)
00627 array.Append(after_statement[i]);
00628 }
00629
00630 before_statement.Clear();
00631 after_statement.Clear();
00632 rest = rest->Cdr();
00633 }
00634
00635 if(changed)
00636 block2 = new PtreeBlock(Ptree::First(block), array.All(),
00637 Ptree::Third(block));
00638 else
00639 block2 = block;
00640
00641 ExitScope();
00642 return block2;
00643 }
00644
00645 Ptree* ClassWalker::TranslateArgDeclList(bool record, Ptree*, Ptree* args)
00646 {
00647 return TranslateArgDeclList2(record, env, TRUE, FALSE, 0, args);
00648 }
00649
00650 Ptree* ClassWalker::TranslateInitializeArgs(PtreeDeclarator* decl, Ptree* init)
00651 {
00652 TypeInfo tinfo;
00653 env->Lookup(decl, tinfo);
00654 Class* metaobject = tinfo.ClassMetaobject();
00655 if(metaobject != nil)
00656 return metaobject->TranslateInitializer(env, decl->Name(), init);
00657 else
00658 return TranslateArguments(init);
00659 }
00660
00661 Ptree* ClassWalker::TranslateAssignInitializer(PtreeDeclarator* decl,
00662 Ptree* init)
00663 {
00664 TypeInfo tinfo;
00665 env->Lookup(decl, tinfo);
00666 Class* metaobject = tinfo.ClassMetaobject();
00667 if(metaobject != nil)
00668 return metaobject->TranslateInitializer(env, decl->Name(), init);
00669 else{
00670 Ptree* exp = init->Second();
00671 Ptree* exp2 = Translate(exp);
00672 if(exp == exp2)
00673 return init;
00674 else
00675 return Ptree::List(init->Car(), exp2);
00676 }
00677 }
00678
00679 Ptree* ClassWalker::TranslateUserAccessSpec(Ptree*)
00680 {
00681 return nil;
00682 }
00683
00684 Ptree* ClassWalker::TranslateAssign(Ptree* exp)
00685 {
00686 Ptree *left, *left2, *right, *right2, *exp2;
00687 Environment* scope;
00688 Class* metaobject;
00689 TypeInfo type;
00690
00691 left = exp->First();
00692 right = exp->Third();
00693 if(left->IsA(ntDotMemberExpr, ntArrowMemberExpr)){
00694 Ptree* object = left->First();
00695 Ptree* op = left->Second();
00696 Ptree* member = left->Third();
00697 Ptree* assign_op = exp->Second();
00698 Typeof(object, type);
00699 if(!op->Eq('.'))
00700 type.Dereference();
00701
00702 metaobject = GetClassMetaobject(type);
00703 if(metaobject != nil){
00704 exp2 = metaobject->TranslateMemberWrite(env, object, op,
00705 member, assign_op, right);
00706 return CheckMemberEquiv(exp, exp2);
00707 }
00708 }
00709 else if((scope = env->IsMember(left)) != nil){
00710 metaobject = scope->IsClassEnvironment();
00711 if(metaobject != nil){
00712 exp2 = metaobject->TranslateMemberWrite(env, left, exp->Second(),
00713 right);
00714 return CheckEquiv(exp, exp2);
00715 }
00716 }
00717 else{
00718 Typeof(left, type);
00719 metaobject = GetClassMetaobject(type);
00720 if(metaobject != nil){
00721 exp2 = metaobject->TranslateAssign(env, left, exp->Second(),
00722 right);
00723 return CheckEquiv(exp, exp2);
00724 }
00725 }
00726
00727 left2 = Translate(left);
00728 right2 = Translate(right);
00729 if(left == left2 && right == right2)
00730 return exp;
00731 else
00732 return new PtreeAssignExpr(left2, Ptree::List(exp->Second(), right2));
00733 }
00734
00735 Ptree* ClassWalker::CheckMemberEquiv(Ptree* exp, Ptree* exp2)
00736 {
00737 if(!exp2->IsLeaf()
00738 && Ptree::Equiv(exp->Car(), exp2->Car())
00739 && Ptree::Equiv(exp->Cdr(), exp2->Cdr()))
00740 return exp;
00741 else
00742 return exp2;
00743 }
00744
00745 Ptree* ClassWalker::TranslateInfix(Ptree* exp)
00746 {
00747 TypeInfo type;
00748
00749 Ptree* left = exp->First();
00750 Ptree* right = exp->Third();
00751 Typeof(right, type);
00752 Class* metaobject = GetClassMetaobject(type);
00753 if(metaobject == nil){
00754 Typeof(left, type);
00755 metaobject = GetClassMetaobject(type);
00756 }
00757
00758 if(metaobject != nil){
00759 Ptree* exp2 = metaobject->TranslateBinary(env, left, exp->Second(),
00760 right);
00761 return CheckEquiv(exp, exp2);
00762 }
00763 else{
00764 Ptree* left2 = Translate(left);
00765 Ptree* right2 = Translate(right);
00766 if(left == left2 && right == right2)
00767 return exp;
00768 else
00769 return new PtreeInfixExpr(left2, Ptree::List(exp->Second(),
00770 right2));
00771 }
00772 }
00773
00774 Ptree* ClassWalker::TranslateUnary(Ptree* exp)
00775 {
00776 TypeInfo type;
00777 Environment* scope;
00778 Class* metaobject;
00779 Ptree* exp2;
00780
00781 Ptree* unaryop = exp->Car();
00782 Ptree* right = exp->Second();
00783 if(right->IsA(ntDotMemberExpr, ntArrowMemberExpr)){
00784 Ptree* object = right->First();
00785 Ptree* op = right->Second();
00786 Typeof(object, type);
00787 if(!op->Eq('.'))
00788 type.Dereference();
00789
00790 metaobject = GetClassMetaobject(type);
00791 if(metaobject != nil){
00792 exp2 = metaobject->TranslateUnaryOnMember(env, unaryop, object,
00793 op, right->Third());
00794 if(exp2->Length() == 2 && exp2->Car() == unaryop
00795 && Ptree::Equiv(exp2->Second(), right))
00796 return exp;
00797 else
00798 return exp2;
00799 }
00800 }
00801 else if((scope = env->IsMember(right)) != nil){
00802 metaobject = scope->IsClassEnvironment();
00803 if(metaobject != nil){
00804 exp2 = metaobject->TranslateUnaryOnMember(env, unaryop, right);
00805 return CheckEquiv(exp, exp2);
00806 }
00807 }
00808
00809 Typeof(right, type);
00810 metaobject = GetClassMetaobject(type);
00811 if(metaobject != nil){
00812 Ptree* exp2 = metaobject->TranslateUnary(env, unaryop, right);
00813 return CheckEquiv(exp, exp2);
00814 }
00815 else{
00816 Ptree* right2 = Translate(right);
00817 if(right == right2)
00818 return exp;
00819 else
00820 return new PtreeUnaryExpr(unaryop, Ptree::List(right2));
00821 }
00822 }
00823
00824 Ptree* ClassWalker::TranslateArray(Ptree* exp)
00825 {
00826 TypeInfo type;
00827
00828 Ptree* array = exp->Car();
00829 Typeof(array, type);
00830 Class* metaobject = GetClassMetaobject(type);
00831 if(metaobject != nil){
00832 Ptree* exp2 = metaobject->TranslateSubscript(env, array, exp->Cdr());
00833 return CheckEquiv(exp, exp2);
00834 }
00835 else{
00836 Ptree* index = exp->Third();
00837 Ptree* array2 = Translate(array);
00838 Ptree* index2 = Translate(index);
00839 if(array == array2 && index == index2)
00840 return exp;
00841 else
00842 return new PtreeArrayExpr(array2,
00843 Ptree::ShallowSubst(index2, index, exp->Cdr()));
00844 }
00845 }
00846
00847 Ptree* ClassWalker::TranslatePostfix(Ptree* exp)
00848 {
00849 TypeInfo type;
00850 Environment* scope;
00851 Class* metaobject;
00852 Ptree* exp2;
00853
00854 Ptree* left = exp->Car();
00855 Ptree* postop = exp->Second();
00856 if(left->IsA(ntDotMemberExpr, ntArrowMemberExpr)){
00857 Ptree* object = left->First();
00858 Ptree* op = left->Second();
00859 Typeof(object, type);
00860 if(!op->Eq('.'))
00861 type.Dereference();
00862
00863 metaobject = GetClassMetaobject(type);
00864 if(metaobject != nil){
00865 exp2 = metaobject->TranslatePostfixOnMember(env, object, op,
00866 left->Third(), postop);
00867 return CheckMemberEquiv(exp, exp2);
00868 }
00869 }
00870 else if((scope = env->IsMember(left)) != nil){
00871 metaobject = scope->IsClassEnvironment();
00872 if(metaobject != nil){
00873 exp2 = metaobject->TranslatePostfixOnMember(env, left, postop);
00874 return CheckEquiv(exp, exp2);
00875 }
00876 }
00877
00878 Typeof(left, type);
00879 metaobject = GetClassMetaobject(type);
00880 if(metaobject != nil){
00881 exp2 = metaobject->TranslatePostfix(env, left, postop);
00882 return CheckEquiv(exp, exp2);
00883 }
00884 else{
00885 Ptree* left2 = Translate(left);
00886 if(left == left2)
00887 return exp;
00888 else
00889 return new PtreePostfixExpr(left2, exp->Cdr());
00890 }
00891 }
00892
00893 Ptree* ClassWalker::TranslateFuncall(Ptree* exp)
00894 {
00895 TypeInfo type;
00896 Environment* scope;
00897 Class* metaobject;
00898 Ptree *fun, *arglist, *exp2;
00899
00900 fun = exp->Car();
00901 arglist = exp->Cdr();
00902 if(fun->IsA(ntDotMemberExpr, ntArrowMemberExpr)){
00903 Ptree* object = fun->First();
00904 Ptree* op = fun->Second();
00905 Ptree* member = fun->Third();
00906 Typeof(object, type);
00907 if(!op->Eq('.'))
00908 type.Dereference();
00909
00910 metaobject = GetClassMetaobject(type);
00911 if(metaobject != nil){
00912 exp2 = metaobject->TranslateMemberCall(env, object, op,
00913 member, arglist);
00914 return CheckMemberEquiv(exp, exp2);
00915 }
00916 }
00917 else if((scope = env->IsMember(fun)) != nil){
00918 metaobject = scope->IsClassEnvironment();
00919 if(metaobject != nil){
00920 exp2 = metaobject->TranslateMemberCall(env, fun, arglist);
00921 return CheckEquiv(exp, exp2);
00922 }
00923 }
00924 else{
00925 Typeof(fun, type);
00926 metaobject = GetClassMetaobject(type);
00927 if(metaobject != nil){
00928 exp2 = metaobject->TranslateFunctionCall(env, fun, arglist);
00929 return CheckEquiv(exp, exp2);
00930 }
00931 else if (Class::for_c_functions != nil) {
00932 exp2 = Class::for_c_functions->TranslateFunctionCall(env,
00933 fun, arglist);
00934 return CheckEquiv(exp, exp2);
00935 }
00936 }
00937
00938 Ptree* fun2 = Translate(fun);
00939 Ptree* arglist2 = TranslateArguments(arglist);
00940 if(fun == fun2 && arglist == arglist2)
00941 return exp;
00942 else
00943 return new PtreeFuncallExpr(fun2, arglist2);
00944 }
00945
00946 Ptree* ClassWalker::TranslateDotMember(Ptree* exp)
00947 {
00948 TypeInfo type;
00949
00950 Ptree* left = exp->Car();
00951 Typeof(left, type);
00952 Class* metaobject = GetClassMetaobject(type);
00953 if(metaobject != nil){
00954 Ptree* exp2 = metaobject->TranslateMemberRead(env, left, exp->Second(),
00955 exp->Third());
00956 return CheckEquiv(exp, exp2);
00957 }
00958 else{
00959 Ptree* left2 = Translate(left);
00960 if(left == left2)
00961 return exp;
00962 else
00963 return new PtreeDotMemberExpr(left2, exp->Cdr());
00964 }
00965 }
00966
00967 Ptree* ClassWalker::TranslateArrowMember(Ptree* exp)
00968 {
00969 TypeInfo type;
00970
00971 Ptree* left = exp->Car();
00972 Typeof(left, type);
00973 type.Dereference();
00974 Class* metaobject = GetClassMetaobject(type);
00975 if(metaobject != nil){
00976 Ptree* exp2 = metaobject->TranslateMemberRead(env, left, exp->Second(),
00977 exp->Third());
00978 return CheckEquiv(exp, exp2);
00979 }
00980 else{
00981 Ptree* left2 = Translate(left);
00982 if(left == left2)
00983 return exp;
00984 else
00985 return new PtreeArrowMemberExpr(left2, exp->Cdr());
00986 }
00987 }
00988
00989 Ptree* ClassWalker::TranslateThis(Ptree* exp)
00990 {
00991 TypeInfo type;
00992 Typeof(exp, type);
00993 type.Dereference();
00994 Class* metaobject = GetClassMetaobject(type);
00995 if(metaobject != nil)
00996 return metaobject->TranslatePointer(env, exp);
00997 else
00998 return exp;
00999 }
01000
01001 Ptree* ClassWalker::TranslateVariable(Ptree* exp)
01002 {
01003 Environment* scope = env->IsMember(exp);
01004 if(scope != nil){
01005 Class* metaobject = scope->IsClassEnvironment();
01006 if(metaobject != nil)
01007 return metaobject->TranslateMemberRead(env, exp);
01008 }
01009
01010 TypeInfo type;
01011 Typeof(exp, type);
01012 if(type.IsPointerType()){
01013 type.Dereference();
01014 Class* metaobject = GetClassMetaobject(type);
01015 if(metaobject != nil)
01016 return metaobject->TranslatePointer(env, exp);
01017 }
01018
01019 return exp;
01020 }
01021
01022 Ptree* ClassWalker::TranslateUserStatement(Ptree* exp)
01023 {
01024 TypeInfo type;
01025 Ptree* object = exp->First();
01026 Ptree* op = exp->Second();
01027 Ptree* keyword = exp->Third();
01028 Ptree* rest = exp->ListTail(3);
01029
01030 Typeof(object, type);
01031 if(!op->Eq('.'))
01032 type.Dereference();
01033
01034 Class* metaobject = GetClassMetaobject(type);
01035 if(metaobject != nil){
01036 NewScope();
01037 if(keyword->IsA(UserKeyword2))
01038 TranslateArgDeclList2(TRUE, env, FALSE, FALSE, 0, rest->Second());
01039
01040 Ptree* exp2 = metaobject->TranslateUserStatement(env, object, op,
01041 keyword, rest);
01042 ExitScope();
01043 return exp2;
01044 }
01045
01046 ErrorMessage("no complete class specification for: ", object, exp);
01047 return nil;
01048 }
01049
01050 Ptree* ClassWalker::TranslateStaticUserStatement(Ptree* exp)
01051 {
01052 bool is_type_name;
01053 TypeInfo type;
01054 Ptree* qualifier = exp->First();
01055 Ptree* keyword = exp->Third();
01056 Ptree* rest = exp->ListTail(3);
01057
01058 if(env->Lookup(qualifier, is_type_name, type))
01059 if(is_type_name){
01060 Class* metaobject = GetClassMetaobject(type);
01061 if(metaobject != nil){
01062 NewScope();
01063 if(keyword->IsA(UserKeyword2))
01064 TranslateArgDeclList2(TRUE, env, FALSE, FALSE, 0,
01065 rest->Second());
01066 Ptree* exp2 = metaobject->TranslateStaticUserStatement(env,
01067 keyword, rest);
01068 ExitScope();
01069 return exp2;
01070 }
01071 }
01072
01073 ErrorMessage("no complete class specification for: ", qualifier, exp);
01074 return nil;
01075 }
01076
01077 Ptree* ClassWalker::TranslateNew2(Ptree* exp, Ptree* userkey, Ptree* scope,
01078 Ptree* op, Ptree* placement,
01079 Ptree* type, Ptree* init)
01080 {
01081 TypeInfo t;
01082
01083 if(type->Car()->Eq('('))
01084 t.Set(type->Second()->Second()->GetEncodedType(), env);
01085 else
01086 t.Set(type->Second()->GetEncodedType(), env);
01087
01088 Class* metaobject = GetClassMetaobject(t);
01089 if(metaobject != nil){
01090 if(userkey == nil)
01091 userkey = scope;
01092
01093 Ptree* exp2 = metaobject->TranslateNew(env, userkey, op,
01094 placement, type, init);
01095 return CheckEquiv(exp, exp2);
01096 }
01097 else{
01098 Ptree* placement2 = TranslateArguments(placement);
01099 Ptree* type2 = TranslateNew3(type);
01100 Ptree* init2 = TranslateArguments(init);
01101 if(userkey == nil && placement == placement2
01102 && type == type2 && init == init2)
01103 return exp;
01104 else{
01105 if(userkey == nil)
01106 return new PtreeNewExpr(exp->Car(),
01107 Ptree::ShallowSubst(placement2, placement,
01108 type2, type,
01109 init2, init, exp->Cdr()));
01110 else{
01111 ErrorMessage("no complete class specification for: ",
01112 type, exp);
01113 exp = exp->Cdr();
01114 if(placement == placement2 && type == type2 && init == init2)
01115 return exp;
01116 else
01117 return new PtreeNewExpr(exp->Car(),
01118 Ptree::ShallowSubst(placement2, placement,
01119 type2, type,
01120 init2, init, exp->Cdr()));
01121 }
01122
01123 }
01124 }
01125 }
01126
01127 Ptree* ClassWalker::TranslateDelete(Ptree* exp)
01128 {
01129 TypeInfo type;
01130
01131 Ptree* obj = Ptree::Last(exp)->Car();
01132 if(exp->Length() == 2){
01133 Typeof(obj, type);
01134 type.Dereference();
01135 Class* metaobject = GetClassMetaobject(type);
01136 if(metaobject != nil){
01137 Ptree* exp2 = metaobject->TranslateDelete(env, exp->Car(), obj);
01138 return CheckEquiv(exp, exp2);
01139 }
01140 }
01141
01142 Ptree* obj2 = Translate(obj);
01143 if(obj == obj2)
01144 return exp;
01145 else
01146 return new PtreeDeleteExpr(exp->Car(),
01147 Ptree::ShallowSubst(obj2, obj,
01148 exp->Cdr()));
01149 }