@@ -90,7 +90,7 @@ export function gen_ast_h({ ast, output }: { ast: AST; output: string }) {
9090 }
9191
9292 emit (
93- ` void accept(ASTVisitor* visitor) override { visitor->visit(this); }` ,
93+ ` void accept(ASTVisitor* visitor) override { visitor->visit(this); }`
9494 ) ;
9595 emit ( ) ;
9696 emit ( ` auto firstSourceLocation() -> SourceLocation override;` ) ;
@@ -110,7 +110,7 @@ export function gen_ast_h({ ast, output }: { ast: AST; output: string }) {
110110 emit ( ` switch (ast->kind()) {` ) ;
111111 nodes . forEach ( ( { name } ) => {
112112 emit (
113- ` case ${ name } ::Kind: return std::invoke(std::forward<Visitor>(visitor), static_cast<${ name } *>(ast));` ,
113+ ` case ${ name } ::Kind: return std::invoke(std::forward<Visitor>(visitor), static_cast<${ name } *>(ast));`
114114 ) ;
115115 } ) ;
116116 emit ( ` default: cxx_runtime_error("unexpected ${ variantName } ");` ) ;
@@ -130,35 +130,76 @@ export function gen_ast_h({ ast, output }: { ast: AST; output: string }) {
130130#include <cxx/const_value.h>
131131#include <cxx/symbols_fwd.h>
132132#include <optional>
133+ #include <ranges>
133134
134135namespace cxx {
135136
136137template <typename T>
137138class List final : public Managed {
138139public:
139- T value;
140- List* next;
140+ T value;
141+ List* next;
141142
142- explicit List(const T& value, List* next = nullptr)
143- : value(value), next(next) {}
143+ explicit List(const T& value, List* next = nullptr)
144+ : value(value), next(next) {}
145+ };
146+
147+ template <typename T>
148+ class ListIterator {
149+ public:
150+ using value_type = T;
151+ using difference_type = std::ptrdiff_t;
152+
153+ ListIterator() = default;
154+ explicit ListIterator(List<T>* list) : list_(list) {}
155+
156+ auto operator<=>(const ListIterator&) const = default;
157+
158+ auto operator*() const -> const T& { return list_->value; }
159+
160+ auto operator++() -> ListIterator& {
161+ list_ = list_->next;
162+ return *this;
163+ }
164+
165+ auto operator++(int) -> ListIterator {
166+ auto it = *this;
167+ ++*this;
168+ return it;
169+ }
170+
171+ private:
172+ List<T>* list_{};
173+ };
174+
175+ template <typename T>
176+ class ListView : std::ranges::view_interface<ListView<T>> {
177+ public:
178+ explicit ListView(List<T>* list) : list_(list) {}
179+
180+ auto begin() const { return ListIterator<T>(list_); }
181+ auto end() const { return ListIterator<T>(); }
182+
183+ private:
184+ List<T>* list_;
144185};
145186
146187class AST : public Managed {
147188public:
148- explicit AST(ASTKind kind): kind_(kind) {}
189+ explicit AST(ASTKind kind): kind_(kind) {}
149190
150- virtual ~AST();
191+ virtual ~AST();
151192
152- [[nodiscard]] auto kind() const -> ASTKind { return kind_; }
193+ [[nodiscard]] auto kind() const -> ASTKind { return kind_; }
153194
154- virtual void accept(ASTVisitor* visitor) = 0;
195+ virtual void accept(ASTVisitor* visitor) = 0;
155196
156- virtual auto firstSourceLocation() -> SourceLocation = 0;
157- virtual auto lastSourceLocation() -> SourceLocation = 0;
197+ virtual auto firstSourceLocation() -> SourceLocation = 0;
198+ virtual auto lastSourceLocation() -> SourceLocation = 0;
158199
159- [[nodiscard]] auto sourceLocationRange() -> SourceLocationRange {
160- return SourceLocationRange(firstSourceLocation(), lastSourceLocation());
161- }
200+ [[nodiscard]] auto sourceLocationRange() -> SourceLocationRange {
201+ return SourceLocationRange(firstSourceLocation(), lastSourceLocation());
202+ }
162203
163204private:
164205 ASTKind kind_;
@@ -173,8 +214,8 @@ template <typename T>
173214
174215template <typename T>
175216[[nodiscard]] inline auto firstSourceLocation(List<T>* nodes) -> SourceLocation {
176- for (auto it = nodes; it; it = it->next ) {
177- if (auto loc = firstSourceLocation(it->value )) return loc;
217+ for (auto node : ListView{ nodes} ) {
218+ if (auto loc = firstSourceLocation(node )) return loc;
178219 }
179220 return {};
180221}
0 commit comments