longjmp(begin, 0);
}
warning(s, t)
char *s, *t;
{
fprintf (stderr, "%s: %s", progname, s);
if (t && *t)
fprintf(stderr, " %s", t);
fprintf(stderr, " near line %d\n", lineno);
}
#include "hoc.h"
#include "y.tab.h"
#include
extern double Log(), Log10(), Exp(), Sqrt(), integer();
static struct { /* Constants */
char *name;
double eval;
} consts [] = {
"PI", 3.14159265358979323846,
"E", 2.71828182845904523536,
"GAMMA", 0.57721566490153286060, /* Euler */
"DEG", 57.29577951308232087680, /* deg/radian */
"PHI", 1.61803398874989484820, /* golden ratio */
0, 0
};
static struct { /* Built-ins */
char *name;
double (*func)();
} builtins[] = {
"sin", sin,
"cos", cos,
"atan", atan,
"log", Log, /* checks argument */
"log10", Log10, /* checks argument */
"exp", Exp, /* checks argument */
"sqrt", Sqrt, /* checks argument */
"int", integer,
"abs", fabs,
0, 0
};
init() /* install constants and built-ins in table */
{
int i;
Symbol *s;
for (i = 0; consts[i].name; i++)
install(consts[i].name, VAR, consts[i].eval);
for (i = 0; builtins[i].name; i++) {
s = install(builtins[i].name, BLTIN, 0.0);
s->u.ptr = builtins[i].func;
}
}
%{
#include "hoc.h"
#include "y.tab.h"
extern int lineno;
%}
%%
[ \t] { ; } /* skip blanks and tabs */
[0-9]+\.?|[0-9][0-9]+ {
sscanf(yytext, "%lf", &yylval.val);
return NUMBER;
}
[a-zA-Z][a-zA-Z0-9]* {
Symbol *s;
if ((s=lookup(yytext)) == 0)
s = install(yytext, UNDEF, 0.0);
yylval.sym = s;
return s->type == UNDEF ? VAR : s->type;
}
\n {
lineno++;
return '\n';
} /* everything else */
. { return yytext[0]; }
YFLAGS = -d
OBJS = hoc.o lex.o init.o math.o symbol.o
hoc3: $(OBJS)
cc $(OBJS) -lm -ll -o hoc3
hoc.o: hoc.h
lex.o init.o symbol.o: hoc.h y.tab.h
#include
#include
extern int errno;
double errcheck();
double Log(x)
double x;
{
return errcheck(log(x), "log");
}
double Log10(x)
double x;
{
return errcheck(log10(x), "log10");
}
double Sqrt(x)
double x;
{
return errcheck(sqrt(x), "sqrt");
}
double Exp(x)
double x;
{
return errcheck(exp(x), "exp");
}
double Pow(x, y)
double x, y;
{
return errcheck(pow(x,y), "exponentiation");
}
double integer(x)
double x;
{
return (double)(long)x;
}
double errcheck(d, s) /* check result of library call */
double d;
char *s;
{
if (errno == EDOM) {
errno = 0;
execerror(s, "argument out of domain");
} else if (errno == ERANGE) {
errno = 0;
execerror(s, "result out of range");
}
return d;
}
#include "hoc.h"
#include "y.tab.h"
static Symbol *symlist =0; /* symbol table: linked list */
Symbol *lookup(s) /* find s in symbol table */
char *s;
{
Symbol *sp;
for (sp = symlist; sp != (Symbol*)0; sp = sp->next)
if (strcmp(sp->name, s) == 0)
return sp;
return 0; /* 0 ==> not found */
}
Symbol *install(s, t, d) /* install s in symbol table */
char *s;
int t;
double d;
{
Symbol *sp;
char *emalloc();
sp = (Symbol*)emalloc(sizeof(Symbol));
sp->name = emalloc(strlen(s)+1); /* +1 for '\0' */
strcpy(sp->name, s);
sp->type = t;
sp->u.val = d;
sp->next = symlist; /* put at front of list */
symlist = sp;
return sp;
}
char *emalloc(n) /* check return from malloc */
unsigned n;
{
char *p, *malloc();
p = malloc(n);
if (p == 0)
execerror("out of memory", (char*)0);
return p;
}
#include "hoc.h"
#include "y.tab.h"
#define NSTACK 256
static Datum stack[NSTACK]; /* the stack */
static Datum *stackp; /* next free spot on stack */
#define NPROG 2000
Inst prog[NPROG]; /* the machine */
Inst *progp; /* next free spot for code generation */
Inst *pc; /* program counter during execution */
initcode() /* initialize for code generation */
{
stackp = stack;
progp = prog;
}
push(d) /* push d onto stack */
Datum d;
{
if (stackp >= &stack[NSTACK])
execerror("stack overflow", (char*)0);
*stackp++ = d;
}
Datum pop() /* pop and return top elem from stack */
{
if (stackp <= stack)
execerror("stack underflow", (char*)0);
return *--stackp;
}
constpush() /* push constant onto stack */
{
Datum d;
d.val = ((Symbol*)*pc++)->u.val;
Читать дальше
Конец ознакомительного отрывка
Купить книгу