value.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464
  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. #include "executable_semantics/interpreter/value.h"
  5. #include <algorithm>
  6. #include <iostream>
  7. #include "common/check.h"
  8. #include "executable_semantics/interpreter/interpreter.h"
  9. namespace Carbon {
  10. auto Value::GetIntValue() const -> int {
  11. return std::get<IntValue>(value).value;
  12. }
  13. auto Value::GetBoolValue() const -> bool {
  14. return std::get<BoolValue>(value).value;
  15. }
  16. auto Value::GetFunctionValue() const -> const FunctionValue& {
  17. return std::get<FunctionValue>(value);
  18. }
  19. auto Value::GetStructValue() const -> const StructValue& {
  20. return std::get<StructValue>(value);
  21. }
  22. auto Value::GetAlternativeConstructorValue() const
  23. -> const AlternativeConstructorValue& {
  24. return std::get<AlternativeConstructorValue>(value);
  25. }
  26. auto Value::GetAlternativeValue() const -> const AlternativeValue& {
  27. return std::get<AlternativeValue>(value);
  28. }
  29. auto Value::GetTupleValue() const -> const TupleValue& {
  30. return std::get<TupleValue>(value);
  31. }
  32. auto Value::GetPointerValue() const -> Address {
  33. return std::get<PointerValue>(value).value;
  34. }
  35. auto Value::GetBindingPlaceholderValue() const
  36. -> const BindingPlaceholderValue& {
  37. return std::get<BindingPlaceholderValue>(value);
  38. }
  39. auto Value::GetFunctionType() const -> const FunctionType& {
  40. return std::get<FunctionType>(value);
  41. }
  42. auto Value::GetPointerType() const -> const PointerType& {
  43. return std::get<PointerType>(value);
  44. }
  45. auto Value::GetStructType() const -> const StructType& {
  46. return std::get<StructType>(value);
  47. }
  48. auto Value::GetChoiceType() const -> const ChoiceType& {
  49. return std::get<ChoiceType>(value);
  50. }
  51. auto Value::GetContinuationValue() const -> const ContinuationValue& {
  52. return std::get<ContinuationValue>(value);
  53. }
  54. auto FindInVarValues(const std::string& field, const VarValues& inits)
  55. -> const Value* {
  56. for (auto& i : inits) {
  57. if (i.first == field) {
  58. return i.second;
  59. }
  60. }
  61. return nullptr;
  62. }
  63. auto FieldsEqual(const VarValues& ts1, const VarValues& ts2) -> bool {
  64. if (ts1.size() == ts2.size()) {
  65. for (auto& iter1 : ts1) {
  66. auto t2 = FindInVarValues(iter1.first, ts2);
  67. if (t2 == nullptr) {
  68. return false;
  69. }
  70. if (!TypeEqual(iter1.second, t2)) {
  71. return false;
  72. }
  73. }
  74. return true;
  75. } else {
  76. return false;
  77. }
  78. }
  79. auto FindTupleField(const std::string& name, const Value* tuple)
  80. -> std::optional<Address> {
  81. CHECK(tuple->tag() == ValKind::TupleValue);
  82. for (const TupleElement& element : tuple->GetTupleValue().elements) {
  83. if (element.name == name) {
  84. return element.address;
  85. }
  86. }
  87. return std::nullopt;
  88. }
  89. auto Value::MakeIntValue(int i) -> const Value* {
  90. auto* v = new Value();
  91. v->value = IntValue({.value = i});
  92. return v;
  93. }
  94. auto Value::MakeBoolValue(bool b) -> const Value* {
  95. auto* v = new Value();
  96. v->value = BoolValue({.value = b});
  97. return v;
  98. }
  99. auto Value::MakeFunctionValue(std::string name, const Value* param,
  100. const Statement* body) -> const Value* {
  101. auto* v = new Value();
  102. v->value =
  103. FunctionValue({.name = std::move(name), .param = param, .body = body});
  104. return v;
  105. }
  106. auto Value::MakePointerValue(Address addr) -> const Value* {
  107. auto* v = new Value();
  108. v->value = PointerValue({.value = addr});
  109. return v;
  110. }
  111. auto Value::MakeStructValue(const Value* type, const Value* inits)
  112. -> const Value* {
  113. auto* v = new Value();
  114. v->value = StructValue({.type = type, .inits = inits});
  115. return v;
  116. }
  117. auto Value::MakeTupleValue(std::vector<TupleElement> elements) -> const Value* {
  118. auto* v = new Value();
  119. v->value = TupleValue({.elements = std::move(elements)});
  120. return v;
  121. }
  122. auto Value::MakeAlternativeValue(std::string alt_name, std::string choice_name,
  123. Address argument) -> const Value* {
  124. auto* v = new Value();
  125. v->value = AlternativeValue({.alt_name = std::move(alt_name),
  126. .choice_name = std::move(choice_name),
  127. .argument = argument});
  128. return v;
  129. }
  130. auto Value::MakeAlternativeConstructorValue(std::string alt_name,
  131. std::string choice_name)
  132. -> const Value* {
  133. auto* v = new Value();
  134. v->value = AlternativeConstructorValue(
  135. {.alt_name = std::move(alt_name), .choice_name = std::move(choice_name)});
  136. return v;
  137. }
  138. // Return a first-class continuation represented a fragment
  139. // of the stack.
  140. auto Value::MakeContinuationValue(std::vector<Frame*> stack) -> Value* {
  141. auto* v = new Value();
  142. v->value = ContinuationValue({.stack = std::move(stack)});
  143. return v;
  144. }
  145. auto Value::MakeBindingPlaceholderValue(std::string name, const Value* type)
  146. -> const Value* {
  147. auto* v = new Value();
  148. v->value = BindingPlaceholderValue({.name = std::move(name), .type = type});
  149. return v;
  150. }
  151. auto Value::MakeIntType() -> const Value* {
  152. auto* v = new Value();
  153. v->value = IntType();
  154. return v;
  155. }
  156. auto Value::MakeBoolType() -> const Value* {
  157. auto* v = new Value();
  158. v->value = BoolType();
  159. return v;
  160. }
  161. auto Value::MakeTypeType() -> const Value* {
  162. auto* v = new Value();
  163. v->value = TypeType();
  164. return v;
  165. }
  166. // Return a Continuation type.
  167. auto Value::MakeContinuationType() -> const Value* {
  168. auto* v = new Value();
  169. v->value = ContinuationType();
  170. return v;
  171. }
  172. auto Value::MakeAutoType() -> const Value* {
  173. auto* v = new Value();
  174. v->value = AutoType();
  175. return v;
  176. }
  177. auto Value::MakeFunctionType(const Value* param, const Value* ret)
  178. -> const Value* {
  179. auto* v = new Value();
  180. v->value = FunctionType({.param = param, .ret = ret});
  181. return v;
  182. }
  183. auto Value::MakePointerType(const Value* type) -> const Value* {
  184. auto* v = new Value();
  185. v->value = PointerType({.type = type});
  186. return v;
  187. }
  188. auto Value::MakeStructType(std::string name, VarValues fields,
  189. VarValues methods) -> const Value* {
  190. auto* v = new Value();
  191. v->value = StructType({.name = std::move(name),
  192. .fields = std::move(fields),
  193. .methods = std::move(methods)});
  194. return v;
  195. }
  196. auto Value::MakeUnitTypeVal() -> const Value* {
  197. auto* v = new Value();
  198. v->value = TupleValue({.elements = {}});
  199. return v;
  200. }
  201. auto Value::MakeChoiceType(std::string name, VarValues alts) -> const Value* {
  202. auto* v = new Value();
  203. v->value =
  204. ChoiceType({.name = std::move(name), .alternatives = std::move(alts)});
  205. return v;
  206. }
  207. auto PrintValue(const Value* val, std::ostream& out) -> void {
  208. switch (val->tag()) {
  209. case ValKind::AlternativeConstructorValue: {
  210. out << val->GetAlternativeConstructorValue().choice_name << "."
  211. << val->GetAlternativeConstructorValue().alt_name;
  212. break;
  213. }
  214. case ValKind::BindingPlaceholderValue: {
  215. PrintValue(val->GetBindingPlaceholderValue().type, out);
  216. out << ": " << val->GetBindingPlaceholderValue().name;
  217. break;
  218. }
  219. case ValKind::AlternativeValue: {
  220. out << "alt " << val->GetAlternativeValue().choice_name << "."
  221. << val->GetAlternativeValue().alt_name << " ";
  222. state->heap.PrintAddress(val->GetAlternativeValue().argument, out);
  223. break;
  224. }
  225. case ValKind::StructValue: {
  226. out << val->GetStructValue().type->GetStructType().name;
  227. PrintValue(val->GetStructValue().inits, out);
  228. break;
  229. }
  230. case ValKind::TupleValue: {
  231. out << "(";
  232. bool add_commas = false;
  233. for (const TupleElement& element : val->GetTupleValue().elements) {
  234. if (add_commas) {
  235. out << ", ";
  236. } else {
  237. add_commas = true;
  238. }
  239. out << element.name << " = ";
  240. state->heap.PrintAddress(element.address, out);
  241. }
  242. out << ")";
  243. break;
  244. }
  245. case ValKind::IntValue:
  246. out << val->GetIntValue();
  247. break;
  248. case ValKind::BoolValue:
  249. out << std::boolalpha << val->GetBoolValue();
  250. break;
  251. case ValKind::FunctionValue:
  252. out << "fun<" << val->GetFunctionValue().name << ">";
  253. break;
  254. case ValKind::PointerValue:
  255. out << "ptr<" << val->GetPointerValue() << ">";
  256. break;
  257. case ValKind::BoolType:
  258. out << "Bool";
  259. break;
  260. case ValKind::IntType:
  261. out << "Int";
  262. break;
  263. case ValKind::TypeType:
  264. out << "Type";
  265. break;
  266. case ValKind::AutoType:
  267. out << "auto";
  268. break;
  269. case ValKind::ContinuationType:
  270. out << "Continuation";
  271. break;
  272. case ValKind::PointerType:
  273. PrintValue(val->GetPointerType().type, out);
  274. out << "*";
  275. break;
  276. case ValKind::FunctionType:
  277. out << "fn ";
  278. PrintValue(val->GetFunctionType().param, out);
  279. out << " -> ";
  280. PrintValue(val->GetFunctionType().ret, out);
  281. break;
  282. case ValKind::StructType:
  283. out << "struct " << val->GetStructType().name;
  284. break;
  285. case ValKind::ChoiceType:
  286. out << "choice " << val->GetChoiceType().name;
  287. break;
  288. case ValKind::ContinuationValue:
  289. out << "continuation[[";
  290. for (Frame* frame : val->GetContinuationValue().stack) {
  291. PrintFrame(frame, out);
  292. out << " :: ";
  293. }
  294. out << "]]";
  295. break;
  296. }
  297. }
  298. auto TypeEqual(const Value* t1, const Value* t2) -> bool {
  299. if (t1->tag() != t2->tag()) {
  300. return false;
  301. }
  302. switch (t1->tag()) {
  303. case ValKind::PointerType:
  304. return TypeEqual(t1->GetPointerType().type, t2->GetPointerType().type);
  305. case ValKind::FunctionType:
  306. return TypeEqual(t1->GetFunctionType().param,
  307. t2->GetFunctionType().param) &&
  308. TypeEqual(t1->GetFunctionType().ret, t2->GetFunctionType().ret);
  309. case ValKind::StructType:
  310. return t1->GetStructType().name == t2->GetStructType().name;
  311. case ValKind::ChoiceType:
  312. return t1->GetChoiceType().name == t2->GetChoiceType().name;
  313. case ValKind::TupleValue: {
  314. if (t1->GetTupleValue().elements.size() !=
  315. t2->GetTupleValue().elements.size()) {
  316. return false;
  317. }
  318. for (size_t i = 0; i < t1->GetTupleValue().elements.size(); ++i) {
  319. if (t1->GetTupleValue().elements[i].name !=
  320. t2->GetTupleValue().elements[i].name) {
  321. return false;
  322. }
  323. if (!TypeEqual(
  324. state->heap.Read(t1->GetTupleValue().elements[i].address, 0),
  325. state->heap.Read(t2->GetTupleValue().elements[i].address, 0))) {
  326. return false;
  327. }
  328. }
  329. return true;
  330. }
  331. case ValKind::IntType:
  332. case ValKind::BoolType:
  333. case ValKind::ContinuationType:
  334. case ValKind::TypeType:
  335. return true;
  336. default:
  337. std::cerr << "TypeEqual used to compare non-type values" << std::endl;
  338. PrintValue(t1, std::cerr);
  339. std::cerr << std::endl;
  340. PrintValue(t2, std::cerr);
  341. exit(-1);
  342. }
  343. }
  344. // Returns true if all the fields of the two tuples contain equal values
  345. // and returns false otherwise.
  346. static auto FieldsValueEqual(const std::vector<TupleElement>& ts1,
  347. const std::vector<TupleElement>& ts2, int line_num)
  348. -> bool {
  349. if (ts1.size() != ts2.size()) {
  350. return false;
  351. }
  352. for (const TupleElement& element : ts1) {
  353. auto iter = std::find_if(
  354. ts2.begin(), ts2.end(),
  355. [&](const TupleElement& e2) { return e2.name == element.name; });
  356. if (iter == ts2.end()) {
  357. return false;
  358. }
  359. if (!ValueEqual(state->heap.Read(element.address, line_num),
  360. state->heap.Read(iter->address, line_num), line_num)) {
  361. return false;
  362. }
  363. }
  364. return true;
  365. }
  366. // Returns true if the two values are equal and returns false otherwise.
  367. //
  368. // This function implements the `==` operator of Carbon.
  369. auto ValueEqual(const Value* v1, const Value* v2, int line_num) -> bool {
  370. if (v1->tag() != v2->tag()) {
  371. return false;
  372. }
  373. switch (v1->tag()) {
  374. case ValKind::IntValue:
  375. return v1->GetIntValue() == v2->GetIntValue();
  376. case ValKind::BoolValue:
  377. return v1->GetBoolValue() == v2->GetBoolValue();
  378. case ValKind::PointerValue:
  379. return v1->GetPointerValue() == v2->GetPointerValue();
  380. case ValKind::FunctionValue:
  381. return v1->GetFunctionValue().body == v2->GetFunctionValue().body;
  382. case ValKind::TupleValue:
  383. return FieldsValueEqual(v1->GetTupleValue().elements,
  384. v2->GetTupleValue().elements, line_num);
  385. default:
  386. case ValKind::IntType:
  387. case ValKind::BoolType:
  388. case ValKind::TypeType:
  389. case ValKind::FunctionType:
  390. case ValKind::PointerType:
  391. case ValKind::AutoType:
  392. case ValKind::StructType:
  393. case ValKind::ChoiceType:
  394. case ValKind::ContinuationType:
  395. return TypeEqual(v1, v2);
  396. case ValKind::StructValue:
  397. case ValKind::AlternativeValue:
  398. case ValKind::BindingPlaceholderValue:
  399. case ValKind::AlternativeConstructorValue:
  400. case ValKind::ContinuationValue:
  401. std::cerr << "ValueEqual does not support this kind of value."
  402. << std::endl;
  403. exit(-1);
  404. }
  405. }
  406. auto ToInteger(const Value* v) -> int {
  407. switch (v->tag()) {
  408. case ValKind::IntValue:
  409. return v->GetIntValue();
  410. default:
  411. std::cerr << "expected an integer, not ";
  412. PrintValue(v, std::cerr);
  413. exit(-1);
  414. }
  415. }
  416. } // namespace Carbon