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