|
|
@@ -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
|