Forráskód Böngészése

Support `p->member`, rewriting it to `(*p).member` in the parser. (#2455)

* Support `p->member`, rewriting it to `(*p).member` in the parser.

This behavior is as described in
https://github.com/carbon-language/carbon-lang/tree/trunk/docs/design#pointer-types:

> `p->m` is syntactic sugar for `(*p).m`.
Richard Smith 3 éve
szülő
commit
0ef7fa3a1d

+ 16 - 0
explorer/syntax/parser.ypp

@@ -395,11 +395,27 @@ postfix_expression:
       $$ = arena->New<SimpleMemberAccessExpression>(context.source_loc(), $1,
                                                     $2);
     }
+| postfix_expression ARROW identifier
+    {
+      auto deref = arena->New<OperatorExpression>(
+          context.source_loc(), Operator::Deref,
+          std::vector<Nonnull<Expression*>>({$1}));
+      $$ = arena->New<SimpleMemberAccessExpression>(context.source_loc(), deref,
+                                                    $3);
+    }
 | postfix_expression PERIOD LEFT_PARENTHESIS expression RIGHT_PARENTHESIS
     {
       $$ = arena->New<CompoundMemberAccessExpression>(context.source_loc(), $1,
                                                       $4);
     }
+| postfix_expression ARROW LEFT_PARENTHESIS expression RIGHT_PARENTHESIS
+    {
+      auto deref = arena->New<OperatorExpression>(
+          context.source_loc(), Operator::Deref,
+          std::vector<Nonnull<Expression*>>({$1}));
+      $$ = arena->New<CompoundMemberAccessExpression>(context.source_loc(),
+                                                      deref, $4);
+    }
 | postfix_expression LEFT_SQUARE_BRACKET expression RIGHT_SQUARE_BRACKET
     { $$ = arena->New<IndexExpression>(context.source_loc(), $1, $3); }
 | intrinsic_identifier tuple

+ 27 - 0
explorer/testdata/member_access/arrow.carbon

@@ -0,0 +1,27 @@
+// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
+// Exceptions. See /LICENSE for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+// AUTOUPDATE
+// RUN: %{explorer-run}
+// RUN: %{explorer-run-trace}
+// CHECK:STDOUT: 1
+// CHECK:STDOUT: 1
+// CHECK:STDOUT: 1
+// CHECK:STDOUT: 1
+// CHECK:STDOUT: result: 0
+
+package Foo api;
+class X {
+  fn F[self: Self]() -> i32 { return self.n; }
+  var n: i32;
+}
+fn Main() -> i32 {
+  var v: X = {.n = 1};
+  let p: X* = &v;
+  Print("{0}", p->n);
+  Print("{0}", p->(X.n));
+  Print("{0}", p->F());
+  Print("{0}", p->(X.F)());
+  return 0;
+}