#include "defs.h" #include "prims.h" PRIM(for_add) { struct inst *vstart; struct inst *vstep; struct inst *vend; struct for_struct *loop; NARGS(3); vstep = TOS(0); vend = TOS(1); vstart = TOS(2); if (vstep->type != PROG_INTEGER) ABORT_INTERP("Invalid step size."); if (vend->type != PROG_INTEGER) ABORT_INTERP("Invalid end (for)."); if (vstart->type != PROG_INTEGER) ABORT_INTERP("Invalid start (for)."); loop = malloc(sizeof(*loop)); loop->next = fr->for_loop; loop->current = vstart->data.number; loop->target = vend->data.number; loop->stepsize = vstep->data.number; fr->for_loop = loop; POP(3); MPUSH(PROG_INTEGER,loop->current); } PRIM(for_check) { struct for_struct *loop; int cond; loop = fr->for_loop; if (! loop) ABORT_INTERP("Invalid check of FOR loop."); loop->current += loop->stepsize; if (loop->stepsize == 0) cond = 1; else if (loop->stepsize > 0) cond = (loop->current <= loop->target); else cond = (loop->current >= loop->target); if (! cond) { fr->for_loop = loop->next; free(loop); } else { STACKROOM(1); MPUSH(PROG_INTEGER,loop->current); } STACKROOM(1); MPUSH(PROG_INTEGER,cond); } PRIM(for_pop) { struct inst *v; struct for_struct *loop; int i; NARGS(1); v = TOS(0); if (v->type != PROG_INTEGER) ABORT_INTERP("Internal FOR error: Invalid argument to for_pop."); for (i=v->data.number;i>0;i--) { loop = fr->for_loop; if (! loop) ABORT_INTERP("Internal FOR error: FOR stack underflow."); fr->for_loop = loop->next; free(loop); } POP(1); }