|
|
1.1 ! root 1: /* Copyright (c) 1979 Regents of the University of California */ ! 2: # ! 3: /* ! 4: * pxp - Pascal execution profiler ! 5: * ! 6: * Bill Joy UCB ! 7: * Version 1.1 February 1978 ! 8: */ ! 9: ! 10: #include "whoami" ! 11: #include "0.h" ! 12: #include "tree.h" ! 13: ! 14: extern int *spacep; ! 15: ! 16: /* ! 17: * LIST MANIPULATION ROUTINES ! 18: * ! 19: * The grammar for Pascal is written left recursively. ! 20: * Because of this, the portions of parse trees which are to resemble ! 21: * lists are in the somewhat inconvenient position of having ! 22: * the nodes built from left to right, while we want to eventually ! 23: * have as semantic value the leftmost node. ! 24: * We could carry the leftmost node as semantic value, but this ! 25: * would be inefficient as to add a new node to the list we would ! 26: * have to chase down to the end. Other solutions involving a head ! 27: * and tail pointer waste space. ! 28: * ! 29: * The simple solution to this apparent dilemma is to carry along ! 30: * a pointer to the leftmost node in a list in the rightmost node ! 31: * which is the current semantic value of the list. ! 32: * When we have completed building the list, we can retrieve this ! 33: * left end pointer very easily; neither adding new elements to the list ! 34: * nor finding the left end is thus expensive. As the bottommost node ! 35: * has an unused next pointer in it, no space is wasted either. ! 36: * ! 37: * The nodes referred to here are of the T_LISTPP type and have ! 38: * the form: ! 39: * ! 40: * T_LISTPP some_pointer next_element ! 41: * ! 42: * Here some_pointer points to the things of interest in the list, ! 43: * and next_element to the next thing in the list except for the ! 44: * rightmost node, in which case it points to the leftmost node. ! 45: * The next_element of the rightmost node is of course zapped to the ! 46: * NIL pointer when the list is completed. ! 47: * ! 48: * Thinking of the lists as tree we heceforth refer to the leftmost ! 49: * node as the "top", and the rightmost node as the "bottom" or as ! 50: * the "virtual root". ! 51: */ ! 52: ! 53: /* ! 54: * Make a new list ! 55: */ ! 56: newlist(new) ! 57: register int *new; ! 58: { ! 59: ! 60: if (new == NIL) ! 61: return (NIL); ! 62: return (tree3(T_LISTPP, new, spacep)); ! 63: } ! 64: ! 65: /* ! 66: * Add a new element to an existing list ! 67: */ ! 68: addlist(vroot, new) ! 69: register int *vroot; ! 70: int *new; ! 71: { ! 72: register int *top; ! 73: ! 74: if (new == NIL) ! 75: return (vroot); ! 76: if (vroot == NIL) ! 77: return (newlist(new)); ! 78: top = vroot[2]; ! 79: vroot[2] = spacep; ! 80: return (tree3(T_LISTPP, new, top)); ! 81: } ! 82: ! 83: /* ! 84: * Fix up the list which has virtual root vroot. ! 85: * We grab the top pointer and return it, zapping the spot ! 86: * where it was so that the tree is not circular. ! 87: */ ! 88: fixlist(vroot) ! 89: register int *vroot; ! 90: { ! 91: register int *top; ! 92: ! 93: if (vroot == NIL) ! 94: return (NIL); ! 95: top = vroot[2]; ! 96: vroot[2] = NIL; ! 97: return (top); ! 98: } ! 99: ! 100: ! 101: /* ! 102: * Set up a T_VAR node for a qualified variable. ! 103: * Init is the initial entry in the qualification, ! 104: * or NIL if there is none. ! 105: * ! 106: * if we are building pTrees, there has to be an extra slot for ! 107: * a pointer to the namelist entry of a field, if this T_VAR refers ! 108: * to a field name within a WITH statement. ! 109: * this extra field is set in lvalue, and used in VarCopy. ! 110: */ ! 111: setupvar(var, init) ! 112: char *var; ! 113: register int *init; ! 114: { ! 115: ! 116: if (init != NIL) ! 117: init = newlist(init); ! 118: # ifndef PTREE ! 119: return (tree4(T_VAR, NOCON, var, init)); ! 120: # else ! 121: return tree5( T_VAR , NOCON , var , init , NIL ); ! 122: # endif ! 123: } ! 124: ! 125: /* ! 126: * set up a T_TYREC node for a record ! 127: * ! 128: * if we are building pTrees, there has to be an extra slot for ! 129: * a pointer to the namelist entry of the record. ! 130: * this extra field is filled in in gtype, and used in RecTCopy. ! 131: */ ! 132: setuptyrec( line , fldlst ) ! 133: int line; ! 134: int *fldlst; ! 135: { ! 136: ! 137: # ifndef PTREE ! 138: return tree3( T_TYREC , line , fldlst ); ! 139: # else ! 140: return tree4( T_TYREC , line , fldlst , NIL ); ! 141: # endif ! 142: } ! 143: ! 144: /* ! 145: * set up a T_FIELD node for a field. ! 146: * ! 147: * if we are building pTrees, there has to be an extra slot for ! 148: * a pointer to the namelist entry of the field. ! 149: * this extra field is set in lvalue, and used in SelCopy. ! 150: */ ! 151: setupfield( field , other ) ! 152: int *field; ! 153: int *other; ! 154: { ! 155: ! 156: # ifndef PTREE ! 157: return tree3( T_FIELD , field , other ); ! 158: # else ! 159: return tree4( T_FIELD , field , other , NIL ); ! 160: # endif ! 161: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.