declaration.h 5.9 KB

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