value.h 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  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. std::string name;
  94. const Value* type;
  95. };
  96. struct IntType {
  97. static constexpr ValKind Kind = ValKind::IntType;
  98. };
  99. struct BoolType {
  100. static constexpr ValKind Kind = ValKind::BoolType;
  101. };
  102. struct TypeType {
  103. static constexpr ValKind Kind = ValKind::TypeType;
  104. };
  105. struct FunctionType {
  106. static constexpr ValKind Kind = ValKind::FunctionType;
  107. const Value* param;
  108. const Value* ret;
  109. };
  110. struct PointerType {
  111. static constexpr ValKind Kind = ValKind::PointerType;
  112. const Value* type;
  113. };
  114. struct AutoType {
  115. static constexpr ValKind Kind = ValKind::AutoType;
  116. };
  117. struct StructType {
  118. static constexpr ValKind Kind = ValKind::StructType;
  119. std::string name;
  120. VarValues fields;
  121. VarValues methods;
  122. };
  123. struct ChoiceType {
  124. static constexpr ValKind Kind = ValKind::ChoiceType;
  125. std::string name;
  126. VarValues alternatives;
  127. };
  128. struct ContinuationType {
  129. static constexpr ValKind Kind = ValKind::ContinuationType;
  130. };
  131. struct ContinuationValue {
  132. static constexpr ValKind Kind = ValKind::ContinuationValue;
  133. std::vector<Frame*> stack;
  134. };
  135. struct Value {
  136. // Constructors
  137. // Return a first-class continuation represented by the
  138. // given stack, down to the nearest enclosing `__continuation`.
  139. static auto MakeContinuationValue(std::vector<Frame*> stack) -> Value*;
  140. static auto MakeIntValue(int i) -> const Value*;
  141. static auto MakeBoolValue(bool b) -> const Value*;
  142. static auto MakeFunctionValue(std::string name, const Value* param,
  143. const Statement* body) -> const Value*;
  144. static auto MakePointerValue(Address addr) -> const Value*;
  145. static auto MakeStructValue(const Value* type, const Value* inits)
  146. -> const Value*;
  147. static auto MakeTupleValue(std::vector<TupleElement> elts) -> const Value*;
  148. static auto MakeAlternativeValue(std::string alt_name,
  149. std::string choice_name,
  150. const Value* argument) -> const Value*;
  151. static auto MakeAlternativeConstructorValue(std::string alt_name,
  152. std::string choice_name)
  153. -> const Value*;
  154. static auto MakeBindingPlaceholderValue(std::string name, const Value* type)
  155. -> const Value*;
  156. static auto MakeIntType() -> const Value*;
  157. static auto MakeContinuationType() -> const Value*;
  158. static auto MakeAutoType() -> const Value*;
  159. static auto MakeBoolType() -> const Value*;
  160. static auto MakeTypeType() -> const Value*;
  161. static auto MakeFunctionType(const Value* param, const Value* ret)
  162. -> const Value*;
  163. static auto MakePointerType(const Value* type) -> const Value*;
  164. static auto MakeStructType(std::string name, VarValues fields,
  165. VarValues methods) -> const Value*;
  166. static auto MakeUnitTypeVal() -> const Value*;
  167. static auto MakeChoiceType(std::string name, VarValues alts) -> const Value*;
  168. // Access to alternatives
  169. auto GetIntValue() const -> int;
  170. auto GetBoolValue() const -> bool;
  171. auto GetFunctionValue() const -> const FunctionValue&;
  172. auto GetStructValue() const -> const StructValue&;
  173. auto GetAlternativeConstructorValue() const
  174. -> const AlternativeConstructorValue&;
  175. auto GetAlternativeValue() const -> const AlternativeValue&;
  176. auto GetTupleValue() const -> const TupleValue&;
  177. auto GetPointerValue() const -> Address;
  178. auto GetBindingPlaceholderValue() const -> const BindingPlaceholderValue&;
  179. auto GetFunctionType() const -> const FunctionType&;
  180. auto GetPointerType() const -> const PointerType&;
  181. auto GetStructType() const -> const StructType&;
  182. auto GetChoiceType() const -> const ChoiceType&;
  183. auto GetContinuationValue() const -> const ContinuationValue&;
  184. inline auto tag() const -> ValKind {
  185. return std::visit([](const auto& t) { return t.Kind; }, value);
  186. }
  187. // Returns the sub-Value specified by `path`, which must be a valid field
  188. // path for *this.
  189. auto GetField(const FieldPath& path, int line_num) const -> const Value*;
  190. // Returns a copy of *this, but with the sub-Value specified by `path`
  191. // set to `field_value`. `path` must be a valid field path for *this.
  192. auto SetField(const FieldPath& path, const Value* field_value,
  193. int line_num) const -> const Value*;
  194. private:
  195. std::variant<IntValue, FunctionValue, PointerValue, BoolValue, StructValue,
  196. AlternativeValue, TupleValue, IntType, BoolType, TypeType,
  197. FunctionType, PointerType, AutoType, StructType, ChoiceType,
  198. ContinuationType, BindingPlaceholderValue,
  199. AlternativeConstructorValue, ContinuationValue>
  200. value;
  201. };
  202. void PrintValue(const Value* val, std::ostream& out);
  203. auto TypeEqual(const Value* t1, const Value* t2) -> bool;
  204. auto ValueEqual(const Value* v1, const Value* v2, int line_num) -> bool;
  205. auto ToInteger(const Value* v) -> int;
  206. } // namespace Carbon
  207. #endif // EXECUTABLE_SEMANTICS_INTERPRETER_VALUE_H_