#include"math.h"

#include"stdlib.h"

#include"string.h"

#include"ctype.h"

#define rad 0.017453292

struct stack1

{

char item;

stack1 *next;

};

stack1 *push1(stack1 *hd,char m)

{

stack1 *ptr;

if(!(ptr=(stack1*)malloc(sizeof(stack1))))

{

cout<<"OVERFLOW";

exit(0);

}

else

{

ptr->item=m;

ptr->next=hd;

hd=ptr;

}

return hd;

}

stack1 *pop1(stack1* hd,char* v)

{

stack1 *ptr;

if(hd==NULL)

{

cout<<"\n\nEXPRESSION ERROR\n";

exit(0);

}

else

{

*v=hd->item;

ptr=hd;

hd=hd->next;

free(ptr);

}

return hd;

}

// **STACK2** [ used for evaluating the postfix expression ]

struct stack2

{

double item;

stack2 *next;

};

stack2 *push2(stack2 *hd,double m)

{

stack2 *ptr;

if(!(ptr=(stack2*)malloc(sizeof(stack2))))

{

cout<<"OVERFLOW";

exit(0);

}

else

{

ptr->item=m;

ptr->next=hd;

hd=ptr;

}

return hd;

}

stack2 *pop2(stack2* hd,double* v)

{

stack2 *ptr;

if(hd==NULL)

{

cout<<"\n\nEXPRESSION ERROR\n";

exit(0);

}

else

{

*v=hd->item;

ptr=hd;

hd=hd->next;

free(ptr);

}

return hd;

}

/* **MAKE_OPERAND** [ function used for converting the

operands from string to double ] */

double make_operand(char acore[] )

{

double sum=0;

int n=0;

for(int i=0;acore[i]!='\0';i++)

{

if(acore[i]=='.')

{

n=i+1;

continue;

}

sum=sum*10+acore[i]-48;

}

if(n>0)

sum=sum/pow(10,i-n);

return sum;

}

/* **CLASS CAL**[ contains the input equation(eqn),postfix equation

(pol),result(result) and functions for postfixing

(polish),and evaluating(evaluate) the equation . ] */

class cal

{

char eqn[100],pol[100][100];

double result;

public:

void geteqn(char*);

void polish();

void evaluate();

void pr_pole();

};

void cal::geteqn(char c[])

{

strcpy(eqn,c);

}

// **POLISH**[function used for postfixing the equation.]

void cal::polish()

{

stack1 *head=NULL;

int m,v=0,error_check=0;

head=push1(head,'(');

m=strlen(eqn);

eqn[m]=')';

eqn[m+1]='\0';

for(int i=0;eqn[i]!='\0';i++)

{

if(isdigit(eqn[i])||eqn[i]=='.')

{

for(int j=0;;j++)

{

if(isdigit(eqn[i])||eqn[i]=='.')

{

pol[v][j]=eqn[i];

i++;

}

else

{

i--;

pol[v][j]='\0';

v++;

break;

}

}

}

if(isalpha(eqn[i]))

{

int n=0;

for(int j=0;;j++)

{

if(eqn[i]=='(')

n++;

if(isdigit(eqn[i])||isalpha(eqn[i])||eqn[i]=='.'||n!=0)

{

pol[v][j]=eqn[i];

if(eqn[i]==')')

n--;

i++;

}

else

{

i--;

pol[v][j]='\0';

v++;

break;

}

}

}

else if(eqn[i]=='(')

{

head=push1(head,'(');

error_check++;

}

else if(eqn[i]=='+'||eqn[i]=='-'||eqn[i]=='*'||eqn[i]=='/'||eqn[i]=='%'||eqn[i]=='^')

{

if(eqn[i]=='+'||eqn[i]=='-')

{

while(head->item!='(')

{

head=pop1(head,&pol[v][0]);

pol[v][1]='\0';

v++;

}

head=push1(head,eqn[i]);

}

else if(eqn[i]=='*')

{

while(head->item!='('&&head->item!='+'&&head->item!='-')

{

head=pop1(head,&pol[v][0]);

pol[v][1]='\0';

v++;

}

head=push1(head,eqn[i]);

}

else if(eqn[i]=='/')

{

while(head->item!='('&&head->item!='+'&&head->item!='-'&&head->item!='*')

{

head=pop1(head,&pol[v][0]);

pol[v][1]='\0';

v++;

}

head=push1(head,eqn[i]);

}

else if(eqn[i]=='%')

{

while(head->item!='('&&head->item!='+'&&head->item!='-'&&head->item!='*'&&head->item!='/')

{

head=pop1(head,&pol[v][0]);

pol[v][1]='\0';

v++;

}

head=push1(head,eqn[i]);

}

else if(eqn[i]=='^')

{

while(head->item!='('&&head->item!='+'&&head->item!='-'&&head->item!='*'&&head->item!='/'&&head->item!='%')

{

head=pop1(head,&pol[v][0]);

pol[v][1]='\0';

v++;

}

head=push1(head,eqn[i]);

}

}

else if(eqn[i]==')')

{

error_check--;

char c;

while(head->item!='(')

{

head=pop1(head,&pol[v][0]);

pol[v][1]='\0';

v++;

}

head=pop1(head,&c);

}

}

if(error_check!=-1)

{

cout<<"\n\nEXPRESSION ERRORs\n";

exit(0);

}

pol[v][0]='\0';

}

// **EVALUATE**[function used for evaluating the equation.]

void cal::evaluate()

{

stack2 *head=NULL;

for(int i=0;pol[i][0]!='\0';i++)

{

if(isdigit(pol[i][0])||pol[i][0]=='.')

head=push2(head,make_operand(pol[i]));

else if(isalpha(pol[i][0]))

{

char trigo[4],rest[100];

double para;

for(int j=0;isalpha(pol[i][j]);j++)

trigo[j]=pol[i][j];

trigo[j]='\0';

for(int k=0;pol[i][j]!='\0';j++,k++)

rest[k]=pol[i][j];

rest[k]='\0';

if(rest[0]=='(')

{

cal Y;

Y.geteqn(rest);

Y.polish();

Y.evaluate();

para=Y.result;

}

else

para=make_operand(rest);

if(!strcmp("tan",trigo))

{

if((int)para%180!=90)

{

cout<<"\n\nMATH ERROR\n";

exit(0);

}

else if((int)para%180!=0)

head=push2(head,tan(para*rad));

else

head=push2(head,0.0);

}

else if(!strcmp("sin",trigo))

{

if((int)para%180!=0)

head=push2(head,sin(para*rad));

else

head=push2(head,0.0);

}

else if(!strcmp("cos",trigo))

{

if((int)para%180!=90)

head=push2(head,cos(para*rad));

else

head=push2(head,0.0);

}

else if(!strcmp("log",trigo))

head=push2(head,log10(para));

else if(!strcmp("ln",trigo))

head=push2(head,log(para));

}

else

{

double opp1,opp2;

head=pop2(head,&opp1);

head=pop2(head,&opp2);

if(pol[i][0]=='+')

head=push2(head,opp2+opp1);

else if(pol[i][0]=='-')

head=push2(head,opp2-opp1);

else if(pol[i][0]=='*')

head=push2(head,opp2*opp1);

else if(pol[i][0]=='/')

{

if(opp1==0)

{

cout<<"\n\nMATH ERROR\n";

exit(0);

}

else

head=push2(head,opp2/opp1);

}

else if(pol[i][0]=='%')

{

if(opp1==0)

{

cout<<"\n\nMATH ERROR\n";

exit(0);

}

head=push2(head,(int)opp2%(int)opp1);

}

else if(pol[i][0]=='^')

head=push2(head,pow(opp2,opp1));

}

}

head=pop2(head,&result);

}

void cal:: pr_pole()

{

cout<<"\n\nRESULT:"<

//MAIN FENCTION

void main()

{

cal X;

char c[100];

cout<<"\n\n*** you can do the operation of +,-,*,/,%,^,sin,cos,tan,log and ln ***"

<<"\n\ngive the equation:\n";

cin>>c;

X.geteqn(c);

X.polish();

X.evaluate();

X.pr_pole();

}