Expand use of IndexBase (#2436)

Initially I'd added this to lexer, this includes parser and semantics. Also adds ComparableIndexBase to unify a few common cases where <> comparisons are supported.

Co-authored-by: Richard Smith <richard@metafoo.co.uk>
This commit is contained in:
Jon Ross-Perkins
2022-12-01 14:09:18 -08:00
committed by GitHub
co-authored by Richard Smith
parent 94cf343b05
commit d50fef1736
9 changed files with 125 additions and 254 deletions
+7 -59
View File
@@ -42,7 +42,7 @@ namespace Carbon {
// applied.
class ParseTree {
public:
class Node;
struct Node;
class PostorderIterator;
class SiblingIterator;
@@ -241,60 +241,8 @@ class ParseTree {
//
// That said, nodes can be compared and are part of a depth-first pre-order
// sequence across all nodes in the parse tree.
class ParseTree::Node {
public:
// Node handles are default constructable, but such a node cannot be used
// for anything. It just allows it to be initialized later through
// assignment. Any other operation on a default constructed node is an
// error.
Node() = default;
friend auto operator==(Node lhs, Node rhs) -> bool {
return lhs.index_ == rhs.index_;
}
friend auto operator!=(Node lhs, Node rhs) -> bool {
return lhs.index_ != rhs.index_;
}
friend auto operator<(Node lhs, Node rhs) -> bool {
return lhs.index_ < rhs.index_;
}
friend auto operator<=(Node lhs, Node rhs) -> bool {
return lhs.index_ <= rhs.index_;
}
friend auto operator>(Node lhs, Node rhs) -> bool {
return lhs.index_ > rhs.index_;
}
friend auto operator>=(Node lhs, Node rhs) -> bool {
return lhs.index_ >= rhs.index_;
}
// Returns an opaque integer identifier of the node in the tree. Clients
// should not expect any particular semantics from this value.
//
// TODO: Maybe we can switch to stream operator overloads?
[[nodiscard]] auto index() const -> int { return index_; }
// Prints the node index.
auto Print(llvm::raw_ostream& output) const -> void;
// Returns true if the node is valid; in other words, it was not default
// initialized.
auto is_valid() -> bool { return index_ != InvalidValue; }
private:
friend ParseTree;
friend PostorderIterator;
friend SiblingIterator;
// Value for uninitialized nodes.
static constexpr int InvalidValue = -1;
// Constructs a node with a specific index into the parse tree's postorder
// sequence of node implementations.
explicit Node(int index) : index_(index) {}
// The index of this node's implementation in the postorder sequence.
int32_t index_ = InvalidValue;
struct ParseTree::Node : public ComparableIndexBase {
using ComparableIndexBase::ComparableIndexBase;
};
// A random-access iterator to the depth-first postorder sequence of parse nodes
@@ -320,15 +268,15 @@ class ParseTree::PostorderIterator
auto operator*() const -> Node { return node_; }
auto operator-(const PostorderIterator& rhs) const -> int {
return node_.index_ - rhs.node_.index_;
return node_.index - rhs.node_.index;
}
auto operator+=(int offset) -> PostorderIterator& {
node_.index_ += offset;
node_.index += offset;
return *this;
}
auto operator-=(int offset) -> PostorderIterator& {
node_.index_ -= offset;
node_.index -= offset;
return *this;
}
@@ -373,7 +321,7 @@ class ParseTree::SiblingIterator
using iterator_facade_base::operator++;
auto operator++() -> SiblingIterator& {
node_.index_ -= std::abs(tree_->node_impls_[node_.index_].subtree_size);
node_.index -= std::abs(tree_->node_impls_[node_.index].subtree_size);
return *this;
}