#include "prims.h"
extern inst *p_oper1, *p_oper2, *p_oper3, *p_oper4;
extern int p_result;
static int conditional;
extern int p_nargs;
void prims_for_add (__P_PROTO)
{
for_list *loop;
CHECKOP(3);
p_oper1 = POP();
p_oper2 = POP();
p_oper3 = POP();
if (p_oper1->type != PROG_INTEGER) abort_interp("Invalid step size.");
if (p_oper2->type != PROG_INTEGER) abort_interp("Invalid end (for).");
if (p_oper3->type != PROG_INTEGER) abort_interp("Invalid start (for).");
loop = (for_list *) malloc(sizeof(for_list));
loop->next = fr->for_loop;
loop->current = p_oper3->data.number;
loop->target = p_oper2->data.number;
loop->stepsize = p_oper1->data.number;
fr->for_loop = loop;
p_result = p_oper3->data.number;
CLEAR(p_oper1);
CLEAR(p_oper2);
CLEAR(p_oper3);
push(arg, top, PROG_INTEGER, MIPSCAST &p_result);
}
void prims_for_check (__P_PROTO)
{
for_list *loop;
loop = fr->for_loop;
if (!loop) abort_interp ("Invalid check of FOR loop.");
loop->current += loop->stepsize;
if (loop->stepsize == 0) conditional = 0;
else if (loop->stepsize>0) conditional = (loop->current <= loop->target)?1:0;
else conditional = (loop->current >= loop->target)?1:0;
p_result = loop->current;
if (conditional == 0)
{
fr->for_loop = loop->next;
free (loop);
}
else
{
if ((*top) >= STACK_SIZE) abort_interp("Stack overflow.");
push(arg, top, PROG_INTEGER, MIPSCAST &p_result);
}
if ((*top) >= STACK_SIZE) abort_interp("Stack overflow.");
push(arg, top, PROG_INTEGER, MIPSCAST &conditional);
}
void prims_for_pop (__P_PROTO)
{
for_list *loop;
CHECKOP(1);
p_oper1 = POP();
if (p_oper1->type != PROG_INTEGER)
abort_interp("Internal FOR error: Invalid argument to clear registers.");
for (p_result = 0; p_result < p_oper1->data.number; p_result++)
{
loop = fr->for_loop;
if (!loop) abort_interp("Internal FOR error: FOR register underflow.");
fr->for_loop = loop->next;
free (loop);
}
CLEAR(p_oper1);
}