Skip to content

Commit 54df803

Browse files
authored
feat: added codegen plugin utility functions (#134)
1 parent c23aa28 commit 54df803

File tree

2 files changed

+192
-0
lines changed

2 files changed

+192
-0
lines changed

BUILD.bazel

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,18 @@ cc_library(
3030
],
3131
)
3232

33+
cc_library(
34+
name = "cpp_codegen_plugin_util",
35+
hdrs = ["ecsact/cpp_codegen_plugin_util.hh"],
36+
copts = copts,
37+
deps = [
38+
"@ecsact_runtime//:common",
39+
"@ecsact_runtime//:meta",
40+
"@ecsact_runtime//:codegen_plugin_cc",
41+
"@ecsact_lang_cpp//:support",
42+
],
43+
)
44+
3345
filegroup(
3446
name = "headers",
3547
srcs = glob(["ecsact/**/*.hh"]),

ecsact/cpp_codegen_plugin_util.hh

Lines changed: 180 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,180 @@
1+
#pragma once
2+
3+
#include <cassert>
4+
#include <string_view>
5+
#include <vector>
6+
#include <string>
7+
#include <utility>
8+
#include "ecsact/codegen_plugin.hh"
9+
#include "ecsact/runtime/meta.hh"
10+
11+
namespace ecsact::cpp_codegen_plugin_util {
12+
13+
inline auto inc_header( //
14+
ecsact::codegen_plugin_context& ctx,
15+
auto&& header_path
16+
) -> void {
17+
ctx.write("#include \"", header_path, "\"\n");
18+
}
19+
20+
inline auto inc_package_header( //
21+
ecsact::codegen_plugin_context& ctx,
22+
ecsact_package_id pkg_id,
23+
std::string extension = ".hh"
24+
) -> void {
25+
namespace fs = std::filesystem;
26+
27+
auto main_ecsact_file_path = ecsact::meta::package_file_path(ctx.package_id);
28+
if(ctx.package_id == pkg_id) {
29+
main_ecsact_file_path.replace_extension(
30+
main_ecsact_file_path.extension().string() + extension
31+
);
32+
33+
inc_header(ctx, main_ecsact_file_path.filename().string());
34+
} else {
35+
auto cpp_header_path = ecsact::meta::package_file_path(pkg_id);
36+
cpp_header_path.replace_extension(
37+
cpp_header_path.extension().string() + extension
38+
);
39+
if(main_ecsact_file_path.has_parent_path()) {
40+
cpp_header_path =
41+
fs::relative(cpp_header_path, main_ecsact_file_path.parent_path());
42+
}
43+
inc_header(ctx, cpp_header_path.filename().string());
44+
}
45+
}
46+
47+
class method_printer {
48+
using parameters_list_t = std::vector<std::pair<std::string, std::string>>;
49+
50+
bool disposed = false;
51+
std::optional<parameters_list_t> parameters;
52+
ecsact::codegen_plugin_context& ctx;
53+
54+
auto _parameter(std::string param_type, std::string param_name) -> void {
55+
assert(!disposed);
56+
if(disposed) {
57+
return;
58+
}
59+
60+
assert(
61+
parameters.has_value() &&
62+
"Cannot set parametrs after return type has been set"
63+
);
64+
parameters->push_back({param_type, param_name});
65+
}
66+
67+
auto _return_type(std::string type) {
68+
assert(!disposed);
69+
if(disposed) {
70+
return;
71+
}
72+
73+
assert(parameters.has_value());
74+
if(!parameters.has_value()) {
75+
return;
76+
}
77+
78+
if(!parameters->empty()) {
79+
ctx.write("\n");
80+
}
81+
82+
for(auto i = 0; parameters->size() > i; ++i) {
83+
auto&& [param_type, param_name] = parameters->at(i);
84+
ctx.write("\t", param_type, " ", param_name);
85+
if(i + 1 < parameters->size()) {
86+
ctx.write(",");
87+
}
88+
ctx.write("\n");
89+
}
90+
91+
parameters = std::nullopt;
92+
93+
ctx.write(") -> ", type, " {");
94+
ctx.indentation += 1;
95+
ctx.write("\n");
96+
}
97+
98+
public:
99+
method_printer( //
100+
ecsact::codegen_plugin_context& ctx,
101+
std::string method_name
102+
)
103+
: ctx(ctx) {
104+
parameters.emplace();
105+
ctx.write("auto ", method_name, "(");
106+
}
107+
108+
method_printer(method_printer&& other) : ctx(other.ctx) {
109+
disposed = other.disposed;
110+
111+
if(!disposed) {
112+
parameters = std::move(other.parameters);
113+
}
114+
115+
other.disposed = true;
116+
}
117+
118+
auto parameter(
119+
std::string param_type,
120+
std::string param_name
121+
) & -> method_printer& {
122+
_parameter(param_type, param_name);
123+
return *this;
124+
}
125+
126+
auto parameter(
127+
std::string param_type,
128+
std::string param_name
129+
) && -> method_printer {
130+
_parameter(param_type, param_name);
131+
return std::move(*this);
132+
}
133+
134+
auto return_type(std::string type) & -> method_printer& {
135+
_return_type(type);
136+
return *this;
137+
}
138+
139+
auto return_type(std::string type) && -> method_printer {
140+
_return_type(type);
141+
return std::move(*this);
142+
}
143+
144+
~method_printer() {
145+
if(disposed) {
146+
return;
147+
}
148+
disposed = true;
149+
ctx.indentation -= 1;
150+
ctx.write("\n}\n\n");
151+
}
152+
};
153+
154+
class block_printer {
155+
bool disposed = false;
156+
ecsact::codegen_plugin_context& ctx;
157+
158+
public:
159+
block_printer(ecsact::codegen_plugin_context& ctx) : ctx(ctx) {
160+
ctx.write("{");
161+
ctx.indentation += 1;
162+
ctx.write("\n");
163+
}
164+
165+
block_printer(block_printer&& other) : ctx(other.ctx) {
166+
disposed = other.disposed;
167+
other.disposed = true;
168+
}
169+
170+
~block_printer() {
171+
if(disposed) {
172+
return;
173+
}
174+
disposed = true;
175+
ctx.indentation -= 1;
176+
ctx.write("\n}\n\n");
177+
}
178+
};
179+
180+
} // namespace ecsact::cpp_codegen_plugin_util

0 commit comments

Comments
 (0)