Шрифт:
ret /* common return from func or proc */
{
int i;
for (i = 0; i < fp->nargs; i++)
pop; /* pop arguments */
pc = (Inst*)fp->retpc;
--fp;
returning = 1;
}
funcret /* return from a function */
{
Datum d;
if (fp->sp->type == PROCEDURE)
execerror(fp->sp->name, "(proc) returns value");
d = pop; /* preserve function return value */
ret;
push(d);
}
procret /* return from a procedure */
{
if (fp->sp->type == FUNCTION)
execerror(fp->sp->name, "(func) returns no value");
ret;
}
double *getarg /* return pointer to argument */
{
int nargs = (int)*pc++;
if (nargs > fp->nargs)
execerror(fp->sp->name, "not enough arguments");
return &fp->argn[nargs - fp->nargs].val;
}
arg /* push argument onto stack */
{
Datum d;
d.val = *getarg;
push(d);
}
argassign /* store top of stack in argument */
{
Datum d;
d = pop;
push(d); /* leave value on stack */
*getarg = d.val;
}
bltin {
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 != VAR && d.sym->type != UNDEF)
execerror("attempt to evaluate non-variable", d.sym->name);
if (d.sym->type == UNDEF)
execerror("undefined variable", d.sym->name);
d.val = d.sym->u.val;
push(d);
}
add {
Datum d1, d2;
d2 = pop;
d1 = pop;
d1.val += d2.val;
push(d1);
}
sub {
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);