Skip to content

Commit f799f32

Browse files
committed
chore: Add views over AST lists
1 parent 702a644 commit f799f32

File tree

8 files changed

+558
-476
lines changed

8 files changed

+558
-476
lines changed

packages/cxx-gen-ast/src/gen_ast_dump_cc.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,8 @@ export function gen_ast_dump_cc({ ast, output }: { ast: AST; output: string }) {
4242
emit(` ++indent_;`);
4343
emit(` out_ << std::format("{:{}}", "", indent_ * 2);`);
4444
emit(` out_ << std::format("{}\\n", "${fieldName}");`);
45-
emit(` for (auto it = ast->${member.name}; it; it = it->next) {`);
46-
emit(` accept(it->value);`);
45+
emit(` for (auto node: ListView{ast->${member.name}}) {`);
46+
emit(` accept(node);`);
4747
emit(` }`);
4848
emit(` --indent_;`);
4949
emit(` }`);

packages/cxx-gen-ast/src/gen_ast_encoder_cc.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -114,9 +114,9 @@ export function gen_ast_encoder_cc({
114114
const className = makeClassName(m.type);
115115
emit(` std::vector<flatbuffers::Offset<io::${className}>>`);
116116
emit(` ${m.name}Offsets;`);
117-
emit(` for (auto it = ast->${m.name}; it; it = it->next) {`);
118-
emit(` if (!it->value) continue;`);
119-
emit(` ${m.name}Offsets.emplace_back(accept(it->value).o);`);
117+
emit(` for (auto node : ListView{ast->${m.name}}) {`);
118+
emit(` if (!node) continue;`);
119+
emit(` ${m.name}Offsets.emplace_back(accept(node).o);`);
120120
emit(` }`);
121121
emit();
122122
emit(` auto ${m.name}OffsetsVector = fbb_.CreateVector(`);
@@ -130,10 +130,10 @@ export function gen_ast_encoder_cc({
130130
emit(` std::vector<std::underlying_type_t<io::${className}>>`);
131131
emit(` ${m.name}Types;`);
132132
emit();
133-
emit(` for (auto it = ast->${m.name}; it; it = it->next) {`);
134-
emit(` if (!it->value) continue;`);
133+
emit(` for (auto node : ListView{ast->${m.name}}) {`);
134+
emit(` if (!node) continue;`);
135135
emit(` const auto [offset, type] = accept${className}(`);
136-
emit(` it->value);`);
136+
emit(` node);`);
137137
emit(` ${m.name}Offsets.push_back(offset);`);
138138
emit(` ${m.name}Types.push_back(type);`);
139139
emit(` }`);

packages/cxx-gen-ast/src/gen_ast_h.ts

Lines changed: 58 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -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
134135
namespace cxx {
135136
136137
template <typename T>
137138
class List final : public Managed {
138139
public:
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
146187
class AST : public Managed {
147188
public:
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
163204
private:
164205
ASTKind kind_;
@@ -173,8 +214,8 @@ template <typename T>
173214
174215
template <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
}

packages/cxx-gen-ast/src/new_ast_op_cc.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -69,8 +69,8 @@ export function new_ast_op_cc({
6969
}
7070
case "node-list": {
7171
emit();
72-
emit(` for (auto it = ast->${m.name}; it; it = it->next) {`);
73-
emit(` auto value = operator()(it->value);`);
72+
emit(` for (auto node : ListView{ast->${m.name}}) {`);
73+
emit(` auto value = operator()(node);`);
7474
emit(` }`);
7575
emit();
7676
break;
@@ -90,7 +90,7 @@ export function new_ast_op_cc({
9090
const resultTy = `${chopAST(base)}Result`;
9191
emit();
9292
emit(
93-
`auto ${opName}::${className}Visitor::operator()(${name}* ast) -> ${resultTy} {`,
93+
`auto ${opName}::${className}Visitor::operator()(${name}* ast) -> ${resultTy} {`
9494
);
9595
members.forEach((m) => {
9696
switch (m.kind) {
@@ -100,8 +100,8 @@ export function new_ast_op_cc({
100100
}
101101
case "node-list": {
102102
emit();
103-
emit(` for (auto it = ast->${m.name}; it; it = it->next) {`);
104-
emit(` auto value = accept(it->value);`);
103+
emit(` for (auto node : ListView{ast->${m.name}}) {`);
104+
emit(` auto value = accept(node);`);
105105
emit(` }`);
106106
emit();
107107
break;

packages/cxx-gen-ast/src/new_ast_rewriter_cc.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ export function new_ast_rewriter_cc({
6363
emit(` copy->${m.name} = ${visitor}(ast->${m.name});`);
6464
} else {
6565
emit(
66-
` copy->${m.name} = ast_cast<${m.type}>(${visitor}(ast->${m.name}));`,
66+
` copy->${m.name} = ast_cast<${m.type}>(${visitor}(ast->${m.name}));`
6767
);
6868
}
6969
break;
@@ -72,8 +72,8 @@ export function new_ast_rewriter_cc({
7272
emit();
7373
emit(` if (auto it = ast->${m.name}) {`);
7474
emit(` auto out = &copy->${m.name};`);
75-
emit(` for (auto it = ast->${m.name}; it; it = it->next) {`);
76-
emit(` auto value = ${visitor}(it->value);`);
75+
emit(` for (auto node : ListView{ast->${m.name}}) {`);
76+
emit(` auto value = ${visitor}(node);`);
7777
if (isBase(m.type)) {
7878
emit(`*out = new (arena()) List(value);`);
7979
} else {
@@ -126,7 +126,7 @@ export function new_ast_rewriter_cc({
126126
nodes.forEach(({ name, members }) => {
127127
emit();
128128
emit(
129-
`auto ${opName}::${className}Visitor::operator()(${name}* ast) -> ${base}* {`,
129+
`auto ${opName}::${className}Visitor::operator()(${name}* ast) -> ${base}* {`
130130
);
131131
emit(` auto copy = new (arena()) ${name}{};`);
132132
emit();

0 commit comments

Comments
 (0)