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);
}
gt {
Datum d1, d2;
d2 = pop;
d1 = pop;
d1.val = (double)(d1.val d2.val);
push(d1);
}
lt {
Datum d1, d2;
d2 = pop;
d1 = pop;
d1.val = (double)(d1.val d2.val);
push(d1);
}
ge {
Datum d1, d2;
d2 = pop;
d1 = pop;
d1.val = (double)(d1.val = d2.val);
push(d1);
}
le {
Datum d1, d2;
d2 = pop;
d1 = pop;
d1.val = (double)(d1.val = d2.val);
push(d1);
}
eq {
Datum d1, d2;
d2 = pop;
d1 = pop;
d1.val = (double)(d1.val == d2.val);
push(d1);
}
ne {
Datum d1, d2;
d2 = pop;
d1 = pop;
d1.val = (double)(d1.val != d2.val);
push(d1);
}
and {
Datum d1, d2;
d2 = pop;
d1 = pop;
d1.val = (double)(d1.val != 0.0 d2.val != 0.0);
push(d1);
}
or {
Datum d1, d2;
d2 = pop;
d1 = pop;
d1.val = (double)(d1.val != 0.0 || d2.val != 0.0);
push(d1);
}
not {
Datum d;
d = pop;
d.val = (double)(d.val == 0.0);
push(d);
}
power {
Datum d1, d2;
extern double Pow;
d2 = pop;
d1 = pop;
d1.val = Pow(d1.val, d2.val);
push(d1);
}
assign {
Datum d1, d2;
d1 = pop;
d2 = pop;
if (d1.sym-type != VAR d1.sym-type != UNDEF)
execerror("assignment to non-variable", d1.sym-name);
d1.sym-u.val = d2.val;
d1.sym-type = VAR;
push(d2);
}
print {
Datum d;
d = pop;
printf("\t%.8g\n", d.val);
}
prexpr /* print numeric value */
{
Datum d;
d = pop;
printf("%.8g\n", d.val);
}
Inst *code(f) /* install one instruction or operand */
Inst f;
{
Inst *oprogp = progp;
if (progp = prog[NPROG])
execerror("expression too complicated", (char*)0);
*progp++ = f;
return oprogp;
}
execute(p)
Inst *p;
{
for (pc = p; *pc != STOP; ) (*(*pc++));
}
3.6.2 fib
{
a=0
b=1
while(b1000) {
c=b
b=a+b
a=c
print(c)
}
}
3.6.3 fib2
{
n=0
a=0
b=1
while(b10000000){
n=n+1
c=b
b=a+b
a=c
print(b)
}
print(n)
}
3.6.4 hoc.h
typedef struct Symbol { /* symbol table entry */
char *name;
short type; /* VAR, BLTIN, UNDEF */
union {
double val; /* if VAR */
double (*ptr); /* if BLTIN */
} u;
struct Symbol *next; /* to link to another */
} Symbol;
Symbol *install, *lookup;
typedef union Datum { /* interpreter stack type */
double val;
Symbol *sym;
} Datum;
extern Datum pop;
typedef int (*Inst); /* machine instruction */
#define STOP (Inst)0
extern Inst prog[], *progp, *code;
extern eval, add, sub, mul, div, negate, power;
extern assign, bltin, varpush, constpush, print;
extern prexpr;
extern gt, lt, eq, ge, le, ne, and, or, not;
extern ifcode, whilecode;
3.6.5 hoc.y
%{
#include "hoc.h"
#define code2(c1,c2) code(c1); code(c2)