123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120 |
- // _______
- // | | <- 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 holds local variables and grows from high memory towards
- // low memory. The frame area makes local variables visible to the garbage
- // collector.
- #include "stdafx.h"
- #include "defs.h"
- U **frame, **stack;
- 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 -= 10;
- if (frame < stack + tos)
- stop("frame overflow, circular reference?");
- 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;
- }
- void
- restore(void)
- {
- if (frame > stack + TOS - 10)
- stop("frame underflow");
- 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;
- }
- // Local U * is OK here because there is no functional path to the garbage collector.
- void
- swap(void)
- {
- U *p, *q;
- p = pop();
- q = pop();
- push(p);
- push(q);
- }
- // Local U * is OK here because there is no functional path to the garbage collector.
- void
- dupl(void)
- {
- U *p;
- p = pop();
- push(p);
- push(p);
- }
|