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