handle_choice.cpp 3.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  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/parse/context.h"
  5. namespace Carbon::Parse {
  6. auto HandleChoiceIntroducer(Context& context) -> void {
  7. auto state = context.PopState();
  8. context.PushState(state, State::ChoiceDefinitionStart);
  9. context.PushState(State::DeclNameAndParamsAsOptional, state.token);
  10. }
  11. auto HandleChoiceDefinitionStart(Context& context) -> void {
  12. auto state = context.PopState();
  13. if (!context.PositionIs(Lex::TokenKind::OpenCurlyBrace)) {
  14. if (!state.has_error) {
  15. CARBON_DIAGNOSTIC(ExpectedChoiceDefinition, Error,
  16. "Choice definition expected.");
  17. context.emitter().Emit(*context.position(), ExpectedChoiceDefinition);
  18. }
  19. context.AddNode(NodeKind::ChoiceDefinitionStart, *context.position(),
  20. state.subtree_start, /*has_error=*/true);
  21. context.AddNode(NodeKind::ChoiceDefinition, *context.position(),
  22. state.subtree_start, /*has_error=*/true);
  23. context.SkipPastLikelyEnd(*context.position());
  24. return;
  25. }
  26. context.AddNode(NodeKind::ChoiceDefinitionStart, context.Consume(),
  27. state.subtree_start, state.has_error);
  28. state.has_error = false;
  29. state.state = State::ChoiceDefinitionFinish;
  30. context.PushState(state);
  31. if (!context.PositionIs(Lex::TokenKind::CloseCurlyBrace)) {
  32. context.PushState(State::ChoiceAlternative);
  33. }
  34. }
  35. auto HandleChoiceAlternative(Context& context) -> void {
  36. auto state = context.PopState();
  37. context.PushState(State::ChoiceAlternativeFinish);
  38. if (!context.ConsumeAndAddLeafNodeIf(Lex::TokenKind::Identifier,
  39. NodeKind::IdentifierName)) {
  40. if (!state.has_error) {
  41. CARBON_DIAGNOSTIC(ExpectedChoiceAlternativeName, Error,
  42. "Expected choice alternative name.");
  43. context.emitter().Emit(*context.position(),
  44. ExpectedChoiceAlternativeName);
  45. }
  46. context.SkipPastLikelyEnd(*context.position());
  47. context.ReturnErrorOnState();
  48. return;
  49. }
  50. if (context.PositionIs(Lex::TokenKind::OpenParen)) {
  51. context.PushState(State::PatternListAsTuple);
  52. }
  53. }
  54. auto HandleChoiceAlternativeFinish(Context& context) -> void {
  55. const auto state = context.PopState();
  56. if (state.has_error) {
  57. context.ReturnErrorOnState();
  58. if (!context.PositionIs(Lex::TokenKind::CloseCurlyBrace)) {
  59. context.PushState(State::ChoiceAlternative);
  60. }
  61. return;
  62. }
  63. if (context.ConsumeListToken(
  64. NodeKind::ChoiceAlternativeListComma, Lex::TokenKind::CloseCurlyBrace,
  65. state.has_error) == Context::ListTokenKind::Comma) {
  66. context.PushState(State::ChoiceAlternative);
  67. }
  68. }
  69. auto HandleChoiceDefinitionFinish(Context& context) -> void {
  70. const auto state = context.PopState();
  71. context.AddNode(NodeKind::ChoiceDefinition,
  72. context.ConsumeChecked(Lex::TokenKind::CloseCurlyBrace),
  73. state.subtree_start, state.has_error);
  74. }
  75. } // namespace Carbon::Parse