/* * esa3.c * Lexical processing. */ #include #include "esa.h" /* * Get the next non white character * from the input. */ getnb() { register int c; while((c=getraw())==' ' || c=='\t'); return(c); } /* * Get the next input character. * Be very careful with respect to * end of lines. */ getraw() { register int c; if((c = *sptr) != '\0') ++sptr; return(c); } /* * Test if a character is alphabetic. * True return if it is. */ alpha(ac) { register int c; c = ac; if(c=='.' || c=='_' || (c>='a' && c<='z') || (c>='A' && c<='Z')) return(1); return(0); } /* * Push a character back into the input. * Must not push back beyond the start of * the line. */ putback(c) { if(c != '\0') if(--sptr < sbuf) error("Putback\n"); } /* * Read in an indentifier. * Store it (padded with nulls) into the * supplied buffer. */ getid(ac, id) char *id; { register int c; register char *p; c = ac; 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); } /* * Get a number, in either the hexadecimal or * the decimal radix. * Decimal is indicated by a trailing '.'. */ getnum(ac) { register int c, v, hexseen; int hex, dec; c = ac; 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); } } /* * Given a character, return its numeric value. * This is in the range 0 to 15. * Return -1 if the input is junk. */ digvalue(ac) { register int c; c = ac; 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 a symbol in a symbol table, which * may be either `pst' or `ust'. * Failures in the `pst' return NULL. * Failures in the `ust' cause a new symbol to * be added. */ struct sym * lookup(id, astp) char *id; struct sym *astp; { register struct sym *stp, *endp; if((stp=astp) == ust) endp = uptr; else endp = pptr; while(stp < endp) { if(match(id, stp->s_name)) return(stp); ++stp; } if(astp == pst) return(NULL); if(stp >= &ust[USERMAX]) error("Symbol table overflow\n"); 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(aa1, aa2) char *aa1, *aa2; { register char *a1, *a2; register int n; a1 = aa1; a2 = aa2; n = NCPS; do if(*a1++ != *a2++) return(0); while(--n); return(1); } /* * Get the next character from the input * using 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 = 0x20; 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 = '\\'; } else if(c == ' ') c = 0xD0; else if(c == '/') c = 0x40; else if(c == '@') c = 0x3D + 1; /* Kludge */ else if(c == '\t') c = 0x20; else if(c == '_') c = 0x3D; return(c); }