Fixed bug #11227 (T-Test not working with alpha independent variable )
[pspp-builds.git] / src / compute.c
index 60c99ad825b7dde1295a75dd9d558417ee093b2a..6556e8becac0041d63303556817f6f203f4fd09d 100644 (file)
    02111-1307, USA. */
 
 #include <config.h>
-#include <assert.h>
+#include "error.h"
 #include <stdlib.h>
 #include "alloc.h"
+#include "case.h"
 #include "command.h"
+#include "dictionary.h"
 #include "error.h"
 #include "expr.h"
 #include "lexer.h"
@@ -75,8 +77,6 @@ cmd_compute (void)
   struct lvalue *lvalue = NULL;
   struct compute_trns *compute = NULL;
 
-  lex_match_id ("COMPUTE");
-
   lvalue = lvalue_parse ();
   if (lvalue == NULL)
     goto fail;
@@ -104,6 +104,7 @@ cmd_compute (void)
 \f
 /* Transformation functions. */
 
+/* Handle COMPUTE or IF with numeric target variable. */
 static int
 compute_num (struct trns_header *compute_, struct ccase *c,
              int case_num)
@@ -113,12 +114,15 @@ compute_num (struct trns_header *compute_, struct ccase *c,
   if (compute->test == NULL
       || expr_evaluate (compute->test, c, case_num, NULL) == 1.0) 
     {
-      expr_evaluate (compute->rvalue, c, case_num, &c->data[compute->fv]); 
+      expr_evaluate (compute->rvalue, c, case_num,
+                     case_data_rw (c, compute->fv)); 
     }
   
   return -1;
 }
 
+/* Handle COMPUTE or IF with numeric vector element target
+   variable. */
 static int
 compute_num_vec (struct trns_header *compute_, struct ccase *c,
                  int case_num)
@@ -148,12 +152,13 @@ compute_num_vec (struct trns_header *compute_, struct ccase *c,
           return -1;
         }
       expr_evaluate (compute->rvalue, c, case_num,
-                     &c->data[compute->vector->var[rindx - 1]->fv]); 
+                     case_data_rw (c, compute->vector->var[rindx - 1]->fv));
     }
   
   return -1;
 }
 
+/* Handle COMPUTE or IF with string target variable. */
 static int
 compute_str (struct trns_header *compute_, struct ccase *c,
              int case_num)
@@ -167,13 +172,15 @@ compute_str (struct trns_header *compute_, struct ccase *c,
       union value v;
 
       expr_evaluate (compute->rvalue, c, case_num, &v);
-      st_bare_pad_len_copy (c->data[compute->fv].s, &v.c[1], compute->width,
-                            v.c[0]); 
+      st_bare_pad_len_copy (case_data_rw (c, compute->fv)->s,
+                            &v.c[1], compute->width, v.c[0]); 
     }
   
   return -1;
 }
 
+/* Handle COMPUTE or IF with string vector element target
+   variable. */
 static int
 compute_str_vec (struct trns_header *compute_, struct ccase *c,
                  int case_num)
@@ -212,7 +219,8 @@ compute_str_vec (struct trns_header *compute_, struct ccase *c,
 
       expr_evaluate (compute->rvalue, c, case_num, &v);
       vr = compute->vector->var[rindx - 1];
-      st_bare_pad_len_copy (c->data[vr->fv].s, &v.c[1], vr->width, v.c[0]); 
+      st_bare_pad_len_copy (case_data_rw (c, vr->fv)->s,
+                            &v.c[1], vr->width, v.c[0]); 
     }
   
   return -1;
@@ -226,11 +234,10 @@ cmd_if (void)
   struct compute_trns *compute = NULL;
   struct lvalue *lvalue = NULL;
 
-  lex_match_id ("IF");
   compute = compute_trns_create ();
 
   /* Test expression. */
-  compute->test = expr_parse (PXP_BOOLEAN);
+  compute->test = expr_parse (EXPR_BOOLEAN);
   if (compute->test == NULL)
     goto fail;
 
@@ -273,7 +280,7 @@ parse_rvalue_expression (struct compute_trns *compute,
 
   assert (type == NUMERIC || type == ALPHA);
 
-  compute->rvalue = expr_parse (type == ALPHA ? PXP_STRING : PXP_NUMERIC);
+  compute->rvalue = expr_parse (type == ALPHA ? EXPR_STRING : EXPR_NUMERIC);
   if (compute->rvalue == NULL)
     return 0;
 
@@ -317,6 +324,7 @@ compute_trns_free (struct trns_header *compute_)
   expr_free (compute->rvalue);
 }
 \f
+/* COMPUTE or IF target variable or vector element. */
 struct lvalue
   {
     char var_name[9];            /* Destination variable name, or "". */
@@ -324,6 +332,8 @@ struct lvalue
     struct expression *element;  /* Destination vector element, or NULL. */
   };
 
+/* Parses the target variable or vector elector into a new
+   `struct lvalue', which is returned. */
 static struct lvalue *
 lvalue_parse (void) 
 {
@@ -351,7 +361,7 @@ lvalue_parse (void)
       lex_get ();
       if (!lex_force_match ('('))
        goto lossage;
-      lvalue->element = expr_parse (PXP_NUMERIC);
+      lvalue->element = expr_parse (EXPR_NUMERIC);
       if (lvalue->element == NULL)
         goto lossage;
       if (!lex_force_match (')'))
@@ -371,6 +381,8 @@ lvalue_parse (void)
   return NULL;
 }
 
+/* Returns the type (NUMERIC or ALPHA) of the target variable or
+   vector in LVALUE. */
 static int
 lvalue_get_type (const struct lvalue *lvalue) 
 {
@@ -387,12 +399,15 @@ lvalue_get_type (const struct lvalue *lvalue)
     return lvalue->vector->var[0]->type;
 }
 
+/* Returns nonzero if LVALUE has a vector as its target. */
 static int
 lvalue_is_vector (const struct lvalue *lvalue) 
 {
   return lvalue->vector != NULL;
 }
 
+/* Finalizes making LVALUE the target of COMPUTE, by creating the
+   target variable if necessary and setting fields in COMPUTE. */
 static void
 lvalue_finalize (struct lvalue *lvalue,
                  struct compute_trns *compute) 
@@ -407,8 +422,6 @@ lvalue_finalize (struct lvalue *lvalue,
       compute->fv = compute->variable->fv;
       compute->width = compute->variable->width;
 
-      
-
       /* Goofy behavior, but compatible: Turn off LEAVE. */
       if (dict_class_from_id (compute->variable->name) != DC_SCRATCH)
         compute->variable->reinit = 1;
@@ -423,31 +436,10 @@ lvalue_finalize (struct lvalue *lvalue,
   lvalue_destroy (lvalue);
 }
 
+/* Destroys LVALUE. */
 static void 
 lvalue_destroy (struct lvalue *lvalue) 
 {
   expr_free (lvalue->element);
   free (lvalue);
 }
-\f
-/* EVALUATE. */
-
-int
-cmd_evaluate (void)
-{
-  struct expression *expr;
-
-  lex_match_id ("EVALUATE");
-  expr = expr_parse (PXP_DUMP);
-  if (!expr)
-    return CMD_FAILURE;
-
-  expr_free (expr);
-  if (token != '.')
-    {
-      msg (SE, _("Extra characters after expression."));
-      return CMD_FAILURE;
-    }
-  
-  return CMD_SUCCESS;
-}