eigenmath/stack.cpp

114 lines
1.8 KiB
C++

#include "stdafx.h"
//-----------------------------------------------------------------------------
//
// _______
// | | <- stack
// | |
// |_______|
// | | <- stack + tos
// | |
// | |
// |_______|
// | | <- frame
// |_______|
// <- stack + TOS
//
// The stack grows from low memory towards high memory. This is so that
// multiple expressions can be pushed on the stack and then accessed as an
// array.
//
// The frame area grows from high memory towards low memory. The frame
// area is used to store local variables. The frame area is required
// because local variables must be visible to the garbage collector.
//
//-----------------------------------------------------------------------------
#include "defs.h"
U **frame, *stack[TOS];
int tos;
void
push(U *p)
{
if (stack + tos >= frame)
stop("stack overflow");
stack[tos++] = p;
}
U *
pop()
{
if (tos == 0)
stop("stack underflow");
return stack[--tos];
}
void
push_frame(int n)
{
int i;
frame -= n;
if (frame < stack + tos)
stop("frame overflow, circular reference?");
for (i = 0; i < n; i++)
frame[i] = symbol(NIL);
}
void
pop_frame(int n)
{
frame += n;
if (frame > stack + TOS)
stop("frame underflow");
}
void
save(void)
{
frame -= 8;
if (frame < stack + tos)
stop("frame overflow, circular reference?");
frame[0] = p1;
frame[1] = p2;
frame[2] = p3;
frame[3] = p4;
frame[4] = p5;
frame[5] = p6;
frame[6] = p7;
frame[7] = p8;
}
void
restore(void)
{
p1 = frame[0];
p2 = frame[1];
p3 = frame[2];
p4 = frame[3];
p5 = frame[4];
p6 = frame[5];
p7 = frame[6];
p8 = frame[7];
frame += 8;
if (frame > stack + TOS)
stop("frame underflow");
}
void
restore_frame(U **save_frame)
{
frame = save_frame - 8;
restore();
}
void
swap(void)
{
U *tmp;
tmp = stack[tos - 1];
stack[tos - 1] = stack[tos - 2];
stack[tos - 2] = tmp;
}