K & R C Programs Exercise 4-6.

K and R C, Solution to Exercise 4-6:
K and R C Programs Exercises provides the solution to all the exercises in the C Programming Language (2nd Edition). You can learn and solve K&R C Programs Exercise.
C Program to Add commands for handling variables.(It’s easy to provide twenty-six variables with single-letter names.). Add a variable for the most recently printed value.
/***********************************************************
* You can use all the programs on www.c-program-example.com
* for personal and learning purposes. For permissions to use the
* programs for commercial purposes,
* contact info@c-program-example.com
* To find more C programs, do visit www.c-program-example.com
* and browse!
*
* Happy Coding
***********************************************************/

#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <math.h>
#include <string.h>

#define MAXOP 100
#define NUMBER 0
#define IDENTIFIER 1
#define ENDSTRING 2
#define TRUE 1
#define FALSE 0
#define MAX_ID_LEN 32
#define MAXVARS 30


struct varType{
char name[MAX_ID_LEN];
double val;
};


int Getop(char s[]);
void push(double val);
double pop(void);
void showTop(void);
void duplicate(void);
void swapItems(void);
void clearStacks(struct varType var[]);
void dealWithName(char s[], struct varType var[]);
void dealWithVar(char s[], struct varType var[]);

int pos = 0;
struct varType last;

int main(void)
{
int type;
double op2;
char s[MAXOP];
struct varType var[MAXVARS];

clearStacks(var);

while((type = Getop(s)) != EOF)
{
switch(type)
{
case NUMBER:
push(atof(s));
break;
case IDENTIFIER:
dealWithName(s, var);
break;
case '+':
push(pop() + pop());
break;
case '*':
push(pop() * pop());
break;
case '-':
op2 = pop();
push(pop()- op2);
break;
case '/':
op2 = pop();
if(op2)
push(pop() / op2);
else
printf("nError: division by zero!");
break;
case '%':
op2 = pop();
if(op2)
push(fmod(pop(), op2));
else
printf("nError: division by zero!");
break;
case '?':
showTop();
break;
case '#':
duplicate();
break;
case '~':
swapItems();
break;
case '!':
clearStacks(var);
break;
case 'n':
printf("nt%.8gn", pop());
break;
case ENDSTRING:
break;
case '=':
pop();
var[pos].val = pop();
last.val = var[pos].val;
push(last.val);
break;
case '<':
printf("The last variable used was: %s (value == %g)n",
last.name, last.val);
break;

default:
printf("nError: unknown command %s.n", s);
break;
}
}
return EXIT_SUCCESS;
}

#define MAXVAL 100

int sp = 0;
double val[MAXVAL];

/* push: push f onto stack. */
void push(double f)
{
if(sp < MAXVAL)
val[sp++] = f;
else
printf("nError: stack full can't push %gn", f);
}

/*pop: pop and return top value from stack.*/
double pop(void)
{
if(sp > 0)
{
return val[--sp];
}
else
{
printf("nError: stack emptyn");
return 0.0;
}
}

void showTop(void)
{
if(sp > 0)
printf("Top of stack contains: %8gn", val[sp-1]);
else
printf("The stack is empty!n");
}


void duplicate(void)
{
double temp = pop();

push(temp);
push(temp);
}

void swapItems(void)
{
double item1 = pop();
double item2 = pop();

push(item1);
push(item2);
}


void clearStacks(struct varType var[])
{
int i;
sp = 0;

for( i = 0; i < MAXVARS; ++i)
{
var[i].name[0] = '