value.cpp 14 KB

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