It's a stack calculator for the unwise. Public Domain.
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.
Ce dépôt est archivé. Vous pouvez voir les fichiers et le cloner, mais vous ne pouvez pas pousser ni ouvrir de ticket/demande d'ajout.

166 lignes
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"