action.h 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  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_INTERPRETER_ACTION_H_
  5. #define EXECUTABLE_SEMANTICS_INTERPRETER_ACTION_H_
  6. #include <vector>
  7. #include "common/ostream.h"
  8. #include "executable_semantics/ast/expression.h"
  9. #include "executable_semantics/ast/pattern.h"
  10. #include "executable_semantics/ast/statement.h"
  11. #include "executable_semantics/interpreter/dictionary.h"
  12. #include "executable_semantics/interpreter/heap_allocation_interface.h"
  13. #include "executable_semantics/interpreter/stack.h"
  14. #include "executable_semantics/interpreter/value.h"
  15. #include "llvm/Support/Compiler.h"
  16. namespace Carbon {
  17. using Env = Dictionary<std::string, AllocationId>;
  18. // A Scope represents the name lookup environment associated with an Action,
  19. // including any variables that are local to that action. Local variables
  20. // will be deallocated from the Carbon Heap when the Scope is destroyed.
  21. class Scope {
  22. public:
  23. // Constructs a Scope whose name environment is `values`, containing the local
  24. // variables in `locals`. The elements of `locals` must also be keys in
  25. // `values`, and their values must be allocated in `heap`.
  26. Scope(Env values, std::vector<std::string> locals,
  27. Nonnull<HeapAllocationInterface*> heap)
  28. : values_(values), locals_(std::move(locals)), heap_(heap) {}
  29. // Equivalent to `Scope(values, {}, heap)`.
  30. Scope(Env values, Nonnull<HeapAllocationInterface*> heap)
  31. : Scope(values, std::vector<std::string>(), heap) {}
  32. // Moving a Scope transfers ownership of its local variables.
  33. Scope(Scope&&) noexcept;
  34. auto operator=(Scope&&) noexcept -> Scope&;
  35. ~Scope();
  36. // Binds `name` to the value of `allocation` in `heap`, and takes
  37. // ownership of it.
  38. void AddLocal(const std::string& name, AllocationId allocation) {
  39. values_.Set(name, allocation);
  40. locals_.push_back(name);
  41. }
  42. auto values() const -> Env { return values_; }
  43. private:
  44. Env values_;
  45. std::vector<std::string> locals_;
  46. Nonnull<HeapAllocationInterface*> heap_;
  47. };
  48. class Action {
  49. public:
  50. enum class Kind {
  51. LValAction,
  52. ExpressionAction,
  53. PatternAction,
  54. StatementAction,
  55. ScopeAction,
  56. };
  57. Action(const Value&) = delete;
  58. auto operator=(const Value&) -> Action& = delete;
  59. void AddResult(Nonnull<const Value*> result) { results_.push_back(result); }
  60. void Clear() {
  61. CHECK(!scope_.has_value());
  62. pos_ = 0;
  63. results_.clear();
  64. }
  65. // Associates this action with a new scope, with initial state `scope`.
  66. // Values that are local to this scope will be deallocated when this
  67. // Action is completed or unwound. Can only be called once on a given
  68. // Action.
  69. void StartScope(Scope scope) {
  70. CHECK(!scope_.has_value());
  71. scope_ = std::move(scope);
  72. }
  73. // Returns the scope associated with this Action, if any.
  74. auto scope() -> std::optional<Scope>& { return scope_; }
  75. static void PrintList(const Stack<Nonnull<Action*>>& ls,
  76. llvm::raw_ostream& out);
  77. void Print(llvm::raw_ostream& out) const;
  78. LLVM_DUMP_METHOD void Dump() const { Print(llvm::errs()); }
  79. // Returns the enumerator corresponding to the most-derived type of this
  80. // object.
  81. auto kind() const -> Kind { return kind_; }
  82. // The position or state of the action. Starts at 0 and goes up to the number
  83. // of subexpressions.
  84. //
  85. // pos indicates how many of the entries in the following `results` vector
  86. // will be filled in the next time this action is active.
  87. // For each i < pos, results[i] contains a pointer to a Value.
  88. auto pos() const -> int { return pos_; }
  89. void set_pos(int pos) { this->pos_ = pos; }
  90. // Results from a subexpression.
  91. auto results() const -> const std::vector<Nonnull<const Value*>>& {
  92. return results_;
  93. }
  94. virtual ~Action() = default;
  95. protected:
  96. // Constructs an Action. `kind` must be the enumerator corresponding to the
  97. // most-derived type being constructed.
  98. explicit Action(Kind kind) : kind_(kind) {}
  99. private:
  100. int pos_ = 0;
  101. std::vector<Nonnull<const Value*>> results_;
  102. std::optional<Scope> scope_;
  103. const Kind kind_;
  104. };
  105. // An Action which implements evaluation of an Expression to produce an
  106. // LValue.
  107. class LValAction : public Action {
  108. public:
  109. explicit LValAction(Nonnull<const Expression*> expression)
  110. : Action(Kind::LValAction), expression_(expression) {}
  111. static auto classof(const Action* action) -> bool {
  112. return action->kind() == Kind::LValAction;
  113. }
  114. // The Expression this Action evaluates.
  115. auto expression() const -> const Expression& { return *expression_; }
  116. private:
  117. Nonnull<const Expression*> expression_;
  118. };
  119. // An Action which implements evaluation of an Expression to produce an
  120. // rvalue. The result is expressed as a Value.
  121. class ExpressionAction : public Action {
  122. public:
  123. explicit ExpressionAction(Nonnull<const Expression*> expression)
  124. : Action(Kind::ExpressionAction), expression_(expression) {}
  125. static auto classof(const Action* action) -> bool {
  126. return action->kind() == Kind::ExpressionAction;
  127. }
  128. // The Expression this Action evaluates.
  129. auto expression() const -> const Expression& { return *expression_; }
  130. private:
  131. Nonnull<const Expression*> expression_;
  132. };
  133. // An Action which implements evaluation of a Pattern. The result is expressed
  134. // as a Value.
  135. class PatternAction : public Action {
  136. public:
  137. explicit PatternAction(Nonnull<const Pattern*> pattern)
  138. : Action(Kind::PatternAction), pattern_(pattern) {}
  139. static auto classof(const Action* action) -> bool {
  140. return action->kind() == Kind::PatternAction;
  141. }
  142. // The Pattern this Action evaluates.
  143. auto pattern() const -> const Pattern& { return *pattern_; }
  144. private:
  145. Nonnull<const Pattern*> pattern_;
  146. };
  147. // An Action which implements execution of a Statement. Does not produce a
  148. // result.
  149. class StatementAction : public Action {
  150. public:
  151. explicit StatementAction(Nonnull<const Statement*> statement)
  152. : Action(Kind::StatementAction), statement_(statement) {}
  153. static auto classof(const Action* action) -> bool {
  154. return action->kind() == Kind::StatementAction;
  155. }
  156. // The Statement this Action executes.
  157. auto statement() const -> const Statement& { return *statement_; }
  158. private:
  159. Nonnull<const Statement*> statement_;
  160. };
  161. // Action which does nothing except introduce a new scope into the action
  162. // stack. This is useful when a distinct scope doesn't otherwise have an
  163. // Action it can naturally be associated with. ScopeActions are not associated
  164. // with AST nodes.
  165. class ScopeAction : public Action {
  166. public:
  167. explicit ScopeAction(Scope scope) : Action(Kind::ScopeAction) {
  168. StartScope(std::move(scope));
  169. }
  170. static auto classof(const Action* action) -> bool {
  171. return action->kind() == Kind::ScopeAction;
  172. }
  173. };
  174. } // namespace Carbon
  175. #endif // EXECUTABLE_SEMANTICS_INTERPRETER_ACTION_H_