declaration.h 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  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. #include "executable_semantics/interpreter/dictionary.h"
  12. namespace Carbon {
  13. struct Value;
  14. using Address = unsigned int;
  15. using TypeEnv = Dictionary<std::string, Value*>;
  16. using Env = Dictionary<std::string, Address>;
  17. /// TODO:explain this. Also name it if necessary. Consult with jsiek.
  18. using ExecutionEnvironment = std::pair<TypeEnv, Env>;
  19. /// An existential AST declaration satisfying the Declaration concept.
  20. class Declaration {
  21. public: // ValueSemantic concept API.
  22. Declaration(const Declaration& other) = default;
  23. Declaration& operator=(const Declaration& other) = default;
  24. /// Constructs an instance equivalent to `d`, where `Model` satisfies the
  25. /// Declaration concept.
  26. template <class Model>
  27. Declaration(Model d) : box(std::make_shared<Boxed<Model>>(d)) {}
  28. public: // Declaration concept API, in addition to ValueSemantic.
  29. void Print() const { box->Print(); }
  30. auto Name() const -> std::string { return box->Name(); }
  31. // Signals a type error if the declaration is not well typed,
  32. // otherwise returns this declaration with annotated types.
  33. //
  34. // - Parameter env: types of run-time names.
  35. // - Paraemter ct_env: values of compile-time names.
  36. auto TypeChecked(TypeEnv env, Env ct_env) const -> Declaration {
  37. return box->TypeChecked(env, ct_env);
  38. }
  39. // Add an entry in the runtime global symbol table for this declaration.
  40. void InitGlobals(Env& globals) const { return box->InitGlobals(globals); }
  41. // Add an entry in the compile time global symbol tables for this declaration.
  42. auto TopLevel(ExecutionEnvironment& e) const -> void {
  43. return box->TopLevel(e);
  44. }
  45. private: // types
  46. /// A base class that erases the type of a `Boxed<Content>`, where `Content`
  47. /// satisfies the Declaration concept.
  48. struct Box {
  49. protected:
  50. Box() {}
  51. public:
  52. Box(const Box& other) = delete;
  53. Box& operator=(const Box& other) = delete;
  54. virtual ~Box() {}
  55. virtual auto Print() const -> void = 0;
  56. virtual auto Name() const -> std::string = 0;
  57. virtual auto TypeChecked(TypeEnv env, Env ct_env) const -> Declaration = 0;
  58. virtual auto InitGlobals(Env& globals) const -> void = 0;
  59. virtual auto TopLevel(ExecutionEnvironment&) const -> void = 0;
  60. };
  61. /// The derived class that holds an instance of `Content` satisfying the
  62. /// Declaration concept.
  63. template <class Content>
  64. struct Boxed final : Box {
  65. const Content content;
  66. explicit Boxed(Content content) : Box(), content(content) {}
  67. auto Print() const -> void override { return content.Print(); }
  68. auto Name() const -> std::string override { return content.Name(); }
  69. auto TypeChecked(TypeEnv env, Env ct_env) const -> Declaration override {
  70. return content.TypeChecked(env, ct_env);
  71. }
  72. auto InitGlobals(Env& globals) const -> void override {
  73. content.InitGlobals(globals);
  74. }
  75. auto TopLevel(ExecutionEnvironment& e) const -> void override {
  76. content.TopLevel(e);
  77. }
  78. };
  79. private: // data members
  80. // Note: the pointee is const as long as we have no mutating methods. When
  81. std::shared_ptr<const Box> box;
  82. };
  83. struct FunctionDeclaration {
  84. const FunctionDefinition* definition;
  85. explicit FunctionDeclaration(const FunctionDefinition* definition)
  86. : definition(definition) {}
  87. auto Print() const -> void;
  88. auto Name() const -> std::string;
  89. auto TypeChecked(TypeEnv env, Env ct_env) const -> Declaration;
  90. auto InitGlobals(Env& globals) const -> void;
  91. auto TopLevel(ExecutionEnvironment&) const -> void;
  92. };
  93. struct StructDeclaration {
  94. StructDefinition definition;
  95. StructDeclaration(int line_num, std::string name, std::list<Member*>* members)
  96. : definition{line_num, new std::string(name), members} {}
  97. void Print() const;
  98. auto Name() const -> std::string;
  99. auto TypeChecked(TypeEnv env, Env ct_env) const -> Declaration;
  100. void InitGlobals(Env& globals) const;
  101. auto TopLevel(ExecutionEnvironment&) const -> void;
  102. };
  103. struct ChoiceDeclaration {
  104. int line_num;
  105. std::string name;
  106. std::list<std::pair<std::string, Expression*>> alternatives;
  107. ChoiceDeclaration(int line_num, std::string name,
  108. std::list<std::pair<std::string, Expression*>> alternatives)
  109. : line_num(line_num), name(name), alternatives(alternatives) {}
  110. void Print() const;
  111. auto Name() const -> std::string;
  112. auto TypeChecked(TypeEnv env, Env ct_env) const -> Declaration;
  113. void InitGlobals(Env& globals) const;
  114. auto TopLevel(ExecutionEnvironment&) const -> void;
  115. };
  116. // Global variable definition implements the Declaration concept.
  117. class VariableDeclaration {
  118. public:
  119. VariableDeclaration(int source_location, std::string name, Expression* type,
  120. Expression* initializer)
  121. : source_location(source_location),
  122. name(name),
  123. type(type),
  124. initializer(initializer) {}
  125. void Print() const;
  126. auto Name() const -> std::string;
  127. auto TypeChecked(TypeEnv env, Env ct_env) const -> Declaration;
  128. void InitGlobals(Env& globals) const;
  129. auto TopLevel(ExecutionEnvironment&) const -> void;
  130. private:
  131. int source_location;
  132. std::string name;
  133. Expression* type;
  134. Expression* initializer;
  135. };
  136. } // namespace Carbon
  137. #endif // EXECUTABLE_SEMANTICS_AST_DECLARATION_H_