4.3.c 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258
  1. #include <stdio.h>
  2. #include <stdlib.h> /* for atof() */
  3. #include <math.h> /* sin, exp, and pow */
  4. #include "defines.h"
  5. #include <errno.h>
  6. #include <fenv.h>
  7. int getop(char []);
  8. void push(double);
  9. double pop(void);
  10. void clear(void);
  11. /* reverse Polish calculator */
  12. int main()
  13. {
  14. size_t size;
  15. double variable[26]; /* variable stack */
  16. int type;
  17. double op2,outcome;
  18. char *s ;
  19. int dontprintme=0;
  20. feclearexcept(FE_ALL_EXCEPT);
  21. int i=0;
  22. int len=0;
  23. while (1)
  24. {
  25. i=0;
  26. // len=getline(s,&size,stdin);// != EOF ???? @bug
  27. len=getline(&s,&size,stdin);
  28. while ( (i<len+1) && (s!=0) )
  29. {
  30. // while count how long the next token is
  31. int k=0;
  32. while((s[i]==' ')||(s[i]=='\t'))
  33. {
  34. i++;
  35. }
  36. if (s[i]=='\0')
  37. break;
  38. if (s[i]!='\n')
  39. while((s[i]!=' ')&&(s[i]!='\t')&&(s[i]!='\n')&&(s[i]!='\0'))
  40. {
  41. k++;
  42. i++;
  43. }
  44. else //if \n
  45. {
  46. i++;
  47. k++;
  48. }
  49. i-=k; //we're going to recount these ones.
  50. // allocate new char[] for this token
  51. char temp[k+1];
  52. // copy it into this new char[]
  53. for (int j=0;j<k;j++)
  54. {
  55. temp[j]=s[i];
  56. i++;
  57. }
  58. temp[k]='\0'; //terminate de string
  59. // getop for this token
  60. type = getop(temp);
  61. //continue as usual
  62. double d0;
  63. double d1;
  64. int t0;
  65. int t1;
  66. switch (type) {
  67. case '\377':
  68. printf("** !eof detected! **");
  69. break;
  70. case STRNG:
  71. /** */
  72. printf(" ** error: not yet implemented ** \n");
  73. break;
  74. case GET:
  75. /** check if it's a valid variable */
  76. t0 = pop(); //name
  77. if ((t0>=0) && (t0<26))
  78. push(variable[t0]);
  79. else
  80. printf("\n ** error: variable %d not in range ** \n",t0);
  81. /** push the variable on to the top of the stack **/
  82. break;
  83. case SET:
  84. t0 = pop(); //name
  85. d0 = pop(); //value
  86. if ((t0>=0) && (t0<26))
  87. variable[t0]=d0;
  88. else
  89. printf("\n ** error: variable %d not in range ** \n",t0);
  90. dontprintme=1;
  91. break;
  92. /** the variables will be xa through xz */
  93. /** set has two arguments, one variable, one value */
  94. /** **/
  95. case POW:
  96. d0=pop();
  97. d1=pop();
  98. push(pow(d0,d1));
  99. break;
  100. case EXP:
  101. d0=pop();
  102. push(exp(d0));
  103. break;
  104. case PEEK:
  105. d0=pop();
  106. d1=pop();
  107. printf("\t%.8g\n",d0);
  108. printf("\t%.8g\n",d1);
  109. dontprintme=1;
  110. push(d1);
  111. push(d0);
  112. break;
  113. case SINE:
  114. op2=pop();
  115. push(sin(op2));
  116. // printf("sin(op2): \t%.8g\n",sin(op2));
  117. break;
  118. case SWAP:
  119. d0 = pop();
  120. d1 = pop();
  121. push(d0);
  122. push(d1);
  123. dontprintme=1;
  124. break;
  125. case CLEAR:
  126. clear();
  127. dontprintme=1;
  128. break;
  129. case DUPE:
  130. d0 = pop();
  131. push(d0);
  132. push(d0);
  133. break;
  134. case NUMBER:
  135. push(atof(temp));
  136. break;
  137. case '+':
  138. push(pop() + pop());
  139. break;
  140. case '*':
  141. push(pop() * pop());
  142. break;
  143. case '-':
  144. op2 = pop();
  145. push(pop() - op2);
  146. break;
  147. case '/':
  148. op2 = pop();
  149. if (op2 != 0.0)
  150. push(pop() / op2);
  151. else
  152. printf("error: zero divisor\n");
  153. break;
  154. case '%':
  155. t0 = pop();
  156. t1 = pop();
  157. if (t0 != 0)
  158. push(t0%t1);
  159. else
  160. {
  161. push(t0%t1);
  162. printf("this might not work, mod by 0?");
  163. }
  164. break;
  165. case '\n':
  166. if(dontprintme)
  167. {
  168. dontprintme=0;
  169. break;
  170. }
  171. int ferr=fetestexcept(FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW |
  172. FE_UNDERFLOW);
  173. if (ferr!=0)
  174. {
  175. printf("\n ** an error occurred in the math ** \n underflow/overflow?\n");
  176. feclearexcept(FE_ALL_EXCEPT);
  177. }
  178. //else
  179. // {
  180. outcome=pop();
  181. printf("\t%.8g\n", outcome);
  182. push(outcome);
  183. // }
  184. break;
  185. default:
  186. printf("error: unknown command %s\n", temp);
  187. break;
  188. }
  189. }
  190. }
  191. return 0;
  192. }
  193. #define MAXVAL 100 /* maximum depth of val stack */
  194. int sp = 0; /* next free stack position */
  195. double val[MAXVAL]; /* value stack */
  196. void clear(void)
  197. {
  198. sp=0;
  199. }
  200. /* push: push f onto value stack */
  201. void push(double f)
  202. {
  203. if (sp < MAXVAL)
  204. val[sp++] = f;
  205. else
  206. printf("error: stack full, can't push %g\n", f);
  207. }
  208. /* pop: pop and return top value from stack */
  209. double pop(void)
  210. {
  211. if (sp > 0)
  212. return val[--sp];
  213. else {
  214. printf("error: stack empty\n");
  215. return 0.0;
  216. }
  217. }