Modules | Files | Inheritance Tree | Inheritance Graph | Name Index | Config
File: Synopsis/Parser/C++/occ/ptree-core.cc
    1| /*
    2|   Copyright (C) 1997-2000 Shigeru Chiba, University of Tsukuba.
    3| 
    4|   Permission to use, copy, distribute and modify this software and   
    5|   its documentation for any purpose is hereby granted without fee,        
    6|   provided that the above copyright notice appear in all copies and that 
    7|   both that copyright notice and this permission notice appear in 
    8|   supporting documentation.
    9| 
   10|   Shigeru Chiba makes no representations about the suitability of this 
   11|   software for any purpose.  It is provided "as is" without express or
   12|   implied warranty.
   13| */
   14| 
   15| #include <iostream>
   16| #include <cstring>
   17| #include "ptree.h"
   18| #include "token.h"
   19| #include "walker.h"
   20| #include "typeinfo.h"
   21| #include "buffer.h"
   22| 
   23| #if defined(_MSC_VER) || defined(IRIX_CC) || defined(__GLIBC__)
   24| #include <stdlib.h>            /
   25| #endif
   26| 
   27| bool Ptree::show_encoded = FALSE;
   28| 
   29| // error messages
   30| 
   31| void MopErrorMessage(char* where, char* msg)
   32| {
   33|     std::cerr << "MOP error: in " << where << ", " << msg << '\n';
   34|     exit(1);
   35| }
   36| 
   37| void MopErrorMessage2(char* msg1, char* msg2)
   38| {
   39|     std::cerr << "MOP error: " << msg1 << msg2 << '\n';
   40|     exit(1);
   41| }
   42| 
   43| void MopWarningMessage(char* where, char* msg)
   44| {
   45|     std::cerr << "MOP warning: in " << where << ", " << msg << '\n';
   46| }
   47| 
   48| void MopWarningMessage2(char* msg1, char* msg2)
   49| {
   50|     std::cerr << "MOP warning: " << msg1 << msg2 << '\n';
   51| }
   52| 
   53| void MopMoreWarningMessage(char* msg1, char* msg2)
   54| {
   55|     std::cerr << "             " << msg1;
   56|     if(msg2 != nil)
   57|         std::cerr << msg2;
   58| 
   59|     std::cerr << '\n';
   60| }
   61| 
   62| // class Ptree
   63| 
   64| void Ptree::Display()
   65| {
   66|     Display2(std::cerr);
   67| }
   68| 
   69| void Ptree::Display2(std::ostream& s)
   70| {
   71|     if(this == nil)
   72|         s << "nil\n";
   73|     else{
   74|         Print(s00);
   75|         s << '\n';
   76|     }
   77| }
   78| 
   79| int Ptree::Write(std::ostream& s)
   80| {
   81|     if(this == nil)
   82|         return 0;
   83|     else
   84|         return Write(s0);
   85| }
   86| 
   87| void Ptree::PrintIndent(std::ostream& out, int indent)
   88| {
   89|     out << '\n';
   90|     for(int i = 0i < indent; ++i)
   91|         out << "    ";
   92| }
   93| 
   94| charPtree::ToString()
   95| {
   96|     if(this == nil)
   97|         return nil;
   98|     else{
   99|         ProgramString ps;
  100|         WritePS(ps);
  101|         return (char*)ps.Read(0);
  102|     }
  103| }
  104| 
  105| bool Ptree::Eq(char c)
  106| {
  107|     if(this == nil)
  108|         return FALSE;
  109|     else
  110|         return(IsLeaf() && GetLength() == 1 && *GetPosition() == c);
  111| }
  112| 
  113| bool Ptree::Eq(char* str)
  114| {
  115|     if(this == nil)
  116|         return FALSE;
  117|     else if(IsLeaf()){
  118|         charp = GetPosition();
  119|         int n = GetLength();
  120|         int i;
  121|         for(i = 0i < n; ++i)
  122|             if(p[i] != str[i] || str[i] == '\0')
  123|                return FALSE;
  124| 
  125|         return bool(str[i] == '\0');
  126|     }
  127|     else
  128|         return FALSE;
  129| }
  130| 
  131| bool Ptree::Eq(char* str, int len)
  132| {
  133|     if(this != nil && IsLeaf()){
  134|         charp = GetPosition();
  135|         int n = GetLength();
  136|         if(n == len){
  137|           int i;
  138|             for(i = 0i < n; ++i)
  139|                if(p[i] != str[i])
  140|                  return FALSE;
  141| 
  142|             return TRUE;
  143|         }
  144|     }
  145| 
  146|     return FALSE;
  147| }
  148| 
  149| PtreePtree::Ca_ar()          // compu
  150| {
  151|     Ptreep = this;
  152|     while(p != nil && !p->IsLeaf())
  153|         p = p->Car();
  154| 
  155|     return p;
  156| }
  157| 
  158| charPtree::LeftMost()
  159| {
  160|     if(this == nil)
  161|         return nil;
  162|     else if(IsLeaf())
  163|         return GetPosition();
  164|     else{
  165|         Ptreep = this;
  166|         while(p != nil){
  167|             chari = p->Car()->LeftMost();
  168|             if(i != nil)
  169|                return i;
  170|         else
  171|                p = p->Cdr();
  172|         }
  173|         return nil;
  174|     }
  175| }
  176| 
  177| charPtree::RightMost()
  178| {
  179|     if(this == nil)
  180|         return nil;
  181|     else if(IsLeaf())
  182|         return GetPosition() + GetLength();
  183|     else{
  184|         int n = Length();
  185|         while(n > 0){
  186|             chari = Nth(--n)->RightMost();
  187|             if(i != nil)
  188|                return i;
  189|         }
  190| 
  191|         return nil;
  192|     }
  193| }
  194| 
  195| int Ptree::What()
  196| {
  197|     return BadToken;
  198| }
  199| 
  200| bool Ptree::IsA(int kind)
  201| {
  202|     if(this == nil)
  203|         return FALSE;
  204|     else
  205|         return bool(What() == kind);
  206| }
  207| 
  208| bool Ptree::IsA(int kind1, int kind2)
  209| {
  210|     if(this == nil)
  211|         return FALSE;
  212|     else{
  213|         int k = What();
  214|         return bool(k == kind1 || k == kind2);
  215|     }
  216| }
  217| 
  218| bool Ptree::IsA(int kind1, int kind2, int kind3)
  219| {
  220|     if(this == nil)
  221|         return FALSE;
  222|     else{
  223|         int k = What();
  224|         return bool(k == kind1 || k == kind2 || k == kind3);
  225|     }
  226| }
  227| 
  228| PtreePtree::Translate(Walker* w)
  229| {
  230|     return w->TranslatePtree(this);
  231| }
  232| 
  233| void Ptree::Typeof(Walker* w, TypeInfo& t)
  234| {
  235|     w->TypeofPtree(thist);
  236| }
  237| 
  238| charPtree::GetEncodedType()
  239| {
  240|     return nil;
  241| }
  242| 
  243| charPtree::GetEncodedName()
  244| {
  245|     return nil;
  246| }
  247| 
  248| 
  249| // static members
  250| 
  251| bool Ptree::Eq(Ptree* p, char c)
  252| {
  253|     return p->Eq(c);
  254| }
  255| 
  256| bool Ptree::Eq(Ptree* p, char* str)
  257| {
  258|     return p->Eq(str);
  259| }
  260| 
  261| bool Ptree::Eq(Ptree* p, char* str, int len)
  262| {
  263|     return p->Eq(strlen);
  264| }
  265| 
  266| bool Ptree::Eq(Ptree* p, Ptree* q)
  267| {
  268|     if(p == q)
  269|         return TRUE;
  270|     else if(p == nil || q == nil)
  271|         return FALSE;
  272|     else if(p->IsLeaf() && q->IsLeaf()){
  273|         int plen = p->GetLength();
  274|         int qlen = q->GetLength();
  275|         if(plen == qlen){
  276|             charpstr = p->GetPosition();
  277|             charqstr = q->GetPosition();
  278|             while(--plen >= 0)
  279|                if(pstr[plen] != qstr[plen])
  280|                  return FALSE;
  281| 
  282|             return TRUE;
  283|         }
  284|     }
  285| 
  286|     return FALSE;
  287| }
  288| 
  289| /*
  290|   Equiv() returns true even if p and q are lists and all the elements
  291|   are equal respectively.
  292| */
  293| bool Ptree::Equiv(Ptree* p, Ptree* q)
  294| {
  295|     if(p == q)
  296|         return TRUE;
  297|     else if(p == nil || q == nil)
  298|         return FALSE;
  299|     else if(p->IsLeaf() || q->IsLeaf())
  300|         return Eq(pq);
  301|     else{
  302|         while(p != nil && q != nil)
  303|             if(p->Car() != q->Car())
  304|                return FALSE;
  305|          else{
  306|                p = p->Cdr();
  307|                q = q->Cdr();
  308|         }
  309| 
  310|         return p == nil && q == nil;
  311|     }
  312| }
  313| 
  314| bool Ptree::Equal(Ptree* p, Ptree* q)
  315| {
  316|     if(p == q)
  317|         return TRUE;
  318|     else if(p == nil || q == nil)
  319|         return FALSE;
  320|     else if(p->IsLeaf() || q->IsLeaf())
  321|         return Eq(pq);
  322|     else
  323|         return Equal(p->Car(), q->Car()) && Equal(p->Cdr(), q->Cdr());
  324| }
  325| 
  326| PtreePtree::Last(Ptree* p)    // return the last cons c
  327| {
  328|     Ptreenext;
  329|     if(p == nil)
  330|         return nil;
  331| 
  332|     while((next = p->Cdr()) != nil)
  333|         p = next;
  334| 
  335|     return p;
  336| }
  337| 
  338| PtreePtree::First(Ptree* p)
  339| {
  340|     if(p != nil)
  341|         return p->Car();
  342|     else
  343|         return p;
  344| }
  345| 
  346| PtreePtree::Rest(Ptree* p)
  347| {
  348|     if(p != nil)
  349|         return p->Cdr();
  350|     else
  351|         return p;
  352| }
  353| 
  354| PtreePtree::Second(Ptree* p)
  355| {
  356|     if(p != nil){
  357|         p = p->Cdr();
  358|         if(p != nil)
  359|             return p->Car();
  360|     }
  361| 
  362|     return p;
  363| }
  364| 
  365| PtreePtree::Third(Ptree* p)
  366| {
  367|     if(p != nil){
  368|         p = p->Cdr();
  369|         if(p != nil){
  370|             p = p->Cdr();
  371|             if(p != nil)
  372|                return p->Car();
  373|         }
  374|     }
  375| 
  376|     return p;
  377| }
  378| 
  379| /*
  380|   Nth(lst, 0) is equivalent to First(lst).
  381| */
  382| PtreePtree::Nth(Ptree* p, int n)
  383| {
  384|     while(p != nil && n-- > 0)
  385|         p = p->Cdr();
  386| 
  387|     if(p != nil)
  388|         return p->Car();
  389|     else
  390|         return p;
  391| }
  392| 
  393| /*
  394|   Length() returns a negative number if p is not a list.
  395| */
  396| int Ptree::Length(Ptree* p)
  397| {
  398|     int i = 0;
  399| 
  400|     if(p != nil && p->IsLeaf())
  401|         return -2;     /* p is not a pa
  402| 
  403|     while(p != nil){
  404|         ++i;
  405|         if(p->IsLeaf())
  406|             return -1; /* p is a pair, but not a list. *
  407|         else
  408|             p = p->Cdr();
  409|     }
  410| 
  411|     return i;
  412| }
  413| 
  414| PtreePtree::ListTail(Ptree* p, int k)
  415| {
  416|     while(p != nil && k-- > 0)
  417|         p = p->Cdr();
  418| 
  419|     return p;
  420| }
  421| 
  422| PtreePtree::Cons(Ptree* p, Ptree* q)
  423| {
  424|     return new NonLeaf(p, q);
  425| }
  426| 
  427| PtreePtree::List(Ptree* p)
  428| {
  429|     return new NonLeaf(p, nil);
  430| }
  431| 
  432| PtreePtree::List()
  433| {
  434|     return nil;
  435| }
  436| 
  437| PtreePtree::List(Ptree* p, Ptree* q)
  438| {
  439|     return new NonLeaf(p, new NonLeaf(q, nil));
  440| }
  441| 
  442| PtreePtree::List(Ptree* p1, Ptree* p2, Ptree* p3)
  443| {
  444|     return new NonLeaf(p1, new NonLeaf(p2, new NonLeaf(p3, nil)));
  445| }
  446| 
  447| PtreePtree::List(Ptree* p1, Ptree* p2, Ptree* p3, Ptree* p4)
  448| {
  449|     return new NonLeaf(p1, List(p2, p3, p4));
  450| }
  451| 
  452| PtreePtree::List(Ptree* p1, Ptree* p2, Ptree* p3, Ptree* p4, Ptree* p5)
  453| {
  454|     return Nconc(List(p1p2), List(p3p4p5));
  455| }
  456| 
  457| PtreePtree::List(Ptree* p1, Ptree* p2, Ptree* p3, Ptree* p4, Ptree* p5,
  458|                Ptree* p6)
  459| {
  460|     return Nconc(List(p1p2p3), List(p4p5p6));
  461| }
  462| 
  463| PtreePtree::List(Ptree* p1, Ptree* p2, Ptree* p3, Ptree* p4, Ptree* p5,
  464|                   Ptree* p6, Ptree* p7)
  465| {
  466|     return Nconc(List(p1p2p3), List(p4p5p6p7));
  467| }
  468| 
  469| PtreePtree::List(Ptree* p1, Ptree* p2, Ptree* p3, Ptree* p4, Ptree* p5,
  470|                   Ptree* p6, Ptree* p7, Ptree* p8)
  471| {
  472|     return Nconc(List(p1p2p3p4), List(p5p6p7p8));
  473| }
  474| 
  475| PtreePtree::CopyList(Ptree* p)
  476| {
  477|     return Append(p, nil);
  478| }
  479| 
  480| //   q may be a leaf
  481| //
  482| PtreePtree::Append(Ptree* p, Ptree* q)
  483| {
  484|     Ptree *result, *tail;
  485| 
  486|     if(p == nil)
  487|         if(q->IsLeaf())
  488|             return Cons(q, nil);
  489|         else
  490|             return q;
  491| 
  492|     result = tail = Cons(p->Car(), nil);
  493|     p = p->Cdr();
  494|     while(p != nil){
  495|         Ptreecell = Cons(p->Car(), nil);
  496|         tail->SetCdr(cell);
  497|         tail = cell;
  498|         p = p->Cdr();
  499|     }
  500| 
  501|     if(q != nil && q->IsLeaf())
  502|         tail->SetCdr(Cons(q, nil));
  503|     else
  504|         tail->SetCdr(q);
  505| 
  506|     return result;
  507| }
  508| 
  509| /*
  510|   ReplaceAll() substitutes SUBST for all occurences of ORIG in LIST.
  511|   It recursively searches LIST for ORIG.
  512| */
  513| PtreePtree::ReplaceAll(Ptree* list, Ptree* orig, Ptree* subst)
  514| {
  515|     if(Eq(listorig))
  516|         return subst;
  517|     else if(list == nil || list->IsLeaf())
  518|         return list;
  519|     else{
  520|         PtreeArray newlist;
  521|         bool changed = FALSE;
  522|         Ptreerest = list;
  523|         while(rest != nil){
  524|             Ptreep = rest->Car();
  525|             Ptreeq = ReplaceAll(porigsubst);
  526|             newlist.Append(q);
  527|             if(p != q)
  528|                changed = TRUE;
  529| 
  530|             rest = rest->Cdr();
  531|         }
  532| 
  533|         if(changed)
  534|             return newlist.All();
  535|         else
  536|             return list;
  537|     }
  538| }
  539| 
  540| PtreePtree::Subst(Ptree* newone, Ptree* old, Ptree* tree)
  541| {
  542|     if(old == tree)
  543|         return newone;
  544|     else if(tree== nil || tree->IsLeaf())
  545|         return tree;
  546|     else{
  547|         Ptreehead = tree->Car();
  548|         Ptreehead2 = Subst(newoneoldhead);
  549|         Ptreetail = tree->Cdr();
  550|         Ptreetail2 = (tail == nil) ? tail : Subst(newoneoldtail);
  551|         if(head == head2 && tail == tail2)
  552|             return tree;
  553|         else
  554|             return Cons(head2tail2);
  555|     }
  556| }
  557| 
  558| PtreePtree::Subst(Ptree* newone1, Ptree* old1, Ptree* newone2, Ptree* old2,
  559|                 Ptree* tree)
  560| {
  561|     if(old1 == tree)
  562|         return newone1;
  563|     else if(old2 == tree)
  564|         return newone2;
  565|     else if(tree == nil || tree->IsLeaf())
  566|         return tree;
  567|     else{
  568|         Ptreehead = tree->Car();
  569|         Ptreehead2 = Subst(newone1old1newone2old2head);
  570|         Ptreetail = tree->Cdr();
  571|         Ptreetail2 = (tail == nil) ? tail
  572|                       Subst(newone1old1newone2old2tail);
  573|         if(head == head2 && tail == tail2)
  574|             return tree;
  575|         else
  576|             return Cons(head2tail2);
  577|     }
  578| }
  579| 
  580| PtreePtree::Subst(Ptree* newone1, Ptree* old1, Ptree* newone2, Ptree* old2,
  581|                    Ptree* newone3, Ptree* old3, Ptree* tree)
  582| {
  583|     if(old1 == tree)
  584|         return newone1;
  585|     else if(old2 == tree)
  586|         return newone2;
  587|     else if(old3 == tree)
  588|         return newone3;
  589|     else if(tree == nil || tree->IsLeaf())
  590|         return tree;
  591|     else{
  592|         Ptreehead = tree->Car();
  593|         Ptreehead2 = Subst(newone1old1newone2old2,
  594|                           newone3old3head);
  595|         Ptreetail = tree->Cdr();
  596|         Ptreetail2 = (tail == nil) ? tail :
  597|                       Subst(newone1old1newone2old2,
  598|                            newone3old3tail);
  599|         if(head == head2 && tail == tail2)
  600|             return tree;
  601|         else
  602|             return Cons(head2tail2);
  603|     }
  604| }
  605| 
  606| // ShallowSubst() doesn't recursively apply substitution to a subtree.
  607| 
  608| PtreePtree::ShallowSubst(Ptree* newone, Ptree* old, Ptree* tree)
  609| {
  610|     if(old == tree)
  611|         return newone;
  612|     else if(tree== nil || tree->IsLeaf())
  613|         return tree;
  614|     else{
  615|         Ptree *head, *head2;
  616|         head = tree->Car();
  617|         if(old == head)
  618|             head2 = newone;
  619|         else
  620|             head2 = head;
  621| 
  622|         Ptreetail = tree->Cdr();
  623|         Ptreetail2 = (tail == nil) ? tail : ShallowSubst(newoneoldtail);
  624|         if(head == head2 && tail == tail2)
  625|             return tree;
  626|         else
  627|             return Cons(head2tail2);
  628|     }
  629| }
  630| 
  631| PtreePtree::ShallowSubst(Ptree* newone1, Ptree* old1,
  632|                          Ptree* newone2, Ptree* old2, Ptree* tree)
  633| {
  634|     if(old1 == tree)
  635|         return newone1;
  636|     else if(old2 == tree)
  637|         return newone2;
  638|     else if(tree == nil || tree->IsLeaf())
  639|         return tree;
  640|     else{
  641|         Ptree *head, *head2;
  642|         head = tree->Car();
  643|         if(old1 == head)
  644|             head2 = newone1;
  645|         else if(old2 == head)
  646|             head2 = newone2;
  647|         else
  648|             head2 = head;
  649| 
  650|         Ptreetail = tree->Cdr();
  651|         Ptreetail2 = (tail == nil) ? tail :
  652|                       ShallowSubst(newone1old1newone2old2tail);
  653|         if(head == head2 && tail == tail2)
  654|             return tree;
  655|         else
  656|             return Cons(head2tail2);
  657|     }
  658| }
  659| 
  660| PtreePtree::ShallowSubst(Ptree* newone1, Ptree* old1,
  661|                          Ptree* newone2, Ptree* old2,
  662|                          Ptree* newone3, Ptree* old3, Ptree* tree)
  663| {
  664|     if(old1 == tree)
  665|         return newone1;
  666|     else if(old2 == tree)
  667|         return newone2;
  668|     else if(old3 == tree)
  669|         return newone3;
  670|     else if(tree == nil || tree->IsLeaf())
  671|         return tree;
  672|     else{
  673|         Ptree *head, *head2;
  674|         head = tree->Car();
  675|         if(old1 == head)
  676|             head2 = newone1;
  677|         else if(old2 == head)
  678|             head2 = newone2;
  679|         else if(old3 == head)
  680|             head2 = newone3;
  681|         else
  682|             head2 = head;
  683| 
  684|         Ptreetail = tree->Cdr();
  685|         Ptreetail2 = (tail == nil) ? tail :
  686|                       ShallowSubst(newone1old1newone2old2,
  687|                              newone3old3tail);
  688|         if(head == head2 && tail == tail2)
  689|             return tree;
  690|         else
  691|             return Cons(head2tail2);
  692|     }
  693| }
  694| 
  695| PtreePtree::ShallowSubst(Ptree* newone1, Ptree* old1,
  696|                          Ptree* newone2, Ptree* old2,
  697|                          Ptree* newone3, Ptree* old3,
  698|                          Ptree* newone4, Ptree* old4, Ptree* tree)
  699| {
  700|     if(old1 == tree)
  701|         return newone1;
  702|     else if(old2 == tree)
  703|         return newone2;
  704|     else if(old3 == tree)
  705|         return newone3;
  706|     else if(old4 == tree)
  707|         return newone4;
  708|     else if(tree == nil || tree->IsLeaf())
  709|         return tree;
  710|     else{
  711|         Ptree *head, *head2;
  712|         head = tree->Car();
  713|         if(old1 == head)
  714|             head2 = newone1;
  715|         else if(old2 == head)
  716|             head2 = newone2;
  717|         else if(old3 == head)
  718|             head2 = newone3;
  719|         else if(old4 == head)
  720|             head2 = newone4;
  721|         else
  722|             head2 = head;
  723| 
  724|         Ptreetail = tree->Cdr();
  725|         Ptreetail2 =  (tail == nil) ? tail :
  726|                       ShallowSubst(newone1old1newone2old2,
  727|                                   newone3old3newone4old4tail);
  728|         if(head == head2 && tail == tail2)
  729|             return tree;
  730|         else
  731|             return Cons(head2tail2);
  732|     }
  733| }
  734| 
  735| PtreePtree::SubstSublist(Ptree* newsub, Ptree* oldsub, Ptree* lst)
  736| {
  737|     if(lst == oldsub)
  738|         return newsub;
  739|     else
  740|         return Cons(lst->Car(), SubstSublist(newsuboldsublst->Cdr()));
  741| }
  742| 
  743| PtreePtree::Snoc(Ptree* p, Ptree* q)
  744| {
  745|     return Nconc(pCons(q, nil));
  746| }
  747| 
  748| /* Nconc is desctructive append */
  749| 
  750| PtreePtree::Nconc(Ptree* p, Ptree* q)
  751| {
  752|     if(p == nil)
  753|         return q;
  754|     else{
  755|         Last(p)->data.nonleaf.next = q;        // Last(p)->Se
  756|         return p;
  757|     }
  758| }
  759| 
  760| PtreePtree::Nconc(Ptree* p, Ptree* q, Ptree* r)
  761| {
  762|     return Nconc(pNconc(qr));
  763| }
  764| 
  765| 
  766| // class PtreeIter
  767| 
  768| PtreePtreeIter::Pop()
  769| {
  770|     if(ptree == nil)
  771|         return nil;
  772|     else{
  773|         Ptreep = ptree->Car();
  774|         ptree = ptree->Cdr();
  775|         return p;
  776|     }
  777| }
  778| 
  779| bool PtreeIter::Next(Ptree*& car)
  780| {
  781|     if(ptree == nil)
  782|         return FALSE;
  783|     else{
  784|         car = ptree->Car();
  785|         ptree = ptree->Cdr();
  786|         return TRUE;
  787|     }
  788| }
  789| 
  790| PtreePtreeIter::This()
  791| {
  792|     if(ptree == nil)
  793|         return nil;
  794|     else
  795|         return ptree->Car();
  796| }
  797| 
  798| // class PtreeArray
  799| 
  800| PtreeArray::PtreeArray(int s)
  801| {
  802|     num = 0;
  803|     if(s > 8){
  804|         size = s;
  805|         array = new (GC) Ptree*[s];
  806|     }
  807|     else{
  808|         size = 8;
  809|         array = default_buf;
  810|     }
  811| }
  812| 
  813| void PtreeArray::Append(Ptree* p)
  814| {
  815|     if(num >= size){
  816|         size += 8;
  817|         Ptree** a = new (GC) Ptree*[size];
  818|         memmove(aarray, size_t(num * sizeof(Ptree*)));
  819|         array = a;
  820|     }
  821| 
  822|     array[num++] = p;
  823| }
  824| 
  825| Ptree*& PtreeArray::Ref(uint i)
  826| {
  827|     if(i < num)
  828|         return array[i];
  829|     else{
  830|         MopErrorMessage("PtreeArray""out of range");
  831|         return array[0];
  832|     }
  833| }
  834| 
  835| PtreePtreeArray::All()
  836| {
  837|     Ptreelst = nil;
  838| 
  839|     for(sint i = Number() - 1i >= 0; --i)
  840|         lst = Ptree::Cons(Ref(i), lst);
  841| 
  842|     return lst;
  843| }