X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fcompute.c;h=4cc9a18797b4c8b7eea55c8d57fad1f3ff83e103;hb=97d6c6f6b1922621ca013668eba9a9a9f71d60fe;hp=ff127e359f7e984f51075e9117700ddad54bf3c9;hpb=18febf84744dc7ab4248542c2f88d91c01ef3fa1;p=pspp diff --git a/src/compute.c b/src/compute.c index ff127e359f..4cc9a18797 100644 --- a/src/compute.c +++ b/src/compute.c @@ -18,14 +18,14 @@ 02111-1307, USA. */ #include -#include +#include "error.h" #include #include "alloc.h" -#include "approx.h" #include "command.h" #include "error.h" #include "expr.h" #include "lexer.h" +#include "misc.h" #include "str.h" #include "var.h" @@ -75,8 +75,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,27 +102,32 @@ cmd_compute (void) /* Transformation functions. */ +/* Handle COMPUTE or IF with numeric target variable. */ 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 - || 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; } +/* Handle COMPUTE or IF with numeric vector element target + variable. */ 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 - || 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; @@ -132,7 +135,7 @@ compute_num_vec (struct trns_header *compute_, struct ccase *c) /* 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) { @@ -145,25 +148,27 @@ compute_num_vec (struct trns_header *compute_, struct ccase *c) 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; } +/* Handle COMPUTE or IF with string target variable. */ 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 - || 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; - 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]); } @@ -171,13 +176,16 @@ compute_str (struct trns_header *compute_, struct ccase *c) return -1; } +/* Handle COMPUTE or IF with string vector element target + variable. */ 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 - || 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; @@ -191,7 +199,7 @@ compute_str_vec (struct trns_header *compute_, struct ccase *c) /* 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) { @@ -206,7 +214,7 @@ compute_str_vec (struct trns_header *compute_, struct ccase *c) 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]); } @@ -222,11 +230,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; @@ -269,7 +276,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; @@ -313,6 +320,7 @@ compute_trns_free (struct trns_header *compute_) expr_free (compute->rvalue); } +/* COMPUTE or IF target variable or vector element. */ struct lvalue { char var_name[9]; /* Destination variable name, or "". */ @@ -320,6 +328,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) { @@ -347,7 +357,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 (')')) @@ -367,6 +377,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) { @@ -383,12 +395,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) @@ -397,8 +412,9 @@ lvalue_finalize (struct lvalue *lvalue, { compute->variable = dict_lookup_var (default_dict, lvalue->var_name); if (compute->variable == NULL) - compute->variable = dict_create_var_assert (default_dict, - lvalue->var_name, 0); + compute->variable = dict_create_var_assert (default_dict, + lvalue->var_name, 0); + compute->fv = compute->variable->fv; compute->width = compute->variable->width; @@ -416,31 +432,10 @@ lvalue_finalize (struct lvalue *lvalue, lvalue_destroy (lvalue); } +/* Destroys LVALUE. */ static void lvalue_destroy (struct lvalue *lvalue) { expr_free (lvalue->element); free (lvalue); } - -/* 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; -}