declaration.h 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  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. #ifndef EXECUTABLE_SEMANTICS_AST_DECLARATION_H_
  5. #define EXECUTABLE_SEMANTICS_AST_DECLARATION_H_
  6. #include <list>
  7. #include <string>
  8. #include "common/ostream.h"
  9. #include "executable_semantics/ast/function_definition.h"
  10. #include "executable_semantics/ast/member.h"
  11. #include "executable_semantics/ast/pattern.h"
  12. #include "executable_semantics/ast/struct_definition.h"
  13. #include "executable_semantics/interpreter/address.h"
  14. #include "executable_semantics/interpreter/dictionary.h"
  15. #include "llvm/Support/Compiler.h"
  16. namespace Carbon {
  17. class Value;
  18. using TypeEnv = Dictionary<std::string, const Value*>;
  19. using Env = Dictionary<std::string, Address>;
  20. struct TypeCheckContext {
  21. // Symbol table mapping names of runtime entities to their type.
  22. TypeEnv types;
  23. // Symbol table mapping names of compile time entities to their value.
  24. Env values;
  25. };
  26. // Abstract base class of all AST nodes representing patterns.
  27. //
  28. // Declaration and its derived classes support LLVM-style RTTI, including
  29. // llvm::isa, llvm::cast, and llvm::dyn_cast. To support this, every
  30. // class derived from Declaration must provide a `classof` operation, and
  31. // every concrete derived class must have a corresponding enumerator
  32. // in `Kind`; see https://llvm.org/docs/HowToSetUpLLVMStyleRTTI.html for
  33. // details.
  34. class Declaration {
  35. public:
  36. enum class Kind {
  37. FunctionDeclaration,
  38. StructDeclaration,
  39. ChoiceDeclaration,
  40. VariableDeclaration,
  41. };
  42. Declaration(const Member&) = delete;
  43. Declaration& operator=(const Member&) = delete;
  44. // Returns the enumerator corresponding to the most-derived type of this
  45. // object.
  46. auto Tag() const -> Kind { return tag; }
  47. auto LineNumber() const -> int { return line_num; }
  48. void Print(llvm::raw_ostream& out) const;
  49. protected:
  50. // Constructs a Declaration representing syntax at the given line number.
  51. // `tag` must be the enumerator corresponding to the most-derived type being
  52. // constructed.
  53. Declaration(Kind tag, int line_num) : tag(tag), line_num(line_num) {}
  54. private:
  55. const Kind tag;
  56. int line_num;
  57. };
  58. class FunctionDeclaration : public Declaration {
  59. public:
  60. FunctionDeclaration(const FunctionDefinition* definition)
  61. : Declaration(Kind::FunctionDeclaration, definition->line_num),
  62. definition(definition) {}
  63. static auto classof(const Declaration* decl) -> bool {
  64. return decl->Tag() == Kind::FunctionDeclaration;
  65. }
  66. auto Definition() const -> const FunctionDefinition& { return *definition; }
  67. private:
  68. const FunctionDefinition* definition;
  69. };
  70. class StructDeclaration : public Declaration {
  71. public:
  72. StructDeclaration(int line_num, std::string name, std::list<Member*> members)
  73. : Declaration(Kind::StructDeclaration, line_num),
  74. definition({.line_num = line_num,
  75. .name = std::move(name),
  76. .members = std::move(members)}) {}
  77. static auto classof(const Declaration* decl) -> bool {
  78. return decl->Tag() == Kind::StructDeclaration;
  79. }
  80. auto Definition() const -> const StructDefinition& { return definition; }
  81. private:
  82. StructDefinition definition;
  83. };
  84. class ChoiceDeclaration : public Declaration {
  85. public:
  86. ChoiceDeclaration(
  87. int line_num, std::string name,
  88. std::list<std::pair<std::string, const Expression*>> alternatives)
  89. : Declaration(Kind::ChoiceDeclaration, line_num),
  90. name(std::move(name)),
  91. alternatives(std::move(alternatives)) {}
  92. static auto classof(const Declaration* decl) -> bool {
  93. return decl->Tag() == Kind::ChoiceDeclaration;
  94. }
  95. auto Name() const -> const std::string& { return name; }
  96. auto Alternatives() const
  97. -> const std::list<std::pair<std::string, const Expression*>>& {
  98. return alternatives;
  99. }
  100. private:
  101. std::string name;
  102. std::list<std::pair<std::string, const Expression*>> alternatives;
  103. };
  104. // Global variable definition implements the Declaration concept.
  105. class VariableDeclaration : public Declaration {
  106. public:
  107. VariableDeclaration(int line_num, const BindingPattern* binding,
  108. const Expression* initializer)
  109. : Declaration(Kind::VariableDeclaration, line_num),
  110. binding(binding),
  111. initializer(initializer) {}
  112. static auto classof(const Declaration* decl) -> bool {
  113. return decl->Tag() == Kind::VariableDeclaration;
  114. }
  115. auto Binding() const -> const BindingPattern* { return binding; }
  116. auto Initializer() const -> const Expression* { return initializer; }
  117. private:
  118. // TODO: split this into a non-optional name and a type, initialized by
  119. // a constructor that takes a BindingPattern and handles errors like a
  120. // missing name.
  121. const BindingPattern* binding;
  122. const Expression* initializer;
  123. };
  124. } // namespace Carbon
  125. #endif // EXECUTABLE_SEMANTICS_AST_DECLARATION_H_