00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include <string.h>
00016 #include "env.h"
00017 #include "ptree.h"
00018 #include "walker.h"
00019 #include "typeinfo.h"
00020 #include "mop.h"
00021 #include "metaclass.h"
00022 #include "parse.h"
00023 #include "encoding.h"
00024 #include "member.h"
00025
00026 Parser* Walker::default_parser = nil;
00027 char* Walker::argument_name = "_arg_%d_";
00028 char* Walker::default_metaclass = nil;
00029
00030 Walker::Walker(Parser* p)
00031 {
00032 env = new Environment(this);
00033 parser = p;
00034 if(default_parser == nil)
00035 default_parser = p;
00036 }
00037
00038 Walker::Walker(Parser* p, Environment* e)
00039 {
00040 env = new Environment(e, this);
00041 parser = p;
00042 if(default_parser == nil)
00043 default_parser = p;
00044 }
00045
00046 Walker::Walker(Environment* e)
00047 {
00048 env = new Environment(e, this);
00049 if(default_parser == nil)
00050 MopErrorMessage("Walker::Walker()", "no default parser");
00051
00052 parser = default_parser;
00053 }
00054
00055 Walker::Walker(Walker* w)
00056 {
00057 env = w->env;
00058 parser = w->parser;
00059 }
00060
00061 void Walker::NewScope()
00062 {
00063 env = new Environment(env);
00064 }
00065
00066 void Walker::NewScope(Environment* e)
00067 {
00068 if (e != nil)
00069 env = e;
00070 else
00071 env = new Environment(env);
00072 }
00073
00074 void Walker::NewScope(Class* metaobject)
00075 {
00076 env = new Environment(env);
00077 if(metaobject != nil)
00078 metaobject->SetEnvironment(env);
00079 }
00080
00081 Environment* Walker::ExitScope()
00082 {
00083 Environment* old_env = env;
00084 env = old_env->GetOuterEnvironment();
00085 return old_env;
00086 }
00087
00088 void Walker::RecordBaseclassEnv(Ptree* bases)
00089 {
00090 while(bases != nil){
00091 bases = bases->Cdr();
00092 Ptree* base_class = bases->Car()->Last()->Car();
00093 Class* metaobject = env->LookupClassMetaobject(base_class);
00094 if(metaobject != nil){
00095 Environment* e = metaobject->GetEnvironment();
00096 if(e != nil)
00097 env->AddBaseclassEnv(e);
00098 }
00099
00100 bases = bases->Cdr();
00101 }
00102 }
00103
00104 Walker::NameScope Walker::ChangeScope(Environment* e)
00105 {
00106 NameScope scope;
00107 scope.walker = e->GetWalker();
00108 e->SetWalker(this);
00109 scope.env = env;
00110 env = e;
00111 return scope;
00112 }
00113
00114 void Walker::RestoreScope(Walker::NameScope& scope)
00115 {
00116 env->SetWalker(scope.walker);
00117 env = scope.env;
00118 }
00119
00120 bool Walker::IsClassWalker()
00121 {
00122 return FALSE;
00123 }
00124
00125 Ptree* Walker::Translate(Ptree* p)
00126 {
00127 if(p == nil)
00128 return p;
00129 else
00130 return p->Translate(this);
00131 }
00132
00133 void Walker::Typeof(Ptree* p, TypeInfo& t)
00134 {
00135 if(p != nil)
00136 p->Typeof(this, t);
00137 }
00138
00139
00140
00141 Ptree* Walker::TranslatePtree(Ptree* p)
00142 {
00143 return p;
00144 }
00145
00146 void Walker::TypeofPtree(Ptree*, TypeInfo& t)
00147 {
00148 t.Unknown();
00149 }
00150
00151
00152
00153 Ptree* Walker::TranslateTypedef(Ptree* def)
00154 {
00155 Ptree *tspec, *tspec2;
00156
00157 tspec = Ptree::Second(def);
00158 tspec2 = TranslateTypespecifier(tspec);
00159 env->RecordTypedefName(Ptree::Third(def));
00160 if(tspec == tspec2)
00161 return def;
00162 else
00163 return new PtreeTypedef(Ptree::First(def),
00164 Ptree::List(tspec2,
00165 Ptree::ListTail(def, 2)));
00166 }
00167
00168 Ptree* Walker::TranslateTemplateDecl(Ptree* def)
00169 {
00170 Ptree* body = Ptree::Nth(def, 4);
00171 Ptree* class_spec = GetClassTemplateSpec(body);
00172 if(class_spec->IsA(ntClassSpec))
00173 return TranslateTemplateClass(def, class_spec);
00174 else
00175 return TranslateTemplateFunction(def, body);
00176 }
00177
00178 Ptree* Walker::TranslateExternTemplate(Ptree* def)
00179 {
00180 return def;
00181 }
00182
00183 Ptree* Walker::TranslateTemplateClass(Ptree* temp_def, Ptree* class_spec)
00184 {
00185 Ptree* userkey;
00186 Ptree* class_def;
00187
00188 if(class_spec->Car()->IsLeaf()){
00189 userkey = nil;
00190 class_def = class_spec;
00191 }
00192 else{
00193 userkey = class_spec->Car();
00194 class_def = class_spec->Cdr();
00195 }
00196
00197 Class* metaobject = nil;
00198 if(Ptree::Length(class_def) == 4)
00199 metaobject = MakeTemplateClassMetaobject(temp_def, userkey, class_def);
00200
00201 env->RecordTemplateClass(class_spec, metaobject);
00202 Ptree* class_spec2 = TranslateClassSpec(class_spec, userkey, class_def,
00203 metaobject);
00204 if(class_spec == class_spec2)
00205 return temp_def;
00206 else
00207 return new PtreeTemplateDecl(temp_def->Car(),
00208 Ptree::Subst(class_spec2, class_spec,
00209 temp_def->Cdr()));
00210 }
00211
00212 Class* Walker::MakeTemplateClassMetaobject(Ptree* def, Ptree* userkey,
00213 Ptree* class_def)
00214 {
00215 Class* metaobject = LookupMetaclass(def, userkey, class_def, TRUE);
00216 if(metaobject == nil)
00217 metaobject = new TemplateClass;
00218 else
00219 if(metaobject->AcceptTemplate())
00220 return metaobject;
00221 else{
00222
00223 ErrorMessage("the specified metaclass is not for templates.",
00224 nil, def);
00225 metaobject = new TemplateClass;
00226 }
00227
00228 metaobject->InitializeInstance(def, nil);
00229 return metaobject;
00230 }
00231
00232 Ptree* Walker::TranslateTemplateFunction(Ptree* temp_def, Ptree* fun)
00233 {
00234 env->RecordTemplateFunction(temp_def, fun);
00235 return temp_def;
00236 }
00237
00238 Ptree* Walker::TranslateTemplateInstantiation(Ptree *inst_spec)
00239 {
00240 Ptree* userkey;
00241 Ptree* class_spec;
00242 Ptree* full_class_spec = Ptree::First(inst_spec);
00243
00244 if(full_class_spec->Car()->IsLeaf()){
00245 userkey = nil;
00246 class_spec = full_class_spec;
00247 }
00248 else{
00249 userkey = full_class_spec->Car();
00250 class_spec = full_class_spec->Cdr();
00251 }
00252
00253 Class* metaobject = nil;
00254 metaobject = MakeTemplateInstantiationMetaobject(full_class_spec,
00255 userkey, class_spec);
00256 return TranslateTemplateInstantiation(inst_spec, userkey,
00257 class_spec, metaobject);
00258 }
00259
00260 Class* Walker::MakeTemplateInstantiationMetaobject(
00261 Ptree* full_class_spec, Ptree* userkey, Ptree* class_spec)
00262 {
00263
00264 Ptree* class_name = Ptree::First(Ptree::Second(class_spec));
00265 Bind* binding = nil;
00266 if (!env->Lookup(class_name,binding))
00267 return nil;
00268
00269 Class* metaobject = nil;
00270 if (binding->What() != Bind::isTemplateClass) {
00271 ErrorMessage("not declarated as a template class?!?",
00272 nil, full_class_spec);
00273 metaobject = nil;
00274 }
00275 else
00276 metaobject = binding->ClassMetaobject();
00277
00278 if (metaobject == nil)
00279 metaobject = new TemplateClass;
00280 else
00281 if(metaobject->AcceptTemplate())
00282 return metaobject;
00283 else{
00284 ErrorMessage("the specified metaclass is not for templates.",
00285 nil, full_class_spec);
00286 metaobject = new TemplateClass;
00287 }
00288
00289 return metaobject;
00290 }
00291
00292 Ptree* Walker::TranslateTemplateInstantiation(Ptree* inst_spec,
00293 Ptree* userkey, Ptree* class_spec, Class* metaobject)
00294 {
00295 if (metaobject == nil)
00296 return inst_spec;
00297 else {
00298 Ptree *class_spec2 = TranslateClassSpec(class_spec);
00299 if (class_spec == class_spec2)
00300 return inst_spec;
00301 else
00302 return class_spec2;
00303 }
00304 }
00305
00306 Ptree* Walker::TranslateMetaclassDecl(Ptree* decl)
00307 {
00308 env->RecordMetaclassName(decl);
00309 return decl;
00310 }
00311
00312 Ptree* Walker::TranslateLinkageSpec(Ptree* def)
00313 {
00314 Ptree* body = Ptree::Third(def);
00315 Ptree* body2 = Translate(body);
00316 if(body == body2)
00317 return def;
00318 else
00319 return new PtreeLinkageSpec(Ptree::First(def),
00320 Ptree::List(Ptree::Second(def),
00321 body2));
00322 }
00323
00324 Ptree* Walker::TranslateNamespaceSpec(Ptree* def)
00325 {
00326 Ptree* name = Ptree::Second(def);
00327 Ptree* body = Ptree::Third(def);
00328
00329 Environment* name_space = env->LookupNamespace0(name);
00330 NewScope(name_space);
00331 Ptree* body2 = Translate(body);
00332 Environment* name_space2 = ExitScope();
00333
00334 if (name_space == nil)
00335 env->RecordNamespace(name_space2, name);
00336
00337 if(body == body2)
00338 return def;
00339 else
00340 return new PtreeNamespaceSpec(Ptree::First(def),
00341 Ptree::List(name, body2));
00342 }
00343
00344 Ptree* Walker::TranslateUsing(Ptree* def)
00345 {
00346 if (((PtreeUsing*)def)->isNamespace())
00347 env->RecordUsingNamespace(def);
00348 else
00349 env->RecordUsing(def);
00350
00351 return def;
00352 }
00353
00354 Ptree* Walker::TranslateDeclaration(Ptree* def)
00355 {
00356 Ptree* decls = Ptree::Third(def);
00357 if(decls->IsA(ntDeclarator))
00358 return TranslateFunctionImplementation(def);
00359 else{
00360
00361 Ptree* decls2;
00362 Ptree* sspec = Ptree::First(def);
00363 Ptree* sspec2 = TranslateStorageSpecifiers(sspec);
00364 Ptree* tspec = Ptree::Second(def);
00365 Ptree* tspec2 = TranslateTypespecifier(tspec);
00366 if(decls->IsLeaf())
00367 decls2 = decls;
00368 else
00369 decls2 = TranslateDeclarators(decls);
00370
00371 if(sspec == sspec2 && tspec == tspec2 && decls == decls2)
00372 return def;
00373 else if(decls2 == nil)
00374 return new PtreeDeclaration(nil, Ptree::List(nil,
00375 Class::semicolon_t));
00376 else
00377 return new PtreeDeclaration(sspec2,
00378 Ptree::ShallowSubst(tspec2, tspec,
00379 decls2, decls,
00380 def->Cdr()));
00381 }
00382 }
00383
00384
00385
00386 Ptree* Walker::TranslateStorageSpecifiers(Ptree* spec)
00387 {
00388 return spec;
00389 }
00390
00391 Ptree* Walker::TranslateDeclarators(Ptree* decls)
00392 {
00393 return TranslateDeclarators(decls, TRUE);
00394 }
00395
00396 Ptree* Walker::TranslateDeclarators(Ptree* decls, bool record)
00397 {
00398 PtreeArray array;
00399 bool changed = FALSE;
00400 Ptree* rest = decls;
00401 while(rest != nil){
00402 Ptree *p, *q;
00403 int len;
00404 p = q = rest->Car();
00405 if(p->IsA(ntDeclarator)){
00406 Ptree *exp, *exp2;
00407
00408 if(record)
00409 env->RecordDeclarator(p);
00410
00411 len = p->Length();
00412 exp = exp2 = nil;
00413 if(len >= 2 && p->Nth(len - 2)->Eq('=')){
00414 exp = p->ListTail(len - 2);
00415 exp2 = TranslateAssignInitializer((PtreeDeclarator*)p, exp);
00416 }
00417 else{
00418 Ptree* last = p->Last()->Car();
00419 if(last != nil && !last->IsLeaf() && last->Car()->Eq('(')){
00420 exp = last;
00421 exp2 = TranslateInitializeArgs((PtreeDeclarator*)p, last);
00422 }
00423 }
00424
00425 q = TranslateDeclarator(FALSE, (PtreeDeclarator*)p);
00426 if(exp != exp2){
00427
00428 if(exp2 != nil && exp2->IsLeaf())
00429 exp2 = Ptree::List(exp2);
00430
00431 if(p == q){
00432 q = Ptree::SubstSublist(exp2, exp, p->Cdr());
00433 q = new PtreeDeclarator((PtreeDeclarator*)p, p->Car(), q);
00434 }
00435 else if(q != nil && !q->IsLeaf())
00436 q = new PtreeDeclarator((PtreeDeclarator*)p, q->Car(),
00437 Ptree::Subst(exp2, exp, q->Cdr()));
00438 }
00439 }
00440
00441 if(q == nil){
00442 changed = TRUE;
00443 rest = rest->Cdr();
00444 if(rest != nil)
00445 rest = rest->Cdr();
00446 }
00447 else{
00448 array.Append(q);
00449 if(p != q)
00450 changed = TRUE;
00451
00452 rest = rest->Cdr();
00453 if(rest != nil){
00454 array.Append(rest->Car());
00455 rest = rest->Cdr();
00456 }
00457 }
00458 }
00459
00460 if(changed)
00461 return array.All();
00462 else
00463 return decls;
00464 }
00465
00466 Ptree* Walker::TranslateDeclarator(bool record, PtreeDeclarator* decl)
00467 {
00468
00469
00470
00471 Ptree* args;
00472 if(GetArgDeclList(decl, args)){
00473 Ptree* args2 = TranslateArgDeclList(record, decl, args);
00474 if(args == args2)
00475 return decl;
00476 else
00477 return new PtreeDeclarator(decl, decl->Car(),
00478 Ptree::Subst(args2, args,
00479 decl->Cdr()));
00480 }
00481 else
00482 return decl;
00483 }
00484
00485 bool Walker::GetArgDeclList(PtreeDeclarator* decl, Ptree*& args)
00486 {
00487 Ptree* p = decl;
00488 while(p != nil){
00489 Ptree* q = p->Car();
00490 if(q != nil)
00491 if(q->IsLeaf()){
00492 if(q->Eq('(')){
00493 args = p->Cadr();
00494 return TRUE;
00495 }
00496 }
00497 else if(q->Car()->Eq('('))
00498 p = q->Cadr();
00499
00500 p = p->Cdr();
00501 }
00502
00503 args = nil;
00504 return FALSE;
00505 }
00506
00507 Ptree* Walker::TranslateArgDeclList(bool record, Ptree*, Ptree* args)
00508 {
00509 return TranslateArgDeclList2(record, env, FALSE, FALSE, 0, args);
00510 }
00511
00512
00513
00514 Ptree* Walker::TranslateArgDeclList2(bool record, Environment* e,
00515 bool translate,
00516 bool fill_args, int arg_name,
00517 Ptree* args)
00518 {
00519 Ptree* rest;
00520 Ptree* rest2;
00521
00522 if(args == nil)
00523 return args;
00524 else{
00525 Ptree *a, *a2;
00526 a = a2 = args->Car();
00527 if(args->Cdr() == nil)
00528 rest = rest2 = nil;
00529 else{
00530 rest = args->Cddr();
00531 rest2 = TranslateArgDeclList2(record, e, translate, fill_args,
00532 arg_name + 1, rest);
00533 if(rest == rest2)
00534 rest = rest2 = args->Cdr();
00535 else
00536 rest2 = Ptree::Cons(args->Cadr(), rest2);
00537 }
00538
00539 bool is_ellipsis = a->IsLeaf();
00540 if(is_ellipsis)
00541 ;
00542 else if(a->Car()->IsA(ntUserdefKeyword)){
00543 if(record)
00544 e->RecordDeclarator(a->Third());
00545
00546 if(translate){
00547 a2 = a->Cdr();
00548 if(fill_args)
00549 a2 = FillArgumentName(a2, a2->Second(), arg_name);
00550 }
00551 }
00552 else if(a->Car()->IsA(REGISTER)){
00553 if(record)
00554 e->RecordDeclarator(a->Third());
00555
00556 if(translate && fill_args){
00557 a2 = FillArgumentName(a, a->Third(), arg_name);
00558 if(a != a2)
00559 a2 = Ptree::Cons(a->First(), a2);
00560 }
00561 }
00562 else{
00563 if(record)
00564 e->RecordDeclarator(a->Second());
00565
00566 if(translate && fill_args)
00567 a2 = FillArgumentName(a, a->Second(), arg_name);
00568 }
00569
00570 if(a != a2 || rest != rest2)
00571 return Ptree::Cons(a2, rest2);
00572 else
00573 return args;
00574 }
00575 }
00576
00577 Ptree* Walker::FillArgumentName(Ptree* arg, Ptree* d, int arg_name)
00578 {
00579 PtreeDeclarator* decl = (PtreeDeclarator*)d;
00580 if(decl->Name() != nil)
00581 return arg;
00582 else{
00583 unsigned char* type = (unsigned char*)decl->GetEncodedType();
00584 return Encoding::MakePtree(type,
00585 Ptree::Make(argument_name, arg_name));
00586 }
00587 }
00588
00589 Ptree* Walker::TranslateAssignInitializer(PtreeDeclarator*, Ptree* init)
00590 {
00591 Ptree* exp = init->Second();
00592 Ptree* exp2 = Translate(exp);
00593 if(exp == exp2)
00594 return init;
00595 else
00596 return Ptree::List(init->Car(), exp2);
00597 }
00598
00599 Ptree* Walker::TranslateInitializeArgs(PtreeDeclarator*, Ptree* init)
00600 {
00601 return TranslateArguments(init);
00602 }
00603
00604 Ptree* Walker::TranslateFunctionImplementation(Ptree* impl)
00605 {
00606 Ptree* sspec = Ptree::First(impl);
00607 Ptree* sspec2 = TranslateStorageSpecifiers(sspec);
00608 Ptree* tspec = Ptree::Second(impl);
00609 Ptree* decl = Ptree::Third(impl);
00610 Ptree* body = Ptree::Nth(impl, 3);
00611 Ptree* decl2;
00612 Ptree* body2;
00613
00614 Ptree* tspec2 = TranslateTypespecifier(tspec);
00615 Environment* fenv = env->RecordDeclarator(decl);
00616 if(fenv == nil){
00617
00618 NewScope();
00619 decl2 = TranslateDeclarator(TRUE, (PtreeDeclarator*)decl);
00620 body2 = Translate(body);
00621 ExitScope();
00622 }
00623 else{
00624 NameScope old_env = ChangeScope(fenv);
00625 NewScope();
00626 decl2 = TranslateDeclarator(TRUE, (PtreeDeclarator*)decl);
00627 body2 = Translate(body);
00628 ExitScope();
00629 RestoreScope(old_env);
00630 }
00631
00632 if(sspec == sspec2 && tspec == tspec2 && decl == decl2 && body == body2)
00633 return impl;
00634 else
00635 return new PtreeDeclaration(sspec2,
00636 Ptree::List(tspec2, decl2, body2));
00637 }
00638
00639 Ptree* Walker::RecordArgsAndTranslateFbody(Class*, Ptree* args, Ptree* body)
00640 {
00641 NewScope();
00642 TranslateArgDeclList2(TRUE, env, FALSE, FALSE, 0, args);
00643 Ptree* body2 = TranslateFunctionBody(body);
00644 ExitScope();
00645 return body2;
00646 }
00647
00648 Ptree* Walker::TranslateFunctionBody(Ptree* body)
00649 {
00650 return Translate(body);
00651 }
00652
00653 Ptree* Walker::TranslateBrace(Ptree* block)
00654 {
00655 PtreeArray array;
00656 bool changed = FALSE;
00657 Ptree* body = Ptree::Second(block);
00658 Ptree* rest = body;
00659 while(rest != nil){
00660 Ptree* p = rest->Car();
00661 Ptree* q = Translate(p);
00662 array.Append(q);
00663 if(p != q)
00664 changed = TRUE;
00665
00666 rest = rest->Cdr();
00667 }
00668
00669 if(changed)
00670 return new PtreeBrace(Ptree::First(block), array.All(),
00671 Ptree::Third(block));
00672 else
00673 return block;
00674 }
00675
00676 Ptree* Walker::TranslateBlock(Ptree* block)
00677 {
00678 Ptree* block2;
00679
00680 NewScope();
00681
00682 PtreeArray array;
00683 bool changed = FALSE;
00684 Ptree* body = Ptree::Second(block);
00685 Ptree* rest = body;
00686 while(rest != nil){
00687 Ptree* p = rest->Car();
00688 Ptree* q = Translate(p);
00689 array.Append(q);
00690 if(p != q)
00691 changed = TRUE;
00692
00693 rest = rest->Cdr();
00694 }
00695
00696 if(changed)
00697 block2 = new PtreeBlock(Ptree::First(block), array.All(),
00698 Ptree::Third(block));
00699 else
00700 block2 = block;
00701
00702 ExitScope();
00703 return block2;
00704 }
00705
00706 Ptree* Walker::TranslateClassBody(Ptree* block, Ptree* bases,
00707 Class* metaobject)
00708 {
00709 Ptree* block2;
00710
00711 NewScope(metaobject);
00712 RecordBaseclassEnv(bases);
00713
00714 PtreeArray array;
00715 bool changed = FALSE;
00716 Ptree* body = Ptree::Second(block);
00717 Ptree* rest = body;
00718 while(rest != nil){
00719 Ptree* p = rest->Car();
00720 Ptree* q = Translate(p);
00721 array.Append(q);
00722 if(p != q)
00723 changed = TRUE;
00724
00725 rest = rest->Cdr();
00726 }
00727
00728 if(changed)
00729 block2 = new PtreeClassBody(Ptree::First(block), array.All(),
00730 Ptree::Third(block));
00731 else
00732 block2 = block;
00733
00734 ExitScope();
00735 return block2;
00736 }
00737
00738 Ptree* Walker::TranslateClassSpec(Ptree* spec)
00739 {
00740 Ptree* userkey;
00741 Ptree* class_def;
00742
00743 if(spec->Car()->IsLeaf()){
00744 userkey = nil;
00745 class_def = spec;
00746 }
00747 else{
00748 userkey = spec->Car();
00749 class_def = spec->Cdr();
00750 }
00751
00752 Class* metaobject = nil;
00753 if(Ptree::Length(class_def) == 4)
00754 metaobject = MakeClassMetaobject(spec, userkey, class_def);
00755
00756 env->RecordClassName(spec->GetEncodedName(), metaobject);
00757 return TranslateClassSpec(spec, userkey, class_def, metaobject);
00758 }
00759
00760 Class* Walker::MakeClassMetaobject(Ptree* def, Ptree* userkey,
00761 Ptree* class_def)
00762 {
00763 Class* metaobject = LookupMetaclass(def, userkey, class_def, FALSE);
00764 if(metaobject == nil && default_metaclass != nil){
00765 metaobject = opcxx_ListOfMetaclass::New(default_metaclass, class_def,
00766 nil);
00767 if(metaobject == nil)
00768 MopErrorMessage2("the default metaclass cannot be loaded: ",
00769 default_metaclass);
00770 }
00771
00772 if(metaobject == nil)
00773 metaobject = new Class;
00774 else{
00775 if(!metaobject->AcceptTemplate())
00776 return metaobject;
00777 else{
00778 ErrorMessage("the specified metaclass is for templates.",
00779 nil, def);
00780 metaobject = new Class;
00781 }
00782 }
00783
00784 metaobject->InitializeInstance(class_def, nil);
00785 return metaobject;
00786 }
00787
00788 void Walker::ChangeDefaultMetaclass(char* name)
00789 {
00790 default_metaclass = name;
00791 }
00792
00793
00794
00795 Class* Walker::LookupMetaclass(Ptree* def, Ptree* userkey, Ptree* class_def,
00796 bool is_template)
00797 {
00798 Ptree *mclass, *margs;
00799 Class* metaobject;
00800
00801 Ptree* class_name = class_def->Second();
00802
00803
00804 if(Metaclass::IsBuiltinMetaclass(class_name)){
00805 metaobject = new Metaclass;
00806 metaobject->InitializeInstance(def, nil);
00807 return metaobject;
00808 }
00809
00810 Ptree* mdecl = env->LookupMetaclass(class_name);
00811 if(mdecl != nil){
00812 mclass = mdecl->Second();
00813 margs = mdecl->Nth(4);
00814 metaobject = opcxx_ListOfMetaclass::New(mclass, def, margs);
00815 if(metaobject == nil)
00816 ErrorMessage("the metaclass is not loaded: ", mclass, class_def);
00817 else if(userkey != nil)
00818 ErrorMessage("the metaclass declaration conflicts"
00819 " with the keyword: ", mclass, class_def);
00820
00821 return metaobject;
00822 }
00823
00824 if(userkey != nil){
00825 mclass = env->LookupClasskeyword(userkey->Car());
00826 if(mclass == nil)
00827 ErrorMessage("invalid keyword: ", userkey, class_def);
00828 else{
00829 metaobject = opcxx_ListOfMetaclass::New(mclass, class_def,
00830 userkey->Third());
00831 if(metaobject == nil)
00832 ErrorMessage("the metaclass associated with the"
00833 " keyword is not loaded: ", userkey, class_def);
00834
00835 return metaobject;
00836 }
00837 }
00838
00839 return LookupBaseMetaclass(def, class_def, is_template);
00840 }
00841
00842 Class* Walker::LookupBaseMetaclass(Ptree* def, Ptree* class_def,
00843 bool is_template)
00844 {
00845 Class* metaobject = nil;
00846 Ptree* bases = class_def->Third();
00847 while(bases != nil){
00848 bases = bases->Cdr();
00849 Ptree* base = bases->Car()->Last()->Car();
00850 bases = bases->Cdr();
00851 Class* m = env->LookupClassMetaobject(base);
00852 if(m != nil){
00853 if(metaobject == nil)
00854 metaobject = m;
00855 else if(m == nil || strcmp(metaobject->MetaclassName(),
00856 m->MetaclassName()) != 0){
00857 ErrorMessage("inherited metaclasses conflict: ",
00858 class_def->Second(), class_def);
00859 return nil;
00860 }
00861 }
00862 }
00863
00864 if(metaobject == nil)
00865 return nil;
00866
00867 bool accept_template = metaobject->AcceptTemplate();
00868 if((is_template && accept_template) || (!is_template && !accept_template))
00869 return opcxx_ListOfMetaclass::New(metaobject->MetaclassName(),
00870 def, nil);
00871 else
00872 return nil;
00873 }
00874
00875 Ptree* Walker::TranslateClassSpec(Ptree* spec, Ptree*,
00876 Ptree* class_def, Class* metaobject)
00877 {
00878 if(metaobject == nil)
00879 return spec;
00880 else{
00881
00882 Ptree* body = class_def->Nth(3);
00883 Ptree* body2 = TranslateClassBody(body, class_def->Third(),
00884 metaobject);
00885 if(body == body2)
00886 return spec;
00887 else
00888 return new PtreeClassSpec(spec->Car(),
00889 Ptree::ShallowSubst(body2, body,
00890 spec->Cdr()),
00891 nil, spec->GetEncodedName());
00892 }
00893 }
00894
00895
00896 Ptree* Walker::TranslateEnumSpec(Ptree* spec)
00897 {
00898 env->RecordEnumName(spec);
00899 return spec;
00900 }
00901
00902 Ptree* Walker::TranslateAccessSpec(Ptree* p)
00903 {
00904 return p;
00905 }
00906
00907 Ptree* Walker::TranslateAccessDecl(Ptree* p)
00908 {
00909 return p;
00910 }
00911
00912 Ptree* Walker::TranslateUserAccessSpec(Ptree* p)
00913 {
00914 return p;
00915 }
00916
00917 Ptree* Walker::TranslateIf(Ptree* s)
00918 {
00919 Ptree* cond = s->Third();
00920 Ptree* cond2 = Translate(cond);
00921 Ptree* then_part = s->Nth(4);
00922 Ptree* then_part2 = Translate(then_part);
00923 Ptree* else_part = s->Nth(6);
00924 Ptree* else_part2 = Translate(else_part);
00925
00926 if(cond == cond2 && then_part == then_part2 && else_part == else_part2)
00927 return s;
00928 else{
00929 Ptree* rest = Ptree::ShallowSubst(cond2, cond, then_part2, then_part,
00930 else_part2, else_part, s->Cdr());
00931 return new PtreeIfStatement(s->Car(), rest);
00932 }
00933 }
00934
00935 Ptree* Walker::TranslateSwitch(Ptree* s)
00936 {
00937 Ptree* cond = s->Third();
00938 Ptree* cond2 = Translate(cond);
00939 Ptree* body = s->Nth(4);
00940 Ptree* body2 = Translate(body);
00941 if(cond == cond2 && body == body2)
00942 return s;
00943 else{
00944 Ptree* rest = Ptree::ShallowSubst(cond2, cond, body2, body, s->Cdr());
00945 return new PtreeSwitchStatement(s->Car(), rest);
00946 }
00947 }
00948
00949 Ptree* Walker::TranslateWhile(Ptree* s)
00950 {
00951 Ptree* cond = s->Third();
00952 Ptree* cond2 = Translate(cond);
00953 Ptree* body = s->Nth(4);
00954 Ptree* body2 = Translate(body);
00955 if(cond == cond2 && body == body2)
00956 return s;
00957 else{
00958 Ptree* rest = Ptree::ShallowSubst(cond2, cond, body2, body, s->Cdr());
00959 return new PtreeWhileStatement(s->Car(), rest);
00960 }
00961 }
00962
00963 Ptree* Walker::TranslateDo(Ptree* s)
00964 {
00965 Ptree* body = s->Second();
00966 Ptree* body2 = Translate(body);
00967 Ptree* cond = s->Nth(4);
00968 Ptree* cond2 = Translate(cond);
00969 if(cond == cond2 && body == body2)
00970 return s;
00971 else{
00972 Ptree* rest = Ptree::ShallowSubst(body2, body, cond2, cond, s->Cdr());
00973 return new PtreeDoStatement(s->Car(), rest);
00974 }
00975 }
00976
00977 Ptree* Walker::TranslateFor(Ptree* s)
00978 {
00979 NewScope();
00980 Ptree* exp1 = s->Third();
00981 Ptree* exp1t = Translate(exp1);
00982 Ptree* exp2 = s->Nth(3);
00983 Ptree* exp2t = Translate(exp2);
00984 Ptree* exp3 = s->Nth(5);
00985 Ptree* exp3t = Translate(exp3);
00986 Ptree* body = s->Nth(7);
00987 Ptree* body2 = Translate(body);
00988 ExitScope();
00989
00990 if(exp1 == exp1t && exp2 == exp2t && exp3 == exp3t && body == body2)
00991 return s;
00992 else{
00993 Ptree* rest = Ptree::ShallowSubst(exp1t, exp1, exp2t, exp2,
00994 exp3t, exp3, body2, body, s->Cdr());
00995 return new PtreeForStatement(s->Car(), rest);
00996 }
00997 }
00998
00999 Ptree* Walker::TranslateTry(Ptree* s)
01000 {
01001 Ptree* try_block = s->Second();
01002 Ptree* try_block2 = Translate(try_block);
01003
01004 PtreeArray array;
01005 Ptree* handlers = s->Cddr();
01006 bool changed = FALSE;
01007
01008 while(handlers != nil){
01009 Ptree* handle = handlers->Car();
01010 Ptree* body = handle->Nth(4);
01011 Ptree* body2 = Translate(body);
01012 if(body == body2)
01013 array.Append(handle);
01014 else{
01015 array.Append(Ptree::ShallowSubst(body2, body, handle));
01016 changed = TRUE;
01017 }
01018
01019 handlers = handlers->Cdr();
01020 }
01021
01022 if(try_block == try_block2 && !changed)
01023 return s;
01024 else
01025 return new PtreeTryStatement(s->Car(),
01026 Ptree::Cons(try_block2, array.All()));
01027 }
01028
01029 Ptree* Walker::TranslateBreak(Ptree* s)
01030 {
01031 return s;
01032 }
01033
01034 Ptree* Walker::TranslateContinue(Ptree* s)
01035 {
01036 return s;
01037 }
01038
01039 Ptree* Walker::TranslateReturn(Ptree* s)
01040 {
01041 if(s->Length() == 2)
01042 return s;
01043 else{
01044 Ptree* exp = s->Second();
01045 Ptree* exp2 = Translate(exp);
01046 if(exp == exp2)
01047 return s;
01048 else
01049 return new PtreeReturnStatement(s->Car(),
01050 Ptree::ShallowSubst(exp2, exp,
01051 s->Cdr()));
01052 }
01053 }
01054
01055 Ptree* Walker::TranslateGoto(Ptree* s)
01056 {
01057 return s;
01058 }
01059
01060 Ptree* Walker::TranslateCase(Ptree* s)
01061 {
01062 Ptree* st = s->Nth(3);
01063 Ptree* st2 = Translate(st);
01064 if(st == st2)
01065 return s;
01066 else
01067 return new PtreeCaseStatement(s->Car(),
01068 Ptree::ShallowSubst(st2, st, s->Cdr()));
01069 }
01070
01071 Ptree* Walker::TranslateDefault(Ptree* s)
01072 {
01073 Ptree* st = s->Third();
01074 Ptree* st2 = Translate(st);
01075 if(st == st2)
01076 return s;
01077 else
01078 return new PtreeDefaultStatement(s->Car(),
01079 Ptree::List(s->Cadr(), st2));
01080 }
01081
01082 Ptree* Walker::TranslateLabel(Ptree* s)
01083 {
01084 Ptree* st = s->Third();
01085 Ptree* st2 = Translate(st);
01086 if(st == st2)
01087 return s;
01088 else
01089 return new PtreeLabelStatement(s->Car(),
01090 Ptree::List(s->Cadr(), st2));
01091 }
01092
01093 Ptree* Walker::TranslateExprStatement(Ptree* s)
01094 {
01095 Ptree* exp = s->First();
01096 Ptree* exp2 = Translate(exp);
01097 if(exp == exp2)
01098 return s;
01099 else
01100 return new PtreeExprStatement(exp2, s->Cdr());
01101 }
01102
01103 Ptree* Walker::TranslateTypespecifier(Ptree* tspec)
01104 {
01105 Ptree *class_spec, *class_spec2;
01106
01107 class_spec = GetClassOrEnumSpec(tspec);
01108 if(class_spec == nil)
01109 class_spec2 = nil;
01110 else
01111 class_spec2 = Translate(class_spec);
01112
01113 if(class_spec == class_spec2)
01114 return tspec;
01115 else
01116 return Ptree::ShallowSubst(class_spec2, class_spec, tspec);
01117 }
01118
01119 Ptree* Walker::GetClassOrEnumSpec(Ptree* typespec)
01120 {
01121 Ptree* spec = StripCvFromIntegralType(typespec);
01122 if(spec->IsA(ntClassSpec, ntEnumSpec))
01123 return spec;
01124
01125 return nil;
01126 }
01127
01128 Ptree* Walker::GetClassTemplateSpec(Ptree* body)
01129 {
01130 if(Ptree::Eq(Ptree::Third(body), ';')){
01131 Ptree* spec = StripCvFromIntegralType(Ptree::Second(body));
01132 if(spec->IsA(ntClassSpec))
01133 return spec;
01134 }
01135
01136 return nil;
01137 }
01138
01139 Ptree* Walker::StripCvFromIntegralType(Ptree* integral)
01140 {
01141 if(integral == nil)
01142 return nil;
01143
01144 if(!integral->IsLeaf())
01145 if(integral->Car()->IsA(CONST, VOLATILE))
01146 return Ptree::Second(integral);
01147 else if(Ptree::Second(integral)->IsA(CONST, VOLATILE))
01148 return integral->Car();
01149
01150 return integral;
01151 }
01152
01153 Ptree* Walker::TranslateComma(Ptree* exp)
01154 {
01155 Ptree* left = exp->First();
01156 Ptree* left2 = Translate(left);
01157 Ptree* right = exp->Third();
01158 Ptree* right2 = Translate(right);
01159 if(left == left2 && right == right2)
01160 return exp;
01161 else
01162 return new PtreeCommaExpr(left2, Ptree::List(exp->Second(), right2));
01163 }
01164
01165 void Walker::TypeofComma(Ptree* exp, TypeInfo& t)
01166 {
01167 Typeof(exp->Third(), t);
01168 }
01169
01170 Ptree* Walker::TranslateAssign(Ptree* exp)
01171 {
01172 Ptree* left = exp->First();
01173 Ptree* left2 = Translate(left);
01174 Ptree* right = exp->Third();
01175 Ptree* right2 = Translate(right);
01176 if(left == left2 && right == right2)
01177 return exp;
01178 else
01179 return new PtreeAssignExpr(left2, Ptree::List(exp->Second(), right2));
01180 }
01181
01182 void Walker::TypeofAssign(Ptree* exp, TypeInfo& t)
01183 {
01184 Typeof(exp->First(), t);
01185 }
01186
01187 Ptree* Walker::TranslateCond(Ptree* exp)
01188 {
01189 Ptree* c = exp->First();
01190 Ptree* c2 = Translate(c);
01191 Ptree* t = exp->Third();
01192 Ptree* t2 = Translate(t);
01193 Ptree* e = exp->Nth(4);
01194 Ptree* e2 = Translate(e);
01195 if(c == c2 && t == t2 && e == e2)
01196 return exp;
01197 else
01198 return new PtreeCondExpr(c2, Ptree::List(exp->Second(), t2,
01199 exp->Nth(3), e2));
01200 }
01201
01202 void Walker::TypeofCond(Ptree* exp, TypeInfo& t)
01203 {
01204 Typeof(exp->Third(), t);
01205 }
01206
01207 Ptree* Walker::TranslateInfix(Ptree* exp)
01208 {
01209 Ptree* left = exp->First();
01210 Ptree* left2 = Translate(left);
01211 Ptree* right = exp->Third();
01212 Ptree* right2 = Translate(right);
01213 if(left == left2 && right == right2)
01214 return exp;
01215 else
01216 return new PtreeInfixExpr(left2, Ptree::List(exp->Second(), right2));
01217 }
01218
01219 void Walker::TypeofInfix(Ptree* exp, TypeInfo& t)
01220 {
01221 Typeof(exp->First(), t);
01222 }
01223
01224 Ptree* Walker::TranslatePm(Ptree* exp)
01225 {
01226 Ptree* left = exp->First();
01227 Ptree* left2 = Translate(left);
01228 Ptree* right = exp->Third();
01229 Ptree* right2 = Translate(right);
01230 if(left == left2 && right == right2)
01231 return exp;
01232 else
01233 return new PtreePmExpr(left2, Ptree::List(exp->Second(), right2));
01234 }
01235
01236 void Walker::TypeofPm(Ptree* exp, TypeInfo& t)
01237 {
01238 Typeof(exp->Third(), t);
01239 t.Dereference();
01240 }
01241
01242 Ptree* Walker::TranslateCast(Ptree* exp)
01243 {
01244 Ptree* e = exp->Nth(3);
01245 Ptree* e2 = Translate(e);
01246 if(e == e2)
01247 return exp;
01248 else
01249 return new PtreeCastExpr(exp->First(),
01250 Ptree::ShallowSubst(e2, e, exp->Cdr()));
01251 }
01252
01253 void Walker::TypeofCast(Ptree* exp, TypeInfo& t)
01254 {
01255 t.Set(exp->Second()->Second()->GetEncodedType(), env);
01256 }
01257
01258 Ptree* Walker::TranslateUnary(Ptree* exp)
01259 {
01260 Ptree* oprnd = exp->Second();
01261 Ptree* oprnd2 = Translate(oprnd);
01262 if(oprnd == oprnd2)
01263 return exp;
01264 else
01265 return new PtreeUnaryExpr(exp->First(), Ptree::List(oprnd2));
01266 }
01267
01268 void Walker::TypeofUnary(Ptree* exp, TypeInfo& t)
01269 {
01270 Typeof(exp->Second(), t);
01271
01272 Ptree* op = exp->First();
01273 if(op->Eq('*'))
01274 t.Dereference();
01275 else if(op->Eq('&'))
01276 t.Reference();
01277 }
01278
01279 Ptree* Walker::TranslateThrow(Ptree* exp)
01280 {
01281 Ptree* oprnd = exp->Second();
01282 Ptree* oprnd2 = Translate(oprnd);
01283 if(oprnd == oprnd2)
01284 return exp;
01285 else
01286 return new PtreeThrowExpr(exp->First(), Ptree::List(oprnd2));
01287 }
01288
01289 void Walker::TypeofThrow(Ptree*, TypeInfo& t)
01290 {
01291 t.SetVoid();
01292 }
01293
01294 Ptree* Walker::TranslateSizeof(Ptree* exp)
01295 {
01296 Ptree* e = exp->Second();
01297 if(e->Eq('('))
01298 e = exp->Third();
01299
01300 Ptree* e2 = Translate(e);
01301 if(e == e2)
01302 return exp;
01303 else
01304 return new PtreeSizeofExpr(exp->First(),
01305 Ptree::ShallowSubst(e2, e, exp->Cdr()));
01306 }
01307
01308 void Walker::TypeofSizeof(Ptree*, TypeInfo& t)
01309 {
01310 t.SetInt();
01311 }
01312
01313 Ptree* Walker::TranslateNew(Ptree* exp)
01314 {
01315 Ptree *p;
01316 Ptree *userkey, *scope, *op, *placement, *type, *init;
01317
01318 p = exp;
01319 userkey = p->Car();
01320 if(userkey == nil || !userkey->IsLeaf())
01321 p = exp->Cdr();
01322 else
01323 userkey = nil;
01324
01325 if(p->Car()->Eq("::")){
01326 scope = p->Car();
01327 p = p->Cdr();
01328 }
01329 else
01330 scope = nil;
01331
01332 op = p->Car();
01333 placement = p->Cadr();
01334 type = p->Third();
01335 init = p->Nth(3);
01336 return TranslateNew2(exp, userkey, scope, op, placement, type, init);
01337 }
01338
01339 Ptree* Walker::TranslateNew2(Ptree* exp, Ptree*, Ptree*,
01340 Ptree*, Ptree* placement,
01341 Ptree* type, Ptree* init)
01342 {
01343 Ptree* placement2 = TranslateArguments(placement);
01344 Ptree* type2 = TranslateNew3(type);
01345 Ptree* init2 = TranslateArguments(init);
01346 if(placement == placement2 && init == init2)
01347 return exp;
01348 else
01349 return new PtreeNewExpr(exp->Car(),
01350 Ptree::ShallowSubst(placement2, placement,
01351 type2, type,
01352 init2, init,
01353 exp->Cdr()));
01354 }
01355
01356 Ptree* Walker::TranslateNew3(Ptree* type)
01357 {
01358 Ptree* p = type;
01359 if(p->Car()->Eq('('))
01360 p = p->Second();
01361
01362 Ptree* decl = p->Second();
01363 Ptree* decl2 = TranslateNewDeclarator(decl);
01364 if(decl == decl2)
01365 return type;
01366 else
01367 return Ptree::Subst(decl2, decl, type);
01368 }
01369
01370 void Walker::TypeofNew(Ptree* exp, TypeInfo& t)
01371 {
01372 Ptree *p, *userkey, *type;
01373
01374 p = exp;
01375 userkey = p->Car();
01376 if(userkey == nil || !userkey->IsLeaf())
01377 p = exp->Cdr();
01378
01379 if(p->Car()->Eq("::"))
01380 p = p->Cdr();
01381
01382 type = p->Third();
01383
01384 if(type->Car()->Eq('('))
01385 t.Set(type->Second()->Second()->GetEncodedType(), env);
01386 else
01387 t.Set(type->Second()->GetEncodedType(), env);
01388
01389 t.Reference();
01390 }
01391
01392 Ptree* Walker::TranslateDelete(Ptree* exp)
01393 {
01394 Ptree* obj = Ptree::Last(exp)->Car();
01395 Ptree* obj2 = Translate(obj);
01396 if(obj == obj2)
01397 return exp;
01398 else
01399 return new PtreeDeleteExpr(exp->Car(),
01400 Ptree::ShallowSubst(obj2, obj,
01401 exp->Cdr()));
01402 }
01403
01404 void Walker::TypeofDelete(Ptree*, TypeInfo& t)
01405 {
01406 t.SetVoid();
01407 }
01408
01409 Ptree* Walker::TranslateThis(Ptree* exp)
01410 {
01411 return exp;
01412 }
01413
01414 void Walker::TypeofThis(Ptree*, TypeInfo& t)
01415 {
01416 t.Set(env->LookupThis());
01417 }
01418
01419 Ptree* Walker::TranslateVariable(Ptree* exp)
01420 {
01421 return exp;
01422 }
01423
01424
01425
01426
01427 void Walker::TypeofVariable(Ptree* exp, TypeInfo& t)
01428 {
01429 bool is_type_name;
01430
01431 if(env->Lookup(exp, is_type_name, t))
01432 if(is_type_name)
01433 t.Reference();
01434 }
01435
01436
01437
01438
01439
01440 Ptree* Walker::TranslateFstyleCast(Ptree* exp)
01441 {
01442 Ptree* args = exp->Cdr();
01443 Ptree* args2 = TranslateArguments(args);
01444 if(args == args2)
01445 return exp;
01446 else
01447 return new PtreeFstyleCastExpr(exp->GetEncodedType(), exp->Car(),
01448 args2);
01449 }
01450
01451 void Walker::TypeofFstyleCast(Ptree* exp, TypeInfo& t)
01452 {
01453 t.Set(exp->GetEncodedType(), env);
01454 }
01455
01456 Ptree* Walker::TranslateArray(Ptree* exp)
01457 {
01458 Ptree* array = exp->Car();
01459 Ptree* array2 = Translate(array);
01460 Ptree* index = exp->Third();
01461 Ptree* index2 = Translate(index);
01462 if(array == array2 && index == index2)
01463 return exp;
01464 else
01465 return new PtreeArrayExpr(array2, Ptree::Subst(index2, index,
01466 exp->Cdr()));
01467 }
01468
01469 void Walker::TypeofArray(Ptree* exp, TypeInfo& t)
01470 {
01471 Typeof(exp->Car(), t);
01472 t.Dereference();
01473 }
01474
01475
01476
01477
01478 Ptree* Walker::TranslateFuncall(Ptree* exp)
01479 {
01480 Ptree* fun = exp->Car();
01481 Ptree* fun2 = Translate(fun);
01482 Ptree* args = exp->Cdr();
01483 Ptree* args2 = TranslateArguments(args);
01484 if(fun == fun2 && args == args2)
01485 return exp;
01486 else
01487 return new PtreeFuncallExpr(fun2, args2);
01488 }
01489
01490 void Walker::TypeofFuncall(Ptree* exp, TypeInfo& t)
01491 {
01492 Typeof(exp->Car(), t);
01493 if(!t.IsFunction())
01494 t.Dereference();
01495
01496 t.Dereference();
01497 }
01498
01499 Ptree* Walker::TranslatePostfix(Ptree* exp)
01500 {
01501 Ptree* left = exp->Car();
01502 Ptree* left2 = Translate(left);
01503 if(left == left2)
01504 return exp;
01505 else
01506 return new PtreePostfixExpr(left2, exp->Cdr());
01507 }
01508
01509 void Walker::TypeofPostfix(Ptree* exp, TypeInfo& t)
01510 {
01511 Typeof(exp->Car(), t);
01512 }
01513
01514 Ptree* Walker::TranslateUserStatement(Ptree* exp)
01515 {
01516 return exp;
01517 }
01518
01519 void Walker::TypeofUserStatement(Ptree*, TypeInfo& t)
01520 {
01521 t.Unknown();
01522 }
01523
01524 Ptree* Walker::TranslateDotMember(Ptree* exp)
01525 {
01526 Ptree* left = exp->Car();
01527 Ptree* left2 = Translate(left);
01528 if(left == left2)
01529 return exp;
01530 else
01531 return new PtreeDotMemberExpr(left2, exp->Cdr());
01532 }
01533
01534 void Walker::TypeofDotMember(Ptree* exp, TypeInfo& t)
01535 {
01536 Typeof(exp->Car(), t);
01537 t.SetMember(exp->Third());
01538 }
01539
01540 Ptree* Walker::TranslateArrowMember(Ptree* exp)
01541 {
01542 Ptree* left = exp->Car();
01543 Ptree* left2 = Translate(left);
01544 if(left == left2)
01545 return exp;
01546 else
01547 return new PtreeArrowMemberExpr(left2, exp->Cdr());
01548 }
01549
01550 void Walker::TypeofArrowMember(Ptree* exp, TypeInfo& t)
01551 {
01552 Typeof(exp->Car(), t);
01553 t.Dereference();
01554 t.SetMember(exp->Third());
01555 }
01556
01557 Ptree* Walker::TranslateParen(Ptree* exp)
01558 {
01559 Ptree* e = exp->Second();
01560 Ptree* e2 = Translate(e);
01561 if(e == e2)
01562 return exp;
01563 else
01564 return new PtreeParenExpr(exp->Car(), Ptree::List(e2, exp->Third()));
01565 }
01566
01567 void Walker::TypeofParen(Ptree* exp, TypeInfo& t)
01568 {
01569 Typeof(exp->Second(), t);
01570 }
01571
01572 Ptree* Walker::TranslateStaticUserStatement(Ptree* exp)
01573 {
01574 return exp;
01575 }
01576
01577 void Walker::TypeofStaticUserStatement(Ptree*, TypeInfo& t)
01578 {
01579 t.Unknown();
01580 }
01581
01582 Ptree* Walker::TranslateNewDeclarator(Ptree* decl)
01583 {
01584 Ptree* decl2 = decl;
01585 Ptree* p = decl;
01586 while(p != nil){
01587 Ptree* head = p->Car();
01588 if(head == nil)
01589 return decl;
01590 else if(head->Eq('[')){
01591 Ptree* p2 = TranslateNewDeclarator2(p);
01592 if(p == p2)
01593 return decl;
01594 else{
01595 decl2 = Ptree::ShallowSubst(p2, p, decl);
01596 break;
01597 }
01598 }
01599 else if(!head->IsLeaf() && head->Car()->Eq('(')){
01600 Ptree* d = head->Cadr();
01601 Ptree* d2 = TranslateNewDeclarator(d);
01602 decl2 = Ptree::ShallowSubst(d2, d, decl);
01603 break;
01604 }
01605
01606 p = p->Cdr();
01607 }
01608
01609 if(p == nil)
01610 return decl;
01611 else if(decl->IsA(ntDeclarator))
01612 return new PtreeDeclarator((PtreeDeclarator*)decl,
01613 decl2->Car(), decl2->Cdr());
01614 else
01615 return decl2;
01616 }
01617
01618 Ptree* Walker::TranslateNewDeclarator2(Ptree* decl)
01619 {
01620 for(Ptree* p = decl; p != nil; p = p->Cdr()){
01621 Ptree* head = p->Car();
01622 if(head->Eq('[')){
01623 Ptree* size = p->Cadr();
01624 Ptree* size2 = Translate(size);
01625 if(size != size2){
01626 Ptree* q = TranslateNewDeclarator2(Ptree::ListTail(p, 3));
01627 return Ptree::Nconc(Ptree::List(p->Car(), size2, p->Third()),
01628 q);
01629 }
01630 }
01631 else if(head->Eq('('))
01632 break;
01633 }
01634
01635 return decl;
01636 }
01637
01638 Ptree* Walker::TranslateArguments(Ptree* arglist)
01639 {
01640 if(arglist == nil)
01641 return arglist;
01642
01643 PtreeArray array;
01644 bool changed = FALSE;
01645 Ptree* body = Ptree::Second(arglist);
01646 Ptree* args = body;
01647 while(args != nil){
01648 Ptree* p = args->Car();
01649 Ptree* q = Translate(p);
01650 array.Append(q);
01651 if(p != q)
01652 changed = TRUE;
01653
01654 args = args->Cdr();
01655 if(args != nil){
01656 array.Append(args->Car());
01657 args = args->Cdr();
01658 }
01659 }
01660
01661 if(changed)
01662 return Ptree::ShallowSubst(array.All(), body, arglist);
01663 else
01664 return arglist;
01665 }
01666
01667 void Walker::SetDeclaratorComments(Ptree* def, Ptree* comments)
01668 {
01669 if (def == nil || !def->IsA(ntDeclaration))
01670 return;
01671
01672 Ptree* decl;
01673 int n = 0;
01674 for (;;) {
01675 int i = n++;
01676 decl = NthDeclarator(def, i);
01677 if (decl == nil)
01678 break;
01679 else if (decl->IsA(ntDeclarator))
01680 ((PtreeDeclarator*)decl)->SetComments(comments);
01681 }
01682 }
01683
01684 Ptree* Walker::NthDeclarator(Ptree* def, int& nth)
01685 {
01686 Ptree* decls = def->Third();
01687 if(decls == nil || decls->IsLeaf())
01688 return nil;
01689
01690 if(decls->IsA(ntDeclarator)){
01691 if(nth-- == 0)
01692 return decls;
01693 }
01694 else
01695 while(decls != nil && !decls->IsLeaf()){
01696 if(nth-- == 0)
01697 return decls->Car();
01698
01699 if((decls = decls->Cdr()) != nil)
01700 decls = decls->Cdr();
01701 }
01702
01703 return nil;
01704 }
01705
01706 Ptree* Walker::FindDeclarator(Ptree* def, char* name, int len,
01707 char* signature, int& nth, Environment* e)
01708 {
01709 Ptree* decls = def->Third();
01710 if(decls == nil || decls->IsLeaf())
01711 return nil;
01712
01713 if(decls->IsA(ntDeclarator)){
01714 if(MatchedDeclarator(decls, name, len, signature, e))
01715 return decls;
01716
01717 ++nth;
01718 }
01719 else
01720 while(decls != nil){
01721 Ptree* d = decls->Car();
01722 if(MatchedDeclarator(d, name, len, signature, e))
01723 return d;
01724
01725 ++nth;
01726 if((decls = decls->Cdr()) != nil)
01727 decls = decls->Cdr();
01728 }
01729
01730 return nil;
01731 }
01732
01733 bool Walker::MatchedDeclarator(Ptree* decl, char* name, int len,
01734 char* signature, Environment* e)
01735 {
01736 char* str;
01737 int strlen;
01738 char* sig;
01739
01740 str = decl->GetEncodedName();
01741 sig = decl->GetEncodedType();
01742 if(str == nil || sig == nil)
01743 return FALSE;
01744
01745 str = Encoding::GetBaseName(str, strlen, e);
01746 return bool(len == strlen && memcmp(name, str, len) == 0
01747 && strcmp(signature, sig) == 0);
01748 }
01749
01750 bool Walker::WhichDeclarator(Ptree* def, Ptree* name, int& nth,
01751 Environment* env)
01752 {
01753 char* str;
01754 int len;
01755 Environment* e;
01756 Ptree* decls = def->Third();
01757 if(decls == nil || decls->IsLeaf())
01758 return FALSE;
01759
01760 if(decls->IsA(ntDeclarator)){
01761 str = decls->GetEncodedName();
01762 e = env;
01763 str = Encoding::GetBaseName(str, len, e);
01764 if(name->Eq(str, len))
01765 return TRUE;
01766
01767 ++nth;
01768 }
01769 else
01770 while(decls != nil){
01771 str = decls->Car()->GetEncodedName();
01772 e = env;
01773 str = Encoding::GetBaseName(str, len, e);
01774 if(name->Eq(str, len))
01775 return TRUE;
01776
01777 ++nth;
01778 if((decls = decls->Cdr()) != nil)
01779 decls = decls->Cdr();
01780 }
01781
01782 return FALSE;
01783 }
01784
01785 void Walker::ErrorMessage(char* msg, Ptree* name, Ptree* where)
01786 {
01787 parser->ErrorMessage(msg, name, where);
01788 }
01789
01790 void Walker::WarningMessage(char* msg, Ptree* name, Ptree* where)
01791 {
01792 parser->WarningMessage(msg, name, where);
01793 }
01794
01795
01796
01797 void Walker::InaccurateErrorMessage(char* msg, Ptree* name, Ptree* where)
01798 {
01799 if(default_parser == nil)
01800 MopErrorMessage("Walker::InaccurateErrorMessage()",
01801 "no default parser");
01802 else
01803 default_parser->ErrorMessage(msg, name, where);
01804 }
01805
01806 void Walker::InaccurateWarningMessage(char* msg, Ptree* name, Ptree* where)
01807 {
01808 if(default_parser == nil)
01809 MopErrorMessage("Walker::InaccurateWarningMessage()",
01810 "no default parser");
01811 else
01812 default_parser->WarningMessage(msg, name, where);
01813 }