lolamontes69

K+R Exercise4_10

Sep 7th, 2014
125
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 9.38 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>  /* for atof() */
  3.  
  4. #define MAXVAL  100  /* maximum depth of val stack */
  5. #define MAXLINE 1000
  6. #define NUMBER 0
  7. #define LOWER 1
  8.  
  9. int getline(char s[], int lim);
  10. void push(double f);
  11. double pop(void);
  12.  
  13. void skipchars(char s[]);
  14. void coms(char s[]);
  15. void help(void);         /* command: help - print help screen */
  16. void clearstack(void);   /* command: cs - clear current stack */
  17. void cleardupl(void);    /* command: cd - clear duplicate stack */
  18. void stackprint(void);   /* command: ps - print current stack */
  19. void dsprint(void);      /* command: pd - print duplicate stack */
  20. void swaptop(void);      /* command: sw - swap top 2 in current stack */
  21. void duplstack(void);    /* command: du - create duplicate of current stack */
  22.  
  23. int isnegative(char s[]);/* decides if '-' is an operand or for a negative number */
  24.  
  25.  
  26.  
  27. char line[MAXLINE];
  28.  
  29. int sp = 0;              /* Next free stack position        */
  30. double val[MAXVAL];      /* value stack                     */
  31. int STRPOS=0;            /* current position in the string being parsed */
  32. double dupval[MAXVAL];   /* saved stack duplicate        */
  33. int dss = 0;             /* duplicate stack size for printing out dupval */
  34.  
  35. /* Print the input line */
  36. int main()
  37. {
  38.     int i, j;
  39.     double op2;
  40.     double op3;
  41.     double mod;
  42.     char type[MAXLINE];
  43.     char line[MAXLINE];
  44.  
  45.     j=1;
  46.     i = getline(line, MAXLINE);
  47.     while(STRPOS<i) {
  48.         type[0] = line[STRPOS];
  49.         if(isdigit(type[0])) type[0]=NUMBER;
  50.         else if(islower(type[0])) type[0]=LOWER;
  51.         switch(type[0]) {
  52.         case NUMBER:
  53.             op3 = 0;
  54.             while(isdigit(line[STRPOS])) {
  55.                 op3 = (op3*10)+(line[STRPOS++]-'0');
  56.             }
  57.             push(op3);             // Add number to stack
  58.             break;
  59.         case LOWER:
  60.             coms(line);
  61.             break;
  62.         case ' ':
  63.             break;
  64.         case '\t':
  65.             break;
  66.         case '+':
  67.             push(pop() + pop());   // pop last number from stack and add to previous
  68.             break;                 // number from stack then add to stack as last item
  69.         case '*':
  70.             push(pop() * pop());   // as above with *
  71.             break;
  72.         case '-':                  // pop last number from stack save as op2
  73.             j = isnegative(line);
  74.             if(j==1){
  75.                 op2 = pop();           // pop previous number from stack
  76.                 push(pop() - op2);     // otherwise would produce op2 - pop()
  77.             }
  78.             break;                 // and push to stack replacing them
  79.         case '/':
  80.             op2 = pop();           // as for '-' but with an errorcheck for
  81.             if(op2!=0.0)           // division by zero
  82.                 push(pop()/op2);
  83.             else
  84.                 printf("error: zero divisor\n");
  85.             break;
  86.         case '\%':
  87.             op2 = pop();            // as for '-' but with an errorcheck for
  88.             mod = pop();            // % cannot be applied to float or double
  89.             if(op2!=0.0) {          // so do the math here instead.
  90.                 if(mod>0 && op2>0) {
  91.                     while(mod-op2>=0)
  92.                         mod = mod - op2;
  93.                 }
  94.                 else if(mod<0 && op2>0) {
  95.                     mod = mod-mod-mod;
  96.                     while(mod-op2>=0)
  97.                         mod = mod - op2;
  98.                 }
  99.                 else if(mod<0 && op2<0) {
  100.                     mod = mod-mod-mod;
  101.                     op2 = op2-op2-op2;
  102.                     while(mod-op2>=0)
  103.                         mod = mod - op2;
  104.                     mod = mod-mod-mod;
  105.                 }
  106.                 else if(mod>0 && op2<0) {
  107.                     op2 = op2-op2-op2;
  108.                     while(mod-op2>=0)
  109.                         mod = mod - op2;  
  110.                     mod = mod-mod-mod;
  111.                 }
  112.                 push(mod);
  113.             }
  114.             else
  115.                 printf("error: zero divisor\n");
  116.             break;
  117.         case '\n':                      // if end of equation pop last item from stack
  118.             printf("\t%.8g\n", pop());  // aka the answer
  119.             break;
  120.         default:
  121.             printf("error: unknown command %c\n", line[STRPOS]);  
  122.             break;
  123.         }
  124.         STRPOS+=1;
  125.     }
  126.     return(0);
  127. }
  128.  
  129. /* getline: read a line into s, return length */
  130. int getline(char s[], int lim)
  131. {
  132.     int c, i;
  133.  
  134.     for(i=0; i<lim-1 && (c=getchar())!=EOF && c!='\n'; ++i)
  135.         s[i]=c;
  136.     if(c=='\n') {
  137.         s[i]=c;
  138.         ++i;
  139.     }
  140.     s[i]='\0';
  141.     return i;
  142. }
  143.  
  144. /* push: push f onto value stack */
  145. void push(double f)
  146. {
  147.     if(sp < MAXVAL)
  148.         val[sp++] = f;     // Add item as stack[sp] then increment sp
  149.     else
  150.         printf("error: stack full, cant push %g\n", f);
  151. }
  152.  
  153. /* pop: pop and return top value from stack */
  154. double pop(void)
  155. {
  156.     if(sp > 0)
  157.         return val[--sp];   // return last item in stack first decrementing sp
  158.     else {
  159.         printf("error: stack empty\n");
  160.         return 0.0;
  161.     }
  162. }
  163.  
  164. /* skipchars: skip lowercase non keywords */
  165. void skipchars(char s[])
  166. {
  167.     while(islower(s[++STRPOS]))
  168.         ;
  169.     --STRPOS;
  170.     //printf("skipchars: exits on %c\n",s[STRPOS]);
  171. }
  172.  
  173. /* coms: filter commands from the string */
  174. void coms(char s[])
  175. {
  176.     if(s[STRPOS++]=='h') {
  177.         if(s[STRPOS]=='e') {
  178.             if(s[++STRPOS]=='l') {
  179.                 if(s[++STRPOS]=='p') help();
  180.                 else {
  181.                     STRPOS++;
  182.                     skipchars(s);
  183.                 }
  184.             }
  185.             else {
  186.                 STRPOS++;
  187.                 skipchars(s);
  188.             }
  189.         }
  190.         else {
  191.             STRPOS++;
  192.             skipchars(s);
  193.         }
  194.     }
  195.     else if(s[--STRPOS]=='c') {
  196.         if(s[++STRPOS]=='s') clearstack();
  197.         else if(s[STRPOS]=='d') cleardupl();
  198.         else {
  199.             STRPOS++;
  200.             skipchars(s);
  201.         }
  202.     }
  203.     else if(s[STRPOS]=='d') {
  204.         if(s[++STRPOS]=='u') duplstack();
  205.         else {
  206.             STRPOS++;
  207.             skipchars(s);
  208.         }
  209.     }
  210.     else if(s[STRPOS]=='p')  {
  211.         if(s[++STRPOS]=='s') stackprint();
  212.         else if(s[STRPOS]=='d') dsprint();
  213.         else {
  214.             STRPOS++;
  215.             skipchars(s);
  216.         }
  217.     }
  218.     else if(s[STRPOS]=='s')  {
  219.         if(s[++STRPOS]=='w') swaptop();
  220.         else {
  221.             STRPOS++;
  222.             skipchars(s);
  223.         }
  224.     }
  225.     else {
  226.         STRPOS++;
  227.         //printf("char b4 is %c\n",s[STRPOS]);
  228.         skipchars(s);
  229.         //printf("char after is %c\n",s[STRPOS]);
  230.     }
  231. }
  232.  
  233. /* help: Print out help on available commands */
  234. void help(void)
  235. {
  236.     puts("------------------------------");
  237.     puts("Help: Commands (you wish, lol.)");
  238.     puts("cs   - Clear current stack");
  239.     puts("cd   - Clear duplicate stack");
  240.     puts("ps   - Print current stack");
  241.     puts("pd   - Print duplicate stack");
  242.     puts("sw   - Swap top two elements in current stack");
  243.     puts("du   - Make duplicate of current stack");
  244.     puts("help - Print this 'Help screen'");
  245.     puts("------------------------------");
  246.     puts("Help: Functions");
  247.     puts("pi - add the value of pi to the input line");
  248.     puts("x cos");
  249.     puts("x exp");
  250.     puts("x y pow");
  251.     puts("x sin");
  252.     puts("x sqrt");
  253.     puts("------------------------------");
  254. }
  255.  
  256. /* clearstack: Clear current stack  */
  257. void clearstack(void)
  258. {
  259.     sp=0;
  260.     puts("Stack cleared");
  261. }
  262.  
  263. /* cleardupl: Clear duplicate stack */
  264. void cleardupl(void)
  265. {
  266.     dss=0;
  267.     puts("Duplicate stack cleared");
  268. }
  269.  
  270. /* stackprint: print out current stack */
  271. void stackprint(void)
  272. {
  273.     int spp = sp;
  274.  
  275.     if(spp<=0) printf("error: stack empty\n");
  276.     else {
  277.         printf("--Top of current stack--\n");
  278.         while(spp>sp-2)                    // Note > 0 to print full stack
  279.             printf("%9g\n", val[--spp]);   // print last item in stack
  280.         printf("-------------\n");
  281.     }
  282. }
  283.  
  284. /* dsprint: print out the duplicate stack top down */
  285. void dsprint(void)
  286. {
  287.     int spp = dss;
  288.  
  289.     if(spp<=0) printf("error: duplicate stack empty\n");
  290.     else {
  291.         printf("--duplicate stack--\n");
  292.         while(spp>0)                    // Note > 0 to print full stack
  293.             printf("%9g\n", dupval[--spp]);   // print last item in stack
  294.         printf("--end of duplicate stack --\n");
  295.     }
  296. }
  297.  
  298. /* swaptop: Swap top two elements of stack */
  299. void swaptop(void)
  300. {
  301.     double temp;
  302.  
  303.     if(sp<=0) printf("error: stack empty\n");
  304.     else if(sp==1) printf("error: \n");
  305.     else {
  306.         temp = val[sp-1];
  307.         val[sp-1]=val[sp-2];
  308.         val[sp-2]=temp;
  309.         puts("Top two elements of stack swapped");
  310.     }
  311. }
  312.  
  313. /* duplstack: make duplicate of the current stack */
  314. void duplstack(void)
  315. {
  316.     dss=0;
  317.  
  318.     if(sp<=0) printf("error: can't duplicate, stack is empty\n");
  319.     else {
  320.         while(dss<sp) {
  321.             dupval[dss] = val[dss];  
  322.             dss++;
  323.         }
  324.     puts("Duplicate stack created");
  325.     }
  326. }
  327.  
  328. int isnegative(char s[])
  329. {
  330.     double op3 = 0;
  331.    
  332.     if(isdigit(s[++STRPOS])) {
  333.         while(isdigit(s[STRPOS])) {
  334.             op3 = (op3*10)+(s[STRPOS++]-'0');
  335.         }
  336.         op3 = op3-op3-op3;
  337.         push(op3);
  338.         return 0;
  339.     }
  340.     else {
  341.         --STRPOS;
  342.         return 1;
  343.     }
  344. }
Advertisement
Add Comment
Please, Sign In to add comment