value.h 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251
  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_VALUE_H_
  5. #define EXECUTABLE_SEMANTICS_INTERPRETER_VALUE_H_
  6. #include <list>
  7. #include <optional>
  8. #include <string>
  9. #include <variant>
  10. #include <vector>
  11. #include "common/ostream.h"
  12. #include "executable_semantics/ast/statement.h"
  13. #include "executable_semantics/interpreter/address.h"
  14. #include "executable_semantics/interpreter/field_path.h"
  15. #include "executable_semantics/interpreter/stack.h"
  16. namespace Carbon {
  17. struct Value;
  18. using VarValues = std::list<std::pair<std::string, const Value*>>;
  19. auto FindInVarValues(const std::string& field, const VarValues& inits)
  20. -> const Value*;
  21. auto FieldsEqual(const VarValues& ts1, const VarValues& ts2) -> bool;
  22. // A TupleElement represents the value of a single tuple field.
  23. struct TupleElement {
  24. // The field name.
  25. std::string name;
  26. // The field's value.
  27. const Value* value;
  28. };
  29. enum class ValKind {
  30. IntValue,
  31. FunctionValue,
  32. PointerValue,
  33. BoolValue,
  34. StructValue,
  35. AlternativeValue,
  36. TupleValue,
  37. IntType,
  38. BoolType,
  39. TypeType,
  40. FunctionType,
  41. PointerType,
  42. AutoType,
  43. StructType,
  44. ChoiceType,
  45. ContinuationType, // The type of a continuation.
  46. BindingPlaceholderValue,
  47. AlternativeConstructorValue,
  48. ContinuationValue // A first-class continuation value.
  49. };
  50. struct Frame; // used by continuation
  51. struct IntValue {
  52. static constexpr ValKind Kind = ValKind::IntValue;
  53. int value;
  54. };
  55. struct FunctionValue {
  56. static constexpr ValKind Kind = ValKind::FunctionValue;
  57. std::string name;
  58. const Value* param;
  59. const Statement* body;
  60. };
  61. struct PointerValue {
  62. static constexpr ValKind Kind = ValKind::PointerValue;
  63. Address value;
  64. };
  65. struct BoolValue {
  66. static constexpr ValKind Kind = ValKind::BoolValue;
  67. bool value;
  68. };
  69. struct StructValue {
  70. static constexpr ValKind Kind = ValKind::StructValue;
  71. const Value* type;
  72. const Value* inits;
  73. };
  74. struct AlternativeConstructorValue {
  75. static constexpr ValKind Kind = ValKind::AlternativeConstructorValue;
  76. std::string alt_name;
  77. std::string choice_name;
  78. };
  79. struct AlternativeValue {
  80. static constexpr ValKind Kind = ValKind::AlternativeValue;
  81. std::string alt_name;
  82. std::string choice_name;
  83. const Value* argument;
  84. };
  85. struct TupleValue {
  86. static constexpr ValKind Kind = ValKind::TupleValue;
  87. std::vector<TupleElement> elements;
  88. // Returns the value of the field named `name` in this tuple, or
  89. // null if there is no such field.
  90. auto FindField(const std::string& name) const -> const Value*;
  91. };
  92. struct BindingPlaceholderValue {
  93. static constexpr ValKind Kind = ValKind::BindingPlaceholderValue;
  94. // nullopt represents the `_` placeholder
  95. std::optional<std::string> name;
  96. const Value* type;
  97. };
  98. struct IntType {
  99. static constexpr ValKind Kind = ValKind::IntType;
  100. };
  101. struct BoolType {
  102. static constexpr ValKind Kind = ValKind::BoolType;
  103. };
  104. struct TypeType {
  105. static constexpr ValKind Kind = ValKind::TypeType;
  106. };
  107. struct FunctionType {
  108. static constexpr ValKind Kind = ValKind::FunctionType;
  109. const Value* param;
  110. const Value* ret;
  111. };
  112. struct PointerType {
  113. static constexpr ValKind Kind = ValKind::PointerType;
  114. const Value* type;
  115. };
  116. struct AutoType {
  117. static constexpr ValKind Kind = ValKind::AutoType;
  118. };
  119. struct StructType {
  120. static constexpr ValKind Kind = ValKind::StructType;
  121. std::string name;
  122. VarValues fields;
  123. VarValues methods;
  124. };
  125. struct ChoiceType {
  126. static constexpr ValKind Kind = ValKind::ChoiceType;
  127. std::string name;
  128. VarValues alternatives;
  129. };
  130. struct ContinuationType {
  131. static constexpr ValKind Kind = ValKind::ContinuationType;
  132. };
  133. struct ContinuationValue {
  134. static constexpr ValKind Kind = ValKind::ContinuationValue;
  135. std::vector<Frame*> stack;
  136. };
  137. struct Value {
  138. // Constructors
  139. // Return a first-class continuation represented by the
  140. // given stack, down to the nearest enclosing `__continuation`.
  141. static auto MakeContinuationValue(std::vector<Frame*> stack) -> Value*;
  142. static auto MakeIntValue(int i) -> const Value*;
  143. static auto MakeBoolValue(bool b) -> const Value*;
  144. static auto MakeFunctionValue(std::string name, const Value* param,
  145. const Statement* body) -> const Value*;
  146. static auto MakePointerValue(Address addr) -> const Value*;
  147. static auto MakeStructValue(const Value* type, const Value* inits)
  148. -> const Value*;
  149. static auto MakeTupleValue(std::vector<TupleElement> elts) -> const Value*;
  150. static auto MakeAlternativeValue(std::string alt_name,
  151. std::string choice_name,
  152. const Value* argument) -> const Value*;
  153. static auto MakeAlternativeConstructorValue(std::string alt_name,
  154. std::string choice_name)
  155. -> const Value*;
  156. static auto MakeBindingPlaceholderValue(std::optional<std::string> name,
  157. const Value* type) -> const Value*;
  158. static auto MakeIntType() -> const Value*;
  159. static auto MakeContinuationType() -> const Value*;
  160. static auto MakeAutoType() -> const Value*;
  161. static auto MakeBoolType() -> const Value*;
  162. static auto MakeTypeType() -> const Value*;
  163. static auto MakeFunctionType(const Value* param, const Value* ret)
  164. -> const Value*;
  165. static auto MakePointerType(const Value* type) -> const Value*;
  166. static auto MakeStructType(std::string name, VarValues fields,
  167. VarValues methods) -> const Value*;
  168. static auto MakeUnitTypeVal() -> const Value*;
  169. static auto MakeChoiceType(std::string name, VarValues alts) -> const Value*;
  170. // Access to alternatives
  171. auto GetIntValue() const -> int;
  172. auto GetBoolValue() const -> bool;
  173. auto GetFunctionValue() const -> const FunctionValue&;
  174. auto GetStructValue() const -> const StructValue&;
  175. auto GetAlternativeConstructorValue() const
  176. -> const AlternativeConstructorValue&;
  177. auto GetAlternativeValue() const -> const AlternativeValue&;
  178. auto GetTupleValue() const -> const TupleValue&;
  179. auto GetPointerValue() const -> Address;
  180. auto GetBindingPlaceholderValue() const -> const BindingPlaceholderValue&;
  181. auto GetFunctionType() const -> const FunctionType&;
  182. auto GetPointerType() const -> const PointerType&;
  183. auto GetStructType() const -> const StructType&;
  184. auto GetChoiceType() const -> const ChoiceType&;
  185. auto GetContinuationValue() const -> const ContinuationValue&;
  186. inline auto tag() const -> ValKind {
  187. return std::visit([](const auto& t) { return t.Kind; }, value);
  188. }
  189. // Returns the sub-Value specified by `path`, which must be a valid field
  190. // path for *this.
  191. auto GetField(const FieldPath& path, int line_num) const -> const Value*;
  192. // Returns a copy of *this, but with the sub-Value specified by `path`
  193. // set to `field_value`. `path` must be a valid field path for *this.
  194. auto SetField(const FieldPath& path, const Value* field_value,
  195. int line_num) const -> const Value*;
  196. void Print(llvm::raw_ostream& out) const;
  197. private:
  198. std::variant<IntValue, FunctionValue, PointerValue, BoolValue, StructValue,
  199. AlternativeValue, TupleValue, IntType, BoolType, TypeType,
  200. FunctionType, PointerType, AutoType, StructType, ChoiceType,
  201. ContinuationType, BindingPlaceholderValue,
  202. AlternativeConstructorValue, ContinuationValue>
  203. value;
  204. };
  205. auto CopyVal(const Value* val, int line_num) -> const Value*;
  206. auto TypeEqual(const Value* t1, const Value* t2) -> bool;
  207. auto ValueEqual(const Value* v1, const Value* v2, int line_num) -> bool;
  208. } // namespace Carbon
  209. #endif // EXECUTABLE_SEMANTICS_INTERPRETER_VALUE_H_