/[pspp]/pspp/src/compute.c
ViewVC logotype

Diff of /pspp/src/compute.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.21 by blp, Sun Jul 31 21:42:46 2005 UTC revision 1.22 by blp, Thu Nov 3 06:21:46 2005 UTC
# Line 41  struct lvalue; Line 41  struct lvalue;
41     vector element. */     vector element. */
42  static struct lvalue *lvalue_parse (void);  static struct lvalue *lvalue_parse (void);
43  static int lvalue_get_type (const struct lvalue *);  static int lvalue_get_type (const struct lvalue *);
44  static int lvalue_is_vector (const struct lvalue *);  static bool lvalue_is_vector (const struct lvalue *);
45  static void lvalue_finalize (struct lvalue *,  static void lvalue_finalize (struct lvalue *,
46                               struct compute_trns *);                               struct compute_trns *);
47  static void lvalue_destroy (struct lvalue *);  static void lvalue_destroy (struct lvalue *);
# Line 49  static void lvalue_destroy (struct lvalu Line 49  static void lvalue_destroy (struct lvalu
49  /* COMPUTE and IF transformation. */  /* COMPUTE and IF transformation. */
50  struct compute_trns  struct compute_trns
51    {    {
     struct trns_header h;  
   
52      /* Test expression (IF only). */      /* Test expression (IF only). */
53      struct expression *test;     /* Test expression. */      struct expression *test;     /* Test expression. */
54    
# Line 67  struct compute_trns Line 65  struct compute_trns
65      struct expression *rvalue;   /* Rvalue expression. */      struct expression *rvalue;   /* Rvalue expression. */
66    };    };
67    
68  static int parse_rvalue_expression (struct compute_trns *,  static struct expression *parse_rvalue (const struct lvalue *);
                                     const struct lvalue *);  
69  static struct compute_trns *compute_trns_create (void);  static struct compute_trns *compute_trns_create (void);
70  static void compute_trns_free (struct trns_header *);  static trns_proc_func *get_proc_func (const struct lvalue *);
71    static trns_free_func compute_trns_free;
72    
73  /* COMPUTE. */  /* COMPUTE. */
74    
# Line 80  cmd_compute (void) Line 78  cmd_compute (void)
78    struct lvalue *lvalue = NULL;    struct lvalue *lvalue = NULL;
79    struct compute_trns *compute = NULL;    struct compute_trns *compute = NULL;
80    
81      compute = compute_trns_create ();
82    
83    lvalue = lvalue_parse ();    lvalue = lvalue_parse ();
84    if (lvalue == NULL)    if (lvalue == NULL)
85      goto fail;      goto fail;
86    
87    compute = compute_trns_create ();    if (!lex_force_match ('='))
88        goto fail;
89    if (!lex_force_match ('=') || !parse_rvalue_expression (compute, lvalue))    compute->rvalue = parse_rvalue (lvalue);
90      if (compute->rvalue == NULL)
91      goto fail;      goto fail;
92    
93    lvalue_finalize (lvalue, compute);    add_transformation (get_proc_func (lvalue), compute_trns_free, compute);
94    
95    add_transformation (&compute->h);    lvalue_finalize (lvalue, compute);
96    
97    return CMD_SUCCESS;    return lex_end_of_command ();
98    
99   fail:   fail:
100    lvalue_destroy (lvalue);    lvalue_destroy (lvalue);
101    if (compute != NULL)    compute_trns_free (compute);
     {  
       compute_trns_free (&compute->h);  
       free (compute);  
     }  
102    return CMD_FAILURE;    return CMD_FAILURE;
103  }  }
104    
# Line 109  cmd_compute (void) Line 106  cmd_compute (void)
106    
107  /* Handle COMPUTE or IF with numeric target variable. */  /* Handle COMPUTE or IF with numeric target variable. */
108  static int  static int
109  compute_num (struct trns_header *compute_, struct ccase *c,  compute_num (void *compute_, struct ccase *c, int case_num)
              int case_num)  
110  {  {
111    struct compute_trns *compute = (struct compute_trns *) compute_;    struct compute_trns *compute = compute_;
112    
113    if (compute->test == NULL    if (compute->test == NULL
114        || expr_evaluate_num (compute->test, c, case_num) == 1.0)        || expr_evaluate_num (compute->test, c, case_num) == 1.0)
# Line 125  compute_num (struct trns_header *compute Line 121  compute_num (struct trns_header *compute
121  /* Handle COMPUTE or IF with numeric vector element target  /* Handle COMPUTE or IF with numeric vector element target
122     variable. */     variable. */
123  static int  static int
124  compute_num_vec (struct trns_header *compute_, struct ccase *c,  compute_num_vec (void *compute_, struct ccase *c, int case_num)
                  int case_num)  
125  {  {
126    struct compute_trns *compute = (struct compute_trns *) compute_;    struct compute_trns *compute = compute_;
127    
128    if (compute->test == NULL    if (compute->test == NULL
129        || expr_evaluate_num (compute->test, c, case_num) == 1.0)        || expr_evaluate_num (compute->test, c, case_num) == 1.0)
# Line 158  compute_num_vec (struct trns_header *com Line 153  compute_num_vec (struct trns_header *com
153    
154  /* Handle COMPUTE or IF with string target variable. */  /* Handle COMPUTE or IF with string target variable. */
155  static int  static int
156  compute_str (struct trns_header *compute_, struct ccase *c,  compute_str (void *compute_, struct ccase *c, int case_num)
              int case_num)  
157  {  {
158    struct compute_trns *compute = (struct compute_trns *) compute_;    struct compute_trns *compute = compute_;
159    
160    if (compute->test == NULL    if (compute->test == NULL
161        || expr_evaluate_num (compute->test, c, case_num) == 1.0)        || expr_evaluate_num (compute->test, c, case_num) == 1.0)
# Line 174  compute_str (struct trns_header *compute Line 168  compute_str (struct trns_header *compute
168  /* Handle COMPUTE or IF with string vector element target  /* Handle COMPUTE or IF with string vector element target
169     variable. */     variable. */
170  static int  static int
171  compute_str_vec (struct trns_header *compute_, struct ccase *c,  compute_str_vec (void *compute_, struct ccase *c, int case_num)
                  int case_num)  
172  {  {
173    struct compute_trns *compute = (struct compute_trns *) compute_;    struct compute_trns *compute = compute_;
174    
175    if (compute->test == NULL    if (compute->test == NULL
176        || expr_evaluate_num (compute->test, c, case_num) == 1.0)        || expr_evaluate_num (compute->test, c, case_num) == 1.0)
# Line 232  cmd_if (void) Line 225  cmd_if (void)
225      goto fail;      goto fail;
226    
227    /* Rvalue expression. */    /* Rvalue expression. */
228    if (!lex_force_match ('=') || !parse_rvalue_expression (compute, lvalue))    if (!lex_force_match ('='))
229        goto fail;
230      compute->rvalue = parse_rvalue (lvalue);
231      if (compute->rvalue == NULL)
232      goto fail;      goto fail;
233    
234    lvalue_finalize (lvalue, compute);    add_transformation (get_proc_func (lvalue), compute_trns_free, compute);
235    
236    add_transformation (&compute->h);    lvalue_finalize (lvalue, compute);
237    
238    return CMD_SUCCESS;    return lex_end_of_command ();
239    
240   fail:   fail:
241    lvalue_destroy (lvalue);    lvalue_destroy (lvalue);
242    if (compute != NULL)    compute_trns_free (compute);
     {  
       compute_trns_free (&compute->h);  
       free (compute);  
     }  
243    return CMD_FAILURE;    return CMD_FAILURE;
244  }  }
245    
246  /* Code common to COMPUTE and IF. */  /* Code common to COMPUTE and IF. */
247    
248  /* Checks for type mismatches on transformation C.  Also checks for  static trns_proc_func *
249     command terminator, sets the case-handling proc from the array  get_proc_func (const struct lvalue *lvalue)
    passed. */  
 static int  
 parse_rvalue_expression (struct compute_trns *compute,  
                          const struct lvalue *lvalue)  
250  {  {
251    int type = lvalue_get_type (lvalue);    bool is_numeric = lvalue_get_type (lvalue) == NUMERIC;
252    int vector = lvalue_is_vector (lvalue);    bool is_vector = lvalue_is_vector (lvalue);
253    
254    assert (type == NUMERIC || type == ALPHA);    return (is_numeric
255              ? (is_vector ? compute_num_vec : compute_num)
256    compute->rvalue = expr_parse (default_dict,            : (is_vector ? compute_str_vec : compute_str));
257                                  type == ALPHA ? EXPR_STRING : EXPR_NUMBER);  }
   if (compute->rvalue == NULL)  
     return 0;  
258    
259    if (type == NUMERIC)  /* Parses and returns an rvalue expression of the same type as
260      compute->h.proc = vector ? compute_num_vec : compute_num;     LVALUE, or a null pointer on failure. */
261    else  static struct expression *
262      compute->h.proc = vector ? compute_str_vec : compute_str;  parse_rvalue (const struct lvalue *lvalue)
263    {
264      bool is_numeric = lvalue_get_type (lvalue) == NUMERIC;
265    
266    if (token != '.')    return expr_parse (default_dict, is_numeric ? EXPR_NUMBER : EXPR_STRING);
     {  
       lex_error (_("expecting end of command"));  
       return 0;  
     }  
     
   return 1;  
267  }  }
268    
269  /* Returns a new struct compute_trns after initializing its fields. */  /* Returns a new struct compute_trns after initializing its fields. */
# Line 289  static struct compute_trns * Line 271  static struct compute_trns *
271  compute_trns_create (void)  compute_trns_create (void)
272  {  {
273    struct compute_trns *compute = xmalloc (sizeof *compute);    struct compute_trns *compute = xmalloc (sizeof *compute);
   compute->h.proc = NULL;  
   compute->h.free = compute_trns_free;  
274    compute->test = NULL;    compute->test = NULL;
275    compute->variable = NULL;    compute->variable = NULL;
276    compute->vector = NULL;    compute->vector = NULL;
# Line 301  compute_trns_create (void) Line 281  compute_trns_create (void)
281    
282  /* Deletes all the fields in COMPUTE. */  /* Deletes all the fields in COMPUTE. */
283  static void  static void
284  compute_trns_free (struct trns_header *compute_)  compute_trns_free (void *compute_)
285  {  {
286    struct compute_trns *compute = (struct compute_trns *) compute_;    struct compute_trns *compute = compute_;
287    
288    expr_free (compute->test);    if (compute != NULL)
289    expr_free (compute->element);      {
290    expr_free (compute->rvalue);        expr_free (compute->test);
291          expr_free (compute->element);
292          expr_free (compute->rvalue);
293          free (compute);
294        }
295  }  }
296    
297  /* COMPUTE or IF target variable or vector element. */  /* COMPUTE or IF target variable or vector element. */
# Line 384  lvalue_get_type (const struct lvalue *lv Line 368  lvalue_get_type (const struct lvalue *lv
368  }  }
369    
370  /* Returns nonzero if LVALUE has a vector as its target. */  /* Returns nonzero if LVALUE has a vector as its target. */
371  static int  static bool
372  lvalue_is_vector (const struct lvalue *lvalue)  lvalue_is_vector (const struct lvalue *lvalue)
373  {  {
374    return lvalue->vector != NULL;    return lvalue->vector != NULL;
# Line 393  lvalue_is_vector (const struct lvalue *l Line 377  lvalue_is_vector (const struct lvalue *l
377  /* Finalizes making LVALUE the target of COMPUTE, by creating the  /* Finalizes making LVALUE the target of COMPUTE, by creating the
378     target variable if necessary and setting fields in COMPUTE. */     target variable if necessary and setting fields in COMPUTE. */
379  static void  static void
380  lvalue_finalize (struct lvalue *lvalue,  lvalue_finalize (struct lvalue *lvalue, struct compute_trns *compute)
                  struct compute_trns *compute)  
381  {  {
382    if (lvalue->vector == NULL)    if (lvalue->vector == NULL)
383      {      {
# Line 424  lvalue_finalize (struct lvalue *lvalue, Line 407  lvalue_finalize (struct lvalue *lvalue,
407  static void  static void
408  lvalue_destroy (struct lvalue *lvalue)  lvalue_destroy (struct lvalue *lvalue)
409  {  {
410    if ( ! lvalue )    if (lvalue == NULL)
411       return ;       return;
412    
413    expr_free (lvalue->element);    expr_free (lvalue->element);
414    free (lvalue);    free (lvalue);

Legend:
Removed from v.1.21  
changed lines
  Added in v.1.22

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26