Advertisement
konalisp

Forth.c

Apr 18th, 2014
97
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 5.42 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 operator or operand */
  7. #define MAXVAL 100 /* maximum depth of val stack */
  8. #define NUMBER '0' /* signal that a number was found */
  9. #define BUFSIZE 100
  10. #define COMMAND 'A' /* signal that a command was found */
  11.  
  12. int getop(char []);
  13. void push(double f);
  14. double pop(void);
  15. int getch(void);
  16. void ungetch(int);
  17.  
  18. int sp = 0;
  19. double val[MAXVAL];
  20. char buf[BUFSIZE]; /* buffer for ungetch */
  21. int bufp = 0; /* next free position in buf */
  22.  
  23. /* push: push f onto value stack */
  24. void push(double f)
  25. {
  26.     if (sp < MAXVAL)
  27.         val[sp++] = f;
  28.     else
  29.         printf("error: stack full, can't push %g\n", f);
  30. }
  31.  
  32. /* pop: pop and return top value from stack */
  33. double pop(void)
  34. {
  35.     if (sp > 0)
  36.         return val[--sp];
  37.     else {
  38.         printf("error: stack empty\n");
  39.         return 0.0;
  40.     }
  41. }
  42.  
  43. /* getop: get next character or numeric operand */
  44. int getop(char s[])
  45. {
  46.     int i, c;
  47.    
  48.     while ((s[0] = c = getch()) == ' ' || c == '\t')
  49.         ;
  50.     s[1] = '\0';
  51.     if (isalpha(c)) {
  52.         while (isalpha(s[++i] = c = getch()))
  53.             ;
  54.         s[i] = '\0';
  55.         printf("Entered string: %s\n", s);
  56.         return COMMAND;
  57.     }
  58.     if (!isdigit(c) && c != '.' && c != '-')
  59.         return c; /* not a number */
  60.     i = 0;
  61.     if (c == '-') { /* check to see if we have a neg number or a minus operator */
  62.         s[++i] = c = getch();
  63.         if (!isdigit(c)) /* if the next char is a number it's a neg num, else not */
  64.             return '-';
  65.     }
  66.     if (isdigit(c)) { /* collect integer part */
  67.         while (isdigit(s[++i] = c = getch()))
  68.             ;
  69.     }
  70.     if (c == '.') /* collect fraction part */
  71.         while (isdigit(s[++i] = c = getch()))
  72.             ;
  73.     s[i] = '\0';
  74.     if (c != EOF)
  75.         ungetch(c);
  76.     return NUMBER;
  77. }
  78.  
  79. int getch(void) /* get a (possibly pushed-back) character */
  80. {
  81.     return (bufp > 0) ? buf[--bufp] : getchar();
  82. }
  83.  
  84. void ungetch(int c) /* push character back on input */
  85. {
  86.     if (bufp >= BUFSIZE)
  87.         printf("ungetch: too many characters\n");
  88.     else
  89.         buf[bufp++] = c;
  90. }
  91.  
  92. /* reverse Polish calculator */
  93. main()
  94. {
  95.     int type, temp, i, sp_mark;
  96.     double op2;
  97.     char s[MAXOP];
  98.  
  99.     while ((type = getop(s)) != EOF) {
  100.             switch (type) {
  101.             case NUMBER:
  102.                 push(atof(s));
  103.                 break;
  104.             case COMMAND:
  105.                 printf("s is: %s\n", s);
  106.                 if (s == "sin") {
  107.                     printf("sin command received\n");
  108.                     push(sin(pop()));
  109.                     printf("\t%.8g\n", val[sp-1]);
  110.                 }
  111.                 break;
  112.             case '+':
  113.                 push(pop() + pop());
  114.                 printf("\t%.8g\n", val[sp-1]);
  115.                 break;
  116.             case '*':
  117.                 push(pop() * pop());
  118.                 printf("\t%.8g\n", val[sp-1]);
  119.                 break;
  120.             case '-':
  121.                 op2 = pop();
  122.                 push(pop() - op2);
  123.                 printf("\t%.8g\n", val[sp-1]);
  124.                 break;
  125.             case '/':
  126.                 op2 = pop();
  127.                 if (op2 != 0.0) {
  128.                     push(pop() / op2);
  129.                     printf("\t%.8g\n", val[sp-1]);
  130.                 }
  131.                 else
  132.                     printf("error: zero divisor\n");
  133.                 break;
  134.             case '%':
  135.                 op2 = pop();
  136.                 if (op2 != 0.0) {
  137.                     push(fmod(pop(), op2));
  138.                     printf("\t%.8g\n", val[sp-1]);
  139.                 }
  140.                 else
  141.                     printf("error: zero divisor\n");
  142.                 break;
  143.         /* ignore the rest of the cases, they're left over from previous exercise */
  144.             case 'c': /* clears the stack */
  145.                 sp = 0;
  146.                 printf("All values cleared\n");
  147.                 break;
  148.             case 's': /* shows the top values on the stack */
  149.                 if (sp > 1)
  150.                     printf("The top elements on the stack are %.8g and %.8g\n",
  151.                         val[sp-1], val[sp-2]);
  152.                 else if (sp == 1)
  153.                     printf("The only element on the stack is %.8g\n", val[sp-1]);
  154.                 else
  155.                     printf("The stack is empty\n");
  156.                 break;
  157.             case 'S': /* swaps the top two elements */
  158.                 if (sp > 1) {
  159.                 temp = val[sp-1];
  160.                 val[sp-1] = val[sp-2];
  161.                 val[sp-2] = temp;
  162.                 }
  163.                 else
  164.                     printf("Error: Not enough elements on stack\n");
  165.                 break;
  166.             case 'd': /* duplicates the stack */
  167.                 if (sp > 0 && sp * 2 < MAXVAL - 1) {
  168.                     for (i = 0, sp_mark = sp; i < sp_mark; i++)
  169.                         push(val[i]);
  170.                 }
  171.                 else if (sp == 0)
  172.                     printf("Error: Stack is empty");
  173.                 else
  174.                     printf("Error: Insufficient space on stack");
  175.                 break;
  176.             case '\n':
  177.                 /* printf("\t%.8g\n", pop()); */
  178.                 printf("\n");
  179.                 break;
  180.             default:
  181.                 printf("error: unknown command %s\n", s);
  182.                 break;
  183.             }
  184.     }
  185.     return 0;
  186. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement