correct a test
[calc.git] / stack.c
diff --git a/stack.c b/stack.c
index 5c203edfdd54a0a940be9a0432bf49b14d589d6d..f4117f5ce0fd397432933cc8062c219f6e15bbf0 100644 (file)
--- a/stack.c
+++ b/stack.c
-#include <malloc.h>
+#include <math.h>
 #include <stdio.h>
-#include <string.h>
 
-#include "alloc.h"
 #include "debug.h"
 #include "format.h"
 #include "parser.h"
+#include "tabular.h"
 
 #include "stack.h"
 
 /* global variables */
 
-int stack_size = 0;
-double *stack = NULL;
+tab_t * stack = NULL;
 
 /* stack management */
 
 double get (int n)
 {
-    double ret = 0;
-    if ((n <= 0) || (n > stack_size)) {
-        VERBOSE (WARNING, fprintf (stdout, "error out of bound (%d/%d)\n", n, stack_size));
-    } else {
-        ret = stack[n - 1];
-    }
-    return ret;
+    return get_tab (stack, n);
 }
 
 double length ()
 {
-    return stack_size;
+    return size_tab (stack);
 }
 
 double pop ()
 {
-    double ret = 0;
-    if (stack_size > 0) {
-        ret = stack[--stack_size];
-        double *tmp = (double *) callocordie (stack_size, sizeof (double));
-        memcpy (tmp, stack, stack_size * sizeof (double));
-        free (stack);
-        stack = tmp;
-    } else {
-        VERBOSE (WARNING, fprintf (stdout, "error stack empty\n"));
-    }
-    return ret;
+    return pop_tab (stack, -1);
 }
 
 double push (double val)
 {
-    double *tmp = (double *) callocordie (stack_size + 1, sizeof (double));
-    memcpy (tmp, stack, stack_size * sizeof (double));
+    double ret = NAN;
     if (stack) {
-        free (stack);
+        ret = push_tab (stack, -1, val);
+    } else {
+        stack = resize_tab (stack, 1);
+        ret = set_tab (stack, 1, val);
     }
-    stack = tmp;
-    stack[stack_size++] = val;
-    return val;
+    return ret;
 }
 
 double put (int n, double val)
 {
-    if (n <= 0) {
-        VERBOSE (WARNING, fprintf (stdout, "error out of bound (%d/%d)\n", n, stack_size));
-        return 0;
-    }
-    if (n > stack_size) {
-        double *tmp = (double *) callocordie (n, sizeof (double));
-        memcpy (tmp, stack, stack_size * sizeof (double));
-        free (stack);
-        stack = tmp;
-        stack_size = n;
+    if (n > size_tab (stack)) {
+        stack = resize_tab (stack, n);
     }
-    stack[n - 1] = val;
-    return val;
+    return set_tab (stack, n, val);
 }
 
 double set (int nbops, element_t **ops)
 {
     int i;
-    if (stack) {
-        free (stack);
-    }
-    stack = NULL;
-    stack_size = 0;
-    if (nbops != 0) {
-         stack = (double *) callocordie (nbops, sizeof (double));
-         for (i = 0; i < nbops; i++) {
-             stack[i] = evaluate_element (ops[i], 0);
-         }
-         stack_size = nbops;
-    }
-    return stack_size;
+    stack = resize_tab (stack, nbops);
+    for (i = 0; i < nbops; i++) {
+        set_tab (stack, i + 1, evaluate_element (ops[i], 0));
+    }
+    return size_tab (stack);
 }
 
 void show (void)
 {
-    int i;
-    fprintf (stdout, "stack:");
-    for (i = 0; i < stack_size; i++) {
-        fprintf (stdout, " ");
-        fprintf (stdout, minform, stack[i]);
+    int i, n = size_tab (stack);
+    printf ("stack:");
+    for (i = 0; i < n; i++) {
+        printf (" ");
+        printl (get_tab (stack, i + 1));
     }
-    fprintf (stdout, "\n");
+    printf ("\n");
 }
 
 /* stack functions */
@@ -110,15 +75,16 @@ void show (void)
 double max ()
 {
     double ret = 0;
-    int i;
-    if (stack_size < 1) {
-        VERBOSE (WARNING, fprintf (stdout, "error not enough element in stack (%d)\n", stack_size));
+    int i, n = size_tab (stack);
+    if (n < 1) {
+        VERBOSE (WARNING, fprintf (stdout, "error not enough element in stack (%d)\n", n));
         return 0;
     }
-    ret = stack[0];
-    for (i = 1; i < stack_size; i++) {
-        if (stack[i] > ret) {
-            ret = stack[i];
+    ret = get_tab (stack, 1);
+    for (i = 1; i < n; i++) {
+        double cur = get_tab (stack, i + 1);
+        if (cur > ret) {
+            ret = cur;
         }
     }
     return ret;
@@ -127,29 +93,30 @@ double max ()
 double mean ()
 {
     double ret = 0;
-    int i;
-    if (stack_size < 1) {
-        VERBOSE (WARNING, fprintf (stdout, "error not enough element in stack (%d)\n", stack_size));
+    int i, n = size_tab (stack);
+    if (n < 1) {
+        VERBOSE (WARNING, fprintf (stdout, "error not enough element in stack (%d)\n", n));
         return 0;
     }
-    for (i = 0; i < stack_size; i++) {
-        ret += stack[i];
+    for (i = 0; i < n; i++) {
+        ret += get_tab (stack, i + 1);
     }
-    return ret / stack_size;
+    return ret / n;
 }
 
 double min ()
 {
     double ret = 0;
-    int i;
-    if (stack_size < 1) {
-        VERBOSE (WARNING, fprintf (stdout, "error not enough element in stack (%d)\n", stack_size));
+    int i, n = size_tab (stack);
+    if (n < 1) {
+        VERBOSE (WARNING, fprintf (stdout, "error not enough element in stack (%d)\n", n));
         return 0;
     }
-    ret = stack[0];
-    for (i = 1; i < stack_size; i++) {
-        if (stack[i] < ret) {
-            ret = stack[i];
+    ret = get_tab (stack, 1);
+    for (i = 1; i < n; i++) {
+        double cur = get_tab (stack, i + 1);
+        if (cur < ret) {
+            ret = cur;
         }
     }
     return ret;
@@ -157,53 +124,34 @@ double min ()
 
 void order ()
 {
-    int i, j;
-    if (stack_size < 1) {
-        VERBOSE (WARNING, fprintf (stdout, "error not enough element in stack (%d)\n", stack_size));
-        return;
-    }
-    for (i = 0; i < stack_size - 1; i++) {
-        int done = 0;
-        for (j = 0; j < stack_size - 1; j++) {
-            if (stack[j] > stack[j + 1]) {
-                double tmp = stack[j];
-                stack[j] = stack[j + 1];
-                stack[j + 1] = tmp;
-                done = 1;
-            }
-        }
-        if (done == 0) {
-            break;
-        }
-    }
+    order_tab (stack);
 }
 
 double median ()
 {
     double ret = 0;
-    if (stack_size < 3) {
-        VERBOSE (WARNING, fprintf (stdout, "error not enough element in stack (%d)\n", stack_size));
-        return 0;
+    int n = size_tab (stack);
+    if (n < 3) {
+        VERBOSE (WARNING, fprintf (stdout, "error not enough element in stack (%d)\n", n));
+    } else {
+        tab_t *tmp = copy_tab (stack);
+        order_tab (tmp);
+        ret = get_tab (tmp, (n - 1) / 2 + 1);
+        free_tab (tmp);
     }
-    double *tmp = (double *) callocordie (stack_size, sizeof (double));
-    memcpy (tmp, stack, stack_size * sizeof (double));
-    order ();
-    ret = stack[(stack_size - 1)/ 2];
-    memcpy (stack, tmp, stack_size * sizeof (double));
-    free (tmp);
     return ret;
 }
 
 double prod ()
 {
     double ret = 1;
-    int i;
-    if (stack_size < 1) {
-        VERBOSE (WARNING, fprintf (stdout, "error not enough element in stack (%d)\n", stack_size));
+    int i, n = size_tab (stack);
+    if (n < 1) {
+        VERBOSE (WARNING, fprintf (stdout, "error not enough element in stack (%d)\n", n));
         return 0;
     }
-    for (i = 0; i < stack_size; i++) {
-        ret *= stack[i];
+    for (i = 0; i < n; i++) {
+        ret *= get_tab (stack, i + 1);
     }
     return ret;
 }
@@ -211,13 +159,13 @@ double prod ()
 double sum ()
 {
     double ret = 0;
-    int i;
-    if (stack_size < 1) {
-        VERBOSE (WARNING, fprintf (stdout, "error not enough element in stack (%d)\n", stack_size));
+    int i, n = size_tab (stack);
+    if (n < 1) {
+        VERBOSE (WARNING, fprintf (stdout, "error not enough element in stack (%d)\n", n));
         return 0;
     }
-    for (i = 0; i < stack_size; i++) {
-        ret += stack[i];
+    for (i = 0; i < n; i++) {
+        ret += get_tab (stack, i + 1);
     }
     return ret;
 }
@@ -225,17 +173,17 @@ double sum ()
 double variance ()
 {
     double ret = 0;
-    double m = 0;
-    int i;
-    if (stack_size < 2) {
-        VERBOSE (WARNING, fprintf (stdout, "error not enough element in stack (%d)\n", stack_size));
+    int i, n = size_tab (stack);
+    if (n < 2) {
+        VERBOSE (WARNING, fprintf (stdout, "error not enough element in stack (%d)\n", n));
         return 0;
     }
-    m = mean ();
-    for (i = 0; i < stack_size; i++) {
-        ret += (stack[i] - m) * (stack[i] - m);
+    double m = mean ();
+    for (i = 0; i < n; i++) {
+        double x = get_tab (stack, i + 1);
+        ret += (x - m) * (x - m);
     }
-    return ret / stack_size;
+    return ret / n;
 }
 
 /* vim: set ts=4 sw=4 et: */