int c; /* global for use by warning */
yylex /* hoc6 */
{
while ((c=getc(fin)) == ' ' || c == '\t')
;
if (c == EOF)
return 0;
if (c == '.' || isdigit(c)) { /* number */
double d;
ungetc(c, fin);
fscanf(fin, "%lf", d);
yylval.sym = install("", NUMBER, d);
return NUMBER;
}
if (isalpha(c)) {
Symbol *s;
char sbuf[100], *p = sbuf;
do {
if (p = sbuf + sizeof(sbuf) - 1) {
*p = '\0';
execerror("name too long", sbuf);
}
*p++ = c;
} while ((c=getc(fin)) != EOF isalnum(c));
ungetc(c, fin);
*p = '\0';
if ((s=lookup(sbuf)) == 0)
s = install(sbuf, UNDEF, 0.0);
yylval.sym = s;
return s-type == UNDEF ? VAR : s-type;
}
if (c == '$') { /* argument? */
int n = 0;
while (isdigit(c=getc(fin)))
n=10*n+c- '0';
ungetc(c, fin);
if (n == 0)
execerror("strange $...", (char*)0);
yylval.narg = n;
return ARG;
}
if (c == '"') { /* quoted string */
char sbuf[100], *p, *emalloc;
for (p = sbuf; (c=getc(fin)) != '"'; p++) {
if (с == '\n' || c == EOF)
execerror("missing quote", "");
if (p = sbuf + sizeof(sbuf) - 1) {
*p = '\0';
execerror("string too long", sbuf);
}
*p = backslash(c);
}
*p = 0;
yylval.sym = (Symbol*)emalloc(strlen(sbuf)+1);
strcpy(yylval.sym, sbuf);
return STRING;
}
switch (c) {
case '': return follow('=', GE, GT);
case '': return follow('=', LE, LT);
case '=': return follow('=', EQ, '=');
case '!': return follow('=', NE, NOT);
case '|': return follow(' |', OR, '|');
case '': return follow('', AND, '');
case '\n': lineno++; return '\n';
default: return c;
}
}
backslash(c) /* get next char with \'s interpreted */
int c;
{
char *index; /* 'strchr' in some systems */
static char transtab[] = "b\bf\fn\nr\rt\t";
if (c != '\\')
return c;
с = getc(fin);
if (islower(c) index(transtab, c))
return index(transtab, с)[1];
return c;
}
follow(expect, ifyes, ifno) /* look ahead for =, etc. */
{
int с = getc(fin);
if (c == expect)
return ifyes;
ungetc(c, fin);
return ifno;
}
defnonly(s) /* warn if illegal definition */
char *s;
{
if (!indef)
execerror(s, "used outside definition");
}
yyerror(s) /* report compile-time error */
char *s;
{
warning(s, (char *)0);
}
execerror(s, t) /* recover from run-time error */
char *s, *t;
{
warning(s, t);
fseek(fin, 0L, 2); /* flush rest of file */
longjmp(begin, 0);
}
fpecatch /* catch floating point exceptions */
{
execerror("floating point exception", (char*)0);
}
main(argc, argv) /* hoc6 */
char *argv[];
{
int i, fpecatch;
progname = argv[0];
if (argc == 1) { /* fake an argument list */
static char *stdinonly[] = { "-" };
gargv = stdinonly;
gargc = 1;
} else {
gargv = argv+1;
gargc = argc-1;
}
init;
while (moreinput)
run;
return 0;
}
moreinput {
if (gargc-- = 0)
return 0;