Files
Le-Compte-est-Bon/stack.c

272 lines
6.2 KiB
C

#include <stdio.h>
#include <malloc.h>
#include <string.h>
#include <signal.h>
#include "lceb.h"
static STACK *allstacks=NULL;
static int nstacks=0;
int totalstacks=0;
int laststack=0;
void print_stack(stack, details)
STACK *stack;
int details;
{
int i;
if (details) {
printf("Stack [%s] dump: %d/%d used\n", stack->name, stack->last, stack->size);
//printf("\tValue: %4d\n", stack->eval);
for (i=0; i<stack->last; ++i)
printf("\t%02d: Val=%4d\n",
i, stack->stack[i]);
} else {
printf("Stack [%s] : ", stack->name);
for (i=0; i<stack->last; ++i) {
printf("%d ", stack->stack[i]);
}
printf("\n");
}
}
void print_stacks()
{
int i;
//STACK *stack=stacks;
printf("nstacks=%d laststack=%d totalstacks=%d\n", nstacks, laststack, totalstacks);
//while (stack) {
for (i=0; i<laststack; ++i) {
printf("stack %d=", i);
//stack=stack->next;
print_stack(nth_stack(i), 1);
//stack=stack->next;
}
}
STACK *new_stack(size, name, keep)
int size; /* unused */
char *name;
int keep;
{
STACK *stack;
int i;
# ifdef DEBUG_STACK
printf("new_stack(size=%d, name=[%s] last=%d total=%d)\n",
size, name, laststack, totalstacks);
# endif
if (!allstacks) {
totalstacks=ALLOCSIZE;
# ifdef DEBUG_MEM
printf("new_stack: allocating %d stacks\n", totalstacks);
# endif
allstacks=malloc(totalstacks*sizeof (STACK));
}
if (laststack==totalstacks) {
totalstacks+=ALLOCSIZE;
# ifdef DEBUG_MEM
printf("new_stack: resizing stacks array to %d\n", totalstacks);
# endif
allstacks=realloc(allstacks, totalstacks*sizeof (STACK));
}
stack=allstacks+laststack;
//printf("new_stack %d/%d: address=%p\n", laststack, totalstacks, stack);
laststack++;
//malloc(sizeof (STACK));
//stack->stack=NULL;
//stack->size=0;
stack->last=0;
//stack->eval=0;
strncpy(stack->name, name? name: "No name", sizeof(stack->name));
//if (size) {
//pelt=malloc(size*sizeof(int));
stack->size=size;
//stack->stack=pelt;
//if (keep)
// keep_stack(stack);
for (i=0; i<MAXINPUT; ++i) {
//(pelt+i)->nop=0;
//(pelt+i)->curop=0;
//(pelt+i)->op[0]=End;
stack->stack[i]=-1;
//(pelt+i)->next=i+1;
//(pelt+i+1)->prev=i;
}
return stack;
}
int *push_stack(stack, val)
STACK *stack;
int val;
{
int pos=stack->last;
int size=stack->size;
int *pelt=stack->stack+stack->last;
# ifdef DEBUG_STACK2
printf("push_stack(%d:[%s]): last=%d size=%d\n",
val, stack->name, stack->last, stack->size);
# endif
if (pos >= size) {
fprintf(stderr, "stack overflow: size=%d last=%d. generating core.\n", size, pos);
raise(SIGABRT);
return NULL; /* useless, we died */
}
//pelt->nop=0;
//pelt->curop=0;
//pelt->op[0]=op;
*pelt=val;
stack->last++;
return pelt;
}
int *pop_stack(stack)
STACK *stack;
{
int pos=stack->last+1;
int *pelt=stack->stack+stack->last;
if (pos==0) {
# ifdef DEBUG_STACK
printf("pop: empty stack [%s]: size=%d last=%d\n", stack->name, stack->size, pos);
# endif
return NULL;
}
stack->last--;
return pelt;
}
STACK *dup_stack(stack, name)
STACK *stack;
char *name;
{
STACK *new;
int *dst;
int size=stack->size, last=stack->last, i;
//printf("DUP: totalstacks=%d\n", totalstacks);
new=new_stack(size, name, 0);
new->last=stack->last;
dst=new->stack;
for (i=0; i<last; ++i) {
dst[i]=stack->stack[i];
//dst->nop=src->nop;
//dst->curop=src->curop;
//dst->val=src->val;
//memcpy(dst->op, src->op, sizeof(src->op));
}
//stack->last++;
return new;
}
void swap(elts, i, j)
int *elts;
int i, j;
{
int tmp=elts[i];
elts[i] = elts[j];
elts[j] = tmp;
}
int permute_stack(array, n)
int *array;
int n;
{
int i, j, start, end;
for(i=n-2; i>-1; i--) {
if(array[i+1] > array[i]) {
for(j=n-1; j>i; j--){
if(array[j] > array[i]){
// swap
swap(array, i, j);
// reverse
for (start=i+1, end=n-1; start < end; ++start, --end)
swap(array, start, end);
return 1;
}
}
}
}
return 0;
}
void gen_stacks(stack)
STACK *stack;
{
char name[80];
int last=stack->last;
int n=1;
int exists=1;
printf("GEN: totalstacks=%d\n", totalstacks);
# ifdef DEBUG_STACK
printf("generating stacks...\n");
# endif
//printf("last=%d laststack=%d totalstacks=%d\n", last, laststack, totalstacks);
# ifdef DEBUG_STACK
printf("sorting initial stack...\n");
# endif
mergesort_stack(stack->stack, 0, last-1);
# ifdef DEBUG_STACK
print_stack(stack, 0);
# endif
dup_stack(stack, "Main stack");
while (exists) {
sprintf(name, "Stack copy %d", n);
exists=permute_stack(stack->stack, stack->last);
if (exists) {
dup_stack(stack, name);
}
n++;
}
}
void mergesort_stack(array, left, right)
int *array;
int left, right;
{
int mid = (left+right)/2;
int pos=0, l=left, r=mid+1, i;
int tmp[right-left+1];
if(left < right) {
mergesort_stack(array, left, mid);
mergesort_stack(array, mid+1,right);
while (l <= mid && r <= right) {
if (array[l] < array[r]) {
tmp[pos++] = array[l++];
}
else {
tmp[pos++] = array[r++];
}
}
while (l <= mid)
tmp[pos++] = array[l++];
while (r <= right)
tmp[pos++] = array[r++];
for (i = 0; i < pos; ++i)
array[i+left] = tmp[i];
}
}
STACK *nth_stack(n)
int n;
{
//int i;
//STACK *stack=stacks;
//for (i=0; i<n && stack; ++i) {
// stack=stack->next;
//}
return allstacks+n;
}
int n_stacks()
{
return laststack;
}