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