|
|
1.1 root 1: /* Copyright (c) 1979 Regents of the University of California */
2:
3: static char sccsid[] = "@(#)yyid.c 1.2 10/2/80";
4:
5: #include "whoami.h"
6: #include "0.h"
7: #include "yy.h"
8:
9: #ifdef PI
10: extern 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: */
23: identis(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);
54: gotit:
55: if (p->class == BADUSE && !Recovery) {
56: yybadref(p, OY.Yyeline);
57: yypv[0] = NIL;
58: }
59: return (1);
60: }
61:
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: */
67: yybaduse(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: */
90: struct udinfo ud = { ~0 , ~0 , 0};
91: /*
92: * Record a reference to an undefined identifier,
93: * or one which is improperly used.
94: */
95: yybadref(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) \
110: |(1<<RECORD)|(1<<FIELD)|(1<<FUNC)|(1<<FVAR) \
111: |(1<<FFUNC)|(1<<PROC)|(1<<FPROC))
112: /*
113: * Is the symbol in the p entry of the namelist
114: * even possibly a kind kind? If not, update
115: * what we have based on this encounter.
116: */
117: yyidok(p, kind)
118: register struct nl *p;
119: int kind;
120: {
121:
122: if (p->class == BADUSE) {
123: if (kind == VAR)
124: return (p->value[0] & varkinds);
125: return (p->value[0] & (1 << kind));
126: }
127: if (yyidok1(p, kind))
128: return (1);
129: if (yyidhave != NIL)
130: yyidhave = IMPROPER;
131: else
132: yyidhave = p->class;
133: return (0);
134: }
135:
136: yyidok1(p, kind)
137: register struct nl *p;
138: int kind;
139: {
140: int i;
141:
142: switch (kind) {
143: case FUNC:
144: return ( p -> class == FUNC
145: || p -> class == FVAR
146: || p -> class == FFUNC );
147: case PROC:
148: return ( p -> class == PROC || p -> class == FPROC );
149: case CONST:
150: case TYPE:
151: case FIELD:
152: return (p->class == kind);
153: case VAR:
154: return (p->class == CONST || yyisvar(p, NIL));
155: case ARRAY:
156: case RECORD:
157: return (yyisvar(p, kind));
158: case PTRFILE:
159: return (yyisvar(p, PTR) || yyisvar(p, FILET));
160: }
161: }
162:
163: yyisvar(p, class)
164: register struct nl *p;
165: int class;
166: {
167:
168: switch (p->class) {
169: case FIELD:
170: case VAR:
171: case REF:
172: case FVAR:
173: /*
174: * We would prefer to return
175: * parameterless functions only.
176: */
177: case FUNC:
178: case FFUNC:
179: return (class == NIL || (p->type != NIL && p->type->class == class));
180: case PROC:
181: case FPROC:
182: return ( class == NIL );
183: }
184: return (0);
185: }
186: #endif
187: #ifdef PXP
188: #ifndef DEBUG
189: identis()
190: {
191:
192: return (1);
193: }
194: #endif
195: #ifdef DEBUG
196: extern char *classes[];
197:
198: char kindchars[] "UCTVAQRDPF";
199: /*
200: * Fake routine "identis" for pxp when testing error recovery.
201: * Looks at letters in variable names to answer questions
202: * about attributes. Mapping is
203: * C const_id
204: * T type_id
205: * V var_id also if any of AQRDF
206: * A array_id
207: * Q ptr_id
208: * R record_id
209: * D field_id D for "dot"
210: * P proc_id
211: * F func_id
212: */
213: identis(cp, kind)
214: register char *cp;
215: int kind;
216: {
217: register char *dp;
218: char kindch;
219:
220: /*
221: * Don't do anything unless -T
222: */
223: if (!typetest)
224: return (1);
225:
226: /*
227: * Inserted symbols are always correct
228: */
229: if (cp == NIL)
230: return (1);
231: /*
232: * Set up the names for error messages
233: */
234: yyidwant = classes[kind];
235: for (dp = kindchars; *dp; dp++)
236: if (any(cp, *dp)) {
237: yyidhave = classes[dp - kindchars];
238: break;
239: }
240:
241: /*
242: * U in the name means undefined
243: */
244: if (any(cp, 'U'))
245: return (0);
246:
247: kindch = kindchars[kind];
248: if (kindch == 'V')
249: for (dp = "AQRDF"; *dp; dp++)
250: if (any(cp, *dp))
251: return (1);
252: return (any(cp, kindch));
253: }
254: #endif
255: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.