Add inclusive range support for Rust
[deliverable/binutils-gdb.git] / gdb / rust-exp.y
index b661a803e31af5263cb6bebb7026e5cf87adbccd..56aa689a08b7f6ff0a36b514291bc50361a94e38 100644 (file)
@@ -111,7 +111,8 @@ static const struct rust_op *ast_string (struct stoken str);
 static const struct rust_op *ast_struct (const struct rust_op *name,
                                         rust_set_vector *fields);
 static const struct rust_op *ast_range (const struct rust_op *lhs,
-                                       const struct rust_op *rhs);
+                                       const struct rust_op *rhs,
+                                       bool inclusive);
 static const struct rust_op *ast_array_type (const struct rust_op *lhs,
                                             struct typed_val_int val);
 static const struct rust_op *ast_slice_type (const struct rust_op *type);
@@ -300,6 +301,9 @@ struct rust_op
      name occurred at the end of the expression and is eligible for
      completion.  */
   unsigned int completing : 1;
+  /* For OP_RANGE, indicates whether the range is inclusive or
+     exclusive.  */
+  unsigned int inclusive : 1;
   /* Operands of expression.  Which one is used and how depends on the
      particular opcode.  */
   RUSTSTYPE left;
@@ -333,6 +337,7 @@ struct rust_op
 
 /* Operator tokens.  */
 %token <voidval> DOTDOT
+%token <voidval> DOTDOTEQ
 %token <voidval> OROR
 %token <voidval> ANDAND
 %token <voidval> EQEQ
@@ -382,7 +387,7 @@ struct rust_op
 %type <one_field_init> struct_expr_tail
 
 /* Precedence.  */
-%nonassoc DOTDOT
+%nonassoc DOTDOT DOTDOTEQ
 %right '=' COMPOUND_ASSIGN
 %left OROR
 %left ANDAND
@@ -535,13 +540,17 @@ array_expr:
 
 range_expr:
        expr DOTDOT
-               { $$ = ast_range ($1, NULL); }
+               { $$ = ast_range ($1, NULL, false); }
 |      expr DOTDOT expr
-               { $$ = ast_range ($1, $3); }
+               { $$ = ast_range ($1, $3, false); }
+|      expr DOTDOTEQ expr
+               { $$ = ast_range ($1, $3, true); }
 |      DOTDOT expr
-               { $$ = ast_range (NULL, $2); }
+               { $$ = ast_range (NULL, $2, false); }
+|      DOTDOTEQ expr
+               { $$ = ast_range (NULL, $2, true); }
 |      DOTDOT
-               { $$ = ast_range (NULL, NULL); }
+               { $$ = ast_range (NULL, NULL, false); }
 ;
 
 literal:
@@ -956,6 +965,7 @@ static const struct token_info operator_tokens[] =
   { "&=", COMPOUND_ASSIGN, BINOP_BITWISE_AND },
   { "|=", COMPOUND_ASSIGN, BINOP_BITWISE_IOR },
   { "^=", COMPOUND_ASSIGN, BINOP_BITWISE_XOR },
+  { "..=", DOTDOTEQ, OP_NULL },
 
   { "::", COLONCOLON, OP_NULL },
   { "..", DOTDOT, OP_NULL },
@@ -1841,11 +1851,13 @@ ast_structop_anonymous (const struct rust_op *left,
 /* Make a range operation.  */
 
 static const struct rust_op *
-ast_range (const struct rust_op *lhs, const struct rust_op *rhs)
+ast_range (const struct rust_op *lhs, const struct rust_op *rhs,
+          bool inclusive)
 {
   struct rust_op *result = OBSTACK_ZALLOC (work_obstack, struct rust_op);
 
   result->opcode = OP_RANGE;
+  result->inclusive = inclusive;
   result->left.op = lhs;
   result->right.op = rhs;
 
@@ -2473,13 +2485,22 @@ convert_ast_to_expression (struct parser_state *state,
          {
            convert_ast_to_expression (state, operation->right.op, top);
            if (kind == BOTH_BOUND_DEFAULT)
-             kind = LOW_BOUND_DEFAULT;
+             kind = (operation->inclusive
+                     ? LOW_BOUND_DEFAULT : LOW_BOUND_DEFAULT_EXCLUSIVE);
            else
              {
                gdb_assert (kind == HIGH_BOUND_DEFAULT);
-               kind = NONE_BOUND_DEFAULT;
+               kind = (operation->inclusive
+                       ? NONE_BOUND_DEFAULT : NONE_BOUND_DEFAULT_EXCLUSIVE);
              }
          }
+       else
+         {
+           /* Nothing should make an inclusive range without an upper
+              bound.  */
+           gdb_assert (!operation->inclusive);
+         }
+
        write_exp_elt_opcode (state, OP_RANGE);
        write_exp_elt_longcst (state, kind);
        write_exp_elt_opcode (state, OP_RANGE);
This page took 0.029778 seconds and 4 git commands to generate.