00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #include <iostream.h>
00030 #include <stdlib.h>
00031 #include <string.h>
00032 #include "ptree.h"
00033 #include "token.h"
00034 #include "walker.h"
00035 #include "typeinfo.h"
00036 #include "buffer.h"
00037
00038 #if defined(_MSC_VER) || defined(IRIX_CC)
00039 #include <stdlib.h>
00040 #endif
00041
00042 bool Ptree::show_encoded = FALSE;
00043
00044
00045
00046 void MopErrorMessage(char* where, char* msg)
00047 {
00048 cerr << "MOP error: in " << where << ", " << msg << '\n';
00049 exit(1);
00050 }
00051
00052 void MopErrorMessage2(char* msg1, char* msg2)
00053 {
00054 cerr << "MOP error: " << msg1 << msg2 << '\n';
00055 exit(1);
00056 }
00057
00058 void MopWarningMessage(char* where, char* msg)
00059 {
00060 cerr << "MOP warning: in " << where << ", " << msg << '\n';
00061 }
00062
00063 void MopWarningMessage2(char* msg1, char* msg2)
00064 {
00065 cerr << "MOP warning: " << msg1 << msg2 << '\n';
00066 }
00067
00068 void MopMoreWarningMessage(char* msg1, char* msg2)
00069 {
00070 cerr << " " << msg1;
00071 if(msg2 != nil)
00072 cerr << msg2;
00073
00074 cerr << '\n';
00075 }
00076
00077
00078
00079 void Ptree::Display()
00080 {
00081 Display2(cerr);
00082 }
00083
00084 void Ptree::Display2(ostream& s)
00085 {
00086 if(this == nil)
00087 s << "nil\n";
00088 else{
00089 Print(s, 0, 0);
00090 s << '\n';
00091 }
00092 }
00093
00094 int Ptree::Write(ostream& s)
00095 {
00096 if(this == nil)
00097 return 0;
00098 else
00099 return Write(s, 0);
00100 }
00101
00102 void Ptree::PrintIndent(ostream& out, int indent)
00103 {
00104 out << '\n';
00105 for(int i = 0; i < indent; ++i)
00106 out << " ";
00107 }
00108
00109 char* Ptree::ToString()
00110 {
00111 if(this == nil)
00112 return nil;
00113 else{
00114 ProgramString ps;
00115 WritePS(ps);
00116 return (char*)ps.Read(0);
00117 }
00118 }
00119
00120 bool Ptree::Eq(char c)
00121 {
00122 if(this == nil)
00123 return FALSE;
00124 else
00125 return(IsLeaf() && GetLength() == 1 && *GetPosition() == c);
00126 }
00127
00128 bool Ptree::Eq(char* str)
00129 {
00130 if(this == nil)
00131 return FALSE;
00132 else if(IsLeaf()){
00133 char* p = GetPosition();
00134 int n = GetLength();
00135 int i;
00136 for(i = 0; i < n; ++i)
00137 if(p[i] != str[i] || str[i] == '\0')
00138 return FALSE;
00139
00140 return bool(str[i] == '\0');
00141 }
00142 else
00143 return FALSE;
00144 }
00145
00146 bool Ptree::Eq(const char* str, int len)
00147 {
00148 if(this != nil && IsLeaf()){
00149 char* p = GetPosition();
00150 int n = GetLength();
00151 if(n == len){
00152 int i;
00153 for(i = 0; i < n; ++i)
00154 if(p[i] != str[i])
00155 return FALSE;
00156
00157 return TRUE;
00158 }
00159 }
00160
00161 return FALSE;
00162 }
00163
00164 Ptree* Ptree::Ca_ar()
00165 {
00166 Ptree* p = this;
00167 while(p != nil && !p->IsLeaf())
00168 p = p->Car();
00169
00170 return p;
00171 }
00172
00173 char* Ptree::LeftMost()
00174 {
00175 if(this == nil)
00176 return nil;
00177 else if(IsLeaf())
00178 return GetPosition();
00179 else{
00180 Ptree* p = this;
00181 while(p != nil){
00182 char* i = p->Car()->LeftMost();
00183 if(i != nil)
00184 return i;
00185 else
00186 p = p->Cdr();
00187 }
00188 return nil;
00189 }
00190 }
00191
00192 char* Ptree::RightMost()
00193 {
00194 if(this == nil)
00195 return nil;
00196 else if(IsLeaf())
00197 return GetPosition() + GetLength();
00198 else{
00199 int n = Length();
00200 while(n > 0){
00201 char* i = Nth(--n)->RightMost();
00202 if(i != nil)
00203 return i;
00204 }
00205
00206 return nil;
00207 }
00208 }
00209
00210 int Ptree::What()
00211 {
00212 return BadToken;
00213 }
00214
00215 bool Ptree::IsA(int kind)
00216 {
00217 if(this == nil)
00218 return FALSE;
00219 else
00220 return bool(What() == kind);
00221 }
00222
00223 bool Ptree::IsA(int kind1, int kind2)
00224 {
00225 if(this == nil)
00226 return FALSE;
00227 else{
00228 int k = What();
00229 return bool(k == kind1 || k == kind2);
00230 }
00231 }
00232
00233 bool Ptree::IsA(int kind1, int kind2, int kind3)
00234 {
00235 if(this == nil)
00236 return FALSE;
00237 else{
00238 int k = What();
00239 return bool(k == kind1 || k == kind2 || k == kind3);
00240 }
00241 }
00242
00243 Ptree* Ptree::Translate(Walker* w)
00244 {
00245 return w->TranslatePtree(this);
00246 }
00247
00248 void Ptree::Typeof(Walker* w, TypeInfo& t)
00249 {
00250 w->TypeofPtree(this, t);
00251 }
00252
00253 char* Ptree::GetEncodedType()
00254 {
00255 return nil;
00256 }
00257
00258 char* Ptree::GetEncodedName()
00259 {
00260 return nil;
00261 }
00262
00263
00264
00265
00266 bool Ptree::Eq(Ptree* p, char c)
00267 {
00268 return p->Eq(c);
00269 }
00270
00271 bool Ptree::Eq(Ptree* p, char* str)
00272 {
00273 return p->Eq(str);
00274 }
00275
00276 bool Ptree::Eq(Ptree* p, char* str, int len)
00277 {
00278 return p->Eq(str, len);
00279 }
00280
00281 bool Ptree::Eq(Ptree* p, Ptree* q)
00282 {
00283 if(p == q)
00284 return TRUE;
00285 else if(p == nil || q == nil)
00286 return FALSE;
00287 else if(p->IsLeaf() && q->IsLeaf()){
00288 int plen = p->GetLength();
00289 int qlen = q->GetLength();
00290 if(plen == qlen){
00291 char* pstr = p->GetPosition();
00292 char* qstr = q->GetPosition();
00293 while(--plen >= 0)
00294 if(pstr[plen] != qstr[plen])
00295 return FALSE;
00296
00297 return TRUE;
00298 }
00299 }
00300
00301 return FALSE;
00302 }
00303
00304
00305
00306
00307
00308 bool Ptree::Equiv(Ptree* p, Ptree* q)
00309 {
00310 if(p == q)
00311 return TRUE;
00312 else if(p == nil || q == nil)
00313 return FALSE;
00314 else if(p->IsLeaf() || q->IsLeaf())
00315 return Eq(p, q);
00316 else{
00317 while(p != nil && q != nil)
00318 if(p->Car() != q->Car())
00319 return FALSE;
00320 else{
00321 p = p->Cdr();
00322 q = q->Cdr();
00323 }
00324
00325 return p == nil && q == nil;
00326 }
00327 }
00328
00329 bool Ptree::Equal(Ptree* p, Ptree* q)
00330 {
00331 if(p == q)
00332 return TRUE;
00333 else if(p == nil || q == nil)
00334 return FALSE;
00335 else if(p->IsLeaf() || q->IsLeaf())
00336 return Eq(p, q);
00337 else
00338 return Equal(p->Car(), q->Car()) && Equal(p->Cdr(), q->Cdr());
00339 }
00340
00341 Ptree* Ptree::Last(Ptree* p)
00342 {
00343 Ptree* next;
00344 if(p == nil)
00345 return nil;
00346
00347 while((next = p->Cdr()) != nil)
00348 p = next;
00349
00350 return p;
00351 }
00352
00353 Ptree* Ptree::First(Ptree* p)
00354 {
00355 if(p != nil)
00356 return p->Car();
00357 else
00358 return p;
00359 }
00360
00361 Ptree* Ptree::Rest(Ptree* p)
00362 {
00363 if(p != nil)
00364 return p->Cdr();
00365 else
00366 return p;
00367 }
00368
00369 Ptree* Ptree::Second(Ptree* p)
00370 {
00371 if(p != nil){
00372 p = p->Cdr();
00373 if(p != nil)
00374 return p->Car();
00375 }
00376
00377 return p;
00378 }
00379
00380 Ptree* Ptree::Third(Ptree* p)
00381 {
00382 if(p != nil){
00383 p = p->Cdr();
00384 if(p != nil){
00385 p = p->Cdr();
00386 if(p != nil)
00387 return p->Car();
00388 }
00389 }
00390
00391 return p;
00392 }
00393
00394
00395
00396
00397 Ptree* Ptree::Nth(Ptree* p, int n)
00398 {
00399 while(p != nil && n-- > 0)
00400 p = p->Cdr();
00401
00402 if(p != nil)
00403 return p->Car();
00404 else
00405 return p;
00406 }
00407
00408
00409
00410
00411 int Ptree::Length(Ptree* p)
00412 {
00413 int i = 0;
00414
00415 if(p != nil && p->IsLeaf())
00416 return -2;
00417
00418 while(p != nil){
00419 ++i;
00420 if(p->IsLeaf())
00421 return -1;
00422 else
00423 p = p->Cdr();
00424 }
00425
00426 return i;
00427 }
00428
00429 Ptree* Ptree::ListTail(Ptree* p, int k)
00430 {
00431 while(p != nil && k-- > 0)
00432 p = p->Cdr();
00433
00434 return p;
00435 }
00436
00437 Ptree* Ptree::Cons(Ptree* p, Ptree* q)
00438 {
00439 return new NonLeaf(p, q);
00440 }
00441
00442 Ptree* Ptree::List(Ptree* p)
00443 {
00444 return new NonLeaf(p, nil);
00445 }
00446
00447 Ptree* Ptree::List()
00448 {
00449 return nil;
00450 }
00451
00452 Ptree* Ptree::List(Ptree* p, Ptree* q)
00453 {
00454 return new NonLeaf(p, new NonLeaf(q, nil));
00455 }
00456
00457 Ptree* Ptree::List(Ptree* p1, Ptree* p2, Ptree* p3)
00458 {
00459 return new NonLeaf(p1, new NonLeaf(p2, new NonLeaf(p3, nil)));
00460 }
00461
00462 Ptree* Ptree::List(Ptree* p1, Ptree* p2, Ptree* p3, Ptree* p4)
00463 {
00464 return new NonLeaf(p1, List(p2, p3, p4));
00465 }
00466
00467 Ptree* Ptree::List(Ptree* p1, Ptree* p2, Ptree* p3, Ptree* p4, Ptree* p5)
00468 {
00469 return Nconc(List(p1, p2), List(p3, p4, p5));
00470 }
00471
00472 Ptree* Ptree::List(Ptree* p1, Ptree* p2, Ptree* p3, Ptree* p4, Ptree* p5,
00473 Ptree* p6)
00474 {
00475 return Nconc(List(p1, p2, p3), List(p4, p5, p6));
00476 }
00477
00478 Ptree* Ptree::List(Ptree* p1, Ptree* p2, Ptree* p3, Ptree* p4, Ptree* p5,
00479 Ptree* p6, Ptree* p7)
00480 {
00481 return Nconc(List(p1, p2, p3), List(p4, p5, p6, p7));
00482 }
00483
00484 Ptree* Ptree::List(Ptree* p1, Ptree* p2, Ptree* p3, Ptree* p4, Ptree* p5,
00485 Ptree* p6, Ptree* p7, Ptree* p8)
00486 {
00487 return Nconc(List(p1, p2, p3, p4), List(p5, p6, p7, p8));
00488 }
00489
00490 Ptree* Ptree::CopyList(Ptree* p)
00491 {
00492 return Append(p, nil);
00493 }
00494
00495
00496
00497 Ptree* Ptree::Append(Ptree* p, Ptree* q)
00498 {
00499 Ptree *result, *tail;
00500
00501 if(p == nil)
00502 if(q->IsLeaf())
00503 return Cons(q, nil);
00504 else
00505 return q;
00506
00507 result = tail = Cons(p->Car(), nil);
00508 p = p->Cdr();
00509 while(p != nil){
00510 Ptree* cell = Cons(p->Car(), nil);
00511 tail->SetCdr(cell);
00512 tail = cell;
00513 p = p->Cdr();
00514 }
00515
00516 if(q != nil && q->IsLeaf())
00517 tail->SetCdr(Cons(q, nil));
00518 else
00519 tail->SetCdr(q);
00520
00521 return result;
00522 }
00523
00524
00525
00526
00527
00528 Ptree* Ptree::ReplaceAll(Ptree* list, Ptree* orig, Ptree* subst)
00529 {
00530 if(Eq(list, orig))
00531 return subst;
00532 else if(list == nil || list->IsLeaf())
00533 return list;
00534 else{
00535 PtreeArray newlist;
00536 bool changed = FALSE;
00537 Ptree* rest = list;
00538 while(rest != nil){
00539 Ptree* p = rest->Car();
00540 Ptree* q = ReplaceAll(p, orig, subst);
00541 newlist.Append(q);
00542 if(p != q)
00543 changed = TRUE;
00544
00545 rest = rest->Cdr();
00546 }
00547
00548 if(changed)
00549 return newlist.All();
00550 else
00551 return list;
00552 }
00553 }
00554
00555 Ptree* Ptree::Subst(Ptree* newone, Ptree* old, Ptree* tree)
00556 {
00557 if(old == tree)
00558 return newone;
00559 else if(tree== nil || tree->IsLeaf())
00560 return tree;
00561 else{
00562 Ptree* head = tree->Car();
00563 Ptree* head2 = Subst(newone, old, head);
00564 Ptree* tail = tree->Cdr();
00565 Ptree* tail2 = (tail == nil) ? tail : Subst(newone, old, tail);
00566 if(head == head2 && tail == tail2)
00567 return tree;
00568 else
00569 return Cons(head2, tail2);
00570 }
00571 }
00572
00573 Ptree* Ptree::Subst(Ptree* newone1, Ptree* old1, Ptree* newone2, Ptree* old2,
00574 Ptree* tree)
00575 {
00576 if(old1 == tree)
00577 return newone1;
00578 else if(old2 == tree)
00579 return newone2;
00580 else if(tree == nil || tree->IsLeaf())
00581 return tree;
00582 else{
00583 Ptree* head = tree->Car();
00584 Ptree* head2 = Subst(newone1, old1, newone2, old2, head);
00585 Ptree* tail = tree->Cdr();
00586 Ptree* tail2 = (tail == nil) ? tail
00587 : Subst(newone1, old1, newone2, old2, tail);
00588 if(head == head2 && tail == tail2)
00589 return tree;
00590 else
00591 return Cons(head2, tail2);
00592 }
00593 }
00594
00595 Ptree* Ptree::Subst(Ptree* newone1, Ptree* old1, Ptree* newone2, Ptree* old2,
00596 Ptree* newone3, Ptree* old3, Ptree* tree)
00597 {
00598 if(old1 == tree)
00599 return newone1;
00600 else if(old2 == tree)
00601 return newone2;
00602 else if(old3 == tree)
00603 return newone3;
00604 else if(tree == nil || tree->IsLeaf())
00605 return tree;
00606 else{
00607 Ptree* head = tree->Car();
00608 Ptree* head2 = Subst(newone1, old1, newone2, old2,
00609 newone3, old3, head);
00610 Ptree* tail = tree->Cdr();
00611 Ptree* tail2 = (tail == nil) ? tail :
00612 Subst(newone1, old1, newone2, old2,
00613 newone3, old3, tail);
00614 if(head == head2 && tail == tail2)
00615 return tree;
00616 else
00617 return Cons(head2, tail2);
00618 }
00619 }
00620
00621
00622
00623 Ptree* Ptree::ShallowSubst(Ptree* newone, Ptree* old, Ptree* tree)
00624 {
00625 if(old == tree)
00626 return newone;
00627 else if(tree== nil || tree->IsLeaf())
00628 return tree;
00629 else{
00630 Ptree *head, *head2;
00631 head = tree->Car();
00632 if(old == head)
00633 head2 = newone;
00634 else
00635 head2 = head;
00636
00637 Ptree* tail = tree->Cdr();
00638 Ptree* tail2 = (tail == nil) ? tail : ShallowSubst(newone, old, tail);
00639 if(head == head2 && tail == tail2)
00640 return tree;
00641 else
00642 return Cons(head2, tail2);
00643 }
00644 }
00645
00646 Ptree* Ptree::ShallowSubst(Ptree* newone1, Ptree* old1,
00647 Ptree* newone2, Ptree* old2, Ptree* tree)
00648 {
00649 if(old1 == tree)
00650 return newone1;
00651 else if(old2 == tree)
00652 return newone2;
00653 else if(tree == nil || tree->IsLeaf())
00654 return tree;
00655 else{
00656 Ptree *head, *head2;
00657 head = tree->Car();
00658 if(old1 == head)
00659 head2 = newone1;
00660 else if(old2 == head)
00661 head2 = newone2;
00662 else
00663 head2 = head;
00664
00665 Ptree* tail = tree->Cdr();
00666 Ptree* tail2 = (tail == nil) ? tail :
00667 ShallowSubst(newone1, old1, newone2, old2, tail);
00668 if(head == head2 && tail == tail2)
00669 return tree;
00670 else
00671 return Cons(head2, tail2);
00672 }
00673 }
00674
00675 Ptree* Ptree::ShallowSubst(Ptree* newone1, Ptree* old1,
00676 Ptree* newone2, Ptree* old2,
00677 Ptree* newone3, Ptree* old3, Ptree* tree)
00678 {
00679 if(old1 == tree)
00680 return newone1;
00681 else if(old2 == tree)
00682 return newone2;
00683 else if(old3 == tree)
00684 return newone3;
00685 else if(tree == nil || tree->IsLeaf())
00686 return tree;
00687 else{
00688 Ptree *head, *head2;
00689 head = tree->Car();
00690 if(old1 == head)
00691 head2 = newone1;
00692 else if(old2 == head)
00693 head2 = newone2;
00694 else if(old3 == head)
00695 head2 = newone3;
00696 else
00697 head2 = head;
00698
00699 Ptree* tail = tree->Cdr();
00700 Ptree* tail2 = (tail == nil) ? tail :
00701 ShallowSubst(newone1, old1, newone2, old2,
00702 newone3, old3, tail);
00703 if(head == head2 && tail == tail2)
00704 return tree;
00705 else
00706 return Cons(head2, tail2);
00707 }
00708 }
00709
00710 Ptree* Ptree::ShallowSubst(Ptree* newone1, Ptree* old1,
00711 Ptree* newone2, Ptree* old2,
00712 Ptree* newone3, Ptree* old3,
00713 Ptree* newone4, Ptree* old4, Ptree* tree)
00714 {
00715 if(old1 == tree)
00716 return newone1;
00717 else if(old2 == tree)
00718 return newone2;
00719 else if(old3 == tree)
00720 return newone3;
00721 else if(old4 == tree)
00722 return newone4;
00723 else if(tree == nil || tree->IsLeaf())
00724 return tree;
00725 else{
00726 Ptree *head, *head2;
00727 head = tree->Car();
00728 if(old1 == head)
00729 head2 = newone1;
00730 else if(old2 == head)
00731 head2 = newone2;
00732 else if(old3 == head)
00733 head2 = newone3;
00734 else if(old4 == head)
00735 head2 = newone4;
00736 else
00737 head2 = head;
00738
00739 Ptree* tail = tree->Cdr();
00740 Ptree* tail2 = (tail == nil) ? tail :
00741 ShallowSubst(newone1, old1, newone2, old2,
00742 newone3, old3, newone4, old4, tail);
00743 if(head == head2 && tail == tail2)
00744 return tree;
00745 else
00746 return Cons(head2, tail2);
00747 }
00748 }
00749
00750 Ptree* Ptree::SubstSublist(Ptree* newsub, Ptree* oldsub, Ptree* lst)
00751 {
00752 if(lst == oldsub)
00753 return newsub;
00754 else
00755 return Cons(lst->Car(), SubstSublist(newsub, oldsub, lst->Cdr()));
00756 }
00757
00758 Ptree* Ptree::Snoc(Ptree* p, Ptree* q)
00759 {
00760 return Nconc(p, Cons(q, nil));
00761 }
00762
00763
00764
00765 Ptree* Ptree::Nconc(Ptree* p, Ptree* q)
00766 {
00767 if(p == nil)
00768 return q;
00769 else{
00770 Last(p)->data.nonleaf.next = q;
00771 return p;
00772 }
00773 }
00774
00775 Ptree* Ptree::Nconc(Ptree* p, Ptree* q, Ptree* r)
00776 {
00777 return Nconc(p, Nconc(q, r));
00778 }
00779
00780
00781
00782
00783 Ptree* PtreeIter::Pop()
00784 {
00785 if(ptree == nil)
00786 return nil;
00787 else{
00788 Ptree* p = ptree->Car();
00789 ptree = ptree->Cdr();
00790 return p;
00791 }
00792 }
00793
00794 bool PtreeIter::Next(Ptree*& car)
00795 {
00796 if(ptree == nil)
00797 return FALSE;
00798 else{
00799 car = ptree->Car();
00800 ptree = ptree->Cdr();
00801 return TRUE;
00802 }
00803 }
00804
00805 Ptree* PtreeIter::This()
00806 {
00807 if(ptree == nil)
00808 return nil;
00809 else
00810 return ptree->Car();
00811 }
00812
00813
00814
00815 PtreeArray::PtreeArray(int s)
00816 {
00817 num = 0;
00818 if(s > 8){
00819 size = s;
00820 array = new (GC) Ptree*[s];
00821 }
00822 else{
00823 size = 8;
00824 array = default_buf;
00825 }
00826 }
00827
00828 void PtreeArray::Append(Ptree* p)
00829 {
00830 if(num >= size){
00831 size = size * 2;
00832 Ptree** a = new (GC) Ptree*[size];
00833 memmove(a, array, size_t(num * sizeof(Ptree*)));
00834 array = a;
00835 }
00836
00837 array[num++] = p;
00838 }
00839
00840 Ptree*& PtreeArray::Ref(uint i)
00841 {
00842 if(i < num)
00843 return array[i];
00844 else{
00845 MopErrorMessage("PtreeArray", "out of range");
00846 return array[0];
00847 }
00848 }
00849
00850 Ptree* PtreeArray::All()
00851 {
00852 Ptree* lst = nil;
00853
00854 for(sint i = Number() - 1; i >= 0; --i)
00855 lst = Ptree::Cons(Ref(i), lst);
00856
00857 return lst;
00858 }