semantics_ir_factory.cpp 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255
  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/semantics/semantics_ir_factory.h"
  5. #include <stack>
  6. #include "common/check.h"
  7. #include "llvm/ADT/StringMap.h"
  8. #include "llvm/Support/FormatVariadic.h"
  9. #include "toolchain/lexer/token_kind.h"
  10. #include "toolchain/lexer/tokenized_buffer.h"
  11. #include "toolchain/parser/parse_node_kind.h"
  12. //#include "toolchain/semantics/meta_node_block.h"
  13. #include "toolchain/semantics/nodes/binary_operator.h"
  14. #include "toolchain/semantics/parse_subtree_consumer.h"
  15. namespace Carbon {
  16. // The ParseTree is walked in reverse post order, meaning a lot of nodes are
  17. // added in reverse. This fixes that ordering to be the easier to understand
  18. // code ordering.
  19. template <typename T>
  20. static void FixReverseOrdering(T& container) {
  21. std::reverse(container.begin(), container.end());
  22. }
  23. auto SemanticsIRFactory::Build(const TokenizedBuffer& tokens,
  24. const ParseTree& parse_tree) -> SemanticsIR {
  25. SemanticsIRFactory builder(tokens, parse_tree);
  26. builder.Build();
  27. return builder.semantics_;
  28. }
  29. void SemanticsIRFactory::Build() {
  30. auto subtree = ParseSubtreeConsumer::ForTree(parse_tree());
  31. semantics_.root_block_ =
  32. TransformBlockSubtree(subtree, ParseNodeKind::FileEnd());
  33. }
  34. void SemanticsIRFactory::RequireNodeEmpty(ParseTree::Node node) {
  35. auto subtree_size = parse_tree().node_subtree_size(node);
  36. CARBON_CHECK(subtree_size == 1)
  37. << "At index " << node.index() << ", expected "
  38. << parse_tree().node_kind(node)
  39. << "would have subtree_size of 1, but was " << subtree_size;
  40. }
  41. auto SemanticsIRFactory::TransformBlockSubtree(ParseSubtreeConsumer& subtree,
  42. ParseNodeKind end_kind)
  43. -> llvm::SmallVector<Semantics::NodeRef, 0> {
  44. RequireNodeEmpty(subtree.RequireConsume(end_kind));
  45. llvm::SmallVector<Semantics::NodeRef, 0> nodes;
  46. while (llvm::Optional<ParseTree::Node> child = subtree.TryConsume()) {
  47. switch (auto child_kind = parse_tree().node_kind(*child)) {
  48. case ParseNodeKind::FunctionDeclaration(): {
  49. TransformFunctionDeclaration(nodes, *child);
  50. break;
  51. }
  52. // case ParseNodeKind::ExpressionStatement():
  53. // nodes.push_back(TransformExpressionStatement(*child));
  54. // break;
  55. case ParseNodeKind::ReturnStatement():
  56. TransformReturnStatement(nodes, *child);
  57. break;
  58. // case ParseNodeKind::VariableDeclaration():
  59. // // TODO: Handle.
  60. // break;
  61. default:
  62. CARBON_FATAL() << "At index " << child->index() << ", unexpected "
  63. << child_kind;
  64. }
  65. }
  66. FixReverseOrdering(nodes);
  67. return nodes;
  68. }
  69. auto SemanticsIRFactory::TransformCodeBlock(ParseTree::Node node)
  70. -> llvm::SmallVector<Semantics::NodeRef, 0> {
  71. CARBON_CHECK(parse_tree().node_kind(node) == ParseNodeKind::CodeBlock());
  72. auto subtree = ParseSubtreeConsumer::ForParent(parse_tree(), node);
  73. return TransformBlockSubtree(subtree, ParseNodeKind::CodeBlockEnd());
  74. }
  75. void SemanticsIRFactory::TransformDeclaredName(
  76. llvm::SmallVector<Semantics::NodeRef, 0>& nodes, ParseTree::Node node,
  77. Semantics::NodeId target_id) {
  78. CARBON_CHECK(parse_tree().node_kind(node) == ParseNodeKind::DeclaredName());
  79. RequireNodeEmpty(node);
  80. nodes.push_back(semantics_.nodes_.Store(
  81. Semantics::SetName(node, parse_tree().GetNodeText(node), target_id)));
  82. }
  83. void SemanticsIRFactory::TransformExpression(
  84. llvm::SmallVector<Semantics::NodeRef, 0>& nodes, ParseTree::Node node,
  85. Semantics::NodeId target_id) {
  86. switch (auto node_kind = parse_tree().node_kind(node)) {
  87. case ParseNodeKind::Literal(): {
  88. RequireNodeEmpty(node);
  89. auto token = parse_tree().node_token(node);
  90. switch (auto token_kind = tokens_->GetKind(token)) {
  91. case TokenKind::IntegerLiteral(): {
  92. nodes.push_back(semantics_.nodes_.Store(Semantics::IntegerLiteral(
  93. node, target_id, tokens_->GetIntegerLiteral(token))));
  94. break;
  95. }
  96. default:
  97. CARBON_FATAL() << "Unhandled kind: " << token_kind.Name();
  98. }
  99. break;
  100. }
  101. case ParseNodeKind::InfixOperator():
  102. return TransformInfixOperator(nodes, node, target_id);
  103. default:
  104. CARBON_FATAL() << "At index " << node.index() << ", unexpected "
  105. << node_kind;
  106. }
  107. }
  108. /*
  109. auto SemanticsIRFactory::TransformExpressionStatement(ParseTree::Node node)
  110. -> Semantics::Statement {
  111. CARBON_CHECK(parse_tree().node_kind(node) ==
  112. ParseNodeKind::ExpressionStatement());
  113. auto subtree = ParseSubtreeConsumer::ForParent(parse_tree(), node);
  114. RequireNodeEmpty(subtree.RequireConsume(ParseNodeKind::StatementEnd()));
  115. return TransformExpression(subtree.RequireConsume());
  116. }
  117. */
  118. void SemanticsIRFactory::TransformFunctionDeclaration(
  119. llvm::SmallVector<Semantics::NodeRef, 0>& nodes, ParseTree::Node node) {
  120. CARBON_CHECK(parse_tree().node_kind(node) ==
  121. ParseNodeKind::FunctionDeclaration());
  122. auto id = next_id();
  123. auto subtree = ParseSubtreeConsumer::ForParent(parse_tree(), node);
  124. auto body =
  125. TransformCodeBlock(subtree.RequireConsume(ParseNodeKind::CodeBlock()));
  126. // llvm::Optional<Semantics::Statement> return_type_expr;
  127. // if (auto return_type_node =
  128. // subtree.TryConsume(ParseNodeKind::ReturnType())) {
  129. // return_type_expr = TransformReturnType(*return_type_node);
  130. // }
  131. (void)subtree.RequireConsume(ParseNodeKind::ParameterList());
  132. // auto params = TransformParameterList(
  133. // subtree.RequireConsume(ParseNodeKind::ParameterList()));
  134. TransformDeclaredName(
  135. nodes, subtree.RequireConsume(ParseNodeKind::DeclaredName()), id);
  136. nodes.push_back(
  137. semantics_.nodes_.Store(Semantics::Function(node, id, std::move(body))));
  138. }
  139. static auto GetBinaryOp(TokenKind kind) -> Semantics::BinaryOperator::Op {
  140. switch (kind) {
  141. case TokenKind::Plus():
  142. return Semantics::BinaryOperator::Op::Add;
  143. default:
  144. CARBON_FATAL() << "Unrecognized token kind: " << kind.Name();
  145. }
  146. }
  147. void SemanticsIRFactory::TransformInfixOperator(
  148. llvm::SmallVector<Semantics::NodeRef, 0>& nodes, ParseTree::Node node,
  149. Semantics::NodeId target_id) {
  150. CARBON_CHECK(parse_tree().node_kind(node) == ParseNodeKind::InfixOperator());
  151. auto token = parse_tree().node_token(node);
  152. auto token_kind = tokens_->GetKind(token);
  153. auto op = GetBinaryOp(token_kind);
  154. auto rhs_id = next_id();
  155. auto lhs_id = next_id();
  156. nodes.push_back(semantics_.nodes_.Store(
  157. Semantics::BinaryOperator(node, target_id, op, lhs_id, rhs_id)));
  158. auto subtree = ParseSubtreeConsumer::ForParent(parse_tree(), node);
  159. TransformExpression(nodes, subtree.RequireConsume(), rhs_id);
  160. TransformExpression(nodes, subtree.RequireConsume(), lhs_id);
  161. }
  162. /*
  163. auto SemanticsIRFactory::TransformParameterList(ParseTree::Node node)
  164. -> llvm::SmallVector<Semantics::PatternBinding, 0> {
  165. CARBON_CHECK(parse_tree().node_kind(node) ==
  166. ParseNodeKind::ParameterList());
  167. auto subtree = ParseSubtreeConsumer::ForParent(parse_tree(), node);
  168. RequireNodeEmpty(subtree.RequireConsume(ParseNodeKind::ParameterListEnd()));
  169. llvm::SmallVector<Semantics::PatternBinding, 0> params;
  170. if (auto first_param_node =
  171. subtree.TryConsume(ParseNodeKind::PatternBinding())) {
  172. params.push_back(TransformPatternBinding(*first_param_node));
  173. while (auto comma_node =
  174. subtree.TryConsume(ParseNodeKind::ParameterListComma())) {
  175. RequireNodeEmpty(*comma_node);
  176. params.push_back(TransformPatternBinding(
  177. subtree.RequireConsume(ParseNodeKind::PatternBinding())));
  178. }
  179. }
  180. FixReverseOrdering(params);
  181. return params;
  182. }
  183. auto SemanticsIRFactory::TransformPatternBinding(ParseTree::Node node)
  184. -> Semantics::PatternBinding {
  185. CARBON_CHECK(parse_tree().node_kind(node) ==
  186. ParseNodeKind::PatternBinding());
  187. auto subtree = ParseSubtreeConsumer::ForParent(parse_tree(), node);
  188. auto type = TransformExpression(subtree.RequireConsume());
  189. auto name = TransformDeclaredName(
  190. subtree.RequireConsume(ParseNodeKind::DeclaredName()));
  191. return Semantics::PatternBinding(node, name, type);
  192. }
  193. */
  194. void SemanticsIRFactory::TransformReturnStatement(
  195. llvm::SmallVector<Semantics::NodeRef, 0>& nodes, ParseTree::Node node) {
  196. CARBON_CHECK(parse_tree().node_kind(node) ==
  197. ParseNodeKind::ReturnStatement());
  198. auto subtree = ParseSubtreeConsumer::ForParent(parse_tree(), node);
  199. RequireNodeEmpty(subtree.RequireConsume(ParseNodeKind::StatementEnd()));
  200. auto expr = subtree.TryConsume();
  201. if (expr) {
  202. // return expr;
  203. auto id = next_id();
  204. nodes.push_back(semantics_.nodes_.Store(Semantics::Return(node, id)));
  205. TransformExpression(nodes, *expr, id);
  206. } else {
  207. // return;
  208. nodes.push_back(
  209. semantics_.nodes_.Store(Semantics::Return(node, llvm::None)));
  210. }
  211. }
  212. /*
  213. auto SemanticsIRFactory::TransformReturnType(ParseTree::Node node)
  214. -> Semantics::Statement {
  215. CARBON_CHECK(parse_tree().node_kind(node) == ParseNodeKind::ReturnType());
  216. auto subtree = ParseSubtreeConsumer::ForParent(parse_tree(), node);
  217. return TransformExpression(subtree.RequireConsume());
  218. }
  219. */
  220. } // namespace Carbon