blob: 810777adccd255bdf7a432512a6f8f3d42e36bb0 (
plain) (
tree)
|
|
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <math.h>
#include <string.h>
#define MAXOP 100
#define NUMBER_SIG '0'
#define SPECIAL_SIG '1'
#define VARIABLE_SIG '2'
#define ALPHABET_LEN 26
#define ON 1
#define OFF 0
double pop(void);
void push(double f);
char getop(char str[]);
void ptop(void);
void duplitop(void);
void swaptoptwo(void);
void clearstack(void);
void do_special(char str[]);
char getch(void);
void ungetch(char input);
double last_print;
int
main(void)
{
char str[MAXOP];
char vars[ALPHABET_LEN];
char vars_state[ALPHABET_LEN];
char type;
double op2;
for (int i = 0; i < ALPHABET_LEN; i++)
vars_state[i] = OFF;
vars_state[ALPHABET_LEN-1] = '\0';
while ((type = getop(str)) != EOF) {
switch (type) {
case NUMBER_SIG :
push(atof(str));
break;
case SPECIAL_SIG :
do_special(str);
break;
case VARIABLE_SIG :
/* Assuming variabke can only be set once */
if (vars_state[*str-'a'] == 1)
push(vars[*str-'a']);
else {
vars_state[*str-'a'] = ON;
push(vars[*str - 'a'] = pop());
}
break;
case '+' :
push(pop() + pop());
break;
case '*' :
push(pop() * pop());
break;
case '-' :
op2 = pop();
push(pop() - op2);
break;
case '/' :
if ((op2 = pop()) == 0.0)
printf("Err: deviser cant be zero\n");
else
push(pop() / op2);
break;
case '%' :
op2 = pop();
if (op2 != 0)
push(fmod(pop(), op2));
else
printf("Err: deviser cant be zero\n");
break;
case '^' :
ptop();
break;
case '>' :
duplitop();
break;
case '#' :
swaptoptwo();
break;
case '<' :
clearstack();
break;
case '\n' :
printf("%.8g\n", (last_print = pop()));
break;
default :
printf("Err: unknown command\n");
}
}
return 0;
}
#define MAXVAL 100
double val[MAXVAL];
int sp = 0;
void
do_special(char str[])
{
double tempop;
if (!strcmp(str, "sin"))
push(sin(pop()));
else if (!strcmp(str, "exp"))
push(exp(pop()));
else if (!strcmp(str, "pow")) {
tempop = pop();
push(pow(pop(), tempop));
}
}
void
ptop(void)
{
if (sp > 0)
printf("Top of the stack: %.8g\n", (last_print = val[sp-1]));
else
printf("Err: stack is empty\n");
}
void
duplitop(void)
{
val[sp] = val[sp-1];
++sp;
}
void
swaptoptwo(void)
{
double temp1 = pop();
double temp2 = pop();
push(temp1);
push(temp2);
}
void
clearstack(void)
{
sp = 0;
}
double
pop(void)
{
if (sp > 0)
return val[--sp];
else {
printf("Err: stack empty\n");
return 0.0;
}
}
void
push(double f)
{
if (sp < MAXVAL)
val[sp++] = f;
else
printf("Err: stack is full\n");
}
char
getop(char str[])
{
char input;
int i;
/* ignore blanks */
while ((input = str[0] = getch()) == ' ' || input == '\t');
if (isalpha(input)) {
i = 1;
while(isalpha(str[i++] = input = getch()));
str[--i] = '\0';
ungetch(input);
/* all single chars are reserved for variables*/
if (i == 1)
return VARIABLE_SIG;
return SPECIAL_SIG;
}
/* return operator */
if (!isdigit(input) && input != '.')
return input;
/* collect digits*/
for (i = 1; i < MAXOP && (isdigit(input=getch()) || input == '.'); i++)
str[i] = input;
str[i] = '\0';
if (input != EOF)
ungetch(input);
return NUMBER_SIG;
}
double buff = 0;
char
getch(void)
{
int temp;
if (buff) {
temp = buff;
buff = 0;
return temp;
}
else
return getchar();
}
void
ungetch(char input)
{
if (input == EOF) {
printf("Err: cant push back EOF\n");
return;
}
if (buff)
printf("Err: buffer full\n");
else
buff = input;
}
|