eigenmath/stack.cpp

120 lines
1.8 KiB
C++
Raw Permalink Normal View History

2004-03-03 21:24:06 +01:00
// _______
// | | <- 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.
//
2007-08-18 18:27:31 +02:00
// The frame area holds local variables and grows from high memory towards
// low memory. The frame area makes local variables visible to the garbage
// collector.
2004-03-03 21:24:06 +01:00
2007-08-18 18:27:31 +02:00
#include "stdafx.h"
2004-03-03 21:24:06 +01:00
#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)
2006-05-06 01:27:26 +02:00
stop("frame overflow, circular reference?");
2004-03-03 21:24:06 +01:00
for (i = 0; i < n; i++)
2006-01-16 20:37:31 +01:00
frame[i] = symbol(NIL);
2004-03-03 21:24:06 +01:00
}
void
pop_frame(int n)
{
frame += n;
if (frame > stack + TOS)
stop("frame underflow");
}
void
save(void)
{
2008-04-14 02:20:00 +02:00
frame -= 10;
2004-03-03 21:24:06 +01:00
if (frame < stack + tos)
2006-05-06 01:27:26 +02:00
stop("frame overflow, circular reference?");
2008-04-14 02:20:00 +02:00
frame[0] = p0;
frame[1] = p1;
frame[2] = p2;
frame[3] = p3;
frame[4] = p4;
frame[5] = p5;
frame[6] = p6;
frame[7] = p7;
frame[8] = p8;
frame[9] = p9;
2004-03-03 21:24:06 +01:00
}
void
restore(void)
{
2008-05-18 21:34:03 +02:00
if (frame > stack + TOS - 10)
stop("frame underflow");
2008-04-14 02:20:00 +02:00
p0 = frame[0];
p1 = frame[1];
p2 = frame[2];
p3 = frame[3];
p4 = frame[4];
p5 = frame[5];
p6 = frame[6];
p7 = frame[7];
p8 = frame[8];
p9 = frame[9];
frame += 10;
2004-03-03 21:24:06 +01:00
}
2008-05-10 03:31:26 +02:00
// Local U * is OK here because there is no functional path to the garbage collector.
2008-04-14 04:35:01 +02:00
2004-03-03 21:24:06 +01:00
void
swap(void)
{
2008-05-10 03:31:26 +02:00
U *p, *q;
p = pop();
q = pop();
push(p);
push(q);
2008-04-14 04:35:01 +02:00
}
2008-05-10 03:31:26 +02:00
// Local U * is OK here because there is no functional path to the garbage collector.
2008-04-14 04:35:01 +02:00
void
dupl(void)
{
U *p;
p = pop();
push(p);
push(p);
2004-03-03 21:24:06 +01:00
}