9
static Datum stack[NSTACK]; /* the stack */
10
static Datum *stackp; /* next free spot on stack */
13
Inst prog[NPROG]; /* the machine */
14
Inst *progp; /* next free spot for code generation */
15
Inst *pc; /* program counter during execution */
16
Inst *progbase = prog; /* start of current subprogram */
17
int returning; /* 1 if return stmt seen */
18
int indef; /* 1 if parsing a func or proc */
20
typedef struct Frame { /* proc/func call stack frame */
21
Symbol *sp; /* symbol table entry */
22
Inst *retpc; /* where to resume after return */
23
Datum *argn; /* n-th argument on stack */
24
int nargs; /* number of arguments */
28
Frame *fp; /* frame pointer */
48
if (stackp >= &stack[NSTACK])
49
execerror("stack too deep", 0);
57
execerror("stack underflow", 0);
62
xpop(void) /* for when no value is wanted */
65
execerror("stack underflow", (char *)0);
73
d.val = ((Symbol *)*pc++)->u.val;
81
d.sym = (Symbol *)(*pc++);
91
execute(savepc+2); /* condition */
94
execute(*((Inst **)(savepc))); /* body */
97
execute(savepc+2); /* condition */
101
pc = *((Inst **)(savepc+1)); /* next stmt */
110
execute(savepc+4); /* precharge */
112
execute(*((Inst **)(savepc))); /* condition */
115
execute(*((Inst **)(savepc+2))); /* body */
118
execute(*((Inst **)(savepc+1))); /* post loop */
120
execute(*((Inst **)(savepc))); /* condition */
124
pc = *((Inst **)(savepc+3)); /* next stmt */
131
Inst *savepc = pc; /* then part */
133
execute(savepc+3); /* condition */
136
execute(*((Inst **)(savepc)));
137
else if (*((Inst **)(savepc+1))) /* else part? */
138
execute(*((Inst **)(savepc+1)));
140
pc = *((Inst **)(savepc+2)); /* next stmt */
144
define(Symbol* sp, Formal *f) /* put func/proc in symbol table */
149
fd = emalloc(sizeof(Fndefn));
150
fd->code = progbase; /* start of code */
151
progbase = progp; /* next code starts here */
153
for(n=0; f; f=f->next)
160
call(void) /* call a function */
167
Symbol *sp = (Symbol *)pc[0]; /* symbol table entry */
169
if (fp >= &frame[NFRAME])
170
execerror(sp->name, "call nested too deeply");
173
fp->nargs = (int)(uintptr)pc[1];
175
fp->argn = stackp - 1; /* last argument */
176
if(fp->nargs != sp->u.defn->nargs)
177
execerror(sp->name, "called with wrong number of arguments");
179
f = sp->u.defn->formals;
180
arg = stackp - fp->nargs;
182
s = emalloc(sizeof(Saveval));
184
s->type = f->sym->type;
187
f->sym->u.val = arg->val;
192
for (i = 0; i < fp->nargs; i++)
193
pop(); /* pop arguments; no longer needed */
194
execute(sp->u.defn->code);
199
restore(Symbol *sp) /* restore formals associated with symbol */
204
f = sp->u.defn->formals;
207
if(s == 0) /* more actuals than formals */
210
f->sym->type = s->type;
218
restoreall(void) /* restore all variables in case of error */
220
while(fp>=frame && fp->sp){
228
ret(void) /* common return from func or proc */
230
/* restore formals */
232
pc = (Inst *)fp->retpc;
238
funcret(void) /* return from a function */
241
if (fp->sp->type == PROCEDURE)
242
execerror(fp->sp->name, "(proc) returns value");
243
d = pop(); /* preserve function return value */
249
procret(void) /* return from a procedure */
251
if (fp->sp->type == FUNCTION)
252
execerror(fp->sp->name,
253
"(func) returns no value");
263
d.val = (*(double (*)(double))*pc++)(d.val);
303
execerror("division by zero", (char *)0);
315
execerror("division by zero", (char *)0);
317
/* d1.val %= d2.val; */
318
d1.val = fmod(d1.val, d2.val);
334
if (s->type != VAR && s->type != UNDEF)
335
execerror("attempt to evaluate non-variable", s->name);
336
if (s->type == UNDEF)
337
execerror("undefined variable", s->name);
341
eval(void) /* evaluate variable on stack */
346
d.val = d.sym->u.val;
354
d.sym = (Symbol *)(*pc++);
356
d.val = d.sym->u.val += 1.0;
364
d.sym = (Symbol *)(*pc++);
366
d.val = d.sym->u.val -= 1.0;
375
d.sym = (Symbol *)(*pc++);
388
d.sym = (Symbol *)(*pc++);
402
d1.val = (double)(d1.val > d2.val);
412
d1.val = (double)(d1.val < d2.val);
422
d1.val = (double)(d1.val >= d2.val);
432
d1.val = (double)(d1.val <= d2.val);
442
d1.val = (double)(d1.val == d2.val);
452
d1.val = (double)(d1.val != d2.val);
462
d1.val = (double)(d1.val != 0.0 && d2.val != 0.0);
472
d1.val = (double)(d1.val != 0.0 || d2.val != 0.0);
481
d.val = (double)(d.val == 0.0);
491
d1.val = Pow(d1.val, d2.val);
501
if (d1.sym->type != VAR && d1.sym->type != UNDEF)
502
execerror("assignment to non-variable",
504
d1.sym->u.val = d2.val;
515
if (d1.sym->type != VAR && d1.sym->type != UNDEF)
516
execerror("assignment to non-variable",
518
d2.val = d1.sym->u.val += d2.val;
529
if (d1.sym->type != VAR && d1.sym->type != UNDEF)
530
execerror("assignment to non-variable",
532
d2.val = d1.sym->u.val -= d2.val;
543
if (d1.sym->type != VAR && d1.sym->type != UNDEF)
544
execerror("assignment to non-variable",
546
d2.val = d1.sym->u.val *= d2.val;
557
if (d1.sym->type != VAR && d1.sym->type != UNDEF)
558
execerror("assignment to non-variable",
560
d2.val = d1.sym->u.val /= d2.val;
579
if (d1.sym->type != VAR && d1.sym->type != UNDEF)
580
execerror("assignment to non-variable",
582
/* d2.val = d1.sym->u.val %= d2.val; */
589
/* push(d2) generates a compiler error on Linux w. gcc 2.95.4 */
594
printtop(void) /* pop top value from stack, print it */
597
static Symbol *s; /* last value computed */
599
s = install("_", VAR, 0.0);
601
print("%.17g\n", d.val);
606
prexpr(void) /* print numeric value */
610
print("%.17g ", d.val);
614
prstr(void) /* print string value */
616
print("%s", (char *) *pc++);
620
varread(void) /* read into variable */
624
Symbol *var = (Symbol *) *pc++;
630
while(c==' ' || c=='\t');
635
d.val = var->u.val = 0.0;
639
if(strchr("+-.0123456789", c) == 0)
640
execerror("non-number read into", var->name);
642
if(Bgetd(bin, &var->u.val) == Beof)
652
code(Inst f) /* install one instruction or operand */
654
Inst *oprogp = progp;
655
if (progp >= &prog[NPROG])
656
execerror("program too big", (char *)0);
664
for (pc = p; *pc != STOP && !returning; )