xref: /csrg-svn/usr.bin/pascal/src/yyid.c (revision 786)
1*786Speter /* Copyright (c) 1979 Regents of the University of California */
2*786Speter 
3*786Speter static	char sccsid[] = "@(#)yyid.c 1.1 08/27/80";
4*786Speter 
5*786Speter #include "whoami.h"
6*786Speter #include "0.h"
7*786Speter #include "yy.h"
8*786Speter 
9*786Speter #ifdef PI
10*786Speter extern	int *yypv;
11*786Speter /*
12*786Speter  * Determine whether the identifier whose name
13*786Speter  * is "cp" can possibly be a kind, which is a
14*786Speter  * namelist class.  We look through the symbol
15*786Speter  * table for the first instance of cp as a non-field,
16*786Speter  * and at all instances of cp as a field.
17*786Speter  * If any of these are ok, we return true, else false.
18*786Speter  * It would be much better to handle with's correctly,
19*786Speter  * even to just know whether we are in a with at all.
20*786Speter  *
21*786Speter  * Note that we don't disallow constants on the lhs of assignment.
22*786Speter  */
23*786Speter identis(cp, kind)
24*786Speter 	register char *cp;
25*786Speter 	int kind;
26*786Speter {
27*786Speter 	register struct nl *p;
28*786Speter 	int i;
29*786Speter 
30*786Speter 	/*
31*786Speter 	 * Cp is NIL when error recovery inserts it.
32*786Speter 	 */
33*786Speter 	if (cp == NIL)
34*786Speter 		return (1);
35*786Speter 
36*786Speter 	/*
37*786Speter 	 * Record kind we want for possible later use by yyrecover
38*786Speter 	 */
39*786Speter 	yyidwant = kind;
40*786Speter 	yyidhave = NIL;
41*786Speter 	i = ( (int) cp ) & 077;
42*786Speter 	for (p = disptab[i]; p != NIL; p = p->nl_next)
43*786Speter 		if (p->symbol == cp) {
44*786Speter 			if (yyidok(p, kind))
45*786Speter 				goto gotit;
46*786Speter 			if (p->class != FIELD && p->class != BADUSE)
47*786Speter 				break;
48*786Speter 		}
49*786Speter 	if (p != NIL)
50*786Speter 		for (p = p->nl_next; p != NIL; p = p->nl_next)
51*786Speter 			if (p->symbol == cp && p->class == FIELD && yyidok(p, kind))
52*786Speter 				goto gotit;
53*786Speter 	return (0);
54*786Speter gotit:
55*786Speter 	if (p->class == BADUSE && !Recovery) {
56*786Speter 		yybadref(p, OY.Yyeline);
57*786Speter 		yypv[0] = NIL;
58*786Speter 	}
59*786Speter 	return (1);
60*786Speter }
61*786Speter 
62*786Speter /*
63*786Speter  * A bad reference to the identifier cp on line
64*786Speter  * line and use implying the addition of kindmask
65*786Speter  * to the mask of kind information.
66*786Speter  */
67*786Speter yybaduse(cp, line, kindmask)
68*786Speter 	register char *cp;
69*786Speter 	int line, kindmask;
70*786Speter {
71*786Speter 	register struct nl *p, *oldp;
72*786Speter 	int i;
73*786Speter 
74*786Speter 	i = ( (int) cp ) & 077;
75*786Speter 	for (p = disptab[i]; p != NIL; p = p->nl_next)
76*786Speter 		if (p->symbol == cp)
77*786Speter 			break;
78*786Speter 	oldp = p;
79*786Speter 	if (p == NIL || p->class != BADUSE)
80*786Speter 		p = enter(defnl(cp, BADUSE, 0, 0));
81*786Speter 	p->value[NL_KINDS] =| kindmask;
82*786Speter 	yybadref(p, line);
83*786Speter 	return (oldp);
84*786Speter }
85*786Speter 
86*786Speter     /*
87*786Speter      *	ud is initialized so that esavestr will allocate
88*786Speter      *	sizeof ( struct udinfo ) bytes for the 'real' struct udinfo
89*786Speter      */
90*786Speter struct	udinfo ud = { ~0 , ~0 , 0};
91*786Speter /*
92*786Speter  * Record a reference to an undefined identifier,
93*786Speter  * or one which is improperly used.
94*786Speter  */
95*786Speter yybadref(p, line)
96*786Speter 	register struct nl *p;
97*786Speter 	int line;
98*786Speter {
99*786Speter 	register struct udinfo *udp;
100*786Speter 
101*786Speter 	if (p->chain != NIL && p->chain->ud_line == line)
102*786Speter 		return;
103*786Speter 	udp = esavestr(&ud);
104*786Speter 	udp->ud_line = line;
105*786Speter 	udp->ud_next = p->chain;
106*786Speter 	p->chain = udp;
107*786Speter }
108*786Speter 
109*786Speter #define	varkinds	((1<<CONST)|(1<<VAR)|(1<<REF)|(1<<ARRAY)|(1<<PTR)|(1<<RECORD)|(1<<FIELD)|(1<<FUNC)|(1<<FVAR))
110*786Speter /*
111*786Speter  * Is the symbol in the p entry of the namelist
112*786Speter  * even possibly a kind kind?  If not, update
113*786Speter  * what we have based on this encounter.
114*786Speter  */
115*786Speter yyidok(p, kind)
116*786Speter 	register struct nl *p;
117*786Speter 	int kind;
118*786Speter {
119*786Speter 
120*786Speter 	if (p->class == BADUSE) {
121*786Speter 		if (kind == VAR)
122*786Speter 			return (p->value[0] & varkinds);
123*786Speter 		return (p->value[0] & (1 << kind));
124*786Speter 	}
125*786Speter 	if (yyidok1(p, kind))
126*786Speter 		return (1);
127*786Speter 	if (yyidhave != NIL)
128*786Speter 		yyidhave = IMPROPER;
129*786Speter 	else
130*786Speter 		yyidhave = p->class;
131*786Speter 	return (0);
132*786Speter }
133*786Speter 
134*786Speter yyidok1(p, kind)
135*786Speter 	register struct nl *p;
136*786Speter 	int kind;
137*786Speter {
138*786Speter 	int i;
139*786Speter 
140*786Speter 	switch (kind) {
141*786Speter 		case FUNC:
142*786Speter 			if (p->class == FVAR)
143*786Speter 				return(1);
144*786Speter 		case CONST:
145*786Speter 		case TYPE:
146*786Speter 		case PROC:
147*786Speter 		case FIELD:
148*786Speter 			return (p->class == kind);
149*786Speter 		case VAR:
150*786Speter 			return (p->class == CONST || yyisvar(p, NIL));
151*786Speter 		case ARRAY:
152*786Speter 		case RECORD:
153*786Speter 			return (yyisvar(p, kind));
154*786Speter 		case PTRFILE:
155*786Speter 			return (yyisvar(p, PTR) || yyisvar(p, FILET));
156*786Speter 	}
157*786Speter }
158*786Speter 
159*786Speter yyisvar(p, class)
160*786Speter 	register struct nl *p;
161*786Speter 	int class;
162*786Speter {
163*786Speter 
164*786Speter 	switch (p->class) {
165*786Speter 		case FIELD:
166*786Speter 		case VAR:
167*786Speter 		case REF:
168*786Speter 		case FVAR:
169*786Speter 		/*
170*786Speter 		 * We would prefer to return
171*786Speter 		 * parameterless functions only.
172*786Speter 		 */
173*786Speter 		case FUNC:
174*786Speter 			return (class == NIL || (p->type != NIL && p->type->class == class));
175*786Speter 	}
176*786Speter 	return (0);
177*786Speter }
178*786Speter #endif
179*786Speter #ifdef PXP
180*786Speter #ifndef DEBUG
181*786Speter identis()
182*786Speter {
183*786Speter 
184*786Speter 	return (1);
185*786Speter }
186*786Speter #endif
187*786Speter #ifdef DEBUG
188*786Speter extern	char *classes[];
189*786Speter 
190*786Speter char	kindchars[]	"UCTVAQRDPF";
191*786Speter /*
192*786Speter  * Fake routine "identis" for pxp when testing error recovery.
193*786Speter  * Looks at letters in variable names to answer questions
194*786Speter  * about attributes.  Mapping is
195*786Speter  *	C	const_id
196*786Speter  *	T	type_id
197*786Speter  *	V	var_id		also if any of AQRDF
198*786Speter  *	A	array_id
199*786Speter  *	Q	ptr_id
200*786Speter  *	R	record_id
201*786Speter  *	D	field_id	D for "dot"
202*786Speter  *	P	proc_id
203*786Speter  *	F	func_id
204*786Speter  */
205*786Speter identis(cp, kind)
206*786Speter 	register char *cp;
207*786Speter 	int kind;
208*786Speter {
209*786Speter 	register char *dp;
210*786Speter 	char kindch;
211*786Speter 
212*786Speter 	/*
213*786Speter 	 * Don't do anything unless -T
214*786Speter 	 */
215*786Speter 	if (!typetest)
216*786Speter 		return (1);
217*786Speter 
218*786Speter 	/*
219*786Speter 	 * Inserted symbols are always correct
220*786Speter 	 */
221*786Speter 	if (cp == NIL)
222*786Speter 		return (1);
223*786Speter 	/*
224*786Speter 	 * Set up the names for error messages
225*786Speter 	 */
226*786Speter 	yyidwant = classes[kind];
227*786Speter 	for (dp = kindchars; *dp; dp++)
228*786Speter 		if (any(cp, *dp)) {
229*786Speter 			yyidhave = classes[dp - kindchars];
230*786Speter 			break;
231*786Speter 		}
232*786Speter 
233*786Speter 	/*
234*786Speter 	 * U in the name means undefined
235*786Speter 	 */
236*786Speter 	if (any(cp, 'U'))
237*786Speter 		return (0);
238*786Speter 
239*786Speter 	kindch = kindchars[kind];
240*786Speter 	if (kindch == 'V')
241*786Speter 		for (dp = "AQRDF"; *dp; dp++)
242*786Speter 			if (any(cp, *dp))
243*786Speter 				return (1);
244*786Speter 	return (any(cp, kindch));
245*786Speter }
246*786Speter #endif
247*786Speter #endif
248