value.cpp 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617
  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 "common/check.h"
  7. #include "executable_semantics/common/arena.h"
  8. #include "executable_semantics/common/error.h"
  9. #include "llvm/ADT/StringExtras.h"
  10. namespace Carbon {
  11. auto Value::GetIntValue() const -> int {
  12. return std::get<IntValue>(value).value;
  13. }
  14. auto Value::GetBoolValue() const -> bool {
  15. return std::get<BoolValue>(value).value;
  16. }
  17. auto Value::GetFunctionValue() const -> const FunctionValue& {
  18. return std::get<FunctionValue>(value);
  19. }
  20. auto Value::GetStructValue() const -> const StructValue& {
  21. return std::get<StructValue>(value);
  22. }
  23. auto Value::GetAlternativeConstructorValue() const
  24. -> const AlternativeConstructorValue& {
  25. return std::get<AlternativeConstructorValue>(value);
  26. }
  27. auto Value::GetAlternativeValue() const -> const AlternativeValue& {
  28. return std::get<AlternativeValue>(value);
  29. }
  30. auto Value::GetTupleValue() const -> const TupleValue& {
  31. return std::get<TupleValue>(value);
  32. }
  33. auto Value::GetPointerValue() const -> Address {
  34. return std::get<PointerValue>(value).value;
  35. }
  36. auto Value::GetBindingPlaceholderValue() const
  37. -> const BindingPlaceholderValue& {
  38. return std::get<BindingPlaceholderValue>(value);
  39. }
  40. auto Value::GetFunctionType() const -> const FunctionType& {
  41. return std::get<FunctionType>(value);
  42. }
  43. auto Value::GetPointerType() const -> const PointerType& {
  44. return std::get<PointerType>(value);
  45. }
  46. auto Value::GetStructType() const -> const StructType& {
  47. return std::get<StructType>(value);
  48. }
  49. auto Value::GetChoiceType() const -> const ChoiceType& {
  50. return std::get<ChoiceType>(value);
  51. }
  52. auto Value::GetVariableType() const -> const VariableType& {
  53. return std::get<VariableType>(value);
  54. }
  55. auto Value::GetContinuationValue() const -> const ContinuationValue& {
  56. return std::get<ContinuationValue>(value);
  57. }
  58. auto FindInVarValues(const std::string& field, const VarValues& inits)
  59. -> const Value* {
  60. for (auto& i : inits) {
  61. if (i.first == field) {
  62. return i.second;
  63. }
  64. }
  65. return nullptr;
  66. }
  67. auto FieldsEqual(const VarValues& ts1, const VarValues& ts2) -> bool {
  68. if (ts1.size() == ts2.size()) {
  69. for (auto& iter1 : ts1) {
  70. auto t2 = FindInVarValues(iter1.first, ts2);
  71. if (t2 == nullptr) {
  72. return false;
  73. }
  74. if (!TypeEqual(iter1.second, t2)) {
  75. return false;
  76. }
  77. }
  78. return true;
  79. } else {
  80. return false;
  81. }
  82. }
  83. auto TupleValue::FindField(const std::string& name) const -> const Value* {
  84. for (const TupleElement& element : elements) {
  85. if (element.name == name) {
  86. return element.value;
  87. }
  88. }
  89. return nullptr;
  90. }
  91. auto Value::MakeIntValue(int i) -> const Value* {
  92. auto* v = global_arena->New<Value>();
  93. v->value = IntValue({.value = i});
  94. return v;
  95. }
  96. auto Value::MakeBoolValue(bool b) -> const Value* {
  97. auto* v = global_arena->New<Value>();
  98. v->value = BoolValue({.value = b});
  99. return v;
  100. }
  101. auto Value::MakeFunctionValue(std::string name, const Value* param,
  102. const Statement* body) -> const Value* {
  103. auto* v = global_arena->New<Value>();
  104. v->value =
  105. FunctionValue({.name = std::move(name), .param = param, .body = body});
  106. return v;
  107. }
  108. auto Value::MakePointerValue(Address addr) -> const Value* {
  109. auto* v = global_arena->New<Value>();
  110. v->value = PointerValue({.value = addr});
  111. return v;
  112. }
  113. auto Value::MakeStructValue(const Value* type, const Value* inits)
  114. -> const Value* {
  115. auto* v = global_arena->New<Value>();
  116. v->value = StructValue({.type = type, .inits = inits});
  117. return v;
  118. }
  119. auto Value::MakeTupleValue(std::vector<TupleElement> elements) -> const Value* {
  120. auto* v = global_arena->New<Value>();
  121. v->value = TupleValue({.elements = std::move(elements)});
  122. return v;
  123. }
  124. auto Value::MakeAlternativeValue(std::string alt_name, std::string choice_name,
  125. const Value* argument) -> const Value* {
  126. auto* v = global_arena->New<Value>();
  127. v->value = AlternativeValue({.alt_name = std::move(alt_name),
  128. .choice_name = std::move(choice_name),
  129. .argument = argument});
  130. return v;
  131. }
  132. auto Value::MakeAlternativeConstructorValue(std::string alt_name,
  133. std::string choice_name)
  134. -> const Value* {
  135. auto* v = global_arena->New<Value>();
  136. v->value = AlternativeConstructorValue(
  137. {.alt_name = std::move(alt_name), .choice_name = std::move(choice_name)});
  138. return v;
  139. }
  140. // Return a first-class continuation represented a fragment
  141. // of the stack.
  142. auto Value::MakeContinuationValue(std::vector<Frame*> stack) -> Value* {
  143. auto* v = global_arena->New<Value>();
  144. v->value = ContinuationValue({.stack = std::move(stack)});
  145. return v;
  146. }
  147. auto Value::MakeBindingPlaceholderValue(std::optional<std::string> name,
  148. const Value* type) -> const Value* {
  149. auto* v = global_arena->New<Value>();
  150. v->value = BindingPlaceholderValue({.name = std::move(name), .type = type});
  151. return v;
  152. }
  153. auto Value::MakeIntType() -> const Value* {
  154. auto* v = global_arena->New<Value>();
  155. v->value = IntType();
  156. return v;
  157. }
  158. auto Value::MakeBoolType() -> const Value* {
  159. auto* v = global_arena->New<Value>();
  160. v->value = BoolType();
  161. return v;
  162. }
  163. auto Value::MakeTypeType() -> const Value* {
  164. auto* v = global_arena->New<Value>();
  165. v->value = TypeType();
  166. return v;
  167. }
  168. // Return a Continuation type.
  169. auto Value::MakeContinuationType() -> const Value* {
  170. auto* v = global_arena->New<Value>();
  171. v->value = ContinuationType();
  172. return v;
  173. }
  174. auto Value::MakeAutoType() -> const Value* {
  175. auto* v = global_arena->New<Value>();
  176. v->value = AutoType();
  177. return v;
  178. }
  179. auto Value::MakeFunctionType(std::vector<GenericBinding> deduced_params,
  180. const Value* param, const Value* ret)
  181. -> const Value* {
  182. auto* v = global_arena->New<Value>();
  183. v->value = FunctionType(
  184. {.deduced = std::move(deduced_params), .param = param, .ret = ret});
  185. return v;
  186. }
  187. auto Value::MakePointerType(const Value* type) -> const Value* {
  188. auto* v = global_arena->New<Value>();
  189. v->value = PointerType({.type = type});
  190. return v;
  191. }
  192. auto Value::MakeStructType(std::string name, VarValues fields,
  193. VarValues methods) -> const Value* {
  194. auto* v = global_arena->New<Value>();
  195. v->value = StructType({.name = std::move(name),
  196. .fields = std::move(fields),
  197. .methods = std::move(methods)});
  198. return v;
  199. }
  200. auto Value::MakeUnitTypeVal() -> const Value* {
  201. auto* v = global_arena->New<Value>();
  202. v->value = TupleValue({.elements = {}});
  203. return v;
  204. }
  205. auto Value::MakeChoiceType(std::string name, VarValues alts) -> const Value* {
  206. auto* v = global_arena->New<Value>();
  207. v->value =
  208. ChoiceType({.name = std::move(name), .alternatives = std::move(alts)});
  209. return v;
  210. }
  211. auto Value::MakeVariableType(std::string name) -> const Value* {
  212. auto* v = global_arena->New<Value>();
  213. v->value = VariableType({.name = std::move(name)});
  214. return v;
  215. }
  216. namespace {
  217. auto GetMember(const Value* v, const std::string& f, int line_num)
  218. -> const Value* {
  219. switch (v->tag()) {
  220. case ValKind::StructValue: {
  221. const Value* field =
  222. v->GetStructValue().inits->GetTupleValue().FindField(f);
  223. if (field == nullptr) {
  224. FATAL_RUNTIME_ERROR(line_num) << "member " << f << " not in " << *v;
  225. }
  226. return field;
  227. }
  228. case ValKind::TupleValue: {
  229. const Value* field = v->GetTupleValue().FindField(f);
  230. if (field == nullptr) {
  231. FATAL_RUNTIME_ERROR(line_num) << "field " << f << " not in " << *v;
  232. }
  233. return field;
  234. }
  235. case ValKind::ChoiceType: {
  236. if (FindInVarValues(f, v->GetChoiceType().alternatives) == nullptr) {
  237. FATAL_RUNTIME_ERROR(line_num)
  238. << "alternative " << f << " not in " << *v;
  239. }
  240. return Value::MakeAlternativeConstructorValue(f, v->GetChoiceType().name);
  241. }
  242. default:
  243. llvm::errs() << "field access not allowed for value " << *v << "\n";
  244. exit(-1);
  245. }
  246. }
  247. } // namespace
  248. auto Value::GetField(const FieldPath& path, int line_num) const
  249. -> const Value* {
  250. const Value* value = this;
  251. for (const std::string& field : path.components) {
  252. value = GetMember(value, field, line_num);
  253. }
  254. return value;
  255. }
  256. namespace {
  257. auto SetFieldImpl(const Value* value,
  258. std::vector<std::string>::const_iterator path_begin,
  259. std::vector<std::string>::const_iterator path_end,
  260. const Value* field_value, int line_num) -> const Value* {
  261. if (path_begin == path_end) {
  262. return field_value;
  263. }
  264. switch (value->tag()) {
  265. case ValKind::StructValue: {
  266. return SetFieldImpl(value->GetStructValue().inits, path_begin, path_end,
  267. field_value, line_num);
  268. }
  269. case ValKind::TupleValue: {
  270. std::vector<TupleElement> elements = value->GetTupleValue().elements;
  271. auto it = std::find_if(elements.begin(), elements.end(),
  272. [path_begin](const TupleElement& element) {
  273. return element.name == *path_begin;
  274. });
  275. if (it == elements.end()) {
  276. FATAL_RUNTIME_ERROR(line_num)
  277. << "field " << *path_begin << " not in " << *value;
  278. }
  279. it->value = SetFieldImpl(it->value, path_begin + 1, path_end, field_value,
  280. line_num);
  281. return Value::MakeTupleValue(elements);
  282. }
  283. default:
  284. llvm::errs() << "field access not allowed for value " << *value << "\n";
  285. exit(-1);
  286. }
  287. }
  288. } // namespace
  289. auto Value::SetField(const FieldPath& path, const Value* field_value,
  290. int line_num) const -> const Value* {
  291. return SetFieldImpl(this, path.components.begin(), path.components.end(),
  292. field_value, line_num);
  293. }
  294. void Value::Print(llvm::raw_ostream& out) const {
  295. switch (tag()) {
  296. case ValKind::AlternativeConstructorValue: {
  297. out << GetAlternativeConstructorValue().choice_name << "."
  298. << GetAlternativeConstructorValue().alt_name;
  299. break;
  300. }
  301. case ValKind::BindingPlaceholderValue: {
  302. const BindingPlaceholderValue& placeholder = GetBindingPlaceholderValue();
  303. if (placeholder.name.has_value()) {
  304. out << *placeholder.name;
  305. } else {
  306. out << "_";
  307. }
  308. out << ": " << *placeholder.type;
  309. break;
  310. }
  311. case ValKind::AlternativeValue: {
  312. out << "alt " << GetAlternativeValue().choice_name << "."
  313. << GetAlternativeValue().alt_name << " "
  314. << *GetAlternativeValue().argument;
  315. break;
  316. }
  317. case ValKind::StructValue: {
  318. out << GetStructValue().type->GetStructType().name
  319. << *GetStructValue().inits;
  320. break;
  321. }
  322. case ValKind::TupleValue: {
  323. out << "(";
  324. llvm::ListSeparator sep;
  325. for (const TupleElement& element : GetTupleValue().elements) {
  326. out << sep << element.name << " = " << *element.value;
  327. }
  328. out << ")";
  329. break;
  330. }
  331. case ValKind::IntValue:
  332. out << GetIntValue();
  333. break;
  334. case ValKind::BoolValue:
  335. out << (GetBoolValue() ? "true" : "false");
  336. break;
  337. case ValKind::FunctionValue:
  338. out << "fun<" << GetFunctionValue().name << ">";
  339. break;
  340. case ValKind::PointerValue:
  341. out << "ptr<" << GetPointerValue() << ">";
  342. break;
  343. case ValKind::BoolType:
  344. out << "Bool";
  345. break;
  346. case ValKind::IntType:
  347. out << "Int";
  348. break;
  349. case ValKind::TypeType:
  350. out << "Type";
  351. break;
  352. case ValKind::AutoType:
  353. out << "auto";
  354. break;
  355. case ValKind::ContinuationType:
  356. out << "Continuation";
  357. break;
  358. case ValKind::PointerType:
  359. out << *GetPointerType().type << "*";
  360. break;
  361. case ValKind::FunctionType:
  362. out << "fn ";
  363. if (GetFunctionType().deduced.size() > 0) {
  364. out << "[";
  365. unsigned int i = 0;
  366. for (const auto& deduced : GetFunctionType().deduced) {
  367. if (i != 0) {
  368. out << ", ";
  369. }
  370. out << deduced.name << ":! " << *deduced.type;
  371. ++i;
  372. }
  373. out << "]";
  374. }
  375. out << *GetFunctionType().param << " -> " << *GetFunctionType().ret;
  376. break;
  377. case ValKind::StructType:
  378. out << "struct " << GetStructType().name;
  379. break;
  380. case ValKind::ChoiceType:
  381. out << "choice " << GetChoiceType().name;
  382. break;
  383. case ValKind::VariableType:
  384. out << GetVariableType().name;
  385. break;
  386. case ValKind::ContinuationValue:
  387. out << "continuation";
  388. // TODO: Find a way to print useful information about the continuation
  389. // without creating a dependency cycle.
  390. break;
  391. }
  392. }
  393. auto CopyVal(const Value* val, int line_num) -> const Value* {
  394. switch (val->tag()) {
  395. case ValKind::TupleValue: {
  396. std::vector<TupleElement> elements;
  397. for (const TupleElement& element : val->GetTupleValue().elements) {
  398. elements.push_back(
  399. {.name = element.name, .value = CopyVal(element.value, line_num)});
  400. }
  401. return Value::MakeTupleValue(std::move(elements));
  402. }
  403. case ValKind::AlternativeValue: {
  404. const Value* arg = CopyVal(val->GetAlternativeValue().argument, line_num);
  405. return Value::MakeAlternativeValue(val->GetAlternativeValue().alt_name,
  406. val->GetAlternativeValue().choice_name,
  407. arg);
  408. }
  409. case ValKind::StructValue: {
  410. const Value* inits = CopyVal(val->GetStructValue().inits, line_num);
  411. return Value::MakeStructValue(val->GetStructValue().type, inits);
  412. }
  413. case ValKind::IntValue:
  414. return Value::MakeIntValue(val->GetIntValue());
  415. case ValKind::BoolValue:
  416. return Value::MakeBoolValue(val->GetBoolValue());
  417. case ValKind::FunctionValue:
  418. return Value::MakeFunctionValue(val->GetFunctionValue().name,
  419. val->GetFunctionValue().param,
  420. val->GetFunctionValue().body);
  421. case ValKind::PointerValue:
  422. return Value::MakePointerValue(val->GetPointerValue());
  423. case ValKind::ContinuationValue:
  424. // Copying a continuation is "shallow".
  425. return val;
  426. case ValKind::FunctionType:
  427. return Value::MakeFunctionType(
  428. val->GetFunctionType().deduced,
  429. CopyVal(val->GetFunctionType().param, line_num),
  430. CopyVal(val->GetFunctionType().ret, line_num));
  431. case ValKind::PointerType:
  432. return Value::MakePointerType(
  433. CopyVal(val->GetPointerType().type, line_num));
  434. case ValKind::IntType:
  435. return Value::MakeIntType();
  436. case ValKind::BoolType:
  437. return Value::MakeBoolType();
  438. case ValKind::TypeType:
  439. return Value::MakeTypeType();
  440. case ValKind::AutoType:
  441. return Value::MakeAutoType();
  442. case ValKind::ContinuationType:
  443. return Value::MakeContinuationType();
  444. case ValKind::VariableType:
  445. case ValKind::StructType:
  446. case ValKind::ChoiceType:
  447. case ValKind::BindingPlaceholderValue:
  448. case ValKind::AlternativeConstructorValue:
  449. // TODO: These should be copied so that they don't get destructed.
  450. return val;
  451. }
  452. }
  453. auto TypeEqual(const Value* t1, const Value* t2) -> bool {
  454. if (t1->tag() != t2->tag()) {
  455. return false;
  456. }
  457. switch (t1->tag()) {
  458. case ValKind::PointerType:
  459. return TypeEqual(t1->GetPointerType().type, t2->GetPointerType().type);
  460. case ValKind::FunctionType:
  461. return TypeEqual(t1->GetFunctionType().param,
  462. t2->GetFunctionType().param) &&
  463. TypeEqual(t1->GetFunctionType().ret, t2->GetFunctionType().ret);
  464. case ValKind::StructType:
  465. return t1->GetStructType().name == t2->GetStructType().name;
  466. case ValKind::ChoiceType:
  467. return t1->GetChoiceType().name == t2->GetChoiceType().name;
  468. case ValKind::TupleValue: {
  469. if (t1->GetTupleValue().elements.size() !=
  470. t2->GetTupleValue().elements.size()) {
  471. return false;
  472. }
  473. for (size_t i = 0; i < t1->GetTupleValue().elements.size(); ++i) {
  474. if (t1->GetTupleValue().elements[i].name !=
  475. t2->GetTupleValue().elements[i].name) {
  476. return false;
  477. }
  478. if (!TypeEqual(t1->GetTupleValue().elements[i].value,
  479. t2->GetTupleValue().elements[i].value)) {
  480. return false;
  481. }
  482. }
  483. return true;
  484. }
  485. case ValKind::IntType:
  486. case ValKind::BoolType:
  487. case ValKind::ContinuationType:
  488. case ValKind::TypeType:
  489. return true;
  490. case ValKind::VariableType:
  491. return t1->GetVariableType().name == t2->GetVariableType().name;
  492. default:
  493. llvm::errs() << "TypeEqual used to compare non-type values\n"
  494. << *t1 << "\n"
  495. << *t2 << "\n";
  496. exit(-1);
  497. }
  498. }
  499. // Returns true if all the fields of the two tuples contain equal values
  500. // and returns false otherwise.
  501. static auto FieldsValueEqual(const std::vector<TupleElement>& ts1,
  502. const std::vector<TupleElement>& ts2, int line_num)
  503. -> bool {
  504. if (ts1.size() != ts2.size()) {
  505. return false;
  506. }
  507. for (const TupleElement& element : ts1) {
  508. auto iter = std::find_if(
  509. ts2.begin(), ts2.end(),
  510. [&](const TupleElement& e2) { return e2.name == element.name; });
  511. if (iter == ts2.end()) {
  512. return false;
  513. }
  514. if (!ValueEqual(element.value, iter->value, line_num)) {
  515. return false;
  516. }
  517. }
  518. return true;
  519. }
  520. // Returns true if the two values are equal and returns false otherwise.
  521. //
  522. // This function implements the `==` operator of Carbon.
  523. auto ValueEqual(const Value* v1, const Value* v2, int line_num) -> bool {
  524. if (v1->tag() != v2->tag()) {
  525. return false;
  526. }
  527. switch (v1->tag()) {
  528. case ValKind::IntValue:
  529. return v1->GetIntValue() == v2->GetIntValue();
  530. case ValKind::BoolValue:
  531. return v1->GetBoolValue() == v2->GetBoolValue();
  532. case ValKind::PointerValue:
  533. return v1->GetPointerValue() == v2->GetPointerValue();
  534. case ValKind::FunctionValue:
  535. return v1->GetFunctionValue().body == v2->GetFunctionValue().body;
  536. case ValKind::TupleValue:
  537. return FieldsValueEqual(v1->GetTupleValue().elements,
  538. v2->GetTupleValue().elements, line_num);
  539. default:
  540. case ValKind::IntType:
  541. case ValKind::BoolType:
  542. case ValKind::TypeType:
  543. case ValKind::FunctionType:
  544. case ValKind::PointerType:
  545. case ValKind::AutoType:
  546. case ValKind::StructType:
  547. case ValKind::ChoiceType:
  548. case ValKind::ContinuationType:
  549. return TypeEqual(v1, v2);
  550. case ValKind::StructValue:
  551. case ValKind::AlternativeValue:
  552. case ValKind::BindingPlaceholderValue:
  553. case ValKind::AlternativeConstructorValue:
  554. case ValKind::ContinuationValue:
  555. llvm::errs() << "ValueEqual does not support this kind of value.\n";
  556. exit(-1);
  557. }
  558. }
  559. } // namespace Carbon