|
|
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.