// Part of the Carbon Language project, under the Apache License v2.0 with LLVM // Exceptions. See /LICENSE for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception #include "explorer/ast/bindings.h" #include "common/error.h" #include "explorer/ast/impl_binding.h" #include "explorer/ast/pattern.h" #include "explorer/ast/value.h" #include "llvm/ADT/StringExtras.h" namespace Carbon { Bindings::Bindings(CloneContext& context, const Bindings& other) { for (auto [binding, value] : other.args_) { args_.insert({context.Remap(binding), context.Clone(value)}); } for (auto [binding, value] : other.witnesses_) { witnesses_.insert({context.Remap(binding), context.Clone(value)}); } } void Bindings::Add(Nonnull binding, Nonnull value, std::optional> witness) { bool added_value = args_.insert({binding, value}).second; CARBON_CHECK(added_value, "Add of already-existing binding"); if (witness) { // TODO: Eventually we should check that we have a witness if and only if // the binding has an impl binding. auto impl_binding = binding->impl_binding(); CARBON_CHECK(impl_binding, "Given witness but have no impl binding"); bool added_witness = witnesses_.insert({*impl_binding, *witness}).second; CARBON_CHECK(added_witness, "Add of already-existing binding"); } } void Bindings::Print(llvm::raw_ostream& out) const { std::vector, Nonnull>> args(args_.begin(), args_.end()); std::vector, Nonnull>> witnesses(witnesses_.begin(), witnesses_.end()); std::stable_sort(args.begin(), args.end(), [](const auto& a, const auto& b) { return a.first->index() < b.first->index(); }); std::stable_sort( witnesses.begin(), witnesses.end(), [](const auto& a, const auto& b) { return a.first->type_var()->index() < b.first->type_var()->index(); }); llvm::ListSeparator sep; out << " > bindings args: ["; for (const auto& [binding, value] : args) { out << sep << "`" << *binding << "`: `" << *value << "`"; } out << "]\n > bindings witnesses: ["; for (const auto& [binding, value] : witnesses) { out << sep << "`" << *binding << "`: `" << *value << "`"; } out << "]"; } auto Bindings::None() -> Nonnull { static Nonnull bindings = new Bindings; return bindings; } auto Bindings::SymbolicIdentity( Nonnull arena, llvm::ArrayRef> bindings) -> Nonnull { auto* result = arena->New(); for (const auto* binding : bindings) { std::optional> witness; if (binding->impl_binding()) { witness = *binding->impl_binding().value()->symbolic_identity(); } result->Add(binding, *binding->symbolic_identity(), witness); } return result; } } // namespace Carbon