expressions: Major work to improve error messages.
[pspp] / src / language / expressions / private.h
index 5deb8b369eb2cafbf97c8f3efcc3d1ea1a182a0a..235c2ecf207771ec0e8c6500f72cd965ebb7bac3 100644 (file)
@@ -1,5 +1,5 @@
 /* PSPP - a program for statistical analysis.
-   Copyright (C) 1997-9, 2000 Free Software Foundation, Inc.
+   Copyright (C) 1997-9, 2000, 2011 Free Software Foundation, Inc.
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
 
 #include <assert.h>
 #include <stddef.h>
-#include <data/format.h>
-#include <libpspp/str.h>
 
-#include "public.h"
+#include "data/format.h"
 #include "operations.h"
+#include "public.h"
+#include "libpspp/str.h"
 
 enum operation_flags
   {
@@ -33,36 +33,40 @@ enum operation_flags
        missing input values (although it is not obliged to do
        so).  Unless this bit is set, the operation's evaluation
        function will never be passed a missing argument. */
-    OPF_ABSORB_MISS = 004,
+    OPF_ABSORB_MISS = 1 << 0,
 
     /* If set, this operation's final operand is an array of one
        or more elements. */
-    OPF_ARRAY_OPERAND = 001,
+    OPF_ARRAY_OPERAND = 1 << 1,
 
     /* If set, the user can specify the minimum number of array
        elements that must be non-missing for the function result
        to be non-missing.  The operation must have an array
        operand and the array must contain `double's.  Both
        OPF_ABSORB_MISS and OPF_ARRAY_OPERAND must also be set. */
-    OPF_MIN_VALID = 002,
+    OPF_MIN_VALID = 1 << 2,
 
     /* If set, operation is non-optimizable in general.  Unless
        combined with OPF_ABSORB_MISS, missing input values are
        still assumed to yield missing results. */
-    OPF_NONOPTIMIZABLE = 010,
+    OPF_NONOPTIMIZABLE = 1 << 3,
 
     /* If set, this operation is not implemented. */
-    OPF_UNIMPLEMENTED = 020,
+    OPF_UNIMPLEMENTED = 1 << 4,
 
     /* If set, this operation is a PSPP extension. */
-    OPF_EXTENSION = 040,
+    OPF_EXTENSION = 1 << 5,
 
     /* If set, this operation may not occur after TEMPORARY.
        (Currently this applies only to LAG.) */
-    OPF_PERM_ONLY = 0100,
+    OPF_PERM_ONLY = 1 << 6,
 
     /* If set, this operation's name may not be abbreviated. */
-    OPF_NO_ABBREV = 0200
+    OPF_NO_ABBREV = 1 << 7,
+
+    /* If set, this operation needs the "struct expr_node *", for message
+       locations. */
+    OPF_EXPR_NODE = 1 << 8,
   };
 
 #define EXPR_ARG_MAX 4
@@ -71,8 +75,8 @@ struct operation
     const char *name;
     const char *prototype;
     enum operation_flags flags;
-    atom_type returns;
-    int arg_cnt;
+    atom_type returns;       /* Usually OP_number, OP_string, or OP_boolean. */
+    int n_args;
     atom_type args[EXPR_ARG_MAX];
     int array_min_elems;
     int array_granularity;
@@ -80,65 +84,43 @@ struct operation
 
 extern const struct operation operations[];
 
-/* Tree structured expressions. */
-
-/* Atoms. */
-struct number_node
+/* Expression parse tree. */
+struct expr_node
   {
-    operation_type type;   /* OP_number. */
-    double n;
-  };
+    operation_type type;
+    struct msg_location *location;
 
-struct string_node
-  {
-    operation_type type;   /* OP_string. */
-    struct substring s;
-  };
+    union
+      {
+        /* OP_number. */
+        double number;
 
-struct variable_node
-  {
-    operation_type type;   /* OP_variable. */
-    const struct variable *v;
-  };
+        /* OP_string. */
+        struct substring string;
 
-struct integer_node
-  {
-    operation_type type;   /* OP_integer. */
-    int i;
-  };
+        /* OP_variable. */
+        const struct variable *variable;
 
-struct vector_node
-  {
-    operation_type type;   /* OP_vector. */
-    const struct vector *v;
-  };
+        /* OP_integer. */
+        int integer;
 
-struct format_node
-  {
-    operation_type type;   /* OP_format. */
-    struct fmt_spec f;
-  };
+        /* OP_vector. */
+        const struct vector *vector;
 
-/* Any composite node. */
-struct composite_node
-  {
-    operation_type type;   /* One of OP_*. */
-    size_t arg_cnt;             /* Number of arguments. */
-    union any_node **args;     /* Arguments. */
-    size_t min_valid;           /* Min valid array args to get valid result. */
-  };
+        /* OP_format. */
+        struct fmt_spec format;
 
-/* Any node. */
-union any_node
-  {
-    operation_type type;
-    struct number_node number;
-    struct string_node string;
-    struct variable_node variable;
-    struct integer_node integer;
-    struct vector_node vector;
-    struct format_node format;
-    struct composite_node composite;
+        /* All the other node types. */
+        struct
+          {
+            size_t n_args;         /* Number of arguments. */
+            struct expr_node **args; /* Arguments. */
+            size_t min_valid;   /* Min valid array args to get valid result. */
+          };
+
+        /* OP_exprnode. */
+        const struct expr_node *expr_node;
+      };
   };
 
 union operation_data
@@ -149,6 +131,7 @@ union operation_data
     const struct variable *variable;
     const struct vector *vector;
     struct fmt_spec *format;
+    const struct expr_node *expr_node;
     int integer;
   };
 
@@ -161,7 +144,7 @@ struct expression
 
     union operation_data *ops;  /* Expression data. */
     operation_type *op_types;   /* ops[] element types (for debugging). */
-    size_t op_cnt, op_cap;      /* Number of ops, amount of allocated space. */
+    size_t n_ops, allocated_ops; /* Number of ops, amount of allocated space. */
 
     double *number_stack;       /* Evaluation stack: numerics, Booleans. */
     struct substring *string_stack; /* Evaluation stack: strings. */
@@ -171,31 +154,33 @@ struct expression
 struct expression *expr_parse_any (struct lexer *lexer, struct dataset *,  bool optimize);
 void expr_debug_print_postfix (const struct expression *);
 
-union any_node *expr_optimize (union any_node *, struct expression *);
-void expr_flatten (union any_node *, struct expression *);
-
-atom_type expr_node_returns (const union any_node *);
-
-union any_node *expr_allocate_nullary (struct expression *e, operation_type);
-union any_node *expr_allocate_unary (struct expression *e,
-                                     operation_type, union any_node *);
-union any_node *expr_allocate_binary (struct expression *e, operation_type,
-                                 union any_node *, union any_node *);
-union any_node *expr_allocate_composite (struct expression *e, operation_type,
-                                         union any_node **, size_t);
-union any_node *expr_allocate_number (struct expression *e, double);
-union any_node *expr_allocate_boolean (struct expression *e, double);
-union any_node *expr_allocate_integer (struct expression *e, int);
-union any_node *expr_allocate_pos_int (struct expression *e, int);
-union any_node *expr_allocate_string_buffer (struct expression *e,
-                                             const char *string, size_t length);
-union any_node *expr_allocate_string (struct expression *e,
-                                      struct substring);
-union any_node *expr_allocate_variable (struct expression *e,
+struct expr_node *expr_optimize (struct expr_node *, struct expression *);
+void expr_flatten (struct expr_node *, struct expression *);
+
+atom_type expr_node_returns (const struct expr_node *);
+
+struct expr_node *expr_allocate_nullary (struct expression *e, operation_type);
+struct expr_node *expr_allocate_unary (struct expression *e,
+                                     operation_type, struct expr_node *);
+struct expr_node *expr_allocate_binary (struct expression *e, operation_type,
+                                 struct expr_node *, struct expr_node *);
+struct expr_node *expr_allocate_composite (struct expression *e, operation_type,
+                                         struct expr_node **, size_t);
+struct expr_node *expr_allocate_number (struct expression *e, double);
+struct expr_node *expr_allocate_boolean (struct expression *e, double);
+struct expr_node *expr_allocate_integer (struct expression *e, int);
+struct expr_node *expr_allocate_pos_int (struct expression *e, int);
+struct expr_node *expr_allocate_string (struct expression *e, struct substring);
+struct expr_node *expr_allocate_variable (struct expression *e,
                                         const struct variable *);
-union any_node *expr_allocate_format (struct expression *e,
+struct expr_node *expr_allocate_format (struct expression *e,
                                  const struct fmt_spec *);
-union any_node *expr_allocate_vector (struct expression *e,
+struct expr_node *expr_allocate_expr_node (struct expression *,
+                                           const struct expr_node *);
+struct expr_node *expr_allocate_vector (struct expression *e,
                                       const struct vector *);
 
+const struct msg_location *expr_location (const struct expression *,
+                                          const struct expr_node *);
+
 #endif /* expressions/private.h */