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