lots of tests
[pspp] / src / language / expressions / parse.c
index da027b5e7afa1e3610a1fda91979428f1789095b..24aaecf7f12c98fe0c632073d38c58d163b76137 100644 (file)
@@ -67,6 +67,15 @@ static struct expr_node *allocate_unary_variable (struct expression *,
 \f
 /* Public functions. */
 
+static struct expr_node *
+parse_expr (struct lexer *lexer, struct expression *e)
+{
+  struct expr_node *n = parse_or (lexer, e);
+  if (n && n->type == OP_VEC_ELEM_NUM_RAW)
+    n->type = OP_VEC_ELEM_NUM;
+  return n;
+}
+
 /* Parses an expression of the given TYPE.  If DS is nonnull then variables and
    vectors within it may be referenced within the expression; otherwise, the
    expression must not reference any variables or vectors.  Returns the new
@@ -77,7 +86,7 @@ expr_parse (struct lexer *lexer, struct dataset *ds, enum val_type type)
   assert (val_type_is_valid (type));
 
   struct expression *e = expr_create (ds);
-  struct expr_node *n = parse_or (lexer, e);
+  struct expr_node *n = parse_expr (lexer, e);
   if (!n || !type_check (e, n, type))
     {
       expr_free (e);
@@ -92,7 +101,7 @@ struct expression *
 expr_parse_bool (struct lexer *lexer, struct dataset *ds)
 {
   struct expression *e = expr_create (ds);
-  struct expr_node *n = parse_or (lexer, e);
+  struct expr_node *n = parse_expr (lexer, e);
   if (!n)
     {
       expr_free (e);
@@ -124,7 +133,7 @@ expr_parse_new_variable (struct lexer *lexer, struct dataset *ds,
                          const char *new_var_name)
 {
   struct expression *e = expr_create (ds);
-  struct expr_node *n = parse_or (lexer, e);
+  struct expr_node *n = parse_expr (lexer, e);
   if (!n)
     {
       expr_free (e);
@@ -161,7 +170,7 @@ expr_parse_any (struct lexer *lexer, struct dataset *ds, bool optimize)
   struct expression *e;
 
   e = expr_create (ds);
-  n = parse_or (lexer, e);
+  n = parse_expr (lexer, e);
   if (n == NULL)
     {
       expr_free (e);
@@ -198,6 +207,7 @@ atom_type_stack (atom_type type)
     {
     case OP_number:
     case OP_boolean:
+    case OP_num_vec_elem:
       return &on_number_stack;
 
     case OP_string:
@@ -440,6 +450,12 @@ type_coercion__ (struct expression *e, struct expr_node *node, size_t arg_idx,
             *argp = expr_allocate_unary (e, OP_BOOLEAN_TO_NUM, arg);
           return true;
         }
+      else if (actual_type == OP_num_vec_elem)
+        {
+          if (do_coercion)
+            arg->type = OP_VEC_ELEM_NUM;
+          return true;
+        }
       break;
 
     case OP_string:
@@ -1027,7 +1043,7 @@ parse_vector_element (struct lexer *lexer, struct expression *e)
     return NULL;
 
   operation_type type = (vector_get_type (vector) == VAL_NUMERIC
-                         ? OP_VEC_ELEM_NUM : OP_VEC_ELEM_STR);
+                         ? OP_VEC_ELEM_NUM_RAW : OP_VEC_ELEM_STR);
   struct expr_node *node = expr_allocate_binary (
     e, type, element, expr_allocate_vector (e, vector));
   expr_add_location (lexer, e, vector_start_ofs, node);