lolamontes69

K+R Exercise4_5

Sep 7th, 2014
246
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 11.81 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>    /*for atof() */
  3. #include <ctype.h>
  4. #include <math.h>
  5.  
  6. #define MAXOP   100    /* max size of operand or operator */
  7. #define MAXVAL  100    /* maximum depth of val stack      */
  8. #define NUMBER  '0'    /* signal that a number was found  */
  9. #define BUFSIZE 100    /* buffer for ungetch              */
  10.  
  11. /* Main functions */
  12. int    getop(char s[]);
  13. void   push(double f);
  14. double pop(void);
  15. int    getch(void);
  16. void   ungetch(int);
  17.  
  18. /* Command functions */
  19. void clearstack(void);     /* Command 'cs' Clear current stack   */
  20. void cleardupl(void);      /* Command 'cd' Clear duplicate stack */
  21. void stackprint(void);     /* Command 'ps' Print current stack   */
  22. void dsprint(void);        /* Command 'pd' Print duplicate stack*/
  23. void duplstack(void);      /* Command 'du' Duplicate stack print */
  24. void swaptop(void);        /* Command 'sw' Swap top two elements of stack */
  25. void help(void);           /* Command 'help' Print 'help screen' */
  26.  
  27. /* External variables */
  28. int sp = 0;                /* Next free stack position        */
  29. double val[MAXVAL];        /* value stack                     */
  30. char buf[BUFSIZE];
  31. int bufp = 0;              /* next free position in buffer    */
  32.  
  33. double dupval[MAXVAL];     /* saved stack duplicate        */
  34. int dss = 0;               /* duplicate stack size for printing out dupval */
  35.  
  36. int NOPOP = 0;             /* try not to pop stack after typing in help */
  37.  
  38. /* main program:  A Reverse Polish calculator. */
  39. main()
  40. {
  41.     int type;
  42.     double op2;
  43.     double mod;
  44.     char s[MAXOP];
  45.  
  46.     while((type = getop(s)) != EOF) {
  47.         switch(type) {
  48.         case NUMBER:
  49.             NOPOP=0;
  50.             push(atof(s));         /* Add number to stack   */
  51.             break;
  52.         case '+':
  53.             NOPOP=0;
  54.             push(pop() + pop());   // pop last number from stack and add to previous
  55.             break;                 // number from stack then add to stack as last item
  56.         case '*':
  57.             NOPOP=0;
  58.             push(pop() * pop());   // as above with *
  59.             break;
  60.         case '-':                  // pop last number from stack save as op2
  61.             NOPOP=0;
  62.             op2 = pop();           // pop previous number from stack
  63.             push(pop() - op2);     // otherwise would produce op2 - pop()
  64.             break;                 // and push to stack replacing them
  65.         case '/':
  66.             NOPOP=0;
  67.             op2 = pop();           // as for '-' but with an errorcheck for
  68.             if(op2!=0.0)           // division by zero
  69.                 push(pop()/op2);
  70.             else
  71.                 printf("error: zero divisor\n");
  72.             break;
  73.         case '\%':
  74.             NOPOP=0;
  75.             op2 = pop();            // as for '-' but with an errorcheck for
  76.             mod = pop();            // % cannot be applied to float or double
  77.             if(op2!=0.0) {          // so do the math here instead.
  78.                 if(mod>0 && op2>0) {
  79.                     while(mod-op2>=0)
  80.                         mod = mod - op2;
  81.                 }
  82.                 else if(mod<0 && op2>0) {
  83.                     mod = mod-mod-mod;
  84.                     while(mod-op2>=0)
  85.                         mod = mod - op2;
  86.                 }
  87.                 else if(mod<0 && op2<0) {
  88.                     mod = mod-mod-mod;
  89.                     op2 = op2-op2-op2;
  90.                     while(mod-op2>=0)
  91.                         mod = mod - op2;
  92.                     mod = mod-mod-mod;
  93.                 }
  94.                 else if(mod>0 && op2<0) {
  95.                     op2 = op2-op2-op2;
  96.                     while(mod-op2>=0)
  97.                         mod = mod - op2;  
  98.                     mod = mod-mod-mod;
  99.                 }
  100.                 push(mod);
  101.             }
  102.             else
  103.                 printf("error: zero divisor\n");
  104.             break;
  105.         case '\n':                      // if end of equation pop last item from stack
  106.             if(NOPOP==0) printf("\t%.8g\n", pop());  // aka the answer
  107.             NOPOP=0;
  108.             break;
  109.         default:
  110.             NOPOP=0;
  111.             printf("error: unknown command %s\n", s);  // None of the above
  112.             break;                                     // You dun goofed
  113.         }
  114.     }
  115.     return 0;
  116. }
  117.  
  118. /* ////////////// MAIN FUNCTIONS ////////////// */
  119.  
  120. /* getop: get next character or numeric operand */
  121. int getop(char s[])
  122. {
  123.     int i, c;
  124.     double l, op2;  /* Used to keep answer passed to push() compatible */
  125.  
  126.     do {
  127.     while((s[0] = c = getch()) == ' ' || c == '\t')
  128.         ;
  129.     if(c=='c') {
  130.         s[0] = c = getch();
  131.         if(c =='s') clearstack();       /* cs - Clear current stack    */
  132.         else if(c=='d') cleardupl();    /* cd - Clear duplicate stack   */
  133.         else if(c=='o') {
  134.             s[0] = c = getch();
  135.             if(c=='s') {                /* cos - cos(x) function */
  136.                 l = cos(pop());
  137.                 NOPOP=0;
  138.                 push(l);                /* push to stack here */
  139.             }
  140.         }
  141.         while((s[0] = c = getch()) == ' ' || c == '\t')
  142.             ;
  143.     }
  144.     else if(c=='d') {
  145.         s[0] = c = getch();
  146.         if(c =='u') duplstack();        /* du - Make duplicate of current stack */
  147.         while((s[0] = c = getch()) == ' ' || c == '\t')
  148.             ;
  149.     }
  150.     else if(c=='e') {
  151.         s[0] = c = getch();
  152.         if(c=='x') {
  153.             s[0] = c = getch();
  154.             if(c=='p') {                /* exp - exp(x) function */
  155.                 l = exp(pop());
  156.                 NOPOP=0;
  157.                 push(l);                /* push to stack here */
  158.             }
  159.         }
  160.         while((s[0] = c = getch()) == ' ' || c == '\t')
  161.             ;
  162.     }
  163.  
  164.     else if(c=='h') {
  165.         s[0] = c = getch();
  166.         if(c =='e') {          /* help - Print 'Help screen' */
  167.             s[0] = c = getch();
  168.             if(c =='l') {
  169.                 s[0] = c = getch();
  170.                 if(c =='p') {
  171.                     help();
  172.                 }
  173.             }
  174.         }
  175.         while((s[0] = c = getch()) == ' ' || c == '\t')
  176.             ;
  177.     }
  178.     else if(c=='p') {
  179.         s[0] = c = getch();
  180.         if(c =='s') stackprint();       /* ps - Print current stack   */
  181.         else if(c=='d') dsprint();      /* pd - Print duplicate stack   */
  182.         else if(c=='o') {
  183.             s[0] = c = getch();
  184.             if(c=='w') {                /* pow - pow(x,y) function */
  185.                 op2 = pop();
  186.                 l = pow(pop(),op2);           //    pow(x,y)   x**y
  187.                 NOPOP=0;
  188.                 push(l);                /* push to stack here */
  189.             }
  190.         }
  191.         while((s[0] = c = getch()) == ' ' || c == '\t') // Skip spaces and tabs
  192.             ;
  193.     }
  194.     else if(c=='s') {
  195.         s[0] = c = getch();
  196.         if(c =='w') swaptop();          /* sw - Swap top two elements in current stack */
  197.         else if(c=='i') {
  198.             s[0] = c = getch();
  199.             if(c=='n') {                /* sin - sin(x) function */
  200.                 l = sin(pop());
  201.                 NOPOP=0;
  202.                 push(l);                /* push to stack here */
  203.             }
  204.         }
  205.         else if(c=='q') {
  206.             s[0] = c = getch();
  207.             if(c=='r') {                /* sqrt - sqrt(x) function */
  208.                 s[0] = c = getch();
  209.                 if(c=='t') {
  210.                     l = sqrt(pop());
  211.                     NOPOP=0;
  212.                     push(l);                /* push to stack here */
  213.                 }
  214.             }
  215.         }
  216.         while((s[0] = c = getch()) == ' ' || c == '\t')
  217.             ;
  218.     }
  219.  
  220.     }  /* End of do while*/
  221.     while(isalpha(c));
  222.     s[0] = c;
  223.     s[1] = '\0';
  224.     if(!isdigit(c) && c != '.' && c != '-')
  225.         return c;      /* Not a number          */
  226.     i = 0;
  227.     if(c == '-'){      /* collect fraction part */
  228.         NOPOP=0;
  229.         if(!isdigit(s[++i] = c = getch())) {
  230.            
  231.             if(c != EOF)     // if an extra char and not a digit
  232.                 ungetch(c);  // put into buffer (eg 4 4 * help
  233.             return '-';
  234.         }
  235.     }
  236.  
  237.     if(isdigit(c))    /* collect integer part  */
  238.         while(isdigit(s[++i] = c = getch()))
  239.             ;
  240.     if(c == '.')      /* collect fraction part */
  241.         while(isdigit(s[++i] = c = getch()))
  242.             ;
  243.     s[i] = '\0';
  244.     if(c != EOF)
  245.         ungetch(c);
  246.     return NUMBER;
  247. }
  248.  
  249. /* push: push f onto value stack    */
  250. void push(double f)
  251. {
  252.     if(sp < MAXVAL)
  253.         val[sp++] = f;     // Add item as stack[sp] then increment sp
  254.     else
  255.         printf("error: stack full, cant push %g\n", f);
  256. }
  257.  
  258. /* pop: pop and return top value from stack */
  259. double pop(void)
  260. {
  261.     if(sp > 0) {
  262.         if(NOPOP==0) return val[--sp];   // return last item in stack first decrementing sp
  263.         else NOPOP=0;
  264.     }
  265.     else {
  266.         if(NOPOP==0) {
  267.             printf("error: stack empty\n");
  268.             return 0.0;
  269.         }
  270.         else NOPOP=0;
  271.     }
  272. }
  273.  
  274. /* get a (possibly pushed-back) character */
  275. int getch(void)
  276. {
  277.     return (bufp > 0) ? buf[--bufp] : getchar();  
  278. }
  279.  
  280. /* push character back on input */
  281. void ungetch(int c)
  282. {
  283.     if(bufp >= BUFSIZE)
  284.         printf("ungetch: too many characters\n");
  285.     else
  286.         buf[bufp++] = c;  // Add character to buffer and increment bufp
  287. }
  288.  
  289. /* ////////////// COMMAND FUNCTIONS ////////////// */
  290.  
  291. /* clearstack: Clear current stack  */
  292. void clearstack(void)
  293. {
  294.     sp=0;
  295.     puts("Stack cleared");
  296.     NOPOP=1;
  297. }
  298.  
  299. /* cleardupl: Clear duplicate stack */
  300. void cleardupl(void)
  301. {
  302.     dss=0;
  303.     puts("Duplicate stack cleared");
  304.     NOPOP=1;
  305. }
  306.  
  307. /* stackprint: print out current stack */
  308. void stackprint(void)
  309. {
  310.     int spp = sp;
  311.  
  312.     if(spp<=0) printf("error: stack empty\n");
  313.     else {
  314.         printf("--Top of current stack--\n");
  315.         while(spp>sp-2)                    // Note > 0 to print full stack
  316.             printf("%9g\n", val[--spp]);   // print last item in stack
  317.         printf("-------------\n");
  318.     }
  319.     NOPOP=1;
  320. }
  321.  
  322. /* dsprint: print out the duplicate stack top down */
  323. void dsprint(void)
  324. {
  325.     int spp = dss;
  326.  
  327.     if(spp<=0) printf("error: duplicate stack empty\n");
  328.     else {
  329.         printf("--duplicate stack--\n");
  330.         while(spp>0)                    // Note > 0 to print full stack
  331.             printf("%9g\n", val[--spp]);   // print last item in stack
  332.         printf("--end of duplicate stack --\n");
  333.     }
  334.     NOPOP=1;
  335. }
  336.  
  337. /* duplstack: make duplicate of the current stack */
  338. void duplstack(void)
  339. {
  340.     dss=0;
  341.  
  342.     if(sp<=0) printf("error: can't duplicate, stack is empty\n");
  343.     else {
  344.         while(dss<sp) {
  345.             dupval[dss] = val[dss];  
  346.             dss++;
  347.         }
  348.     puts("Duplicate stack created");
  349.     }
  350.     NOPOP=1;
  351. }
  352.  
  353. /* swaptop: Swap top two elements of stack */
  354. void swaptop(void)
  355. {
  356.     double temp;
  357.  
  358.     if(sp<=0) printf("error: stack empty\n");
  359.     else if(sp==1) printf("error: \n");
  360.     else {
  361.         temp = val[sp-1];
  362.         val[sp-1]=val[sp-2];
  363.         val[sp-2]=temp;
  364.         puts("Top two elements of stack swapped");
  365.     }
  366.     NOPOP=1;
  367. }
  368.  
  369. /* help: Print out help on available commands */
  370. void help(void)
  371. {
  372.     puts("------------------------------");
  373.     puts("Help: Commands");
  374.     puts("cs   - Clear current stack");
  375.     puts("cd   - Clear duplicate stack");
  376.     puts("ps   - Print current stack");
  377.     puts("pd   - Print duplicate stack");
  378.     puts("sw   - Swap top two elements in current stack");
  379.     puts("du   - Make duplicate of current stack");
  380.     puts("help - Print this 'Help screen'");
  381.     puts("------------------------------");
  382.     puts("Help: Functions");
  383.     puts("x cos");
  384.     puts("x exp");
  385.     puts("x y pow");
  386.     puts("x sin");
  387.     puts("x sqrt");
  388.     puts("------------------------------");
  389.     NOPOP=1;
  390. }
Advertisement
Add Comment
Please, Sign In to add comment