mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-04 22:02:52 +01:00
Fix equality for tuples (#446)
* fix tuple equality, added test cases * added a comment to an old function * Update executable_semantics/interpreter/value.cpp Co-authored-by: Geoff Romer <gromer@google.com> * fix error in Geoffrey's edit Co-authored-by: Geoff Romer <gromer@google.com>
This commit is contained in:
committed by
GitHub
co-authored by
Geoff Romer
parent
6639a915dc
commit
c1d651fc15
@@ -288,8 +288,7 @@ auto TypeCheckExp(const Expression* e, TypeEnv types, Env values,
|
||||
ExpectType(e->line_num, "!", MakeBoolTypeVal(), ts[0]);
|
||||
return TCResult(new_e, MakeBoolTypeVal(), new_types);
|
||||
case Operator::Eq:
|
||||
ExpectType(e->line_num, "==(1)", MakeIntTypeVal(), ts[0]);
|
||||
ExpectType(e->line_num, "==(2)", MakeIntTypeVal(), ts[1]);
|
||||
ExpectType(e->line_num, "==", ts[0], ts[1]);
|
||||
return TCResult(new_e, MakeBoolTypeVal(), new_types);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
#include "executable_semantics/interpreter/value.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <iostream>
|
||||
|
||||
@@ -360,6 +361,31 @@ auto TypeEqual(const Value* t1, const Value* t2) -> bool {
|
||||
}
|
||||
}
|
||||
|
||||
// Returns true if all the fields of the two tuples contain equal values
|
||||
// and returns false otherwise.
|
||||
static auto FieldsValueEqual(VarAddresses* ts1, VarAddresses* ts2, int line_num)
|
||||
-> bool {
|
||||
if (ts1->size() != ts2->size()) {
|
||||
return false;
|
||||
}
|
||||
for (const auto& [name, address] : *ts1) {
|
||||
auto iter =
|
||||
std::find_if(ts2->begin(), ts2->end(),
|
||||
[name = name](const auto& p) { return p.first == name; });
|
||||
if (iter == ts2->end()) {
|
||||
return false;
|
||||
}
|
||||
if (!ValueEqual(state->heap[address], state->heap[iter->second],
|
||||
line_num)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Returns true if the two values are equal and returns false otherwise.
|
||||
//
|
||||
// This function implements the `==` operator of Carbon.
|
||||
auto ValueEqual(const Value* v1, const Value* v2, int line_num) -> bool {
|
||||
if (v1->tag != v2->tag) {
|
||||
return false;
|
||||
@@ -373,6 +399,9 @@ auto ValueEqual(const Value* v1, const Value* v2, int line_num) -> bool {
|
||||
return v1->u.ptr == v2->u.ptr;
|
||||
case ValKind::FunV:
|
||||
return v1->u.fun.body == v2->u.fun.body;
|
||||
case ValKind::TupleV:
|
||||
return FieldsValueEqual(v1->u.tuple.elts, v2->u.tuple.elts, line_num);
|
||||
default:
|
||||
case ValKind::VarTV:
|
||||
case ValKind::IntTV:
|
||||
case ValKind::BoolTV:
|
||||
@@ -384,7 +413,6 @@ auto ValueEqual(const Value* v1, const Value* v2, int line_num) -> bool {
|
||||
case ValKind::ChoiceTV:
|
||||
case ValKind::ContinuationTV:
|
||||
return TypeEqual(v1, v2);
|
||||
case ValKind::TupleV:
|
||||
case ValKind::StructV:
|
||||
case ValKind::AltV:
|
||||
case ValKind::VarPatV:
|
||||
|
||||
@@ -17,6 +17,7 @@ namespace Carbon {
|
||||
struct Value;
|
||||
using Address = unsigned int;
|
||||
using VarValues = std::list<std::pair<std::string, const Value*>>;
|
||||
using VarAddresses = std::vector<std::pair<std::string, Address>>;
|
||||
|
||||
auto FindInVarValues(const std::string& field, VarValues* inits)
|
||||
-> const Value*;
|
||||
@@ -81,7 +82,7 @@ struct Value {
|
||||
} alt;
|
||||
|
||||
struct {
|
||||
std::vector<std::pair<std::string, Address>>* elts;
|
||||
VarAddresses* elts;
|
||||
} tuple;
|
||||
|
||||
Address ptr;
|
||||
|
||||
Reference in New Issue
Block a user