case: Introduce new functions for numbers and substrings in cases.
[pspp] / src / language / xforms / compute.c
index 00f7c5ad4706b4eec18f51872eb78640c32df110..8e0ce85d61e08ddfe121ba3682eb95cfddea748a 100644 (file)
 struct compute_trns;
 struct lvalue;
 
+/* COMPUTE or IF target variable or vector element.
+   For a variable, the `variable' member is non-null.
+   For a vector element, the `vector' member is non-null. */
+struct lvalue
+  {
+    struct variable *variable;   /* Destination variable. */
+    bool is_new_variable;        /* Did we create the variable? */
+
+    const struct vector *vector; /* Destination vector, if any, or NULL. */
+    struct expression *element;  /* Destination vector element, or NULL. */
+  };
+
 /* Target of a COMPUTE or IF assignment, either a variable or a
    vector element. */
 static struct lvalue *lvalue_parse (struct lexer *lexer, struct dataset *);
@@ -121,7 +133,7 @@ compute_num (void *compute_, struct ccase **c, casenumber case_num)
       || expr_evaluate_num (compute->test, *c, case_num) == 1.0)
     {
       *c = case_unshare (*c);
-      case_data_rw (*c, compute->variable)->f
+      *case_num_rw (*c, compute->variable)
         = expr_evaluate_num (compute->rvalue, *c, case_num);
     }
 
@@ -158,7 +170,7 @@ compute_num_vec (void *compute_, struct ccase **c, casenumber case_num)
         }
 
       *c = case_unshare (*c);
-      case_data_rw (*c, vector_get_var (compute->vector, rindx - 1))->f
+      *case_num_rw (*c, vector_get_var (compute->vector, rindx - 1))
         = expr_evaluate_num (compute->rvalue, *c, case_num);
     }
 
@@ -237,7 +249,7 @@ cmd_if (struct lexer *lexer, struct dataset *ds)
   compute = compute_trns_create ();
 
   /* Test expression. */
-  compute->test = expr_parse (lexer, ds, EXPR_BOOLEAN);
+  compute->test = expr_parse_bool (lexer, NULL, ds);
   if (compute->test == NULL)
     goto fail;
 
@@ -284,9 +296,10 @@ static struct expression *
 parse_rvalue (struct lexer *lexer,
              const struct lvalue *lvalue, struct dataset *ds)
 {
-  bool is_numeric = lvalue_get_type (lvalue) == VAL_NUMERIC;
-
-  return expr_parse (lexer, ds, is_numeric ? EXPR_NUMBER : EXPR_STRING);
+  if (lvalue->is_new_variable)
+    return expr_parse_new_variable (lexer, NULL, ds, var_get_name (lvalue->variable));
+  else
+    return expr_parse (lexer, NULL, ds, lvalue_get_type (lvalue));
 }
 
 /* Returns a new struct compute_trns after initializing its fields. */
@@ -318,18 +331,6 @@ compute_trns_free (void *compute_)
   return true;
 }
 \f
-/* COMPUTE or IF target variable or vector element.
-   For a variable, the `variable' member is non-null.
-   For a vector element, the `vector' member is non-null. */
-struct lvalue
-  {
-    struct variable *variable;   /* Destination variable. */
-    bool is_new_variable;        /* Did we create the variable? */
-
-    const struct vector *vector; /* Destination vector, if any, or NULL. */
-    struct expression *element;  /* Destination vector element, or NULL. */
-  };
-
 /* Parses the target variable or vector element into a new
    `struct lvalue', which is returned. */
 static struct lvalue *
@@ -361,7 +362,7 @@ lvalue_parse (struct lexer *lexer, struct dataset *ds)
       lex_get (lexer);
       if (!lex_force_match (lexer, T_LPAREN))
        goto lossage;
-      lvalue->element = expr_parse (lexer, ds, EXPR_NUMBER);
+      lvalue->element = expr_parse (lexer, NULL, ds, VAL_NUMERIC);
       if (lvalue->element == NULL)
         goto lossage;
       if (!lex_force_match (lexer, T_RPAREN))