xref: /csrg-svn/usr.bin/pascal/src/yyid.c (revision 3085)
1786Speter /* Copyright (c) 1979 Regents of the University of California */
2786Speter 
3*3085Smckusic static char sccsid[] = "@(#)yyid.c 1.3 03/08/81";
4786Speter 
5786Speter #include "whoami.h"
6786Speter #include "0.h"
7786Speter #include "yy.h"
8786Speter 
9786Speter #ifdef PI
10786Speter extern	int *yypv;
11786Speter /*
12786Speter  * Determine whether the identifier whose name
13786Speter  * is "cp" can possibly be a kind, which is a
14786Speter  * namelist class.  We look through the symbol
15786Speter  * table for the first instance of cp as a non-field,
16786Speter  * and at all instances of cp as a field.
17786Speter  * If any of these are ok, we return true, else false.
18786Speter  * It would be much better to handle with's correctly,
19786Speter  * even to just know whether we are in a with at all.
20786Speter  *
21786Speter  * Note that we don't disallow constants on the lhs of assignment.
22786Speter  */
23786Speter identis(cp, kind)
24786Speter 	register char *cp;
25786Speter 	int kind;
26786Speter {
27786Speter 	register struct nl *p;
28786Speter 	int i;
29786Speter 
30786Speter 	/*
31786Speter 	 * Cp is NIL when error recovery inserts it.
32786Speter 	 */
33786Speter 	if (cp == NIL)
34786Speter 		return (1);
35786Speter 
36786Speter 	/*
37786Speter 	 * Record kind we want for possible later use by yyrecover
38786Speter 	 */
39786Speter 	yyidwant = kind;
40786Speter 	yyidhave = NIL;
41786Speter 	i = ( (int) cp ) & 077;
42786Speter 	for (p = disptab[i]; p != NIL; p = p->nl_next)
43786Speter 		if (p->symbol == cp) {
44786Speter 			if (yyidok(p, kind))
45786Speter 				goto gotit;
46786Speter 			if (p->class != FIELD && p->class != BADUSE)
47786Speter 				break;
48786Speter 		}
49786Speter 	if (p != NIL)
50786Speter 		for (p = p->nl_next; p != NIL; p = p->nl_next)
51786Speter 			if (p->symbol == cp && p->class == FIELD && yyidok(p, kind))
52786Speter 				goto gotit;
53786Speter 	return (0);
54786Speter gotit:
55786Speter 	if (p->class == BADUSE && !Recovery) {
56786Speter 		yybadref(p, OY.Yyeline);
57786Speter 		yypv[0] = NIL;
58786Speter 	}
59786Speter 	return (1);
60786Speter }
61786Speter 
62786Speter /*
63786Speter  * A bad reference to the identifier cp on line
64786Speter  * line and use implying the addition of kindmask
65786Speter  * to the mask of kind information.
66786Speter  */
67786Speter yybaduse(cp, line, kindmask)
68786Speter 	register char *cp;
69786Speter 	int line, kindmask;
70786Speter {
71786Speter 	register struct nl *p, *oldp;
72786Speter 	int i;
73786Speter 
74786Speter 	i = ( (int) cp ) & 077;
75786Speter 	for (p = disptab[i]; p != NIL; p = p->nl_next)
76786Speter 		if (p->symbol == cp)
77786Speter 			break;
78786Speter 	oldp = p;
79786Speter 	if (p == NIL || p->class != BADUSE)
80786Speter 		p = enter(defnl(cp, BADUSE, 0, 0));
81*3085Smckusic 	p->value[NL_KINDS] |= kindmask;
82786Speter 	yybadref(p, line);
83786Speter 	return (oldp);
84786Speter }
85786Speter 
86786Speter     /*
87786Speter      *	ud is initialized so that esavestr will allocate
88786Speter      *	sizeof ( struct udinfo ) bytes for the 'real' struct udinfo
89786Speter      */
90786Speter struct	udinfo ud = { ~0 , ~0 , 0};
91786Speter /*
92786Speter  * Record a reference to an undefined identifier,
93786Speter  * or one which is improperly used.
94786Speter  */
95786Speter yybadref(p, line)
96786Speter 	register struct nl *p;
97786Speter 	int line;
98786Speter {
99786Speter 	register struct udinfo *udp;
100786Speter 
101786Speter 	if (p->chain != NIL && p->chain->ud_line == line)
102786Speter 		return;
103786Speter 	udp = esavestr(&ud);
104786Speter 	udp->ud_line = line;
105786Speter 	udp->ud_next = p->chain;
106786Speter 	p->chain = udp;
107786Speter }
108786Speter 
1091201Speter #define	varkinds	((1<<CONST)|(1<<VAR)|(1<<REF)|(1<<ARRAY)|(1<<PTR) \
1101201Speter 			|(1<<RECORD)|(1<<FIELD)|(1<<FUNC)|(1<<FVAR) \
1111201Speter 			|(1<<FFUNC)|(1<<PROC)|(1<<FPROC))
112786Speter /*
113786Speter  * Is the symbol in the p entry of the namelist
114786Speter  * even possibly a kind kind?  If not, update
115786Speter  * what we have based on this encounter.
116786Speter  */
117786Speter yyidok(p, kind)
118786Speter 	register struct nl *p;
119786Speter 	int kind;
120786Speter {
121786Speter 
122786Speter 	if (p->class == BADUSE) {
123786Speter 		if (kind == VAR)
124786Speter 			return (p->value[0] & varkinds);
125786Speter 		return (p->value[0] & (1 << kind));
126786Speter 	}
127786Speter 	if (yyidok1(p, kind))
128786Speter 		return (1);
129786Speter 	if (yyidhave != NIL)
130786Speter 		yyidhave = IMPROPER;
131786Speter 	else
132786Speter 		yyidhave = p->class;
133786Speter 	return (0);
134786Speter }
135786Speter 
136786Speter yyidok1(p, kind)
137786Speter 	register struct nl *p;
138786Speter 	int kind;
139786Speter {
140786Speter 	int i;
141786Speter 
142786Speter 	switch (kind) {
143786Speter 		case FUNC:
1441201Speter 			return (   p -> class == FUNC
1451201Speter 				|| p -> class == FVAR
1461201Speter 				|| p -> class == FFUNC );
1471201Speter 		case PROC:
1481201Speter 			return ( p -> class == PROC || p -> class == FPROC );
149786Speter 		case CONST:
150786Speter 		case TYPE:
151786Speter 		case FIELD:
152786Speter 			return (p->class == kind);
153786Speter 		case VAR:
154786Speter 			return (p->class == CONST || yyisvar(p, NIL));
155786Speter 		case ARRAY:
156786Speter 		case RECORD:
157786Speter 			return (yyisvar(p, kind));
158786Speter 		case PTRFILE:
159786Speter 			return (yyisvar(p, PTR) || yyisvar(p, FILET));
160786Speter 	}
161786Speter }
162786Speter 
163786Speter yyisvar(p, class)
164786Speter 	register struct nl *p;
165786Speter 	int class;
166786Speter {
167786Speter 
168786Speter 	switch (p->class) {
169786Speter 		case FIELD:
170786Speter 		case VAR:
171786Speter 		case REF:
172786Speter 		case FVAR:
173786Speter 		/*
174786Speter 		 * We would prefer to return
175786Speter 		 * parameterless functions only.
176786Speter 		 */
177786Speter 		case FUNC:
1781201Speter 		case FFUNC:
179786Speter 			return (class == NIL || (p->type != NIL && p->type->class == class));
1801201Speter 		case PROC:
1811201Speter 		case FPROC:
1821201Speter 			return ( class == NIL );
183786Speter 	}
184786Speter 	return (0);
185786Speter }
186786Speter #endif
187786Speter #ifdef PXP
188786Speter #ifndef DEBUG
189786Speter identis()
190786Speter {
191786Speter 
192786Speter 	return (1);
193786Speter }
194786Speter #endif
195786Speter #ifdef DEBUG
196786Speter extern	char *classes[];
197786Speter 
198786Speter char	kindchars[]	"UCTVAQRDPF";
199786Speter /*
200786Speter  * Fake routine "identis" for pxp when testing error recovery.
201786Speter  * Looks at letters in variable names to answer questions
202786Speter  * about attributes.  Mapping is
203786Speter  *	C	const_id
204786Speter  *	T	type_id
205786Speter  *	V	var_id		also if any of AQRDF
206786Speter  *	A	array_id
207786Speter  *	Q	ptr_id
208786Speter  *	R	record_id
209786Speter  *	D	field_id	D for "dot"
210786Speter  *	P	proc_id
211786Speter  *	F	func_id
212786Speter  */
213786Speter identis(cp, kind)
214786Speter 	register char *cp;
215786Speter 	int kind;
216786Speter {
217786Speter 	register char *dp;
218786Speter 	char kindch;
219786Speter 
220786Speter 	/*
221786Speter 	 * Don't do anything unless -T
222786Speter 	 */
223786Speter 	if (!typetest)
224786Speter 		return (1);
225786Speter 
226786Speter 	/*
227786Speter 	 * Inserted symbols are always correct
228786Speter 	 */
229786Speter 	if (cp == NIL)
230786Speter 		return (1);
231786Speter 	/*
232786Speter 	 * Set up the names for error messages
233786Speter 	 */
234786Speter 	yyidwant = classes[kind];
235786Speter 	for (dp = kindchars; *dp; dp++)
236786Speter 		if (any(cp, *dp)) {
237786Speter 			yyidhave = classes[dp - kindchars];
238786Speter 			break;
239786Speter 		}
240786Speter 
241786Speter 	/*
242786Speter 	 * U in the name means undefined
243786Speter 	 */
244786Speter 	if (any(cp, 'U'))
245786Speter 		return (0);
246786Speter 
247786Speter 	kindch = kindchars[kind];
248786Speter 	if (kindch == 'V')
249786Speter 		for (dp = "AQRDF"; *dp; dp++)
250786Speter 			if (any(cp, *dp))
251786Speter 				return (1);
252786Speter 	return (any(cp, kindch));
253786Speter }
254786Speter #endif
255786Speter #endif
256