handle_observe.cpp 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. // Part of the Carbon Language project, under the Apache License v2.0 with LLVM
  2. // Exceptions. See /LICENSE for license information.
  3. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  4. #include "toolchain/lex/token_kind.h"
  5. #include "toolchain/parse/context.h"
  6. #include "toolchain/parse/handle.h"
  7. #include "toolchain/parse/node_kind.h"
  8. #include "toolchain/parse/precedence.h"
  9. #include "toolchain/parse/state.h"
  10. #include "toolchain/parse/typed_nodes.h"
  11. namespace Carbon::Parse {
  12. auto HandleObserveAfterIntroducer(Context& context) -> void {
  13. auto state = context.PopState();
  14. context.PushState(state, StateKind::ObserveOperator);
  15. context.PushStateForExpr(PrecedenceGroup::ForRequirements());
  16. }
  17. auto HandleObserveOperator(Context& context) -> void {
  18. auto state = context.PopState();
  19. switch (context.PositionKind()) {
  20. case Lex::TokenKind::EqualEqual: {
  21. state.token = context.Consume();
  22. context.PushState(state, StateKind::ObserveFinishOperator);
  23. context.PushStateForExpr(PrecedenceGroup::ForRequirements());
  24. return;
  25. }
  26. case Lex::TokenKind::Impls: {
  27. state.token = context.Consume();
  28. context.PushState(state, StateKind::ObserveFinishOperator);
  29. context.PushState(StateKind::Expr);
  30. return;
  31. }
  32. default: {
  33. if (!state.has_error) {
  34. CARBON_DIAGNOSTIC(ExpectedObserveOperator, Error,
  35. "observe should use `==` or `impls` operator");
  36. context.emitter().Emit(*context.position(), ExpectedObserveOperator);
  37. }
  38. context.RecoverFromDeclError(state, NodeKind::ObserveDecl,
  39. /*skip_past_likely_end=*/true);
  40. return;
  41. }
  42. }
  43. }
  44. auto HandleObserveFinishOperator(Context& context) -> void {
  45. auto state = context.PopState();
  46. auto token_kind = context.tokens().GetKind(state.token);
  47. if (token_kind == Lex::TokenKind::EqualEqual) {
  48. context.AddNode(NodeKind::ObserveEqualEqual, state.token, state.has_error);
  49. } else {
  50. context.AddNode(NodeKind::ObserveImpls, state.token, state.has_error);
  51. }
  52. if (context.PositionIs(Lex::TokenKind::Semi)) {
  53. context.PushState(state, StateKind::ObserveDecl);
  54. } else {
  55. context.PushState(state, StateKind::ObserveOperator);
  56. }
  57. }
  58. auto HandleObserveDecl(Context& context) -> void {
  59. auto state = context.PopState();
  60. context.AddNodeExpectingDeclSemi(state, NodeKind::ObserveDecl,
  61. Lex::TokenKind::Observe,
  62. /*is_def_allowed=*/false);
  63. }
  64. } // namespace Carbon::Parse