|
|
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.2 January 1979
8: */
9:
10: #include "0.h"
11: #include "tree.h"
12:
13: extern int *spacep;
14:
15: /*
16: * LIST MANIPULATION ROUTINES
17: *
18: * The grammar for Pascal is written left recursively.
19: * Because of this, the portions of parse trees which are to resemble
20: * lists are in the somewhat inconvenient position of having
21: * the nodes built from left to right, while we want to eventually
22: * have as semantic value the leftmost node.
23: * We could carry the leftmost node as semantic value, but this
24: * would be inefficient as to add a new node to the list we would
25: * have to chase down to the end. Other solutions involving a head
26: * and tail pointer waste space.
27: *
28: * The simple solution to this apparent dilemma is to carry along
29: * a pointer to the leftmost node in a list in the rightmost node
30: * which is the current semantic value of the list.
31: * When we have completed building the list, we can retrieve this
32: * left end pointer very easily; neither adding new elements to the list
33: * nor finding the left end is thus expensive. As the bottommost node
34: * has an unused next pointer in it, no space is wasted either.
35: *
36: * The nodes referred to here are of the T_LISTPP type and have
37: * the form:
38: *
39: * T_LISTPP some_pointer next_element
40: *
41: * Here some_pointer points to the things of interest in the list,
42: * and next_element to the next thing in the list except for the
43: * rightmost node, in which case it points to the leftmost node.
44: * The next_element of the rightmost node is of course zapped to the
45: * NIL pointer when the list is completed.
46: *
47: * Thinking of the lists as tree we heceforth refer to the leftmost
48: * node as the "top", and the rightmost node as the "bottom" or as
49: * the "virtual root".
50: */
51:
52: /*
53: * Make a new list
54: */
55: newlist(new)
56: register int *new;
57: {
58:
59: if (new == NIL)
60: return (NIL);
61: return (tree3(T_LISTPP, new, spacep));
62: }
63:
64: /*
65: * Add a new element to an existing list
66: */
67: addlist(vroot, new)
68: register int *vroot;
69: int *new;
70: {
71: register int *top;
72:
73: if (new == NIL)
74: return (vroot);
75: if (vroot == NIL)
76: return (newlist(new));
77: top = vroot[2];
78: vroot[2] = spacep;
79: return (tree3(T_LISTPP, new, top));
80: }
81:
82: /*
83: * Fix up the list which has virtual root vroot.
84: * We grab the top pointer and return it, zapping the spot
85: * where it was so that the tree is not circular.
86: */
87: fixlist(vroot)
88: register int *vroot;
89: {
90: register int *top;
91:
92: if (vroot == NIL)
93: return (NIL);
94: top = vroot[2];
95: vroot[2] = NIL;
96: return (top);
97: }
98:
99:
100: /*
101: * Set up a T_VAR node for a qualified variable.
102: * Init is the initial entry in the qualification,
103: * or NIL if there is none.
104: */
105: setupvar(var, init)
106: char *var;
107: register int *init;
108: {
109:
110: if (init != NIL)
111: init = newlist(init);
112: return (tree4(T_VAR, NOCON, var, init));
113: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.