resolve_names.cpp 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  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 "executable_semantics/interpreter/resolve_names.h"
  5. #include "executable_semantics/ast/declaration.h"
  6. #include "llvm/Support/Casting.h"
  7. using llvm::cast;
  8. namespace Carbon {
  9. namespace {
  10. // Populates names for a pattern. See PopulateNamesInDeclaration for overall
  11. // flow.
  12. void PopulateNamesInPattern(const Pattern& pattern, StaticScope& static_scope) {
  13. switch (pattern.kind()) {
  14. case Pattern::Kind::AlternativePattern: {
  15. const auto& alt = cast<AlternativePattern>(pattern);
  16. PopulateNamesInPattern(alt.arguments(), static_scope);
  17. break;
  18. }
  19. case Pattern::Kind::BindingPattern: {
  20. const auto& binding = cast<BindingPattern>(pattern);
  21. if (binding.name().has_value()) {
  22. static_scope.Add(*binding.name(), &binding);
  23. }
  24. break;
  25. }
  26. case Pattern::Kind::TuplePattern: {
  27. const auto& tuple = cast<TuplePattern>(pattern);
  28. for (auto* field : tuple.fields()) {
  29. PopulateNamesInPattern(*field, static_scope);
  30. }
  31. break;
  32. }
  33. case Pattern::Kind::AutoPattern:
  34. case Pattern::Kind::ExpressionPattern:
  35. // These don't add names.
  36. break;
  37. }
  38. }
  39. // Populates names for a statement. See PopulateNamesInDeclaration for overall
  40. // flow.
  41. void PopulateNamesInStatement(Arena* arena,
  42. std::optional<Nonnull<Statement*>> opt_statement,
  43. StaticScope& static_scope) {
  44. if (!opt_statement.has_value()) {
  45. return;
  46. }
  47. Statement& statement = **opt_statement;
  48. switch (statement.kind()) {
  49. case Statement::Kind::Block: {
  50. // Defines a new scope for names.
  51. auto& block = cast<Block>(statement);
  52. for (const auto& statement : block.statements()) {
  53. PopulateNamesInStatement(arena, statement, block.static_scope());
  54. }
  55. break;
  56. }
  57. case Statement::Kind::Continuation: {
  58. // Defines a new name and contains a block.
  59. auto& cont = cast<Continuation>(statement);
  60. static_scope.Add(cont.continuation_variable(), &cont);
  61. PopulateNamesInStatement(arena, &cont.body(), static_scope);
  62. break;
  63. }
  64. case Statement::Kind::VariableDefinition: {
  65. // Defines a new name.
  66. const auto& var = cast<VariableDefinition>(statement);
  67. PopulateNamesInPattern(var.pattern(), static_scope);
  68. break;
  69. }
  70. case Statement::Kind::If: {
  71. // Contains blocks.
  72. auto& if_stmt = cast<If>(statement);
  73. PopulateNamesInStatement(arena, &if_stmt.then_block(), static_scope);
  74. PopulateNamesInStatement(arena, if_stmt.else_block(), static_scope);
  75. break;
  76. }
  77. case Statement::Kind::While: {
  78. // Contains a block.
  79. auto& while_stmt = cast<While>(statement);
  80. PopulateNamesInStatement(arena, &while_stmt.body(), static_scope);
  81. break;
  82. }
  83. case Statement::Kind::Match: {
  84. // Contains blocks.
  85. auto& match = cast<Match>(statement);
  86. for (auto& clause : match.clauses()) {
  87. PopulateNamesInPattern(clause.pattern(), clause.static_scope());
  88. PopulateNamesInStatement(arena, &clause.statement(),
  89. clause.static_scope());
  90. }
  91. break;
  92. }
  93. case Statement::Kind::Assign:
  94. case Statement::Kind::Await:
  95. case Statement::Kind::Break:
  96. case Statement::Kind::Continue:
  97. case Statement::Kind::ExpressionStatement:
  98. case Statement::Kind::Return:
  99. case Statement::Kind::Run:
  100. // Neither contains names nor a scope.
  101. break;
  102. }
  103. }
  104. // Populates names for a member. See PopulateNamesInDeclaration for overall
  105. // flow.
  106. void PopulateNamesInMember(Arena* arena, const Member& member,
  107. StaticScope& static_scope) {
  108. switch (member.kind()) {
  109. case Member::Kind::FieldMember: {
  110. const auto& field = cast<FieldMember>(member);
  111. if (field.binding().name().has_value()) {
  112. static_scope.Add(*field.binding().name(), &member);
  113. }
  114. break;
  115. }
  116. }
  117. }
  118. // Populates declared names at scoped boundaries, such as file-level or
  119. // function bodies. This doesn't currently recurse into expressions, but
  120. // likely will in the future in order to resolve names in lambdas.
  121. void PopulateNamesInDeclaration(Arena* arena, Declaration& declaration,
  122. StaticScope& static_scope) {
  123. switch (declaration.kind()) {
  124. case Declaration::Kind::FunctionDeclaration: {
  125. auto& func = cast<FunctionDeclaration>(declaration);
  126. static_scope.Add(func.name(), &declaration);
  127. for (const auto& param : func.deduced_parameters()) {
  128. func.static_scope().Add(param.name(), &param);
  129. }
  130. PopulateNamesInPattern(func.param_pattern(), func.static_scope());
  131. PopulateNamesInStatement(arena, func.body(), static_scope);
  132. break;
  133. }
  134. case Declaration::Kind::ClassDeclaration: {
  135. auto& class_def = cast<ClassDeclaration>(declaration).definition();
  136. static_scope.Add(class_def.name(), &declaration);
  137. for (auto* member : class_def.members()) {
  138. PopulateNamesInMember(arena, *member, class_def.static_scope());
  139. }
  140. break;
  141. }
  142. case Declaration::Kind::ChoiceDeclaration: {
  143. auto& choice = cast<ChoiceDeclaration>(declaration);
  144. static_scope.Add(choice.name(), &declaration);
  145. for (auto& alt : choice.alternatives()) {
  146. choice.static_scope().Add(alt.name(), &alt);
  147. }
  148. // Populate name into declared_names.
  149. // Init the choice's declared_names, and populate it with the
  150. // alternatives.
  151. break;
  152. }
  153. case Declaration::Kind::VariableDeclaration:
  154. auto& var = cast<VariableDeclaration>(declaration);
  155. if (var.binding().name().has_value()) {
  156. static_scope.Add(*(var.binding().name()), &var.binding());
  157. }
  158. return;
  159. }
  160. }
  161. // TODO: ResolveNames for Expression, Member, Pattern, and Statement will be
  162. // needed for recursion.
  163. // Recurses through a declaration to find and resolve IdentifierExpressions
  164. // using declared_names.
  165. void ResolveNamesInDeclaration(Declaration& declaration,
  166. const StaticScope& static_scope) {
  167. switch (declaration.kind()) {
  168. case Declaration::Kind::FunctionDeclaration:
  169. case Declaration::Kind::ClassDeclaration:
  170. case Declaration::Kind::ChoiceDeclaration:
  171. case Declaration::Kind::VariableDeclaration:
  172. break;
  173. }
  174. }
  175. } // namespace
  176. void ResolveNames(Arena* arena, AST& ast) {
  177. for (auto declaration : ast.declarations) {
  178. PopulateNamesInDeclaration(arena, *declaration, ast.static_scope);
  179. }
  180. for (auto declaration : ast.declarations) {
  181. ResolveNamesInDeclaration(*declaration, ast.static_scope);
  182. }
  183. }
  184. } // namespace Carbon