better base (merged master into adding-extures)
This commit is contained in:
commit
0de4ca1848
4
.gitignore
vendored
4
.gitignore
vendored
@ -11,4 +11,6 @@ vgcore.*
|
||||
*.xcf
|
||||
*_NORMAL.png
|
||||
*_TEMPLATE.png
|
||||
/out
|
||||
/out
|
||||
GRAPH*.gv
|
||||
GRAPH*.png
|
||||
@ -31,30 +31,31 @@ add_compile_options(-fno-trapping-math)
|
||||
#target_compile_definitions(codegen_l1
|
||||
# PRIVATE PROTOTYPE1_L1_CODEGEN_BOOTSTRAP_USE_CHICKEN_VECU8)
|
||||
|
||||
add_executable(0_test src/l1_4/tests/t0.c)
|
||||
add_executable(1_test src/l1_4/tests/t1.c)
|
||||
#add_executable(0_test src/l1_4/tests/t0.c)
|
||||
#add_executable(1_test src/l1_4/tests/t1.c)
|
||||
#
|
||||
add_executable(l1_4_t2 src/l1_4/tests/t2.c)
|
||||
|
||||
add_executable(codegen_l1_5 src/l1_5/anne/codegen.c)
|
||||
|
||||
add_executable(0_render_test src/l2/tests/r0/r0.c gen/l_wl_protocols/xdg-shell-private.c)
|
||||
target_link_libraries(0_render_test -lvulkan -lwayland-client -lm -lxkbcommon -lpng)
|
||||
|
||||
add_executable(0r_tex_init_prep src/l2/tests/r0/r0_tex_init_prep.c)
|
||||
target_link_libraries(0r_tex_init_prep -lm -lpng)
|
||||
|
||||
add_executable(1_render_test src/l2/tests/r1/r1.c gen/l_wl_protocols/xdg-shell-private.c)
|
||||
target_link_libraries(1_render_test -lwayland-client -lrt -lm -lxkbcommon)
|
||||
|
||||
add_executable(2a_render_test src/l2/tests/r2/r2a.c gen/l_wl_protocols/xdg-shell-private.c)
|
||||
target_link_libraries(2a_render_test ${LIBPIPEWIRE_LIBS} -lwayland-client -lrt -lm -lxkbcommon)
|
||||
|
||||
add_executable(3_render_test src/l2/tests/r3/r3.c gen/l_wl_protocols/xdg-shell-private.c)
|
||||
target_link_libraries(3_render_test -lwayland-client -lm -lvulkan -lxkbcommon)
|
||||
#
|
||||
#add_executable(0_render_test src/l2/tests/r0/r0.c gen/l_wl_protocols/xdg-shell-private.c
|
||||
# src/l1/core/rb_tree_node.h)
|
||||
#target_link_libraries(0_render_test -lvulkan -lwayland-client -lm -lxkbcommon -lpng)
|
||||
#
|
||||
#add_executable(0r_tex_init_prep src/l2/tests/r0/r0_tex_init_prep.c)
|
||||
#target_link_libraries(0r_tex_init_prep -lm -lpng)
|
||||
#
|
||||
#add_executable(1_render_test src/l2/tests/r1/r1.c gen/l_wl_protocols/xdg-shell-private.c)
|
||||
#target_link_libraries(1_render_test -lwayland-client -lrt -lm -lxkbcommon)
|
||||
#
|
||||
#add_executable(2a_render_test src/l2/tests/r2/r2a.c gen/l_wl_protocols/xdg-shell-private.c)
|
||||
#target_link_libraries(2a_render_test ${LIBPIPEWIRE_LIBS} -lwayland-client -lrt -lm -lxkbcommon)
|
||||
#
|
||||
#add_executable(3_render_test src/l2/tests/r3/r3.c gen/l_wl_protocols/xdg-shell-private.c)
|
||||
#target_link_libraries(3_render_test -lwayland-client -lm -lvulkan -lxkbcommon)
|
||||
|
||||
#add_executable(0_play_test src/l3/tests/p0.c)
|
||||
#target_link_libraries(0_play_test -lncurses)
|
||||
#
|
||||
## Recursively collect all .h files in the src directory.
|
||||
#file(GLOB_RECURSE HEADER_FILES "${CMAKE_SOURCE_DIR}/src/*.h")
|
||||
## Do not build utku
|
||||
#add_executable(utka src/l1/tests/t0.c ${HEADER_FILES})
|
||||
|
||||
add_executable(l2t0 src/l2/tests/data_structures/t0.c)
|
||||
|
||||
41
Makefile
41
Makefile
@ -53,23 +53,60 @@ gen/l_wl_protocols/xdg-shell-private.c: $(wl_protocols)/stable/xdg-shell/xdg-she
|
||||
xdg_shell_private := gen/l_wl_protocols/xdg-shell-private.c
|
||||
l_wl_protocols := gen/l_wl_protocols/xdg-shell-client.h $(xdg_shell_private)
|
||||
|
||||
|
||||
out/l2/t0: src/l2/tests/data_structures/t0.c $(HEADERS_gen_l1_5)
|
||||
mkdir -p out/l2
|
||||
$(cc) $(cflags) -o $@ $<
|
||||
|
||||
.PHONY: run_l2_t0
|
||||
run_l2_t0: out/l2/t0
|
||||
mkdir -p src/l2/tests/data_structures/GRAPHS
|
||||
cd src/l2/tests/data_structures && ../../../../out/l2/t0
|
||||
|
||||
out/l2/r0: src/l2/tests/r0/r0.c $(HEADERS_src_l2) $(l_wl_protocols)
|
||||
mkdir -p out/l2
|
||||
$(cc) $(cflags) -o $@ $< $(xdg_shell_private) -lvulkan -lm -lxkbcommon -lwayland-client -lpng
|
||||
|
||||
out/l2/r0_tex_init_prep: src/l2/tests/r0/r0_tex_init_prep.c $(HEADERS_src_l2)
|
||||
mkdir -p out/l2
|
||||
$(cc) $(cflags) -o $@ $< -lm -lpng
|
||||
|
||||
.PHONY: run_r0
|
||||
run_r0: out/l2/r0
|
||||
cd src/l2/tests/r0 && ../../../../out/l2/r0
|
||||
|
||||
.PHONY: run_r0_tex_init_prep
|
||||
run_r0_tex_init_prep: out/l2/r0_tex_init_prep
|
||||
cd src/l2/tests/r0 && ../../../../out/l2/r0_tex_init_prep
|
||||
|
||||
|
||||
out/l2/r1: src/l2/tests/r1/r1.c $(HEADERS_src_l2) $(l_wl_protocols)
|
||||
mkdir -p out/l2
|
||||
$(cc) $(cflags) -o $@ $< $(xdg_shell_private) -lwayland-client -lrt -lxkbcommon -lm
|
||||
|
||||
out/l2/r2a: src/l2/tests/r2/r2a.c $(HEADERS_src_l2) $(l_wl_protocols)
|
||||
.PHONY: run_r1
|
||||
run_r1: out/l2/r1
|
||||
./out/l2/r1
|
||||
|
||||
|
||||
out/l2/r2: src/l2/tests/r2/r2a.c $(HEADERS_src_l2) $(l_wl_protocols)
|
||||
mkdir -p out/l2
|
||||
$(cc) $(cflags) -o $@ $< $(xdg_shell_private) -lwayland-client -lrt -lxkbcommon -lm $(libpipewire_flags)
|
||||
|
||||
.PHONY: run_r2
|
||||
run_r2: out/l2/r2
|
||||
./out/l2/r2
|
||||
|
||||
|
||||
out/l2/r3: src/l2/tests/r3/r3.c $(HEADERS_src_l2) $(l_wl_protocols)
|
||||
mkdir -p out/l2
|
||||
$(cc) $(cflags) -o $@ $< $(xdg_shell_private) -lwayland-client -lrt -lxkbcommon -lm -lvulkan
|
||||
|
||||
.PHONY: run_r3
|
||||
run_r3: out/l2/r3
|
||||
./out/l2/r3
|
||||
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
rm -rf gen out
|
||||
|
||||
|
||||
@ -12,7 +12,8 @@ let libs = (with pkgs; [
|
||||
libpng
|
||||
]); in
|
||||
pkgs.mkShell {
|
||||
buildInputs = with pkgs; [
|
||||
buildInputs = with pkgs; [
|
||||
graphviz
|
||||
pipewire
|
||||
shaderc
|
||||
gnumake
|
||||
@ -28,6 +29,6 @@ pkgs.mkShell {
|
||||
shellHook = ''
|
||||
export VK_LAYER_PATH="${pkgs.vulkan-validation-layers}/share/vulkan/explicit_layer.d"
|
||||
echo Day ruined.
|
||||
'';
|
||||
'';
|
||||
}
|
||||
|
||||
|
||||
@ -10,6 +10,7 @@ void generate_l1_headers_for_l1_5() {
|
||||
SpanU8 ns = cstr("embassy_l1_5");
|
||||
generate_eve_span_company_for_primitive(l, ns, cstr("NamedVariableRecordRef"), false, true);
|
||||
generate_eve_span_company_for_primitive(l, ns, cstr("NamedMethodSignatureRecordRef"), false, true);
|
||||
generate_eve_span_company_for_primitive(l, ns, cstr("RBTreeNode"), true, false);
|
||||
}
|
||||
|
||||
#endif
|
||||
@ -20,13 +20,13 @@ NODISCARD VecU8 generate_xvecn_struct_and_base_methods(SpanU8 xvec, SpanU8 memb,
|
||||
/* Structure definition */
|
||||
VecU8_append_span(&res, cstr("typedef struct {\n"));
|
||||
for (int ci = 0; ci < n; ci++) {
|
||||
VecU8_append_vec(&res, VecU8_fmt(SPACE4 "%s %s;\n", memb, vec_field_name(ci)));
|
||||
VecU8_append_vec(&res, VecU8_fmt(SPACE "%s %s;\n", memb, vec_field_name(ci)));
|
||||
}
|
||||
VecU8_append_vec(&res, VecU8_fmt("} %s;\n\n", xvecn));
|
||||
/* xvecn_add_xvecn method */
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"%s %s_add_%s(%s A, %s B) {\n"
|
||||
SPACE4 "return(%s){ ",
|
||||
SPACE "return(%s){ ",
|
||||
xvecn, xvecn, xvecn, xvecn, xvecn, xvecn));
|
||||
for (int ci = 0; ci < n; ci++) {
|
||||
if (ci)
|
||||
@ -37,7 +37,7 @@ NODISCARD VecU8 generate_xvecn_struct_and_base_methods(SpanU8 xvec, SpanU8 memb,
|
||||
/* xvecn_minus_xvecn method */
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"%s %s_minus_%s(%s A, %s B) {\n"
|
||||
SPACE4 "return (%s){ ",
|
||||
SPACE "return (%s){ ",
|
||||
xvecn, xvecn, xvecn, xvecn, xvecn, xvecn));
|
||||
for (int ci = 0; ci < n; ci++) {
|
||||
if (ci)
|
||||
@ -48,7 +48,7 @@ NODISCARD VecU8 generate_xvecn_struct_and_base_methods(SpanU8 xvec, SpanU8 memb,
|
||||
/* xvecn_minus method */
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"%s %s_minus(%s A) {\n"
|
||||
SPACE4 "return (%s){ ",
|
||||
SPACE "return (%s){ ",
|
||||
xvecn, xvecn, xvecn, xvecn));
|
||||
for (int ci = 0; ci < n; ci++) {
|
||||
if (ci)
|
||||
@ -68,7 +68,7 @@ NODISCARD VecU8 generate_xvecn_struct_and_cool_methods(SpanU8 xvec, SpanU8 memb,
|
||||
/* xvecn_length method */
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"%s %s_length(%s A) {\n"
|
||||
SPACE4 "return %s(",
|
||||
SPACE "return %s(",
|
||||
memb, xvecn, xvecn, sqrt_func));
|
||||
for (int i = 0; i < n; i++) {
|
||||
if (i)
|
||||
@ -79,7 +79,7 @@ NODISCARD VecU8 generate_xvecn_struct_and_cool_methods(SpanU8 xvec, SpanU8 memb,
|
||||
/* xvecn_mul_scal method */
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"%s %s_mul_scal(%s A, %s B) {\n"
|
||||
SPACE4 "return (%s) { ",
|
||||
SPACE "return (%s) { ",
|
||||
xvecn, xvecn, xvecn, memb, xvecn));
|
||||
for (int ci = 0; ci < n; ci++) {
|
||||
if (ci)
|
||||
@ -90,12 +90,12 @@ NODISCARD VecU8 generate_xvecn_struct_and_cool_methods(SpanU8 xvec, SpanU8 memb,
|
||||
/* xvecn_div_by_scal method */
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"%s %s_div_by_scal(%s A, %s B) {\n"
|
||||
SPACE4 "return %s_mul_scal(A, 1/B);\n"
|
||||
SPACE "return %s_mul_scal(A, 1/B);\n"
|
||||
"}\n\n", xvecn, xvecn, xvecn, memb, xvecn));
|
||||
/* xvecn_mul_xvecn method */
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"%s %s_mul_%s(%s A, %s B) {\n"
|
||||
SPACE4 "return (%s){ ",
|
||||
SPACE "return (%s){ ",
|
||||
xvecn, xvecn, xvecn, xvecn, xvecn, xvecn));
|
||||
for (int ci = 0; ci < n; ci++) {
|
||||
if (ci)
|
||||
@ -106,7 +106,7 @@ NODISCARD VecU8 generate_xvecn_struct_and_cool_methods(SpanU8 xvec, SpanU8 memb,
|
||||
/* xvecn_dot method */
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"%s %s_dot(%s A, %s B) {\n"
|
||||
SPACE4 "return ",
|
||||
SPACE "return ",
|
||||
memb, xvecn, xvecn, xvecn));
|
||||
for (int i = 0; i < n; i++) {
|
||||
if (i)
|
||||
@ -117,7 +117,7 @@ NODISCARD VecU8 generate_xvecn_struct_and_cool_methods(SpanU8 xvec, SpanU8 memb,
|
||||
/* xvecn_normalize method */
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"%s %s_normalize(%s A) {\n"
|
||||
SPACE4 "return %s_div_by_scal(A, %s_length(A));\n"
|
||||
SPACE "return %s_div_by_scal(A, %s_length(A));\n"
|
||||
"}\n\n", xvecn, xvecn, xvecn, xvecn, xvecn));
|
||||
|
||||
VecU8_drop(g_xvecn);
|
||||
@ -133,7 +133,7 @@ NODISCARD VecU8 generate_xvecn_method_and_one(SpanU8 xvec, int n) {
|
||||
|
||||
VecU8 res = VecU8_fmt(
|
||||
"%s %s_and_one(%s A) {\n"
|
||||
SPACE4 "return (%s){ ",
|
||||
SPACE "return (%s){ ",
|
||||
xvecn_pp, xvecn, xvecn, xvecn_pp);
|
||||
for (int i = 0; i < n; i++) {
|
||||
VecU8_append_vec(&res, VecU8_fmt("A.%s, ", vec_field_name(i)));
|
||||
@ -150,7 +150,7 @@ NODISCARD VecU8 generate_xvec3_method_cross(SpanU8 xvec) {
|
||||
SpanU8 xvec3 = VecU8_to_span(&g_xvec3);
|
||||
VecU8 res = VecU8_fmt(
|
||||
"%s %s_cross(%s A, %s B) {\n"
|
||||
SPACE4 "return (%s){A.y * B.z - A.z * B.y, -A.x * B.z + A.z * B.x, A.x * B.y - A.y * B.x};\n"
|
||||
SPACE "return (%s){A.y * B.z - A.z * B.y, -A.x * B.z + A.z * B.x, A.x * B.y - A.y * B.x};\n"
|
||||
"}\n\n", xvec3, xvec3, xvec3, xvec3, xvec3);
|
||||
VecU8_drop(g_xvec3);
|
||||
return res;
|
||||
@ -177,9 +177,9 @@ NODISCARD VecU8 generate_xmatnm_struct_and_methods(
|
||||
int sv = (rows * sizeof_member) % 16;
|
||||
VecU8_append_span(&res, cstr("typedef struct {\n"));
|
||||
for (int x = 0; x < cols; x++) {
|
||||
VecU8_append_vec(&res, VecU8_fmt(SPACE4 "%s %s;\n", xvecm, vec_field_name(x)));
|
||||
VecU8_append_vec(&res, VecU8_fmt(SPACE "%s %s;\n", xvecm, vec_field_name(x)));
|
||||
if (sv) {
|
||||
VecU8_append_vec(&res, VecU8_format(SPACE4 "char _padding_%d[%d];\n", x, 16 - sv));
|
||||
VecU8_append_vec(&res, VecU8_format(SPACE "char _padding_%d[%d];\n", x, 16 - sv));
|
||||
}
|
||||
}
|
||||
VecU8_append_vec(&res, VecU8_fmt("} %s;\n\n", xmatnm));
|
||||
@ -192,7 +192,7 @@ NODISCARD VecU8 generate_xmatnm_struct_and_methods(
|
||||
VecU8_append_vec(&res, VecU8_fmt("%s %s%s", memb, vec_field_name(x), vec_field_name(y)));
|
||||
}
|
||||
}
|
||||
VecU8_append_vec(&res, VecU8_fmt(") {\n" SPACE4 "return (%s){ ", xmatnm));
|
||||
VecU8_append_vec(&res, VecU8_fmt(") {\n" SPACE "return (%s){ ", xmatnm));
|
||||
for (int x = 0; x < cols; x++) {
|
||||
if (x)
|
||||
VecU8_append_span(&res, cstr(", "));
|
||||
@ -208,7 +208,7 @@ NODISCARD VecU8 generate_xmatnm_struct_and_methods(
|
||||
/* xmatnm_add_xmatnm method */
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"%s %s_add_%s(%s A, %s B) {\n"
|
||||
SPACE4 "return (%s){ ",
|
||||
SPACE "return (%s){ ",
|
||||
xmatnm, xmatnm, xmatnm, xmatnm, xmatnm, xmatnm));
|
||||
for (int x = 0; x < cols; x++) {
|
||||
if (x)
|
||||
@ -220,7 +220,7 @@ NODISCARD VecU8 generate_xmatnm_struct_and_methods(
|
||||
/* xmatnm_minus_xmatnm method */
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"%s %s_minus_%s(%s A, %s B) {\n"
|
||||
SPACE4 "return (%s){ ",
|
||||
SPACE "return (%s){ ",
|
||||
xmatnm, xmatnm, xmatnm, xmatnm, xmatnm, xmatnm));
|
||||
for (int x = 0; x < cols; x++) {
|
||||
if (x)
|
||||
@ -232,7 +232,7 @@ NODISCARD VecU8 generate_xmatnm_struct_and_methods(
|
||||
/* xmatnm_minus method */
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"%s %s_minus(%s A) {\n"
|
||||
SPACE4 "return (%s){ ",
|
||||
SPACE "return (%s){ ",
|
||||
xmatnm, xmatnm, xmatnm, xmatnm));
|
||||
for (int x = 0; x < cols; x++) {
|
||||
if (x)
|
||||
@ -244,7 +244,7 @@ NODISCARD VecU8 generate_xmatnm_struct_and_methods(
|
||||
/* xmatnm_mul_scal method */
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"%s %s_mul_scal(%s A, %s B) {\n"
|
||||
SPACE4 "return (%s){ ",
|
||||
SPACE "return (%s){ ",
|
||||
xmatnm, xmatnm, xmatnm, memb, xmatnm));
|
||||
for (int x = 0; x < cols; x++) {
|
||||
if (x)
|
||||
@ -256,7 +256,7 @@ NODISCARD VecU8 generate_xmatnm_struct_and_methods(
|
||||
/* xmatnm_div_by_scal method */
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"%s %s_div_by_scal(%s A, %s B) {\n"
|
||||
SPACE4 "return %s_mul_scal(A, 1/B);\n"
|
||||
SPACE "return %s_mul_scal(A, 1/B);\n"
|
||||
"}\n\n", xmatnm, xmatnm, xmatnm, memb, xmatnm));
|
||||
|
||||
|
||||
@ -265,7 +265,7 @@ NODISCARD VecU8 generate_xmatnm_struct_and_methods(
|
||||
/* xmatnm_mul_xvecn */
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"%s %s_mul_%s(%s A, %s B) {\n"
|
||||
SPACE4 "return (%s){ ",
|
||||
SPACE "return (%s){ ",
|
||||
xvecm, xmatnm, xvecn, xmatnm, xvecn, xvecm));
|
||||
for (int y = 0; y < rows; y++) {
|
||||
if (y)
|
||||
@ -277,7 +277,7 @@ NODISCARD VecU8 generate_xmatnm_struct_and_methods(
|
||||
VecU8_append_vec(&res, VecU8_fmt("A.%s.%s * B.%s", vec_field_name(x), vec_field_name(y), vec_field_name(x)));
|
||||
}
|
||||
}
|
||||
VecU8_append_span(&res, cstr("\n" SPACE4 "};\n}\n\n"));
|
||||
VecU8_append_span(&res, cstr("\n" SPACE "};\n}\n\n"));
|
||||
|
||||
VecU8_drop(g_xvecn);
|
||||
VecU8_drop(g_xvecm);
|
||||
@ -293,7 +293,7 @@ NODISCARD VecU8 generate_xmatnm_transpose_method(SpanU8 xmat, SpanU8 xvec, SpanU
|
||||
SpanU8 xmatmn = VecU8_to_span(&g_xmatmn);
|
||||
VecU8 res = VecU8_fmt(
|
||||
"%s %s_transpose(%s A) {\n"
|
||||
SPACE4 "return (%s){ ",
|
||||
SPACE "return (%s){ ",
|
||||
xmatmn, xmatnm, xmatnm, xmatmn);
|
||||
for (int bx = 0; bx < rows; bx++) {
|
||||
if (bx)
|
||||
@ -347,7 +347,7 @@ NODISCARD VecU8 generate_xmatnm_method_mul_xmatkn(SpanU8 xmat, int n, int m, int
|
||||
|
||||
VecU8 res = VecU8_fmt(
|
||||
"%s %s_mul_%s(%s A, %s B) {\n"
|
||||
SPACE4 "return (%s){ ",
|
||||
SPACE "return (%s){ ",
|
||||
xmatkm, xmatnm, xmatkn, xmatnm, xmatkn, xmatkm);
|
||||
for (int x = 0; x < k; x++) {
|
||||
if (x)
|
||||
|
||||
@ -7,14 +7,15 @@ void generate_liza_l1_headers() {
|
||||
SpanU8 l = cstr("l1");
|
||||
SpanU8 ns = cstr("liza");
|
||||
mkdir_nofail("l1/eve/liza");
|
||||
generate_util_templ_inst_eve_header(l, ns, cstr("BoxLizaSound"),
|
||||
(util_templates_instantiation_options){ .vec = true});
|
||||
generate_util_templ_inst_eve_header(l, ns, cstr("PlayingSound"),
|
||||
(util_templates_instantiation_options){.vec_extended = true});
|
||||
generate_util_templ_inst_eve_header(l, ns, cstr("BoxLizaInstrument"),
|
||||
(util_templates_instantiation_options){ .vec = true});
|
||||
generate_util_templ_inst_eve_header(l, ns, cstr("MyInstrument"),
|
||||
(util_templates_instantiation_options){ .vec = true});
|
||||
// todo: continue OptionT + util_templates_instantiation_options refactoring from here
|
||||
generate_util_templ_inst_eve_header(l, ns, (util_templates_instantiation_options){
|
||||
.T = cstr("BoxLizaSound"), .vec = true});
|
||||
generate_util_templ_inst_eve_header(l, ns, (util_templates_instantiation_options){
|
||||
.T = cstr("PlayingSound"), .vec_extended = true});
|
||||
generate_util_templ_inst_eve_header(l, ns, (util_templates_instantiation_options){
|
||||
.T = cstr("BoxLizaInstrument"), .vec = true});
|
||||
generate_util_templ_inst_eve_header(l, ns, (util_templates_instantiation_options){
|
||||
.T = cstr("MyInstrument"), .vec = true});
|
||||
}
|
||||
|
||||
#endif
|
||||
@ -7,18 +7,20 @@ void generate_margaret_eve_for_vulkan_utils() {
|
||||
SpanU8 l = cstr("l1");
|
||||
SpanU8 ns = cstr("margaret");
|
||||
mkdir_nofail("l1/eve/margaret");
|
||||
generate_util_templ_inst_eve_header(l, ns, cstr("MargaretScoredPhysicalDevice"),
|
||||
(util_templates_instantiation_options){ .t_primitive = true, .vec = true, .span = true,
|
||||
.mut_span = true, .collab_vec_span = true, .span_sort = true});
|
||||
|
||||
generate_util_templ_inst_eve_header(l, ns, (util_templates_instantiation_options){
|
||||
.T = cstr("MargaretScoredPhysicalDevice"), .t_primitive = true, .vec = true, .span = true,
|
||||
.mut_span = true, .collab_vec_span = true, .span_sort = true
|
||||
});
|
||||
generate_eve_span_company_for_primitive(l, ns, cstr("MargaretBufferInMemoryInfo"), true, false);
|
||||
generate_util_templ_inst_eve_header(l, ns, cstr("PtrMargaretBufferInMemoryInfo"),
|
||||
(util_templates_instantiation_options){ .t_primitive = true, .vec = true, .span = true, .mut_span = true,
|
||||
.collab_vec_span = true});
|
||||
generate_util_templ_inst_eve_header(l, ns, (util_templates_instantiation_options){
|
||||
.T = cstr("PtrMargaretBufferInMemoryInfo"), .t_primitive = true, .vec = true, .span = true, .mut_span = true,
|
||||
.collab_vec_span = true
|
||||
});
|
||||
generate_eve_span_company_for_primitive(l, ns, cstr("MargaretImageInMemoryInfo"), true, false);
|
||||
generate_util_templ_inst_eve_header(l, ns, cstr("PtrMargaretImageInMemoryInfo"),
|
||||
(util_templates_instantiation_options){ .t_primitive = true, .vec = true, .span = true, .mut_span = true,
|
||||
.collab_vec_span = true});
|
||||
generate_util_templ_inst_eve_header(l, ns, (util_templates_instantiation_options){
|
||||
.T = cstr("PtrMargaretImageInMemoryInfo"), .t_primitive = true, .vec = true, .span = true, .mut_span = true,
|
||||
.collab_vec_span = true
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -8,8 +8,8 @@
|
||||
NODISCARD VecU8 generate_texture_data_method_at(SpanU8 tex, SpanU8 pixvec, SpanU8 memb, bool const_access) {
|
||||
return VecU8_fmt(
|
||||
"%s%s* %s_%sat(%s%s* self, size_t x, size_t y) {\n"
|
||||
SPACE4 "assert(x < self->width);\n"
|
||||
SPACE4 "return %s_%sat(&self->pixels, x + y * self->width);\n"
|
||||
SPACE "assert(x < self->width);\n"
|
||||
SPACE "return %s_%sat(&self->pixels, x + y * self->width);\n"
|
||||
"}\n\n",
|
||||
const_access ? cstr("const ") : cstr(""), memb, tex, const_access ? cstr("") : cstr("m"),
|
||||
const_access ? cstr("const ") : cstr(""), tex, pixvec, const_access ? cstr("") : cstr("m"));
|
||||
@ -23,24 +23,24 @@ NODISCARD VecU8 generate_texture_data_struct_and_necc_methods(SpanU8 tex, SpanU8
|
||||
|
||||
VecU8 res = VecU8_fmt(
|
||||
"typedef struct {\n"
|
||||
SPACE4 "%s pixels;\n"
|
||||
SPACE4 "size_t width;\n"
|
||||
SPACE "%s pixels;\n"
|
||||
SPACE "size_t width;\n"
|
||||
"} %s;\n\n", pixvec, tex);
|
||||
/* Method _new() */
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"%s %s_new(U32 width, U32 height) {\n"
|
||||
SPACE4 "assert(!(SIZE_MAX / width / height < 100 || UINT32_MAX / width < 10 || UINT32_MAX / height < 10));\n"
|
||||
SPACE4 "return (%s){.pixels = %s_new_zeroinit((size_t)width * height), .width = width};\n"
|
||||
SPACE "assert(!(SIZE_MAX / width / height < 100 || UINT32_MAX / width < 10 || UINT32_MAX / height < 10));\n"
|
||||
SPACE "return (%s){.pixels = %s_new_zeroinit((size_t)width * height), .width = width};\n"
|
||||
"}\n\n", tex, tex, tex, pixvec));
|
||||
/* Method _drop() */
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"void %s_drop(%s self) {\n"
|
||||
SPACE4 "%s_drop(self.pixels);\n"
|
||||
SPACE "%s_drop(self.pixels);\n"
|
||||
"}\n\n", tex, tex, pixvec));
|
||||
/* Method _get_height() */
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"size_t %s_get_height(const %s* self) {\n"
|
||||
SPACE4 "return self->pixels.len / self->width;\n"
|
||||
SPACE "return self->pixels.len / self->width;\n"
|
||||
"}\n\n", tex, tex));
|
||||
/* Methods _at and _cat */
|
||||
VecU8_append_vec(&res, generate_texture_data_method_at(tex, pixvec, memb, false));
|
||||
@ -48,7 +48,7 @@ NODISCARD VecU8 generate_texture_data_struct_and_necc_methods(SpanU8 tex, SpanU8
|
||||
/* Method _get_size_in_bytes */
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"size_t %s_get_size_in_bytes(const %s* self) {\n"
|
||||
SPACE4 "return self->pixels.len * sizeof(%s);\n"
|
||||
SPACE "return self->pixels.len * sizeof(%s);\n"
|
||||
"}\n\n", tex, tex, memb));
|
||||
/* Method _to_bitmap_text()
|
||||
* We use the assumption that bytes in type member are tightly packed
|
||||
@ -56,70 +56,70 @@ NODISCARD VecU8 generate_texture_data_struct_and_necc_methods(SpanU8 tex, SpanU8
|
||||
*/
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"VecU8 %s_to_bitmap_text(const %s* self) {\n"
|
||||
SPACE4 "assert(SIZE_MAX / self->pixels.len >= 100);\n"
|
||||
SPACE4 "size_t len = self->pixels.len * sizeof(%s);\n"
|
||||
SPACE4 "VecU8 res = VecU8_new_zeroinit(8 + len);\n"
|
||||
SPACE4 "size_t width = self->width;\n"
|
||||
SPACE4 "size_t height = self->pixels.len / self->width;\n"
|
||||
SPACE4 "assert(UINT32_MAX / width >= 10 && UINT32_MAX / height >= 10);\n"
|
||||
SPACE4 "for (int i = 0; i < 4; i++)\n"
|
||||
SPACE4 SPACE4 "*VecU8_mat(&res, 0 + i) = (width >> (8 * i)) & 0xff;\n"
|
||||
SPACE4 "for (int i = 0; i < 4; i++)\n"
|
||||
SPACE4 SPACE4 "*VecU8_mat(&res, 4 + i) = (height >> (8 * i)) & 0xff;\n"
|
||||
SPACE4 "memcpy(res.buf + 8, self->pixels.buf, len);\n"
|
||||
SPACE4 "return res;\n"
|
||||
SPACE "assert(SIZE_MAX / self->pixels.len >= 100);\n"
|
||||
SPACE "size_t len = self->pixels.len * sizeof(%s);\n"
|
||||
SPACE "VecU8 res = VecU8_new_zeroinit(8 + len);\n"
|
||||
SPACE "size_t width = self->width;\n"
|
||||
SPACE "size_t height = self->pixels.len / self->width;\n"
|
||||
SPACE "assert(UINT32_MAX / width >= 10 && UINT32_MAX / height >= 10);\n"
|
||||
SPACE "for (int i = 0; i < 4; i++)\n"
|
||||
SPACE SPACE "*VecU8_mat(&res, 0 + i) = (width >> (8 * i)) & 0xff;\n"
|
||||
SPACE "for (int i = 0; i < 4; i++)\n"
|
||||
SPACE SPACE "*VecU8_mat(&res, 4 + i) = (height >> (8 * i)) & 0xff;\n"
|
||||
SPACE "memcpy(res.buf + 8, self->pixels.buf, len);\n"
|
||||
SPACE "return res;\n"
|
||||
"}\n\n", tex, tex, memb));
|
||||
/* Method _write_to_file
|
||||
* Aborts on failure */
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"void %s_write_to_file(const %s* self, const char* path) {\n"
|
||||
SPACE4 "VecU8 data = %s_to_bitmap_text(self);\n"
|
||||
SPACE4 "write_whole_file_or_abort(path, VecU8_to_span(&data));\n"
|
||||
SPACE4 "VecU8_drop(data);\n"
|
||||
SPACE "VecU8 data = %s_to_bitmap_text(self);\n"
|
||||
SPACE "write_whole_file_or_abort(path, VecU8_to_span(&data));\n"
|
||||
SPACE "VecU8_drop(data);\n"
|
||||
"}\n\n", tex, tex, tex));
|
||||
/* Result<tex, SpanU8> structure */
|
||||
VecU8 g_resoftex = get_ResultType_inst_name(tex, cstr("SpanU8"));
|
||||
SpanU8 resoftex = VecU8_to_span(&g_resoftex);
|
||||
VecU8_append_vec(&res, generate_result_template_inst(tex, cstr("SpanU8"), false, true));
|
||||
/* I also add this, because why not?? Maye I will use it in the future... */
|
||||
VecU8_append_vec(&res, generate_result_template_inst(tex, cstr("VecU8"), false, false));
|
||||
VecU8_append_vec(&res, generate_result_template_inst(tex, cstr("VecU8"), false, false));1
|
||||
/* Method _from_bitmap_text()
|
||||
* We assume that bytes are tightly packed in member type */
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"%s %s_from_bitmap_text(SpanU8 text) {\n"
|
||||
SPACE4 "if (text.len < 8)\n"
|
||||
SPACE4 SPACE4 "return (%s){.variant = Result_Err, .err = cstr(\"No header *crying emoji*\")};\n"
|
||||
SPACE4 "size_t width = 0, height = 0;\n"
|
||||
SPACE4 "for (int i = 0; i < 4; i++)\n"
|
||||
SPACE4 SPACE4 "width |= (((size_t)*SpanU8_at(text, 0 + i)) << (8 * i));\n"
|
||||
SPACE4 "for (int i = 0; i < 4; i++)\n"
|
||||
SPACE4 SPACE4 "height |= (((size_t)*SpanU8_at(text, 4 + i)) << (8 * i));\n"
|
||||
SPACE4 "if (SIZE_MAX / width / height < 100 || UINT32_MAX / width < 10 || UINT32_MAX / height < 10)\n"
|
||||
SPACE4 SPACE4 "return (%s){.variant = Result_Err, .err = cstr(\"Image is too big\")};\n"
|
||||
SPACE4 "size_t len = width * height * sizeof(%s);\n"
|
||||
SPACE4 "if (text.len < 8 + len)\n"
|
||||
SPACE4 SPACE4 "return (%s){.variant = Result_Err, .err = cstr(\"Texture size and file size mismatch\")};\n"
|
||||
SPACE4 "%s res = %s_new(width, height);\n"
|
||||
SPACE4 "memcpy(res.pixels.buf, text.data + 8, len);\n"
|
||||
SPACE4 "return (%s){.variant = Result_Ok, .ok = res};\n"
|
||||
SPACE "if (text.len < 8)\n"
|
||||
SPACE SPACE "return (%s){.variant = Result_Err, .err = cstr(\"No header *crying emoji*\")};\n"
|
||||
SPACE "size_t width = 0, height = 0;\n"
|
||||
SPACE "for (int i = 0; i < 4; i++)\n"
|
||||
SPACE SPACE "width |= (((size_t)*SpanU8_at(text, 0 + i)) << (8 * i));\n"
|
||||
SPACE "for (int i = 0; i < 4; i++)\n"
|
||||
SPACE SPACE "height |= (((size_t)*SpanU8_at(text, 4 + i)) << (8 * i));\n"
|
||||
SPACE "if (SIZE_MAX / width / height < 100 || UINT32_MAX / width < 10 || UINT32_MAX / height < 10)\n"
|
||||
SPACE SPACE "return (%s){.variant = Result_Err, .err = cstr(\"Image is too big\")};\n"
|
||||
SPACE "size_t len = width * height * sizeof(%s);\n"
|
||||
SPACE "if (text.len < 8 + len)\n"
|
||||
SPACE SPACE "return (%s){.variant = Result_Err, .err = cstr(\"Texture size and file size mismatch\")};\n"
|
||||
SPACE "%s res = %s_new(width, height);\n"
|
||||
SPACE "memcpy(res.pixels.buf, text.data + 8, len);\n"
|
||||
SPACE "return (%s){.variant = Result_Ok, .ok = res};\n"
|
||||
"}\n\n", resoftex, tex, resoftex, resoftex, memb, resoftex, tex, tex, resoftex));
|
||||
/* Method _read_from_file */
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"%s %s_read_from_file(const char* path) {\n"
|
||||
SPACE4 "VecU8 data = read_whole_file_or_abort(path);\n"
|
||||
SPACE4 "%s res = %s_from_bitmap_text(VecU8_to_span(&data));\n"
|
||||
SPACE4 "if (res.variant != Result_Ok) {\n"
|
||||
SPACE4 SPACE4 "fprintf(stderr, \"Tried loading bitmap texture from file, but encountered decoding error: \");\n"
|
||||
SPACE4 SPACE4 "SpanU8_fprint(res.err, stderr);\n"
|
||||
SPACE4 SPACE4 "abortf(\"\\n\");\n"
|
||||
SPACE4 "}\n"
|
||||
SPACE4 "VecU8_drop(data);\n"
|
||||
SPACE4 "return res.ok;\n"
|
||||
SPACE "VecU8 data = read_whole_file_or_abort(path);\n"
|
||||
SPACE "%s res = %s_from_bitmap_text(VecU8_to_span(&data));\n"
|
||||
SPACE "if (res.variant != Result_Ok) {\n"
|
||||
SPACE SPACE "fprintf(stderr, \"Tried loading bitmap texture from file, but encountered decoding error: \");\n"
|
||||
SPACE SPACE "SpanU8_fprint(res.err, stderr);\n"
|
||||
SPACE SPACE "abortf(\"\\n\");\n"
|
||||
SPACE "}\n"
|
||||
SPACE "VecU8_drop(data);\n"
|
||||
SPACE "return res.ok;\n"
|
||||
"}\n\n", tex, tex, resoftex, tex));
|
||||
/* Method _is_inside() */
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"bool %s_is_inside(const %s* self, S32 x, S32 y) {\n"
|
||||
SPACE4 "return x >= 0 && y >= 0 && x < (S32)self->width && self->width * y + x < self->pixels.len;\n"
|
||||
SPACE "return x >= 0 && y >= 0 && x < (S32)self->width && self->width * y + x < self->pixels.len;\n"
|
||||
"}\n\n", tex, tex));
|
||||
|
||||
VecU8_drop(g_resoftex);
|
||||
|
||||
@ -28,9 +28,9 @@ void generate_headers_for_r0_r1_r2_r3() {
|
||||
mkdir_nofail("l1/eve/r2");
|
||||
{ /* r2 */
|
||||
SpanU8 ns = cstr("r2");
|
||||
generate_util_templ_inst_eve_header(l, ns, cstr("PlayingSound"), (util_templates_instantiation_options){
|
||||
.vec_extended = true});
|
||||
|
||||
generate_util_templ_inst_eve_header(l, ns, (util_templates_instantiation_options){
|
||||
.T = cstr("PlayingSound"), .vec_extended = true
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -10,10 +10,9 @@ void generate_util_temp_geom_headers() {
|
||||
VecU8_append_span(&head.result, cstr("#include \"../../src/l1/core/util.h\"\n\n"));
|
||||
SpanU8 T[] = {cstr("cvec3"), cstr("cvec4")};
|
||||
for (size_t i = 0; i < ARRAY_SIZE(T); i++) {
|
||||
VecU8_append_vec(&head.result, generate_util_templates_instantiation(T[i],
|
||||
(util_templates_instantiation_options){
|
||||
.t_primitive = true, .vec = true, .span = true, .collab_vec_span = true,
|
||||
}));
|
||||
VecU8_append_vec(&head.result, generate_util_templates_instantiation((util_templates_instantiation_options){
|
||||
.T = T[i], .t_primitive = true, .vec = true, .span = true, .collab_vec_span = true,
|
||||
}));
|
||||
}
|
||||
finish_header(head);
|
||||
}
|
||||
@ -23,10 +22,9 @@ void generate_util_temp_geom_headers() {
|
||||
VecU8_append_span(&head.result, cstr("#include \"../../src/l1/core/util.h\"\n\n"));
|
||||
SpanU8 T[] = {cstr("vec2"), cstr("vec3"), cstr("vec4")};
|
||||
for (size_t i = 0; i < ARRAY_SIZE(T); i++) {
|
||||
VecU8_append_vec(&head.result, generate_util_templates_instantiation(T[i],
|
||||
(util_templates_instantiation_options){
|
||||
.t_primitive = true, .vec = true, .span = true, .collab_vec_span = true,
|
||||
}));
|
||||
VecU8_append_vec(&head.result, generate_util_templates_instantiation((util_templates_instantiation_options){
|
||||
.T = T[i], .t_primitive = true, .vec = true, .span = true, .collab_vec_span = true,
|
||||
}));
|
||||
}
|
||||
finish_header(head);
|
||||
}
|
||||
|
||||
@ -3,14 +3,17 @@
|
||||
|
||||
#include "../codegen/util_template_inst.h"
|
||||
|
||||
// todo: split VecAndSpan_int_primitives into multiple files (one file per integer type)
|
||||
|
||||
/* These headers are guarded */
|
||||
void generate_util_temp_very_base_headers() {
|
||||
{
|
||||
GeneratedHeader head = begin_header(cstr("l1/VecAndSpan_int_primitives.h"));
|
||||
VecU8_append_span(&head.result, cstr("#include \"../../src/l1/core/util.h\"\n\n"));
|
||||
SpanU8 T[4] = {cstr("U8"), cstr("U16"), cstr("U32"), cstr("U64")};
|
||||
SpanU8 T[] = {cstr("U8"), cstr("U16"), cstr("U32"), cstr("U64"), cstr("S64")};
|
||||
for (size_t i = 0; i < ARRAY_SIZE(T); i++) {
|
||||
VecU8_append_vec(&head.result, generate_util_templates_instantiation(T[i], (util_templates_instantiation_options){
|
||||
VecU8_append_vec(&head.result, generate_util_templates_instantiation((util_templates_instantiation_options){
|
||||
.T = T[i],
|
||||
.t_integer = true, .t_primitive = true, .vec = true, .vec_extended = true,
|
||||
.vec_equal = true, .span = true, .span_extended = true, .mut_span = true,
|
||||
.collab_vec_span = true, .collab_vec_span_extended = true,
|
||||
@ -21,10 +24,10 @@ void generate_util_temp_very_base_headers() {
|
||||
{
|
||||
GeneratedHeader head = begin_header(cstr("l1/Option_int_primitives.h"));
|
||||
VecU8_append_span(&head.result, cstr("#include \"../../src/l1/core/util.h\"\n\n"));
|
||||
SpanU8 T[4] = {cstr("U8"), cstr("U16"), cstr("U32"), cstr("U64")};
|
||||
SpanU8 T[] = {cstr("U8"), cstr("U16"), cstr("U32"), cstr("U64"), cstr("S64")};
|
||||
for (size_t i = 0; i < ARRAY_SIZE(T); i++) {
|
||||
VecU8_append_vec(&head.result, generate_util_templates_instantiation(T[i], (util_templates_instantiation_options){
|
||||
.t_integer = true, .t_primitive = true, .option = true
|
||||
VecU8_append_vec(&head.result, generate_OptionT_struct_and_methods((option_template_instantiation_op){
|
||||
.T = T[i], .t_integer = true, .t_primitive = true
|
||||
}));
|
||||
}
|
||||
finish_header(head);
|
||||
@ -32,10 +35,11 @@ void generate_util_temp_very_base_headers() {
|
||||
{
|
||||
GeneratedHeader head = begin_header(cstr("l1/VecAndSpan_Vec_int_primitives.h"));
|
||||
VecU8_append_span(&head.result, cstr("#include \"VecAndSpan_int_primitives.h\"\n\n"));
|
||||
SpanU8 T[4] = {cstr("VecU8"), cstr("VecU16"), cstr("VecU32"), cstr("VecU64")};
|
||||
SpanU8 T[] = {cstr("VecU8"), cstr("VecU16"), cstr("VecU32"), cstr("VecU64")};
|
||||
for (size_t i = 0; i < ARRAY_SIZE(T); i++) {
|
||||
VecU8_append_vec(&head.result, generate_util_templates_instantiation(T[i], (util_templates_instantiation_options){
|
||||
.t_clonable = true, .vec = true, .vec_extended = true, .span = true, .collab_vec_span = true, .vec_equal = true,
|
||||
VecU8_append_vec(&head.result, generate_util_templates_instantiation((util_templates_instantiation_options){
|
||||
.T = T[i], .t_clonable = true, .vec = true, .vec_extended = true,
|
||||
.span = true, .collab_vec_span = true, .vec_equal = true,
|
||||
}));
|
||||
}
|
||||
VecU8_append_vec(&head.result, generate_VecT_new_of_size_method(cstr("VecU8")));
|
||||
@ -46,9 +50,8 @@ void generate_util_temp_very_base_headers() {
|
||||
VecU8_append_span(&head.result, cstr("#include \"VecAndSpan_int_primitives.h\"\n\n"));
|
||||
SpanU8 T[1] = {cstr("SpanU8")};
|
||||
for (size_t i = 0; i < ARRAY_SIZE(T); i++) {
|
||||
VecU8_append_vec(&head.result, generate_util_templates_instantiation(T[i], (util_templates_instantiation_options){
|
||||
.t_primitive = true, .vec = true, .span = true, .mut_span = true,
|
||||
.collab_vec_span = true,
|
||||
VecU8_append_vec(&head.result, generate_util_templates_instantiation((util_templates_instantiation_options){
|
||||
.T = T[i], .t_primitive = true, .vec = true, .span = true, .mut_span = true, .collab_vec_span = true,
|
||||
}));
|
||||
}
|
||||
finish_header(head);
|
||||
|
||||
@ -11,16 +11,29 @@ void generate_util_templ_inst_for_vulkan_headers() {
|
||||
mkdir_nofail("l1/vulkan");
|
||||
generate_guarded_span_company_for_primitive(l, ns, cstr("VkQueueFamilyProperties"), vulkan_dep, true, false);
|
||||
generate_guarded_span_company_for_primitive(l, ns, cstr("VkExtensionProperties"), vulkan_dep, true, false);
|
||||
generate_util_templ_inst_guarded_header(l, ns, cstr("VkSurfaceFormatKHR"), vulkan_dep,
|
||||
(util_templates_instantiation_options){ .t_primitive = true, .vec = true, .option = true });
|
||||
generate_util_templ_inst_guarded_header(l, ns, cstr("VkPresentModeKHR"), vulkan_dep,
|
||||
(util_templates_instantiation_options){ .t_primitive = true, .vec = true, .option = true });
|
||||
generate_util_templ_inst_guarded_header(l, ns, cstr("VkCompositeAlphaFlagBitsKHR"), vulkan_dep,
|
||||
(util_templates_instantiation_options){ .t_primitive = true, .option = true });
|
||||
generate_util_templ_inst_guarded_header(l, ns, cstr("VkExtent2D"), vulkan_dep,
|
||||
(util_templates_instantiation_options){ .t_primitive = true, .option = true });
|
||||
generate_util_templ_inst_guarded_header(l, ns, cstr("VkFormat"), vulkan_dep,
|
||||
(util_templates_instantiation_options){ .t_primitive = true, .span = true, .option = true });
|
||||
|
||||
generate_guarded_span_company_for_primitive(l, ns, cstr("VkSurfaceFormatKHR"), vulkan_dep, true, false);
|
||||
generate_guarded_span_company_for_primitive(l, ns, cstr("VkPresentModeKHR"), vulkan_dep, true, false);
|
||||
generate_guarded_span_company_for_primitive(l, ns, cstr("VkFormat"), vulkan_dep, false, true);
|
||||
|
||||
generate_Option_templ_inst_guarded_header(l, ns, vulkan_dep, (option_template_instantiation_op){
|
||||
.T = cstr("VkPresentModeKHR"), .t_integer = true
|
||||
});
|
||||
generate_Option_templ_inst_guarded_header(l, ns, vulkan_dep, (option_template_instantiation_op){
|
||||
.T = cstr("VkFormat"), .t_integer = true
|
||||
});
|
||||
generate_Option_templ_inst_guarded_header(l, ns, vulkan_dep, (option_template_instantiation_op){
|
||||
.T = cstr("VkSurfaceFormatKHR"), .t_primitive = true
|
||||
});
|
||||
generate_Option_templ_inst_guarded_header(l, ns, vulkan_dep, (option_template_instantiation_op){
|
||||
.T = cstr("VkCompositeAlphaFlagBitsKHR"), .t_integer = true
|
||||
});
|
||||
generate_Option_templ_inst_guarded_header(l, ns, vulkan_dep, (option_template_instantiation_op){
|
||||
.T = cstr("VkExtent2D"), .t_primitive = true
|
||||
});
|
||||
// for these
|
||||
|
||||
|
||||
generate_guarded_span_company_for_primitive(l, ns, cstr("VkPhysicalDevice"), vulkan_dep, true, false);
|
||||
generate_guarded_span_company_for_primitive(l, ns, cstr("VkImage"), vulkan_dep, true, false);
|
||||
generate_guarded_span_company_for_primitive(l, ns, cstr("VkImageView"), vulkan_dep, true, false);
|
||||
|
||||
@ -37,7 +37,7 @@ void finish_header(GeneratedHeader header) {
|
||||
VecU8_drop(header.result);
|
||||
}
|
||||
|
||||
#define SPACE4 " "
|
||||
#define SPACE " "
|
||||
#define SPACE8 " "
|
||||
#define SPACE12 " "
|
||||
#define SPACE16 " "
|
||||
@ -48,4 +48,41 @@ void finish_layer(SpanU8 layer_name) {
|
||||
VecU8_drop(nt_name);
|
||||
}
|
||||
|
||||
int get_number_of_parts_in_header_namespace(SpanU8 ns) {
|
||||
int a = 0;
|
||||
for (size_t i = 0; i < ns.len; i++) {
|
||||
if (*SpanU8_at(ns, i) != '/' && (i == 0 || *SpanU8_at(ns, i - 1) == '/'))
|
||||
a++;
|
||||
}
|
||||
return a;
|
||||
}
|
||||
|
||||
/* takes ownership of strings a, b */
|
||||
NODISCARD VecU8 codegen_T_ref_equal_T_ref(SpanU8 T, bool t_integer, VecU8 a, VecU8 b){
|
||||
if (t_integer)
|
||||
return VecU8_fmt("(%s == %s)", VecU8_to_span(&a), VecU8_to_span(&b));
|
||||
return VecU8_fmt("%s_equal_%s(%v, %v)", T, T, a, b);
|
||||
}
|
||||
|
||||
/* takes ownership of strings a, b */
|
||||
NODISCARD VecU8 codegen_T_ref_less_T_ref(SpanU8 T, bool t_integer, VecU8 a, VecU8 b){
|
||||
if (t_integer)
|
||||
return VecU8_fmt("(%s < %s)", VecU8_to_span(&a), VecU8_to_span(&b));
|
||||
return VecU8_fmt("%s_equal_%s(%v, %v)", T, T, a, b);
|
||||
}
|
||||
|
||||
NODISCARD VecU8 prepend_spaces_to_SpanU8_lines(SpanU8 lines, int tabulation){
|
||||
VecU8 res = VecU8_new();
|
||||
if (lines.len > 0)
|
||||
for (int j = 0; j < tabulation; j++)
|
||||
VecU8_append_span(&res, cstr(SPACE));
|
||||
for (size_t i = 0; i < lines.len; i++) {
|
||||
VecU8_append(&res, lines.data[i]);
|
||||
if (lines.data[i] == '\n' && i + 1 < lines.len)
|
||||
for (int j = 0; j < tabulation; j++)
|
||||
VecU8_append_span(&res, cstr(SPACE));
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@ -12,9 +12,9 @@ NODISCARD VecU8 generate_VecT_struct_and_base_methods(SpanU8 T, bool primitive,
|
||||
SpanU8 VecT = VecU8_to_span(&g_VecT);
|
||||
VecU8 res = VecU8_fmt(
|
||||
"typedef struct {\n"
|
||||
SPACE4 "%s* buf;\n"
|
||||
SPACE4 "size_t len;\n"
|
||||
SPACE4 "size_t capacity;\n"
|
||||
SPACE "%s* buf;\n"
|
||||
SPACE "size_t len;\n"
|
||||
SPACE "size_t capacity;\n"
|
||||
"} %s;\n\n", T, VecT);
|
||||
|
||||
VecU8_append_vec(&res, VecU8_fmt("#define %s_new() ((%s){ 0 })\n\n", VecT, VecT));
|
||||
@ -22,76 +22,76 @@ NODISCARD VecU8 generate_VecT_struct_and_base_methods(SpanU8 T, bool primitive,
|
||||
VecU8_append_vec(&res, VecU8_fmt("void %s_drop(%s self) {\n", VecT, VecT));
|
||||
if (!primitive) {
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
SPACE4 "for (size_t i = 0; i < self.len; i++) \n"
|
||||
SPACE4 SPACE4 "%s_drop(self.buf[i]);\n", T));
|
||||
SPACE "for (size_t i = 0; i < self.len; i++) \n"
|
||||
SPACE SPACE "%s_drop(self.buf[i]);\n", T));
|
||||
}
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
SPACE4 "free(self.buf);\n"
|
||||
SPACE "free(self.buf);\n"
|
||||
"}\n\n"));
|
||||
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"NODISCARD %s %s_new_reserved(size_t n) {\n"
|
||||
SPACE4 "return (%s){ .buf = safe_calloc(n, sizeof(%s)), .len = 0, .capacity = n };\n"
|
||||
SPACE "return (%s){ .buf = safe_calloc(n, sizeof(%s)), .len = 0, .capacity = n };\n"
|
||||
"}\n\n", VecT, VecT, VecT, T));
|
||||
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"void %s_append(%s* self, %s el) {\n"
|
||||
SPACE4 "size_t new_length = self->len + 1;\n"
|
||||
SPACE4 "if (new_length > self->capacity) {\n"
|
||||
SPACE4 SPACE4 "size_t new_capacity = Vec_get_new_capacity(self->capacity, new_length);\n"
|
||||
SPACE4 SPACE4 "self->buf = safe_realloc(self->buf, new_capacity * sizeof(%s));\n"
|
||||
SPACE4 SPACE4 "self->capacity = new_capacity;\n"
|
||||
SPACE4 "}\n"
|
||||
SPACE4 "self->buf[self->len] = el;\n"
|
||||
SPACE4 "self->len = new_length;\n"
|
||||
SPACE "size_t new_length = self->len + 1;\n"
|
||||
SPACE "if (new_length > self->capacity) {\n"
|
||||
SPACE SPACE "size_t new_capacity = Vec_get_new_capacity(self->capacity, new_length);\n"
|
||||
SPACE SPACE "self->buf = safe_realloc(self->buf, new_capacity * sizeof(%s));\n"
|
||||
SPACE SPACE "self->capacity = new_capacity;\n"
|
||||
SPACE "}\n"
|
||||
SPACE "self->buf[self->len] = el;\n"
|
||||
SPACE "self->len = new_length;\n"
|
||||
"}\n\n", VecT, VecT, T, T));
|
||||
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"%s* %s_mat(%s* self, size_t i) {\n"
|
||||
SPACE4 "assert(i < self->len);\n"
|
||||
SPACE4 "return &self->buf[i];\n"
|
||||
SPACE "assert(i < self->len);\n"
|
||||
SPACE "return &self->buf[i];\n"
|
||||
"}\n\n", T, VecT, VecT));
|
||||
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"const %s* %s_at(const %s* self, size_t i) {\n"
|
||||
SPACE4 "assert(i < self->len);\n"
|
||||
SPACE4 "return &self->buf[i];\n"
|
||||
SPACE "assert(i < self->len);\n"
|
||||
SPACE "return &self->buf[i];\n"
|
||||
"}\n\n", T, VecT, VecT));
|
||||
|
||||
if (clonable) {
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"NODISCARD %s %s_clone(const %s* self) {\n"
|
||||
SPACE4 "%s res = (%s){.buf = safe_calloc(self->len, sizeof(%s)), .len = self->len, .capacity = self->len};\n",
|
||||
SPACE "%s res = (%s){.buf = safe_calloc(self->len, sizeof(%s)), .len = self->len, .capacity = self->len};\n",
|
||||
VecT, VecT, VecT, VecT, VecT, T));
|
||||
if (primitive) {
|
||||
VecU8_append_vec(&res, VecU8_fmt(SPACE4 "memcpy(res.buf, self->buf, self->len * sizeof(%s));\n", T));
|
||||
VecU8_append_vec(&res, VecU8_fmt(SPACE "memcpy(res.buf, self->buf, self->len * sizeof(%s));\n", T));
|
||||
} else {
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
SPACE4 "for (size_t i = 0; i < self->len; i++)\n"
|
||||
SPACE4 SPACE4 "res.buf[i] = %s_clone(&self->buf[i]);\n", T));
|
||||
SPACE "for (size_t i = 0; i < self->len; i++)\n"
|
||||
SPACE SPACE "res.buf[i] = %s_clone(&self->buf[i]);\n", T));
|
||||
}
|
||||
VecU8_append_span(&res, cstr(SPACE4 "return res;\n}\n\n"));
|
||||
VecU8_append_span(&res, cstr(SPACE "return res;\n}\n\n"));
|
||||
}
|
||||
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"void %s_append_vec(%s* self, %s b) {\n"
|
||||
SPACE4 "size_t new_length = self->len + b.len;\n"
|
||||
SPACE4 "if (new_length > self->capacity) {\n"
|
||||
SPACE4 SPACE4 "size_t new_capacity = Vec_get_new_capacity(self->capacity, new_length);\n"
|
||||
SPACE4 SPACE4 "self->buf = safe_realloc(self->buf, new_capacity * sizeof(%s));\n"
|
||||
SPACE4 SPACE4 "self->capacity = new_capacity;\n"
|
||||
SPACE4 "}\n"
|
||||
SPACE4 "for (size_t i = 0; i < b.len; i++){\n"
|
||||
SPACE4 SPACE4 "self->buf[self->len + i] = b.buf[i];\n"
|
||||
SPACE4 "}\n"
|
||||
SPACE4 "self->len = new_length;\n"
|
||||
SPACE4 "free(b.buf);\n"
|
||||
SPACE "size_t new_length = self->len + b.len;\n"
|
||||
SPACE "if (new_length > self->capacity) {\n"
|
||||
SPACE SPACE "size_t new_capacity = Vec_get_new_capacity(self->capacity, new_length);\n"
|
||||
SPACE SPACE "self->buf = safe_realloc(self->buf, new_capacity * sizeof(%s));\n"
|
||||
SPACE SPACE "self->capacity = new_capacity;\n"
|
||||
SPACE "}\n"
|
||||
SPACE "for (size_t i = 0; i < b.len; i++){\n"
|
||||
SPACE SPACE "self->buf[self->len + i] = b.buf[i];\n"
|
||||
SPACE "}\n"
|
||||
SPACE "self->len = new_length;\n"
|
||||
SPACE "free(b.buf);\n"
|
||||
"}\n\n", VecT, VecT, VecT, T));
|
||||
|
||||
if (primitive) {
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"NODISCARD %s %s_new_zeroinit(size_t len) {\n"
|
||||
SPACE4 "return (%s){.buf = safe_calloc(len, sizeof(%s)), .len = len, .capacity = len};\n"
|
||||
SPACE "return (%s){.buf = safe_calloc(len, sizeof(%s)), .len = len, .capacity = len};\n"
|
||||
"}\n\n", VecT, VecT, VecT, T));
|
||||
}
|
||||
|
||||
@ -107,61 +107,61 @@ NODISCARD VecU8 generate_VecT_trivmove_extended_methods(SpanU8 T, bool primitive
|
||||
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"%s%s %s_pop(%s* self) {\n"
|
||||
SPACE4 "assert(self->len > 0);\n"
|
||||
SPACE4 "self->len--;\n"
|
||||
SPACE4 "return self->buf[self->len];\n"
|
||||
SPACE "assert(self->len > 0);\n"
|
||||
SPACE "self->len--;\n"
|
||||
SPACE "return self->buf[self->len];\n"
|
||||
"}\n\n", primitive ? cstr("") : cstr("NODISCARD "), T, VecT, VecT));
|
||||
|
||||
if (!primitive) {
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"void %s_pop_and_drop(%s* self) {\n"
|
||||
SPACE4 "assert(self->len > 0);\n"
|
||||
SPACE4 "%s_drop(self->buf[self->len - 1]);\n"
|
||||
SPACE4 "self->len--;\n"
|
||||
SPACE "assert(self->len > 0);\n"
|
||||
SPACE "%s_drop(self->buf[self->len - 1]);\n"
|
||||
SPACE "self->len--;\n"
|
||||
"}\n\n", VecT, VecT, T));
|
||||
}
|
||||
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"%s%s %s_unordered_pop(%s* self, size_t ind) {\n"
|
||||
SPACE4 "assert(ind < self->len);\n"
|
||||
SPACE4 "%s res = self->buf[ind];\n"
|
||||
SPACE4 "self->buf[ind] = self->buf[self->len - 1];\n"
|
||||
SPACE4 "self->len--;\n"
|
||||
SPACE4 "return res;\n"
|
||||
SPACE "assert(ind < self->len);\n"
|
||||
SPACE "%s res = self->buf[ind];\n"
|
||||
SPACE "self->buf[ind] = self->buf[self->len - 1];\n"
|
||||
SPACE "self->len--;\n"
|
||||
SPACE "return res;\n"
|
||||
"}\n\n", primitive ? cstr("") : cstr("NODISCARD "), T, VecT, VecT, T));
|
||||
|
||||
if (!primitive) {
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"void %s_unordered_pop_and_drop(%s* self, size_t ind) {\n"
|
||||
SPACE4 "assert(ind < self->len);\n"
|
||||
SPACE4 "%s_drop(self->buf[ind]);\n"
|
||||
SPACE4 "self->buf[ind] = self->buf[self->len - 1];\n"
|
||||
SPACE4 "self->len--;\n"
|
||||
SPACE "assert(ind < self->len);\n"
|
||||
SPACE "%s_drop(self->buf[ind]);\n"
|
||||
SPACE "self->buf[ind] = self->buf[self->len - 1];\n"
|
||||
SPACE "self->len--;\n"
|
||||
"}\n\n", VecT, VecT, T));
|
||||
}
|
||||
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"NODISCARD %s %s_swap_with_empty(%s* cell) {\n"
|
||||
SPACE4 "%s val = *cell;\n"
|
||||
SPACE4 "*cell = (%s){NULL, 0, 0};\n"
|
||||
SPACE4 "return val;\n"
|
||||
SPACE "%s val = *cell;\n"
|
||||
SPACE "*cell = (%s){NULL, 0, 0};\n"
|
||||
SPACE "return val;\n"
|
||||
"}\n\n", VecT, VecT, VecT, VecT, VecT));
|
||||
|
||||
if (primitive) {
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"NODISCARD %s %s_new_filled(size_t len, %s el) {\n"
|
||||
SPACE4 "%s res = (%s){.buf = safe_calloc(len, sizeof(%s)), .len = len, .capacity = len};\n"
|
||||
SPACE4 "for (size_t i = 0; i < len; i++)\n"
|
||||
SPACE4 SPACE4 "res.buf[i] = el;\n"
|
||||
SPACE4 "return res;\n"
|
||||
SPACE "%s res = (%s){.buf = safe_calloc(len, sizeof(%s)), .len = len, .capacity = len};\n"
|
||||
SPACE "for (size_t i = 0; i < len; i++)\n"
|
||||
SPACE SPACE "res.buf[i] = el;\n"
|
||||
SPACE "return res;\n"
|
||||
"}\n\n", VecT, VecT, T, VecT, VecT, T));
|
||||
} else if (clonable) {
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"NODISCARD %s %s_new_filled(size_t len, const %s* el) {\n"
|
||||
SPACE4 "%s res = (%s){.buf = safe_calloc(len, sizeof(%s)), .len = len, .capacity = len};\n"
|
||||
SPACE4 "for (size_t i = 0; i < len; i++)\n"
|
||||
SPACE4 SPACE4 "res.buf[i] = %s_clone(el);\n"
|
||||
SPACE4 "return res;\n"
|
||||
SPACE "%s res = (%s){.buf = safe_calloc(len, sizeof(%s)), .len = len, .capacity = len};\n"
|
||||
SPACE "for (size_t i = 0; i < len; i++)\n"
|
||||
SPACE SPACE "res.buf[i] = %s_clone(el);\n"
|
||||
SPACE "return res;\n"
|
||||
"}\n\n", VecT, VecT, T, VecT, VecT, T, T));
|
||||
}
|
||||
|
||||
@ -175,18 +175,18 @@ NODISCARD VecU8 generate_VecT_equal_method(SpanU8 T, bool integer) {
|
||||
SpanU8 VecT = VecU8_to_span(&g_VecT);
|
||||
VecU8 res = VecU8_fmt(
|
||||
"bool %s_equal_%s(const %s* A, const %s* B) {\n"
|
||||
SPACE4 "if (A->len != B->len)\n"
|
||||
SPACE4 SPACE4 "return false;\n"
|
||||
SPACE4 "for (size_t i = 0; i < A->len; i++) {\n", VecT, VecT, VecT, VecT);
|
||||
SPACE "if (A->len != B->len)\n"
|
||||
SPACE SPACE "return false;\n"
|
||||
SPACE "for (size_t i = 0; i < A->len; i++) {\n", VecT, VecT, VecT, VecT);
|
||||
if (integer) {
|
||||
VecU8_append_span(&res, cstr(SPACE8 "if (A->buf[i] != B->buf[i])\n"));
|
||||
} else {
|
||||
VecU8_append_vec(&res, VecU8_fmt(SPACE8 "if (!%s_equal_%s(A->buf + i, B->buf + i))\n", T, T));
|
||||
}
|
||||
VecU8_append_span(&res, cstr(
|
||||
SPACE4 SPACE4 SPACE4 "return false;\n"
|
||||
SPACE4 "}\n"
|
||||
SPACE4 "return true;\n"
|
||||
SPACE SPACE SPACE "return false;\n"
|
||||
SPACE "}\n"
|
||||
SPACE "return true;\n"
|
||||
"}\n\n"
|
||||
));
|
||||
|
||||
@ -200,10 +200,10 @@ NODISCARD VecU8 generate_VecT_new_of_size_method(SpanU8 T) {
|
||||
SpanU8 VecT = VecU8_to_span(&g_VecT);
|
||||
VecU8 res = VecU8_fmt(
|
||||
"NODISCARD %s %s_new_of_size(size_t len) {\n"
|
||||
SPACE4 "%s res = (%s){.buf = safe_calloc(len, sizeof(%s)), .len = len, .capacity = len};\n"
|
||||
SPACE4 "for (size_t i = 0; i < len; i++)\n"
|
||||
SPACE4 SPACE4 "res.buf[i] = %s_new();\n"
|
||||
SPACE4 "return res;\n"
|
||||
SPACE "%s res = (%s){.buf = safe_calloc(len, sizeof(%s)), .len = len, .capacity = len};\n"
|
||||
SPACE "for (size_t i = 0; i < len; i++)\n"
|
||||
SPACE SPACE "res.buf[i] = %s_new();\n"
|
||||
SPACE "return res;\n"
|
||||
"}\n", VecT, VecT, VecT, VecT, T, T);
|
||||
|
||||
VecU8_drop(g_VecT);
|
||||
@ -214,7 +214,7 @@ NODISCARD VecU8 generate_VecT_new_of_size_method(SpanU8 T) {
|
||||
void codegen_append_some_span_equal_method(VecU8* res, SpanU8 SpanT) {
|
||||
VecU8_append_vec(res, VecU8_fmt(
|
||||
"bool %s_equal_%s(%s A, %s B) {\n"
|
||||
SPACE4 "return A->data == B->data && A->len == B->len;\n"
|
||||
SPACE "return A->data == B->data && A->len == B->len;\n"
|
||||
"}\n\n", SpanT, SpanT, SpanT, SpanT));
|
||||
}
|
||||
|
||||
@ -222,8 +222,8 @@ void codegen_append_some_span_equal_method(VecU8* res, SpanU8 SpanT) {
|
||||
void codegen_append_some_span_struct(VecU8* res, SpanU8 T, SpanU8 SpanT, SpanU8 mod) {
|
||||
VecU8_append_vec(res, VecU8_fmt(
|
||||
"typedef struct {\n"
|
||||
SPACE4 "%s%s* data;\n"
|
||||
SPACE4 "size_t len;\n"
|
||||
SPACE "%s%s* data;\n"
|
||||
SPACE "size_t len;\n"
|
||||
"} %s;\n\n", mod, T, SpanT));
|
||||
}
|
||||
|
||||
@ -231,8 +231,8 @@ void codegen_append_some_span_struct(VecU8* res, SpanU8 T, SpanU8 SpanT, SpanU8
|
||||
void codegen_append_some_span_at_method(VecU8* res, SpanU8 T, SpanU8 SpanT, SpanU8 mod) {
|
||||
VecU8_append_vec(res, VecU8_fmt(
|
||||
"%s%s* %s_at(%s self, size_t i) {\n"
|
||||
SPACE4 "assert(i < self.len);\n"
|
||||
SPACE4 "return self.data + i;\n"
|
||||
SPACE "assert(i < self.len);\n"
|
||||
SPACE "return self.data + i;\n"
|
||||
"}\n\n", mod, T, SpanT, SpanT));
|
||||
}
|
||||
|
||||
@ -241,8 +241,8 @@ void codegen_append_some_span_at_method(VecU8* res, SpanU8 T, SpanU8 SpanT, Span
|
||||
void codegen_append_some_span_span_method(VecU8* res, SpanU8 SpanT) {
|
||||
VecU8_append_vec(res, VecU8_fmt(
|
||||
"%s %s_span(%s self, size_t start, size_t len){\n"
|
||||
SPACE4 "assert(start < SIZE_MAX - len && start + len <= self.len);\n"
|
||||
SPACE4 "return (%s){.data = self.data + start, .len = len};\n"
|
||||
SPACE "assert(start < SIZE_MAX - len && start + len <= self.len);\n"
|
||||
SPACE "return (%s){.data = self.data + start, .len = len};\n"
|
||||
"}\n\n", SpanT, SpanT, SpanT, SpanT));
|
||||
}
|
||||
|
||||
@ -270,7 +270,7 @@ NODISCARD VecU8 generate_SpanT_struct_and_methods(
|
||||
if (add_mutable) {
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"%s %s_to_%s(%s self) {\n"
|
||||
SPACE4 "return (%s){.data = self.data, .len = self.len};\n"
|
||||
SPACE "return (%s){.data = self.data, .len = self.len};\n"
|
||||
"}\n\n", SpanT, MutSpanT, SpanT, MutSpanT, SpanT));
|
||||
}
|
||||
codegen_append_some_span_at_method(&res, T, SpanT, cstr("const "));
|
||||
@ -286,18 +286,18 @@ NODISCARD VecU8 generate_SpanT_struct_and_methods(
|
||||
assert(add_mutable);
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"int %s_qcompare(const void* a, const void* b) {\n"
|
||||
SPACE4 "const %s* A = a;\n"
|
||||
SPACE4 "const %s* B = b;\n", T, T, T));
|
||||
SPACE "const %s* A = a;\n"
|
||||
SPACE "const %s* B = b;\n", T, T, T));
|
||||
if (integer) {
|
||||
VecU8_append_span(&res, cstr(SPACE4 "return (int)(B < A) - (int)(A < B);\n"));
|
||||
VecU8_append_span(&res, cstr(SPACE "return (int)(B < A) - (int)(A < B);\n"));
|
||||
} else {
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
SPACE4 "return (int)%s_less_%s(B, A) - (int)%s_less_%s(A, B);\n", T, T, T, T));
|
||||
SPACE "return (int)%s_less_%s(B, A) - (int)%s_less_%s(A, B);\n", T, T, T, T));
|
||||
}
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"}\n\n"
|
||||
"void %s_sort(%s self) {\n"
|
||||
SPACE4 "qsort(self.data, self.len, sizeof(%s), %s_qcompare);\n"
|
||||
SPACE "qsort(self.data, self.len, sizeof(%s), %s_qcompare);\n"
|
||||
"}\n\n", MutSpanT, MutSpanT, T, T));
|
||||
}
|
||||
|
||||
@ -321,63 +321,63 @@ NODISCARD VecU8 generate_SpanT_VecT_trivmove_collab(SpanU8 T, bool primitive, bo
|
||||
if (clonable) {
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"NODISCARD %s %s_from_span(%s src){\n"
|
||||
SPACE4 "%s res = (%s){ .buf = safe_calloc(src.len, sizeof(%s)), .len = src.len, .capacity = src.len };\n",
|
||||
SPACE "%s res = (%s){ .buf = safe_calloc(src.len, sizeof(%s)), .len = src.len, .capacity = src.len };\n",
|
||||
VecT, VecT, SpanT, VecT, VecT, T));
|
||||
if (primitive) {
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
SPACE4 "memcpy(res.buf, src.data, src.len * sizeof(%s));\n", T));
|
||||
SPACE "memcpy(res.buf, src.data, src.len * sizeof(%s));\n", T));
|
||||
} else {
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
SPACE4 "for (size_t i = 0; i < src.len; i++)\n"
|
||||
SPACE "for (size_t i = 0; i < src.len; i++)\n"
|
||||
SPACE8 "res.buf[i] = %s_clone(&src.data[i]);\n", T));
|
||||
}
|
||||
VecU8_append_span(&res, cstr(SPACE4 "return res;\n}\n\n"));
|
||||
VecU8_append_span(&res, cstr(SPACE "return res;\n}\n\n"));
|
||||
|
||||
}
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"%s %s_to_span(const %s* vec){\n"
|
||||
SPACE4 "return (%s){vec->buf, vec->len};\n"
|
||||
SPACE "return (%s){vec->buf, vec->len};\n"
|
||||
"}\n\n", SpanT, VecT, VecT, SpanT));
|
||||
if (add_mutable) {
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"%s %s_to_mspan(%s* vec){\n"
|
||||
SPACE4 "return (%s){vec->buf, vec->len};\n"
|
||||
SPACE "return (%s){vec->buf, vec->len};\n"
|
||||
"}\n\n", MutSpanT, VecT, VecT, MutSpanT));
|
||||
}
|
||||
|
||||
if (clonable) {
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"void %s_append_span(%s* self, %s b) {\n"
|
||||
SPACE4 "size_t new_length = self->len + b.len;\n"
|
||||
SPACE4 "if (new_length > self->capacity) {\n"
|
||||
SPACE4 SPACE4 "size_t new_capacity = Vec_get_new_capacity(self->capacity, new_length);\n"
|
||||
SPACE4 SPACE4 "self->buf = safe_realloc(self->buf, new_capacity * sizeof(%s));\n"
|
||||
SPACE4 SPACE4 "self->capacity = new_capacity;\n"
|
||||
SPACE4 "}\n", VecT, VecT, SpanT, T));
|
||||
SPACE "size_t new_length = self->len + b.len;\n"
|
||||
SPACE "if (new_length > self->capacity) {\n"
|
||||
SPACE SPACE "size_t new_capacity = Vec_get_new_capacity(self->capacity, new_length);\n"
|
||||
SPACE SPACE "self->buf = safe_realloc(self->buf, new_capacity * sizeof(%s));\n"
|
||||
SPACE SPACE "self->capacity = new_capacity;\n"
|
||||
SPACE "}\n", VecT, VecT, SpanT, T));
|
||||
if (primitive) {
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
SPACE4 "memcpy(self->buf + self->len, b.data, b.len * sizeof(%s));\n", T));
|
||||
SPACE "memcpy(self->buf + self->len, b.data, b.len * sizeof(%s));\n", T));
|
||||
} else {
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
SPACE4 "for (size_t i = 0; i < b.len; i++)\n"
|
||||
SPACE4 SPACE4 "self->buf[self->len + i] = %s_clone(&b.data[i]);\n", T));
|
||||
SPACE "for (size_t i = 0; i < b.len; i++)\n"
|
||||
SPACE SPACE "self->buf[self->len + i] = %s_clone(&b.data[i]);\n", T));
|
||||
}
|
||||
VecU8_append_span(&res, cstr(
|
||||
SPACE4 "self->len = new_length;\n"
|
||||
SPACE "self->len = new_length;\n"
|
||||
"}\n\n"));
|
||||
}
|
||||
|
||||
if (add_extended) {
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"%s %s_span(const %s* vec, size_t start, size_t len) {\n"
|
||||
SPACE4 "assert(start < SIZE_MAX - len && start + len <= vec->len);\n"
|
||||
SPACE4 "return (%s){.data = vec->buf + start, .len = len};\n"
|
||||
SPACE "assert(start < SIZE_MAX - len && start + len <= vec->len);\n"
|
||||
SPACE "return (%s){.data = vec->buf + start, .len = len};\n"
|
||||
"}\n\n", SpanT, VecT, VecT, SpanT));
|
||||
if (add_mutable) {
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"%s %s_mspan(%s* vec, size_t start, size_t len) {\n"
|
||||
SPACE4 "assert(start < SIZE_MAX - len && start + len <= vec->len);\n"
|
||||
SPACE4 "return (%s){.data = vec->buf + start, .len = len};\n"
|
||||
SPACE "assert(start < SIZE_MAX - len && start + len <= vec->len);\n"
|
||||
SPACE "return (%s){.data = vec->buf + start, .len = len};\n"
|
||||
"}\n\n", MutSpanT, VecT, VecT, MutSpanT));
|
||||
}
|
||||
}
|
||||
@ -388,65 +388,13 @@ NODISCARD VecU8 generate_SpanT_VecT_trivmove_collab(SpanU8 T, bool primitive, bo
|
||||
return res;
|
||||
}
|
||||
|
||||
NODISCARD VecU8 generate_OptionT_struct_and_methods(SpanU8 T, bool primitive, bool clonable) {
|
||||
VecU8 g_OptionT = VecU8_fmt("Option%s", T);
|
||||
SpanU8 OptionT = VecU8_to_span(&g_OptionT);
|
||||
|
||||
VecU8 res = VecU8_fmt(
|
||||
"typedef struct {\n"
|
||||
SPACE4 "Option_variant variant;\n"
|
||||
SPACE4 "%s some;\n"
|
||||
"} %s;\n\n", T, OptionT);
|
||||
|
||||
VecU8_append_vec(&res, VecU8_fmt("#define None_%s() (%s){ .variant = Option_None }\n\n", T, OptionT));
|
||||
VecU8_append_vec(&res, VecU8_fmt("%s Some_%s(%s obj) {\n"
|
||||
SPACE4 "return (%s){ .variant = Option_Some, .some = obj };\n"
|
||||
"}\n\n", OptionT, T, T, OptionT));
|
||||
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"const %s* %s_expect_ref(const %s* self){\n"
|
||||
SPACE4 "if (self->variant == Option_None)\n"
|
||||
SPACE4 SPACE4 "abortf(\"Expected something in const %s* got None\\n\");\n"
|
||||
SPACE4 "return &self->some;\n"
|
||||
"}\n\n", T, OptionT, OptionT, OptionT));
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"%s* %s_expect_mut_ref(%s* self){\n"
|
||||
SPACE4 "if (self->variant == Option_None)\n"
|
||||
SPACE4 SPACE4 "abortf(\"Expected something in %s* got None\\n\");\n"
|
||||
SPACE4 "return &self->some;\n"
|
||||
"}\n\n", T, OptionT, OptionT, OptionT));
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"%s %s_expect(%s self){\n"
|
||||
SPACE4 "if (self.variant == Option_None)\n"
|
||||
SPACE4 SPACE4 "abortf(\"Expected something in %s got None\\n\");\n"
|
||||
SPACE4 "return self.some;\n"
|
||||
"}\n\n", T, OptionT, OptionT, OptionT));
|
||||
if (!primitive) {
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"void %s_drop(%s self) {\n"
|
||||
SPACE4 "if (self.variant == Option_None)\n"
|
||||
SPACE4 SPACE4 "%s_drop(self.some);\n"
|
||||
"}\n\n", OptionT, OptionT, T));
|
||||
if (clonable) {
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"NODISCARD %s %s_clone(const %s* self) {\n"
|
||||
SPACE4 "if (self->variant == Option_None)\n"
|
||||
SPACE4 SPACE4 "return (%s) { .variant = Option_None };\n"
|
||||
SPACE4 "return (%s){ .variant = Option_Some, .some = %s_clone(&self->some) };\n"
|
||||
"}\n\n", OptionT, OptionT, OptionT, OptionT, OptionT, T));
|
||||
}
|
||||
}
|
||||
|
||||
VecU8_drop(g_OptionT);
|
||||
return res;
|
||||
}
|
||||
|
||||
/* The only reason this function exists is because in C it is easier to supply a lot of brace list arguments,
|
||||
* than function arguments. This struct is an argument for generate_util_templates_instantiation
|
||||
* It is assumed that all necessary properties of T have been met, including cases where
|
||||
* T needs to be sized (everywhere) and trivially movable (for VecT)
|
||||
*/
|
||||
typedef struct {
|
||||
SpanU8 T;
|
||||
bool t_integer;
|
||||
bool t_primitive;
|
||||
bool t_clonable;
|
||||
@ -460,10 +408,10 @@ typedef struct {
|
||||
bool span_sort;
|
||||
bool collab_vec_span;
|
||||
bool collab_vec_span_extended;
|
||||
bool option;
|
||||
} util_templates_instantiation_options;
|
||||
|
||||
void util_templates_instantiation_options_fix(util_templates_instantiation_options* op) {
|
||||
assert(op->T.len > 0);
|
||||
if (op->t_integer)
|
||||
op->t_primitive = true;
|
||||
if (op->t_primitive)
|
||||
@ -484,98 +432,84 @@ void util_templates_instantiation_options_fix(util_templates_instantiation_optio
|
||||
op->span = true;
|
||||
op->vec = true;
|
||||
}
|
||||
assert(op->vec || op->span || op->option);
|
||||
assert(op->vec || op->span);
|
||||
assert(op->t_primitive || !op->t_integer);
|
||||
assert(!op->t_primitive || op->t_clonable);
|
||||
}
|
||||
|
||||
NODISCARD VecU8 generate_util_templates_instantiation(SpanU8 T, util_templates_instantiation_options op) {
|
||||
NODISCARD VecU8 generate_util_templates_instantiation(util_templates_instantiation_options op) {
|
||||
VecU8 res = VecU8_new();
|
||||
util_templates_instantiation_options_fix(&op);
|
||||
if (op.vec) {
|
||||
VecU8_append_vec(&res, generate_VecT_struct_and_base_methods(T, op.t_primitive, op.t_clonable));
|
||||
VecU8_append_vec(&res, generate_VecT_struct_and_base_methods(op.T, op.t_primitive, op.t_clonable));
|
||||
}
|
||||
if (op.vec_extended) {
|
||||
assert(op.vec);
|
||||
VecU8_append_vec(&res, generate_VecT_trivmove_extended_methods(T, op.t_primitive, op.t_clonable));
|
||||
VecU8_append_vec(&res, generate_VecT_trivmove_extended_methods(op.T, op.t_primitive, op.t_clonable));
|
||||
}
|
||||
if (op.vec_equal) {
|
||||
assert(op.vec);
|
||||
VecU8_append_vec(&res, generate_VecT_equal_method(T, op.t_integer));
|
||||
VecU8_append_vec(&res, generate_VecT_equal_method(op.T, op.t_integer));
|
||||
}
|
||||
if (op.vec_new_of_size) {
|
||||
assert(op.vec);
|
||||
VecU8_append_vec(&res, generate_VecT_new_of_size_method(T));
|
||||
VecU8_append_vec(&res, generate_VecT_new_of_size_method(op.T));
|
||||
}
|
||||
if (op.span) {
|
||||
VecU8_append_vec(&res, generate_SpanT_struct_and_methods(T, op.t_integer, op.mut_span, false, op.span_extended, op.span_sort));
|
||||
VecU8_append_vec(&res, generate_SpanT_struct_and_methods(op.T, op.t_integer, op.mut_span, false, op.span_extended, op.span_sort));
|
||||
}
|
||||
if (op.collab_vec_span) {
|
||||
assert(op.vec && op.span);
|
||||
VecU8_append_vec(&res, generate_SpanT_VecT_trivmove_collab(T, op.t_primitive, op.t_clonable, op.mut_span, op.collab_vec_span_extended));
|
||||
}
|
||||
if (op.option) {
|
||||
VecU8_append_vec(&res, generate_OptionT_struct_and_methods(T, op.t_primitive, op.t_clonable));
|
||||
VecU8_append_vec(&res, generate_SpanT_VecT_trivmove_collab(op.T, op.t_primitive, op.t_clonable, op.mut_span, op.collab_vec_span_extended));
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
NODISCARD VecU8 util_templates_instantiation_get_appropriate_filename(
|
||||
SpanU8 T, util_templates_instantiation_options op
|
||||
) {
|
||||
NODISCARD VecU8 util_templates_instantiation_get_appropriate_filename(util_templates_instantiation_options op) {
|
||||
util_templates_instantiation_options_fix(&op);
|
||||
return VecU8_fmt("%s%s%s%s%s""%s%s.h",
|
||||
return VecU8_fmt("%s%s%s""%s%s.h",
|
||||
op.vec ? cstr("Vec") : cstr(""), op.vec && op.span ? cstr("And") : cstr(""), op.span ? cstr("Span") : cstr(""),
|
||||
(op.span || op.vec) && op.option ? cstr("And") : cstr(""), op.option ? cstr("Option") : cstr(""),
|
||||
(int)op.vec + (int)op.span + (int)op.option > 1 ? cstr("_") : cstr(""), T);
|
||||
(int)op.vec + (int)op.span > 1 ? cstr("_") : cstr(""), op.T);
|
||||
}
|
||||
|
||||
void generate_util_templ_inst_eve_header(SpanU8 layer, SpanU8 bonus_ns, SpanU8 T, util_templates_instantiation_options op) {
|
||||
void generate_util_templ_inst_eve_header(SpanU8 layer, SpanU8 bonus_ns, util_templates_instantiation_options op) {
|
||||
VecU8 text = VecU8_from_cstr("/* Automatically generated file. Do not edit it.\n"
|
||||
" * Do not include it in more than one place */\n\n");
|
||||
VecU8_append_vec(&text, generate_util_templates_instantiation(T, op));
|
||||
VecU8 filename = util_templates_instantiation_get_appropriate_filename(T, op);
|
||||
VecU8_append_vec(&text, generate_util_templates_instantiation(op));
|
||||
VecU8 filename = util_templates_instantiation_get_appropriate_filename(op);
|
||||
// todo: add %v that takes a vector
|
||||
VecU8 nt_path = VecU8_fmt("%s/eve/%s/%s%c", layer, bonus_ns, VecU8_to_span(&filename), 0);
|
||||
VecU8 nt_path = VecU8_fmt("%s/eve/%s/%v%c", layer, bonus_ns, filename, 0);
|
||||
write_whole_file_or_abort((const char*)nt_path.buf, VecU8_to_span(&text));
|
||||
VecU8_drop(nt_path);
|
||||
VecU8_drop(filename);
|
||||
VecU8_drop(text);
|
||||
}
|
||||
|
||||
void generate_eve_span_company_for_primitive(SpanU8 layer, SpanU8 ns, SpanU8 T, bool with_vector, bool with_span) {
|
||||
generate_util_templ_inst_eve_header(layer, ns, T, (util_templates_instantiation_options){
|
||||
generate_util_templ_inst_eve_header(layer, ns, (util_templates_instantiation_options){
|
||||
.T = T,
|
||||
.t_primitive = true, .vec = with_vector, .span = with_span, .collab_vec_span = with_vector && with_span
|
||||
});
|
||||
}
|
||||
|
||||
void generate_eve_span_company_for_non_primitive_clonable(SpanU8 layer, SpanU8 ns, SpanU8 T, bool with_vector, bool with_span) {
|
||||
generate_util_templ_inst_eve_header(layer, ns, T, (util_templates_instantiation_options){
|
||||
generate_util_templ_inst_eve_header(layer, ns, (util_templates_instantiation_options){
|
||||
.T = T,
|
||||
.t_clonable = true, .vec = with_vector, .span = with_span, .collab_vec_span = with_vector && with_span
|
||||
});
|
||||
}
|
||||
|
||||
void generate_eve_span_company_for_non_primitive_non_clonable(SpanU8 layer, SpanU8 ns, SpanU8 T, bool with_vector, bool with_span) {
|
||||
generate_util_templ_inst_eve_header(layer, ns, T, (util_templates_instantiation_options){
|
||||
generate_util_templ_inst_eve_header(layer, ns, (util_templates_instantiation_options){
|
||||
.T = T,
|
||||
.vec = with_vector, .span = with_span, .collab_vec_span = with_vector && with_span
|
||||
});
|
||||
}
|
||||
|
||||
int get_number_of_parts_in_header_namespace(SpanU8 ns) {
|
||||
int a = 0;
|
||||
for (size_t i = 0; i < ns.len; i++) {
|
||||
if (*SpanU8_at(ns, i) != '/' && (i == 0 || *SpanU8_at(ns, i - 1) == '/'))
|
||||
a++;
|
||||
}
|
||||
return a;
|
||||
}
|
||||
|
||||
void generate_util_templ_inst_guarded_header(
|
||||
SpanU8 layer, SpanU8 bonus_ns, SpanU8 T, SpanU8 dependencies,
|
||||
util_templates_instantiation_options op
|
||||
SpanU8 layer, SpanU8 bonus_ns, SpanU8 dependencies, util_templates_instantiation_options op
|
||||
) {
|
||||
assert(layer.len > 1);
|
||||
VecU8 filename = util_templates_instantiation_get_appropriate_filename(T, op);
|
||||
VecU8 filename = util_templates_instantiation_get_appropriate_filename(op);
|
||||
VecU8 path = VecU8_fmt("%s/%s%s%s", layer, bonus_ns, bonus_ns.len ? cstr("/") : cstr(""), VecU8_to_span(&filename));
|
||||
GeneratedHeader head = begin_header(VecU8_to_span(&path));
|
||||
VecU8_drop(path);
|
||||
@ -587,14 +521,15 @@ void generate_util_templ_inst_guarded_header(
|
||||
VecU8_append_span(&head.result, cstr("src/l1/core/util.h\"\n"));
|
||||
VecU8_append_span(&head.result, dependencies);
|
||||
VecU8_append_span(&head.result, cstr("\n\n"));
|
||||
VecU8_append_vec(&head.result, generate_util_templates_instantiation(T, op));
|
||||
VecU8_append_vec(&head.result, generate_util_templates_instantiation(op));
|
||||
finish_header(head);
|
||||
}
|
||||
|
||||
void generate_guarded_span_company_for_primitive(
|
||||
SpanU8 layer, SpanU8 ns, SpanU8 T, SpanU8 dependencies, bool with_vector, bool with_span
|
||||
) {
|
||||
generate_util_templ_inst_guarded_header(layer, ns, T, dependencies, (util_templates_instantiation_options){
|
||||
generate_util_templ_inst_guarded_header(layer, ns, dependencies, (util_templates_instantiation_options){
|
||||
.T = T,
|
||||
.t_primitive = true, .vec = with_vector, .span = with_span, .collab_vec_span = with_vector && with_span
|
||||
});
|
||||
}
|
||||
@ -602,7 +537,8 @@ void generate_guarded_span_company_for_primitive(
|
||||
void generate_guarded_span_company_for_non_primitive_clonable(
|
||||
SpanU8 layer, SpanU8 ns, SpanU8 T, SpanU8 dependencies, bool with_vector, bool with_span
|
||||
) {
|
||||
generate_util_templ_inst_guarded_header(layer, ns, T, dependencies, (util_templates_instantiation_options){
|
||||
generate_util_templ_inst_guarded_header(layer, ns, dependencies, (util_templates_instantiation_options){
|
||||
.T = T,
|
||||
.t_clonable = true, .vec = with_vector, .span = with_span, .collab_vec_span = with_vector && with_span
|
||||
});
|
||||
}
|
||||
@ -610,7 +546,8 @@ void generate_guarded_span_company_for_non_primitive_clonable(
|
||||
void generate_guarded_span_company_for_non_primitive_non_clonable(
|
||||
SpanU8 layer, SpanU8 ns, SpanU8 T, SpanU8 dependencies, bool with_vector, bool with_span
|
||||
) {
|
||||
generate_util_templ_inst_guarded_header(layer, ns, T, dependencies, (util_templates_instantiation_options){
|
||||
generate_util_templ_inst_guarded_header(layer, ns, dependencies, (util_templates_instantiation_options){
|
||||
.T = T,
|
||||
.vec = with_vector, .span = with_span, .collab_vec_span = with_vector && with_span
|
||||
});
|
||||
}
|
||||
@ -697,6 +634,95 @@ void generate_guarded_header_of_result_type_instantiation(
|
||||
GeneratedHeader head = begin_header(VecU8_to_span(&path));
|
||||
VecU8_drop(path);
|
||||
VecU8_drop(filename);
|
||||
|
||||
|
||||
typedef struct{
|
||||
SpanU8 T;
|
||||
bool t_ptr;
|
||||
bool t_integer;
|
||||
bool t_primitive;
|
||||
bool t_clonable;
|
||||
} option_template_instantiation_op;
|
||||
|
||||
void option_template_instantiation_op_fix(option_template_instantiation_op* self){
|
||||
assert(self->T.len > 0);
|
||||
if (self->t_ptr)
|
||||
self->t_integer = true;
|
||||
if (self->t_integer)
|
||||
self->t_primitive = true;
|
||||
if (self->t_primitive)
|
||||
self->t_clonable = true;
|
||||
}
|
||||
|
||||
NODISCARD VecU8 generate_OptionT_struct_and_methods(option_template_instantiation_op op) {
|
||||
option_template_instantiation_op_fix(&op);
|
||||
VecU8 g_OptionT = VecU8_fmt("Option%s", op.T);
|
||||
SpanU8 OptionT = VecU8_to_span(&g_OptionT);
|
||||
|
||||
VecU8 res = VecU8_new();
|
||||
if (op.t_ptr) {
|
||||
VecU8_append_vec(&res, VecU8_fmt("typedef %s %s;\n", op.T, OptionT));
|
||||
VecU8_append_vec(&res, VecU8_fmt("#define None_%s() NULL\n", op.T));
|
||||
VecU8_append_vec(&res, VecU8_fmt("%s Some_%s(%s ref) {\n" SPACE "return ref;\n}\n\n", OptionT, op.T, op.T));
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"%s %s_expect(%s self) {\n"
|
||||
SPACE "return self;\n"
|
||||
"}\n\n", op.T, OptionT, OptionT));
|
||||
} else {
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"typedef struct {\n"
|
||||
SPACE "Option_variant variant;\n"
|
||||
SPACE "%s some;\n"
|
||||
"} %s;\n\n", op.T, OptionT));
|
||||
VecU8_append_vec(&res, VecU8_fmt("#define None_%s() (%s){ .variant = Option_None }\n\n", op.T, OptionT));
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"NODISCARD %s Some_%s(%s obj) {\n"
|
||||
SPACE "return (%s){ .variant = Option_Some, .some = obj };\n"
|
||||
"}\n\n", OptionT, op.T, op.T, OptionT));
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"NODISCARD %s %s_expect(%s self){\n"
|
||||
SPACE "if (self.variant == Option_None)\n"
|
||||
SPACE SPACE "abortf(\"Expected something in %s got None\\n\");\n"
|
||||
SPACE "return self.some;\n"
|
||||
"}\n\n", op.T, OptionT, OptionT, OptionT));
|
||||
if (!op.t_primitive) {
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"void %s_drop(%s self) {\n"
|
||||
SPACE "if (self.variant == Option_None)\n"
|
||||
SPACE SPACE "%s_drop(self.some);\n"
|
||||
"}\n\n", OptionT, OptionT, op.T));
|
||||
if (op.t_clonable) {
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"NODISCARD %s %s_clone(const %s* self) {\n"
|
||||
SPACE "if (self->variant == Option_None)\n"
|
||||
SPACE SPACE "return (%s) { .variant = Option_None };\n"
|
||||
SPACE "return (%s){ .variant = Option_Some, .some = %s_clone(&self->some) };\n"
|
||||
"}\n\n", OptionT, OptionT, OptionT, OptionT, OptionT, op.T));
|
||||
}
|
||||
}
|
||||
}
|
||||
VecU8_drop(g_OptionT);
|
||||
return res;
|
||||
}
|
||||
|
||||
void generate_Option_templ_inst_eve_header(SpanU8 layer, SpanU8 bonus_ns, option_template_instantiation_op op) {
|
||||
VecU8 text = VecU8_from_cstr("/* Automatically generated file. Do not edit it.\n"
|
||||
" * Do not include it in more than one place */\n\n");
|
||||
VecU8_append_vec(&text, generate_OptionT_struct_and_methods(op));
|
||||
VecU8 nt_path = VecU8_fmt("%s/eve/%s/Option%s%c", layer, bonus_ns, op.T, 0);
|
||||
write_whole_file_or_abort((const char*)nt_path.buf, VecU8_to_span(&text));
|
||||
VecU8_drop(nt_path);
|
||||
VecU8_drop(text);
|
||||
}
|
||||
|
||||
void generate_Option_templ_inst_guarded_header(
|
||||
SpanU8 layer, SpanU8 bonus_ns, SpanU8 dependencies, option_template_instantiation_op op
|
||||
) {
|
||||
assert(layer.len > 1);
|
||||
VecU8 path = VecU8_fmt("%s/%s%sOption%s.h", layer, bonus_ns, bonus_ns.len ? cstr("/") : cstr(""), op.T);
|
||||
GeneratedHeader head = begin_header(VecU8_to_span(&path));
|
||||
VecU8_drop(path);
|
||||
|
||||
VecU8_append_span(&head.result, cstr("#include \"../../"));
|
||||
int to_my_layer = get_number_of_parts_in_header_namespace(bonus_ns);
|
||||
for (int i = 0; i < to_my_layer; i++)
|
||||
@ -704,7 +730,7 @@ void generate_guarded_header_of_result_type_instantiation(
|
||||
VecU8_append_span(&head.result, cstr("src/l1/core/util.h\"\n"));
|
||||
VecU8_append_span(&head.result, dependencies);
|
||||
VecU8_append_span(&head.result, cstr("\n\n"));
|
||||
VecU8_append_vec(&head.result, generate_result_template_inst(OkT, ErrT, ok_t_primitive, err_t_primitive));
|
||||
VecU8_append_vec(&head.result, generate_OptionT_struct_and_methods(op));
|
||||
finish_header(head);
|
||||
}
|
||||
|
||||
|
||||
@ -19,6 +19,8 @@ VecU8 VecU8_from_cstr(const char* dc) {
|
||||
SpanU8 SpanU8_from_cstr(const char* dc) {
|
||||
return (SpanU8){.data = (const U8*)dc, .len = strlen(dc)};
|
||||
}
|
||||
|
||||
#define vcstr(dc) (VecU8_from_cstr(dc))
|
||||
#define cstr(dc) ((SpanU8){(const U8*)dc, sizeof(dc) - 1})
|
||||
|
||||
/* Not thread safe (for stdout) !*/
|
||||
@ -57,6 +59,82 @@ NODISCARD VecU8 VecU8_format(const char *fmt, ...) {
|
||||
return (VecU8){ .buf = buf, .len = len, .capacity = len + 1 };
|
||||
}
|
||||
|
||||
size_t S64_stringification_get_length(S64 x){
|
||||
if (x == -9223372036854775807L-1)
|
||||
return 20;
|
||||
int i = 0;
|
||||
if (x <= 0) {
|
||||
x = -x;
|
||||
i++;
|
||||
}
|
||||
while (x > 0) {
|
||||
i++;
|
||||
x /= 10;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
void S64_stringification_into_buf(S64 x, VecU8* targ){
|
||||
if (x == 0) {
|
||||
VecU8_append(targ, '0');
|
||||
} else if (x == -9223372036854775807L-1) {
|
||||
VecU8_append_span(targ, cstr("-9223372036854775808"));
|
||||
} else {
|
||||
if (x < 0) {
|
||||
VecU8_append(targ, '-');
|
||||
x = -x;
|
||||
}
|
||||
int digits = 0;
|
||||
while (x > 0) {
|
||||
VecU8_append(targ, '0' + (x % 10));
|
||||
x /= 10;
|
||||
digits++;
|
||||
}
|
||||
U8* left = targ->buf + targ->len - digits;
|
||||
U8* right = targ->buf + targ->len - 1;
|
||||
while (left < right) {
|
||||
U8 t = *right;
|
||||
*right = *left;
|
||||
*left = t;
|
||||
left++;
|
||||
right--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
size_t U64_stringification_get_length(U64 x){
|
||||
if (x == 0)
|
||||
return 1;
|
||||
int i = 0;
|
||||
while (x > 0) {
|
||||
i++;
|
||||
x /= 10;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
void U64_stringification_into_buf(U64 x, VecU8* targ){
|
||||
if (x == 0) {
|
||||
VecU8_append(targ, '0');
|
||||
} else {
|
||||
int digits = 0;
|
||||
while (x > 0) {
|
||||
VecU8_append(targ, '0' + (x % 10));
|
||||
x /= 10;
|
||||
digits++;
|
||||
}
|
||||
U8* left = targ->buf + targ->len - digits;
|
||||
U8* right = targ->buf + targ->len - 1;
|
||||
while (left < right) {
|
||||
U8 t = *right;
|
||||
*right = *left;
|
||||
*left = t;
|
||||
left++;
|
||||
right--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// todo: add %d (when I figure out how to do it)
|
||||
NODISCARD VecU8 VecU8_fmt(const char* fmt, ...) {
|
||||
assert(fmt);
|
||||
@ -73,7 +151,17 @@ NODISCARD VecU8 VecU8_fmt(const char* fmt, ...) {
|
||||
k += s.len;
|
||||
} else if (*ch == 'c') {
|
||||
va_arg(args, int);
|
||||
k ++;
|
||||
k++;
|
||||
} else if (*ch == 'v') {
|
||||
/* We had not taken ownership of YET (will take it the next iteration) */
|
||||
VecU8 vs = va_arg(args, VecU8);
|
||||
k += vs.len;
|
||||
} else if (*ch == 'i') {
|
||||
S64 x = va_arg(args, S64);
|
||||
k += S64_stringification_get_length(x);
|
||||
} else if (*ch == 'u') {
|
||||
U64 x = va_arg(args, U64);
|
||||
k += U64_stringification_get_length(x);
|
||||
} else
|
||||
abortf("Format syntax error at pos %lu! Watch out, be careful", (size_t)(ch - fmt));
|
||||
} else {
|
||||
@ -95,6 +183,15 @@ NODISCARD VecU8 VecU8_fmt(const char* fmt, ...) {
|
||||
} else if (*ch == 'c') {
|
||||
int byte = va_arg(args, int);
|
||||
VecU8_append(&res, (U8)byte);
|
||||
} else if (*ch == 'v') {
|
||||
VecU8 vs = va_arg(args, VecU8);
|
||||
VecU8_append_vec(&res, vs); /* Moved ownership of vs argument */
|
||||
} else if (*ch == 'i') {
|
||||
S64 x = va_arg(args, S64);
|
||||
S64_stringification_into_buf(x, &res);
|
||||
} else if (*ch == 'u') {
|
||||
U64 x = va_arg(args, U64);
|
||||
U64_stringification_into_buf(x, &res);
|
||||
} else
|
||||
assert(false);
|
||||
} else {
|
||||
@ -106,4 +203,16 @@ NODISCARD VecU8 VecU8_fmt(const char* fmt, ...) {
|
||||
return res;
|
||||
}
|
||||
|
||||
// todo: generate a special span method to check equality of contents
|
||||
bool strings_in_spans_equal(SpanU8 a, SpanU8 b) {
|
||||
if (a.len != b.len)
|
||||
return false;
|
||||
for (size_t i = 0; i < a.len; i++) {
|
||||
if (*SpanU8_at(a, i) != *SpanU8_at(b, i))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@ -22,6 +22,7 @@ int_minmax_function_Definition(U8)
|
||||
int_minmax_function_Definition(U32)
|
||||
int_minmax_function_Definition(S32)
|
||||
int_minmax_function_Definition(U64)
|
||||
int_minmax_function_Definition(S64)
|
||||
int_minmax_function_Definition(float)
|
||||
int_minmax_function_Definition(double)
|
||||
|
||||
|
||||
@ -85,4 +85,6 @@ typedef struct {
|
||||
U32 height;
|
||||
} SizeOfRectangleU32;
|
||||
|
||||
#define check(expr) if (!(expr)) { abortf("Assertion failed at %s : %d : " #expr "\n", __FILE__, __LINE__); }
|
||||
|
||||
#endif
|
||||
|
||||
18
src/l1/system/creating_child_proc.h
Normal file
18
src/l1/system/creating_child_proc.h
Normal file
@ -0,0 +1,18 @@
|
||||
#ifndef prototype1_src_l1_system_creating_child_proc_h
|
||||
#define prototype1_src_l1_system_creating_child_proc_h
|
||||
|
||||
#include "../core/util.h"
|
||||
|
||||
void calling_system_func_nofail(const char* command) {
|
||||
int ret = system(command);
|
||||
if (ret == -1) {
|
||||
abortf("system() failed\n");
|
||||
} else if (WIFEXITED(ret) && WEXITSTATUS(ret) != 0) {
|
||||
abortf("Error: command exited with code %d\n", WEXITSTATUS(ret));
|
||||
} else if (!WIFEXITED(ret)) {
|
||||
abortf("Error: command terminated abnormally\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
41
src/l1_4/tests/t2.c
Normal file
41
src/l1_4/tests/t2.c
Normal file
@ -0,0 +1,41 @@
|
||||
#include "../../l1/core/VecU8_as_str.h"
|
||||
|
||||
int main(){
|
||||
{
|
||||
VecU8 res = VecU8_fmt("%i", 0);
|
||||
check(strings_in_spans_equal(VecU8_to_span(&res), cstr("0")));
|
||||
VecU8_drop(res);
|
||||
}
|
||||
{
|
||||
VecU8 res = VecU8_fmt("%i%i%i%i", -1LL, 0LL, 44LL, -231LL);
|
||||
check(strings_in_spans_equal(VecU8_to_span(&res), cstr("-1044-231")));
|
||||
VecU8_drop(res);
|
||||
}
|
||||
{
|
||||
VecU8 res = VecU8_fmt("%i", 44LL);
|
||||
check(strings_in_spans_equal(VecU8_to_span(&res), cstr("44")));
|
||||
VecU8_drop(res);
|
||||
}
|
||||
{
|
||||
VecU8 res = VecU8_fmt("%u", 44ULL);
|
||||
check(strings_in_spans_equal(VecU8_to_span(&res), cstr("44")));
|
||||
VecU8_drop(res);
|
||||
}
|
||||
{
|
||||
VecU8 res = VecU8_fmt("%u %i", 18446744073709551615ULL, -1LL);
|
||||
check(strings_in_spans_equal(VecU8_to_span(&res), cstr("18446744073709551615 -1")));
|
||||
VecU8_drop(res);
|
||||
}
|
||||
{
|
||||
VecU8 res = VecU8_fmt("%i %i", 9223372036854775807LL, -9223372036854775807LL-1);
|
||||
check(strings_in_spans_equal(VecU8_to_span(&res), cstr("9223372036854775807 -9223372036854775808")));
|
||||
VecU8_drop(res);
|
||||
}
|
||||
{
|
||||
VecU8 vec2 = vcstr("vec2");
|
||||
VecU8 res = VecU8_fmt("%i %v %i", -1230LL, vec2, 1340LL);
|
||||
check(strings_in_spans_equal(VecU8_to_span(&res), cstr("-1230 vec2 1340")));
|
||||
VecU8_drop(res);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -2,12 +2,14 @@
|
||||
|
||||
#include "marie/clipping.h"
|
||||
#include "liza.h"
|
||||
#include "l1_5_templ_very_base.h"
|
||||
|
||||
int main() {
|
||||
mkdir_nofail("l1_5");
|
||||
mkdir_nofail("l1_5/marie");
|
||||
generate_marie_clipping_header();
|
||||
generate_l1_5_liza_headers();
|
||||
generate_l1_5_template_instantiation_for_base_types();
|
||||
finish_layer(cstr("l1_5"));
|
||||
return 0;
|
||||
}
|
||||
|
||||
17
src/l1_5/anne/l1_5_templ_very_base.h
Normal file
17
src/l1_5/anne/l1_5_templ_very_base.h
Normal file
@ -0,0 +1,17 @@
|
||||
#ifndef prototype1_src_l1_5_anne_l1_5_templ_very_base_h
|
||||
#define prototype1_src_l1_5_anne_l1_5_templ_very_base_h
|
||||
|
||||
#include "../codegen/rb_tree_set_map_template_inst.h"
|
||||
|
||||
void generate_l1_5_template_instantiation_for_base_types(){
|
||||
SpanU8 l = cstr("l1_5");
|
||||
SpanU8 ns = cstr("");
|
||||
SpanU8 dep = cstr(
|
||||
"#include \"../l1/VecAndSpan_int_primitives.h\""
|
||||
);
|
||||
// todo: split VecAndSpan_int_primitives into multiple files (one file per integer type)
|
||||
generate_rb_tree_Set_templ_inst_guarded_header(l, ns, dep, (set_instantiation_op){.T = cstr("U64"), .t_integer = true});
|
||||
generate_rb_tree_Set_templ_inst_guarded_header(l, ns, dep, (set_instantiation_op){.T = cstr("S64"), .t_integer = true});
|
||||
}
|
||||
|
||||
#endif
|
||||
@ -144,7 +144,7 @@ int mod3_dec(int x) {
|
||||
|
||||
void generate_func_clip_triang_on_triang_case_where_some_vertex_stuck(VecU8* res, char tC, char tT, bool tables_turned) {
|
||||
/* Case where all 3 vertices of tT are inside tC */
|
||||
VecU8_append_span(res, cstr(SPACE4 "if ("));
|
||||
VecU8_append_span(res, cstr(SPACE "if ("));
|
||||
for (int cs = 0; cs < 3; cs++) {
|
||||
for (int tv = 0; tv < 3; tv++) {
|
||||
if (cs != 0 || tv != 0)
|
||||
@ -155,11 +155,11 @@ void generate_func_clip_triang_on_triang_case_where_some_vertex_stuck(VecU8* res
|
||||
VecU8_append_span(res, cstr(") {\n" SPACE8));
|
||||
append_triangle_registration_stmt(res,
|
||||
get_firstborn_vertex_stmt(tT, 0), get_firstborn_vertex_stmt(tT, 1), get_firstborn_vertex_stmt(tT, 2));
|
||||
VecU8_append_span(res, cstr(SPACE8 "return;\n" SPACE4 "}\n\n"));
|
||||
VecU8_append_span(res, cstr(SPACE8 "return;\n" SPACE "}\n\n"));
|
||||
|
||||
/* Cases where two vertices of tT are inside tC, but one is outside */
|
||||
for (int ti = 0; ti < 3; ti++) {
|
||||
VecU8_append_span(res, cstr(SPACE4 "if ("));
|
||||
VecU8_append_span(res, cstr(SPACE "if ("));
|
||||
int TA = mod3_inc(ti);
|
||||
int TB = mod3_inc(TA);
|
||||
for (int j = 1; j <= 2; j++) {
|
||||
@ -216,14 +216,14 @@ void generate_func_clip_triang_on_triang_case_where_some_vertex_stuck(VecU8* res
|
||||
}
|
||||
VecU8_append_span(res, cstr(SPACE8 "}\n"));
|
||||
}
|
||||
VecU8_append_span(res, cstr(SPACE4 "}\n\n"));
|
||||
VecU8_append_span(res, cstr(SPACE "}\n\n"));
|
||||
}
|
||||
|
||||
/* Case where one vertice of tT is inside tC, but other two are outside tC */
|
||||
for (int pl = 0; pl < 3; pl++) {
|
||||
int TA = mod3_inc(pl);
|
||||
int TB = mod3_inc(TA);
|
||||
VecU8_append_span(res, cstr(SPACE4 "if ("));
|
||||
VecU8_append_span(res, cstr(SPACE "if ("));
|
||||
for (int cb = 0; cb < 3; cb++) {
|
||||
if (cb)
|
||||
VecU8_append_span(res, cstr(" && "));
|
||||
@ -298,7 +298,7 @@ void generate_func_clip_triang_on_triang_case_where_some_vertex_stuck(VecU8* res
|
||||
}
|
||||
VecU8_append_span(res, cstr(SPACE8 "}\n"));
|
||||
}
|
||||
VecU8_append_span(res, cstr(SPACE4 "}\n\n"));
|
||||
VecU8_append_span(res, cstr(SPACE "}\n\n"));
|
||||
}
|
||||
}
|
||||
|
||||
@ -306,7 +306,7 @@ void generate_func_clip_triang_on_triang_case_where_some_vertex_stuck(VecU8* res
|
||||
void generate_func_clip_triang_on_triang_case_boring(VecU8* res) {
|
||||
/* Star of David case */
|
||||
for (int cb = 0; cb < 3; cb++) {
|
||||
VecU8_append_span(res, cstr(SPACE4 "if ("));
|
||||
VecU8_append_span(res, cstr(SPACE "if ("));
|
||||
for (int i = 0; i < 3; i++) {
|
||||
if (i)
|
||||
VecU8_append_span(res, cstr(" && "));
|
||||
@ -325,12 +325,12 @@ void generate_func_clip_triang_on_triang_case_boring(VecU8* res) {
|
||||
VecU8_append_span(res, cstr(SPACE8 "for (int i = 0; i < 4; i++)\n"
|
||||
SPACE12 "VecMarieTriangle_append(pile, (MarieTriangle){hex[i], hex[i + 1], hex[5]});\n"));
|
||||
}
|
||||
VecU8_append_span(res, cstr(SPACE4 "}\n"));
|
||||
VecU8_append_span(res, cstr(SPACE "}\n"));
|
||||
}
|
||||
/* Wedge cases */
|
||||
for (int cf = 0; cf < 3; cf++) {
|
||||
for (int ti = 0; ti < 3; ti++){
|
||||
VecU8_append_span(res, cstr(SPACE4 "if ("));
|
||||
VecU8_append_span(res, cstr(SPACE "if ("));
|
||||
append_on_the_left_stmt(res, 'T', ti, 'T', mod3_dec(ti), 'C', cf);
|
||||
VecU8_append_span(res, cstr(" && "));
|
||||
append_on_the_right_stmt(res, 'T', mod3_inc(ti), 'T', mod3_dec(ti), 'C', (cf + 2) % 3);
|
||||
@ -380,7 +380,7 @@ void generate_func_clip_triang_on_triang_case_boring(VecU8* res) {
|
||||
}
|
||||
VecU8_append_span(res, cstr(SPACE8 "}\n"));
|
||||
}
|
||||
VecU8_append_span(res, cstr(SPACE4 "}\n"));
|
||||
VecU8_append_span(res, cstr(SPACE "}\n"));
|
||||
}
|
||||
}
|
||||
|
||||
@ -390,7 +390,7 @@ NODISCARD VecU8 generate_func_clip_ccw_triang_with_ccw_triang_append_to_Vec() {
|
||||
VecU8 res = VecU8_from_cstr(
|
||||
"void marie_clip_ccw_triang_with_ccw_triang_append_to_Vec(MarieTriangle C, MarieTriangle T, VecMarieTriangle* pile) {\n");
|
||||
for (int ord = 0; ord < 18; ord++) {
|
||||
VecU8_append_vec(&res, VecU8_format(SPACE4 "float M%d = marie_surface(", ord));
|
||||
VecU8_append_vec(&res, VecU8_format(SPACE "float M%d = marie_surface(", ord));
|
||||
for (int a = 0; a < 3; a++) {
|
||||
if (a)
|
||||
VecU8_append_span(&res, cstr(", "));
|
||||
|
||||
27
src/l1_5/codegen/all_set_map_templ_util_inst.h
Normal file
27
src/l1_5/codegen/all_set_map_templ_util_inst.h
Normal file
@ -0,0 +1,27 @@
|
||||
#ifndef PROTOTYPE1_SRC_L1_5_CODEGEN_ALL_SET_MAP_TEMPL_UTIL_INST_H
|
||||
#define PROTOTYPE1_SRC_L1_5_CODEGEN_ALL_SET_MAP_TEMPL_UTIL_INST_H
|
||||
|
||||
#include "../../l1/codegen/util_template_inst.h"
|
||||
|
||||
// todo: continue from here
|
||||
|
||||
/* We assume that T is trivially movable */
|
||||
typedef struct {
|
||||
SpanU8 T;
|
||||
bool t_ptr;
|
||||
bool t_integer;
|
||||
bool t_primitive;
|
||||
bool t_clonable;
|
||||
} set_instantiation_op;
|
||||
|
||||
void set_instantiation_op_fix(set_instantiation_op* self){
|
||||
assert(self->T.len > 0);
|
||||
if (self->t_ptr)
|
||||
self->t_integer = true;
|
||||
if (self->t_integer)
|
||||
self->t_primitive = true;
|
||||
if (self->t_primitive)
|
||||
self->t_clonable = true;
|
||||
}
|
||||
|
||||
#endif
|
||||
419
src/l1_5/codegen/rb_tree_set_map_template_inst.h
Normal file
419
src/l1_5/codegen/rb_tree_set_map_template_inst.h
Normal file
@ -0,0 +1,419 @@
|
||||
#ifndef PROTOTYPE1_SRC_L1_5_CODEGEN_RB_TREE_SET_MAP_TEMPLATE_INST_H
|
||||
#define PROTOTYPE1_SRC_L1_5_CODEGEN_RB_TREE_SET_MAP_TEMPLATE_INST_H
|
||||
|
||||
#include "all_set_map_templ_util_inst.h"
|
||||
|
||||
/* When key is given by value into some method of Buff_RBTreeSet */
|
||||
NODISCARD VecU8 codegen_rb_tree_set_key_value_NOT_EQUAL_element(set_instantiation_op op){
|
||||
if (op.t_integer)
|
||||
return VecU8_fmt("key != self->el.buf[cur - 1]");
|
||||
return VecU8_fmt("!%s_equal_%s(&key, &self->el.buf[cur - 1])", op.T, op.T);
|
||||
}
|
||||
|
||||
/* When key is given by value into some method of Buff_RBTreeSet */
|
||||
NODISCARD VecU8 codegen_rb_tree_set_key_value_LESS_element(set_instantiation_op op){
|
||||
if (op.t_integer)
|
||||
return VecU8_fmt("key < self->el.buf[cur - 1]");
|
||||
return VecU8_fmt("%s_less_%s(&key, &self->el.buf[cur - 1])", op.T, op.T);
|
||||
}
|
||||
|
||||
/* When key is given by ref into some method of Buff_RBTreeSet
|
||||
* Ofk when op.T is integer, argument is still taken by a value */
|
||||
NODISCARD VecU8 codegen_rb_tree_set_key_ref_NOT_EQUAL_element(set_instantiation_op op){
|
||||
if (op.t_integer)
|
||||
return VecU8_fmt("key != self->el.buf[cur - 1]");
|
||||
return VecU8_fmt("!%s_equal_%s(key, &self->el.buf[cur - 1])", op.T, op.T);
|
||||
}
|
||||
|
||||
/* When key is given by a pointer into some method of Buff_RBTreeSet */
|
||||
NODISCARD VecU8 codegen_rb_tree_set_key_ref_EQUAL_element(set_instantiation_op op){
|
||||
if (op.t_integer)
|
||||
return VecU8_fmt("key == self->el.buf[cur - 1]");
|
||||
return VecU8_fmt("%s_equal_%s(ref, &self->el.buf[cur - 1])", op.T, op.T);
|
||||
}
|
||||
|
||||
/* When key is given by a pointer into some method of Buff_RBTreeSet */
|
||||
NODISCARD VecU8 codegen_rb_tree_set_key_ref_LESS_element(set_instantiation_op op){
|
||||
if (op.t_integer)
|
||||
return VecU8_fmt("key < self->el.buf[cur - 1]");
|
||||
return VecU8_fmt("%s_less_%s(key, &self->el.buf[cur - 1])", op.T, op.T);
|
||||
}
|
||||
|
||||
/* When method returns constant pointer to found key (wrapped in Option) we will use this type
|
||||
* Ofcourse, it can turn out that it is not generated. So be careful and generate it by yourself
|
||||
*/
|
||||
NODISCARD VecU8 codegen_rb_tree_set_option_returned_ref_t(set_instantiation_op op){
|
||||
/* Constant pointer to an integer is an integer */
|
||||
return op.t_integer ? VecU8_fmt("Option%s", op.T) : VecU8_fmt("OptionRef%s", op.T);
|
||||
}
|
||||
|
||||
/* Suppose some method returns pointer to key (ofc wrapped in option). And we found what to return
|
||||
* we return it from self->el array */
|
||||
NODISCARD VecU8 codegen_rb_tree_set_some_ref_t(set_instantiation_op op, SpanU8 index_var_name){
|
||||
if (op.t_integer)
|
||||
return VecU8_fmt("Some_%s(self->el[%s - 1])", op.T, index_var_name);
|
||||
return VecU8_fmt("Some_Ref%s(&self->el[%s - 1])", op.T, index_var_name);
|
||||
}
|
||||
|
||||
/* Suppose some method returns pointer to key (ofc wrapped in option). But this time we found nothing */
|
||||
NODISCARD VecU8 codegen_rb_tree_set_none_ref_t(set_instantiation_op op){
|
||||
if (op.t_integer)
|
||||
return VecU8_fmt("Some_%s()", op.T);
|
||||
return VecU8_fmt("Some_Ref%s()", op.T);
|
||||
}
|
||||
|
||||
NODISCARD VecU8 codegen_rb_tree_set_option_returned_value_t(set_instantiation_op op){
|
||||
return VecU8_fmt("Option%s", op.T);
|
||||
}
|
||||
|
||||
/* Suppose some method returns an owned key (by value, ofc wrapped in option). If we DID found something,
|
||||
* we construct Option_Some */
|
||||
NODISCARD VecU8 codegen_rb_tree_set_some_t(set_instantiation_op op, SpanU8 val_giving_expr){
|
||||
return VecU8_fmt("Some_%s(%s)", op.T, val_giving_expr);
|
||||
}
|
||||
|
||||
/* Suppose some method returns an owned key (by value, ofc wrapped in option). But this time we found nothing */
|
||||
NODISCARD VecU8 codegen_rb_tree_set_none_t(set_instantiation_op op){
|
||||
return VecU8_fmt("None_%s()", op.T);
|
||||
}
|
||||
|
||||
/* Suppose some method (like _erase() or _pop(), or _find(), or _at(), takes constant reference to key T
|
||||
* This function tells how to write type of this argument. Basically it is needed to take into account that
|
||||
* integer is better than pointer to integer. (Though, notice that _pop family of methods don't exist for
|
||||
* sets of integers
|
||||
*/
|
||||
NODISCARD VecU8 codegen_rb_tree_set_taking_ref_t_argument(set_instantiation_op op){
|
||||
return !op.t_integer ? VecU8_fmt("const %s*", op.T) : VecU8_from_span(op.T);
|
||||
}
|
||||
|
||||
/* Generates methods _insert() _pop_substitute() _erase_substitute() for SetT
|
||||
* Takes ownership of strings Tc, Fc */
|
||||
void codegen_append_rb_tree_set_insert_kind_method(
|
||||
VecU8* result, set_instantiation_op op, SpanU8 set, SpanU8 method_name, VecU8 RT, VecU8 Tc, VecU8 Fc
|
||||
){
|
||||
VecU8 Tc_root = prepend_spaces_to_SpanU8_lines(VecU8_to_span(&Tc), 2);
|
||||
VecU8 Tc_on_left = prepend_spaces_to_SpanU8_lines(VecU8_to_span(&Tc), 4);
|
||||
VecU8 Tc_on_right = prepend_spaces_to_SpanU8_lines(VecU8_to_span(&Tc), 4);
|
||||
VecU8 Fc_exists = prepend_spaces_to_SpanU8_lines(VecU8_to_span(&Fc), 1);
|
||||
VecU8_drop(Tc);
|
||||
VecU8_drop(Fc);
|
||||
|
||||
VecU8_append_vec(result, VecU8_fmt(
|
||||
"%v %s_%s(%s* self, %s key) {\n" /* set, set, op.T */
|
||||
SPACE "if (self->root == 0) {\n"
|
||||
SPACE SPACE "assert(self->tree.len == 1);\n"
|
||||
SPACE SPACE "VecRBTreeNode_append(&self->tree, (RBTreeNode){.color = RBTree_black});\n"
|
||||
SPACE SPACE "Vec%s_append(&self->el, key);\n" /* op.T */
|
||||
SPACE SPACE "self->root = 1;\n"
|
||||
"%v" /* Tc_root */
|
||||
/* Should have returned by now in Tc*/
|
||||
SPACE "}\n"
|
||||
SPACE "U64 cur = self->root;\n"
|
||||
SPACE "while (%v) {\n" /* el[cur] != key */
|
||||
SPACE SPACE "if (%v) {\n" /* key < el[cur] */
|
||||
SPACE SPACE SPACE "if (self->tree.buf[cur].left != 0) {\n"
|
||||
SPACE SPACE SPACE SPACE "cur = self->tree.buf[cur].left;\n"
|
||||
SPACE SPACE SPACE "} else { \n"
|
||||
/* We are inserting to the left of cur */
|
||||
SPACE SPACE SPACE SPACE "U64 n = self->tree.len;\n"
|
||||
SPACE SPACE SPACE SPACE "VecRBTreeNode_append(&self->tree, (RBTreeNode){.parent = cur, .color = RBTree_red});\n"
|
||||
SPACE SPACE SPACE SPACE "self->tree.buf[cur].left = n;\n"
|
||||
SPACE SPACE SPACE SPACE "RBTree_fix_after_insert(self->tree.buf, &self->root, n);\n"
|
||||
SPACE SPACE SPACE SPACE "Vec%s_append(&self->el, key);\n" /* op.T */
|
||||
"%v" /* Tc_on_left */
|
||||
/* Should have returned by now in Tc*/
|
||||
SPACE SPACE SPACE "}\n"
|
||||
SPACE SPACE "} else {\n"
|
||||
SPACE SPACE SPACE "if (self->tree.buf[cur].right != 0) {\n"
|
||||
SPACE SPACE SPACE SPACE "cur = self->tree.buf[cur].right;\n"
|
||||
SPACE SPACE SPACE "} else {\n"
|
||||
/* We are inserting to the right of cur */
|
||||
SPACE SPACE SPACE SPACE "U64 n = self->tree.len;\n"
|
||||
SPACE SPACE SPACE SPACE "VecRBTreeNode_append(&self->tree, (RBTreeNode){.parent = cur, .color = RBTree_red});\n"
|
||||
SPACE SPACE SPACE SPACE "self->tree.buf[cur].right = n;\n"
|
||||
SPACE SPACE SPACE SPACE "RBTree_fix_after_insert(self->tree.buf, &self->root, n);\n"
|
||||
SPACE SPACE SPACE SPACE "Vec%s_append(&self->el, key);\n" /* op.T */
|
||||
"%v" /* Tc_on_right */
|
||||
/* Should have returned by now in Tc*/
|
||||
SPACE SPACE SPACE "}\n"
|
||||
SPACE SPACE "}\n"
|
||||
SPACE "}\n"
|
||||
"%v" /* Fc_exists */
|
||||
/* Should have returned by now in Tc*/
|
||||
"}\n\n",
|
||||
RT, set, method_name, set, op.T, op.T, Tc_root,
|
||||
codegen_rb_tree_set_key_value_NOT_EQUAL_element(op),
|
||||
codegen_rb_tree_set_key_value_LESS_element(op),
|
||||
op.T, Tc_on_left, op.T, Tc_on_right, Fc_exists
|
||||
));
|
||||
}
|
||||
|
||||
void codegen_append_rb_tree_set_erase_kind_method(
|
||||
VecU8* result, set_instantiation_op op, SpanU8 set, SpanU8 method_name, VecU8 RT,
|
||||
VecU8 Fc, VecU8 Tc_cur_available, VecU8 Tc_returning
|
||||
){
|
||||
VecU8 not_found_case = prepend_spaces_to_SpanU8_lines(VecU8_to_span(&Fc), 3);
|
||||
VecU8 saving_prev = prepend_spaces_to_SpanU8_lines(VecU8_to_span(&Tc_cur_available), 1);
|
||||
VecU8 ret_found_case = prepend_spaces_to_SpanU8_lines(VecU8_to_span(&Tc_returning), 1);
|
||||
VecU8_drop(Fc);
|
||||
VecU8_drop(Tc_cur_available);
|
||||
VecU8_drop(Tc_returning);
|
||||
|
||||
VecU8_append_vec(result, VecU8_fmt(
|
||||
"%v %s_%s(%s* self, %v key) {\n" /* RT, set, method_name, set, taking_ref_t_argument */
|
||||
SPACE "U64 cur = self->root;\n"
|
||||
SPACE "while (true){\n"
|
||||
SPACE SPACE "if (cur == 0) {\n"
|
||||
"%v" /* not_found_case */
|
||||
SPACE SPACE "}\n"
|
||||
SPACE SPACE "if (%v)\n" /* key_ref_EQUAL_element */
|
||||
SPACE SPACE SPACE "break;\n"
|
||||
SPACE SPACE "if (%v)\n" /* key_ref_LESS_element */
|
||||
SPACE SPACE SPACE "cur = self->tree.buf[cur].left;\n"
|
||||
SPACE SPACE "else\n"
|
||||
SPACE SPACE SPACE "cur = self->tree.buf[cur].right;\n"
|
||||
SPACE "}\n"
|
||||
"%v" /* saving_prev */
|
||||
SPACE "U64 z = cur;\n"
|
||||
SPACE "U64 y = (self->tree.buf[z].left == 0 || self->tree.buf[z].right == 0) ? z : RBTree_minimum_in_subtree(self->tree.buf, self->tree.buf[z].right);\n"
|
||||
SPACE "U64 x = self->tree.buf[y].left != 0 ? self->tree.buf[y].left : self->tree.buf[y].right;\n"
|
||||
SPACE "assert(x != y && x != z);\n"
|
||||
SPACE "U64 x_adopter = self->tree.buf[y].parent;\n"
|
||||
SPACE "self->tree.buf[x].parent = x_adopter;\n"
|
||||
SPACE "if (x_adopter == 0)\n"
|
||||
SPACE SPACE "self->root = x;\n"
|
||||
SPACE "else if (self->tree.buf[x_adopter].left == y)\n"
|
||||
SPACE SPACE "self->tree.buf[x_adopter].left = x;\n"
|
||||
SPACE "else\n"
|
||||
SPACE SPACE "self->tree.buf[x_adopter].right = x;\n"
|
||||
SPACE "RBTreeColor y_org_clr = self->tree.buf[y].color;\n"
|
||||
SPACE "if (z != y) {\n"
|
||||
SPACE SPACE "RBTree_steal_neighbours(self->tree.buf, &self->root, z, y);\n"
|
||||
SPACE SPACE "if (x_adopter == z)\n"
|
||||
SPACE SPACE SPACE "x_adopter = y;\n"
|
||||
SPACE "}\n"
|
||||
SPACE "U64 L = self->el.len;\n"
|
||||
SPACE "if (L != z) {\n"
|
||||
SPACE SPACE "RBTree_steal_neighbours(self->tree.buf, &self->root, L, z);\n"
|
||||
SPACE SPACE "self->el.buf[z-1] = self->el.buf[L-1];\n"
|
||||
SPACE SPACE "if (L == x)\n"
|
||||
SPACE SPACE SPACE "x = z;\n"
|
||||
SPACE SPACE "else if (L == x_adopter) \n"
|
||||
SPACE SPACE SPACE "x_adopter = z;\n"
|
||||
SPACE "}\n"
|
||||
SPACE "self->tree.buf[x].parent = x_adopter;\n"
|
||||
SPACE "self->tree.len--;\n"
|
||||
SPACE "self->el.len--;\n"
|
||||
SPACE "if (y_org_clr == RBTree_black)\n"
|
||||
SPACE SPACE "RBTree_fix_after_delete(self->tree.buf, &self->root, x);\n"
|
||||
"%v" /* ret_found_case */
|
||||
"}\n\n",
|
||||
RT, set, method_name, set, codegen_rb_tree_set_taking_ref_t_argument(op),
|
||||
not_found_case,
|
||||
codegen_rb_tree_set_key_ref_EQUAL_element(op),
|
||||
codegen_rb_tree_set_key_ref_LESS_element(op),
|
||||
saving_prev,
|
||||
ret_found_case
|
||||
));
|
||||
}
|
||||
|
||||
/* src/l1_5/core/rb_tree_node.h is a dependency of all instantiations of rb_tree_set template
|
||||
* Don't forget to include them
|
||||
*/
|
||||
NODISCARD VecU8 generate_rb_tree_Set_template_instantiation(set_instantiation_op op){
|
||||
set_instantiation_op_fix(&op);
|
||||
VecU8 res = VecU8_new();
|
||||
VecU8 g_set = VecU8_fmt("BuffRBTree_Set%s", op.T);
|
||||
SpanU8 set = VecU8_to_span(&g_set);
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"typedef struct {\n"
|
||||
SPACE "VecRBTreeNode tree;\n"
|
||||
SPACE "U64 root;\n"
|
||||
SPACE "Vec%s el;\n"
|
||||
"} %s;\n\n", op.T, set));
|
||||
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"NODISCARD %s %s_new() {\n"
|
||||
SPACE "return (%s){.tree = VecRBTreeNode_new_zeroinit(1), .root = 0, .el = Vec%s_new()};\n"
|
||||
"}\n\n", set, set, set, op.T));
|
||||
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"void %s_drop(%s self) {\n"
|
||||
SPACE "VecRBTreeNode_drop(self.tree);\n"
|
||||
SPACE "Vec%s_drop(self.el);\n"
|
||||
"}\n\n", set, set, op.T));
|
||||
|
||||
/* Method _insert() does not try to replace the existing element with equal key,
|
||||
* it returns true if insertion was done, false if collision happened and key was not inserted */
|
||||
codegen_append_rb_tree_set_insert_kind_method(&res, op, set, cstr("insert"), vcstr("bool"),
|
||||
vcstr("return true;\n"),
|
||||
op.t_integer ?
|
||||
vcstr("return false;\n") :
|
||||
VecU8_fmt(
|
||||
"%s_drop(key);\n" /* op.T */
|
||||
"return false;\n",
|
||||
op.T));
|
||||
|
||||
if (!op.t_integer) {
|
||||
/* Method _erase_substitute() is a more bald version of _insert() method. It will substitute
|
||||
* previous element with equal key it it was found. It still returns true if no conflict has happened, though */
|
||||
codegen_append_rb_tree_set_insert_kind_method(&res, op, set, cstr("erase_substitute"), vcstr("bool"),
|
||||
vcstr("return true;\n"),
|
||||
op.t_integer ?
|
||||
vcstr("return false;\n") :
|
||||
VecU8_fmt(
|
||||
"%s_drop(self->el.buf[cur - 1]);\n"
|
||||
"self->el.buf[cur - 1] = key;\n"
|
||||
"return false;\n"
|
||||
));
|
||||
|
||||
/* Method _pop_substitute() is just like _erase_substitute(), but it returns a previous key
|
||||
* that was overthrown after collision. Wrapped in option, ofcourse */
|
||||
codegen_append_rb_tree_set_insert_kind_method(&res, op, set, cstr("pop_substitute"),
|
||||
codegen_rb_tree_set_option_returned_value_t(op),
|
||||
VecU8_fmt("return %v;\n", codegen_rb_tree_set_none_t(op)),
|
||||
VecU8_fmt(
|
||||
"%s old = self->el.buf[cur - 1];\n" /* op.T */
|
||||
"self->el.buf[cur - 1] = key;\n"
|
||||
"return %v;", /* Some_T(old) */
|
||||
op.T, codegen_rb_tree_set_some_t(op, cstr("old"))));
|
||||
}
|
||||
|
||||
codegen_append_rb_tree_set_erase_kind_method(&res, op, set, cstr("erase"), vcstr("bool"),
|
||||
vcstr("return false;\n"),
|
||||
op.t_primitive ? vcstr("") : VecU8_fmt("%s_drop(self->el.buf[cur - 1]);\n", op.T),
|
||||
vcstr("return true;\n"));
|
||||
|
||||
if (!op.t_integer) {
|
||||
codegen_append_rb_tree_set_erase_kind_method(&res, op, set, cstr("pop"),
|
||||
codegen_rb_tree_set_option_returned_value_t(op),
|
||||
VecU8_fmt("return %v;\n", codegen_rb_tree_set_none_t(op)),
|
||||
VecU8_fmt("%s saved = self->el[cur - 1];\n", op.T),
|
||||
VecU8_fmt("return %v;\n", codegen_rb_tree_set_some_t(op, cstr("saved")))
|
||||
);
|
||||
}
|
||||
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"U64 %s_find(const %s* self, %v key) {\n" /* set, set taking_ref_t_argument */
|
||||
SPACE "U64 cur = self->root;\n"
|
||||
SPACE "while (cur != 0 && %v) {\n" /* key reference not equal cur element */
|
||||
SPACE SPACE "if (%v) {\n" /* key reference less than cue element */
|
||||
SPACE SPACE SPACE "cur = self->tree.buf[cur].left;\n"
|
||||
SPACE SPACE "} else {\n"
|
||||
SPACE SPACE SPACE "cur = self->tree.buf[cur].right;\n"
|
||||
SPACE SPACE "}\n"
|
||||
SPACE "}\n"
|
||||
SPACE "return cur;\n"
|
||||
"}\n\n",
|
||||
set, set, codegen_rb_tree_set_taking_ref_t_argument(op),
|
||||
codegen_rb_tree_set_key_ref_NOT_EQUAL_element(op),
|
||||
codegen_rb_tree_set_key_ref_LESS_element(op)
|
||||
));
|
||||
|
||||
if (!op.t_integer) {
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"%v %s_at(const %s* self, %v key) {\n" /* option_returned_ref_t, set, set, taking_ref_t_argument */
|
||||
SPACE "U64 cur = self->root;\n"
|
||||
SPACE "while (cur != 0) {\n"
|
||||
SPACE SPACE "if (%v) {\n" /* key_ref_EQUAL_element */
|
||||
SPACE SPACE SPACE "return %v;\n" /* some_ref_t */
|
||||
SPACE SPACE "} else if (%v) {\n" /* key_ref_LESS_element */
|
||||
SPACE SPACE SPACE "cur = self->tree.buf[cur].left;\n"
|
||||
SPACE SPACE "} else {\n"
|
||||
SPACE SPACE SPACE "cur = self->tree.buf[cur].right;\n"
|
||||
SPACE SPACE "}\n"
|
||||
SPACE "}\n"
|
||||
SPACE "return %v;\n" /* none_ref_t */
|
||||
"}\n\n",
|
||||
codegen_rb_tree_set_option_returned_ref_t(op), set, set, codegen_rb_tree_set_taking_ref_t_argument(op),
|
||||
codegen_rb_tree_set_key_ref_EQUAL_element(op),
|
||||
codegen_rb_tree_set_some_ref_t(op, cstr("cur")),
|
||||
codegen_rb_tree_set_key_ref_LESS_element(op),
|
||||
codegen_rb_tree_set_none_ref_t(op)
|
||||
));
|
||||
}
|
||||
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"NODISCARD %s %s_clone(const %s* self){\n"
|
||||
SPACE "return (%s){.tree = VecRBTreeNode_clone(&self->tree), .root = self->root,\n"
|
||||
SPACE SPACE "Vec%s_clone(&self->el)};\n"
|
||||
"}\n\n", set, set, set, set, op.T));
|
||||
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"U64 %s_find_next(const %s* self, U64 x){\n"
|
||||
SPACE "assert(x != 0 && x < self->tree.len);\n"
|
||||
SPACE "if (self->tree.buf[x].right != 0)\n"
|
||||
SPACE SPACE "return RBTree_minimum_in_subtree(self->tree.buf, self->tree.buf[x].right);\n"
|
||||
SPACE "while (true) {\n"
|
||||
SPACE SPACE "U64 p = self->tree.buf[x].parent;\n"
|
||||
SPACE SPACE "if (p == 0)\n"
|
||||
SPACE SPACE SPACE "return 0;\n"
|
||||
SPACE SPACE "if (self->tree.buf[p].left == x)\n"
|
||||
SPACE SPACE SPACE "return p;\n"
|
||||
SPACE SPACE "x = p;\n"
|
||||
SPACE "}\n"
|
||||
"}\n\n", set, set));
|
||||
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"U64 %s_find_prev(const %s* self, U64 x){\n"
|
||||
SPACE "assert(x != 0 && x < self->tree.len);\n"
|
||||
SPACE "if (self->tree.buf[x].left != 0)\n"
|
||||
SPACE SPACE "return RBTree_maximum_in_subtree(self->tree.buf, self->tree.buf[x].left);\n"
|
||||
SPACE "while (true) {\n"
|
||||
SPACE SPACE "U64 p = self->tree.buf[x].parent;\n"
|
||||
SPACE SPACE "if (p == 0)\n"
|
||||
SPACE SPACE SPACE "return 0;\n"
|
||||
SPACE SPACE "if (self->tree.buf[p].right == x)\n"
|
||||
SPACE SPACE SPACE "return p;\n"
|
||||
SPACE SPACE "x = p;\n"
|
||||
SPACE "}\n"
|
||||
"}\n\n", set, set));
|
||||
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"U64 %s_find_min(const %s* self) {\n"
|
||||
SPACE "return self->root != 0 ? RBTree_minimum_in_subtree(self->tree.buf, self->root) : 0;\n"
|
||||
"}\n\n", set, set));
|
||||
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"U64 %s_find_max(const %s* self) {\n"
|
||||
SPACE "return self->root != 0 ? RBTree_maximum_in_subtree(self->tree.buf, self->root) : 0;\n"
|
||||
"}\n\n", set, set));
|
||||
|
||||
// todo: continue from here. Implement method _pop_and_substitute()
|
||||
|
||||
// todo: All the other methods are secondary in importance
|
||||
|
||||
VecU8_drop(g_set);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
void generate_rb_tree_Set_templ_inst_eve_header(SpanU8 layer, SpanU8 bonus_ns, option_template_instantiation_op op) {
|
||||
VecU8 text = VecU8_from_cstr("/* Automatically generated file. Do not edit it.\n"
|
||||
" * Do not include it in more than one place */\n\n");
|
||||
VecU8_append_vec(&text, generate_OptionT_struct_and_methods(op));
|
||||
VecU8 nt_path = VecU8_fmt("%s/eve/%s/BuffRBTree_Set%s%c", layer, bonus_ns, op.T, 0);
|
||||
write_whole_file_or_abort((const char*)nt_path.buf, VecU8_to_span(&text));
|
||||
VecU8_drop(nt_path);
|
||||
VecU8_drop(text);
|
||||
}
|
||||
|
||||
void generate_rb_tree_Set_templ_inst_guarded_header(
|
||||
SpanU8 layer, SpanU8 bonus_ns, SpanU8 dependencies, set_instantiation_op op
|
||||
){
|
||||
assert(layer.len > 1);
|
||||
VecU8 path = VecU8_fmt("%s/%s%sBuffRBTree_Set%s.h", layer, bonus_ns, bonus_ns.len ? cstr("/") : cstr(""), op.T);
|
||||
GeneratedHeader head = begin_header(VecU8_to_span(&path));
|
||||
VecU8_drop(path);
|
||||
VecU8_append_span(&head.result, cstr("#include \"../../"));
|
||||
int to_my_layer = get_number_of_parts_in_header_namespace(bonus_ns);
|
||||
for (int i = 0; i < to_my_layer; i++)
|
||||
VecU8_append_span(&head.result, cstr("../"));
|
||||
VecU8_append_span(&head.result, cstr("src/l1_5/core/rb_tree_node.h\"\n"));
|
||||
VecU8_append_span(&head.result, dependencies);
|
||||
VecU8_append_span(&head.result, cstr("\n\n"));
|
||||
VecU8_append_vec(&head.result, generate_rb_tree_Set_template_instantiation(op));
|
||||
finish_header(head);
|
||||
}
|
||||
|
||||
#endif
|
||||
@ -28,7 +28,7 @@ NODISCARD VecU8 generate_trait_table_structure(NamedTraitDefRecordRef trait){
|
||||
// todo: add iteration macro
|
||||
for (size_t i = 0; i < trait.methods.len; i++) {
|
||||
NamedMethodSignatureRecordRef method = *SpanNamedMethodSignatureRecordRef_at(trait.methods, i);
|
||||
VecU8_append_vec(&res, VecU8_fmt(SPACE4 "%s (*%s)(", method.return_type, method.name));
|
||||
VecU8_append_vec(&res, VecU8_fmt(SPACE "%s (*%s)(", method.return_type, method.name));
|
||||
for (size_t p = 0; p < method.params.len; p++) {
|
||||
NamedVariableRecordRef param = *SpanNamedVariableRecordRef_at(method.params, p);
|
||||
if (p)
|
||||
|
||||
222
src/l1_5/core/rb_tree_node.h
Normal file
222
src/l1_5/core/rb_tree_node.h
Normal file
@ -0,0 +1,222 @@
|
||||
#ifndef PROTOTYPE1_SRC_L1_5_CORE_RB_TREE_NODE_H
|
||||
#define PROTOTYPE1_SRC_L1_5_CORE_RB_TREE_NODE_H
|
||||
|
||||
#include "../../l1/core/util.h"
|
||||
|
||||
typedef enum {
|
||||
RBTree_black = 0,
|
||||
RBTree_red = 1,
|
||||
} RBTreeColor;
|
||||
|
||||
typedef struct {
|
||||
size_t left;
|
||||
size_t right;
|
||||
size_t parent;
|
||||
/* 0 is black, 1 is red */
|
||||
RBTreeColor color;
|
||||
} RBTreeNode;
|
||||
|
||||
#include "../../../gen/l1/eve/embassy_l1_5/VecRBTreeNode.h"
|
||||
|
||||
void RBTree_left_rotate(RBTreeNode* tree, U64* root, U64 x){
|
||||
assert(x != 0);
|
||||
U64 y = tree[x].right;
|
||||
assert(y != 0);
|
||||
tree[x].right = tree[y].left;
|
||||
if (tree[x].right != 0)
|
||||
tree[tree[x].right].parent = x;
|
||||
|
||||
tree[y].parent = tree[x].parent;
|
||||
if (tree[y].parent == 0) {
|
||||
*root = y;
|
||||
} else if (x == tree[tree[x].parent].left) {
|
||||
tree[tree[x].parent].left = y;
|
||||
} else {
|
||||
tree[tree[x].parent].right = y;
|
||||
}
|
||||
tree[x].parent = y;
|
||||
tree[y].left = x;
|
||||
}
|
||||
|
||||
void RBTree_right_rotate(RBTreeNode* tree, U64* root, U64 x){
|
||||
assert(x != 0);
|
||||
U64 y = tree[x].left;
|
||||
assert(y != 0);
|
||||
tree[x].left = tree[y].right;
|
||||
if (tree[x].left != 0)
|
||||
tree[tree[x].left].parent = x;
|
||||
|
||||
tree[y].parent = tree[x].parent;
|
||||
if (tree[y].parent == 0) {
|
||||
*root = y;
|
||||
} else if (x == tree[tree[x].parent].right) {
|
||||
tree[tree[x].parent].right = y;
|
||||
} else {
|
||||
tree[tree[x].parent].left = y;
|
||||
}
|
||||
tree[x].parent = y;
|
||||
tree[y].right = x;
|
||||
}
|
||||
|
||||
/* Helper function. Called in automatically generated code */
|
||||
void RBTree_fix_after_insert(RBTreeNode* tree, U64* root, U64 me){
|
||||
assert(me);
|
||||
while (true) {
|
||||
U64 mom = tree[me].parent;
|
||||
if (mom == 0)
|
||||
break;
|
||||
if (tree[mom].color == RBTree_black)
|
||||
return;
|
||||
U64 grandma = tree[mom].parent;
|
||||
U64 aunt = tree[grandma].left == mom ? tree[grandma].right : tree[grandma].left;
|
||||
assert(aunt != mom);
|
||||
if (tree[aunt].color == RBTree_red) {
|
||||
/* Easy case */
|
||||
tree[mom].color = RBTree_black;
|
||||
tree[aunt].color = RBTree_black;
|
||||
tree[grandma].color = RBTree_red;
|
||||
me = grandma;
|
||||
} else if (tree[grandma].left == mom) {
|
||||
/* Hard case: firstborn orientation */
|
||||
if (tree[mom].right == me) {
|
||||
RBTree_left_rotate(tree, root, mom);
|
||||
tree[me].color = RBTree_black;
|
||||
} else {
|
||||
tree[mom].color = RBTree_black;
|
||||
}
|
||||
RBTree_right_rotate(tree, root, grandma);
|
||||
tree[grandma].color = RBTree_red;
|
||||
return;
|
||||
} else {
|
||||
/* Hard case: benjamin orientation */
|
||||
if (tree[mom].left == me) {
|
||||
RBTree_right_rotate(tree, root, mom);
|
||||
tree[me].color = RBTree_black;
|
||||
} else {
|
||||
tree[mom].color = RBTree_black;
|
||||
}
|
||||
RBTree_left_rotate(tree, root, grandma);
|
||||
tree[grandma].color = RBTree_red;
|
||||
return;
|
||||
}
|
||||
}
|
||||
assert(*root == me);
|
||||
tree[me].color = RBTree_black;
|
||||
}
|
||||
|
||||
/* fr index will be forgotten. to fields will be overwritten (all fields replaced by fr's values)
|
||||
* If you need the old values of `to` position, you better save them on stack */
|
||||
void RBTree_steal_neighbours(RBTreeNode* tree, U64* root, U64 fr, U64 to){
|
||||
if (tree[fr].parent == 0)
|
||||
*root = to;
|
||||
else if (tree[tree[fr].parent].left == fr)
|
||||
tree[tree[fr].parent].left = to;
|
||||
else
|
||||
tree[tree[fr].parent].right = to;
|
||||
tree[tree[fr].left].parent = to;
|
||||
tree[tree[fr].right].parent = to;
|
||||
tree[to] = tree[fr];
|
||||
}
|
||||
|
||||
/* helper function (used in _erase, _find_min methods). It is assumed that s is not null.
|
||||
* Guaranteed to return no-null
|
||||
*/
|
||||
U64 RBTree_minimum_in_subtree(RBTreeNode* tree, U64 s){
|
||||
assert(s != 0);
|
||||
while (tree[s].left != 0)
|
||||
s = tree[s].left;
|
||||
return s;
|
||||
}
|
||||
|
||||
/* helper function (used in _find_max, _find_prev methods). It is assumed that s is not null.
|
||||
* Guaranteed to return no-null
|
||||
*/
|
||||
U64 RBTree_maximum_in_subtree(RBTreeNode* tree, U64 s){
|
||||
assert(s != 0);
|
||||
while (tree[s].right != 0)
|
||||
s = tree[s].right;
|
||||
return s;
|
||||
}
|
||||
|
||||
void RBTree_fix_after_delete(RBTreeNode* tree, U64* root, U64 me){
|
||||
assert(tree[*root].parent == 0);
|
||||
while (me != *root && tree[me].color == RBTree_black) {
|
||||
U64 mom = tree[me].parent;
|
||||
if (me == tree[mom].left) { /* We are on the left */
|
||||
U64 sister = tree[mom].right;
|
||||
if (tree[sister].color == RBTree_red) { /* Case 1 */
|
||||
tree[mom].color = RBTree_red;
|
||||
tree[sister].color = RBTree_black;
|
||||
RBTree_left_rotate(tree, root, mom);
|
||||
/* Reassignation required */
|
||||
sister = tree[mom].right;
|
||||
}
|
||||
/* Cases 2,3,4 (every instance of red-black tree has an itchy substring in source code containing 2,3,4) */
|
||||
assert(sister != 0);
|
||||
U64 nephew_firstborn = tree[sister].left;
|
||||
U64 nephew_benjamin = tree[sister].right;
|
||||
if (tree[nephew_firstborn].color == RBTree_black && tree[nephew_benjamin].color == RBTree_black) {
|
||||
/* Case 2 */
|
||||
tree[sister].color = RBTree_red;
|
||||
me = mom;
|
||||
continue;
|
||||
}
|
||||
/* Cases 3,4 */
|
||||
if (tree[nephew_benjamin].color == RBTree_black) {
|
||||
/* Case 3 */
|
||||
tree[nephew_firstborn].color = RBTree_black;
|
||||
tree[sister].color = RBTree_red;
|
||||
RBTree_right_rotate(tree, root, sister);
|
||||
/* Reassignation required */
|
||||
nephew_benjamin = sister;
|
||||
sister = nephew_firstborn;
|
||||
nephew_firstborn = tree[sister].left;
|
||||
}
|
||||
/* Case 4 */
|
||||
tree[sister].color = tree[mom].color;
|
||||
tree[mom].color = RBTree_black;
|
||||
tree[nephew_benjamin].color = RBTree_black;
|
||||
RBTree_left_rotate(tree, root, mom);
|
||||
me = *root;
|
||||
} else if (me == tree[mom].right) { /* We are on the right */
|
||||
U64 sister = tree[mom].left;
|
||||
if (tree[sister].color == RBTree_red) { /* Case 1 */
|
||||
tree[mom].color = RBTree_red;
|
||||
tree[sister].color = RBTree_black;
|
||||
RBTree_right_rotate(tree, root, mom);
|
||||
/* Reassignation required */
|
||||
sister = tree[mom].left;
|
||||
}
|
||||
/* Cases 2,3,4 (every instance of red-black tree has an itchy substring in source code containing 2,3,4) */
|
||||
assert(sister != 0);
|
||||
U64 nephew_firstborn = tree[sister].left;
|
||||
U64 nephew_benjamin = tree[sister].right;
|
||||
if (tree[nephew_firstborn].color == RBTree_black && tree[nephew_benjamin].color == RBTree_black) {
|
||||
/* Case 2 */
|
||||
tree[sister].color = RBTree_red;
|
||||
me = mom;
|
||||
continue;
|
||||
}
|
||||
/* Cases 3,4 */
|
||||
if (tree[nephew_firstborn].color == RBTree_black) {
|
||||
/* Case 3 */
|
||||
tree[nephew_benjamin].color = RBTree_black;
|
||||
tree[sister].color = RBTree_red;
|
||||
RBTree_left_rotate(tree, root, sister);
|
||||
/* Reassignation required */
|
||||
nephew_firstborn = sister;
|
||||
sister = nephew_benjamin;
|
||||
nephew_benjamin = tree[sister].right;
|
||||
}
|
||||
/* Case 4 */
|
||||
tree[sister].color = tree[mom].color;
|
||||
tree[mom].color = RBTree_black;
|
||||
tree[nephew_firstborn].color = RBTree_black;
|
||||
RBTree_right_rotate(tree, root, mom);
|
||||
me = *root;
|
||||
}
|
||||
}
|
||||
tree[me].color = RBTree_black;
|
||||
}
|
||||
|
||||
#endif
|
||||
@ -27,17 +27,6 @@ bool string_contains_string_ignorecase(SpanU8 str1, SpanU8 str2) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// todo: create a method "span_contents_equal" in span template
|
||||
bool strings_in_spans_equal(SpanU8 a, SpanU8 b) {
|
||||
if (a.len != b.len)
|
||||
return false;
|
||||
for (size_t i = 0; i < a.len; i++) {
|
||||
if (*SpanU8_at(a, i) != *SpanU8_at(b, i))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool is_string_in_string_vec(SpanU8 a, const VecVecU8* B) {
|
||||
for (size_t i = 0; i < B->len; i++) {
|
||||
if (strings_in_spans_equal(a, VecU8_to_span(VecVecU8_at(B, i))))
|
||||
|
||||
@ -22,7 +22,7 @@ typedef struct {
|
||||
typedef struct {
|
||||
void* r;
|
||||
const LizaSound_Table* t;
|
||||
} MutRefLizaSound;
|
||||
} RefMutLizaSound;
|
||||
|
||||
/* Existence of Box<Trait> type implies that _drop method is virtual according to this trait */
|
||||
typedef struct {
|
||||
|
||||
@ -16,13 +16,19 @@
|
||||
#include "../../../gen/l1/vulkan/VecVkExtensionProperties.h"
|
||||
#include "../../../gen/l1/vulkan/VecVkImageView.h"
|
||||
#include "../../../gen/l1/vulkan/VecVkPhysicalDevice.h"
|
||||
#include "../../../gen/l1/vulkan/SpanAndOption_VkFormat.h"
|
||||
#include "../../../gen/l1/vulkan/SpanVkFormat.h"
|
||||
#include "../../../gen/l1/vulkan/OptionVkFormat.h"
|
||||
#include "../../../gen/l1/vulkan/VecVkDescriptorPoolSize.h"
|
||||
#include "../../../gen/l1/vulkan/VecVkQueueFamilyProperties.h"
|
||||
#include "../../../gen/l1/vulkan/OptionVkCompositeAlphaFlagBitsKHR.h"
|
||||
#include "../../../gen/l1/vulkan/VecAndOption_VkPresentModeKHR.h"
|
||||
#include "../../../gen/l1/vulkan/VecAndOption_VkSurfaceFormatKHR.h"
|
||||
#include "../../../gen/l1/vulkan/VecVkPresentModeKHR.h"
|
||||
#include "../../../gen/l1/vulkan/OptionVkPresentModeKHR.h"
|
||||
#include "../../../gen/l1/vulkan/OptionVkPresentModeKHR.h"
|
||||
#include "../../../gen/l1/vulkan/VecVkPresentModeKHR.h"
|
||||
#include "../../../gen/l1/vulkan/VecVkSurfaceFormatKHR.h"
|
||||
#include "../../../gen/l1/vulkan/OptionVkSurfaceFormatKHR.h"
|
||||
#include <vulkan/vulkan_wayland.h>
|
||||
// #include <vulkan/vulkan.h>
|
||||
|
||||
|
||||
|
||||
|
||||
522
src/l2/tests/data_structures/t0.c
Normal file
522
src/l2/tests/data_structures/t0.c
Normal file
@ -0,0 +1,522 @@
|
||||
#include "../../../../gen/l1_5/BuffRBTree_SetS64.h"
|
||||
#include "../../../../gen/l1/VecAndSpan_int_primitives.h"
|
||||
#include "../../../l1/core/VecU8_as_str.h"
|
||||
#include "../../../l1/system/fileio.h"
|
||||
#include "../../../l1/system/fsmanip.h"
|
||||
#include "../../../l1/system/creating_child_proc.h"
|
||||
|
||||
void check_structure_h_dfs(const VecRBTreeNode* tree, U64 x, VecU8* f){
|
||||
if (x == 0)
|
||||
return;
|
||||
if (*VecU8_at(f, x - 1) != 0)
|
||||
check(false);
|
||||
*VecU8_mat(f, x - 1) = 1;
|
||||
check_structure_h_dfs(tree, VecRBTreeNode_at(tree, x)->left, f);
|
||||
check_structure_h_dfs(tree, VecRBTreeNode_at(tree, x)->right, f);
|
||||
}
|
||||
|
||||
U32 check_structure_h_dfs_2(RBTreeNode* tree, U64 x){
|
||||
if (x == 0) {
|
||||
return 0;
|
||||
}
|
||||
U32 a = check_structure_h_dfs_2(tree, tree[x].left);
|
||||
U32 b = check_structure_h_dfs_2(tree, tree[x].right);
|
||||
check(a == b);
|
||||
return a + (tree[x].color == RBTree_black ? 1 : 0);
|
||||
}
|
||||
|
||||
S64 min_key_in_subtree(const BuffRBTree_SetS64* self, U64 x){
|
||||
assert(x != 0 && x < self->tree.len);
|
||||
S64 ans = self->el.buf[x - 1];
|
||||
if (self->tree.buf[x].left != 0) {
|
||||
ans = MIN_S64(ans, min_key_in_subtree(self, self->tree.buf[x].left));
|
||||
}
|
||||
if (self->tree.buf[x].right != 0) {
|
||||
ans = MIN_S64(ans, min_key_in_subtree(self, self->tree.buf[x].right));
|
||||
}
|
||||
return ans;
|
||||
}
|
||||
|
||||
S64 max_key_in_subtree(const BuffRBTree_SetS64* self, U64 x){
|
||||
assert(x != 0 && x < self->tree.len);
|
||||
S64 ans = self->el.buf[x - 1];
|
||||
if (self->tree.buf[x].left != 0) {
|
||||
ans = MAX_S64(ans, max_key_in_subtree(self, self->tree.buf[x].left));
|
||||
}
|
||||
if (self->tree.buf[x].right != 0) {
|
||||
ans = MAX_S64(ans, max_key_in_subtree(self, self->tree.buf[x].right));
|
||||
}
|
||||
return ans;
|
||||
}
|
||||
|
||||
void check_only_structure(const BuffRBTree_SetS64* self){
|
||||
check(self->tree.len == self->el.len + 1);
|
||||
check(self->root < self->tree.len);
|
||||
if (self->tree.len > 1) {
|
||||
check(self->root != 0);
|
||||
}
|
||||
VecU8 f = VecU8_new_zeroinit(self->tree.len - 1);
|
||||
check_structure_h_dfs(&self->tree, self->root, &f);
|
||||
for (size_t i = 0; i < self->tree.len - 1; i++) {
|
||||
check(*VecU8_at(&f, i));
|
||||
}
|
||||
VecU8_drop(f); /* f invalidated */
|
||||
for (size_t v = 1; v < self->tree.len; v++) {
|
||||
if (v == self->root) {
|
||||
check(self->tree.buf[v].parent == 0);
|
||||
} else {
|
||||
check(self->tree.buf[v].parent != 0);
|
||||
}
|
||||
check(self->tree.buf[v].parent < self->tree.len);
|
||||
check(self->tree.buf[v].left < self->tree.len);
|
||||
check(self->tree.buf[v].right < self->tree.len);
|
||||
if (self->tree.buf[v].left != 0) {
|
||||
check(self->tree.buf[self->tree.buf[v].left].parent == v);
|
||||
}
|
||||
if (self->tree.buf[v].right != 0) {
|
||||
check(self->tree.buf[self->tree.buf[v].right].parent == v);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void check_correctness(const BuffRBTree_SetS64* self){
|
||||
check_only_structure(self);
|
||||
|
||||
/* Checking coloring */
|
||||
check(self->tree.buf[0].color == RBTree_black);
|
||||
if (self->root != 0)
|
||||
check(self->tree.buf[self->root].color == RBTree_black);
|
||||
for (size_t v = 1; v < self->tree.len; v++) {
|
||||
if (self->tree.buf[v].color == RBTree_red) {
|
||||
check(self->tree.buf[self->tree.buf[v].left].color == RBTree_black);
|
||||
check(self->tree.buf[self->tree.buf[v].right].color == RBTree_black);
|
||||
}
|
||||
}
|
||||
check_structure_h_dfs_2(self->tree.buf, self->root);
|
||||
|
||||
/* checking keys, but better */
|
||||
for (size_t v = 1; v < self->tree.len; v++) {
|
||||
if (self->tree.buf[v].left != 0) {
|
||||
check(self->el.buf[self->tree.buf[v].left - 1] < self->el.buf[v - 1]);
|
||||
}
|
||||
if (self->tree.buf[v].right != 0) {
|
||||
check(self->el.buf[v - 1] < self->el.buf[self->tree.buf[v].right - 1]);
|
||||
}
|
||||
}
|
||||
for (size_t v = 1; v < self->tree.len; v++) {
|
||||
if (self->tree.buf[v].left != 0) {
|
||||
check(max_key_in_subtree(self, self->tree.buf[v].left) < self->el.buf[v - 1]);
|
||||
}
|
||||
if (self->tree.buf[v].right != 0) {
|
||||
check(self->el.buf[v - 1] < min_key_in_subtree(self, self->tree.buf[v].right));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void save_tree_to_file(const BuffRBTree_SetS64* set, SpanU8 name){
|
||||
check_only_structure(set);
|
||||
|
||||
VecS64 ranked_node_to_rb_node = VecS64_new_reserved(set->el.len);
|
||||
{
|
||||
VecS64 bfs_nxt = VecS64_new();
|
||||
VecS64 bfs = VecS64_new();
|
||||
if (set->root != 0)
|
||||
VecS64_append(&bfs_nxt, (S64)set->root);
|
||||
while (bfs_nxt.len > 0) {
|
||||
VecS64 t = bfs_nxt;
|
||||
bfs_nxt = bfs;
|
||||
bfs = t;
|
||||
for (size_t j = 0; j < bfs.len; j++) {
|
||||
S64 cur = *VecS64_at(&bfs, j);
|
||||
assert(cur != 0);
|
||||
VecS64_append(&ranked_node_to_rb_node, cur);
|
||||
if (cur < 0)
|
||||
continue;
|
||||
if (set->tree.buf[cur].left != 0)
|
||||
VecS64_append(&bfs_nxt, (S64)set->tree.buf[cur].left);
|
||||
else if (set->tree.buf[cur].right != 0)
|
||||
VecS64_append(&bfs_nxt, -cur);
|
||||
if (set->tree.buf[cur].right != 0)
|
||||
VecS64_append(&bfs_nxt, (S64)set->tree.buf[cur].right);
|
||||
else if (set->tree.buf[cur].left != 0)
|
||||
VecS64_append(&bfs_nxt, -cur);
|
||||
}
|
||||
bfs.len = 0;
|
||||
}
|
||||
}
|
||||
VecU8 graph = VecU8_new();
|
||||
VecU8_append_span(&graph, cstr(
|
||||
"digraph rbtree {\n"
|
||||
" fontsize = 20\n"
|
||||
" rankdir = TB\n"
|
||||
" bgcolor = \"lightgray\"\n"
|
||||
" node [fontname = \"Arial\", style=\"rounded,filled\", shape=circle];\n"));
|
||||
for (U64 j = 0; j < ranked_node_to_rb_node.len; j++) {
|
||||
S64 cur = ranked_node_to_rb_node.buf[j];
|
||||
assert(cur != 0);
|
||||
if (cur < 0) {
|
||||
VecU8_append_vec(&graph, VecU8_fmt(" n_%i [style=invis, label=\"\"]\n", -cur));
|
||||
continue;
|
||||
}
|
||||
U64 i = (U64)cur;
|
||||
VecU8_append_vec(&graph, VecU8_fmt(
|
||||
" v%u [label=%i, xlabel=<<FONT color='%s'>%u</FONT>>, color=%s, fontcolor=%s]\n",
|
||||
i, set->el.buf[i - 1],
|
||||
set->tree.buf[i].color == RBTree_black ? cstr("black") : cstr("red"), i,
|
||||
set->tree.buf[i].color == RBTree_black ? cstr("black") : cstr("red"),
|
||||
set->tree.buf[i].color == RBTree_black ? cstr("white") : cstr("black")));
|
||||
}
|
||||
VecU8_append_span(&graph, cstr("\n"));
|
||||
for (U64 j = 0; j < ranked_node_to_rb_node.len; j++) {
|
||||
S64 cur = ranked_node_to_rb_node.buf[j];
|
||||
if (cur < 0)
|
||||
continue;
|
||||
U64 i = (U64)cur;
|
||||
if (set->tree.buf[i].left != 0) {
|
||||
VecU8_append_vec(&graph, VecU8_fmt(" v%u -> v%u [weight=2]\n", i, set->tree.buf[i].left));
|
||||
} else if (set->tree.buf[i].right != 0) {
|
||||
VecU8_append_vec(&graph, VecU8_fmt(" v%u -> n_%u [style=invis, weight=3]\n", i, i));
|
||||
}
|
||||
if (set->tree.buf[i].right != 0) {
|
||||
VecU8_append_vec(&graph, VecU8_fmt(" v%u -> v%u [weight=2]\n", i, set->tree.buf[i].right));
|
||||
} else if (set->tree.buf[i].left != 0) {
|
||||
VecU8_append_vec(&graph, VecU8_fmt(" v%u -> n_%u [style=invis, weight=3]\n", i, i));
|
||||
}
|
||||
}
|
||||
VecU8_append_span(&graph, cstr("}\n"));
|
||||
mkdir_nofail("GRAPHS");
|
||||
VecU8 dot_filename_nt = VecU8_fmt("GRAPHS/GRAPH_%s.gv%c", name, 0);
|
||||
write_whole_file_or_abort((CSTR)dot_filename_nt.buf, VecU8_to_span(&graph));
|
||||
VecU8_drop(graph);
|
||||
VecU8_drop(dot_filename_nt);
|
||||
VecU8 command_nt = VecU8_fmt("dot -Tpng GRAPHS/GRAPH_%s.gv -o GRAPHS/GRAPH_%s.png%c", name, name, 0);
|
||||
calling_system_func_nofail((CSTR)command_nt.buf);
|
||||
VecU8_drop(command_nt);
|
||||
}
|
||||
|
||||
void insert_only(){
|
||||
{
|
||||
BuffRBTree_SetS64 set = BuffRBTree_SetS64_new();
|
||||
check_correctness(&set);
|
||||
BuffRBTree_SetS64_drop(set);
|
||||
}
|
||||
{
|
||||
BuffRBTree_SetS64 set = BuffRBTree_SetS64_new();
|
||||
bool ret = BuffRBTree_SetS64_insert(&set, 42);
|
||||
check(ret);
|
||||
check_correctness(&set);
|
||||
check(set.el.len == 1);
|
||||
check(set.root == 1);
|
||||
BuffRBTree_SetS64_drop(set);
|
||||
}
|
||||
{
|
||||
bool ret;
|
||||
BuffRBTree_SetS64 set = BuffRBTree_SetS64_new();
|
||||
ret = BuffRBTree_SetS64_insert(&set, 42);
|
||||
check(ret);
|
||||
check_correctness(&set);
|
||||
ret = BuffRBTree_SetS64_insert(&set, 69);
|
||||
check(ret);
|
||||
check_correctness(&set);
|
||||
check(set.el.len == 2);
|
||||
BuffRBTree_SetS64_drop(set);
|
||||
}
|
||||
{
|
||||
bool ret;
|
||||
BuffRBTree_SetS64 set = BuffRBTree_SetS64_new();
|
||||
ret = BuffRBTree_SetS64_insert(&set, 70);
|
||||
check(ret);
|
||||
check_correctness(&set);
|
||||
ret = BuffRBTree_SetS64_insert(&set, 50);
|
||||
check(ret);
|
||||
check_correctness(&set);
|
||||
check(set.el.len == 2);
|
||||
BuffRBTree_SetS64_drop(set);
|
||||
}
|
||||
{
|
||||
bool ret;
|
||||
BuffRBTree_SetS64 set = BuffRBTree_SetS64_new();
|
||||
ret = BuffRBTree_SetS64_insert(&set, 1);
|
||||
check(ret);
|
||||
check_correctness(&set);
|
||||
ret = BuffRBTree_SetS64_insert(&set, 2);
|
||||
check(ret);
|
||||
check_correctness(&set);
|
||||
ret = BuffRBTree_SetS64_insert(&set, 3);
|
||||
check(ret);
|
||||
check_correctness(&set);
|
||||
BuffRBTree_SetS64_drop(set);
|
||||
}
|
||||
{
|
||||
BuffRBTree_SetS64 set = BuffRBTree_SetS64_new();
|
||||
for (S64 i = 10; i < 100; i++) {
|
||||
bool ret = BuffRBTree_SetS64_insert(&set, i);
|
||||
check(ret);
|
||||
check_correctness(&set);
|
||||
}
|
||||
BuffRBTree_SetS64_drop(set);
|
||||
}
|
||||
{
|
||||
BuffRBTree_SetS64 set = BuffRBTree_SetS64_new();
|
||||
for (S64 i = 99; i >= 10; i--) {
|
||||
bool ret = BuffRBTree_SetS64_insert(&set, i);
|
||||
check(ret);
|
||||
check_correctness(&set);
|
||||
}
|
||||
BuffRBTree_SetS64_drop(set);
|
||||
}
|
||||
{
|
||||
BuffRBTree_SetS64 set = BuffRBTree_SetS64_new();
|
||||
for (S64 i = 10; i < 100; i++) {
|
||||
bool ret = BuffRBTree_SetS64_insert(&set, i);
|
||||
check(ret);
|
||||
check_correctness(&set);
|
||||
bool ret2 = BuffRBTree_SetS64_insert(&set, 1000 - i);
|
||||
check(ret2);
|
||||
check_correctness(&set);
|
||||
}
|
||||
BuffRBTree_SetS64_drop(set);
|
||||
}
|
||||
{
|
||||
BuffRBTree_SetS64 set = BuffRBTree_SetS64_new();
|
||||
// BuffRBTree_SetS64_erase_substitute()
|
||||
BuffRBTree_SetS64_drop(set);
|
||||
}
|
||||
}
|
||||
|
||||
void insert_and_then_find(){
|
||||
BuffRBTree_SetS64 set = BuffRBTree_SetS64_new();
|
||||
for (S64 p = 0; p < 100; p++) {
|
||||
bool ret = BuffRBTree_SetS64_insert(&set, 2 * p);
|
||||
check(ret);
|
||||
check_correctness(&set);
|
||||
for (S64 i = 0; i <= p; i++) {
|
||||
U64 ret1 = BuffRBTree_SetS64_find(&set, 2 * i);
|
||||
check(ret1);
|
||||
U64 ret2 = BuffRBTree_SetS64_find(&set, 2 * i + 1);
|
||||
check(ret2 == 0);
|
||||
}
|
||||
}
|
||||
BuffRBTree_SetS64_drop(set);
|
||||
}
|
||||
|
||||
void insert_and_delete(){
|
||||
{
|
||||
BuffRBTree_SetS64 set = BuffRBTree_SetS64_new();
|
||||
check(BuffRBTree_SetS64_insert(&set, 1))
|
||||
check_correctness(&set);
|
||||
check(BuffRBTree_SetS64_find(&set, 1));
|
||||
check(BuffRBTree_SetS64_erase(&set, 1));
|
||||
check_correctness(&set);
|
||||
check(!BuffRBTree_SetS64_find(&set, 1));
|
||||
BuffRBTree_SetS64_drop(set);
|
||||
}
|
||||
{
|
||||
BuffRBTree_SetS64 set = BuffRBTree_SetS64_new();
|
||||
check(BuffRBTree_SetS64_insert(&set, 1))
|
||||
check_correctness(&set);
|
||||
check(BuffRBTree_SetS64_insert(&set, 2))
|
||||
check_correctness(&set);
|
||||
check(BuffRBTree_SetS64_erase(&set, 2));
|
||||
check_correctness(&set);
|
||||
check(BuffRBTree_SetS64_find(&set, 1));
|
||||
check(!BuffRBTree_SetS64_find(&set, 2));
|
||||
check(BuffRBTree_SetS64_erase(&set, 1));
|
||||
check_correctness(&set);
|
||||
check(!BuffRBTree_SetS64_find(&set, 1));
|
||||
check(!BuffRBTree_SetS64_find(&set, 2));
|
||||
BuffRBTree_SetS64_drop(set);
|
||||
}
|
||||
{
|
||||
BuffRBTree_SetS64 set = BuffRBTree_SetS64_new();
|
||||
check(BuffRBTree_SetS64_insert(&set, 1))
|
||||
check_correctness(&set);
|
||||
check(BuffRBTree_SetS64_insert(&set, 2))
|
||||
check_correctness(&set);
|
||||
check(BuffRBTree_SetS64_erase(&set, 1));
|
||||
check_correctness(&set);
|
||||
check(!BuffRBTree_SetS64_find(&set, 1));
|
||||
check(BuffRBTree_SetS64_find(&set, 2));
|
||||
|
||||
check(!BuffRBTree_SetS64_erase(&set, 1));
|
||||
check(!BuffRBTree_SetS64_find(&set, 1));
|
||||
check(BuffRBTree_SetS64_find(&set, 2));
|
||||
check(BuffRBTree_SetS64_erase(&set, 2));
|
||||
check_correctness(&set);
|
||||
check(!BuffRBTree_SetS64_find(&set, 1));
|
||||
check(!BuffRBTree_SetS64_find(&set, 2));
|
||||
BuffRBTree_SetS64_drop(set);
|
||||
}
|
||||
{
|
||||
BuffRBTree_SetS64 set = BuffRBTree_SetS64_new();
|
||||
for (S64 i = -120; i < 1000; i += 10) {
|
||||
check(BuffRBTree_SetS64_insert(&set, i))
|
||||
check_correctness(&set);
|
||||
}
|
||||
// save_tree_to_file(&set, cstr("tree"));
|
||||
BuffRBTree_SetS64_drop(set);
|
||||
}
|
||||
{
|
||||
BuffRBTree_SetS64 set = BuffRBTree_SetS64_new();
|
||||
check(BuffRBTree_SetS64_insert(&set, 1))
|
||||
check_correctness(&set);
|
||||
check(BuffRBTree_SetS64_insert(&set, 2))
|
||||
check_correctness(&set);
|
||||
check(BuffRBTree_SetS64_insert(&set, 3))
|
||||
check_correctness(&set);
|
||||
// save_tree_to_file(&set, cstr("trio"));
|
||||
check(BuffRBTree_SetS64_erase(&set, 2));
|
||||
check_correctness(&set);
|
||||
// save_tree_to_file(&set, cstr("duo"));
|
||||
BuffRBTree_SetS64_drop(set);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void MutSpanS64_shuffle(MutSpanS64 span){
|
||||
if (span.len <= 1)
|
||||
return;
|
||||
for (size_t i = span.len-1; i > 0; i--) {
|
||||
size_t j = rand() % (i + 1);
|
||||
S64 temp = span.data[i];
|
||||
span.data[i] = span.data[j];
|
||||
span.data[j] = temp;
|
||||
}
|
||||
}
|
||||
|
||||
VecS64 gen_cool_sequence(S64 i){
|
||||
VecS64 res = VecS64_new_reserved(i);
|
||||
for (S64 j = 0; j < i; j++) {
|
||||
VecS64_append(&res, (j + 1) * 10);
|
||||
}
|
||||
MutSpanS64_shuffle(VecS64_to_mspan(&res));
|
||||
return res;
|
||||
}
|
||||
|
||||
void chaos(){
|
||||
for (int i = 1; i < 100; i++) {
|
||||
srand(i);
|
||||
BuffRBTree_SetS64 set = BuffRBTree_SetS64_new();
|
||||
VecS64 seq_to_insert = gen_cool_sequence(i);
|
||||
for (int j = 0; j < i; j++) {
|
||||
S64 to_insert = seq_to_insert.buf[j];
|
||||
BuffRBTree_SetS64_insert(&set, to_insert);
|
||||
check_correctness(&set);
|
||||
}
|
||||
assert(set.el.len == (size_t)i);
|
||||
// save_tree_to_file(&set, cstr("last_good"));
|
||||
S64 to_delete = (rand() % i + 1) * 10;
|
||||
printf("Started deleting from i=%d\n", i);
|
||||
check(BuffRBTree_SetS64_erase(&set, to_delete));
|
||||
printf("Deleted from i=%d\n", i);
|
||||
check_only_structure(&set);
|
||||
// save_tree_to_file(&set, cstr("fucked_tree"));
|
||||
check_correctness(&set);
|
||||
VecS64_drop(seq_to_insert);
|
||||
BuffRBTree_SetS64_drop(set);
|
||||
}
|
||||
}
|
||||
|
||||
void triple_black(){
|
||||
BuffRBTree_SetS64 set;
|
||||
{
|
||||
VecRBTreeNode tree = VecRBTreeNode_new_zeroinit(4);
|
||||
tree.buf[1] = (RBTreeNode){.parent = 3};
|
||||
tree.buf[2] = (RBTreeNode){.parent = 3};
|
||||
tree.buf[3] = (RBTreeNode){.left = 2, .right = 1};
|
||||
VecS64 el = VecS64_new_reserved(3);
|
||||
VecS64_append(&el, 300);
|
||||
VecS64_append(&el, 100);
|
||||
VecS64_append(&el, 200);
|
||||
set = (BuffRBTree_SetS64){.tree = tree, .root = 3, .el = el};
|
||||
}
|
||||
check_correctness(&set);
|
||||
check(BuffRBTree_SetS64_erase(&set, 300));
|
||||
check_correctness(&set);
|
||||
BuffRBTree_SetS64_drop(set);
|
||||
}
|
||||
|
||||
void absolute_chaos(){
|
||||
for (int i = 1; i < 100; i++) {
|
||||
srand(i);
|
||||
BuffRBTree_SetS64 set = BuffRBTree_SetS64_new();
|
||||
VecS64 seq_to_insert = gen_cool_sequence(i);
|
||||
for (int j = 0; j < i; j++) {
|
||||
S64 to_insert = seq_to_insert.buf[j];
|
||||
check(BuffRBTree_SetS64_insert(&set, to_insert));
|
||||
check_correctness(&set);
|
||||
}
|
||||
printf("Filled chaos with i = %d\n", i);
|
||||
// save_tree_to_file(&set, cstr("i_3"));
|
||||
assert(set.el.len == (size_t)i);
|
||||
VecS64 seq_to_erase = gen_cool_sequence(i);
|
||||
for (int j = 0; j < i; j++) {
|
||||
S64 to_erase = seq_to_erase.buf[j];
|
||||
check(BuffRBTree_SetS64_erase(&set, to_erase));
|
||||
check_correctness(&set);
|
||||
}
|
||||
printf("Emptied chaos with i = %d\n", i);
|
||||
assert(set.el.len == 0);
|
||||
VecS64_drop(seq_to_insert);
|
||||
VecS64_drop(seq_to_erase);
|
||||
BuffRBTree_SetS64_drop(set);
|
||||
}
|
||||
}
|
||||
|
||||
void stress(){
|
||||
printf("Prepare for some real stress\n");
|
||||
for (int s = 2; s < 1000; s++) {
|
||||
srand(s);
|
||||
BuffRBTree_SetS64 set = BuffRBTree_SetS64_new();
|
||||
VecS64 real_set = VecS64_new();
|
||||
U32 n = (U32)s;
|
||||
VecS64 complementary_set = VecS64_new_reserved(n);
|
||||
for (size_t i = 0; i < n; i++) {
|
||||
VecS64_append(&complementary_set, (S64)i * 10);
|
||||
}
|
||||
for (int t = 0; t < 1000; t++) {
|
||||
/* Do something */
|
||||
int do_insertion = rand() % 2;
|
||||
if (real_set.len == 0)
|
||||
do_insertion = 1;
|
||||
if (complementary_set.len == 0)
|
||||
do_insertion = 0;
|
||||
if (do_insertion) {
|
||||
assert(complementary_set.len > 0);
|
||||
size_t j = rand() % complementary_set.len;
|
||||
S64 v = VecS64_unordered_pop(&complementary_set, j);
|
||||
VecS64_append(&real_set, v);
|
||||
check(BuffRBTree_SetS64_insert(&set, v));
|
||||
} else {
|
||||
assert(real_set.len > 0);
|
||||
size_t j = rand() % real_set.len;
|
||||
S64 v = VecS64_unordered_pop(&real_set, j);
|
||||
VecS64_append(&complementary_set, v);
|
||||
check(BuffRBTree_SetS64_erase(&set, v));
|
||||
}
|
||||
/* We did something */
|
||||
check(real_set.len == set.el.len);
|
||||
for (size_t j = 0; j < real_set.len; j++) {
|
||||
check(BuffRBTree_SetS64_find(&set, real_set.buf[j]) != 0);
|
||||
}
|
||||
for (size_t j = 0; j < complementary_set.len; j++) {
|
||||
check(BuffRBTree_SetS64_find(&set, complementary_set.buf[j]) == 0);
|
||||
}
|
||||
}
|
||||
VecS64_drop(real_set);
|
||||
VecS64_drop(complementary_set);
|
||||
BuffRBTree_SetS64_drop(set);
|
||||
printf("Seed s=%d passed test\n", s);
|
||||
}
|
||||
}
|
||||
|
||||
int main() {
|
||||
insert_only();
|
||||
insert_and_then_find();
|
||||
insert_and_delete();
|
||||
chaos();
|
||||
triple_black();
|
||||
absolute_chaos();
|
||||
stress();
|
||||
return 0;
|
||||
}
|
||||
@ -9,7 +9,7 @@
|
||||
#include "../../../l1/system/fsmanip.h"
|
||||
#include "../../../../gen/l_wl_protocols/xdg-shell-client.h"
|
||||
#include <xkbcommon/xkbcommon.h>
|
||||
|
||||
#include "../../../l1/system/creating_child_proc.h"
|
||||
#include "../../margaret/png_pixel_masses.h"
|
||||
|
||||
// todo: generate this structure in l2
|
||||
@ -1646,27 +1646,16 @@ static const struct wl_callback_listener main_h_wl_surface_frame_listener = {
|
||||
|
||||
|
||||
|
||||
void calling_system_func(const char* command) {
|
||||
int ret = system(command);
|
||||
if (ret == -1) {
|
||||
abortf("system() failed\n");
|
||||
} else if (WIFEXITED(ret) && WEXITSTATUS(ret) != 0) {
|
||||
abortf("Error: command exited with code %d\n", WEXITSTATUS(ret));
|
||||
} else if (!WIFEXITED(ret)) {
|
||||
abortf("Error: command terminated abnormally\n");
|
||||
}
|
||||
}
|
||||
|
||||
void compile_shader_dir(SpanU8 name) {
|
||||
mkdir_nofail("shaders/spv");
|
||||
VecU8 spv_shader_dir_name = VecU8_fmt("shaders/spv/%s%c", name, 0);
|
||||
mkdir_nofail((CSTR)spv_shader_dir_name.buf);
|
||||
VecU8_drop(spv_shader_dir_name);
|
||||
VecU8 vert_cmd = VecU8_fmt("glslc -o shaders/spv/%s/vert.spv shaders/glsl/%s/%s.vert%c", name, name, name, 0);
|
||||
calling_system_func((CSTR)vert_cmd.buf);
|
||||
calling_system_func_nofail((CSTR)vert_cmd.buf);
|
||||
VecU8_drop(vert_cmd);
|
||||
VecU8 frag_cmd = VecU8_fmt("glslc -o shaders/spv/%s/frag.spv shaders/glsl/%s/%s.frag%c", name, name, name, 0);
|
||||
calling_system_func((CSTR)frag_cmd.buf);
|
||||
calling_system_func_nofail((CSTR)frag_cmd.buf);
|
||||
VecU8_drop(frag_cmd);
|
||||
}
|
||||
|
||||
|
||||
@ -6,6 +6,8 @@
|
||||
#include "../../../l1/system/pthread.h"
|
||||
#include "../../margaret/time_utils.h"
|
||||
|
||||
// todo: delete this file
|
||||
|
||||
#define DEFAULT_RATE 44100
|
||||
#define DEFAULT_CHANNELS 2
|
||||
#define DEFAULT_VOLUME 0.1
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user