/* * as83.c * Lex. */ #include #include "as8.h" /* * Get the next non white * character. */ getnb() { register int c; while((c=getraw())==' ' || c=='\t'); return(c); } /* * Get next character from * the input. * Apply string mappings. */ getmap() { register int n, c, v; if((c=getraw()) == '\\') switch(c = getraw()) { case 'n': c = '\n'; break; case 'r': c = '\r'; break; case 't': c = '\t'; break; case 'b': c = '\b'; break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': v = n = 0; while(++n<=3 && c>='0' && c<='7') { v = 8*v + c - '0'; c = getraw(); } putback(c); c = v; break; default: putback(c); c = '\\'; } return(c); } /* * Get next character. * Basic routine. * Don't screw up on end of * line. */ getraw() { register int c; if((c = *sptr) != '\0') ++sptr; return(c); } /* * Check for alpha. */ alpha(c) register int c; { if(c=='.' || c=='_' || (c>='a' && c<='z') || (c>='A' && c<='Z')) return(1); return(0); } /* * Put a character back. * A line at a time version * of ungetc. * Die if too many characters * are put back. */ putback(c) { if(c != '\0') if(--sptr < sbuf) abort(); } /* * Read in an indentifier. * Store it (padded with nulls) into the * supplied buffer. */ getid(c, id) register int c; char *id; { register char *p; p = id; while(alpha(c) || (c>='0' && c<='9')) { if(p < &id[NCPS]) *p++ = c; c = getraw(); } while(p < &id[NCPS]) *p++ = '\0'; putback(c); } /* * Read numbers. * Trailing period means decimal. * Otherwise hex. */ getnum(c) register int c; { register int v, hexseen; int hex, dec; hex = dec = hexseen = 0; while((v=digvalue(c)) >= 0) { hex = 16*hex + v; dec = 10*dec + v; if(v > 9) ++hexseen; c = getraw(); } if(c == '.') { if(hexseen) err('n'); return(dec); } else { putback(c); return(hex); } } /* * Return the numeric value * of a character (0 to 15) or * -1 if bad. */ digvalue(c) register int c; { if(c>='0' && c<='9') return(c-'0'); if(c>='a' && c<='f') return(c-'a'+10); if(c>='A' && c<='F') return(c-'A'+10); return(-1); } /* * Lookup id. * The table is either the pst or * the ust. * Failure in the pst returns * NULL; failure in the ust adds * a symbol. */ struct sym * lookup(id, stp) char *id; register struct sym *stp; { register struct sym *endp; if(stp == ust) endp = uptr; else endp = pptr; while(stp < endp) { if(match(id, stp->s_name)) return(stp); ++stp; } if(stp == pst) return(NULL); if(stp >= &ust[USERMAX]) { fprintf(stderr, "Symbol overflow!\n"); exit(1); } copy(stp->s_name, id, NCPS); stp->s_type = S_UND; stp->s_flag = 0; stp->s_value = 0; ++uptr; return(stp); } /* * Compare two names. * True return if the same. */ match(a1, a2) register char *a1, *a2; { register int n; n = NCPS; do if(*a1++ != *a2++) return(0); while(--n); return(1); }