declaration.h 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  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 "executable_semantics/ast/function_definition.h"
  9. #include "executable_semantics/ast/member.h"
  10. #include "executable_semantics/ast/struct_definition.h"
  11. namespace Carbon {
  12. struct Value;
  13. template <class K, class V>
  14. struct AssocList;
  15. using Address = unsigned int;
  16. using TypeEnv = AssocList<std::string, Value*>;
  17. using Env = AssocList<std::string, Address>;
  18. /// TODO:explain this. Also name it if necessary. Consult with jsiek.
  19. using ExecutionEnvironment = std::pair<TypeEnv*, Env*>;
  20. /// An existential AST declaration satisfying the Declaration concept.
  21. class Declaration {
  22. public: // ValueSemantic concept API.
  23. Declaration(const Declaration& other) = default;
  24. Declaration& operator=(const Declaration& other) = default;
  25. /// Constructs an instance equivalent to `d`, where `Model` satisfies the
  26. /// Declaration concept.
  27. template <class Model>
  28. Declaration(Model d) : box(std::make_shared<Boxed<Model>>(d)) {}
  29. public: // Declaration concept API, in addition to ValueSemantic.
  30. void Print() const { box->Print(); }
  31. auto Name() const -> std::string { return box->Name(); }
  32. auto TypeChecked(TypeEnv* env, Env* ct_env) const -> Declaration {
  33. return box->TypeChecked(env, ct_env);
  34. }
  35. void InitGlobals(Env*& globals) const { return box->InitGlobals(globals); }
  36. auto TopLevel(ExecutionEnvironment& e) const -> void {
  37. return box->TopLevel(e);
  38. }
  39. private: // types
  40. /// A base class that erases the type of a `Boxed<Content>`, where `Content`
  41. /// satisfies the Declaration concept.
  42. struct Box {
  43. protected:
  44. Box() {}
  45. public:
  46. Box(const Box& other) = delete;
  47. Box& operator=(const Box& other) = delete;
  48. virtual ~Box() {}
  49. virtual auto Print() const -> void = 0;
  50. virtual auto Name() const -> std::string = 0;
  51. virtual auto TypeChecked(TypeEnv* env, Env* ct_env) const
  52. -> Declaration = 0;
  53. virtual auto InitGlobals(Env*& globals) const -> void = 0;
  54. virtual auto TopLevel(ExecutionEnvironment&) const -> void = 0;
  55. };
  56. /// The derived class that holds an instance of `Content` satisfying the
  57. /// Declaration concept.
  58. template <class Content>
  59. struct Boxed final : Box {
  60. const Content content;
  61. explicit Boxed(Content content) : Box(), content(content) {}
  62. auto Print() const -> void override { return content.Print(); }
  63. auto Name() const -> std::string override { return content.Name(); }
  64. auto TypeChecked(TypeEnv* env, Env* ct_env) const -> Declaration override {
  65. return content.TypeChecked(env, ct_env);
  66. }
  67. auto InitGlobals(Env*& globals) const -> void override {
  68. content.InitGlobals(globals);
  69. }
  70. auto TopLevel(ExecutionEnvironment& e) const -> void override {
  71. content.TopLevel(e);
  72. }
  73. };
  74. private: // data members
  75. // Note: the pointee is const as long as we have no mutating methods. When
  76. std::shared_ptr<const Box> box;
  77. };
  78. struct FunctionDeclaration {
  79. const FunctionDefinition* definition;
  80. explicit FunctionDeclaration(const FunctionDefinition* definition)
  81. : definition(definition) {}
  82. auto Print() const -> void;
  83. auto Name() const -> std::string;
  84. auto TypeChecked(TypeEnv* env, Env* ct_env) const -> Declaration;
  85. auto InitGlobals(Env*& globals) const -> void;
  86. auto TopLevel(ExecutionEnvironment&) const -> void;
  87. };
  88. struct StructDeclaration {
  89. StructDefinition definition;
  90. StructDeclaration(int line_num, std::string name, std::list<Member*>* members)
  91. : definition{line_num, new std::string(name), members} {}
  92. void Print() const;
  93. auto Name() const -> std::string;
  94. auto TypeChecked(TypeEnv* env, Env* ct_env) const -> Declaration;
  95. void InitGlobals(Env*& globals) const;
  96. auto TopLevel(ExecutionEnvironment&) const -> void;
  97. };
  98. struct ChoiceDeclaration {
  99. int line_num;
  100. std::string name;
  101. std::list<std::pair<std::string, Expression*>> alternatives;
  102. ChoiceDeclaration(int line_num, std::string name,
  103. std::list<std::pair<std::string, Expression*>> alternatives)
  104. : line_num(line_num), name(name), alternatives(alternatives) {}
  105. void Print() const;
  106. auto Name() const -> std::string;
  107. auto TypeChecked(TypeEnv* env, Env* ct_env) const -> Declaration;
  108. void InitGlobals(Env*& globals) const;
  109. auto TopLevel(ExecutionEnvironment&) const -> void;
  110. };
  111. } // namespace Carbon
  112. #endif // EXECUTABLE_SEMANTICS_AST_DECLARATION_H_