partial recursivity
authorLaurent Mazet <mazet@softndesign.org>
Thu, 16 Feb 2023 08:59:23 +0000 (09:59 +0100)
committerLaurent Mazet <mazet@softndesign.org>
Thu, 16 Feb 2023 08:59:23 +0000 (09:59 +0100)
argument.c
argument.h
calc.c
program.c

index c8f345f40d4d1c83895492eef5fe00f574a8ca8a..2c6a93d6aff50d3eea10e2abefbc1946f66b5dd0 100644 (file)
@@ -20,7 +20,7 @@ double arg (int n)
 
 /* set arguments */
 
-double def (int nbops, element_t **ops)
+tab_t *def (int nbops, element_t **ops)
 {
     int i;
     tab_t *new = alloc_tab (nbops);
@@ -29,9 +29,7 @@ double def (int nbops, element_t **ops)
         VERBOSE (DEBUG, fprintf (stdout, "arg[%d] = %g\n", i + i, val));
         set_tab (new, i + 1, val);
     }
-    free_tab (argument);
-    argument = new;
-    return size_tab (argument);
+    return new;
 }
 
 /* vim: set ts=4 sw=4 et: */
index 01ae454393dbb35706db160abe37bdc3b38628c1..9bd83063f8df50e9a08bfd018454d214c2026d42 100644 (file)
@@ -11,7 +11,7 @@ extern tab_t *argument;
 /* argument management */
 
 double arg (int n);
-double def (int nbops, element_t **ops);
+tab_t *def (int nbops, element_t **ops);
 
 #endif /* __ARGUMENT_H__ */
 
diff --git a/calc.c b/calc.c
index 6bac59e91cd662c72add8f7b263e941a132da809..cad608fe528f52bfcded3425a3c4bc5f5a595da3 100644 (file)
--- a/calc.c
+++ b/calc.c
@@ -412,4 +412,7 @@ int main (int argc, char *argv[])
 // Gold number
 // test: echo -e '{sto (1, 1), sto (2, 1), sto (10, 1), while (inc (10) < 15 - 1, {sto (3, rcl (1) + rcl (2)), sto (1, rcl (2)), print (sto (2, rcl (3)) / rcl (1))})};' | calc.exe | grep -q '=> 1.61803'
 
+// Factorial sequence
+// test: echo -e 'prog (1, cond (arg (1) > 1, arg (1) * call (1, arg (1) - 1), 1))\ncall (1, 10)' | ./calc.exe | grep -q '=> 3628800'
+
 /* vim: set ts=4 sw=4 et: */
index a6801f8a48574ed34a003ed5451e1ef8e6a35ea7..7db9d40291b3433a503b32f07c0b605f2ff7497e 100644 (file)
--- a/program.c
+++ b/program.c
@@ -81,20 +81,17 @@ double call (int id, int nbargs, element_t **args)
         VERBOSE (WARNING, fprintf (stdout, "error unknown program (%d)\n", id));
         return 0;
     }
-    VERBOSE (DEBUG, fprintf (stdout, "id -> n; %d -> %d\n", id, n));
 
     /* set arguments */
-    free_tab (argument);
-    argument = NULL;
-    VERBOSE (DEBUG, fprintf (stdout, "nbargs; %d\n", nbargs));
-    if (nbargs > 0) {
-        def (nbargs, args);
-    }
+    tab_t *old_argument = copy_tab (argument);
 
     /* backup context */
     workspace_t *tmp = backup_ws (alloc_ws ());
     restore_ws (programs[n]);
 
+    /* set arguments */
+    argument = def (nbargs, args);
+
     /* evaluate program */
     answer = 0;
     element_t *elements = dupelement (programs[n]->root);
@@ -102,15 +99,15 @@ double call (int id, int nbargs, element_t **args)
     VERBOSE (DEBUG, fprintf (stdout, "ret; %g\n", ret));
     delelement (elements);
 
-    /* clean arguments */
-    free_tab (argument);
-    argument = NULL;
-
     /* restore context */
     backup_ws (programs[n]);
     restore_ws (tmp);
     free_ws (tmp);
 
+    /* clean arguments */
+    free_tab (argument);
+    argument = old_argument;
+
     return ret;
 }