value.h 8.2 KB

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