Преглед изворни кода

Refactor SemanticsIR switch cases into functions. (#2326)

Proactively trying to avoid the large switch case problem.
Jon Ross-Perkins пре 3 година
родитељ
комит
64850e66bf
2 измењених фајлова са 101 додато и 60 уклоњено
  1. 92 60
      toolchain/semantics/semantics_ir_factory.cpp
  2. 9 0
      toolchain/semantics/semantics_ir_factory.h

+ 92 - 60
toolchain/semantics/semantics_ir_factory.cpp

@@ -26,30 +26,15 @@ void SemanticsIRFactory::Build() {
     auto parse_node = *it;
     switch (auto parse_kind = parse_tree().node_kind(parse_node)) {
       case ParseNodeKind::DeclaredName(): {
-        auto text = parse_tree().GetNodeText(parse_node);
-        auto identifier_id = semantics_.AddIdentifier(text);
-        Push(parse_node, SemanticsNode::MakeIdentifier(identifier_id));
+        HandleDeclaredName(parse_node);
         break;
       }
       case ParseNodeKind::FunctionDefinition(): {
-        // Merges code block children up under the FunctionDefinitionStart.
-        while (parse_tree().node_kind(node_stack_.back().parse_node) !=
-               ParseNodeKind::FunctionDefinitionStart()) {
-          node_stack_.pop_back();
-        }
-        Pop(ParseNodeKind::FunctionDefinitionStart());
-        semantics_.AddNode(SemanticsNode::MakeFunctionDefinitionEnd());
-        Push(parse_node);
+        HandleFunctionDefinition(parse_node);
         break;
       }
       case ParseNodeKind::FunctionDefinitionStart(): {
-        Pop(ParseNodeKind::ParameterList());
-        auto name_node_id = PopWithResult(ParseNodeKind::DeclaredName());
-        Pop(ParseNodeKind::FunctionIntroducer());
-        auto decl_id = semantics_.AddNode(
-            SemanticsNode::MakeFunctionDeclaration(name_node_id));
-        semantics_.AddNode(SemanticsNode::MakeFunctionDefinitionStart(decl_id));
-        Push(parse_node);
+        HandleFunctionDefinitionStart(parse_node);
         break;
       }
       case ParseNodeKind::FileEnd(): {
@@ -60,55 +45,19 @@ void SemanticsIRFactory::Build() {
         return;
       }
       case ParseNodeKind::InfixOperator(): {
-        auto rhs_id = PopWithResult();
-        auto lhs_id = PopWithResult();
-
-        // Figure out the operator for the token.
-        auto token = parse_tree().node_token(parse_node);
-        switch (auto token_kind = tokens_->GetKind(token)) {
-          case TokenKind::Plus():
-            Push(parse_node,
-                 SemanticsNode::MakeBinaryOperatorAdd(lhs_id, rhs_id));
-            break;
-          default:
-            CARBON_FATAL() << "Unrecognized token kind: " << token_kind.Name();
-        }
+        HandleInfixOperator(parse_node);
         break;
       }
       case ParseNodeKind::Literal(): {
-        auto token = parse_tree().node_token(parse_node);
-        switch (auto token_kind = tokens_->GetKind(token)) {
-          case TokenKind::IntegerLiteral(): {
-            auto id =
-                semantics_.AddIntegerLiteral(tokens_->GetIntegerLiteral(token));
-            Push(parse_node, SemanticsNode::MakeIntegerLiteral(id));
-            break;
-          }
-          default:
-            CARBON_FATAL() << "Unhandled kind: " << token_kind.Name();
-        }
+        HandleLiteral(parse_node);
         break;
       }
-      case ParseNodeKind::ReturnStatement(): {
-        Pop(ParseNodeKind::StatementEnd());
-
-        // TODO: Restructure ReturnStatement so that we can do this without
-        // looking at the subtree size.
-        if (parse_tree().node_subtree_size(parse_node) == 2) {
-          Push(parse_node, SemanticsNode::MakeReturn());
-        } else {
-          auto arg = PopWithResult();
-          Push(parse_node, SemanticsNode::MakeReturnExpression(arg));
-        }
+      case ParseNodeKind::ParameterList(): {
+        HandleParameterList(parse_node);
         break;
       }
-      case ParseNodeKind::ParameterList(): {
-        // TODO: This should transform into a usable parameter list. For now
-        // it's unused and only stored so that node counts match.
-        // TODO: Reorder with ParameterListStart so that we can traverse without
-        // subtree_size.
-        Pop(ParseNodeKind::ParameterListEnd());
-        Push(parse_node);
+      case ParseNodeKind::ReturnStatement(): {
+        HandleReturnStatement(parse_node);
         break;
       }
       case ParseNodeKind::FunctionIntroducer():
@@ -127,4 +76,87 @@ void SemanticsIRFactory::Build() {
   llvm_unreachable("Should always end at FileEnd");
 }
 
+auto SemanticsIRFactory::HandleDeclaredName(ParseTree::Node parse_node)
+    -> void {
+  auto text = parse_tree().GetNodeText(parse_node);
+  auto identifier_id = semantics_.AddIdentifier(text);
+  Push(parse_node, SemanticsNode::MakeIdentifier(identifier_id));
+}
+
+auto SemanticsIRFactory::HandleFunctionDefinition(ParseTree::Node parse_node)
+    -> void {
+  // Merges code block children up under the FunctionDefinitionStart.
+  while (parse_tree().node_kind(node_stack_.back().parse_node) !=
+         ParseNodeKind::FunctionDefinitionStart()) {
+    node_stack_.pop_back();
+  }
+  Pop(ParseNodeKind::FunctionDefinitionStart());
+  semantics_.AddNode(SemanticsNode::MakeFunctionDefinitionEnd());
+  Push(parse_node);
+}
+
+auto SemanticsIRFactory::HandleFunctionDefinitionStart(
+    ParseTree::Node parse_node) -> void {
+  Pop(ParseNodeKind::ParameterList());
+  auto name_node_id = PopWithResult(ParseNodeKind::DeclaredName());
+  Pop(ParseNodeKind::FunctionIntroducer());
+  auto decl_id =
+      semantics_.AddNode(SemanticsNode::MakeFunctionDeclaration(name_node_id));
+  semantics_.AddNode(SemanticsNode::MakeFunctionDefinitionStart(decl_id));
+  Push(parse_node);
+}
+
+auto SemanticsIRFactory::HandleInfixOperator(ParseTree::Node parse_node)
+    -> void {
+  auto rhs_id = PopWithResult();
+  auto lhs_id = PopWithResult();
+
+  // Figure out the operator for the token.
+  auto token = parse_tree().node_token(parse_node);
+  switch (auto token_kind = tokens_->GetKind(token)) {
+    case TokenKind::Plus():
+      Push(parse_node, SemanticsNode::MakeBinaryOperatorAdd(lhs_id, rhs_id));
+      break;
+    default:
+      CARBON_FATAL() << "Unrecognized token kind: " << token_kind.Name();
+  }
+}
+
+auto SemanticsIRFactory::HandleLiteral(ParseTree::Node parse_node) -> void {
+  auto token = parse_tree().node_token(parse_node);
+  switch (auto token_kind = tokens_->GetKind(token)) {
+    case TokenKind::IntegerLiteral(): {
+      auto id = semantics_.AddIntegerLiteral(tokens_->GetIntegerLiteral(token));
+      Push(parse_node, SemanticsNode::MakeIntegerLiteral(id));
+      break;
+    }
+    default:
+      CARBON_FATAL() << "Unhandled kind: " << token_kind.Name();
+  }
+}
+
+auto SemanticsIRFactory::HandleParameterList(ParseTree::Node parse_node)
+    -> void {
+  // TODO: This should transform into a usable parameter list. For now
+  // it's unused and only stored so that node counts match.
+  // TODO: Reorder with ParameterListStart so that we can traverse without
+  // subtree_size.
+  Pop(ParseNodeKind::ParameterListEnd());
+  Push(parse_node);
+}
+
+auto SemanticsIRFactory::HandleReturnStatement(ParseTree::Node parse_node)
+    -> void {
+  Pop(ParseNodeKind::StatementEnd());
+
+  // TODO: Restructure ReturnStatement so that we can do this without
+  // looking at the subtree size.
+  if (parse_tree().node_subtree_size(parse_node) == 2) {
+    Push(parse_node, SemanticsNode::MakeReturn());
+  } else {
+    auto arg = PopWithResult();
+    Push(parse_node, SemanticsNode::MakeReturnExpression(arg));
+  }
+}
+
 }  // namespace Carbon

+ 9 - 0
toolchain/semantics/semantics_ir_factory.h

@@ -65,6 +65,15 @@ class SemanticsIRFactory {
     return node_id;
   }
 
+  // Parse node handlers.
+  auto HandleDeclaredName(ParseTree::Node parse_node) -> void;
+  auto HandleFunctionDefinition(ParseTree::Node parse_node) -> void;
+  auto HandleFunctionDefinitionStart(ParseTree::Node parse_node) -> void;
+  auto HandleInfixOperator(ParseTree::Node parse_node) -> void;
+  auto HandleLiteral(ParseTree::Node parse_node) -> void;
+  auto HandleParameterList(ParseTree::Node parse_node) -> void;
+  auto HandleReturnStatement(ParseTree::Node parse_node) -> void;
+
   // Convenience accessor.
   auto parse_tree() -> const ParseTree& { return *semantics_.parse_tree_; }