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;
}
3.4.7 symbol.c
#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;
}
3.5 hoc4
3.5.1 code.c
#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;
push(d);
}
varpush /* push variable onto stack */
{
Datum d;
d.sym = (Symbol*)(*pc++);
push(d);
}
bltin /* evaluate built-in on top of stack */
{
Datum d;
d = pop;
d.val = (*(double(*))(*pc++))(d.val);
push(d);
}
eval /* evaluate variable on stack */
{
Datum d;
d = pop ;
if (d.sym-type == UNDEF)
execerror("undefined variable", d.sym-name);
d.val = d.sym-u.val;
push(d);
}
add /* add top two elems on stack */
{
Datum d1, d2;
d2 = pop;
d1 = pop;
d1.val += d2.val;
push(d1);
}
sub /* subtract top of stack from next */
{
Datum d1, d2;
d2 = pop;
d1 = pop;
d1.val -= d2.val;
push(d1);
}
mul {
Datum d1, d2;
d2 = pop;
d1 = pop;
d1.val *= d2.val;
push(d1);
}
div {
Datum d1, d2;
d2 = pop;
if (d2.val == 0.0)
execerror("division by zero", (char*)0);
d1 = pop;
d1.val /= d2.val;
push(d1);
}
negate {
Datum d;
d = pop;
d.val = -d.val;
push(d);
}
power {
Datum d1, d2;