projects
/
pspp
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
Make the expression code a little nicer and fix bugs found
[pspp]
/
src
/
compute.c
diff --git
a/src/compute.c
b/src/compute.c
index e299bd67f52f32100cc741cbfafdbb04c67e23cd..4cc9a18797b4c8b7eea55c8d57fad1f3ff83e103 100644
(file)
--- a/
src/compute.c
+++ b/
src/compute.c
@@
-18,15
+18,14
@@
02111-1307, USA. */
#include <config.h>
02111-1307, USA. */
#include <config.h>
-#include
<assert.h>
+#include
"error.h"
#include <stdlib.h>
#include "alloc.h"
#include <stdlib.h>
#include "alloc.h"
-#include "approx.h"
-#include "cases.h"
#include "command.h"
#include "error.h"
#include "expr.h"
#include "lexer.h"
#include "command.h"
#include "error.h"
#include "expr.h"
#include "lexer.h"
+#include "misc.h"
#include "str.h"
#include "var.h"
#include "str.h"
#include "var.h"
@@
-76,8
+75,6
@@
cmd_compute (void)
struct lvalue *lvalue = NULL;
struct compute_trns *compute = NULL;
struct lvalue *lvalue = NULL;
struct compute_trns *compute = NULL;
- lex_match_id ("COMPUTE");
-
lvalue = lvalue_parse ();
if (lvalue == NULL)
goto fail;
lvalue = lvalue_parse ();
if (lvalue == NULL)
goto fail;
@@
-105,27
+102,32
@@
cmd_compute (void)
\f
/* Transformation functions. */
\f
/* Transformation functions. */
+/* Handle COMPUTE or IF with numeric target variable. */
static int
static int
-compute_num (struct trns_header *compute_, struct ccase *c)
+compute_num (struct trns_header *compute_, struct ccase *c,
+ int case_num)
{
struct compute_trns *compute = (struct compute_trns *) compute_;
if (compute->test == NULL
{
struct compute_trns *compute = (struct compute_trns *) compute_;
if (compute->test == NULL
- || expr_evaluate (compute->test, c, NULL) == 1.0)
+ || expr_evaluate (compute->test, c,
case_num,
NULL) == 1.0)
{
{
- expr_evaluate (compute->rvalue, c, &c->data[compute->fv]);
+ expr_evaluate (compute->rvalue, c,
case_num,
&c->data[compute->fv]);
}
return -1;
}
}
return -1;
}
+/* Handle COMPUTE or IF with numeric vector element target
+ variable. */
static int
static int
-compute_num_vec (struct trns_header *compute_, struct ccase *c)
+compute_num_vec (struct trns_header *compute_, struct ccase *c,
+ int case_num)
{
struct compute_trns *compute = (struct compute_trns *) compute_;
if (compute->test == NULL
{
struct compute_trns *compute = (struct compute_trns *) compute_;
if (compute->test == NULL
- || expr_evaluate (compute->test, c, NULL) == 1.0)
+ || expr_evaluate (compute->test, c,
case_num,
NULL) == 1.0)
{
/* Index into the vector. */
union value index;
{
/* Index into the vector. */
union value index;
@@
-133,7
+135,7
@@
compute_num_vec (struct trns_header *compute_, struct ccase *c)
/* Rounded index value. */
int rindx;
/* Rounded index value. */
int rindx;
- expr_evaluate (compute->element, c, &index);
+ expr_evaluate (compute->element, c,
case_num,
&index);
rindx = floor (index.f + EPSILON);
if (index.f == SYSMIS || rindx < 1 || rindx > compute->vector->cnt)
{
rindx = floor (index.f + EPSILON);
if (index.f == SYSMIS || rindx < 1 || rindx > compute->vector->cnt)
{
@@
-146,25
+148,27
@@
compute_num_vec (struct trns_header *compute_, struct ccase *c)
index.f, compute->vector->name);
return -1;
}
index.f, compute->vector->name);
return -1;
}
- expr_evaluate (compute->rvalue, c,
+ expr_evaluate (compute->rvalue, c,
case_num,
&c->data[compute->vector->var[rindx - 1]->fv]);
}
return -1;
}
&c->data[compute->vector->var[rindx - 1]->fv]);
}
return -1;
}
+/* Handle COMPUTE or IF with string target variable. */
static int
static int
-compute_str (struct trns_header *compute_, struct ccase *c)
+compute_str (struct trns_header *compute_, struct ccase *c,
+ int case_num)
{
struct compute_trns *compute = (struct compute_trns *) compute_;
if (compute->test == NULL
{
struct compute_trns *compute = (struct compute_trns *) compute_;
if (compute->test == NULL
- || expr_evaluate (compute->test, c, NULL) == 1.0)
+ || expr_evaluate (compute->test, c,
case_num,
NULL) == 1.0)
{
/* Temporary storage for string expression return value. */
union value v;
{
/* Temporary storage for string expression return value. */
union value v;
- expr_evaluate (compute->rvalue, c, &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 (c->data[compute->fv].s, &v.c[1], compute->width,
v.c[0]);
}
@@
-172,13
+176,16
@@
compute_str (struct trns_header *compute_, struct ccase *c)
return -1;
}
return -1;
}
+/* Handle COMPUTE or IF with string vector element target
+ variable. */
static int
static int
-compute_str_vec (struct trns_header *compute_, struct ccase *c)
+compute_str_vec (struct trns_header *compute_, struct ccase *c,
+ int case_num)
{
struct compute_trns *compute = (struct compute_trns *) compute_;
if (compute->test == NULL
{
struct compute_trns *compute = (struct compute_trns *) compute_;
if (compute->test == NULL
- || expr_evaluate (compute->test, c, NULL) == 1.0)
+ || expr_evaluate (compute->test, c,
case_num,
NULL) == 1.0)
{
/* Temporary storage for string expression return value. */
union value v;
{
/* Temporary storage for string expression return value. */
union value v;
@@
-192,7
+199,7
@@
compute_str_vec (struct trns_header *compute_, struct ccase *c)
/* Variable reference by indexed vector. */
struct variable *vr;
/* Variable reference by indexed vector. */
struct variable *vr;
- expr_evaluate (compute->element, c, &index);
+ expr_evaluate (compute->element, c,
case_num,
&index);
rindx = floor (index.f + EPSILON);
if (index.f == SYSMIS || rindx < 1 || rindx > compute->vector->cnt)
{
rindx = floor (index.f + EPSILON);
if (index.f == SYSMIS || rindx < 1 || rindx > compute->vector->cnt)
{
@@
-207,7
+214,7
@@
compute_str_vec (struct trns_header *compute_, struct ccase *c)
return -1;
}
return -1;
}
- expr_evaluate (compute->rvalue, c, &v);
+ 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]);
}
vr = compute->vector->var[rindx - 1];
st_bare_pad_len_copy (c->data[vr->fv].s, &v.c[1], vr->width, v.c[0]);
}
@@
-223,11
+230,10
@@
cmd_if (void)
struct compute_trns *compute = NULL;
struct lvalue *lvalue = NULL;
struct compute_trns *compute = NULL;
struct lvalue *lvalue = NULL;
- lex_match_id ("IF");
compute = compute_trns_create ();
/* Test expression. */
compute = compute_trns_create ();
/* Test expression. */
- compute->test = expr_parse (
PXP
_BOOLEAN);
+ compute->test = expr_parse (
EXPR
_BOOLEAN);
if (compute->test == NULL)
goto fail;
if (compute->test == NULL)
goto fail;
@@
-270,7
+276,7
@@
parse_rvalue_expression (struct compute_trns *compute,
assert (type == NUMERIC || type == ALPHA);
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;
if (compute->rvalue == NULL)
return 0;
@@
-314,6
+320,7
@@
compute_trns_free (struct trns_header *compute_)
expr_free (compute->rvalue);
}
\f
expr_free (compute->rvalue);
}
\f
+/* COMPUTE or IF target variable or vector element. */
struct lvalue
{
char var_name[9]; /* Destination variable name, or "". */
struct lvalue
{
char var_name[9]; /* Destination variable name, or "". */
@@
-321,6
+328,8
@@
struct lvalue
struct expression *element; /* Destination vector element, or NULL. */
};
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)
{
static struct lvalue *
lvalue_parse (void)
{
@@
-348,7
+357,7
@@
lvalue_parse (void)
lex_get ();
if (!lex_force_match ('('))
goto lossage;
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 (')'))
if (lvalue->element == NULL)
goto lossage;
if (!lex_force_match (')'))
@@
-368,6
+377,8
@@
lvalue_parse (void)
return NULL;
}
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)
{
static int
lvalue_get_type (const struct lvalue *lvalue)
{
@@
-384,12
+395,15
@@
lvalue_get_type (const struct lvalue *lvalue)
return lvalue->vector->var[0]->type;
}
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;
}
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)
static void
lvalue_finalize (struct lvalue *lvalue,
struct compute_trns *compute)
@@
-398,21
+412,15
@@
lvalue_finalize (struct lvalue *lvalue,
{
compute->variable = dict_lookup_var (default_dict, lvalue->var_name);
if (compute->variable == NULL)
{
compute->variable = dict_lookup_var (default_dict, lvalue->var_name);
if (compute->variable == NULL)
- compute->variable = dict_create_var (default_dict, lvalue->var_name,
- 0);
- assert (compute->variable != NULL);
+ compute->variable = dict_create_var_assert (default_dict,
+ lvalue->var_name, 0);
compute->fv = compute->variable->fv;
compute->width = compute->variable->width;
/* Goofy behavior, but compatible: Turn off LEAVE. */
compute->fv = compute->variable->fv;
compute->width = compute->variable->width;
/* Goofy behavior, but compatible: Turn off LEAVE. */
- if (compute->variable->left
- && dict_class_from_id (compute->variable->name) != DC_SCRATCH)
- {
- devector (compute->variable);
- compute->variable->left = 0;
- envector (compute->variable);
- }
+ if (dict_class_from_id (compute->variable->name) != DC_SCRATCH)
+ compute->variable->reinit = 1;
}
else
{
}
else
{
@@
-424,31
+432,10
@@
lvalue_finalize (struct lvalue *lvalue,
lvalue_destroy (lvalue);
}
lvalue_destroy (lvalue);
}
+/* Destroys LVALUE. */
static void
lvalue_destroy (struct lvalue *lvalue)
{
expr_free (lvalue->element);
free (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;
-}