/*
 * rpn_1.c
 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct {
    int max_size;
    int tos;
    float *data;
} t_stack;

void init_stack(t_stack * s, int size)
{
    s->max_size = size;
    s->tos = 0;
    s->data = (float *)malloc(size * sizeof(float));
}

void delete_stack(t_stack * s)
{
    free(s->data);
}

int push(t_stack * s, float value)
{
    if (s->tos < s->max_size) {
        s->data[s->tos++] = value;
        return 1;
    }
    else
        return 0;
}

int pop(t_stack * s, float * value)
{
    if (s->tos > 0) {
        *value = s->data[--s->tos];
        return 1;
    }
    else
        return 0;
}

int top_of_stack(t_stack * s, float * value)
{
    if (s->tos > 0) {
        *value = s->data[s->tos - 1];
        return 1;
    }
    else
        return 0;
}

int stack_size(t_stack * s)
{
    return s->tos;
}

void show(t_stack * s)
{
    int i;
    printf("STACK: [");
    for (i = s->tos - 1;i >= 0;i--)
        printf("%f ", s->data[i]);
    printf("]\n");
}

void main()
{
    t_stack mystack;
    init_stack(&mystack, 16);
    for (;;) {
        char cmd[64];
        float x, y;
        show(&mystack);
        printf("CMD> ");
        scanf("%s", cmd);
        if (!strcmp(cmd, "quit")) {
            delete_stack(&mystack);
            return;
        }
        else if (isdigit(cmd[0])) {
            x = atof(cmd);
            if (!push(&mystack, x))
                printf("Stack full!!\n");
        }
        else if (!strcmp(cmd, "+")) {
            if (stack_size(&mystack) < 2) {
                printf("Too few operands in stack!!\n");
            }
            else {
                pop(&mystack, &x);
                pop(&mystack, &y);
                x = x + y;
                push(&mystack, x);
            }
        }
        else if (!strcmp(cmd, "-")) {
            if (stack_size(&mystack) < 2) {
                printf("Too few operands in stack!!\n");
            }
            else {
                pop(&mystack, &x);
                pop(&mystack, &y);
                x = x - y;
                push(&mystack, x);
            }
        }
        else if (!strcmp(cmd, "*")) {
            if (stack_size(&mystack) < 2) {
                printf("Too few operands in stack!!\n");
            }
            else {
                pop(&mystack, &x);
                pop(&mystack, &y);
                x = x * y;
                push(&mystack, x);
            }
        }
        else if (!strcmp(cmd, "/")) {
            if (stack_size(&mystack) < 2) {
                printf("Too few operands in stack!!\n");
            }
            else {
                pop(&mystack, &x);
                pop(&mystack, &y);
                x = x / y;
                push(&mystack, x);
            }
        }
        else if (!strcmp(cmd, "neg")) {
            if (stack_size(&mystack) < 1) {
                printf("Too few operands in stack!!\n");
            }
            else {
                pop(&mystack, &x);
                push(&mystack, -x);
            }
        }
        else if (!strcmp(cmd, "tos")) {
            if (stack_size(&mystack) < 1) {
                printf("Too few operands in stack!!\n");
            }
            else {
                top_of_stack(&mystack, &x);
                printf("TOS: %f\n", x);
            }
        }
        else if (!strcmp(cmd, "pop")) {
            if (!pop(&mystack, &x))
                printf("Stack is empty!!\n");
        }
        else {
            printf("Invalid command\n");
        }
    }
}



