1796Speter /* Copyright (c) 1979 Regents of the University of California */ 2796Speter 3*14749Sthien #ifndef lint 4*14749Sthien static char sccsid[] = "@(#)yytree.c 1.2 08/19/83"; 5*14749Sthien #endif 6796Speter 7796Speter #include "whoami.h" 8796Speter #include "0.h" 9796Speter #include "tree.h" 10*14749Sthien #include "tree_ty.h" 11796Speter 12796Speter extern int *spacep; 13796Speter 14796Speter /* 15796Speter * LIST MANIPULATION ROUTINES 16796Speter * 17796Speter * The grammar for Pascal is written left recursively. 18796Speter * Because of this, the portions of parse trees which are to resemble 19796Speter * lists are in the somewhat inconvenient position of having 20796Speter * the nodes built from left to right, while we want to eventually 21796Speter * have as semantic value the leftmost node. 22796Speter * We could carry the leftmost node as semantic value, but this 23796Speter * would be inefficient as to add a new node to the list we would 24796Speter * have to chase down to the end. Other solutions involving a head 25796Speter * and tail pointer waste space. 26796Speter * 27796Speter * The simple solution to this apparent dilemma is to carry along 28796Speter * a pointer to the leftmost node in a list in the rightmost node 29796Speter * which is the current semantic value of the list. 30796Speter * When we have completed building the list, we can retrieve this 31796Speter * left end pointer very easily; neither adding new elements to the list 32796Speter * nor finding the left end is thus expensive. As the bottommost node 33796Speter * has an unused next pointer in it, no space is wasted either. 34796Speter * 35796Speter * The nodes referred to here are of the T_LISTPP type and have 36796Speter * the form: 37796Speter * 38796Speter * T_LISTPP some_pointer next_element 39796Speter * 40796Speter * Here some_pointer points to the things of interest in the list, 41796Speter * and next_element to the next thing in the list except for the 42796Speter * rightmost node, in which case it points to the leftmost node. 43796Speter * The next_element of the rightmost node is of course zapped to the 44796Speter * NIL pointer when the list is completed. 45796Speter * 46796Speter * Thinking of the lists as tree we heceforth refer to the leftmost 47796Speter * node as the "top", and the rightmost node as the "bottom" or as 48796Speter * the "virtual root". 49796Speter */ 50796Speter 51796Speter /* 52796Speter * Make a new list 53796Speter */ 54*14749Sthien struct tnode * 55796Speter newlist(new) 56*14749Sthien register struct tnode *new; 57796Speter { 58796Speter 59*14749Sthien if (new == TR_NIL) 60*14749Sthien return (TR_NIL); 61*14749Sthien return ((struct tnode *) tree3(T_LISTPP, (int) new, 62*14749Sthien (struct tnode *) spacep)); 63796Speter } 64796Speter 65796Speter /* 66796Speter * Add a new element to an existing list 67796Speter */ 68*14749Sthien struct tnode * 69796Speter addlist(vroot, new) 70*14749Sthien register struct tnode *vroot; 71*14749Sthien struct tnode *new; 72796Speter { 73*14749Sthien register struct tnode *top; 74796Speter 75*14749Sthien if (new == TR_NIL) 76796Speter return (vroot); 77*14749Sthien if (vroot == TR_NIL) 78796Speter return (newlist(new)); 79*14749Sthien top = vroot->list_node.next; 80*14749Sthien vroot->list_node.next = (struct tnode *) spacep; 81*14749Sthien return ((struct tnode *) tree3(T_LISTPP, (int) new, top)); 82796Speter } 83796Speter 84796Speter /* 85796Speter * Fix up the list which has virtual root vroot. 86796Speter * We grab the top pointer and return it, zapping the spot 87796Speter * where it was so that the tree is not circular. 88796Speter */ 89*14749Sthien struct tnode * 90796Speter fixlist(vroot) 91*14749Sthien register struct tnode *vroot; 92796Speter { 93*14749Sthien register struct tnode *top; 94796Speter 95*14749Sthien if (vroot == TR_NIL) 96*14749Sthien return (TR_NIL); 97*14749Sthien top = vroot->list_node.next; 98*14749Sthien vroot->list_node.next = TR_NIL; 99796Speter return (top); 100796Speter } 101796Speter 102796Speter 103796Speter /* 104796Speter * Set up a T_VAR node for a qualified variable. 105796Speter * Init is the initial entry in the qualification, 106796Speter * or NIL if there is none. 107796Speter * 108796Speter * if we are building pTrees, there has to be an extra slot for 109796Speter * a pointer to the namelist entry of a field, if this T_VAR refers 110796Speter * to a field name within a WITH statement. 111796Speter * this extra field is set in lvalue, and used in VarCopy. 112796Speter */ 113*14749Sthien struct tnode * 114796Speter setupvar(var, init) 115796Speter char *var; 116*14749Sthien register struct tnode *init; 117796Speter { 118796Speter 119*14749Sthien if (init != TR_NIL) 120796Speter init = newlist(init); 121796Speter # ifndef PTREE 122*14749Sthien return (tree4(T_VAR, NOCON, (struct tnode *) var, init)); 123796Speter # else 124*14749Sthien return tree5( T_VAR, NOCON, (struct tnode *) var, init, TR_NIL ); 125796Speter # endif 126796Speter } 127796Speter 128796Speter /* 129796Speter * set up a T_TYREC node for a record 130796Speter * 131796Speter * if we are building pTrees, there has to be an extra slot for 132796Speter * a pointer to the namelist entry of the record. 133796Speter * this extra field is filled in in gtype, and used in RecTCopy. 134796Speter */ 135*14749Sthien struct tnode * 136*14749Sthien setuptyrec( line , fldlist ) 137796Speter int line; 138*14749Sthien struct tnode *fldlist; 139796Speter { 140796Speter 141796Speter # ifndef PTREE 142*14749Sthien return tree3( T_TYREC , line , fldlist ); 143796Speter # else 144*14749Sthien return tree4( T_TYREC , line , fldlst , TR_NIL ); 145796Speter # endif 146796Speter } 147796Speter 148796Speter /* 149796Speter * set up a T_FIELD node for a field. 150796Speter * 151796Speter * if we are building pTrees, there has to be an extra slot for 152796Speter * a pointer to the namelist entry of the field. 153796Speter * this extra field is set in lvalue, and used in SelCopy. 154796Speter */ 155*14749Sthien struct tnode * 156796Speter setupfield( field , other ) 157*14749Sthien struct tnode *field; 158*14749Sthien struct tnode *other; 159796Speter { 160796Speter 161796Speter # ifndef PTREE 162*14749Sthien return tree3( T_FIELD , (int) field , other ); 163796Speter # else 164*14749Sthien return tree4( T_FIELD , (int) field , other , TR_NIL ); 165796Speter # endif 166796Speter } 167