213 lines
4.8 KiB
C
213 lines
4.8 KiB
C
#include <stdio.h>
|
|
#include <malloc.h>
|
|
#include <string.h>
|
|
#include "lceb.h"
|
|
|
|
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: Op=%s Val=%4d\n",
|
|
i, (char *)stack->stack[i].op, stack->stack[i].val);
|
|
} else {
|
|
printf("Stack [%s] : ", stack->name);
|
|
for (i=0; i<stack->last; ++i) {
|
|
printf("%d[%s] ", stack->stack[i].val, (char *)stack->stack[i].op);
|
|
}
|
|
printf("\n");
|
|
}
|
|
}
|
|
|
|
STACK *new_stack(size, name)
|
|
int size; /* 0 if empty */
|
|
char *name;
|
|
{
|
|
STACK *stack;
|
|
STACKELT *pelt;
|
|
int i;
|
|
|
|
stack=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(STACKELT));
|
|
stack->size=size;
|
|
stack->stack=pelt;
|
|
for (i=0; i<size; ++i) {
|
|
(pelt+i)->nop=0;
|
|
(pelt+i)->curop=0;
|
|
(pelt+i)->op[0]=End;
|
|
(pelt+i)->val=-1;
|
|
(pelt+i)->next=i+1;
|
|
(pelt+i+1)->prev=i;
|
|
}
|
|
(pelt+i-1)->next=-1;
|
|
}
|
|
return stack;
|
|
}
|
|
|
|
STACKELT *push_stack(stack, op, val)
|
|
STACK *stack;
|
|
OPER op;
|
|
int val;
|
|
{
|
|
int pos=stack->last;
|
|
int size=stack->size;
|
|
STACKELT *pelt=stack->stack+stack->last;
|
|
|
|
if (pos >= size) {
|
|
fprintf(stderr, "stack overflow: size=%d last=%d\n", size, pos);
|
|
return NULL;
|
|
}
|
|
pelt->nop=0;
|
|
pelt->curop=0;
|
|
//pelt->op[0]=op;
|
|
pelt->val=val;
|
|
stack->last++;
|
|
return pelt;
|
|
}
|
|
|
|
STACKELT *pop_stack(stack)
|
|
STACK *stack;
|
|
{
|
|
int pos=stack->last+1;
|
|
int size=stack->size;
|
|
STACKELT *pelt=stack->stack+stack->last;
|
|
|
|
if (pos==0) {
|
|
fprintf(stderr, "stack empty: size=%d last=%d\n", size, pos);
|
|
return NULL;
|
|
}
|
|
stack->last--;
|
|
return pelt;
|
|
}
|
|
|
|
STACK *dup_stack(stack, name)
|
|
STACK *stack;
|
|
char *name;
|
|
{
|
|
STACK *new;
|
|
STACKELT *src=stack->stack, *dst;
|
|
int size=stack->size, last=stack->last, i;
|
|
|
|
new=new_stack(size, name);
|
|
dst=new->stack;
|
|
for (i=0; i<last; ++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)
|
|
STACKELT *elts;
|
|
int i, j;
|
|
{
|
|
STACKELT tmp=elts[i];
|
|
elts[i] = elts[j];
|
|
elts[j] = tmp;
|
|
}
|
|
|
|
int permute_stack(array, n)
|
|
STACKELT *array;
|
|
int n;
|
|
{
|
|
int i, j, start, end;
|
|
|
|
for(i=n-2; i>-1; i--) {
|
|
if(array[i+1].val > array[i].val) {
|
|
for(j=n-1; j>i; j--){
|
|
if(array[j].val > array[i].val){
|
|
// 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 mergesort_stack(array, left, right)
|
|
STACKELT *array;
|
|
int left, right;
|
|
{
|
|
int mid = (left+right)/2;
|
|
int pos=0, l=left, r=mid+1, i;
|
|
STACKELT 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].val < array[r].val) {
|
|
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];
|
|
}
|
|
}
|
|
|
|
STACKELT *set_op_stack(stack, pos, op)
|
|
STACK *stack;
|
|
int pos;
|
|
OPER op;
|
|
{
|
|
int size=stack->size;
|
|
STACKELT *pelt=stack->stack+pos;
|
|
|
|
if (pos >= size) {
|
|
fprintf(stderr, "set_op: stack overflow: size=%d last=%d\n", size, pos);
|
|
return NULL;
|
|
}
|
|
pelt->op[pelt->nop++]=op;
|
|
pelt->op[pelt->nop]=End;
|
|
//pelt->val=val;
|
|
//stack->last++;
|
|
return pelt;
|
|
}
|
|
|
|
STACKELT *set_ops_stack(stack, ops)
|
|
STACK *stack;
|
|
char *ops;
|
|
{
|
|
//int size=stack->size;
|
|
int last=stack->last;
|
|
int i, j; /* 1st operator in on second number */
|
|
STACKELT *pelt=stack->stack;
|
|
|
|
printf("setting ops [%s]\n", (char *)ops);
|
|
for (i=1, j=0; i<last; ++i, ++j) {
|
|
pelt[i].nop=1;
|
|
pelt[i].curop=0;
|
|
printf("setting op [%c-%x] to pos %d[%d]\n", ops[j], ops[j], i, pelt[i].nop);
|
|
pelt[i].op[0]=ops[j];
|
|
pelt[i].op[1]=End;
|
|
}
|
|
return pelt;
|
|
}
|