#include "infixtopostfix.h"

// The following functions are for converting from Prefix to PostFix Expression

// arrstk_x means arraystack_x, pointing to stack operations happening on array

// Gives a initial value to the top of stack
void arrstk_initialize(int *top)
{
    *top = 0;
}

// Pop the topmost element of stack (by changing where top points)
int arrstk_pop(char *stack, int *top)
{
    return stack[(*top)--];
}

// Add an element to the stack, it will replace any other element that was at that
// array index
void arrstk_push(char *stack, int* top, char elem)
{
    stack[++(*top)] = elem;
}

// Precedence of operators checker
int oper_prec(char opr)
{
    switch(opr)
    {
    case '(': return 1;
    case '>': return 2;
    case '+': return 3;
    case '*': return 4;
    case '~': return 5;
    default : return 0;
    }
}

// Check if stack is empty
int arrstk_empty(int *top)
{
    return *top == 0 ? 1 : 0;
}

// The Infix to PostFix Function

void inToPostfix(char *arg_inFix, char *arg_postfix)
{
    char arr_stack[4000]; // The max size of the expression that we consider
    int stack_top, infix_iter = 0, postfix_iter=-1; //The indicies for our arrays
    char checker, element;
    arrstk_initialize(&stack_top);

    while((checker = arg_inFix[infix_iter++]) != '\0')
    {
        if( checker == '(')   // If '(' then push on stack
        {
            arrstk_push(arr_stack, &stack_top, checker);
        }
        else if(isalnum(checker))  // If an operand then send to postfix
        {
            arg_postfix[++postfix_iter] = checker;
        }
        // For closing bracket pop elements from stack and send to postfix
        else if(checker == ')')
        {   while((arr_stack[stack_top] != '('))
            {
                arg_postfix[++postfix_iter] = arrstk_pop(arr_stack, &stack_top);
            }
            arrstk_pop(arr_stack, &stack_top);
        }
        // It is an operator
        else
        {
            while(!arrstk_empty(&stack_top) && (oper_prec(arr_stack[stack_top]) >= oper_prec(checker)))
            {
                arg_postfix[++postfix_iter] = arrstk_pop(arr_stack, &stack_top);
            }
            arrstk_push(arr_stack, &stack_top, checker);
        }
    }

    while(stack_top != 0)
        {
            arg_postfix[++postfix_iter] = arrstk_pop(arr_stack, &stack_top);
        }
    arg_postfix[++postfix_iter]='\0';
}