bindings.cpp 3.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  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 "explorer/ast/bindings.h"
  5. #include "common/error.h"
  6. #include "explorer/ast/impl_binding.h"
  7. #include "explorer/ast/pattern.h"
  8. #include "explorer/ast/value.h"
  9. #include "llvm/ADT/StringExtras.h"
  10. namespace Carbon {
  11. Bindings::Bindings(CloneContext& context, const Bindings& other) {
  12. for (auto [binding, value] : other.args_) {
  13. args_.insert({context.Remap(binding), context.Clone(value)});
  14. }
  15. for (auto [binding, value] : other.witnesses_) {
  16. witnesses_.insert({context.Remap(binding), context.Clone(value)});
  17. }
  18. }
  19. void Bindings::Add(Nonnull<const GenericBinding*> binding,
  20. Nonnull<const Value*> value,
  21. std::optional<Nonnull<const Value*>> witness) {
  22. bool added_value = args_.insert({binding, value}).second;
  23. CARBON_CHECK(added_value, "Add of already-existing binding");
  24. if (witness) {
  25. // TODO: Eventually we should check that we have a witness if and only if
  26. // the binding has an impl binding.
  27. auto impl_binding = binding->impl_binding();
  28. CARBON_CHECK(impl_binding, "Given witness but have no impl binding");
  29. bool added_witness = witnesses_.insert({*impl_binding, *witness}).second;
  30. CARBON_CHECK(added_witness, "Add of already-existing binding");
  31. }
  32. }
  33. void Bindings::Print(llvm::raw_ostream& out) const {
  34. std::vector<std::pair<Nonnull<const GenericBinding*>, Nonnull<const Value*>>>
  35. args(args_.begin(), args_.end());
  36. std::vector<std::pair<Nonnull<const ImplBinding*>, Nonnull<const Value*>>>
  37. witnesses(witnesses_.begin(), witnesses_.end());
  38. std::stable_sort(args.begin(), args.end(), [](const auto& a, const auto& b) {
  39. return a.first->index() < b.first->index();
  40. });
  41. std::stable_sort(
  42. witnesses.begin(), witnesses.end(), [](const auto& a, const auto& b) {
  43. return a.first->type_var()->index() < b.first->type_var()->index();
  44. });
  45. llvm::ListSeparator sep;
  46. out << " > bindings args: [";
  47. for (const auto& [binding, value] : args) {
  48. out << sep << "`" << *binding << "`: `" << *value << "`";
  49. }
  50. out << "]\n > bindings witnesses: [";
  51. for (const auto& [binding, value] : witnesses) {
  52. out << sep << "`" << *binding << "`: `" << *value << "`";
  53. }
  54. out << "]";
  55. }
  56. auto Bindings::None() -> Nonnull<const Bindings*> {
  57. static Nonnull<const Bindings*> bindings = new Bindings;
  58. return bindings;
  59. }
  60. auto Bindings::SymbolicIdentity(
  61. Nonnull<Arena*> arena,
  62. llvm::ArrayRef<Nonnull<const GenericBinding*>> bindings)
  63. -> Nonnull<const Bindings*> {
  64. auto* result = arena->New<Bindings>();
  65. for (const auto* binding : bindings) {
  66. std::optional<Nonnull<const Value*>> witness;
  67. if (binding->impl_binding()) {
  68. witness = *binding->impl_binding().value()->symbolic_identity();
  69. }
  70. result->Add(binding, *binding->symbolic_identity(), witness);
  71. }
  72. return result;
  73. }
  74. } // namespace Carbon