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

ptree-core.cc

Go to the documentation of this file.
00001 /*
00002   Copyright (C) 1997-2001 Shigeru Chiba, Tokyo Institute of Technology.
00003 
00004   Permission to use, copy, distribute and modify this software and   
00005   its documentation for any purpose is hereby granted without fee,        
00006   provided that the above copyright notice appear in all copies and that 
00007   both that copyright notice and this permission notice appear in 
00008   supporting documentation.
00009 
00010   Shigeru Chiba makes no representations about the suitability of this 
00011   software for any purpose.  It is provided "as is" without express or
00012   implied warranty.
00013 */
00014 
00015 /*
00016   Copyright (C) 1997-2001 Shigeru Chiba, University of Tsukuba.
00017 
00018   Permission to use, copy, distribute and modify this software and   
00019   its documentation for any purpose is hereby granted without fee,        
00020   provided that the above copyright notice appear in all copies and that 
00021   both that copyright notice and this permission notice appear in 
00022   supporting documentation.
00023 
00024   Shigeru Chiba makes no representations about the suitability of this 
00025   software for any purpose.  It is provided "as is" without express or
00026   implied warranty.
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>             // for exit()
00040 #endif
00041 
00042 bool Ptree::show_encoded = FALSE;
00043 
00044 // error messages
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 // class Ptree
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()           // compute Caa..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 // static members
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   Equiv() returns true even if p and q are lists and all the elements
00306   are equal respectively.
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)    // return the last cons cell.
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   Nth(lst, 0) is equivalent to First(lst).
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   Length() returns a negative number if p is not a list.
00410 */
00411 int Ptree::Length(Ptree* p)
00412 {
00413     int i = 0;
00414 
00415     if(p != nil && p->IsLeaf())
00416         return -2;      /* p is not a pair */
00417 
00418     while(p != nil){
00419         ++i;
00420         if(p->IsLeaf())
00421             return -1;  /* p is a pair, but not a list. */
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 //   q may be a leaf
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   ReplaceAll() substitutes SUBST for all occurences of ORIG in LIST.
00526   It recursively searches LIST for ORIG.
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 // ShallowSubst() doesn't recursively apply substitution to a subtree.
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 /* Nconc is desctructive append */
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; // Last(p)->SetCdr(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 // class PtreeIter
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 // class PtreeArray
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 }

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