122206Sdist /* 222206Sdist * Copyright (c) 1980 Regents of the University of California. 322206Sdist * All rights reserved. The Berkeley software License Agreement 422206Sdist * specifies the terms and conditions for redistribution. 522206Sdist */ 6786Speter 714748Sthien #ifndef lint 8*44619Sbostic static char sccsid[] = "@(#)yyid.c 5.2 (Berkeley) 06/29/90"; 922206Sdist #endif not lint 10786Speter 11786Speter #include "whoami.h" 12*44619Sbostic #include <0.h> 1314748Sthien #include "tree_ty.h" /* must be included for yy.h */ 14786Speter #include "yy.h" 15786Speter 16786Speter #ifdef PI 1714748Sthien extern union semstack *yypv; 18786Speter /* 19786Speter * Determine whether the identifier whose name 20786Speter * is "cp" can possibly be a kind, which is a 21786Speter * namelist class. We look through the symbol 22786Speter * table for the first instance of cp as a non-field, 23786Speter * and at all instances of cp as a field. 24786Speter * If any of these are ok, we return true, else false. 25786Speter * It would be much better to handle with's correctly, 26786Speter * even to just know whether we are in a with at all. 27786Speter * 28786Speter * Note that we don't disallow constants on the lhs of assignment. 29786Speter */ 30786Speter identis(cp, kind) 31786Speter register char *cp; 32786Speter int kind; 33786Speter { 34786Speter register struct nl *p; 35786Speter int i; 36786Speter 37786Speter /* 38786Speter * Cp is NIL when error recovery inserts it. 39786Speter */ 40786Speter if (cp == NIL) 41786Speter return (1); 42786Speter 43786Speter /* 44786Speter * Record kind we want for possible later use by yyrecover 45786Speter */ 46786Speter yyidwant = kind; 47786Speter yyidhave = NIL; 48786Speter i = ( (int) cp ) & 077; 49786Speter for (p = disptab[i]; p != NIL; p = p->nl_next) 50786Speter if (p->symbol == cp) { 51786Speter if (yyidok(p, kind)) 52786Speter goto gotit; 53786Speter if (p->class != FIELD && p->class != BADUSE) 54786Speter break; 55786Speter } 56786Speter if (p != NIL) 57786Speter for (p = p->nl_next; p != NIL; p = p->nl_next) 58786Speter if (p->symbol == cp && p->class == FIELD && yyidok(p, kind)) 59786Speter goto gotit; 60786Speter return (0); 61786Speter gotit: 62786Speter if (p->class == BADUSE && !Recovery) { 63786Speter yybadref(p, OY.Yyeline); 6414748Sthien yypv[0].i_entry = NIL; 65786Speter } 66786Speter return (1); 67786Speter } 68786Speter 69786Speter /* 70786Speter * A bad reference to the identifier cp on line 71786Speter * line and use implying the addition of kindmask 72786Speter * to the mask of kind information. 73786Speter */ 7414748Sthien struct nl * 75786Speter yybaduse(cp, line, kindmask) 76786Speter register char *cp; 77786Speter int line, kindmask; 78786Speter { 79786Speter register struct nl *p, *oldp; 80786Speter int i; 81786Speter 82786Speter i = ( (int) cp ) & 077; 83786Speter for (p = disptab[i]; p != NIL; p = p->nl_next) 84786Speter if (p->symbol == cp) 85786Speter break; 86786Speter oldp = p; 87786Speter if (p == NIL || p->class != BADUSE) 8814748Sthien p = enter(defnl(cp, BADUSE, NLNIL, 0)); 893085Smckusic p->value[NL_KINDS] |= kindmask; 90786Speter yybadref(p, line); 91786Speter return (oldp); 92786Speter } 93786Speter 94786Speter /* 95786Speter * ud is initialized so that esavestr will allocate 96786Speter * sizeof ( struct udinfo ) bytes for the 'real' struct udinfo 97786Speter */ 9814748Sthien struct udinfo ud = { ~0 , (struct udinfo *) ~0 , 0}; 99786Speter /* 100786Speter * Record a reference to an undefined identifier, 101786Speter * or one which is improperly used. 102786Speter */ 103786Speter yybadref(p, line) 104786Speter register struct nl *p; 105786Speter int line; 106786Speter { 107786Speter register struct udinfo *udp; 108786Speter 10914748Sthien if (p->chain != NIL && ((struct udinfo *) p->chain)->ud_line == line) 110786Speter return; 11114748Sthien udp = (struct udinfo *) esavestr((char *) &ud); 112786Speter udp->ud_line = line; 11314748Sthien udp->ud_next = (struct udinfo *) p->chain; 11414748Sthien p->chain = (struct nl *) udp; 115786Speter } 116786Speter 1171201Speter #define varkinds ((1<<CONST)|(1<<VAR)|(1<<REF)|(1<<ARRAY)|(1<<PTR) \ 1181201Speter |(1<<RECORD)|(1<<FIELD)|(1<<FUNC)|(1<<FVAR) \ 1191201Speter |(1<<FFUNC)|(1<<PROC)|(1<<FPROC)) 120786Speter /* 121786Speter * Is the symbol in the p entry of the namelist 122786Speter * even possibly a kind kind? If not, update 123786Speter * what we have based on this encounter. 124786Speter */ 125786Speter yyidok(p, kind) 126786Speter register struct nl *p; 127786Speter int kind; 128786Speter { 129786Speter 130786Speter if (p->class == BADUSE) { 131786Speter if (kind == VAR) 132786Speter return (p->value[0] & varkinds); 133786Speter return (p->value[0] & (1 << kind)); 134786Speter } 135786Speter if (yyidok1(p, kind)) 136786Speter return (1); 137786Speter if (yyidhave != NIL) 138786Speter yyidhave = IMPROPER; 139786Speter else 140786Speter yyidhave = p->class; 141786Speter return (0); 142786Speter } 143786Speter 144786Speter yyidok1(p, kind) 145786Speter register struct nl *p; 146786Speter int kind; 147786Speter { 148786Speter 149786Speter switch (kind) { 15014748Sthien default: 151786Speter case FUNC: 1521201Speter return ( p -> class == FUNC 1531201Speter || p -> class == FVAR 1541201Speter || p -> class == FFUNC ); 1551201Speter case PROC: 1561201Speter return ( p -> class == PROC || p -> class == FPROC ); 157786Speter case CONST: 158786Speter case TYPE: 159786Speter case FIELD: 160786Speter return (p->class == kind); 161786Speter case VAR: 162786Speter return (p->class == CONST || yyisvar(p, NIL)); 163786Speter case ARRAY: 164786Speter case RECORD: 165786Speter return (yyisvar(p, kind)); 166786Speter case PTRFILE: 167786Speter return (yyisvar(p, PTR) || yyisvar(p, FILET)); 168786Speter } 169786Speter } 170786Speter 1717922Smckusick yyisvar(p, varclass) 172786Speter register struct nl *p; 1737922Smckusick int varclass; 174786Speter { 175786Speter 176786Speter switch (p->class) { 177786Speter case FIELD: 178786Speter case VAR: 179786Speter case REF: 180786Speter case FVAR: 181786Speter /* 182786Speter * We would prefer to return 183786Speter * parameterless functions only. 184786Speter */ 185786Speter case FUNC: 1861201Speter case FFUNC: 1877922Smckusick return (varclass == NIL || (p->type != NIL && p->type->class == varclass)); 1881201Speter case PROC: 1891201Speter case FPROC: 1907922Smckusick return ( varclass == NIL ); 191786Speter } 192786Speter return (0); 193786Speter } 194786Speter #endif 195786Speter #ifdef PXP 196786Speter #ifndef DEBUG 197786Speter identis() 198786Speter { 199786Speter 200786Speter return (1); 201786Speter } 202786Speter #endif 203786Speter #ifdef DEBUG 204786Speter extern char *classes[]; 205786Speter 206786Speter char kindchars[] "UCTVAQRDPF"; 207786Speter /* 208786Speter * Fake routine "identis" for pxp when testing error recovery. 209786Speter * Looks at letters in variable names to answer questions 210786Speter * about attributes. Mapping is 211786Speter * C const_id 212786Speter * T type_id 213786Speter * V var_id also if any of AQRDF 214786Speter * A array_id 215786Speter * Q ptr_id 216786Speter * R record_id 217786Speter * D field_id D for "dot" 218786Speter * P proc_id 219786Speter * F func_id 220786Speter */ 221786Speter identis(cp, kind) 222786Speter register char *cp; 223786Speter int kind; 224786Speter { 225786Speter register char *dp; 226786Speter char kindch; 227786Speter 228786Speter /* 229786Speter * Don't do anything unless -T 230786Speter */ 231786Speter if (!typetest) 232786Speter return (1); 233786Speter 234786Speter /* 235786Speter * Inserted symbols are always correct 236786Speter */ 237786Speter if (cp == NIL) 238786Speter return (1); 239786Speter /* 240786Speter * Set up the names for error messages 241786Speter */ 242786Speter yyidwant = classes[kind]; 243786Speter for (dp = kindchars; *dp; dp++) 244786Speter if (any(cp, *dp)) { 245786Speter yyidhave = classes[dp - kindchars]; 246786Speter break; 247786Speter } 248786Speter 249786Speter /* 250786Speter * U in the name means undefined 251786Speter */ 252786Speter if (any(cp, 'U')) 253786Speter return (0); 254786Speter 255786Speter kindch = kindchars[kind]; 256786Speter if (kindch == 'V') 257786Speter for (dp = "AQRDF"; *dp; dp++) 258786Speter if (any(cp, *dp)) 259786Speter return (1); 260786Speter return (any(cp, kindch)); 261786Speter } 262786Speter #endif 263786Speter #endif 264