Compare commits
No commits in common. "master" and "physics-app" have entirely different histories.
master
...
physics-ap
4
Makefile
4
Makefile
@ -69,8 +69,8 @@ gen/l_wl_protocols/xdg-shell-private.c: $(wl_protocols)/stable/xdg-shell/xdg-she
|
||||
mkdir -p gen/l_wl_protocols
|
||||
wayland-scanner private-code $< $@
|
||||
|
||||
.PHONY: gen_l_wl_protocols
|
||||
gen_l_wl_protocols : $(l_wl_protocols)
|
||||
.PHONY: gen/l_wl_protocols
|
||||
gen/l_wl_protocols : $(l_wl_protocols)
|
||||
|
||||
out/l2/codegen: src/l2/anne/codegen.c $(HEADERS_src_l2)
|
||||
mkdir -p out/l2
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
// todo: refactor (with VecU8_append_fmt)
|
||||
#include "../../codegen/util_template_inst.h"
|
||||
|
||||
typedef struct {
|
||||
@ -14,9 +14,7 @@ color_type_name_in_png color_types_names_in_png[] = {
|
||||
{4, cstr("PNG_COLOR_TYPE_RGBA")},
|
||||
};
|
||||
|
||||
void codegen_append_margaret_png_texture_data_methods(VecU8* res,
|
||||
SpanU8 format_signature, S64 depth, S64 channel_count
|
||||
){
|
||||
NODISCARD VecU8 generate_margaret_png_texture_data_methods(SpanU8 format_signature, S64 depth, S64 channel_count) {
|
||||
if (depth != 8)
|
||||
abortf("Please no\n");
|
||||
SpanU8 color_type = cstr("");
|
||||
@ -28,12 +26,15 @@ void codegen_append_margaret_png_texture_data_methods(VecU8* res,
|
||||
abortf("Please don't\n");
|
||||
|
||||
U64 sizeof_pixel = (U64)depth / 8 * (U64)channel_count;
|
||||
VecU8 res = VecU8_new();
|
||||
|
||||
VecU8 promise = VecU8_fmt("MargaretPromisedPng%s", format_signature);
|
||||
VecU8 tex = VecU8_fmt("TextureData%s", format_signature);
|
||||
VecU8 g_promise = VecU8_fmt("MargaretPromisedPng%s", format_signature);
|
||||
SpanU8 promise = VecU8_to_span(&g_promise);
|
||||
VecU8 g_tex = VecU8_fmt("TextureData%s", format_signature);
|
||||
SpanU8 tex = VecU8_to_span(&g_tex);
|
||||
|
||||
VecU8_append_fmt(res,
|
||||
"NODISCARD ResultVoidOrVecU8 %r_write_to_png(const %r* self, SpanU8 filename) {\n" /* tex, tex */
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"NODISCARD ResultVoidOrVecU8 %s_write_to_png(const %s* self, SpanU8 filename) {\n" /* tex, tex */
|
||||
SPACE "VecU8 nt_filename = VecU8_fmt(\"%%s%%c\", filename, 0);\n"
|
||||
SPACE "FILE *fp = fopen((CSTR)nt_filename.buf, \"wb\");\n"
|
||||
SPACE "VecU8_drop(nt_filename);\n"
|
||||
@ -61,7 +62,7 @@ void codegen_append_margaret_png_texture_data_methods(VecU8* res,
|
||||
SPACE SPACE "PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);\n"
|
||||
SPACE "row_pointers = calloc(height, sizeof(row_pointers));\n"
|
||||
SPACE "for (U32 y = 0; y < height; y++) {\n"
|
||||
SPACE SPACE "row_pointers[height - 1 - y] = (png_bytep)((%r_at(self, 0, y)));\n" /* tex */
|
||||
SPACE SPACE "row_pointers[height - 1 - y] = (png_bytep)((%s_at(self, 0, y)));\n" /* tex */
|
||||
SPACE "}\n"
|
||||
SPACE "png_set_rows(pngshka, info, row_pointers);\n"
|
||||
SPACE "png_write_png(pngshka, info, 0, NULL);\n"
|
||||
@ -72,38 +73,38 @@ void codegen_append_margaret_png_texture_data_methods(VecU8* res,
|
||||
SPACE "return (ResultVoidOrVecU8){.variant = Result_Ok};\n"
|
||||
"}\n\n"
|
||||
"/* Aborts on error */\n"
|
||||
"void %r_write_to_png_nofail(const %r* self, SpanU8 filename) {\n" /* tex, tex */
|
||||
SPACE "ResultVoidOrVecU8 res = %r_write_to_png(self, filename);\n" /* tex */
|
||||
"void %s_write_to_png_nofail(const %s* self, SpanU8 filename) {\n" /* tex, tex*/
|
||||
SPACE "ResultVoidOrVecU8 res = %s_write_to_png(self, filename);\n" /* tex */
|
||||
SPACE "if (res.variant == Result_Err) {\n"
|
||||
SPACE SPACE "SpanU8_fprint(VecU8_to_span(&res.err), stderr);\n"
|
||||
SPACE SPACE "abortf(\" %r_write_to_png\\n\");\n" /* tex */
|
||||
SPACE SPACE "abortf(\" %s_write_to_png\\n\");\n" /* tex */
|
||||
SPACE "}\n"
|
||||
"}\n",
|
||||
tex, tex, depth, color_type, tex, tex, tex, tex, tex);
|
||||
tex, tex, depth, color_type, tex, tex, tex, tex, tex));
|
||||
|
||||
/* Non clonable structure */
|
||||
VecU8_append_fmt(res,
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"typedef struct {\n"
|
||||
SPACE "FILE* fp;\n"
|
||||
SPACE "png_structp pngshka;\n"
|
||||
SPACE "png_infop info;\n"
|
||||
SPACE "png_infop end_info;\n"
|
||||
"} %r;\n\n"
|
||||
"void %r_drop(%r self) {\n"
|
||||
"} %s;\n\n"
|
||||
"void %s_drop(%s self) {\n"
|
||||
SPACE "png_destroy_read_struct(&self.pngshka, &self.info, &self.end_info);\n"
|
||||
SPACE "fclose(self.fp);\n"
|
||||
"}\n\n",
|
||||
promise, promise, promise);
|
||||
promise, promise, promise));
|
||||
|
||||
VecU8_append_vec(res, generate_result_template_inst(VecU8_to_span(&promise), cstr("VecU8"), false, false));
|
||||
VecU8_append_vec(&res, generate_result_template_inst(promise, cstr("VecU8"), false, false));
|
||||
|
||||
VecU8_append_fmt(res,
|
||||
"NODISCARD Result%rOrVecU8 %r_begin(SpanU8 filename) {\n" /* promise, promise */
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"NODISCARD Result%sOrVecU8 %s_begin(SpanU8 filename) {\n" /* promise, promise */
|
||||
SPACE "VecU8 nt_filename = VecU8_fmt(\"%%s%%c\", filename, 0);\n"
|
||||
SPACE "FILE* fp = fopen((CSTR)nt_filename.buf, \"rb\");\n"
|
||||
SPACE "VecU8_drop(nt_filename);\n"
|
||||
SPACE "if (!fp) {\n"
|
||||
SPACE SPACE "return (Result%rOrVecU8){.variant = Result_Err,\n" /* promise */
|
||||
SPACE SPACE "return (Result%sOrVecU8){.variant = Result_Err,\n" /* promise */
|
||||
SPACE SPACE SPACE ".err = VecU8_fmt(\"Unable to open file %%s\", filename)};\n"
|
||||
SPACE "}\n"
|
||||
SPACE "png_structp pngshka = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, margaret_libpng_h_error_cb, margaret_libpng_h_warning_cb);\n"
|
||||
@ -118,7 +119,7 @@ void codegen_append_margaret_png_texture_data_methods(VecU8* res,
|
||||
SPACE "if (setjmp(png_jmpbuf(pngshka))) {\n"
|
||||
SPACE SPACE "png_destroy_read_struct(&pngshka, &info, &end_info);\n"
|
||||
SPACE SPACE "fclose(fp);\n"
|
||||
SPACE SPACE "return (Result%rOrVecU8){.variant = Result_Err,\n" /* promise */
|
||||
SPACE SPACE "return (Result%sOrVecU8){.variant = Result_Err,\n" /* promise */
|
||||
SPACE SPACE SPACE ".err = VecU8_from_cstr(\"Some png error happened\")};\n"
|
||||
SPACE "}\n"
|
||||
SPACE "png_init_io(pngshka, fp);\n"
|
||||
@ -126,55 +127,55 @@ void codegen_append_margaret_png_texture_data_methods(VecU8* res,
|
||||
SPACE "U32 width, height;\n"
|
||||
SPACE "int bit_depth, color_type;\n"
|
||||
SPACE "check(png_get_IHDR(pngshka, info, &width, &height, &bit_depth, &color_type, NULL, NULL, NULL));\n",
|
||||
promise, promise, promise, promise);
|
||||
promise, promise, promise, promise));
|
||||
|
||||
/* We are still in PROMISE_begin method, now we need to do the conversion */
|
||||
if (depth == 8) {
|
||||
VecU8_append_cstr(res,
|
||||
VecU8_append_span(&res, cstr(
|
||||
SPACE "if (bit_depth == 16)\n"
|
||||
SPACE SPACE "png_set_strip_16(pngshka);\n"
|
||||
SPACE "else if (color_type == PNG_COLOR_TYPE_GRAY && (bit_depth == 1 || bit_depth == 2 || bit_depth == 4))\n"
|
||||
SPACE SPACE "png_set_expand_gray_1_2_4_to_8(pngshka);\n"
|
||||
);
|
||||
));
|
||||
} else
|
||||
assert(false);
|
||||
if (channel_count == 3 || channel_count == 4) {
|
||||
VecU8_append_cstr(res,
|
||||
VecU8_append_span(&res, cstr(
|
||||
SPACE "if (color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_GRAY_ALPHA)\n"
|
||||
SPACE SPACE "png_set_gray_to_rgb(pngshka);\n"
|
||||
SPACE "else if (color_type == PNG_COLOR_TYPE_PALETTE)"
|
||||
SPACE SPACE "png_set_palette_to_rgb(pngshka);\n"
|
||||
);
|
||||
));
|
||||
} else if (channel_count == 1 || channel_count == 2) {
|
||||
VecU8_append_cstr(res,
|
||||
VecU8_append_span(&res, cstr(
|
||||
SPACE "if (color_type == PNG_COLOR_TYPE_RGB || color_type == PNG_COLOR_TYPE_RGBA) {\n"
|
||||
SPACE SPACE "png_set_rgb_to_gray_fixed(pngshka, 1, 21268, 71514);\n"
|
||||
SPACE "} else if (color_type == PNG_COLOR_TYPE_PALETTE) {\n"
|
||||
SPACE SPACE "png_set_palette_to_rgb(pngshka);\n"
|
||||
SPACE SPACE "png_set_rgb_to_gray_fixed(pngshka, 1, 21268, 71514);\n"
|
||||
SPACE "}\n"
|
||||
);
|
||||
));
|
||||
} else
|
||||
assert(false);
|
||||
if (channel_count == 4 || channel_count == 2) {
|
||||
VecU8_append_cstr(res,
|
||||
VecU8_append_span(&res, cstr(
|
||||
SPACE "if (color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_RGB || color_type == PNG_COLOR_TYPE_PALETTE) {\n"
|
||||
SPACE SPACE "if (png_get_valid(pngshka, info, PNG_INFO_tRNS)) \n"
|
||||
SPACE SPACE SPACE "png_set_tRNS_to_alpha(pngshka);\n"
|
||||
SPACE SPACE "else\n"
|
||||
SPACE SPACE SPACE "png_set_add_alpha(pngshka, 0xFF, PNG_FILLER_AFTER);\n"
|
||||
SPACE "}\n"
|
||||
);
|
||||
));
|
||||
} else if (channel_count == 1 || channel_count == 3) {
|
||||
VecU8_append_cstr(res,
|
||||
VecU8_append_span(&res, cstr(
|
||||
SPACE "if (color_type == PNG_COLOR_TYPE_GRAY_ALPHA || color_type == PNG_COLOR_TYPE_RGBA)\n"
|
||||
SPACE SPACE "png_set_strip_alpha(pngshka);\n"
|
||||
);
|
||||
));
|
||||
} else
|
||||
assert(false);
|
||||
/* At this point we have a converted image png structure */
|
||||
|
||||
VecU8_append_fmt(res,
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
SPACE "png_read_update_info(pngshka, info);\n"
|
||||
SPACE "{\n"
|
||||
SPACE SPACE "U32 new_width, new_height;\n"
|
||||
@ -182,34 +183,34 @@ void codegen_append_margaret_png_texture_data_methods(VecU8* res,
|
||||
SPACE SPACE "check(png_get_IHDR(pngshka, info, &new_width, &new_height, &new_bit_depth, &new_color_type, NULL, NULL, NULL));\n"
|
||||
SPACE SPACE "assert(new_width == width && new_height == height && new_bit_depth == %i && new_color_type == %s);\n" /* depth, color_type */
|
||||
SPACE "}\n"
|
||||
SPACE "return (Result%rOrVecU8){.variant = Result_Ok,\n" /* promise */
|
||||
SPACE SPACE ".ok = (%r){.fp = fp, .pngshka = pngshka, .info = info, .end_info = end_info}};\n" /* promise */
|
||||
SPACE "return (Result%sOrVecU8){.variant = Result_Ok,\n" /* promise */
|
||||
SPACE SPACE ".ok = (%s){.fp = fp, .pngshka = pngshka, .info = info, .end_info = end_info}};\n" /* promise */
|
||||
"}\n\n",
|
||||
(S64)depth, color_type,
|
||||
promise, promise);
|
||||
promise, promise));
|
||||
|
||||
VecU8_append_fmt(res,
|
||||
"SizeOfRectangleU32 %r_get_extent(const %r* self) {\n" /* promise, promise */
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"SizeOfRectangleU32 %s_get_extent(const %s* self) {\n" /* promise, promise */
|
||||
SPACE "U32 width, height;\n"
|
||||
SPACE "int bit_depth, color_type;\n"
|
||||
SPACE "check(png_get_IHDR(self->pngshka, self->info, &width, &height, &bit_depth, &color_type, NULL, NULL, NULL));\n"
|
||||
SPACE "return (SizeOfRectangleU32){width, height};\n"
|
||||
"}\n\n",
|
||||
promise, promise);
|
||||
promise, promise));
|
||||
|
||||
assert(depth == 8 || depth == 16);
|
||||
assert(channel_count == 1 || channel_count == 2 || channel_count == 4 || channel_count == 3);
|
||||
|
||||
VecU8_append_fmt(res,
|
||||
"size_t %r_get_needed_buffer_size(const %r* self) {\n" /* promise, promise */
|
||||
SPACE "SizeOfRectangleU32 dim = %r_get_extent(self);\n" /* promise */
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"size_t %s_get_needed_buffer_size(const %s* self) {\n" /* promise, promise */
|
||||
SPACE "SizeOfRectangleU32 dim = %s_get_extent(self);\n" /* promise */
|
||||
SPACE "return %u * dim.width * dim.height;\n" /* sizeof_pixel */
|
||||
"}\n\n",
|
||||
promise, promise, promise, sizeof_pixel);
|
||||
promise, promise, promise, sizeof_pixel));
|
||||
|
||||
VecU8_append_fmt(res,
|
||||
"NODISCARD ResultVoidOrVecU8 %r_finish(%r self, void* buffer) {\n" /* promise, promise */
|
||||
SPACE "SizeOfRectangleU32 dim = %r_get_extent(&self);\n" /* promise */
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"NODISCARD ResultVoidOrVecU8 %s_finish(%s self, void* buffer) {\n" /* promise, promise */
|
||||
SPACE "SizeOfRectangleU32 dim = %s_get_extent(&self);\n" /* promise */
|
||||
SPACE "png_bytep* row_pointers = NULL;\n"
|
||||
SPACE "if (setjmp(png_jmpbuf(self.pngshka))) {\n"
|
||||
SPACE SPACE "png_destroy_read_struct(&self.pngshka, &self.info, &self.end_info);\n"
|
||||
@ -229,35 +230,37 @@ void codegen_append_margaret_png_texture_data_methods(VecU8* res,
|
||||
SPACE "free(row_pointers);\n"
|
||||
SPACE "return (ResultVoidOrVecU8){.variant = Result_Ok};\n"
|
||||
"}\n\n",
|
||||
promise, promise, promise, sizeof_pixel);
|
||||
promise, promise, promise, sizeof_pixel
|
||||
));
|
||||
|
||||
VecU8_append_fmt(res,
|
||||
"NODISCARD Result%rOrVecU8 %r_finish_into_%r(%r self) {\n" /* tex, promise, tex, promise */
|
||||
SPACE "SizeOfRectangleU32 dim = %r_get_extent(&self);\n" /* promise */
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"NODISCARD Result%sOrVecU8 %s_finish_into_%s(%s self) {\n" /* tex, promise, tex, promise */
|
||||
SPACE "SizeOfRectangleU32 dim = %s_get_extent(&self);\n" /* promise */
|
||||
SPACE "if (dim.width >= UINT32_MAX / 10 || dim.height >= UINT32_MAX / 10) {\n"
|
||||
SPACE SPACE "return (Result%rOrVecU8){.variant = Result_Err, .err = vcstr(\"Input image is too big\")};\n" /* tex */
|
||||
SPACE SPACE "return (Result%sOrVecU8){.variant = Result_Err, .err = vcstr(\"Input image is too big\")};\n" /* tex */
|
||||
SPACE "}\n"
|
||||
SPACE "%r tex = %r_new(dim.width, dim.height);\n" /* tex, tex */
|
||||
SPACE "ResultVoidOrVecU8 res = %r_finish(self, tex.pixels.buf);\n" /* promise */
|
||||
SPACE "%s tex = %s_new(dim.width, dim.height);\n" /* tex, tex */
|
||||
SPACE "ResultVoidOrVecU8 res = %s_finish(self, tex.pixels.buf);\n" /* promise */
|
||||
SPACE "if (res.variant == Result_Err) {\n"
|
||||
SPACE SPACE "%r_drop(tex);\n" /* tex */
|
||||
SPACE SPACE "return (Result%rOrVecU8){.variant = Result_Err, .err = res.err};\n" /* tex */
|
||||
SPACE SPACE "%s_drop(tex);\n" /* tex */
|
||||
SPACE SPACE "return (Result%sOrVecU8){.variant = Result_Err, .err = res.err};\n" /* tex */
|
||||
SPACE "}\n"
|
||||
SPACE "return (Result%rOrVecU8){.variant = Result_Ok, .ok = tex};\n" /* tex */
|
||||
SPACE "return (Result%sOrVecU8){.variant = Result_Ok, .ok = tex};\n" /* tex */
|
||||
"}\n\n",
|
||||
tex, promise, tex, promise, promise, tex, tex, tex, promise, tex, tex, tex
|
||||
);
|
||||
));
|
||||
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
|
||||
VecU8_append_fmt(res,
|
||||
"/* aborts on error */\n"
|
||||
"NODISCARD %r %r_read_from_png_nofail(SpanU8 name) {\n" /* tex, tex */
|
||||
SPACE "Result%rOrVecU8 res_1 = %r_begin(name);\n" /* promise, promise */
|
||||
"NODISCARD %s %s_read_from_png_nofail(SpanU8 name) {\n" /* tex, tex */
|
||||
SPACE "Result%sOrVecU8 res_1 = %s_begin(name);\n" /* promise, promise */
|
||||
SPACE "if (res_1.variant == Result_Err) {\n"
|
||||
SPACE SPACE "SpanU8_fprint(VecU8_to_span(&res_1.err), stderr);\n"
|
||||
SPACE SPACE "abortf(\" MargaretPromisedPng_begin\\n\");\n"
|
||||
SPACE "}\n"
|
||||
SPACE "/* res_1 invalidated, we moved ownership to _finish methos */\n"
|
||||
SPACE "Result%rOrVecU8 res_2 = %r_finish_into_%r(res_1.ok);\n" /* tex, promise, tex */
|
||||
SPACE "Result%sOrVecU8 res_2 = %s_finish_into_%s(res_1.ok);\n" /* tex, promise, tex */
|
||||
SPACE "if (res_2.variant == Result_Err) {\n"
|
||||
SPACE SPACE "SpanU8_fprint(VecU8_to_span(&res_2.err), stderr);\n"
|
||||
SPACE SPACE "abortf(\" MargaretPromisedPng_finish (into TextureData)\\n\");\n"
|
||||
@ -265,31 +268,32 @@ void codegen_append_margaret_png_texture_data_methods(VecU8* res,
|
||||
SPACE "return res_2.ok;\n"
|
||||
"}\n\n",
|
||||
tex, tex, promise, promise, tex, promise, tex
|
||||
);
|
||||
));
|
||||
|
||||
VecU8_drop(promise);
|
||||
VecU8_drop(tex);
|
||||
VecU8_drop(g_promise);
|
||||
VecU8_drop(g_tex);
|
||||
return res;
|
||||
}
|
||||
|
||||
void generate_margaret_png_pixel_masses_header() {
|
||||
GeneratedHeader header = begin_header(cstr("l1/margaret/png_pixel_masses.h"));
|
||||
|
||||
VecU8_append_cstr(&header.result,
|
||||
VecU8_append_span(&header.result, cstr(
|
||||
"#include \"../pixel_masses.h\"\n"
|
||||
"#include \"../ResultVoidOrVecU8.h\"\n"
|
||||
"#include <png.h>\n\n");
|
||||
"#include <png.h>\n\n"));
|
||||
|
||||
VecU8_append_cstr(&header.result,
|
||||
VecU8_append_span(&header.result, cstr(
|
||||
"void margaret_libpng_h_error_cb(png_structp pngshka, png_const_charp err) {\n"
|
||||
SPACE "printf(\"[!] %s\\n\", err);\n"
|
||||
"}\n\n"
|
||||
"void margaret_libpng_h_warning_cb(png_structp pngshka, png_const_charp warning) {\n"
|
||||
SPACE "printf(\"[.] %s\\n\", warning);\n"
|
||||
"}\n\n");
|
||||
"}\n\n"));
|
||||
|
||||
codegen_append_margaret_png_texture_data_methods(&header.result, cstr("R8"), 8, 1);
|
||||
codegen_append_margaret_png_texture_data_methods(&header.result, cstr("R8G8B8"), 8, 3);
|
||||
codegen_append_margaret_png_texture_data_methods(&header.result, cstr("R8G8B8A8"), 8, 4);
|
||||
VecU8_append_vec(&header.result, generate_margaret_png_texture_data_methods(cstr("R8"), 8, 1));
|
||||
VecU8_append_vec(&header.result, generate_margaret_png_texture_data_methods(cstr("R8G8B8"), 8, 3));
|
||||
VecU8_append_vec(&header.result, generate_margaret_png_texture_data_methods(cstr("R8G8B8A8"), 8, 4));
|
||||
|
||||
finish_header(header);
|
||||
}
|
||||
|
||||
@ -21,61 +21,61 @@ void codegen_append_buff_rbtree_map__structure_and_simplest_methods(
|
||||
VecU8_append_vec(res, VecU8_fmt("typedef struct %s %s;\n\n", set, set));
|
||||
}
|
||||
|
||||
VecU8_append_fmt(res,
|
||||
VecU8_append_vec(res, VecU8_fmt(
|
||||
"struct %s{\n"
|
||||
SPACE "VecBufRBTreeNode tree;\n"
|
||||
SPACE "U64 root;\n"
|
||||
SPACE "Vec%s el;\n"
|
||||
"%v"
|
||||
"};\n\n",
|
||||
set, TT, op.guest_data_T.len > 0 ? VecU8_fmt(SPACE "%s guest;\n", op.guest_data_T) : vcstr(""));
|
||||
set, TT, op.guest_data_T.len > 0 ? VecU8_fmt(SPACE "%s guest;\n", op.guest_data_T) : vcstr("")));
|
||||
|
||||
if (op.guest_data_T.len > 0) {
|
||||
VecU8_append_fmt(res,
|
||||
VecU8_append_vec(res, VecU8_fmt(
|
||||
"NODISCARD %s %s_new(%s guest) {\n" /* set, set, op.guest_data_T */
|
||||
SPACE "return (%s){.tree = VecBufRBTreeNode_new_zeroinit(1), .root = 0, .el = Vec%s_new(), .guest = guest};\n" /* set, TT */
|
||||
"}\n\n",
|
||||
set, set, op.guest_data_T,
|
||||
set, TT);
|
||||
VecU8_append_fmt(res,
|
||||
set, TT));
|
||||
VecU8_append_vec(res, VecU8_fmt(
|
||||
"NODISCARD %s %s_new_reserved(%s guest, size_t size) {\n" /* set, set, op.guest_data_T */
|
||||
SPACE "return (%s){.tree = (VecBufRBTreeNode){\n" /* set */
|
||||
SPACE SPACE ".buf = (BufRBTreeNode*)safe_calloc(size + 1, sizeof(BufRBTreeNode)), .len = 1, .capacity = size + 1},\n"
|
||||
SPACE SPACE ".root = 0, .el = Vec%s_new_reserved(size), .guest = guest};\n" /* TT */
|
||||
"}\n\n",
|
||||
set, set, op.guest_data_T,
|
||||
set, TT);
|
||||
set, TT));
|
||||
} else {
|
||||
VecU8_append_fmt(res,
|
||||
VecU8_append_vec(res, VecU8_fmt(
|
||||
"NODISCARD %s %s_new() {\n" /* set, set */
|
||||
SPACE "return (%s){.tree = VecBufRBTreeNode_new_zeroinit(1), .root = 0, .el = Vec%s_new()};\n" /* set, TT */
|
||||
"}\n\n",
|
||||
set, set,
|
||||
set, TT);
|
||||
VecU8_append_fmt(res,
|
||||
set, TT));
|
||||
VecU8_append_vec(res, VecU8_fmt(
|
||||
"NODISCARD %s %s_new_reserved(size_t size) {\n" /* set, set */
|
||||
SPACE "return (%s){.tree = (VecBufRBTreeNode){\n"
|
||||
SPACE SPACE ".buf = (BufRBTreeNode*)safe_calloc(size + 1, sizeof(BufRBTreeNode)), .len = 1, .capacity = size + 1},\n"
|
||||
SPACE SPACE ".root = 0, .el = Vec%s_new_reserved(size)};\n" /* set, TT */
|
||||
"}\n\n",
|
||||
set, set,
|
||||
set, TT);
|
||||
set, TT));
|
||||
}
|
||||
|
||||
VecU8_append_fmt(res,
|
||||
VecU8_append_vec(res, VecU8_fmt(
|
||||
"void %s_drop(%s self) {\n" /* set, set */
|
||||
SPACE "VecBufRBTreeNode_drop(self.tree);\n"
|
||||
SPACE "Vec%s_drop(self.el);\n" /* TT */
|
||||
"}\n\n", set, set, TT);
|
||||
"}\n\n", set, set, TT));
|
||||
|
||||
VecU8_append_fmt(res,
|
||||
VecU8_append_vec(res, VecU8_fmt(
|
||||
"void %s_sink(%s* self) {\n" /* set, set */
|
||||
SPACE "self->tree.len = 1;\n"
|
||||
SPACE "self->tree.buf[0] = (BufRBTreeNode){0};\n"
|
||||
SPACE "Vec%s_sink(&self->el, 0);\n" /* TT */
|
||||
"}\n\n", set, set, TT);
|
||||
"}\n\n", set, set, TT));
|
||||
|
||||
VecU8_append_fmt(res,
|
||||
VecU8_append_vec(res, VecU8_fmt(
|
||||
"U64 %s_find(const %s* self, %v key) {\n" /* set, set, taking_ref_k_argument */
|
||||
SPACE "U64 cur = self->root;\n"
|
||||
SPACE "while (cur != 0) {\n"
|
||||
@ -90,21 +90,21 @@ void codegen_append_buff_rbtree_map__structure_and_simplest_methods(
|
||||
"}\n\n",
|
||||
set, set, codegen_rbtree_map__taking_ref_k_argument(op),
|
||||
codegen_rbtree_map__less(op, vcstr("key"), codegen_buf_rbtree_map__exp_passing_cur_key(op)),
|
||||
codegen_rbtree_map__less(op, codegen_buf_rbtree_map__exp_passing_cur_key(op), vcstr("key")));
|
||||
codegen_rbtree_map__less(op, codegen_buf_rbtree_map__exp_passing_cur_key(op), vcstr("key"))));
|
||||
|
||||
if (op.k_clonable && op.v_clonable) {
|
||||
VecU8_append_fmt(res,
|
||||
VecU8_append_vec(res, VecU8_fmt(
|
||||
"NODISCARD %s %s_clone(const %s* self){\n" /* set, set, set */
|
||||
SPACE "return (%s){.tree = VecBufRBTreeNode_clone(&self->tree), .root = self->root,\n" /* set */
|
||||
SPACE SPACE ".el = Vec%s_clone(&self->el)%s};\n" /* TT, whether to clone guest or no */
|
||||
"}\n\n",
|
||||
set, set, set,
|
||||
set,
|
||||
TT, op.guest_data_T.len > 0 ? cstr(", .guest = self->guest") : cstr(""));
|
||||
TT, op.guest_data_T.len > 0 ? cstr(", .guest = self->guest") : cstr("")));
|
||||
}
|
||||
|
||||
// todo: move to common code (update: I no longer care)
|
||||
VecU8_append_fmt(res,
|
||||
// todo: move to common code
|
||||
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"
|
||||
@ -117,10 +117,10 @@ void codegen_append_buff_rbtree_map__structure_and_simplest_methods(
|
||||
SPACE SPACE SPACE "return p;\n"
|
||||
SPACE SPACE "x = p;\n"
|
||||
SPACE "}\n"
|
||||
"}\n\n", set, set);
|
||||
"}\n\n", set, set));
|
||||
|
||||
// todo: move to comon code (core/buff_rb_tree_node.h)
|
||||
VecU8_append_fmt(res,
|
||||
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"
|
||||
@ -133,19 +133,19 @@ void codegen_append_buff_rbtree_map__structure_and_simplest_methods(
|
||||
SPACE SPACE SPACE "return p;\n"
|
||||
SPACE SPACE "x = p;\n"
|
||||
SPACE "}\n"
|
||||
"}\n\n", set, set);
|
||||
"}\n\n", set, set));
|
||||
|
||||
VecU8_append_fmt(res,
|
||||
VecU8_append_vec(res, VecU8_fmt(
|
||||
"U64 %s_find_min(const %s* self) {\n"
|
||||
SPACE "return self->root != 0 ? BufRBTree_minimum_in_subtree(self->tree.buf, self->root) : 0;\n"
|
||||
"}\n\n", set, set);
|
||||
"}\n\n", set, set));
|
||||
|
||||
VecU8_append_fmt(res,
|
||||
VecU8_append_vec(res, VecU8_fmt(
|
||||
"U64 %s_find_max(const %s* self) {\n"
|
||||
SPACE "return self->root != 0 ? BufRBTree_maximum_in_subtree(self->tree.buf, self->root) : 0;\n"
|
||||
"}\n\n", set, set);
|
||||
"}\n\n", set, set));
|
||||
|
||||
VecU8_append_fmt(res,
|
||||
VecU8_append_vec(res, VecU8_fmt(
|
||||
"U64 %s_find_max_less(const %s* self, %v key) {\n" /* set, set, taking_ref_t_argument */
|
||||
SPACE "U64 last_less = 0;\n"
|
||||
SPACE "U64 cur = self->root;\n"
|
||||
@ -168,9 +168,9 @@ void codegen_append_buff_rbtree_map__structure_and_simplest_methods(
|
||||
"}\n\n",
|
||||
set, set, codegen_rbtree_map__taking_ref_k_argument(op),
|
||||
codegen_rbtree_map__less(op, vcstr("key"), codegen_buf_rbtree_map__exp_passing_cur_key(op)),
|
||||
codegen_rbtree_map__less(op, codegen_buf_rbtree_map__exp_passing_cur_key(op), vcstr("key")));
|
||||
codegen_rbtree_map__less(op, codegen_buf_rbtree_map__exp_passing_cur_key(op), vcstr("key"))));
|
||||
|
||||
VecU8_append_fmt(res,
|
||||
VecU8_append_vec(res, VecU8_fmt(
|
||||
"U64 %s_find_max_less_or_eq(const %s* self, %v key) {\n" /* set, set, taking_ref_t_argument */
|
||||
SPACE "U64 last_less = 0;\n"
|
||||
SPACE "U64 cur = self->root;\n"
|
||||
@ -188,10 +188,10 @@ void codegen_append_buff_rbtree_map__structure_and_simplest_methods(
|
||||
"}\n\n",
|
||||
set, set, codegen_rbtree_map__taking_ref_k_argument(op),
|
||||
codegen_rbtree_map__less(op, vcstr("key"), codegen_buf_rbtree_map__exp_passing_cur_key(op)),
|
||||
codegen_rbtree_map__less(op, codegen_buf_rbtree_map__exp_passing_cur_key(op), vcstr("key")));
|
||||
codegen_rbtree_map__less(op, codegen_buf_rbtree_map__exp_passing_cur_key(op), vcstr("key"))));
|
||||
|
||||
|
||||
VecU8_append_fmt(res,
|
||||
VecU8_append_vec(res, VecU8_fmt(
|
||||
"U64 %s_find_min_grtr(const %s* self, %v key) {\n" /* set, set, taking_ref_t_argument */
|
||||
SPACE "U64 last_grtr = 0;\n"
|
||||
SPACE "U64 cur = self->root;\n"
|
||||
@ -214,10 +214,10 @@ void codegen_append_buff_rbtree_map__structure_and_simplest_methods(
|
||||
"}\n\n",
|
||||
set, set, codegen_rbtree_map__taking_ref_k_argument(op),
|
||||
codegen_rbtree_map__less(op, vcstr("key"), codegen_buf_rbtree_map__exp_passing_cur_key(op)),
|
||||
codegen_rbtree_map__less(op, codegen_buf_rbtree_map__exp_passing_cur_key(op), vcstr("key")));
|
||||
codegen_rbtree_map__less(op, codegen_buf_rbtree_map__exp_passing_cur_key(op), vcstr("key"))));
|
||||
|
||||
|
||||
VecU8_append_fmt(res,
|
||||
VecU8_append_vec(res, VecU8_fmt(
|
||||
"U64 %s_find_min_grtr_or_eq(const %s* self, %v key) {\n" /* set, set, taking_ref_t_argument */
|
||||
SPACE "U64 last_grtr = 0;\n"
|
||||
SPACE "U64 cur = self->root;\n"
|
||||
@ -235,13 +235,13 @@ void codegen_append_buff_rbtree_map__structure_and_simplest_methods(
|
||||
"}\n\n",
|
||||
set, set, codegen_rbtree_map__taking_ref_k_argument(op),
|
||||
codegen_rbtree_map__less(op, vcstr("key"), codegen_buf_rbtree_map__exp_passing_cur_key(op)),
|
||||
codegen_rbtree_map__less(op, codegen_buf_rbtree_map__exp_passing_cur_key(op), vcstr("key")));
|
||||
codegen_rbtree_map__less(op, codegen_buf_rbtree_map__exp_passing_cur_key(op), vcstr("key"))));
|
||||
|
||||
VecU8 line_that_appends_new_el_to_el_vec = op.V.len > 0 ?
|
||||
VecU8_fmt("VecKVP%sTo%s_append(&self->el, (KVP%sTo%s){.key = key, .value = value});", op.K, op.V, op.K, op.V) :
|
||||
VecU8_fmt("Vec%s_append(&self->el, key);", op.K);
|
||||
|
||||
VecU8_append_fmt(res,
|
||||
VecU8_append_vec(res, VecU8_fmt(
|
||||
/* This method is unsafe. Arguments key, value will be taken if 0 is returned,
|
||||
* or left on their place if not-0 is returned */
|
||||
"/* UNSAFE */\n"
|
||||
@ -250,7 +250,7 @@ void codegen_append_buff_rbtree_map__structure_and_simplest_methods(
|
||||
SPACE SPACE "assert(self->tree.len == 1);\n"
|
||||
SPACE SPACE "VecBufRBTreeNode_append(&self->tree, (BufRBTreeNode){.color = RBTree_black});\n"
|
||||
SPACE SPACE "self->root = 1;\n"
|
||||
SPACE SPACE "%r\n" /* line_that_appends_new_el_to_el_vec */
|
||||
SPACE SPACE "%s\n" /* line_that_appends_new_el_to_el_vec */
|
||||
SPACE SPACE "return 0;\n"
|
||||
SPACE "}\n"
|
||||
SPACE "U64 cur = self->root;\n"
|
||||
@ -263,7 +263,7 @@ void codegen_append_buff_rbtree_map__structure_and_simplest_methods(
|
||||
SPACE SPACE SPACE SPACE "VecBufRBTreeNode_append(&self->tree, (BufRBTreeNode){.parent = cur, .color = RBTree_red});\n"
|
||||
SPACE SPACE SPACE SPACE "self->tree.buf[cur].left = n;\n"
|
||||
SPACE SPACE SPACE SPACE "BufRBTree_fix_after_insert(self->tree.buf, &self->root, n);\n"
|
||||
SPACE SPACE SPACE SPACE "%r\n" /* line_that_appends_new_el_to_el_vec */
|
||||
SPACE SPACE SPACE SPACE "%s\n" /* line_that_appends_new_el_to_el_vec */
|
||||
SPACE SPACE SPACE SPACE "return 0;\n"
|
||||
SPACE SPACE SPACE "}\n"
|
||||
SPACE SPACE "} else if (%v) {\n" /* el[cur] < key */
|
||||
@ -274,7 +274,7 @@ void codegen_append_buff_rbtree_map__structure_and_simplest_methods(
|
||||
SPACE SPACE SPACE SPACE "VecBufRBTreeNode_append(&self->tree, (BufRBTreeNode){.parent = cur, .color = RBTree_red});\n"
|
||||
SPACE SPACE SPACE SPACE "self->tree.buf[cur].right = n;\n"
|
||||
SPACE SPACE SPACE SPACE "BufRBTree_fix_after_insert(self->tree.buf, &self->root, n);\n"
|
||||
SPACE SPACE SPACE SPACE "%r\n" /* line_that_appends_new_el_to_el_vec */
|
||||
SPACE SPACE SPACE SPACE "%s\n" /* line_that_appends_new_el_to_el_vec */
|
||||
SPACE SPACE SPACE SPACE "return 0;\n"
|
||||
SPACE SPACE SPACE "}\n"
|
||||
SPACE SPACE "} else {\n"
|
||||
@ -283,11 +283,11 @@ void codegen_append_buff_rbtree_map__structure_and_simplest_methods(
|
||||
SPACE "}\n"
|
||||
"}\n\n",
|
||||
set, set, codegen_rbtree_map__taking_t_argument(op),
|
||||
line_that_appends_new_el_to_el_vec,
|
||||
VecU8_to_span(&line_that_appends_new_el_to_el_vec),
|
||||
codegen_rbtree_map__less(op, codegen_rbtree_map__exp_passing_key_val(op), codegen_buf_rbtree_map__exp_passing_cur_key(op)),
|
||||
line_that_appends_new_el_to_el_vec,
|
||||
VecU8_to_span(&line_that_appends_new_el_to_el_vec),
|
||||
codegen_rbtree_map__less(op, codegen_buf_rbtree_map__exp_passing_cur_key(op), codegen_rbtree_map__exp_passing_key_val(op)),
|
||||
line_that_appends_new_el_to_el_vec);
|
||||
VecU8_to_span(&line_that_appends_new_el_to_el_vec)));
|
||||
VecU8_drop(line_that_appends_new_el_to_el_vec);
|
||||
|
||||
// VecU8_append_vec(res, VecU8_fmt(
|
||||
@ -328,7 +328,7 @@ void codegen_append_buff_rbtree_map__structure_and_simplest_methods(
|
||||
// "}\n\n",
|
||||
// set, set));
|
||||
|
||||
VecU8_append_fmt(res,
|
||||
VecU8_append_vec(res, VecU8_fmt(
|
||||
"bool %s_insert(%s* self, %v) {\n" /* set, set, taking_t_argument */
|
||||
SPACE "U64 col = %s_try_insert(self, key" "%s" ");\n" /* set, "" /, value */
|
||||
SPACE "if (col == 0)\n"
|
||||
@ -339,12 +339,12 @@ void codegen_append_buff_rbtree_map__structure_and_simplest_methods(
|
||||
set, set, codegen_rbtree_map__taking_t_argument(op),
|
||||
set, op.V.len > 0 ? cstr(", value") : cstr(""),
|
||||
op.k_primitive ? vcstr("") : VecU8_fmt(SPACE "%s_drop(key);\n", op.K),
|
||||
op.v_primitive ? vcstr("") : VecU8_fmt(SPACE "%s_drop(value);\n", op.V));
|
||||
op.v_primitive ? vcstr("") : VecU8_fmt(SPACE "%s_drop(value);\n", op.V)));
|
||||
|
||||
// todo: write _erase_by_iter method
|
||||
|
||||
// todo: rewrite _erase using _erase_by_it
|
||||
VecU8_append_fmt(res,
|
||||
VecU8_append_vec(res, VecU8_fmt(
|
||||
"bool %s_erase(%s* self, %v key) {\n" /* set, set, taking_ref_k_argument */
|
||||
SPACE "U64 v = %s_find(self, key);\n" /* set */
|
||||
SPACE "if (v == 0)\n"
|
||||
@ -359,7 +359,7 @@ void codegen_append_buff_rbtree_map__structure_and_simplest_methods(
|
||||
set, set, codegen_rbtree_map__taking_ref_k_argument(op), set,
|
||||
op.k_primitive ? vcstr("") : VecU8_fmt(
|
||||
SPACE "%s_drop(self->el.buf[v - 1]%s);\n", op.K, op.V.len > 0 ? cstr(".key") : cstr("")),
|
||||
op.v_primitive ? vcstr("") : VecU8_fmt(SPACE "%s_drop(self->el.buf[v - 1].value);\n", op.V));
|
||||
op.v_primitive ? vcstr("") : VecU8_fmt(SPACE "%s_drop(self->el.buf[v - 1].value);\n", op.V)));
|
||||
}
|
||||
|
||||
NODISCARD VecU8 codegen_buf_rbtree_map__option_returned_ref_v(map_instantiation_op op, bool mut){
|
||||
@ -386,7 +386,7 @@ NODISCARD VecU8 codegen_buf_rbtree_map__none_ref_v(map_instantiation_op op, bool
|
||||
}
|
||||
|
||||
void codegen_append_buf_rbtree_map__method_at(VecU8* res, map_instantiation_op op, SpanU8 set, bool mut){
|
||||
VecU8_append_fmt(res,
|
||||
VecU8_append_vec(res, VecU8_fmt(
|
||||
"%v %s_%s(%s%s* self, %v key) {\n" /* option_returned_ref_t, set, mat/at, e/const, set, taking_ref_t_argument */
|
||||
SPACE "U64 cur = self->root;\n"
|
||||
SPACE "while (cur != 0) {\n"
|
||||
@ -406,7 +406,8 @@ void codegen_append_buf_rbtree_map__method_at(VecU8* res, map_instantiation_op o
|
||||
codegen_rbtree_map__less(op, vcstr("key"), codegen_buf_rbtree_map__exp_passing_cur_key(op)),
|
||||
codegen_rbtree_map__less(op, codegen_buf_rbtree_map__exp_passing_cur_key(op), vcstr("key")),
|
||||
codegen_buf_rbtree_map__some_ref_v(op, mut),
|
||||
codegen_buf_rbtree_map__none_ref_v(op, mut));
|
||||
codegen_buf_rbtree_map__none_ref_v(op, mut)
|
||||
));
|
||||
}
|
||||
|
||||
NODISCARD VecU8 get_name_of_buf_rbtree_set_structure(set_instantiation_op op){
|
||||
@ -421,7 +422,8 @@ NODISCARD VecU8 get_name_of_buf_rbtree_set_structure(set_instantiation_op op){
|
||||
NODISCARD VecU8 generate_buf_rbtree_Set_template_instantiation(set_instantiation_op op){
|
||||
set_instantiation_op_fix(&op);
|
||||
VecU8 res = VecU8_new();
|
||||
VecU8 set = get_name_of_buf_rbtree_set_structure(op);
|
||||
VecU8 g_set = get_name_of_buf_rbtree_set_structure(op);
|
||||
SpanU8 set = VecU8_to_span(&g_set);
|
||||
|
||||
map_instantiation_op map_op = {.K = op.T,
|
||||
.k_integer = op.t_integer, .k_primitive = op.t_primitive, .k_clonable = op.t_clonable,
|
||||
@ -430,16 +432,16 @@ NODISCARD VecU8 generate_buf_rbtree_Set_template_instantiation(set_instantiation
|
||||
.alternative_comp_map_name_embed = op.alternative_comp_set_name_embed, .guest_data_T = op.guest_data_T,
|
||||
};
|
||||
|
||||
codegen_append_buff_rbtree_map__structure_and_simplest_methods(&res, map_op, VecU8_to_span(&set), op.T);
|
||||
codegen_append_buff_rbtree_map__structure_and_simplest_methods(&res, map_op, set, op.T);
|
||||
|
||||
VecU8_append_fmt(&res,
|
||||
"const %s* %r_at_iter(const %r* self, U64 it) {\n" /* op.T, set, set */
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"const %s* %s_at_iter(const %s* self, U64 it) {\n" /* op.T, set, set */
|
||||
SPACE "assert(0 < it && it < self->tree.len);\n"
|
||||
SPACE "return &self->el.buf[it - 1];\n"
|
||||
"}\n\n",
|
||||
op.T, set, set);
|
||||
op.T, set, set));
|
||||
|
||||
VecU8_drop(set);
|
||||
VecU8_drop(g_set);
|
||||
return res;
|
||||
}
|
||||
|
||||
@ -462,7 +464,7 @@ void generate_buf_rbtree_Set_templ_inst_guarded_header(
|
||||
|
||||
void codegen_append_buff_rbtree_map__method_at_iter(VecU8* res, map_instantiation_op op, SpanU8 set, bool mut){
|
||||
assert(op.V.len > 0);
|
||||
VecU8_append_fmt(res,
|
||||
VecU8_append_vec(res, VecU8_fmt(
|
||||
"void %s_%s(%s%s* self, U64 it, %v* ret_key, %v* ret_value) {\n" /* set, method name, self access modifier, set, key ret ptr, value ret ptr */
|
||||
SPACE "assert(0 < it && it < self->tree.len);\n"
|
||||
SPACE "*ret_key = %s" "self->el.buf[it - 1].key;\n" /* epsilon / ampersand */
|
||||
@ -472,7 +474,7 @@ void codegen_append_buff_rbtree_map__method_at_iter(VecU8* res, map_instantiatio
|
||||
op.k_integer ? VecU8_from_span(op.K) : VecU8_fmt("const %s*", op.K),
|
||||
mut ? VecU8_fmt("%s*", op.V) : (op.v_integer ? VecU8_from_span(op.V) : VecU8_fmt("const %s*", op.V)),
|
||||
|
||||
op.k_integer ? cstr("") : cstr("&"), (op.v_integer && !mut) ? cstr("") : cstr("&"));
|
||||
op.k_integer ? cstr("") : cstr("&"), (op.v_integer && !mut) ? cstr("") : cstr("&")));
|
||||
}
|
||||
|
||||
NODISCARD VecU8 get_name_of_buf_rbtree_map_structure(map_instantiation_op op){
|
||||
@ -543,7 +545,6 @@ NODISCARD VecU8 generate_buf_rbtree_Map_template_instantiation(map_instantiation
|
||||
codegen_append_buff_rbtree_map__method_at_iter(&res, op, map, false);
|
||||
codegen_append_buff_rbtree_map__method_at_iter(&res, op, map, true);
|
||||
|
||||
VecU8_drop(map_g);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
@ -2,80 +2,84 @@
|
||||
// todo: refactor (with VecU8_append_fmt)
|
||||
#include "all_set_map_templ_util_inst.h"
|
||||
|
||||
NODISCARD VecU8 generate_rbtree__node_struct_name(map_instantiation_op op){
|
||||
NODISCARD VecU8 codegen_rbtree__node_struct_name(map_instantiation_op op){
|
||||
return (op.V.len > 0) ? VecU8_fmt("RBTreeNode_KVP%sTo%s", op.K, op.V) : VecU8_fmt("RBTreeNode_%s", op.K);
|
||||
}
|
||||
|
||||
void codegen_append_rbtree__node_structure(VecU8* res, map_instantiation_op op){
|
||||
NODISCARD VecU8 codegen_rbtree__node_structure(map_instantiation_op op){
|
||||
map_instantiation_op_fix(&op);
|
||||
VecU8_append_fmt(res,
|
||||
VecU8 node_g = codegen_rbtree__node_struct_name(op);
|
||||
SpanU8 node = VecU8_to_span(&node_g);
|
||||
VecU8 res = VecU8_fmt(
|
||||
"typedef struct {\n"
|
||||
SPACE "RBTreeNode base;\n"
|
||||
SPACE "%s key;\n" /* op.K*/
|
||||
"%v" /* "" / op.V value; */
|
||||
"} %v;\n\n", /* node */
|
||||
"} %s;\n\n", /* node */
|
||||
op.K, op.V.len > 0 ? VecU8_fmt(SPACE "%s value;\n", op.V) : vcstr(""),
|
||||
generate_rbtree__node_struct_name(op));
|
||||
node);
|
||||
VecU8_drop(node_g);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
NODISCARD VecU8 codegen_rbtree_map__exp_passing_cur_key(map_instantiation_op op){
|
||||
return VecU8_fmt("%s" "((%v*)cur)->key", op.k_integer ? cstr("") : cstr("&"), generate_rbtree__node_struct_name(op));
|
||||
return VecU8_fmt("%s" "((%v*)cur)->key", op.k_integer ? cstr("") : cstr("&"), codegen_rbtree__node_struct_name(op));
|
||||
}
|
||||
|
||||
void codegen_append_rbtree_map__structure(VecU8* res, map_instantiation_op op, SpanU8 set){
|
||||
if (!op.skip_declaration_gen) {
|
||||
VecU8_append_fmt(res, "typedef struct %s %s;\n\n", set, set);
|
||||
VecU8_append_vec(res, VecU8_fmt("typedef struct %s %s;\n\n", set, set));
|
||||
}
|
||||
|
||||
VecU8_append_fmt(res,
|
||||
VecU8_append_vec(res, VecU8_fmt(
|
||||
"struct %s {\n"
|
||||
SPACE "RBTreeNode* root;\n"
|
||||
SPACE "RBTreeNode* NIL;\n"
|
||||
"%v" /* "" / guest field */
|
||||
"};\n\n",
|
||||
set,
|
||||
op.guest_data_T.len == 0 ? vcstr("") : VecU8_fmt("%s guest;\n", op.guest_data_T));
|
||||
op.guest_data_T.len == 0 ? vcstr("") : VecU8_fmt("%s guest;\n", op.guest_data_T)));
|
||||
}
|
||||
|
||||
void codegen_append_rbtree_map__simplest_methods(VecU8* res, map_instantiation_op op, SpanU8 set, SpanU8 TT){
|
||||
VecU8_append_fmt(res,
|
||||
VecU8_append_vec(res, VecU8_fmt(
|
||||
"NODISCARD %s %s_new(" "%v" ") {\n" /* set, set, "" / GT guest */
|
||||
/* Only color field initialization is important (should be 0) */
|
||||
SPACE "RBTreeNode* NIL = (RBTreeNode*)safe_calloc(1, sizeof(RBTreeNode));\n"
|
||||
SPACE "return (%s){.root = NIL, .NIL = NIL" "%s" "};\n" /* set, "" / , .guest = guest */
|
||||
"}\n\n",
|
||||
set, set, op.guest_data_T.len == 0 ? vcstr("") : VecU8_fmt("%s guest", op.guest_data_T),
|
||||
set, op.guest_data_T.len == 0 ? cstr("") : cstr(", .guest = guest"));
|
||||
set, op.guest_data_T.len == 0 ? cstr("") : cstr(", .guest = guest")));
|
||||
|
||||
// todo: figure out mutability restrictions crrp later (update: it is finally time to do that. But I can't bother)
|
||||
VecU8_append_fmt(res,
|
||||
// todo: figure out mutability restrictions crrp later
|
||||
VecU8_append_vec(res, VecU8_fmt(
|
||||
"RBTreeNode_%s* %s_find_min(const %s* self) {\n" /* TT, set, set */
|
||||
SPACE "if (self->root == self->NIL)\n"
|
||||
SPACE SPACE "return NULL;\n"
|
||||
SPACE "return (RBTreeNode_%s*)RBTreeNode_minimum_in_subtree(self->root, self->NIL);\n" /* TT */
|
||||
"}\n\n", TT, set, set, TT);
|
||||
"}\n\n", TT, set, set, TT));
|
||||
|
||||
VecU8_append_fmt(res,
|
||||
VecU8_append_vec(res, VecU8_fmt(
|
||||
"RBTreeNode_%s* %s_find_max(const %s* self) {\n" /* TT, set, set */
|
||||
SPACE "if (self->root == self->NIL)\n"
|
||||
SPACE SPACE "return NULL;\n"
|
||||
SPACE "return (RBTreeNode_%s*)RBTreeNode_maximum_in_subtree(self->root, self->NIL);\n" /* TT */
|
||||
"}\n\n", TT, set, set, TT);
|
||||
"}\n\n", TT, set, set, TT));
|
||||
|
||||
VecU8_append_fmt(res,
|
||||
VecU8_append_vec(res, VecU8_fmt(
|
||||
"RBTreeNode_%s* %s_find_next(const %s* self, RBTreeNode_%s* x){\n" /* TT, set, set, TT */
|
||||
SPACE "return (RBTreeNode_%s *)RBTreeNode_find_next((RBTreeNode*)x, self->NIL);\n" /* TT */
|
||||
"}\n\n", TT, set, set, TT, TT);
|
||||
"}\n\n", TT, set, set, TT, TT));
|
||||
|
||||
VecU8_append_fmt(res,
|
||||
VecU8_append_vec(res, VecU8_fmt(
|
||||
"RBTreeNode_%s* %s_find_prev(const %s* self, RBTreeNode_%s* x){\n" /* TT, set, set, TT */
|
||||
SPACE "return (RBTreeNode_%s *)RBTreeNode_find_prev((RBTreeNode*)x, self->NIL);\n" /* TT */
|
||||
"}\n\n", TT, set, set, TT, TT);
|
||||
"}\n\n", TT, set, set, TT, TT));
|
||||
|
||||
/* Here we read and write something to ->left, ->right field of NIL sentinel node.
|
||||
* These fields are correct pointers (NULL), so everything is ok */
|
||||
VecU8_append_fmt(res,
|
||||
VecU8_append_vec(res, VecU8_fmt(
|
||||
"void %s_drop(%s self){\n" /* set, set */
|
||||
SPACE "RBTreeNode* cur = self.root;\n"
|
||||
SPACE "while (cur != self.NIL){\n"
|
||||
@ -99,9 +103,10 @@ void codegen_append_rbtree_map__simplest_methods(VecU8* res, map_instantiation_o
|
||||
SPACE "free(self.NIL);\n"
|
||||
"}\n\n", set, set,
|
||||
op.k_primitive ? vcstr("") : VecU8_fmt(SPACE SPACE SPACE "%s_drop(((RBTreeNode_%s*)cur)->key);\n", op.K, TT),
|
||||
op.v_primitive ? vcstr("") : VecU8_fmt(SPACE SPACE SPACE "%s_drop(((RBTreeNode_%s*)cur)->value);\n", op.V, TT));
|
||||
op.v_primitive ? vcstr("") : VecU8_fmt(SPACE SPACE SPACE "%s_drop(((RBTreeNode_%s*)cur)->value);\n", op.V, TT)
|
||||
));
|
||||
|
||||
VecU8_append_fmt(res,
|
||||
VecU8_append_vec(res, VecU8_fmt(
|
||||
"RBTreeNode_%s* %s_find(const %s* self, %v key) {\n" /* TT, set, set, taking_ref_k_argument */
|
||||
SPACE "RBTreeNode* cur = self->root;\n"
|
||||
SPACE "while (cur != self->NIL) {\n"
|
||||
@ -118,9 +123,9 @@ void codegen_append_rbtree_map__simplest_methods(VecU8* res, map_instantiation_o
|
||||
TT, set, set, codegen_rbtree_map__taking_ref_k_argument(op),
|
||||
codegen_rbtree_map__less(op, vcstr("key"), codegen_rbtree_map__exp_passing_cur_key(op)),
|
||||
codegen_rbtree_map__less(op, codegen_rbtree_map__exp_passing_cur_key(op), vcstr("key")),
|
||||
TT);
|
||||
TT));
|
||||
|
||||
VecU8_append_fmt(res,
|
||||
VecU8_append_vec(res, VecU8_fmt(
|
||||
"RBTreeNode_%s* %s_find_max_less(const %s* self, %v key) {\n" /* TT, set, set, taking_ref_t_argument */
|
||||
SPACE "RBTreeNode_%s* last_less = NULL;\n" /* TT */
|
||||
SPACE "RBTreeNode* cur = self->root;\n"
|
||||
@ -144,9 +149,9 @@ void codegen_append_rbtree_map__simplest_methods(VecU8* res, map_instantiation_o
|
||||
TT, set, set, codegen_rbtree_map__taking_ref_k_argument(op), TT,
|
||||
codegen_rbtree_map__less(op, vcstr("key"), codegen_rbtree_map__exp_passing_cur_key(op)),
|
||||
codegen_rbtree_map__less(op, codegen_rbtree_map__exp_passing_cur_key(op), vcstr("key")),
|
||||
TT, TT);
|
||||
TT, TT));
|
||||
|
||||
VecU8_append_fmt(res,
|
||||
VecU8_append_vec(res, VecU8_fmt(
|
||||
"RBTreeNode_%s* %s_find_max_less_or_eq(const %s* self, %v key) {\n" /* TT, set, set, taking_ref_t_argument */
|
||||
SPACE "RBTreeNode_%s* last_less = NULL;\n" /* TT */
|
||||
SPACE "RBTreeNode* cur = self->root;\n"
|
||||
@ -165,9 +170,9 @@ void codegen_append_rbtree_map__simplest_methods(VecU8* res, map_instantiation_o
|
||||
TT, set, set, codegen_rbtree_map__taking_ref_k_argument(op), TT,
|
||||
codegen_rbtree_map__less(op, vcstr("key"), codegen_rbtree_map__exp_passing_cur_key(op)),
|
||||
codegen_rbtree_map__less(op, codegen_rbtree_map__exp_passing_cur_key(op), vcstr("key")),
|
||||
TT, TT);
|
||||
TT, TT));
|
||||
|
||||
VecU8_append_fmt(res,
|
||||
VecU8_append_vec(res, VecU8_fmt(
|
||||
"RBTreeNode_%s* %s_find_min_grtr(const %s* self, %v key) {\n" /* TT, set, set, taking_ref_t_argument */
|
||||
SPACE "RBTreeNode_%s* last_grtr = NULL;\n" /* TT */
|
||||
SPACE "RBTreeNode* cur = self->root;\n"
|
||||
@ -192,10 +197,10 @@ void codegen_append_rbtree_map__simplest_methods(VecU8* res, map_instantiation_o
|
||||
codegen_rbtree_map__less(op, vcstr("key"), codegen_rbtree_map__exp_passing_cur_key(op)),
|
||||
TT,
|
||||
codegen_rbtree_map__less(op, codegen_rbtree_map__exp_passing_cur_key(op), vcstr("key")),
|
||||
TT);
|
||||
TT));
|
||||
|
||||
|
||||
VecU8_append_fmt(res,
|
||||
VecU8_append_vec(res, VecU8_fmt(
|
||||
"RBTreeNode_%s* %s_find_min_grtr_or_eq(const %s* self, %v key) {\n" /* TT, set, set, taking_ref_t_argument */
|
||||
SPACE "RBTreeNode_%s* last_grtr = NULL;\n" /* TT */
|
||||
SPACE "RBTreeNode* cur = self->root;\n"
|
||||
@ -215,10 +220,10 @@ void codegen_append_rbtree_map__simplest_methods(VecU8* res, map_instantiation_o
|
||||
codegen_rbtree_map__less(op, vcstr("key"), codegen_rbtree_map__exp_passing_cur_key(op)),
|
||||
TT,
|
||||
codegen_rbtree_map__less(op, codegen_rbtree_map__exp_passing_cur_key(op), vcstr("key")),
|
||||
TT);
|
||||
TT));
|
||||
|
||||
// todo: implement it like i deed in BufRBTree
|
||||
VecU8_append_fmt(res,
|
||||
VecU8_append_vec(res, VecU8_fmt(
|
||||
/* This method is unsafe. Arguments key, value will be taken if 0 is returned,
|
||||
* or left on their place if not-0 is returned */
|
||||
"/* UNSAFE */\n"
|
||||
@ -251,9 +256,9 @@ void codegen_append_rbtree_map__simplest_methods(VecU8* res, map_instantiation_o
|
||||
codegen_rbtree_map__less(op, codegen_rbtree_map__exp_passing_cur_key(op), codegen_rbtree_map__exp_passing_key_val(op)),
|
||||
TT,
|
||||
TT, TT, TT,
|
||||
TT, op.V.len == 0 ? cstr("") : cstr(", .value = value"));
|
||||
TT, op.V.len == 0 ? cstr("") : cstr(", .value = value")));
|
||||
|
||||
VecU8_append_fmt(res,
|
||||
VecU8_append_vec(res, VecU8_fmt(
|
||||
"bool %s_insert(%s* self, %v){\n" /* set, set, taking_t_argument */
|
||||
SPACE "RBTreeNode_%s* col = %s_try_insert(self, key" "%s" ");\n" /* TT, set, "" /, value */
|
||||
SPACE "if (col == NULL)\n"
|
||||
@ -264,9 +269,9 @@ void codegen_append_rbtree_map__simplest_methods(VecU8* res, map_instantiation_o
|
||||
set, set, codegen_rbtree_map__taking_t_argument(op),
|
||||
TT, set, op.V.len > 0 ? cstr(", value") : cstr(""),
|
||||
op.k_primitive ? vcstr("") : VecU8_fmt(SPACE "%s_drop(key);\n", op.K),
|
||||
op.v_primitive ? vcstr("") : VecU8_fmt(SPACE "%s_drop(value);\n", op.V));
|
||||
op.v_primitive ? vcstr("") : VecU8_fmt(SPACE "%s_drop(value);\n", op.V)));
|
||||
|
||||
VecU8_append_fmt(res,
|
||||
VecU8_append_vec(res, VecU8_fmt(
|
||||
"void %s_erase_by_iter(%s* self, RBTreeNode_%s* it) {\n" /* set, set, TT */
|
||||
SPACE "assert(it != NULL);\n"
|
||||
"%v" /* "" / op.K_drop(it->key) */
|
||||
@ -276,9 +281,9 @@ void codegen_append_rbtree_map__simplest_methods(VecU8* res, map_instantiation_o
|
||||
"}\n\n",
|
||||
set, set, TT,
|
||||
op.k_primitive ? vcstr("") : VecU8_fmt(SPACE "%s_drop(it->key);\n", op.K),
|
||||
op.v_primitive ? vcstr("") : VecU8_fmt(SPACE "%s_drop(it->value);\n", op.V));
|
||||
op.v_primitive ? vcstr("") : VecU8_fmt(SPACE "%s_drop(it->value);\n", op.V)));
|
||||
|
||||
VecU8_append_fmt(res,
|
||||
VecU8_append_vec(res, VecU8_fmt(
|
||||
"bool %s_erase(%s* self, %v key) {\n" /* set, set, taking_ref_k_argument */
|
||||
SPACE "RBTreeNode_%s* v = %s_find(self, key);\n" /* TT, set */
|
||||
SPACE "if (v == NULL)\n"
|
||||
@ -287,13 +292,13 @@ void codegen_append_rbtree_map__simplest_methods(VecU8* res, map_instantiation_o
|
||||
SPACE "return true;\n"
|
||||
"}\n\n",
|
||||
set, set, codegen_rbtree_map__taking_ref_k_argument(op),
|
||||
TT, set, set);
|
||||
TT, set, set));
|
||||
|
||||
VecU8_append_fmt(res,
|
||||
VecU8_append_vec(res, VecU8_fmt(
|
||||
"bool %s_empty(const %s* self){\n" /* set, set */
|
||||
SPACE "return self->root == self->NIL;\n"
|
||||
"}\n\n",
|
||||
set, set);
|
||||
set, set));
|
||||
}
|
||||
|
||||
|
||||
@ -315,7 +320,7 @@ NODISCARD VecU8 generate_rbtree_Set_template_instantiation(set_instantiation_op
|
||||
VecU8 res = VecU8_new();
|
||||
VecU8 set_g = get_name_of_rbtree_set_structure(op);
|
||||
if (generate_node_struct)
|
||||
codegen_append_rbtree__node_structure(&res, map_op);
|
||||
VecU8_append_vec(&res, codegen_rbtree__node_structure(map_op));
|
||||
codegen_append_rbtree_map__structure(&res, map_op, VecU8_to_span(&set_g));
|
||||
codegen_append_rbtree_map__simplest_methods(&res, map_op, VecU8_to_span(&set_g), op.T);
|
||||
VecU8_drop(set_g);
|
||||
@ -350,21 +355,23 @@ NODISCARD VecU8 generate_rbtree_Map_template_instantiation(map_instantiation_op
|
||||
map_instantiation_op_fix(&op);
|
||||
|
||||
VecU8 res = VecU8_new();
|
||||
VecU8 map = get_name_of_rbtree_map_structure(op);
|
||||
VecU8 kvp = VecU8_fmt("KVP%sTo%s", op.K, op.V);
|
||||
VecU8 map_g = get_name_of_rbtree_map_structure(op);
|
||||
SpanU8 map = VecU8_to_span(&map_g);
|
||||
VecU8 kvp_g = VecU8_fmt("KVP%sTo%s", op.K, op.V);
|
||||
SpanU8 kvp = VecU8_to_span(&kvp_g);
|
||||
|
||||
if (generate_node_struct)
|
||||
codegen_append_rbtree__node_structure(&res, op);
|
||||
VecU8_append_vec(&res, codegen_rbtree__node_structure(op));
|
||||
if (generate_map_struct)
|
||||
codegen_append_rbtree_map__structure(&res, op, VecU8_to_span(&map));
|
||||
codegen_append_rbtree_map__structure(&res, op, map);
|
||||
if (generate_methods) {
|
||||
codegen_append_rbtree_map__simplest_methods(&res, op, VecU8_to_span(&map), VecU8_to_span(&kvp));
|
||||
codegen_append_rbtree_map__simplest_methods(&res, op, map, kvp);
|
||||
|
||||
if (op.pop_substitute) {
|
||||
VecU8_append_fmt(&res,
|
||||
"%s" "Option%s %r_pop_substitute(%r* self, %s key, %s value) {\n" /* "" / NODISCARD , op.V, map, map, op.K, op.V */
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"%s" "Option%s %s_pop_substitute(%s* self, %s key, %s value) {\n" /* "" / NODISCARD , op.V, map, map, op.K, op.V */
|
||||
/* Using unsafe method with conditional ownership transfer */
|
||||
SPACE "RBTreeNode_%r* col = %r_try_insert(self, key, value);\n" /* kvp, map */
|
||||
SPACE "RBTreeNode_%s* col = %s_try_insert(self, key, value);\n" /* kvp, map */
|
||||
SPACE "if (col == NULL) {\n"
|
||||
SPACE SPACE "return None_%s();\n" /* op.V */
|
||||
SPACE "} else {\n"
|
||||
@ -378,12 +385,12 @@ NODISCARD VecU8 generate_rbtree_Map_template_instantiation(map_instantiation_op
|
||||
op.v_primitive ? cstr("") : cstr("NODISCARD "), op.V, map, map, op.K, op.V,
|
||||
kvp, map, op.V,
|
||||
op.k_primitive ? vcstr("") : VecU8_fmt(SPACE SPACE"%s_drop(col->key);\n", op.K),
|
||||
op.V, op.V);
|
||||
op.V, op.V));
|
||||
}
|
||||
if (!op.v_primitive) {
|
||||
VecU8_append_fmt(&res,
|
||||
"bool %r_erase_substitute(%r* self, %s key, %s value) {\n" /* map, map, op.K, op.V */
|
||||
SPACE "RBTreeNode_%r* col = %r_try_insert(self, key, value);\n" /* kvp, map */
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"bool %s_erase_substitute(%s* self, %s key, %s value) {\n" /* map, map, op.K, op.V */
|
||||
SPACE "RBTreeNode_%s* col = %s_try_insert(self, key, value);\n" /* kvp, map */
|
||||
SPACE "if (col == NULL)\n"
|
||||
SPACE SPACE "return true;\n"
|
||||
"%v" "%v" /* "" / op.K_drop(col->key), "" / op.V_drop(col->value) */
|
||||
@ -393,16 +400,16 @@ NODISCARD VecU8 generate_rbtree_Map_template_instantiation(map_instantiation_op
|
||||
"}\n\n",
|
||||
map, map, op.K, op.V, kvp, map,
|
||||
op.k_primitive ? vcstr("") : VecU8_fmt(SPACE "%s_drop(col->key);\n", op.K),
|
||||
op.v_primitive ? vcstr("") : VecU8_fmt(SPACE "%s_drop(col->value);\n", op.V));
|
||||
op.v_primitive ? vcstr("") : VecU8_fmt(SPACE "%s_drop(col->value);\n", op.V)));
|
||||
}
|
||||
|
||||
if (op.pop){
|
||||
// todo: write _pop_by_it
|
||||
|
||||
// todo: rewrite pop using _pop_by_it
|
||||
VecU8_append_fmt(&res,
|
||||
"Option%s %r_pop(%r* self, %v key) {\n" /* op.V, map, map, taking_ref_k_argument */
|
||||
SPACE "RBTreeNode_%r* v = %r_find(self, key);\n" /* kvp, map */
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"Option%s %s_pop(%s* self, %v key) {\n" /* op.V, map, map, taking_ref_k_argument */
|
||||
SPACE "RBTreeNode_%s* v = %s_find(self, key);\n" /* kvp, map */
|
||||
SPACE "if (v == NULL)\n"
|
||||
SPACE SPACE "return None_%s();\n" /* op.V */
|
||||
"%v" /* "" / op.K_drop(v->key) */
|
||||
@ -414,18 +421,15 @@ NODISCARD VecU8 generate_rbtree_Map_template_instantiation(map_instantiation_op
|
||||
op.V, map, map, codegen_rbtree_map__taking_ref_k_argument(op),
|
||||
kvp, map, op.V,
|
||||
op.k_primitive ? vcstr("") : VecU8_fmt(SPACE "%s_drop(v->key);\n", op.K),
|
||||
op.V, op.V);
|
||||
op.V, op.V));
|
||||
}
|
||||
// todo: write generator for methods _at and _mat
|
||||
}
|
||||
VecU8_drop(map);
|
||||
VecU8_drop(kvp);
|
||||
return res;
|
||||
}
|
||||
|
||||
void generate_rbtree_Map_templ_inst_eve_header(SpanU8 layer, SpanU8 bonus_ns, map_instantiation_op op,
|
||||
bool generate_node_struct, bool separate_struct_and_methods
|
||||
) {
|
||||
bool generate_node_struct, bool separate_struct_and_methods) {
|
||||
if (separate_struct_and_methods) {
|
||||
assert(!generate_node_struct);
|
||||
VecU8 name_for_struct = VecU8_fmt("%v_struct", get_name_of_rbtree_map_structure(op));
|
||||
|
||||
@ -27,30 +27,31 @@ typedef struct {
|
||||
SpanU8 base_struct_name;
|
||||
} NamedTraitDefRecordRef;
|
||||
|
||||
void codegen_append_trait_table_structure(VecU8* res, NamedTraitDefRecordRef trait){
|
||||
VecU8_append_cstr(res, "typedef struct {\n");
|
||||
NODISCARD VecU8 generate_trait_table_structure(NamedTraitDefRecordRef trait){
|
||||
VecU8 res = VecU8_from_cstr("typedef struct {\n");
|
||||
for (size_t i = 0; i < trait.methods.len; i++) {
|
||||
NamedMethodSignatureRecordRef method = *SpanNamedMethodSignatureRecordRef_at(trait.methods, i);
|
||||
VecU8_append_fmt(res, SPACE "%s (*%s)(", c_type_empty_means_void(method.return_type), method.name);
|
||||
VecU8_append_vec(&res, VecU8_fmt(SPACE "%s (*%s)(", c_type_empty_means_void(method.return_type), method.name));
|
||||
if (method.takes_self) {
|
||||
VecU8_append_fmt(res,
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
method.takes_mut_self ? "%s*" : "const %s*",
|
||||
c_type_empty_means_void(trait.base_struct_name));
|
||||
c_type_empty_means_void(trait.base_struct_name)));
|
||||
}
|
||||
for (size_t p = 0; p < method.params.len; p++) {
|
||||
NamedVariableRecordRef param = *SpanNamedVariableRecordRef_at(method.params, p);
|
||||
if (p || method.takes_self)
|
||||
VecU8_append_cstr(res, ", ");
|
||||
VecU8_append_span(res, param.type);
|
||||
VecU8_append_span(&res, cstr(", "));
|
||||
VecU8_append_span(&res, param.type);
|
||||
}
|
||||
VecU8_append_cstr(res, ");\n");
|
||||
VecU8_append_span(&res, cstr(");\n"));
|
||||
}
|
||||
if (!trait.drop_primitive) {
|
||||
VecU8_append_fmt(res,
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
SPACE "void (*drop)(%s*);\n",
|
||||
c_type_empty_means_void(trait.base_struct_name));
|
||||
c_type_empty_means_void(trait.base_struct_name)));
|
||||
}
|
||||
VecU8_append_fmt(res, "} %s_Table;\n\n", trait.name);
|
||||
VecU8_append_vec(&res, VecU8_fmt("} %s_Table;\n\n", trait.name));
|
||||
return res;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
@ -62,46 +63,45 @@ typedef struct {
|
||||
|
||||
/* (refkind, mut) in {(Ref, false), (MutRef, true), (Box, true)} */
|
||||
void codegen_append_trait_wrapper_structure_some_refkind(VecU8* res, NamedTraitDefRecordRef trait,
|
||||
SpanU8 refkind, bool mut
|
||||
){
|
||||
VecU8_append_fmt(res,
|
||||
SpanU8 refkind, bool mut){
|
||||
VecU8_append_vec(res, VecU8_fmt(
|
||||
"typedef struct {\n"
|
||||
SPACE "%s%s* r;\n" /* epsilon / const, op.trait.base_struct_name */
|
||||
SPACE "const %s_Table* t;\n" /* op.trait.name */
|
||||
"} %s%s;\n\n", /* refkind, op.trait.name */
|
||||
mut ? cstr("") : cstr("const "),
|
||||
c_type_empty_means_void(trait.base_struct_name),
|
||||
trait.name, refkind, trait.name);
|
||||
trait.name, refkind, trait.name));
|
||||
}
|
||||
|
||||
/* (refkind, self_as_ptr) in {(Ref, false), (MutRef, false), (Box, true)} */
|
||||
void codegen_append_trait_wrapper_some_method_some_refkind(VecU8* res, SpanU8 trait_name,
|
||||
NamedMethodSignatureRecordRef method, SpanU8 refkind, bool self_as_ptr
|
||||
){
|
||||
VecU8_append_fmt(res,
|
||||
NamedMethodSignatureRecordRef method, SpanU8 refkind, bool self_as_ptr){
|
||||
VecU8_append_vec(res, VecU8_fmt(
|
||||
"%s %s%s_%s(%s%s%s self",
|
||||
/* return_type, refkind, trait.name, method.name, refkind, trait.name */
|
||||
c_type_empty_means_void(method.return_type),
|
||||
refkind, trait_name, method.name, refkind, trait_name, self_as_ptr ? cstr("*") : cstr(""));
|
||||
refkind, trait_name, method.name, refkind, trait_name, self_as_ptr ? cstr("*") : cstr("")));
|
||||
for (size_t p = 0; p < method.params.len; p++) {
|
||||
NamedVariableRecordRef param = method.params.data[p];
|
||||
VecU8_append_fmt(res, ", %s %s", param.type, param.name);
|
||||
VecU8_append_vec(res, VecU8_fmt(", %s %s", param.type, param.name));
|
||||
}
|
||||
VecU8_append_cstr(res,"){\n" SPACE);
|
||||
VecU8_append_span(res, cstr("){\n" SPACE));
|
||||
if (method.return_type.len > 0)
|
||||
VecU8_append_cstr(res, "return ");
|
||||
VecU8_append_fmt(res, "self%s""t->%s(",
|
||||
self_as_ptr ? cstr("->") : cstr("."), method.name);
|
||||
VecU8_append_span(res, cstr("return "));
|
||||
VecU8_append_vec(res, VecU8_fmt("self%s""t->%s(",
|
||||
self_as_ptr ? cstr("->") : cstr("."),
|
||||
method.name));
|
||||
if (method.takes_self) {
|
||||
VecU8_append_fmt(res, "self%s""r", self_as_ptr ? cstr("->") : cstr("."));
|
||||
VecU8_append_vec(res, VecU8_fmt("self%s""r", self_as_ptr ? cstr("->") : cstr(".")));
|
||||
}
|
||||
for (size_t p = 0; p < method.params.len; p++) {
|
||||
NamedVariableRecordRef param = method.params.data[p];
|
||||
if (p > 0 || method.takes_self)
|
||||
VecU8_append_cstr(res, ", ");
|
||||
VecU8_append_span(res, cstr(", "));
|
||||
VecU8_append_span(res, param.name);
|
||||
}
|
||||
VecU8_append_cstr(res, ");\n}\n\n");
|
||||
VecU8_append_span(res, cstr(");\n}\n\n"));
|
||||
}
|
||||
|
||||
NODISCARD VecU8 generate_trait_wrapper_boilerplate(trait_wrapper_boil_options op) {
|
||||
@ -112,7 +112,7 @@ NODISCARD VecU8 generate_trait_wrapper_boilerplate(trait_wrapper_boil_options op
|
||||
}
|
||||
|
||||
VecU8 res = VecU8_new();
|
||||
codegen_append_trait_table_structure(&res, op.trait);
|
||||
VecU8_append_vec(&res, generate_trait_table_structure(op.trait));
|
||||
if (op.ref) {
|
||||
codegen_append_trait_wrapper_structure_some_refkind(&res, op.trait, cstr("Ref"), false);
|
||||
for (size_t i = 0; i < op.trait.methods.len; i++) {
|
||||
@ -135,24 +135,24 @@ NODISCARD VecU8 generate_trait_wrapper_boilerplate(trait_wrapper_boil_options op
|
||||
NamedMethodSignatureRecordRef method = op.trait.methods.data[i];
|
||||
codegen_append_trait_wrapper_some_method_some_refkind(&res, op.trait.name, method, cstr("Box"), true);
|
||||
}
|
||||
VecU8_append_fmt(&res,
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"void Box%s_drop(Box%s self){\n" /* trait.name, trait.name */
|
||||
"%s" /* epsilon / calling self.t->drop() */
|
||||
SPACE "free(self.r);\n"
|
||||
"}\n\n",
|
||||
op.trait.name, op.trait.name,
|
||||
op.trait.drop_primitive ? cstr("") : cstr(SPACE "self.t->drop(self.r);\n"));
|
||||
op.trait.drop_primitive ? cstr("") : cstr(SPACE "self.t->drop(self.r);\n")));
|
||||
if (op.ref) {
|
||||
VecU8_append_fmt(&res,
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"Ref%s Box%s_ref(Box%s *self) {\n"
|
||||
SPACE "return (Ref%s){.r = self->r, .t = self->t};\n"
|
||||
"}\n\n", op.trait.name, op.trait.name, op.trait.name, op.trait.name);
|
||||
"}\n\n", op.trait.name, op.trait.name, op.trait.name, op.trait.name));
|
||||
}
|
||||
if (op.mut_ref) {
|
||||
VecU8_append_fmt(&res,
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"MutRef%s Box%s_mut_ref(Box%s *self) {\n"
|
||||
SPACE "return (MutRef%s){.r = self->r, .t = self->t};\n"
|
||||
"}\n\n", op.trait.name, op.trait.name, op.trait.name, op.trait.name);
|
||||
"}\n\n", op.trait.name, op.trait.name, op.trait.name, op.trait.name));
|
||||
}
|
||||
}
|
||||
return res;
|
||||
|
||||
@ -6,15 +6,6 @@
|
||||
|
||||
#include "linux/input-event-codes.h"
|
||||
|
||||
|
||||
typedef mat3 quad_form3_t;
|
||||
|
||||
float quad_form3_mul_vec(quad_form3_t Q, vec3 M) {
|
||||
return M.x * M.x * Q.x.x * Q.x.x + M.y * M.y * Q.y.y * Q.y.y + M.z * M.z * Q.z.z * Q.z.z +
|
||||
2 * (M.x * M.y * Q.x.y + M.x * M.z * Q.x.z + M.y * M.x * Q.y.z);
|
||||
}
|
||||
|
||||
|
||||
typedef struct{
|
||||
vec3 pos;
|
||||
vec3 color;
|
||||
@ -25,7 +16,7 @@ typedef struct{
|
||||
|
||||
typedef struct {
|
||||
float mass; /* In kg, Not zero */
|
||||
quad_form3_t inertia_moment; /* Qadratic form, yields kg*m^2 */
|
||||
float moment_of_inertia; /* In kg*m^2 */
|
||||
/* Center of mass relative to "center of mesh" */
|
||||
vec3 mass_center;
|
||||
} RigidBodyConfig;
|
||||
@ -135,10 +126,7 @@ void RigidBodyState_when_shot(RigidBodyState* self, vec3 imp, float m2, vec3 v){
|
||||
self->speed = vec3_add_vec3(self->speed, linear_speed_gain);
|
||||
|
||||
|
||||
vec3 www = vec3_mul_scal(vec3_cross(v, IO), m2);
|
||||
vec3 w = vec3_normalize(www);
|
||||
float I = quad_form3_mul_vec(self->p.inertia_moment, w);
|
||||
vec3 angular_speed_gain = vec3_div_by_scal(www, I);
|
||||
vec3 angular_speed_gain = vec3_mul_scal(vec3_cross(v, IO), m2 / self->p.moment_of_inertia);
|
||||
self->angular_speed = vec3_add_vec3(self->angular_speed, angular_speed_gain);
|
||||
}
|
||||
|
||||
@ -337,15 +325,8 @@ void run_app(){
|
||||
.specular_texture_path = vcstr("./src/l3/textures/log_10_2_6_specular.png")
|
||||
});
|
||||
AliceGenericMeshHand_resize_instance_arr(st.alice, &st.ROA_mesh->el, 1);
|
||||
const float gamma_l_c = 4.f / 3 / M_PIf;
|
||||
st.ROA_state = (RigidBodyState){
|
||||
.p.mass = 1.f * 1/4 * M_PIf * 2*2 * 10,
|
||||
.p.inertia_moment = (mat3){
|
||||
.x = { 16.926308911016392, 1.5411267097545367e-13, -9.491580156388568e-15},
|
||||
.y = { 1.5411267097545367e-13, 259.0981544556158, 2.539003832491438},
|
||||
.z = {-9.491580156388568e-15, 2.539003832491438, 259.09815445561975},
|
||||
},
|
||||
.p.mass_center = (vec3){5, 2 * gamma_l_c, -2 * gamma_l_c},
|
||||
.p.mass = 50.f, .p.moment_of_inertia = 5000.f, .p.mass_center = (vec3){5, 0.77f, -0.77f},
|
||||
.pos = (vec3){11.f, 3, 4}, .speed = {0},
|
||||
.rot = mat3_E, .angular_speed = (vec3){0}};
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user