Rewrite expression code.
[pspp-builds.git] / src / loop.c
index b0c836bcc784fe832c19bc35306d3158fec258d2..6470d7ce77782e3f802ae51afed94013f9f2e461 100644 (file)
    02111-1307, USA. */
 
 #include <config.h>
-#include <assert.h>
+#include "error.h"
 #include "alloc.h"
+#include "case.h"
 #include "command.h"
+#include "dictionary.h"
 #include "do-ifP.h"
 #include "error.h"
-#include "expr.h"
+#include "expressions/public.h"
 #include "lexer.h"
 #include "misc.h"
 #include "settings.h"
@@ -166,8 +168,6 @@ internal_cmd_loop (void)
   /* Name of indexing variable if applicable. */
   char name[9];
 
-  lex_match_id ("LOOP");
-
   /* Create and initialize transformations to facilitate
      error-handling. */
   two = xmalloc (sizeof *two);
@@ -200,7 +200,7 @@ internal_cmd_loop (void)
       assert (token == '=');
       lex_get ();
 
-      one->init = expr_parse (PXP_NUMERIC);
+      one->init = expr_parse (default_dict, EXPR_NUMBER);
       if (!one->init)
        return 0;
 
@@ -209,7 +209,7 @@ internal_cmd_loop (void)
          expr_free (one->init);
          return 0;
        }
-      one->term = expr_parse (PXP_NUMERIC);
+      one->term = expr_parse (default_dict, EXPR_NUMBER);
       if (!one->term)
        {
          expr_free (one->init);
@@ -218,7 +218,7 @@ internal_cmd_loop (void)
 
       if (lex_match (T_BY))
        {
-         one->incr = expr_parse (PXP_NUMERIC);
+         one->incr = expr_parse (default_dict, EXPR_NUMBER);
          if (!one->incr)
            return 0;
        }
@@ -231,7 +231,7 @@ internal_cmd_loop (void)
     {
       two->flags |= LPC_COND;
 
-      two->cond = expr_parse (PXP_BOOLEAN);
+      two->cond = expr_parse (default_dict, EXPR_BOOLEAN);
       if (!two->cond)
        return 0;
     }
@@ -261,15 +261,6 @@ internal_cmd_loop (void)
   add_transformation ((struct trns_header *) one);
   add_transformation ((struct trns_header *) two);
 
-#if DEBUGGING
-  printf ("LOOP");
-  if (two->flags & LPC_INDEX)
-    printf ("(INDEX)");
-  if (two->flags & LPC_COND)
-    printf ("(IF)");
-  printf ("\n");
-#endif
-
   return 1;
 }
 
@@ -315,7 +306,7 @@ internal_cmd_end_loop (void)
   /* Parse the expression if any. */
   if (lex_match_id ("IF"))
     {
-      thr->cond = expr_parse (PXP_BOOLEAN);
+      thr->cond = expr_parse (default_dict, EXPR_BOOLEAN);
       if (!thr->cond)
        return 0;
     }
@@ -330,13 +321,6 @@ internal_cmd_end_loop (void)
   /* Pop off the top of stack. */
   ctl_stack = ctl_stack->down;
 
-#if DEBUGGING
-  printf ("END LOOP");
-  if (thr->cond)
-    printf ("(IF)");
-  printf ("\n");
-#endif
-
   return 1;
 }
 
@@ -351,31 +335,31 @@ loop_1_trns_proc (struct trns_header * trns, struct ccase * c,
   two->pass = -1;
   if (two->flags & LPC_INDEX)
     {
-      union value t1, t2, t3;
+      double t1, t2, t3;
 
-      expr_evaluate (one->init, c, case_num, &t1);
+      t1 = expr_evaluate_num (one->init, c, case_num);
       if (one->incr)
-       expr_evaluate (one->incr, c, case_num, &t2);
+       t2 = expr_evaluate_num (one->incr, c, case_num);
       else
-       t2.f = 1.0;
-      expr_evaluate (one->term, c, case_num, &t3);
+       t2 = 1.0;
+      t3 = expr_evaluate_num (one->term, c, case_num);
 
       /* Even if the loop is never entered, force the index variable
          to assume the initial value. */
-      c->data[two->index->fv].f = t1.f;
+      case_data_rw (c, two->index->fv)->f = t1;
 
       /* Throw out various pathological cases. */
-      if (!finite (t1.f) || !finite (t2.f) || !finite (t3.f) || t2.f == 0.0)
+      if (!finite (t1) || !finite (t2) || !finite (t3) || t2 == 0.0)
        return two->loop_term;
       debug_printf (("LOOP %s=%g TO %g BY %g.\n", two->index->name,
-                    t1.f, t3.f, t2.f));
-      if (t2.f > 0.0)
+                    t1, t3, t2));
+      if (t2 > 0.0)
        {
          /* Loop counts upward: I=1 TO 5 BY 1. */
          two->flags &= ~LPC_RINDEX;
 
          /* incr>0 but init>term */
-         if (t1.f > t3.f)
+         if (t1 > t3)
            return two->loop_term;
        }
       else
@@ -384,13 +368,13 @@ loop_1_trns_proc (struct trns_header * trns, struct ccase * c,
          two->flags |= LPC_RINDEX;
 
          /* incr<0 but init<term */
-         if (t1.f < t3.f)
+         if (t1 < t3)
            return two->loop_term;
        }
 
-      two->curr = t1.f;
-      two->incr = t2.f;
-      two->term = t3.f;
+      two->curr = t1;
+      two->incr = t2;
+      two->term = t3;
     }
 
   return -1;
@@ -418,7 +402,7 @@ loop_2_trns_proc (struct trns_header * trns, struct ccase * c,
   if (two->flags == 0)
     {
       two->pass++;
-      if (two->pass > set_mxloops)
+      if (two->pass > get_mxloops() )
          return two->loop_term;
     }
 
@@ -430,7 +414,7 @@ loop_2_trns_proc (struct trns_header * trns, struct ccase * c,
        return two->loop_term;
 
       /* Set the current value into the case. */
-      c->data[two->index->fv].f = two->curr;
+      case_data_rw (c, two->index->fv)->f = two->curr;
 
       /* Decrement the current value. */
       two->curr += two->incr;
@@ -443,7 +427,7 @@ loop_2_trns_proc (struct trns_header * trns, struct ccase * c,
        return two->loop_term;
 
       /* Set the current value into the case. */
-      c->data[two->index->fv].f = two->curr;
+      case_data_rw (c, two->index->fv)->f = two->curr;
 
       /* Increment the current value. */
       two->curr += two->incr;
@@ -451,7 +435,7 @@ loop_2_trns_proc (struct trns_header * trns, struct ccase * c,
 
   /* Conditional clause limiter. */
   if ((two->flags & LPC_COND)
-      && expr_evaluate (two->cond, c, case_num, NULL) != 1.0)
+      && expr_evaluate_num (two->cond, c, case_num) != 1.0)
     return two->loop_term;
 
   return -1;
@@ -475,7 +459,7 @@ loop_3_trns_proc (struct trns_header * trns, struct ccase * c,
 
   /* Note that it breaks out of the loop if the expression is true *or
      missing*.  This is conformant. */
-  if (thr->cond && expr_evaluate (two->cond, c, case_num, NULL) != 0.0)
+  if (thr->cond && expr_evaluate_num (two->cond, c, case_num) != 0.0)
     return -1;
 
   return thr->loop_start;
@@ -502,8 +486,6 @@ cmd_break (void)
   /* New transformation. */
   struct break_trns *t;
 
-  lex_match_id ("BREAK");
-
   for (loop = ctl_stack; loop; loop = loop->down)
     if (loop->type == CST_LOOP)
       break;