It's a stack calculator for the unwise. Public Domain.
25'ten fazla konu seçemezsiniz Konular bir harf veya rakamla başlamalı, kısa çizgiler ('-') içerebilir ve en fazla 35 karakter uzunluğunda olabilir.
Bu depo arşivlendi. Dosyaları görüntüleyebilir ve klonlayabilirsiniz ama işlem gönderemez ve konu/değişiklik isteği açamazsınız.

166 satır
3.2KB

  1. #define NS_DEFAULT (2 << 11) /* 4096 */
  2. #define MAX_PREC 4
  3. #define PRINT_FORMAT "%.Ff"
  4. #define PRINTLINE_FORMAT PRINT_FORMAT "\n"
  5. #define PERROR_RETURN(str,ret) do { perror(str); return ret; } while (1)
  6. #define NS_EXPAND(s) \
  7. do \
  8. { \
  9. if (s->top + 2 >= (ssize_t) s->max) \
  10. { \
  11. if (ns_expand(s, s->max << 2)) \
  12. { return 1; } \
  13. if (!s->num) \
  14. { return 1; } \
  15. } \
  16. ++s->top; \
  17. } while (0)
  18. #define NS_DEINT(s)\
  19. #define NS_PEEK(s) s->num[s->top]
  20. #define NS_PEEKN(s,n) s->num[s->top + n]
  21. typedef struct
  22. {
  23. ssize_t max;
  24. ssize_t top; /* top < NS_MAX */
  25. mpf_t * num;
  26. } ns_t; /* number stack */
  27. static ns_t *
  28. ns_init(ssize_t max)
  29. {
  30. ssize_t i;
  31. ns_t * s = (ns_t *) malloc(sizeof(ns_t));
  32. if (!s)
  33. { PERROR_RETURN(PROGN, NULL); }
  34. s->num = malloc(max * sizeof(mpf_t));
  35. if (!s->num)
  36. { PERROR_RETURN(PROGN, NULL); }
  37. s->max = max;
  38. s->top = -1;
  39. for (i = 0; i < s->max; ++i)
  40. { mpf_init(s->num[i]); }
  41. return s;
  42. }
  43. static void
  44. ns_free(ns_t * s)
  45. {
  46. ssize_t i;
  47. /* fprintf(stderr, "Freeing %ld blocks\n", s->max); */
  48. for (i = 0; i < s->max; ++i)
  49. { mpf_clear(s->num[i]); }
  50. free(s->num);
  51. free(s);
  52. }
  53. int
  54. ns_expand(ns_t * s, ssize_t newmax)
  55. {
  56. /* fprintf(stderr, "Expanding to %ld blocks\n", newmax); */
  57. assert(newmax > s->max);
  58. s->num = realloc(s->num, (size_t) newmax * sizeof(mpf_t));
  59. if (!s->num)
  60. { PERROR_RETURN(PROGN, 1); }
  61. else
  62. {
  63. ssize_t i;
  64. for (i = s->max; i < newmax; ++i)
  65. { mpf_init(s->num[i]); }
  66. s->max = newmax;
  67. return 0;
  68. }
  69. }
  70. static int
  71. ns_push(ns_t * s, mpf_t val)
  72. {
  73. NS_EXPAND(s);
  74. mpf_set(NS_PEEK(s), val);
  75. return 0;
  76. }
  77. static mpf_t *
  78. ns_pop(ns_t * s)
  79. {
  80. if (s->top > -1)
  81. { return &s->num[s->top--]; }
  82. else
  83. {
  84. fprintf(stderr, PROGN ": underflow\n");
  85. return NULL;
  86. }
  87. }
  88. static void
  89. ns_printline_all(ns_t * s)
  90. {
  91. ssize_t i;
  92. #ifdef FOR_HUMANS
  93. for (i = 0; i <= s->top; ++i)
  94. #else
  95. for (i = s->top; i >= 0; --i)
  96. #endif /* FOR_HUMANS */
  97. { gmp_printf(PRINTLINE_FORMAT, s->num[i]); }
  98. }
  99. static inline void
  100. ns_printline_peek(ns_t * s)
  101. {
  102. if (s->top > -1)
  103. { gmp_printf(PRINTLINE_FORMAT, NS_PEEK(s)); }
  104. }
  105. static inline int
  106. ns_print_peek(ns_t * s)
  107. {
  108. if (s->top > -1)
  109. {
  110. gmp_printf(PRINT_FORMAT, NS_PEEK(s));
  111. return 0;
  112. }
  113. else
  114. { return 1; }
  115. }
  116. static inline void
  117. ns_clear(ns_t * s)
  118. { s->top = -1; }
  119. static inline int
  120. ns_reverse(ns_t * s)
  121. { if (s->top > 0)
  122. {
  123. mpf_swap(NS_PEEK(s), s->num[s->top-1]);
  124. return 0;
  125. }
  126. else
  127. { return 1; }
  128. }
  129. static inline int
  130. ns_dup(ns_t * s)
  131. { return ns_push(s, NS_PEEK(s)); }
  132. /* FIXME REMOVE TEST FUNCTION !!! */
  133. static inline int
  134. ns_ndup(ns_t * s)
  135. {
  136. int ret = 0;
  137. mpf_t dupn;
  138. if (ns_pop(s) == NULL)
  139. { return 1; }
  140. for (mpf_set(dupn, NS_PEEKN(s,1));
  141. !ret &&
  142. mpf_cmp_ui(dupn,1);
  143. mpf_sub_ui(dupn,dupn,1))
  144. { ret += ns_dup(s); }
  145. return ret;
  146. }
  147. #include "arith.c"