lolamontes69

K+R Exercise4_6

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