Files
carbon-lang/explorer/ast/element.cpp
T
Richard Smith 43283cb516 Add Value decomposition and use it to implement Substitute (#2389)
Add a generic mechanism to decompose a `Value` and rebuild it, and use that to implement `Substitute`'s recursive transformation of values instead of a hand-rolled decomposition. This means `Substitute` now covers all kinds of values, whereas previously it used to be unable to transform some values, and should be less work to add new kinds of value.

We can use the same mechanism for various other things: structural dumping of values, equality comparisons, and value instantiation in the interpreter would all benefit from this. But in this change I'm just switching `Substitute` to this as a first step.
2022-12-13 08:55:09 -08:00

75 lines
2.2 KiB
C++

// 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/element.h"
#include "common/check.h"
#include "explorer/ast/declaration.h"
namespace Carbon {
NamedElement::NamedElement(Nonnull<const Declaration*> declaration)
: Element(ElementKind::NamedElement), element_(declaration) {}
NamedElement::NamedElement(Nonnull<const NamedValue*> struct_member)
: Element(ElementKind::NamedElement), element_(struct_member) {}
auto NamedElement::IsNamed(std::string_view name) const -> bool {
return this->name() == name;
}
auto NamedElement::name() const -> std::string_view {
if (const auto* decl = element_.dyn_cast<const Declaration*>()) {
return GetName(*decl).value();
} else {
const auto* named_value = element_.dyn_cast<const NamedValue*>();
return named_value->name;
}
}
auto NamedElement::type() const -> const Value& {
if (const auto* decl = element_.dyn_cast<const Declaration*>()) {
return decl->static_type();
} else {
const auto* named_value = element_.dyn_cast<const NamedValue*>();
return *named_value->value;
}
}
auto NamedElement::declaration() const
-> std::optional<Nonnull<const Declaration*>> {
if (const auto* decl = element_.dyn_cast<const Declaration*>()) {
return decl;
}
return std::nullopt;
}
auto NamedElement::struct_member() const
-> std::optional<Nonnull<const NamedValue*>> {
if (const auto* member = element_.dyn_cast<const NamedValue*>()) {
return member;
}
return std::nullopt;
}
void NamedElement::Print(llvm::raw_ostream& out) const { out << name(); }
// Prints the Element
void PositionalElement::Print(llvm::raw_ostream& out) const {
out << "element #" << index_;
}
// Return whether the element's name matches `name`.
auto PositionalElement::IsNamed(std::string_view /*name*/) const -> bool {
return false;
}
void BaseElement::Print(llvm::raw_ostream& out) const { out << "base class"; }
// Return whether the element's name matches `name`.
auto BaseElement::IsNamed(std::string_view /*name*/) const -> bool {
return false;
}
} // namespace Carbon