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

identis defined in line 217; never used
yybadref defined in line 107; used 2 times
yybaduse defined in line 79; used 3 times
yyidok defined in line 127; used 2 times
yyidok1 defined in line 146; used 1 times
yyisvar defined in line 171; used 4 times

Defined variables

kindchars defined in line 202; used 3 times
ud defined in line 102; used 1 times

Defined macros

varkinds defined in line 121; used 1 times
Last modified: 1986-05-31
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 2277
Valid CSS Valid XHTML 1.0 Strict