value.h 7.6 KB

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