|
- #define NS_DEFAULT (2 << 11) /* 4096 */
- #define MAX_PREC 4
- #define PRINT_FORMAT "%.Ff"
- #define PRINTLINE_FORMAT PRINT_FORMAT "\n"
-
- #define PERROR_RETURN(str,ret) do { perror(str); return ret; } while (1)
-
- #define NS_EXPAND(s) \
- do \
- { \
- if (s->top + 2 >= (ssize_t) s->max) \
- { \
- if (ns_expand(s, s->max << 2)) \
- { return 1; } \
- if (!s->num) \
- { return 1; } \
- } \
- ++s->top; \
- } while (0)
-
- #define NS_DEINT(s)\
-
- #define NS_PEEK(s) s->num[s->top]
- #define NS_PEEKN(s,n) s->num[s->top + n]
-
- typedef struct
- {
- ssize_t max;
- ssize_t top; /* top < NS_MAX */
- mpf_t * num;
- } ns_t; /* number stack */
-
- static ns_t *
- ns_init(ssize_t max)
- {
- ssize_t i;
- ns_t * s = (ns_t *) malloc(sizeof(ns_t));
- if (!s)
- { PERROR_RETURN(PROGN, NULL); }
- s->num = malloc(max * sizeof(mpf_t));
- if (!s->num)
- { PERROR_RETURN(PROGN, NULL); }
- s->max = max;
- s->top = -1;
- for (i = 0; i < s->max; ++i)
- { mpf_init(s->num[i]); }
- return s;
- }
-
- static void
- ns_free(ns_t * s)
- {
- ssize_t i;
- /* fprintf(stderr, "Freeing %ld blocks\n", s->max); */
- for (i = 0; i < s->max; ++i)
- { mpf_clear(s->num[i]); }
- free(s->num);
- free(s);
- }
-
- int
- ns_expand(ns_t * s, ssize_t newmax)
- {
- /* fprintf(stderr, "Expanding to %ld blocks\n", newmax); */
- assert(newmax > s->max);
- s->num = realloc(s->num, (size_t) newmax * sizeof(mpf_t));
- if (!s->num)
- { PERROR_RETURN(PROGN, 1); }
- else
- {
- ssize_t i;
- for (i = s->max; i < newmax; ++i)
- { mpf_init(s->num[i]); }
- s->max = newmax;
- return 0;
- }
- }
-
- static int
- ns_push(ns_t * s, mpf_t val)
- {
- NS_EXPAND(s);
- mpf_set(NS_PEEK(s), val);
- return 0;
- }
-
- static mpf_t *
- ns_pop(ns_t * s)
- {
- if (s->top > -1)
- { return &s->num[s->top--]; }
- else
- {
- fprintf(stderr, PROGN ": underflow\n");
- return NULL;
- }
- }
-
- static void
- ns_printline_all(ns_t * s)
- {
- ssize_t i;
- #ifdef FOR_HUMANS
- for (i = 0; i <= s->top; ++i)
- #else
- for (i = s->top; i >= 0; --i)
- #endif /* FOR_HUMANS */
- { gmp_printf(PRINTLINE_FORMAT, s->num[i]); }
- }
-
- static inline void
- ns_printline_peek(ns_t * s)
- {
- if (s->top > -1)
- { gmp_printf(PRINTLINE_FORMAT, NS_PEEK(s)); }
- }
-
- static inline int
- ns_print_peek(ns_t * s)
- {
- if (s->top > -1)
- {
- gmp_printf(PRINT_FORMAT, NS_PEEK(s));
- return 0;
- }
- else
- { return 1; }
- }
-
- static inline void
- ns_clear(ns_t * s)
- { s->top = -1; }
-
- static inline int
- ns_reverse(ns_t * s)
- { if (s->top > 0)
- {
- mpf_swap(NS_PEEK(s), s->num[s->top-1]);
- return 0;
- }
- else
- { return 1; }
- }
-
- static inline int
- ns_dup(ns_t * s)
- { return ns_push(s, NS_PEEK(s)); }
-
- /* FIXME REMOVE TEST FUNCTION !!! */
- static inline int
- ns_ndup(ns_t * s)
- {
- int ret = 0;
- mpf_t dupn;
- if (ns_pop(s) == NULL)
- { return 1; }
- for (mpf_set(dupn, NS_PEEKN(s,1));
- !ret &&
- mpf_cmp_ui(dupn,1);
- mpf_sub_ui(dupn,dupn,1))
- { ret += ns_dup(s); }
- return ret;
- }
-
- #include "arith.c"
|