parser_handle_function.cpp 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  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/parser/parser_context.h"
  5. namespace Carbon {
  6. auto ParserHandleFunctionIntroducer(ParserContext& context) -> void {
  7. auto state = context.PopState();
  8. context.AddLeafNode(ParseNodeKind::FunctionIntroducer, context.Consume());
  9. state.state = ParserState::FunctionAfterParameters;
  10. context.PushState(state);
  11. context.PushState(ParserState::DeclarationNameAndParamsAsRequired,
  12. state.token);
  13. }
  14. auto ParserHandleFunctionAfterParameters(ParserContext& context) -> void {
  15. auto state = context.PopState();
  16. // Regardless of whether there's a return type, we'll finish the signature.
  17. state.state = ParserState::FunctionSignatureFinish;
  18. context.PushState(state);
  19. // If there is a return type, parse the expression before adding the return
  20. // type nod.e
  21. if (context.PositionIs(TokenKind::MinusGreater)) {
  22. context.PushState(ParserState::FunctionReturnTypeFinish);
  23. ++context.position();
  24. context.PushStateForExpression(PrecedenceGroup::ForType());
  25. }
  26. }
  27. auto ParserHandleFunctionReturnTypeFinish(ParserContext& context) -> void {
  28. auto state = context.PopState();
  29. context.AddNode(ParseNodeKind::ReturnType, state.token, state.subtree_start,
  30. state.has_error);
  31. }
  32. auto ParserHandleFunctionSignatureFinish(ParserContext& context) -> void {
  33. auto state = context.PopState();
  34. switch (context.PositionKind()) {
  35. case TokenKind::Semi: {
  36. context.AddNode(ParseNodeKind::FunctionDeclaration, context.Consume(),
  37. state.subtree_start, state.has_error);
  38. break;
  39. }
  40. case TokenKind::OpenCurlyBrace: {
  41. if (auto decl_context = context.GetDeclarationContext();
  42. decl_context == ParserContext::DeclarationContext::Interface ||
  43. decl_context == ParserContext::DeclarationContext::NamedConstraint) {
  44. CARBON_DIAGNOSTIC(
  45. MethodImplNotAllowed, Error,
  46. "Method implementations are not allowed in interfaces.");
  47. context.emitter().Emit(*context.position(), MethodImplNotAllowed);
  48. context.RecoverFromDeclarationError(state,
  49. ParseNodeKind::FunctionDeclaration,
  50. /*skip_past_likely_end=*/true);
  51. break;
  52. }
  53. context.AddNode(ParseNodeKind::FunctionDefinitionStart, context.Consume(),
  54. state.subtree_start, state.has_error);
  55. // Any error is recorded on the FunctionDefinitionStart.
  56. state.has_error = false;
  57. state.state = ParserState::FunctionDefinitionFinish;
  58. context.PushState(state);
  59. context.PushState(ParserState::StatementScopeLoop);
  60. break;
  61. }
  62. default: {
  63. if (!state.has_error) {
  64. context.EmitExpectedDeclarationSemiOrDefinition(TokenKind::Fn);
  65. }
  66. // Only need to skip if we've not already found a new line.
  67. bool skip_past_likely_end =
  68. context.tokens().GetLine(*context.position()) ==
  69. context.tokens().GetLine(state.token);
  70. context.RecoverFromDeclarationError(
  71. state, ParseNodeKind::FunctionDeclaration, skip_past_likely_end);
  72. break;
  73. }
  74. }
  75. }
  76. auto ParserHandleFunctionDefinitionFinish(ParserContext& context) -> void {
  77. auto state = context.PopState();
  78. context.AddNode(ParseNodeKind::FunctionDefinition, context.Consume(),
  79. state.subtree_start, state.has_error);
  80. }
  81. } // namespace Carbon