some fixes on program functions
[calc.git] / parser.c
index 09a6935763bbc92952ca5cd8715dccf20f2601b7..4b4fab7678dd65352e28a2922fe2e94a56ba4810 100644 (file)
--- a/parser.c
+++ b/parser.c
@@ -784,23 +784,24 @@ void prog (int id, int nbmems, element_t *root)
         exit (1);
     }
     (programs + n)->storage_size = nbmems;
-    (programs + n)->root = root;
+    (programs + n)->root = dupelement (root);
 }
 
-double call (int id, int nbobs, element_t **ops)
+double call (int id, int nbops, element_t **ops)
 {
     workspace_t tmp = {0};
     int i, n = -1;
     double ret = 0;
 
     if (programs) {
+
+        /* look for program */
         for (i = 0; i < nb_programs; i++) {
-            if ((programs + i)->id == i) {
+            if ((programs + i)->id == id) {
                 n = i;
                 break;
             }
         }
-
         if (n == -1) {
             VERBOSE (WARNING, fprintf (stdout, "error unknown program (%d)\n", id));
             return 0;
@@ -813,19 +814,20 @@ double call (int id, int nbobs, element_t **ops)
 
         /* change context */
         answer = 0;
-        storage = (programs + i)->storage;
-        storage_size = (programs + i)->storage_size;
-        if (nbobs > storage_size) {
-            storage = realloc (storage, nbobs * sizeof (double));
-            storage_size = nbobs;
+        storage = (programs + n)->storage;
+        storage_size = (programs + n)->storage_size;
+        if (nbops > storage_size) {
+            storage = realloc (storage, nbops * sizeof (double));
+            storage_size = nbops;
         }
-        for (i = 0; i < nbobs; i++) {
-            store (i + 1, evaluate_element (ops[i], 0));
+        for (i = 0; i < nbops; i++) {
+            double val = evaluate_element (ops[i], 0);
+            store (i + 1, val);
         }
 
         /* evaluate program */
-        element_t *element = dupelement ((programs + n)->root);
-        ret = evaluate_element (element, 0);
+        element_t *elements = dupelement ((programs + n)->root);
+        ret = evaluate_element (elements, 0);
 
         /* restore context */
         answer = tmp.answer;
@@ -890,6 +892,7 @@ double evaluate_element (element_t *root, char mask)
 {
     double op0 = 0, op1 = 0;
     char nextmask = mask;
+    int i, nb;
 
     if ((root == NULL) || (root == ERROR_OP)) {
         VERBOSE (WARNING, fprintf (stdout, "error while evaluating\n"));
@@ -963,7 +966,6 @@ double evaluate_element (element_t *root, char mask)
     case Mem:
     case Cond:
     case Call:
-    case List:
     case Edit:
     case Del:
         if (root->ops[0]) {
@@ -981,6 +983,7 @@ double evaluate_element (element_t *root, char mask)
     case Pi:
     case E:
     case Code:
+    case List:
         break;
     case While:
         if (root->ops[0] == NULL) {
@@ -1047,7 +1050,13 @@ double evaluate_element (element_t *root, char mask)
     case Code: return execute_code (root->ops, root->nbops);
     case Print: return print (op0);
     case Prog: prog ((int)op0, (int)op1, root->ops[2]); break;
-    case Call: return call ((int)op0, root->nbops + 1, root->ops + 1);
+    case Call:
+        for (i = 1, nb =0; i < root->nbops; i++) {
+            if (root->ops[i]) {
+                nb++;
+            }
+        }
+        return call ((int)op0, nb, root->ops + 1);
     case List: list (); break;
     case Edit: edit ((int)op0); break;
     case Del: del ((int)op0); break;