Created
January 15, 2016 15:22
-
-
Save krysseltillada/e746530884f751a83c77 to your computer and use it in GitHub Desktop.
calc polish notation (ex 4-3 --> 4-10 c the programming language 2nd ed)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stdlib.h> | |
#include <ctype.h> | |
#include <math.h> | |
#define MAXOP 100 | |
#define NUMBER '0' | |
#define MAXBUFFER 1000 | |
#define TRUE 1 | |
#define FALSE 0 | |
int ifnegative = 0; | |
int ifprint = 0; | |
int ifcalculated = 0; | |
int ifBufferClear = 1; | |
int buffCount = 0; | |
int indCount = 0; | |
int getop (char []); | |
void push (double); | |
double pop (void); | |
void printStack (); | |
void clearStack (); | |
void duplicate (); | |
void reverse (double [], size_t); | |
void copy (double [], double [], size_t); | |
void swap (); | |
void addVariable (); | |
char buffer[MAXBUFFER]; | |
int main () | |
{ | |
int type; | |
double op2; | |
char s[MAXOP]; | |
int operands = 0; | |
while ( TRUE ) { | |
if (ifBufferClear) | |
getline (buffer, MAXBUFFER); | |
type = getopRevised (s); | |
switch (type) { | |
case '#': | |
buffCount = 0; | |
ifBufferClear = 1; | |
indCount = 0; | |
break; | |
case NUMBER: | |
if (ifnegative) { | |
push (-atof (s)); | |
ifnegative = 0; | |
} | |
else { | |
push (atof (s)); | |
} | |
++operands; | |
break; | |
case '+': | |
push (pop () + pop ()); | |
operands = 0; | |
ifcalculated = 1; | |
break; | |
case '*': | |
push (pop () * pop ()); | |
ifcalculated = 1; | |
break; | |
case '-': | |
if (operands == 2) { | |
op2 = pop (); | |
push (pop () - op2); | |
} | |
ifcalculated = 1; | |
operands = 0; | |
break; | |
case '/': | |
op2 = pop (); | |
if (op2 != 0.0) { | |
push (pop () / op2); | |
ifcalculated = 1; | |
} | |
else | |
printf ("error: zero divisor \n"); | |
break; | |
case '%': | |
push ( (int) pop () % (int) pop ()); | |
ifcalculated = 1; | |
break; | |
case 'p': | |
printStack (); | |
break; | |
case 'd': | |
duplicate (); | |
break; | |
case 'c': | |
clearStack(); | |
break; | |
case 's': | |
swap(); | |
break; | |
case 'e': | |
push (exp (pop ())); | |
ifcalculated = 1; | |
break; | |
case 'i': | |
push(sin (pop () * 3.14159265 / 180)); | |
ifcalculated = 1; | |
break; | |
case 'w': | |
push (pow (pop (), pop())); | |
ifcalculated = 1; | |
break; | |
case 'v': | |
addVariable (); | |
break; | |
case '\n': | |
if (!ifprint) { | |
if (ifcalculated) { | |
printf ("\t%.8g\n", pop ()); | |
ifcalculated = 0; | |
} | |
} else { | |
ifprint = 0; | |
} | |
break; | |
default: | |
printf ("error: unknown command %s\n", s); | |
break; | |
} | |
} | |
return 0; | |
} | |
#define MAXVAL 100 | |
#define MAXLETTER 27 | |
int sp = 0; | |
int tempsp = 0; | |
int tempsp2 = 0; | |
int tempsp3 = 0; | |
int ifduplicate = 0; | |
int ifvariable = 0; | |
int tempsp4 = 0; | |
double val[MAXVAL]; | |
char variable[MAXLETTER]; | |
double top () | |
{ | |
if (tempsp <= 0) | |
tempsp = sp; | |
else if (ifduplicate) | |
return val[--tempsp2]; | |
return val[--tempsp]; | |
} | |
void push (double f) | |
{ | |
if (sp < MAXVAL) { | |
if (ifduplicate) { | |
val[tempsp3++] = f; | |
return; | |
} | |
val[sp++] = f; | |
tempsp = sp; | |
} | |
else | |
printf ("error: stack full. can't push %g\n", f); | |
} | |
double pop (void) | |
{ | |
if (sp > 0) | |
return val[--sp]; | |
else { | |
printf ("error: stack empty\n"); | |
return 0.0; | |
} | |
} | |
void swap () | |
{ | |
int temp; | |
if (sp > 0) { | |
temp = val[sp - 1]; | |
val[sp - 1] = val[sp - 2]; | |
val[sp - 2] = temp; | |
} | |
} | |
void addVariable () | |
{ | |
int i = 0; | |
int c = 'a'; | |
for (; i < sp && i < MAXLETTER ; ++i, ++c) | |
variable[i] = c; | |
ifvariable = 1; | |
} | |
void printStack () | |
{ | |
int i = 0; | |
printf ("stack\n"); | |
printf ("stack size : %d\n", sp); | |
for (; i < sp; ++i) { | |
printf ("%f ", top ()); | |
if (ifvariable) | |
printf ("variable %c\n", variable[i]); | |
else | |
printf ("\n"); | |
} | |
} | |
void reverse (double arr[], size_t sz) { | |
double temparr[MAXVAL]; | |
int i, a; | |
for (i = sz - 1, a = 0; i >= 0; --i, ++a) | |
temparr[a] = arr[i]; | |
copy(temparr, arr, sz); | |
} | |
void copy (double darr1[], double darr2[], size_t sz) | |
{ | |
int i = 0; | |
for (; i < sz ; ++i) | |
darr2[i] = darr1[i]; | |
} | |
void duplicate () | |
{ | |
double tempD [MAXVAL]; | |
int i = 0; | |
int a = 0; | |
tempsp2 = sp; | |
tempsp3 = sp; | |
ifduplicate = 1; | |
for (; a < sp; ++a) | |
tempD[a] = top (); | |
reverse (tempD, a); | |
for (; i < sp; ++i) | |
push(tempD[i]); | |
tempsp2 = tempsp3; | |
ifduplicate = 0; | |
sp = tempsp2; | |
tempsp = sp; | |
} | |
void clearStack () | |
{ | |
printf ("clearStack\n"); | |
tempsp2 = tempsp3 = tempsp = sp = 0; | |
ifvariable = 0; | |
} | |
int getch (void); | |
void ungetch (int); | |
void ungets (char []); | |
void getline (char [], size_t); | |
int inGet (); | |
int inGet () | |
{ | |
int ch, bc; | |
if (indCount <= buffCount) { | |
return buffer[indCount++]; | |
} | |
else | |
printf ("buffer out of range \n"); | |
} | |
void getline (char buf[], size_t bufSz) | |
{ | |
int c, i; | |
for (i = 0; (c = getchar ()) != EOF && c != '\n'; ++i, ++buffCount) | |
buf[i] = c; | |
if (c == '\n') { | |
buf[i++] = '\n'; | |
++buffCount; | |
} | |
ifBufferClear = 0; | |
buf[i] = '\0'; | |
} | |
int getopRevised (char s[]) | |
{ | |
int i, c; | |
for (; isspace ( (s[0] = c = inGet()) ) && c != '\n' ; ) { printf ("space \n"); } | |
s[1] = '\0'; | |
i = 0; | |
if (c == '\n') | |
return c; | |
if ( !isdigit (c) ) { | |
if (c != '.') { | |
if (c == '-') | |
ifnegative = 1; | |
else if (c == '\0') | |
return '#'; | |
return c; | |
} | |
} | |
if ( isdigit (c) ) { | |
s[i++] = c; | |
for (; isdigit (s[i++] = c = inGet()) ;) | |
; | |
} | |
if (c == '.') { | |
s[i] = c; | |
for (; isdigit (s[i++] = c = inGet()) ;) | |
; | |
} | |
s[i] = '\0'; | |
return NUMBER; | |
} | |
int getop (char s[]) | |
{ | |
int i, c; | |
while ( (s[0] = c = getch ()) == ' ' || c == '\t' ) | |
; | |
s[1] = '\0'; | |
i = 0; | |
if ( !isdigit (c) && c != '.') { | |
if (c == '-' ) | |
ifnegative = 1; | |
printf ("%c\n", c); | |
return c; | |
} | |
if ( isdigit (c)) | |
while (isdigit (s[++i] = c = getch ()) ) | |
; | |
if (c == '.') | |
while (isdigit (s[++i] = c = getch ()) ) | |
; | |
s[i] = '\0'; | |
if (c != EOF) { | |
ungetch (c); | |
} | |
return NUMBER; | |
} | |
#define BUFSIZE 1000 | |
char buf[BUFSIZE]; | |
int bufp = 0; | |
int getch (void) | |
{ | |
int c = getchar (); | |
if (c != EOF) | |
return c; | |
else { | |
printf ("EOF::\n"); | |
return -1; | |
} | |
} | |
void ungetch (int c) | |
{ | |
if (bufp >= BUFSIZE && c == EOF) | |
printf ("ungetch: too many characters\n"); | |
else { | |
buf[bufp++] = c; | |
} | |
} | |
void ungets (char str[]) | |
{ | |
int i = 0; | |
if (bufp >= BUFSIZE) | |
printf ("ungets: too many characters\n"); | |
else { | |
for (; i < sizeof (str) / sizeof (char); ++i) | |
ungetch(str[i]); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment