X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fcompute.c;h=37592c885862c4b4d64064e251411ea5b3a06f9b;hb=5ff91bd55867848d448c2f09bc7057cc1fb77b18;hp=6e6bd96ad18992c1b361b2d191825d6c0459ff7a;hpb=4de79b34b329d1da6cdeb145993d3efd911e2967;p=pspp diff --git a/src/compute.c b/src/compute.c index 6e6bd96ad1..37592c8858 100644 --- a/src/compute.c +++ b/src/compute.c @@ -41,7 +41,7 @@ struct lvalue; vector element. */ static struct lvalue *lvalue_parse (void); static int lvalue_get_type (const struct lvalue *); -static int lvalue_is_vector (const struct lvalue *); +static bool lvalue_is_vector (const struct lvalue *); static void lvalue_finalize (struct lvalue *, struct compute_trns *); static void lvalue_destroy (struct lvalue *); @@ -49,8 +49,6 @@ static void lvalue_destroy (struct lvalue *); /* COMPUTE and IF transformation. */ struct compute_trns { - struct trns_header h; - /* Test expression (IF only). */ struct expression *test; /* Test expression. */ @@ -67,10 +65,10 @@ struct compute_trns struct expression *rvalue; /* Rvalue expression. */ }; -static int parse_rvalue_expression (struct compute_trns *, - const struct lvalue *); +static struct expression *parse_rvalue (const struct lvalue *); static struct compute_trns *compute_trns_create (void); -static void compute_trns_free (struct trns_header *); +static trns_proc_func *get_proc_func (const struct lvalue *); +static trns_free_func compute_trns_free; /* COMPUTE. */ @@ -80,28 +78,27 @@ cmd_compute (void) struct lvalue *lvalue = NULL; struct compute_trns *compute = NULL; + compute = compute_trns_create (); + lvalue = lvalue_parse (); if (lvalue == NULL) goto fail; - compute = compute_trns_create (); - - if (!lex_force_match ('=') || !parse_rvalue_expression (compute, lvalue)) + if (!lex_force_match ('=')) + goto fail; + compute->rvalue = parse_rvalue (lvalue); + if (compute->rvalue == NULL) goto fail; - lvalue_finalize (lvalue, compute); + add_transformation (get_proc_func (lvalue), compute_trns_free, compute); - add_transformation (&compute->h); + lvalue_finalize (lvalue, compute); - return CMD_SUCCESS; + return lex_end_of_command (); fail: lvalue_destroy (lvalue); - if (compute != NULL) - { - compute_trns_free (&compute->h); - free (compute); - } + compute_trns_free (compute); return CMD_FAILURE; } @@ -109,10 +106,9 @@ cmd_compute (void) /* Handle COMPUTE or IF with numeric target variable. */ static int -compute_num (struct trns_header *compute_, struct ccase *c, - int case_num) +compute_num (void *compute_, struct ccase *c, int case_num) { - struct compute_trns *compute = (struct compute_trns *) compute_; + struct compute_trns *compute = compute_; if (compute->test == NULL || expr_evaluate_num (compute->test, c, case_num) == 1.0) @@ -125,10 +121,9 @@ compute_num (struct trns_header *compute_, struct ccase *c, /* 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) +compute_num_vec (void *compute_, struct ccase *c, int case_num) { - struct compute_trns *compute = (struct compute_trns *) compute_; + struct compute_trns *compute = compute_; if (compute->test == NULL || expr_evaluate_num (compute->test, c, case_num) == 1.0) @@ -158,10 +153,9 @@ compute_num_vec (struct trns_header *compute_, struct ccase *c, /* Handle COMPUTE or IF with string target variable. */ static int -compute_str (struct trns_header *compute_, struct ccase *c, - int case_num) +compute_str (void *compute_, struct ccase *c, int case_num) { - struct compute_trns *compute = (struct compute_trns *) compute_; + struct compute_trns *compute = compute_; if (compute->test == NULL || expr_evaluate_num (compute->test, c, case_num) == 1.0) @@ -174,10 +168,9 @@ compute_str (struct trns_header *compute_, struct ccase *c, /* 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) +compute_str_vec (void *compute_, struct ccase *c, int case_num) { - struct compute_trns *compute = (struct compute_trns *) compute_; + struct compute_trns *compute = compute_; if (compute->test == NULL || expr_evaluate_num (compute->test, c, case_num) == 1.0) @@ -232,56 +225,45 @@ cmd_if (void) goto fail; /* Rvalue expression. */ - if (!lex_force_match ('=') || !parse_rvalue_expression (compute, lvalue)) + if (!lex_force_match ('=')) + goto fail; + compute->rvalue = parse_rvalue (lvalue); + if (compute->rvalue == NULL) goto fail; - lvalue_finalize (lvalue, compute); + add_transformation (get_proc_func (lvalue), compute_trns_free, compute); - add_transformation (&compute->h); + lvalue_finalize (lvalue, compute); - return CMD_SUCCESS; + return lex_end_of_command (); fail: lvalue_destroy (lvalue); - if (compute != NULL) - { - compute_trns_free (&compute->h); - free (compute); - } + compute_trns_free (compute); return CMD_FAILURE; } /* Code common to COMPUTE and IF. */ -/* Checks for type mismatches on transformation C. Also checks for - command terminator, sets the case-handling proc from the array - passed. */ -static int -parse_rvalue_expression (struct compute_trns *compute, - const struct lvalue *lvalue) +static trns_proc_func * +get_proc_func (const struct lvalue *lvalue) { - int type = lvalue_get_type (lvalue); - int vector = lvalue_is_vector (lvalue); + bool is_numeric = lvalue_get_type (lvalue) == NUMERIC; + bool is_vector = lvalue_is_vector (lvalue); - assert (type == NUMERIC || type == ALPHA); - - compute->rvalue = expr_parse (default_dict, - type == ALPHA ? EXPR_STRING : EXPR_NUMBER); - if (compute->rvalue == NULL) - return 0; + return (is_numeric + ? (is_vector ? compute_num_vec : compute_num) + : (is_vector ? compute_str_vec : compute_str)); +} - if (type == NUMERIC) - compute->h.proc = vector ? compute_num_vec : compute_num; - else - compute->h.proc = vector ? compute_str_vec : compute_str; +/* Parses and returns an rvalue expression of the same type as + LVALUE, or a null pointer on failure. */ +static struct expression * +parse_rvalue (const struct lvalue *lvalue) +{ + bool is_numeric = lvalue_get_type (lvalue) == NUMERIC; - if (token != '.') - { - lex_error (_("expecting end of command")); - return 0; - } - - return 1; + return expr_parse (default_dict, is_numeric ? EXPR_NUMBER : EXPR_STRING); } /* Returns a new struct compute_trns after initializing its fields. */ @@ -289,8 +271,6 @@ static struct compute_trns * compute_trns_create (void) { struct compute_trns *compute = xmalloc (sizeof *compute); - compute->h.proc = NULL; - compute->h.free = compute_trns_free; compute->test = NULL; compute->variable = NULL; compute->vector = NULL; @@ -301,13 +281,17 @@ compute_trns_create (void) /* Deletes all the fields in COMPUTE. */ static void -compute_trns_free (struct trns_header *compute_) +compute_trns_free (void *compute_) { - struct compute_trns *compute = (struct compute_trns *) compute_; + struct compute_trns *compute = compute_; - expr_free (compute->test); - expr_free (compute->element); - expr_free (compute->rvalue); + if (compute != NULL) + { + expr_free (compute->test); + expr_free (compute->element); + expr_free (compute->rvalue); + free (compute); + } } /* COMPUTE or IF target variable or vector element. */ @@ -384,7 +368,7 @@ lvalue_get_type (const struct lvalue *lvalue) } /* Returns nonzero if LVALUE has a vector as its target. */ -static int +static bool lvalue_is_vector (const struct lvalue *lvalue) { return lvalue->vector != NULL; @@ -393,8 +377,7 @@ lvalue_is_vector (const struct lvalue *lvalue) /* 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) +lvalue_finalize (struct lvalue *lvalue, struct compute_trns *compute) { if (lvalue->vector == NULL) { @@ -424,8 +407,8 @@ lvalue_finalize (struct lvalue *lvalue, static void lvalue_destroy (struct lvalue *lvalue) { - if ( ! lvalue ) - return ; + if (lvalue == NULL) + return; expr_free (lvalue->element); free (lvalue);