#pragma prototyped
static const char id_stack[] = "\n@(#)$Id: stack (AT&T Bell Laboratories) 1984-05-01 $\0\n";
#include <ast.h>
#include <stack.h>
STACK
stackalloc(register int size, void* error)
{
register STACK stack;
register struct stackblock *b;
if (size <= 0) size = 100;
if (!(stack = newof(0, struct stacktable, 1, 0))) return(0);
if (!(b = newof(0, struct stackblock, 1, 0)))
{
free(stack);
return(0);
}
if (!(b->stack = newof(0, void*, size, 0)))
{
free(b);
free(stack);
return(0);
}
stack->blocks = b;
stack->size = size;
stack->error = error;
stack->position.block = b;
stack->position.index = -1;
b->next = 0;
b->prev = 0;
return(stack);
}
void
stackfree(register STACK stack)
{
register struct stackblock* b;
register struct stackblock* p;
b = stack->blocks;
while (p = b)
{
b = p->next;
free(p->stack);
free(p);
}
free(stack);
}
void
stackclear(register STACK stack)
{
stack->position.block = stack->blocks;
stack->position.index = -1;
}
void*
stackget(register STACK stack)
{
if (stack->position.index < 0) return(stack->error);
else return(stack->position.block->stack[stack->position.index]);
}
int
stackpush(register STACK stack, void* value)
{
register struct stackblock *b;
if (++stack->position.index >= stack->size)
{
b = stack->position.block;
if (b->next) b = b->next;
else
{
if (!(b->next = newof(0, struct stackblock, 1, 0)))
return(-1);
b = b->next;
if (!(b->stack = newof(0, void*, stack->size, 0)))
return(-1);
b->prev = stack->position.block;
b->next = 0;
}
stack->position.block = b;
stack->position.index = 0;
}
stack->position.block->stack[stack->position.index] = value;
return(0);
}
int
stackpop(register STACK stack)
{
if (stack->position.index < 0) return(-1);
else if (--stack->position.index < 0)
{
if (!stack->position.block->prev) return(0);
stack->position.block = stack->position.block->prev;
stack->position.index = stack->size - 1;
return(1);
}
else return(1);
}
void
stacktell(register STACK stack, int set, STACKPOS* position)
{
if (set) stack->position = *position;
else *position = stack->position;
}