BSD 3 development
[unix-history] / usr / src / cmd / pxp / yytree.c
CommitLineData
d503ec6c
BJ
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
13extern 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\f
52/*
53 * Make a new list
54 */
55newlist(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 */
67addlist(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 */
87fixlist(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\f
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 */
105setupvar(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}