semantics_handle.cpp 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671
  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_context.h"
  5. #include "toolchain/semantics/semantics_node.h"
  6. namespace Carbon {
  7. auto SemanticsHandleAddress(SemanticsContext& context,
  8. ParseTree::Node parse_node) -> bool {
  9. return context.TODO(parse_node, "HandleAddress");
  10. }
  11. auto SemanticsHandleBreakStatement(SemanticsContext& context,
  12. ParseTree::Node parse_node) -> bool {
  13. return context.TODO(parse_node, "HandleBreakStatement");
  14. }
  15. auto SemanticsHandleBreakStatementStart(SemanticsContext& context,
  16. ParseTree::Node parse_node) -> bool {
  17. return context.TODO(parse_node, "HandleBreakStatementStart");
  18. }
  19. auto SemanticsHandleCodeBlock(SemanticsContext& context,
  20. ParseTree::Node parse_node) -> bool {
  21. return context.TODO(parse_node, "HandleCodeBlock");
  22. }
  23. auto SemanticsHandleCodeBlockStart(SemanticsContext& context,
  24. ParseTree::Node parse_node) -> bool {
  25. return context.TODO(parse_node, "HandleCodeBlockStart");
  26. }
  27. auto SemanticsHandleContinueStatement(SemanticsContext& context,
  28. ParseTree::Node parse_node) -> bool {
  29. return context.TODO(parse_node, "HandleContinueStatement");
  30. }
  31. auto SemanticsHandleContinueStatementStart(SemanticsContext& context,
  32. ParseTree::Node parse_node) -> bool {
  33. return context.TODO(parse_node, "HandleContinueStatementStart");
  34. }
  35. auto SemanticsHandleDeclaredName(SemanticsContext& context,
  36. ParseTree::Node parse_node) -> bool {
  37. // The parent is responsible for binding the name.
  38. context.node_stack().Push(parse_node);
  39. return true;
  40. }
  41. auto SemanticsHandleDeducedParameterList(SemanticsContext& context,
  42. ParseTree::Node parse_node) -> bool {
  43. return context.TODO(parse_node, "HandleDeducedParameterList");
  44. }
  45. auto SemanticsHandleDeducedParameterListStart(SemanticsContext& context,
  46. ParseTree::Node parse_node)
  47. -> bool {
  48. return context.TODO(parse_node, "HandleDeducedParameterListStart");
  49. }
  50. auto SemanticsHandleDesignatedName(SemanticsContext& context,
  51. ParseTree::Node parse_node) -> bool {
  52. auto name_str = context.parse_tree().GetNodeText(parse_node);
  53. auto name_id = context.semantics_ir().AddString(name_str);
  54. // The parent is responsible for binding the name.
  55. context.node_stack().Push(parse_node, name_id);
  56. return true;
  57. }
  58. auto SemanticsHandleDesignatorExpression(SemanticsContext& context,
  59. ParseTree::Node parse_node) -> bool {
  60. auto name_id = context.node_stack().Pop<SemanticsStringId>(
  61. ParseNodeKind::DesignatedName);
  62. auto base_id = context.node_stack().Pop<SemanticsNodeId>();
  63. auto base = context.semantics_ir().GetNode(base_id);
  64. auto base_type = context.semantics_ir().GetNode(
  65. context.semantics_ir().GetType(base.type_id()));
  66. switch (base_type.kind()) {
  67. case SemanticsNodeKind::StructType: {
  68. auto refs =
  69. context.semantics_ir().GetNodeBlock(base_type.GetAsStructType());
  70. // TODO: Do we need to optimize this with a lookup table for O(1)?
  71. for (int i = 0; i < static_cast<int>(refs.size()); ++i) {
  72. auto ref = context.semantics_ir().GetNode(refs[i]);
  73. if (name_id == ref.GetAsStructTypeField()) {
  74. context.AddNodeAndPush(
  75. parse_node,
  76. SemanticsNode::StructMemberAccess::Make(
  77. parse_node, ref.type_id(), base_id, SemanticsMemberIndex(i)));
  78. return true;
  79. }
  80. }
  81. CARBON_DIAGNOSTIC(DesignatorExpressionNameNotFound, Error,
  82. "Type `{0}` does not have a member `{1}`.", std::string,
  83. llvm::StringRef);
  84. context.emitter().Emit(
  85. parse_node, DesignatorExpressionNameNotFound,
  86. context.semantics_ir().StringifyType(base.type_id()),
  87. context.semantics_ir().GetString(name_id));
  88. break;
  89. }
  90. default: {
  91. CARBON_DIAGNOSTIC(DesignatorExpressionUnsupported, Error,
  92. "Type `{0}` does not support designator expressions.",
  93. std::string);
  94. context.emitter().Emit(
  95. parse_node, DesignatorExpressionUnsupported,
  96. context.semantics_ir().StringifyType(base.type_id()));
  97. break;
  98. }
  99. }
  100. // Should only be reached on error.
  101. context.node_stack().Push(parse_node, SemanticsNodeId::BuiltinInvalidType);
  102. return true;
  103. }
  104. auto SemanticsHandleEmptyDeclaration(SemanticsContext& context,
  105. ParseTree::Node parse_node) -> bool {
  106. // Empty declarations have no actions associated, but we still balance the
  107. // tree.
  108. context.node_stack().Push(parse_node);
  109. return true;
  110. }
  111. auto SemanticsHandleExpressionStatement(SemanticsContext& context,
  112. ParseTree::Node parse_node) -> bool {
  113. // Pop the expression without investigating its contents.
  114. // TODO: This will probably eventually need to do some "do not discard"
  115. // analysis.
  116. context.node_stack().PopAndDiscardId();
  117. context.node_stack().Push(parse_node);
  118. return true;
  119. }
  120. auto SemanticsHandleFileEnd(SemanticsContext& /*context*/,
  121. ParseTree::Node /*parse_node*/) -> bool {
  122. // Do nothing, no need to balance this node.
  123. return true;
  124. }
  125. auto SemanticsHandleForHeader(SemanticsContext& context,
  126. ParseTree::Node parse_node) -> bool {
  127. return context.TODO(parse_node, "HandleForHeader");
  128. }
  129. auto SemanticsHandleForHeaderStart(SemanticsContext& context,
  130. ParseTree::Node parse_node) -> bool {
  131. return context.TODO(parse_node, "HandleForHeaderStart");
  132. }
  133. auto SemanticsHandleForIn(SemanticsContext& context, ParseTree::Node parse_node)
  134. -> bool {
  135. return context.TODO(parse_node, "HandleForIn");
  136. }
  137. auto SemanticsHandleForStatement(SemanticsContext& context,
  138. ParseTree::Node parse_node) -> bool {
  139. return context.TODO(parse_node, "HandleForStatement");
  140. }
  141. auto SemanticsHandleGenericPatternBinding(SemanticsContext& context,
  142. ParseTree::Node parse_node) -> bool {
  143. return context.TODO(parse_node, "GenericPatternBinding");
  144. }
  145. auto SemanticsHandleIfCondition(SemanticsContext& context,
  146. ParseTree::Node parse_node) -> bool {
  147. return context.TODO(parse_node, "HandleIfCondition");
  148. }
  149. auto SemanticsHandleIfConditionStart(SemanticsContext& context,
  150. ParseTree::Node parse_node) -> bool {
  151. return context.TODO(parse_node, "HandleIfConditionStart");
  152. }
  153. auto SemanticsHandleIfStatement(SemanticsContext& context,
  154. ParseTree::Node parse_node) -> bool {
  155. return context.TODO(parse_node, "HandleIfStatement");
  156. }
  157. auto SemanticsHandleIfStatementElse(SemanticsContext& context,
  158. ParseTree::Node parse_node) -> bool {
  159. return context.TODO(parse_node, "HandleIfStatementElse");
  160. }
  161. auto SemanticsHandleInfixOperator(SemanticsContext& context,
  162. ParseTree::Node parse_node) -> bool {
  163. auto rhs_id = context.node_stack().Pop<SemanticsNodeId>();
  164. auto lhs_id = context.node_stack().Pop<SemanticsNodeId>();
  165. // Figure out the operator for the token.
  166. auto token = context.parse_tree().node_token(parse_node);
  167. switch (auto token_kind = context.tokens().GetKind(token)) {
  168. case TokenKind::Plus:
  169. // TODO: This should search for a compatible interface. For now, it's a
  170. // very trivial check of validity on the operation.
  171. lhs_id = context.ImplicitAsRequired(
  172. parse_node, lhs_id, context.semantics_ir().GetNode(rhs_id).type_id());
  173. context.AddNodeAndPush(
  174. parse_node,
  175. SemanticsNode::BinaryOperatorAdd::Make(
  176. parse_node, context.semantics_ir().GetNode(lhs_id).type_id(),
  177. lhs_id, rhs_id));
  178. break;
  179. case TokenKind::And:
  180. case TokenKind::Or: {
  181. // The first operand is wrapped in a ShortCircuitOperand, which we
  182. // already handled by creating a RHS block and a resumption block, which
  183. // are the current block and its enclosing block.
  184. rhs_id = context.ImplicitAsBool(parse_node, rhs_id);
  185. // When the second operand is evaluated, the result of `and` and `or` is
  186. // its value.
  187. auto rhs_block_id = context.node_block_stack().PopForAdd();
  188. auto resume_block_id = context.node_block_stack().PeekForAdd();
  189. context.AddNodeToBlock(rhs_block_id,
  190. SemanticsNode::BranchWithArg::Make(
  191. parse_node, resume_block_id, rhs_id));
  192. // Collect the result from either the first or second operand.
  193. context.AddNodeAndPush(
  194. parse_node,
  195. SemanticsNode::BlockArg::Make(
  196. parse_node, context.semantics_ir().GetNode(rhs_id).type_id(),
  197. resume_block_id));
  198. break;
  199. }
  200. default:
  201. return context.TODO(parse_node, llvm::formatv("Handle {0}", token_kind));
  202. }
  203. return true;
  204. }
  205. auto SemanticsHandleInvalidParse(SemanticsContext& context,
  206. ParseTree::Node parse_node) -> bool {
  207. return context.TODO(parse_node, "HandleInvalidParse");
  208. }
  209. auto SemanticsHandleLiteral(SemanticsContext& context,
  210. ParseTree::Node parse_node) -> bool {
  211. auto token = context.parse_tree().node_token(parse_node);
  212. switch (auto token_kind = context.tokens().GetKind(token)) {
  213. case TokenKind::False:
  214. case TokenKind::True: {
  215. context.AddNodeAndPush(
  216. parse_node,
  217. SemanticsNode::BoolLiteral::Make(
  218. parse_node,
  219. context.CanonicalizeType(SemanticsNodeId::BuiltinBoolType),
  220. token_kind == TokenKind::True ? SemanticsBoolValue::True
  221. : SemanticsBoolValue::False));
  222. break;
  223. }
  224. case TokenKind::IntegerLiteral: {
  225. auto id = context.semantics_ir().AddIntegerLiteral(
  226. context.tokens().GetIntegerLiteral(token));
  227. context.AddNodeAndPush(
  228. parse_node,
  229. SemanticsNode::IntegerLiteral::Make(
  230. parse_node,
  231. context.CanonicalizeType(SemanticsNodeId::BuiltinIntegerType),
  232. id));
  233. break;
  234. }
  235. case TokenKind::RealLiteral: {
  236. auto token_value = context.tokens().GetRealLiteral(token);
  237. auto id = context.semantics_ir().AddRealLiteral(
  238. {.mantissa = token_value.Mantissa(),
  239. .exponent = token_value.Exponent(),
  240. .is_decimal = token_value.IsDecimal()});
  241. context.AddNodeAndPush(parse_node,
  242. SemanticsNode::RealLiteral::Make(
  243. parse_node,
  244. context.CanonicalizeType(
  245. SemanticsNodeId::BuiltinFloatingPointType),
  246. id));
  247. break;
  248. }
  249. case TokenKind::StringLiteral: {
  250. auto id = context.semantics_ir().AddString(
  251. context.tokens().GetStringLiteral(token));
  252. context.AddNodeAndPush(
  253. parse_node,
  254. SemanticsNode::StringLiteral::Make(
  255. parse_node,
  256. context.CanonicalizeType(SemanticsNodeId::BuiltinStringType),
  257. id));
  258. break;
  259. }
  260. case TokenKind::Bool: {
  261. context.node_stack().Push(parse_node, SemanticsNodeId::BuiltinBoolType);
  262. break;
  263. }
  264. case TokenKind::IntegerTypeLiteral: {
  265. auto text = context.tokens().GetTokenText(token);
  266. if (text != "i32") {
  267. return context.TODO(parse_node, "Currently only i32 is allowed");
  268. }
  269. context.node_stack().Push(parse_node,
  270. SemanticsNodeId::BuiltinIntegerType);
  271. break;
  272. }
  273. case TokenKind::FloatingPointTypeLiteral: {
  274. auto text = context.tokens().GetTokenText(token);
  275. if (text != "f64") {
  276. return context.TODO(parse_node, "Currently only f64 is allowed");
  277. }
  278. context.node_stack().Push(parse_node,
  279. SemanticsNodeId::BuiltinFloatingPointType);
  280. break;
  281. }
  282. case TokenKind::StringTypeLiteral: {
  283. context.node_stack().Push(parse_node, SemanticsNodeId::BuiltinStringType);
  284. break;
  285. }
  286. default: {
  287. return context.TODO(parse_node, llvm::formatv("Handle {0}", token_kind));
  288. }
  289. }
  290. return true;
  291. }
  292. auto SemanticsHandleNameReference(SemanticsContext& context,
  293. ParseTree::Node parse_node) -> bool {
  294. auto name = context.parse_tree().GetNodeText(parse_node);
  295. context.node_stack().Push(parse_node, context.LookupName(parse_node, name));
  296. return true;
  297. }
  298. auto SemanticsHandleNamedConstraintDeclaration(SemanticsContext& context,
  299. ParseTree::Node parse_node)
  300. -> bool {
  301. return context.TODO(parse_node, "HandleNamedConstraintDeclaration");
  302. }
  303. auto SemanticsHandleNamedConstraintDefinition(SemanticsContext& context,
  304. ParseTree::Node parse_node)
  305. -> bool {
  306. return context.TODO(parse_node, "HandleNamedConstraintDefinition");
  307. }
  308. auto SemanticsHandleNamedConstraintDefinitionStart(SemanticsContext& context,
  309. ParseTree::Node parse_node)
  310. -> bool {
  311. return context.TODO(parse_node, "HandleNamedConstraintDefinitionStart");
  312. }
  313. auto SemanticsHandleNamedConstraintIntroducer(SemanticsContext& context,
  314. ParseTree::Node parse_node)
  315. -> bool {
  316. return context.TODO(parse_node, "HandleNamedConstraintIntroducer");
  317. }
  318. auto SemanticsHandleParameterList(SemanticsContext& context,
  319. ParseTree::Node parse_node) -> bool {
  320. auto refs_id = context.ParamOrArgEnd(
  321. /*for_args=*/false, ParseNodeKind::ParameterListStart);
  322. // TODO: This contains the IR block for parameters. At present, it's just
  323. // loose, but it's not strictly required for parameter refs; we should either
  324. // stop constructing it completely or, if it turns out to be needed, store it.
  325. // Note, the underlying issue is that the LLVM IR has nowhere clear to emit,
  326. // so changing storage would require addressing that problem. For comparison
  327. // with function calls, the IR needs to be emitted prior to the call.
  328. context.node_block_stack().Pop();
  329. context.PopScope();
  330. context.node_stack().PopAndDiscardSoloParseNode(
  331. ParseNodeKind::ParameterListStart);
  332. context.node_stack().Push(parse_node, refs_id);
  333. return true;
  334. }
  335. auto SemanticsHandleParameterListComma(SemanticsContext& context,
  336. ParseTree::Node /*parse_node*/) -> bool {
  337. context.ParamOrArgComma(/*for_args=*/false);
  338. return true;
  339. }
  340. auto SemanticsHandleParameterListStart(SemanticsContext& context,
  341. ParseTree::Node parse_node) -> bool {
  342. context.PushScope();
  343. context.node_stack().Push(parse_node);
  344. context.node_block_stack().Push();
  345. context.ParamOrArgStart();
  346. return true;
  347. }
  348. auto SemanticsHandleParenExpression(SemanticsContext& context,
  349. ParseTree::Node parse_node) -> bool {
  350. auto value_id = context.node_stack().Pop<SemanticsNodeId>();
  351. context.node_stack().PopAndDiscardSoloParseNode(
  352. ParseNodeKind::ParenExpressionOrTupleLiteralStart);
  353. context.node_stack().Push(parse_node, value_id);
  354. return true;
  355. }
  356. auto SemanticsHandleParenExpressionOrTupleLiteralStart(
  357. SemanticsContext& context, ParseTree::Node parse_node) -> bool {
  358. context.node_stack().Push(parse_node);
  359. return true;
  360. }
  361. auto SemanticsHandlePatternBinding(SemanticsContext& context,
  362. ParseTree::Node parse_node) -> bool {
  363. auto [type_node, parsed_type_id] =
  364. context.node_stack().PopWithParseNode<SemanticsNodeId>();
  365. auto cast_type_id = context.ExpressionAsType(type_node, parsed_type_id);
  366. // Get the name.
  367. auto name_node =
  368. context.node_stack().PopForSoloParseNode(ParseNodeKind::DeclaredName);
  369. auto name_str = context.parse_tree().GetNodeText(name_node);
  370. auto name_id = context.semantics_ir().AddString(name_str);
  371. // Allocate storage, linked to the name for error locations.
  372. auto storage_id =
  373. context.AddNode(SemanticsNode::VarStorage::Make(name_node, cast_type_id));
  374. // Bind the name to storage.
  375. context.AddNodeAndPush(parse_node,
  376. SemanticsNode::BindName::Make(name_node, cast_type_id,
  377. name_id, storage_id));
  378. return true;
  379. }
  380. auto SemanticsHandlePostfixOperator(SemanticsContext& context,
  381. ParseTree::Node parse_node) -> bool {
  382. return context.TODO(parse_node, "HandlePostfixOperator");
  383. }
  384. auto SemanticsHandlePrefixOperator(SemanticsContext& context,
  385. ParseTree::Node parse_node) -> bool {
  386. auto value_id = context.node_stack().Pop<SemanticsNodeId>();
  387. // Figure out the operator for the token.
  388. auto token = context.parse_tree().node_token(parse_node);
  389. switch (auto token_kind = context.tokens().GetKind(token)) {
  390. case TokenKind::Not:
  391. value_id = context.ImplicitAsBool(parse_node, value_id);
  392. context.AddNodeAndPush(
  393. parse_node,
  394. SemanticsNode::UnaryOperatorNot::Make(
  395. parse_node, context.semantics_ir().GetNode(value_id).type_id(),
  396. value_id));
  397. break;
  398. default:
  399. return context.TODO(parse_node, llvm::formatv("Handle {0}", token_kind));
  400. }
  401. return true;
  402. }
  403. auto SemanticsHandleReturnStatement(SemanticsContext& context,
  404. ParseTree::Node parse_node) -> bool {
  405. CARBON_CHECK(!context.return_scope_stack().empty());
  406. const auto& fn_node =
  407. context.semantics_ir().GetNode(context.return_scope_stack().back());
  408. const auto callable =
  409. context.semantics_ir().GetFunction(fn_node.GetAsFunctionDeclaration());
  410. if (context.parse_tree().node_kind(context.node_stack().PeekParseNode()) ==
  411. ParseNodeKind::ReturnStatementStart) {
  412. context.node_stack().PopAndDiscardSoloParseNode(
  413. ParseNodeKind::ReturnStatementStart);
  414. if (callable.return_type_id.is_valid()) {
  415. // TODO: Add a note pointing at the return type's parse node.
  416. CARBON_DIAGNOSTIC(ReturnStatementMissingExpression, Error,
  417. "Must return a {0}.", std::string);
  418. context.emitter()
  419. .Build(parse_node, ReturnStatementMissingExpression,
  420. context.semantics_ir().StringifyType(callable.return_type_id))
  421. .Emit();
  422. }
  423. context.AddNodeAndPush(parse_node, SemanticsNode::Return::Make(parse_node));
  424. } else {
  425. auto arg = context.node_stack().Pop<SemanticsNodeId>();
  426. context.node_stack().PopAndDiscardSoloParseNode(
  427. ParseNodeKind::ReturnStatementStart);
  428. if (!callable.return_type_id.is_valid()) {
  429. CARBON_DIAGNOSTIC(
  430. ReturnStatementDisallowExpression, Error,
  431. "No return expression should be provided in this context.");
  432. CARBON_DIAGNOSTIC(ReturnStatementImplicitNote, Note,
  433. "There was no return type provided.");
  434. context.emitter()
  435. .Build(parse_node, ReturnStatementDisallowExpression)
  436. .Note(fn_node.parse_node(), ReturnStatementImplicitNote)
  437. .Emit();
  438. } else {
  439. arg =
  440. context.ImplicitAsRequired(parse_node, arg, callable.return_type_id);
  441. }
  442. context.AddNodeAndPush(
  443. parse_node,
  444. SemanticsNode::ReturnExpression::Make(
  445. parse_node, context.semantics_ir().GetNode(arg).type_id(), arg));
  446. }
  447. return true;
  448. }
  449. auto SemanticsHandleReturnStatementStart(SemanticsContext& context,
  450. ParseTree::Node parse_node) -> bool {
  451. // No action, just a bracketing node.
  452. context.node_stack().Push(parse_node);
  453. return true;
  454. }
  455. auto SemanticsHandleReturnType(SemanticsContext& context,
  456. ParseTree::Node parse_node) -> bool {
  457. // Propagate the type expression.
  458. auto [type_parse_node, type_node_id] =
  459. context.node_stack().PopWithParseNode<SemanticsNodeId>();
  460. auto cast_node_id = context.ExpressionAsType(type_parse_node, type_node_id);
  461. context.node_stack().Push(parse_node, cast_node_id);
  462. return true;
  463. }
  464. auto SemanticsHandleSelfTypeIdentifier(SemanticsContext& context,
  465. ParseTree::Node parse_node) -> bool {
  466. return context.TODO(parse_node, "HandleSelfTypeIdentifier");
  467. }
  468. auto SemanticsHandleSelfValueIdentifier(SemanticsContext& context,
  469. ParseTree::Node parse_node) -> bool {
  470. return context.TODO(parse_node, "HandleSelfValueIdentifier");
  471. }
  472. auto SemanticsHandleShortCircuitOperand(SemanticsContext& context,
  473. ParseTree::Node parse_node) -> bool {
  474. // Convert the condition to `bool`.
  475. auto cond_value_id = context.node_stack().Pop<SemanticsNodeId>();
  476. cond_value_id = context.ImplicitAsBool(parse_node, cond_value_id);
  477. auto bool_type_id = context.semantics_ir().GetNode(cond_value_id).type_id();
  478. // Compute the branch value: the condition for `and`, inverted for `or`.
  479. auto token = context.parse_tree().node_token(parse_node);
  480. SemanticsNodeId branch_value_id = SemanticsNodeId::Invalid;
  481. auto short_circuit_result_id = SemanticsNodeId::Invalid;
  482. switch (auto token_kind = context.tokens().GetKind(token)) {
  483. case TokenKind::And:
  484. branch_value_id = cond_value_id;
  485. short_circuit_result_id =
  486. context.AddNode(SemanticsNode::BoolLiteral::Make(
  487. parse_node, bool_type_id, SemanticsBoolValue::False));
  488. break;
  489. case TokenKind::Or:
  490. branch_value_id = context.AddNode(SemanticsNode::UnaryOperatorNot::Make(
  491. parse_node, bool_type_id, cond_value_id));
  492. short_circuit_result_id =
  493. context.AddNode(SemanticsNode::BoolLiteral::Make(
  494. parse_node, bool_type_id, SemanticsBoolValue::True));
  495. break;
  496. default:
  497. CARBON_FATAL() << "Unexpected short-circuiting operator " << parse_node;
  498. }
  499. // Create a block for the right-hand side and for the continuation.
  500. auto lhs_block_id = context.node_block_stack().PopForAdd();
  501. auto end_block_id = context.node_block_stack().PushForAdd();
  502. auto rhs_block_id = context.node_block_stack().PushForAdd();
  503. context.AddNodeToBlock(
  504. lhs_block_id,
  505. SemanticsNode::BranchIf::Make(parse_node, rhs_block_id, branch_value_id));
  506. context.AddNodeToBlock(
  507. lhs_block_id, SemanticsNode::BranchWithArg::Make(
  508. parse_node, end_block_id, short_circuit_result_id));
  509. // Put the condition back on the stack for SemanticsHandleInfixOperator.
  510. context.node_stack().Push(parse_node, cond_value_id);
  511. return true;
  512. }
  513. auto SemanticsHandleTemplate(SemanticsContext& context,
  514. ParseTree::Node parse_node) -> bool {
  515. return context.TODO(parse_node, "HandleTemplate");
  516. }
  517. auto SemanticsHandleTupleLiteral(SemanticsContext& context,
  518. ParseTree::Node parse_node) -> bool {
  519. return context.TODO(parse_node, "HandleTupleLiteral");
  520. }
  521. auto SemanticsHandleTupleLiteralComma(SemanticsContext& context,
  522. ParseTree::Node parse_node) -> bool {
  523. return context.TODO(parse_node, "HandleTupleLiteralComma");
  524. }
  525. auto SemanticsHandleVariableDeclaration(SemanticsContext& context,
  526. ParseTree::Node parse_node) -> bool {
  527. // Handle the optional initializer.
  528. auto expr_node_id = SemanticsNodeId::Invalid;
  529. bool has_init =
  530. context.parse_tree().node_kind(context.node_stack().PeekParseNode()) !=
  531. ParseNodeKind::PatternBinding;
  532. if (has_init) {
  533. expr_node_id = context.node_stack().Pop<SemanticsNodeId>();
  534. context.node_stack().PopAndDiscardSoloParseNode(
  535. ParseNodeKind::VariableInitializer);
  536. }
  537. // Get the storage and add it to name lookup.
  538. auto binding_id =
  539. context.node_stack().Pop<SemanticsNodeId>(ParseNodeKind::PatternBinding);
  540. auto binding = context.semantics_ir().GetNode(binding_id);
  541. auto [name_id, storage_id] = binding.GetAsBindName();
  542. context.AddNameToLookup(binding.parse_node(), name_id, storage_id);
  543. // If there was an initializer, assign it to storage.
  544. if (has_init) {
  545. auto cast_value_id = context.ImplicitAsRequired(
  546. parse_node, expr_node_id,
  547. context.semantics_ir().GetNode(storage_id).type_id());
  548. context.AddNode(SemanticsNode::Assign::Make(
  549. parse_node, context.semantics_ir().GetNode(cast_value_id).type_id(),
  550. storage_id, cast_value_id));
  551. }
  552. context.node_stack().PopAndDiscardSoloParseNode(
  553. ParseNodeKind::VariableIntroducer);
  554. context.node_stack().Push(parse_node);
  555. return true;
  556. }
  557. auto SemanticsHandleVariableIntroducer(SemanticsContext& context,
  558. ParseTree::Node parse_node) -> bool {
  559. // No action, just a bracketing node.
  560. context.node_stack().Push(parse_node);
  561. return true;
  562. }
  563. auto SemanticsHandleVariableInitializer(SemanticsContext& context,
  564. ParseTree::Node parse_node) -> bool {
  565. // No action, just a bracketing node.
  566. context.node_stack().Push(parse_node);
  567. return true;
  568. }
  569. auto SemanticsHandleWhileCondition(SemanticsContext& context,
  570. ParseTree::Node parse_node) -> bool {
  571. return context.TODO(parse_node, "HandleWhileCondition");
  572. }
  573. auto SemanticsHandleWhileConditionStart(SemanticsContext& context,
  574. ParseTree::Node parse_node) -> bool {
  575. return context.TODO(parse_node, "HandleWhileConditionStart");
  576. }
  577. auto SemanticsHandleWhileStatement(SemanticsContext& context,
  578. ParseTree::Node parse_node) -> bool {
  579. return context.TODO(parse_node, "HandleWhileStatement");
  580. }
  581. } // namespace Carbon