Add yet another expression test and fix the bugs it found.
[pspp] / src / expressions / private.h
1 /* PSPP - computes sample statistics.
2    Copyright (C) 1997-9, 2000 Free Software Foundation, Inc.
3    Written by Ben Pfaff <blp@gnu.org>.
4
5    This program is free software; you can redistribute it and/or
6    modify it under the terms of the GNU General Public License as
7    published by the Free Software Foundation; either version 2 of the
8    License, or (at your option) any later version.
9
10    This program is distributed in the hope that it will be useful, but
11    WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13    General Public License for more details.
14
15    You should have received a copy of the GNU General Public License
16    along with this program; if not, write to the Free Software
17    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
18    02111-1307, USA. */
19
20 #ifndef EXPRESSIONS_PRIVATE_H 
21 #define EXPRESSIONS_PRIVATE_H
22
23 #include <assert.h>
24 #include <stddef.h>
25 #include "format.h"
26 #include "str.h"
27
28 #include "public.h"
29 #include "operations.h"
30
31 enum operation_flags 
32   {
33     /* Most operations produce a missing output value if any
34        input value is missing.  Setting this bit indicates that
35        this operation may produce a non-missing result given
36        missing input values (although it is not obliged to do
37        so).  Unless this bit is set, the operation's evaluation
38        function will never be passed a missing argument. */
39     OPF_ABSORB_MISS = 004,
40
41     /* If set, this operation's final operand is an array of one
42        or more elements. */
43     OPF_ARRAY_OPERAND = 001,
44
45     /* If set, the user can specify the minimum number of array
46        elements that must be non-missing for the function result
47        to be non-missing.  The operation must have an array
48        operand and the array must contain `double's.  Both
49        OPF_ABSORB_MISS and OPF_ARRAY_OPERAND must also be set. */
50     OPF_MIN_VALID = 002,     
51
52     /* If set, operation is non-optimizable in general.  Unless
53        combined with OPF_ABSORB_MISS, missing input values are
54        still assumed to yield missing results. */
55     OPF_NONOPTIMIZABLE = 010,
56
57     /* If set, this operation is not implemented. */
58     OPF_UNIMPLEMENTED = 020,
59
60     /* If set, this operation is a PSPP extension. */
61     OPF_EXTENSION = 040
62   };
63
64 #define EXPR_ARG_MAX 4
65 struct operation
66   {
67     const char *name;
68     const char *prototype;
69     enum operation_flags flags;
70     atom_type returns;
71     int arg_cnt;
72     atom_type args[EXPR_ARG_MAX];
73     int array_min_elems;
74     int array_granularity;
75   };
76
77 extern struct operation operations[];
78
79 /* Tree structured expressions. */ 
80
81 /* Atoms. */
82 struct number_node 
83   {
84     operation_type type;   /* OP_number. */
85     double n;
86   };
87
88 struct string_node
89   {
90     operation_type type;   /* OP_string. */
91     struct fixed_string s;
92   };
93
94 struct variable_node
95   {
96     operation_type type;   /* OP_variable. */
97     struct variable *v;
98   };
99
100 struct integer_node
101   {
102     operation_type type;   /* OP_integer. */
103     int i;
104   };
105
106 struct vector_node
107   {
108     operation_type type;   /* OP_vector. */
109     const struct vector *v;
110   };
111
112 struct format_node
113   {
114     operation_type type;   /* OP_format. */
115     struct fmt_spec f;
116   };
117
118 /* Any composite node. */
119 struct composite_node
120   {
121     operation_type type;   /* One of OP_*. */
122     size_t arg_cnt;             /* Number of arguments. */
123     union any_node **args;      /* Arguments. */
124     size_t min_valid;           /* Min valid array args to get valid result. */
125   };
126
127 /* Any node. */
128 union any_node
129   {
130     operation_type type;
131     struct number_node number;
132     struct string_node string;
133     struct variable_node variable;
134     struct integer_node integer;
135     struct vector_node vector;
136     struct format_node format;
137     struct composite_node composite;
138   };
139
140 union operation_data 
141   {
142     operation_type operation;
143     double number;
144     struct fixed_string string;
145     struct variable *variable;
146     const struct vector *vector;
147     struct fmt_spec *format;
148     int integer;
149   };
150
151 /* An expression. */
152 struct expression
153   {
154     struct pool *expr_pool;     /* Pool for expression static data. */
155     struct dictionary *dict;    /* Dictionary for variables, vectors. */
156     atom_type type;             /* Type of expression result. */
157
158     union operation_data *ops;  /* Expression data. */
159     operation_type *op_types;   /* ops[] element types (for debugging). */
160     size_t op_cnt, op_cap;      /* Number of ops, amount of allocated space. */
161
162     double *number_stack;       /* Evaluation stack: numerics, Booleans. */
163     struct fixed_string *string_stack; /* Evaluation stack: strings. */
164     struct pool *eval_pool;     /* Pool for evaluation temporaries. */
165   };
166
167 struct expression *expr_parse_any (struct dictionary *, bool optimize);
168 void expr_debug_print_postfix (const struct expression *);
169
170 union any_node *expr_optimize (union any_node *, struct expression *);
171 void expr_flatten (union any_node *, struct expression *);
172
173 atom_type expr_node_returns (const union any_node *);
174
175 union any_node *expr_allocate_nullary (struct expression *e, operation_type);
176 union any_node *expr_allocate_unary (struct expression *e,
177                                      operation_type, union any_node *);
178 union any_node *expr_allocate_binary (struct expression *e, operation_type,
179                                  union any_node *, union any_node *);
180 union any_node *expr_allocate_composite (struct expression *e, operation_type,
181                                          union any_node **, size_t);
182 union any_node *expr_allocate_number (struct expression *e, double);
183 union any_node *expr_allocate_boolean (struct expression *e, double);
184 union any_node *expr_allocate_integer (struct expression *e, int);
185 union any_node *expr_allocate_pos_int (struct expression *e, int);
186 union any_node *expr_allocate_string_buffer (struct expression *e,
187                                              const char *string, size_t length);
188 union any_node *expr_allocate_string (struct expression *e,
189                                       struct fixed_string);
190 union any_node *expr_allocate_variable (struct expression *e,
191                                         struct variable *);
192 union any_node *expr_allocate_format (struct expression *e,
193                                  const struct fmt_spec *);
194 union any_node *expr_allocate_vector (struct expression *e,
195                                       const struct vector *);
196
197 #endif /* expressions/private.h */