mpcalc.c
资源名称:c.rar [点击查看]
上传用户:shmaik
上传日期:2014-06-01
资源大小:45093k
文件大小:5k
源码类别:

VC书籍

开发平台:

C/C++

  1. static char rcsid[] = "$Id: H:/drh/idioms/book/RCS/mp.doc,v 1.11 1996/06/26 23:02:01 drh Exp $";
  2. #include <ctype.h>
  3. #include <stdio.h>
  4. #include <string.h>
  5. #include <stdlib.h>
  6. #include <limits.h>
  7. #include "mem.h"
  8. #include "seq.h"
  9. #include "fmt.h"
  10. #include "mp.h"
  11. Seq_T sp;
  12. int ibase = 10;
  13. int obase = 10;
  14. struct {
  15. char *fmt;
  16. MP_T (*add)(MP_T, MP_T, MP_T);
  17. MP_T (*sub)(MP_T, MP_T, MP_T);
  18. MP_T (*mul)(MP_T, MP_T, MP_T);
  19. MP_T (*div)(MP_T, MP_T, MP_T);
  20. MP_T (*mod)(MP_T, MP_T, MP_T);
  21. } s = { "%Dn",
  22. MP_add,  MP_sub,  MP_mul,  MP_div,  MP_mod  },
  23.   u = { "%Un",
  24. MP_addu, MP_subu, MP_mulu, MP_divu, MP_modu },
  25.  *f = &s;
  26. MP_T pop(void) {
  27. if (Seq_length(sp) > 0)
  28. return Seq_remhi(sp);
  29. else {
  30. Fmt_fprint(stderr, "?stack underflown");
  31. return MP_new(0);
  32. }
  33. }
  34. int main(int argc, char *argv[]) {
  35. int c;
  36. sp = Seq_new(0);
  37. Fmt_register('D', MP_fmt);
  38. Fmt_register('U', MP_fmtu);
  39. while ((c = getchar()) != EOF) {
  40. MP_T x = NULL, y = NULL, z = NULL;
  41. TRY
  42.   switch (c) {
  43. default:
  44. if (isprint(c))
  45. Fmt_fprint(stderr, "?'%c'", c);
  46. else
  47. Fmt_fprint(stderr, "?'\%03o'", c);
  48. Fmt_fprint(stderr, " is unimplementedn");
  49. break;
  50. case ' ': case 't': case 'n': case 'f': case 'r':
  51. break;
  52. case 'c': while (Seq_length(sp) > 0) {
  53.    MP_T x = Seq_remhi(sp);
  54.    FREE(x);
  55.   } break;
  56. case 'q': while (Seq_length(sp) > 0) {
  57.    MP_T x = Seq_remhi(sp);
  58.    FREE(x);
  59.   }
  60.   Seq_free(&sp);
  61.   return EXIT_SUCCESS;
  62. case '0': case '1': case '2': case '3': case '4':
  63. case '5': case '6': case '7': case '8': case '9': {
  64. char buf[512];
  65. z = MP_new(0);
  66. {
  67. int i = 0;
  68. for ( ;  strchr(&"zyxwvutsrqponmlkjihgfedcba9876543210"[36-ibase],
  69. tolower(c)); c = getchar(), i++)
  70. if (i < (int)sizeof (buf) - 1)
  71. buf[i] = c;
  72. if (i > (int)sizeof (buf) - 1) {
  73. i = (int)sizeof (buf) - 1;
  74. Fmt_fprint(stderr,
  75. "?integer constant exceeds %d digitsn", i);
  76. }
  77. buf[i] = '';
  78. if (c != EOF)
  79. ungetc(c, stdin);
  80. }
  81. MP_fromstr(z, buf, ibase, NULL);
  82. break;
  83. }
  84. case '+': y = pop(); x = pop();
  85.   z = MP_new(0); (*f->add)(z, x, y); break;
  86. case '-': y = pop(); x = pop();
  87.   z = MP_new(0); (*f->sub)(z, x, y); break;
  88. case '*': y = pop(); x = pop();
  89.   z = MP_new(0); (*f->mul)(z, x, y); break;
  90. case '/': y = pop(); x = pop();
  91.   z = MP_new(0); (*f->div)(z, x, y); break;
  92. case '%': y = pop(); x = pop();
  93.   z = MP_new(0); (*f->mod)(z, x, y); break;
  94. case '&': y = pop(); x = pop();
  95.   z = MP_new(0);    MP_and(z, x, y); break;
  96. case '|': y = pop(); x = pop();
  97.   z = MP_new(0);    MP_or (z, x, y); break;
  98. case '^': y = pop(); x = pop();
  99.   z = MP_new(0);    MP_xor(z, x, y); break;
  100. case '!': z = pop(); MP_not(z, z); break;
  101. case '~': z = pop(); MP_neg(z, z); break;
  102. case 'i': case 'o': {
  103. long n;
  104. x = pop();
  105. n = MP_toint(x);
  106. if (n < 2 || n > 36)
  107. Fmt_fprint(stderr, "?%d is an illegal basen",n);
  108. else if (c == 'i')
  109. ibase = n;
  110. else
  111. obase = n;
  112. if (obase == 2 || obase == 8 || obase == 16)
  113. f = &u;
  114. else
  115. f = &s;
  116. break;
  117. }
  118. case 'p':
  119. Fmt_print(f->fmt, z = pop(), obase);
  120. break;
  121. case 'f': {
  122. int n = Seq_length(sp);
  123. while (--n > 0)
  124. Fmt_print(f->fmt, Seq_get(sp, n), obase);
  125. break;
  126. }
  127. case '<': { long s;
  128.     y = pop();
  129.     z = pop();
  130.     s = MP_toint(y);
  131.     if (s < 0 || s > INT_MAX) {
  132.      Fmt_fprint(stderr,
  133.      "?%d is an illegal shift amountn", s);
  134.      break;
  135.     }; MP_lshift(z, z, s); break; }
  136. case '>': { long s;
  137.     y = pop();
  138.     z = pop();
  139.     s = MP_toint(y);
  140.     if (s < 0 || s > INT_MAX) {
  141.      Fmt_fprint(stderr,
  142.      "?%d is an illegal shift amountn", s);
  143.      break;
  144.     }; MP_rshift(z, z, s); break; }
  145. case 'k': {
  146. long n;
  147. x = pop();
  148. n = MP_toint(x);
  149. if (n < 2 || n > INT_MAX)
  150. Fmt_fprint(stderr,
  151. "?%d is an illegal precisionn", n);
  152. else if (Seq_length(sp) > 0)
  153. Fmt_fprint(stderr, "?nonempty stackn");
  154. else
  155. MP_set(n);
  156. break;
  157. }
  158. case 'd': {
  159. MP_T x = pop();
  160. z = MP_new(0);
  161. Seq_addhi(sp, x);
  162. MP_addui(z, x, 0);
  163. break;
  164. }
  165. }
  166. EXCEPT(MP_Overflow)
  167. Fmt_fprint(stderr, "?overflown");
  168. EXCEPT(MP_Dividebyzero)
  169. Fmt_fprint(stderr, "?divide by 0n");
  170. END_TRY;
  171. if (z)
  172. Seq_addhi(sp, z);
  173. FREE(x);
  174. FREE(y);
  175. }
  176. while (Seq_length(sp) > 0) {
  177. MP_T x = Seq_remhi(sp);
  178. FREE(x);
  179. }
  180. Seq_free(&sp);
  181. return EXIT_SUCCESS;
  182. }