diff --git a/src/l1/codegen/codegen.c b/src/l1/codegen/codegen.c index 70e05da..ba26063 100644 --- a/src/l1/codegen/codegen.c +++ b/src/l1/codegen/codegen.c @@ -4,21 +4,32 @@ int main() { make_dir_nofail("l1"); { - VecU8 head = begin_header(cstr("PROTOTYPE1_L1_VECANDSPANANDOPTION_INT_PRIMITIVES_H")); + VecU8 head = begin_header(cstr("PROTOTYPE1_GEN_L1_VECANDSPAN_INT_PRIMITIVES_H")); VecU8_append_span(&head, cstr("#include \"../../src/l1/core/util.h\"\n\n")); SpanU8 T[4] = {cstr("U8"), cstr("U16"), cstr("U32"), cstr("U64")}; for (size_t i = 0; i < ARRAY_SIZE(T); i++) { VecU8_append_vec(&head, generate_util_templates_instantiation(T[i], (util_templates_instantiation_options){ .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, .option = true + .collab_vec_span = true, .collab_vec_span_extended = true, })); } - finish_header(head, "l1/VecAndSpanAndOption_int_primitives.h"); + finish_header(head, "l1/VecAndSpan_int_primitives.h"); } { - VecU8 head = begin_header(cstr("PROTOTYPE1_L1_VECANDSPAN_VEC_INT_PRIMITIVES_H")); - VecU8_append_span(&head, cstr("#include \"VecAndSpanAndOption_int_primitives.h\"\n\n")); + VecU8 head = begin_header(cstr("PROTOTYPE1_GEN_L1_OPTION_INT_PRIMITIVES_H")); + VecU8_append_span(&head, cstr("#include \"../../src/l1/core/util.h\"\n\n")); + SpanU8 T[4] = {cstr("U8"), cstr("U16"), cstr("U32"), cstr("U64")}; + for (size_t i = 0; i < ARRAY_SIZE(T); i++) { + VecU8_append_vec(&head, generate_util_templates_instantiation(T[i], (util_templates_instantiation_options){ + .t_integer = true, .t_primitive = true, .option = true + })); + } + finish_header(head, "l1/Option_int_primitives.h"); + } + { + VecU8 head = begin_header(cstr("PROTOTYPE1_GEN_L1_VECANDSPAN_VEC_INT_PRIMITIVES_H")); + VecU8_append_span(&head, cstr("#include \"VecAndSpan_int_primitives.h\"\n\n")); SpanU8 T[4] = {cstr("VecU8"), cstr("VecU16"), cstr("VecU32"), cstr("VecU64")}; for (size_t i = 0; i < ARRAY_SIZE(T); i++) { VecU8_append_vec(&head, generate_util_templates_instantiation(T[i], (util_templates_instantiation_options){ @@ -28,12 +39,12 @@ int main() { finish_header(head, "l1/VecAndSpan_Vec_int_primitives.h"); } { - VecU8 head = begin_header(cstr("PROTOTYPE1_L1_VECANDSPAN_SPAN_INT_PRIMITIVES_H")); - VecU8_append_span(&head, cstr("#include \"VecAndSpanAndOption_int_primitives.h\"\n\n")); + VecU8 head = begin_header(cstr("PROTOTYPE1_GEN_L1_VECANDSPAN_SPAN_INT_PRIMITIVES_H")); + VecU8_append_span(&head, 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, generate_util_templates_instantiation(T[i], (util_templates_instantiation_options){ - .t_primitive = true, .vec = true, .vec_equal = true, .span = true, .mut_span = true, + .t_primitive = true, .vec = true, .span = true, .mut_span = true, .collab_vec_span = true, })); } diff --git a/src/l1/codegen/codegen.h b/src/l1/codegen/codegen.h index 6150238..6025c32 100644 --- a/src/l1/codegen/codegen.h +++ b/src/l1/codegen/codegen.h @@ -27,10 +27,4 @@ void finish_header(VecU8 text_before_endif, const char* filename) { #define SPACE12 " " #define SPACE16 " " -/* code generation function. We don't append vector data to vecu8, we append vector name to string in VecU8 */ -void VecU8_append_vecoft(VecU8* str, SpanU8 t) { - VecU8_append_span(str, cstr("Vec")); - VecU8_append_span(str, t); -} - #endif diff --git a/src/l1/core/VecU8_as_str.h b/src/l1/core/VecU8_as_str.h index e21dab0..2d8a6cb 100644 --- a/src/l1/core/VecU8_as_str.h +++ b/src/l1/core/VecU8_as_str.h @@ -6,7 +6,7 @@ #ifdef PROTOTYPE1_L1_CODEGEN_BOOTSTRAP_USE_CHICKEN_VECU8 #include "chicken_VecU8.h" #else -#include "../../../gen/l1/VecAndSpanAndOption_int_primitives.h" +#include "../../../gen/l1/VecAndSpan_int_primitives.h" #endif VecU8 VecU8_from_cstr(const char* dc) { @@ -29,7 +29,7 @@ void SpanU8_print(SpanU8 str) { } /* Not thread safe (for `stream`) ! */ -void ConstSpanU8_fprint(SpanU8 str, FILE* stream) { +void SpanU8_fprint(SpanU8 str, FILE* stream) { for (size_t i = 0; i < str.len; i++) putc((int)*SpanU8_at(str, i), stream); } @@ -58,6 +58,7 @@ NODISCARD VecU8 VecU8_format(const char *fmt, ...) { return (VecU8){ .buf = buf, .len = len, .capacity = len + 1 }; } +// todo: add %d (when I figure out how to do it) NODISCARD VecU8 VecU8_fmt(const char* fmt, ...) { assert(fmt); size_t k = 0; @@ -71,6 +72,9 @@ NODISCARD VecU8 VecU8_fmt(const char* fmt, ...) { } else if (*ch == 's') { SpanU8 s = va_arg(args, SpanU8); k += s.len; + } else if (*ch == 'c') { + int byte = va_arg(args, int); + k ++; } else abortf("Format syntax error at pos %lu! Watch out, be careful", (size_t)(ch - fmt)); } else { @@ -89,6 +93,9 @@ NODISCARD VecU8 VecU8_fmt(const char* fmt, ...) { } else if (*ch == 's') { SpanU8 s = va_arg(args, SpanU8); VecU8_append_span(&res, s); + } else if (*ch == 'c') { + int byte = va_arg(args, int); + VecU8_append(&res, (U8)byte); } else assert(false); } else { diff --git a/src/l1/tests/t0.c b/src/l1/tests/t0.c index 1ca6fb3..ceddf96 100644 --- a/src/l1/tests/t0.c +++ b/src/l1/tests/t0.c @@ -1,4 +1,4 @@ -#include "../../../gen/l1/VecAndSpanAndOption_int_primitives.h" +#include "../../../gen/l1/VecAndSpan_int_primitives.h" int main() { VecU8 a = VecU8_new(); diff --git a/src/l1/tests/t1.c b/src/l1/tests/t1.c index 51978a5..8583a87 100644 --- a/src/l1/tests/t1.c +++ b/src/l1/tests/t1.c @@ -1,4 +1,4 @@ -#include "../../../gen/l1/VecAndSpanAndOption_int_primitives.h" +#include "../../../gen/l1/VecAndSpan_int_primitives.h" #include "../../../gen/l1/VecAndSpan_Vec_int_primitives.h" int main() { diff --git a/src/l2/codegen/clipping.h b/src/l2/codegen/clipping.h index 550290c..ea68583 100644 --- a/src/l2/codegen/clipping.h +++ b/src/l2/codegen/clipping.h @@ -6,6 +6,8 @@ // todo: move all of this to marie namespace // todo: instead of returning triangles, return points of convex polygon +// todo: I would say that I need to rewrite all with VecU8_fmt, but I am not sure I even need this code +// todo: rewrite if I decide not to delete typedef struct { int order; diff --git a/src/l2/codegen/codegen.c b/src/l2/codegen/codegen.c index 203c41d..9250fe3 100644 --- a/src/l2/codegen/codegen.c +++ b/src/l2/codegen/codegen.c @@ -2,13 +2,45 @@ #include "pixel_masses.h" #include "clipping.h" #include "../../l1/system/fsmanip.h" +#include "../../l1/codegen/util_template_inst.h" -// todo: generate here lyndas + -//todo + generate here cvec34 vectors and vec2, vec3, vec4 vectors +// todo: generate here eve headers for margaret and for tests (long asset description files in r0) + +void generate_Vec_cvec_header() { + VecU8 res = begin_header(cstr("PROTOTYPE1_GEN_L2_VECANDSPAN_GEOM_CVEC_H")); + VecU8_append_span(&res, cstr("#include \"geom.h\"\n")); + VecU8_append_span(&res, 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(&res, generate_util_templates_instantiation(T[i], + (util_templates_instantiation_options){ + .t_primitive = true, .vec = true, .span = true, .collab_vec_span = true, + })); + } + finish_header(res, "l2/VecAndSpan_cvec.h"); +} + +void generate_Vec_vec_header() { + VecU8 res = begin_header(cstr("PROTOTYPE1_GEN_L2_VECANDSPAN_GEOM_CVEC_H")); + VecU8_append_span(&res, cstr("#include \"geom.h\"\n")); + VecU8_append_span(&res, 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(&res, generate_util_templates_instantiation(T[i], + (util_templates_instantiation_options){ + .t_primitive = true, .vec = true, .span = true, .collab_vec_span = true, + })); + } + finish_header(res, "l2/VecAndSpan_vec.h"); +} int main() { make_dir_nofail("l2"); generate_geom_header(); + + generate_Vec_cvec_header(); + generate_Vec_vec_header(); + generate_pixel_masses_header(); make_dir_nofail("l2/marie"); generate_clipping_header(); diff --git a/src/l2/codegen/geom.h b/src/l2/codegen/geom.h index 4f5253a..8af3f7b 100644 --- a/src/l2/codegen/geom.h +++ b/src/l2/codegen/geom.h @@ -1,321 +1,315 @@ #ifndef PROTOTYPE_SRC_L2_CODEGEN_GEOM_H #define PROTOTYPE_SRC_L2_CODEGEN_GEOM_H +// todo: check for bugs + #include "../../l1/codegen/codegen.h" -void string_append_vec_field_name(VecU8* str, int ci) { +SpanU8 vec_field_name(int ci) { assert(0 <= ci && ci < 4); - - VecU8_append(str, ci == 3 ? 'w' : 'x' + ci); + return cstr(ci == 0 ? "x" : (ci == 1 ? "y" : (ci == 2 ? "z" : "w"))); } -void string_append_xvecy(VecU8* str, SpanU8 xvec, int cc) { - VecU8_append_span(str, xvec); - VecU8_append(str, '0' + cc); +NODISCARD VecU8 codegen_name_xvecn(SpanU8 xvec, int n) { + assert(2 <= n && n <= 4); + return VecU8_fmt("%s%c", xvec, '0' + n); } -NODISCARD VecU8 generate_xvecy_struct_definition(SpanU8 xvec, SpanU8 member, int cc) { - assert(2 <= cc && cc <= 4); +NODISCARD VecU8 generate_xvecn_struct_and_base_methods(SpanU8 xvec, SpanU8 memb, int n) { + VecU8 g_xvecn = codegen_name_xvecn(xvec, n); + SpanU8 xvecn = VecU8_to_span(&g_xvecn); VecU8 res = VecU8_new(); + /* Structure definition */ VecU8_append_span(&res, cstr("typedef struct {\n")); - - for (int ci = 0; ci < cc; ci++) { - VecU8_append_span(&res, cstr(SPACE4)); - VecU8_append_span(&res, member); - VecU8_append(&res, ' '); - string_append_vec_field_name(&res, ci); - VecU8_append_span(&res, cstr(";\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_span(&res, cstr("} ")); - string_append_xvecy(&res, xvec, cc); - VecU8_append_span(&res, cstr(";\n\n")); - return res; -} - -NODISCARD VecU8 generate_xvecy_method_add_xvecy(SpanU8 xvec, SpanU8 member, int cc) { - VecU8 res = VecU8_new(); - string_append_xvecy(&res, xvec, cc); - VecU8_append_span(&res, cstr(" ")); - string_append_xvecy(&res, xvec, cc); - VecU8_append_span(&res, cstr("_add_")); - string_append_xvecy(&res, xvec, cc); - VecU8_append_span(&res, cstr("(")); - string_append_xvecy(&res, xvec, cc); - VecU8_append_span(&res, cstr(" A, ")); - string_append_xvecy(&res, xvec, cc); - VecU8_append_span(&res, cstr(" B) {\n" SPACE4 "return (")); - string_append_xvecy(&res, xvec, cc); - VecU8_append_span(&res, cstr("){ ")); - for (int ci = 0; ci < cc; 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){ ", + xvecn, xvecn, xvecn, xvecn, xvecn, xvecn)); + for (int ci = 0; ci < n; ci++) { if (ci) VecU8_append_span(&res, cstr(", ")); - VecU8_append_span(&res, cstr("A.")); - string_append_vec_field_name(&res, ci); - VecU8_append_span(&res, cstr(" + B.")); - string_append_vec_field_name(&res, ci); + VecU8_append_vec(&res, VecU8_fmt("A.%s + B.%s", vec_field_name(ci), vec_field_name(ci))); } VecU8_append_span(&res, cstr(" };\n}\n\n")); - return res; -} - -NODISCARD VecU8 generate_xvecy_method_minus_xvecy(SpanU8 xvec, SpanU8 member, int cc) { - VecU8 res = VecU8_new(); - string_append_xvecy(&res, xvec, cc); - VecU8_append_span(&res, cstr(" ")); - string_append_xvecy(&res, xvec, cc); - VecU8_append_span(&res, cstr("_minus_")); - string_append_xvecy(&res, xvec, cc); - VecU8_append_span(&res, cstr("(")); - string_append_xvecy(&res, xvec, cc); - VecU8_append_span(&res, cstr(" A, ")); - string_append_xvecy(&res, xvec, cc); - VecU8_append_span(&res, cstr(" B) {\n" SPACE4 "return (")); - string_append_xvecy(&res, xvec, cc); - VecU8_append_span(&res, cstr("){ ")); - for (int ci = 0; ci < cc; ci++) { + /* xvecn_minus_xvecn method */ + VecU8_append_vec(&res, VecU8_fmt( + "%s %s_minus_%s(%s A, %s B) {\n" + SPACE4 "return (%s){ ", + xvecn, xvecn, xvecn, xvecn, xvecn, xvecn)); + for (int ci = 0; ci < n; ci++) { if (ci) VecU8_append_span(&res, cstr(", ")); - VecU8_append_span(&res, cstr("A.")); - string_append_vec_field_name(&res, ci); - VecU8_append_span(&res, cstr(" - B.")); - string_append_vec_field_name(&res, ci); + VecU8_append_vec(&res, VecU8_fmt("A.%s - B.%s", vec_field_name(ci), vec_field_name(ci))); } VecU8_append_span(&res, cstr(" };\n}\n\n")); - return res; -} - - -NODISCARD VecU8 generate_xvecy_method_minus(SpanU8 xvec, SpanU8 member, int cc) { - VecU8 res = VecU8_new(); - string_append_xvecy(&res, xvec, cc); - VecU8_append_span(&res, cstr(" ")); - string_append_xvecy(&res, xvec, cc); - VecU8_append_span(&res, cstr("_minus(")); - string_append_xvecy(&res, xvec, cc); - VecU8_append_span(&res, cstr(" A) {\n" SPACE4 "return(")); - string_append_xvecy(&res, xvec, cc); - VecU8_append_span(&res, cstr("){ ")); - for (int ci = 0; ci < cc; ci++) { + /* xvecn_minus method */ + VecU8_append_vec(&res, VecU8_fmt( + "%s %s_minus(%s A) {\n" + SPACE4 "return (%s){ ", + xvecn, xvecn, xvecn, xvecn)); + for (int ci = 0; ci < n; ci++) { if (ci) VecU8_append_span(&res, cstr(", ")); - VecU8_append_span(&res, cstr("-A.")); - string_append_vec_field_name(&res, ci); + VecU8_append_vec(&res, VecU8_fmt("-A.%s", vec_field_name(ci))); } VecU8_append_span(&res, cstr(" };\n}\n\n")); + + VecU8_drop(g_xvecn); return res; } -NODISCARD VecU8 generate_xvecy_method_mul_scal(SpanU8 xvec, SpanU8 member, int cc) { - VecU8 res = VecU8_new(); - string_append_xvecy(&res, xvec, cc); - VecU8_append_span(&res, cstr(" ")); - string_append_xvecy(&res, xvec, cc); - VecU8_append_span(&res, cstr("_mul_scal(")); - string_append_xvecy(&res, xvec, cc); - VecU8_append_span(&res, cstr(" A, ")); - VecU8_append_span(&res, member); - VecU8_append_span(&res, cstr(" B) {\n" SPACE4 "return (")); - string_append_xvecy(&res, xvec, cc); - VecU8_append_span(&res, cstr("){ ")); - for (int ci = 0; ci < cc; ci++) { +NODISCARD VecU8 generate_xvecn_struct_and_cool_methods(SpanU8 xvec, SpanU8 memb, int n) { + VecU8 g_xvecn = codegen_name_xvecn(xvec, n); + SpanU8 xvecn = VecU8_to_span(&g_xvecn); + VecU8 res = generate_xvecn_struct_and_base_methods(xvec, memb, n); + /* xvecn_mul_scal method */ + VecU8_append_vec(&res, VecU8_fmt( + "%s %s_mul_scal(%s A, %s B) {\n" + SPACE4 "return (%s) { ", + xvecn, xvecn, xvecn, memb, xvecn)); + for (int ci = 0; ci < n; ci++) { if (ci) VecU8_append_span(&res, cstr(", ")); - VecU8_append_span(&res, cstr("A.")); - string_append_vec_field_name(&res, ci); - VecU8_append_span(&res, cstr(" * B")); + VecU8_append_vec(&res, VecU8_fmt("A.%s * B", vec_field_name(ci))); } VecU8_append_span(&res, cstr(" };\n}\n\n")); - return res; -} - -NODISCARD VecU8 generate_xvecy_method_div_by_scal(SpanU8 xvec, SpanU8 member, int cc) { - VecU8 res = VecU8_new(); - string_append_xvecy(&res, xvec, cc); - VecU8_append_span(&res, cstr(" ")); - string_append_xvecy(&res, xvec, cc); - VecU8_append_span(&res, cstr("_div_by_scal(")); - string_append_xvecy(&res, xvec, cc); - VecU8_append_span(&res, cstr(" A, ")); - VecU8_append_span(&res, member); - VecU8_append_span(&res, cstr(" B){\n" SPACE4 "return ")); - string_append_xvecy(&res, xvec, cc); - VecU8_append_span(&res, cstr("_mul_scal(A, 1/B);\n}\n\n")); - return res; -} - -NODISCARD VecU8 generate_xvecy_method_mul_xvecy(SpanU8 xvec, SpanU8 member, int n) { - VecU8 res = VecU8_new(); - string_append_xvecy(&res, xvec, n); - VecU8_append_span(&res, cstr(" ")); - string_append_xvecy(&res, xvec, n); - VecU8_append_span(&res, cstr("_mul_")); - string_append_xvecy(&res, xvec, n); - VecU8_append_span(&res, cstr("(")); - string_append_xvecy(&res, xvec, n); - VecU8_append_span(&res, cstr(" A, ")); - string_append_xvecy(&res, xvec, n); - VecU8_append_span(&res, cstr(" B) {\n" SPACE4 "return (")); - string_append_xvecy(&res, xvec, n); - VecU8_append_span(&res, cstr("){ ")); - for (int i = 0; i < n; i++) { - if (i) + /* 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" + "}\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){ ", + xvecn, xvecn, xvecn, xvecn, xvecn, xvecn)); + for (int ci = 0; ci < n; ci++) { + if (ci) VecU8_append_span(&res, cstr(", ")); - VecU8_append_span(&res, cstr("A.")); - string_append_vec_field_name(&res, i); - VecU8_append_span(&res, cstr(" * B.")); - string_append_vec_field_name(&res, i); + VecU8_append_vec(&res, VecU8_fmt("A.%s * B.%s", vec_field_name(ci), vec_field_name(ci))); } VecU8_append_span(&res, cstr(" };\n}\n\n")); - return res; -} - -NODISCARD VecU8 generate_xvecy_method_and_one(SpanU8 xvec, int n) { - assert(2 <= n && n < 4); - VecU8 res = VecU8_new(); - string_append_xvecy(&res, xvec, n + 1); - VecU8_append_span(&res, cstr(" ")); - string_append_xvecy(&res, xvec, n); - VecU8_append_span(&res, cstr("_and_one(")); - string_append_xvecy(&res, xvec, n); - VecU8_append_span(&res, cstr(" A) {\n" SPACE4 "return (")); - string_append_xvecy(&res, xvec, n + 1); - VecU8_append_span(&res, cstr("){ ")); - for (int i = 0; i < n; i++) { - VecU8_append_span(&res, cstr("A.")); - string_append_vec_field_name(&res, i); - VecU8_append_span(&res, cstr(", ")); - } - VecU8_append_span(&res, cstr("1 };\n}\n\n")); - return res; -} - -NODISCARD VecU8 generate_xvecy_method_dot(SpanU8 xvec, SpanU8 member, int n) { - VecU8 res = VecU8_from_span(member); - VecU8_append(&res, ' '); - string_append_xvecy(&res, xvec, n); - VecU8_append_span(&res, cstr("_dot(")); - string_append_xvecy(&res, xvec, n); - VecU8_append_span(&res, cstr(" A, ")); - string_append_xvecy(&res, xvec, n); - VecU8_append_span(&res, cstr(" B) {\n" SPACE4 "return ")); + /* xvecn_dot method */ + VecU8_append_vec(&res, VecU8_fmt( + "%s %s_dot(%s A, %s B) {\n" + SPACE4 "return ", + memb, xvecn, xvecn, xvecn)); for (int i = 0; i < n; i++) { if (i) VecU8_append_span(&res, cstr(" + ")); - VecU8_append_span(&res, cstr("A.")); - string_append_vec_field_name(&res, i); - VecU8_append_span(&res, cstr(" * B.")); - string_append_vec_field_name(&res, i); + VecU8_append_vec(&res, VecU8_fmt("A.%s * B.%s", vec_field_name(i), vec_field_name(i))); } VecU8_append_span(&res, cstr(";\n}\n\n")); + + VecU8_drop(g_xvecn); + return res; +} + +NODISCARD VecU8 generate_xvecn_method_and_one(SpanU8 xvec, int n) { + assert(2 <= n && n < 4); + VecU8 g_xvecn = codegen_name_xvecn(xvec, n); + VecU8 g_xvecn_pp = codegen_name_xvecn(xvec, n + 1); + SpanU8 xvecn = VecU8_to_span(&g_xvecn); + SpanU8 xvecn_pp = VecU8_to_span(&g_xvecn_pp); + + VecU8 res = VecU8_fmt( + "%s %s_and_one(%s A) {\n" + SPACE4 "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))); + } + VecU8_append_span(&res, cstr("1 };\n}\n\n")); + + VecU8_drop(g_xvecn_pp); + VecU8_drop(g_xvecn); return res; } NODISCARD VecU8 generate_xvec3_method_cross(SpanU8 xvec) { - VecU8 res = VecU8_new(); - string_append_xvecy(&res, xvec, 3); - VecU8_append(&res, ' '); - string_append_xvecy(&res, xvec, 3); - VecU8_append_span(&res, cstr("_cross(")); - string_append_xvecy(&res, xvec, 3); - VecU8_append_span(&res, cstr(" A, ")); - string_append_xvecy(&res, xvec, 3); - VecU8_append_span(&res, cstr(" B) {\n" SPACE4 "return (")); - string_append_xvecy(&res, xvec, 3); - VecU8_append_span(&res, cstr("){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")); + VecU8 g_xvec3 = codegen_name_xvecn(xvec, 3); + 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" + "}\n\n", xvec3, xvec3, xvec3, xvec3, xvec3); + VecU8_drop(g_xvec3); return res; } - -void string_append_xmatnm(VecU8* str, SpanU8 xmat, int cols, int rows) { - VecU8_append_span(str, xmat); - VecU8_append(str, '0' + cols); - if (rows != cols) { - VecU8_append(str, 'x'); - VecU8_append(str, '0' + rows); - } +NODISCARD VecU8 codegen_name_xmatnm(SpanU8 xmat, int cols, int rows) { + assert(2 <= cols && cols <= 4 && 2 <= rows && rows <= 4); + if (cols == rows) + return VecU8_fmt("%s%c", xmat, '0' + cols); + return VecU8_fmt("%s%cx%c", xmat, '0' + cols, '0' + rows); } -/* With columns padded to 16 bytes (for std140, std140 is our everything) */ -NODISCARD VecU8 generate_xmatnm_structure_definition(SpanU8 xmat, SpanU8 xvec, int cols, int rows, int sizeof_member) { +NODISCARD VecU8 generate_xmatnm_struct_and_methods( + SpanU8 xmat, SpanU8 xvec, SpanU8 memb, int cols, int rows, int sizeof_member + ) { + VecU8 g_xmatnm = codegen_name_xmatnm(xmat, cols, rows); + SpanU8 xmatnm = VecU8_to_span(&g_xmatnm); + VecU8 g_xvecm = codegen_name_xvecn(xvec, rows); + SpanU8 xvecm = VecU8_to_span(&g_xvecm); + VecU8 res = VecU8_new(); + + /* Structure xmatnm + * With columns padded to 16 bytes (for std140, std140 is our everything) */ int sv = (rows * sizeof_member) % 16; - VecU8 res = VecU8_from_cstr("typedef struct {\n"); + VecU8_append_span(&res, cstr("typedef struct {\n")); for (int x = 0; x < cols; x++) { - VecU8_append_span(&res, cstr(SPACE4)); - string_append_xvecy(&res, xvec, rows); - VecU8_append_span(&res, cstr(" ")); - string_append_vec_field_name(&res, x); - VecU8_append_span(&res, cstr(";\n")); + VecU8_append_vec(&res, VecU8_fmt(SPACE4 "%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_span(&res, cstr("} ")); - string_append_xmatnm(&res, xmat, cols, rows); - VecU8_append_span(&res, cstr(";\n\n")); - return res; -} - -void string_append_mat_col_definition(VecU8* str, int ci) { - VecU8_append(str, '.'); - string_append_vec_field_name(str, ci); - VecU8_append_span(str, cstr(" = ")); -} - -void string_append_mat_el_access(VecU8* str, int x, int y) { - VecU8_append(str, '.'); - string_append_vec_field_name(str, x); - VecU8_append(str, '.'); - string_append_vec_field_name(str, y); -} - -NODISCARD VecU8 generate_xmatnm_method_new(SpanU8 xmat, SpanU8 xvec, SpanU8 member, int cols, int rows) { - VecU8 res = VecU8_new(); - string_append_xmatnm(&res, xmat, cols, rows); - VecU8_append(&res, ' '); - string_append_xmatnm(&res, xmat, cols, rows); - VecU8_append_span(&res, cstr("_new(")); + VecU8_append_vec(&res, VecU8_fmt("} %s;\n\n", xmatnm)); + /* xmatnm_new method */ + VecU8_append_vec(&res, VecU8_fmt("%s %s_new(", xmatnm, xmatnm)); for (int y = 0; y < rows; y++) { for (int x = 0; x < cols; x++) { if (x > 0 || y > 0) VecU8_append_span(&res, cstr(", ")); - VecU8_append_span(&res, member); - VecU8_append(&res, ' '); - string_append_vec_field_name(&res, x); - string_append_vec_field_name(&res, y); + VecU8_append_vec(&res, VecU8_fmt("%s %s%s", memb, vec_field_name(x), vec_field_name(y))); } } - VecU8_append_span(&res, cstr(") {\n" SPACE4 "return (")); - string_append_xmatnm(&res, xmat, cols, rows); - VecU8_append_span(&res, cstr("){ ")); + VecU8_append_vec(&res, VecU8_fmt(") {\n" SPACE4 "return (%s){ ", xmatnm)); for (int x = 0; x < cols; x++) { if (x) VecU8_append_span(&res, cstr(", ")); - string_append_mat_col_definition(&res, x); - VecU8_append_span(&res, cstr("{ ")); + VecU8_append_vec(&res, VecU8_fmt(".%s = { ", vec_field_name(x))); for (int y = 0; y < rows; y++) { if (y) VecU8_append_span(&res, cstr(", ")); - string_append_vec_field_name(&res, x); - string_append_vec_field_name(&res, y); + VecU8_append_vec(&res, VecU8_fmt("%s%s", vec_field_name(x), vec_field_name(y))); } VecU8_append_span(&res, cstr(" }")); } VecU8_append_span(&res, cstr(" };\n}\n\n")); + /* xmatnm_add_xmatnm method */ + VecU8_append_vec(&res, VecU8_fmt( + "%s %s_add_%s(%s A, %s B) {\n" + SPACE4 "return (%s){ ", + xmatnm, xmatnm, xmatnm, xmatnm, xmatnm, xmatnm)); + for (int x = 0; x < cols; x++) { + if (x) + VecU8_append_span(&res, cstr(", ")); + VecU8_append_vec(&res, VecU8_fmt(".%s = %s_add_%s(A.%s, B.%s)", + vec_field_name(x), xvecm, xvecm, vec_field_name(x), vec_field_name(x))); + } + VecU8_append_span(&res, cstr(" };\n}\n\n")); + /* xmatnm_minus_xmatnm method */ + VecU8_append_vec(&res, VecU8_fmt( + "%s %s_minus_%s(%s A, %s B) {\n" + SPACE4 "return (%s){ ", + xmatnm, xmatnm, xmatnm, xmatnm, xmatnm, xmatnm)); + for (int x = 0; x < cols; x++) { + if (x) + VecU8_append_span(&res, cstr(", ")); + VecU8_append_vec(&res, VecU8_fmt(".%s = %s_minus_%s(A.%s, B.%s)", + vec_field_name(x), xvecm, xvecm, vec_field_name(x), vec_field_name(x))); + } + VecU8_append_span(&res, cstr(" };\n}\n\n")); + /* xmatnm_minus method */ + VecU8_append_vec(&res, VecU8_fmt( + "%s %s_minus(%s A) {\n" + SPACE4 "return (%s){ ", + xmatnm, xmatnm, xmatnm, xmatnm)); + for (int x = 0; x < cols; x++) { + if (x) + VecU8_append_span(&res, cstr(", ")); + VecU8_append_vec(&res, VecU8_fmt(".%s = %s_minus(A.%s)", + vec_field_name(x), xvecm, vec_field_name(x))); + } + VecU8_append_span(&res, cstr(" };\n}\n\n")); + /* xmatnm_mul_scal method */ + VecU8_append_vec(&res, VecU8_fmt( + "%s %s_mul_scal(%s A, %s B) {\n" + SPACE4 "return (%s){ ", + xmatnm, xmatnm, xmatnm, memb, xmatnm)); + for (int x = 0; x < cols; x++) { + if (x) + VecU8_append_span(&res, cstr(", ")); + VecU8_append_vec(&res, VecU8_fmt(".%s = %s_mul_scal(A.%s, B)", + vec_field_name(x), xvecm, vec_field_name(x))); + } + VecU8_append_span(&res, cstr(" };\n}\n\n")); + /* 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" + "}\n\n", xmatnm, xmatnm, xmatnm, memb, xmatnm)); + + + VecU8 g_xvecn = codegen_name_xvecn(xvec, cols); + SpanU8 xvecn = VecU8_to_span(&g_xvecn); + /* xmatnm_mul_xvecn */ + VecU8_append_vec(&res, VecU8_fmt( + "%s %s_mul_%s(%s A, %s B) {\n" + SPACE4 "return (%s){ ", + xvecm, xmatnm, xvecn, xmatnm, xvecn, xvecm)); + for (int y = 0; y < rows; y++) { + if (y) + VecU8_append(&res, ','); + VecU8_append_span(&res, cstr("\n" SPACE8)); + for (int x = 0; x < cols; x++) { + if (x) + VecU8_append_span(&res, cstr(" + ")); + 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_drop(g_xvecn); + VecU8_drop(g_xvecm); + VecU8_drop(g_xmatnm); return res; } -NODISCARD VecU8 generate_square_xmatnn_E_definition(SpanU8 xmat, int n) { - VecU8 res = VecU8_from_cstr("const "); - string_append_xmatnm(&res, xmat, n, n); - VecU8_append(&res, ' '); - string_append_xmatnm(&res, xmat, n, n); - VecU8_append_span(&res, cstr("_E = { ")); +/* xmatnm_transpose method */ +NODISCARD VecU8 generate_xmatnm_transpose_method(SpanU8 xmat, SpanU8 xvec, SpanU8 memb, int cols, int rows) { + VecU8 g_xmatnm = codegen_name_xmatnm(xmat, cols, rows); + VecU8 g_xmatmn = codegen_name_xmatnm(xmat, rows, cols); + SpanU8 xmatnm = VecU8_to_span(&g_xmatnm); + SpanU8 xmatmn = VecU8_to_span(&g_xmatmn); + VecU8 res = VecU8_fmt( + "%s %s_transpose(%s A) {\n" + SPACE4 "return (%s){ ", + xmatmn, xmatnm, xmatnm, xmatmn); + for (int bx = 0; bx < rows; bx++) { + if (bx) + VecU8_append_span(&res, cstr(", ")); + VecU8_append_vec(&res, VecU8_fmt(".%s = { ", vec_field_name(bx))); + for (int by = 0; by < cols; by++) { + if (by) + VecU8_append_span(&res, cstr(", ")); + VecU8_append_vec(&res, VecU8_fmt("A.%s.%s", vec_field_name(by), vec_field_name(bx))); + } + VecU8_append_span(&res, cstr(" }")); + } + VecU8_append_span(&res, cstr(" };\n}\n\n")); + + VecU8_drop(g_xmatmn); + VecU8_drop(g_xmatnm); + return res; +} + +NODISCARD VecU8 generate_square_xmatn_methods(SpanU8 xmat, SpanU8 xvec, SpanU8 memb, int n) { + VecU8 g_xmatn = codegen_name_xmatnm(xmat, n, n); + SpanU8 xmatn = VecU8_to_span(&g_xmatn); + VecU8 res = VecU8_new(); + + VecU8_append_vec(&res, VecU8_fmt( + "const %s %s_E = { ", xmatn, xmatn)); for (int x = 0; x < n; x++) { if (x) VecU8_append_span(&res, cstr(", ")); - string_append_mat_col_definition(&res, x); - VecU8_append_span(&res, cstr("{ ")); + VecU8_append_vec(&res, VecU8_fmt(".%s = {", vec_field_name(x))); for (int y = 0; y < n; y++) { if (y) VecU8_append_span(&res, cstr(", ")); @@ -324,280 +318,80 @@ NODISCARD VecU8 generate_square_xmatnn_E_definition(SpanU8 xmat, int n) { VecU8_append_span(&res, cstr(" }")); } VecU8_append_span(&res, cstr(" };\n\n")); - return res; -} -NODISCARD VecU8 generate_xmatnm_method_add_xmatnm(SpanU8 xmat, SpanU8 xvec, SpanU8 member, int cols, int rows) { - VecU8 res = VecU8_new(); - string_append_xmatnm(&res, xmat, cols, rows); - VecU8_append(&res, ' '); - string_append_xmatnm(&res, xmat, cols, rows); - VecU8_append_span(&res, cstr("_add_")); - string_append_xmatnm(&res, xmat, cols, rows); - VecU8_append_span(&res, cstr("(")); - string_append_xmatnm(&res, xmat, cols, rows); - VecU8_append_span(&res, cstr(" A, ")); - string_append_xmatnm(&res, xmat, cols, rows); - VecU8_append_span(&res, cstr(" B) {\n" SPACE4 "return (")); - string_append_xmatnm(&res, xmat, cols, rows); - VecU8_append_span(&res, cstr("){ ")); - for (int x = 0; x < cols; x++) { - if (x) - VecU8_append_span(&res, cstr(", ")); - string_append_mat_col_definition(&res, x); - string_append_xvecy(&res, xvec, rows); - VecU8_append_span(&res, cstr("_add_")); - string_append_xvecy(&res, xvec, rows); - VecU8_append_span(&res, cstr("(A.")); - string_append_vec_field_name(&res, x); - VecU8_append_span(&res, cstr(", B.")); - string_append_vec_field_name(&res, x); - VecU8_append_span(&res, cstr(")")); - } - VecU8_append_span(&res, cstr(" };\n}\n\n")); - return res; -} - -NODISCARD VecU8 generate_xmatnm_method_minus_xmatnm(SpanU8 xmat, SpanU8 xvec, SpanU8 member, int cols, int rows) { - VecU8 res = VecU8_new(); - string_append_xmatnm(&res, xmat, cols, rows); - VecU8_append(&res, ' '); - string_append_xmatnm(&res, xmat, cols, rows); - VecU8_append_span(&res, cstr("_minus_")); - string_append_xmatnm(&res, xmat, cols, rows); - VecU8_append_span(&res, cstr("(")); - string_append_xmatnm(&res, xmat, cols, rows); - VecU8_append_span(&res, cstr(" A, ")); - string_append_xmatnm(&res, xmat, cols, rows); - VecU8_append_span(&res, cstr(" B) {\n" SPACE4 "return (")); - string_append_xmatnm(&res, xmat, cols, rows); - VecU8_append_span(&res, cstr("){ ")); - for (int x = 0; x < cols; x++) { - if (x) - VecU8_append_span(&res, cstr(", ")); - string_append_mat_col_definition(&res, x); - string_append_xvecy(&res, xvec, rows); - VecU8_append_span(&res, cstr("_minus_")); - string_append_xvecy(&res, xvec, rows); - VecU8_append_span(&res, cstr("(A.")); - string_append_vec_field_name(&res, x); - VecU8_append_span(&res, cstr(", B.")); - string_append_vec_field_name(&res, x); - VecU8_append_span(&res, cstr(")")); - } - VecU8_append_span(&res, cstr(" };\n}\n\n")); - return res; -} - -NODISCARD VecU8 generate_xmatnm_method_minus(SpanU8 xmat, SpanU8 xvec, SpanU8 member, int cols, int rows) { - VecU8 res = VecU8_new(); - string_append_xmatnm(&res, xmat, cols, rows); - VecU8_append(&res, ' '); - string_append_xmatnm(&res, xmat, cols, rows); - VecU8_append_span(&res, cstr("_minus(")); - string_append_xmatnm(&res, xmat, cols, rows); - VecU8_append_span(&res, cstr(" A) {\n" SPACE4 "return (")); - string_append_xmatnm(&res, xmat, cols, rows); - VecU8_append_span(&res, cstr("){ ")); - for (int x = 0; x < cols; x++) { - if (x) - VecU8_append_span(&res, cstr(", ")); - string_append_mat_col_definition(&res, x); - string_append_xvecy(&res, xvec, rows); - VecU8_append_span(&res, cstr("_minus(A.")); - string_append_vec_field_name(&res, x); - VecU8_append_span(&res, cstr(")")); - } - VecU8_append_span(&res, cstr(" };\n}\n\n")); - return res; -} - -NODISCARD VecU8 generate_xmatnm_method_mul_scal(SpanU8 xmat, SpanU8 xvec, SpanU8 member, int cols, int rows) { - VecU8 res = VecU8_new(); - string_append_xmatnm(&res, xmat, cols, rows); - VecU8_append(&res, ' '); - string_append_xmatnm(&res, xmat, cols, rows); - VecU8_append_span(&res, cstr("_mul_scal(")); - string_append_xmatnm(&res, xmat, cols, rows); - VecU8_append_span(&res, cstr(" A, ")); - VecU8_append_span(&res, member); - VecU8_append_span(&res, cstr(" B) {\n" SPACE4 "return (")); - string_append_xmatnm(&res, xmat, cols, rows); - VecU8_append_span(&res, cstr("){ ")); - for (int x = 0; x < cols; x++) { - if (x) - VecU8_append_span(&res, cstr(", ")); - string_append_mat_col_definition(&res, x); - string_append_xvecy(&res, xvec, rows); - VecU8_append_span(&res, cstr("_mul_scal(A.")); - string_append_vec_field_name(&res, x); - VecU8_append_span(&res, cstr(", B)")); - } - VecU8_append_span(&res, cstr(" };\n}\n\n")); - return res; -} - -NODISCARD VecU8 generate_xmatnm_method_div_by_scal(SpanU8 xmat, SpanU8 xvec, SpanU8 member, int cols, int rows) { - VecU8 res = VecU8_new(); - string_append_xmatnm(&res, xmat, cols, rows); - VecU8_append(&res, ' '); - string_append_xmatnm(&res, xmat, cols, rows); - VecU8_append_span(&res, cstr("_div_by_scal(")); - string_append_xmatnm(&res, xmat, cols, rows); - VecU8_append_span(&res, cstr(" A, ")); - VecU8_append_span(&res, member); - VecU8_append_span(&res, cstr(" B) {\n" SPACE4 "return ")); - string_append_xmatnm(&res, xmat, cols, rows); - VecU8_append_span(&res, cstr("_mul_scal(A, 1/B);\n}\n\n")); - return res; -} - -NODISCARD VecU8 generate_xmatnm_method_mul_xvecn(SpanU8 xmat, SpanU8 xvec, int n, int m) { - VecU8 res = VecU8_new(); - string_append_xvecy(&res, xvec, m); - VecU8_append(&res, ' '); - string_append_xmatnm(&res, xmat, n, m); - VecU8_append_span(&res, cstr("_mul_")); - string_append_xvecy(&res, xvec, n); - VecU8_append_span(&res, cstr("(")); - string_append_xmatnm(&res, xmat, n, m); - VecU8_append_span(&res, cstr(" A, ")); - string_append_xvecy(&res, xvec, n); - VecU8_append_span(&res, cstr(" B) {\n" SPACE4 "return (")); - string_append_xvecy(&res, xvec, m); - VecU8_append_span(&res, cstr("){")); - for (int ci = 0; ci < m; ci++) { - if (ci) - VecU8_append(&res, ','); - VecU8_append_span(&res, cstr("\n" SPACE8)); - for (int x = 0; x < n; x++) { - if (x) - VecU8_append_span(&res, cstr(" + ")); - VecU8_append_span(&res, cstr("A")); - string_append_mat_el_access(&res, x, ci); - VecU8_append_span(&res, cstr(" * B.")); - string_append_vec_field_name(&res, x); - } - } - VecU8_append_span(&res, cstr(" };\n}\n\n")); + VecU8_drop(g_xmatn); return res; } NODISCARD VecU8 generate_xmatnm_method_mul_xmatkn(SpanU8 xmat, int n, int m, int k) { - VecU8 res = VecU8_new(); - string_append_xmatnm(&res, xmat, k, m); - VecU8_append(&res, ' '); - string_append_xmatnm(&res, xmat, n, m); - VecU8_append_span(&res, cstr("_mul_")); - string_append_xmatnm(&res, xmat, k, n); - VecU8_append_span(&res, cstr("(")); - string_append_xmatnm(&res, xmat, n, m); - VecU8_append_span(&res, cstr(" A, ")); - string_append_xmatnm(&res, xmat, k, n); - VecU8_append_span(&res, cstr(" B) {\n" SPACE4 "return (")); - string_append_xmatnm(&res, xmat, k, m); - VecU8_append_span(&res, cstr("){")); + VecU8 g_xmatkm = codegen_name_xmatnm(xmat, k, m); + VecU8 g_xmatnm = codegen_name_xmatnm(xmat, n, m); + VecU8 g_xmatkn = codegen_name_xmatnm(xmat, k, n); + SpanU8 xmatkm = VecU8_to_span(&g_xmatkm); + SpanU8 xmatnm = VecU8_to_span(&g_xmatnm); + SpanU8 xmatkn = VecU8_to_span(&g_xmatkn); + + VecU8 res = VecU8_fmt( + "%s %s_mul_%s(%s A, %s B) {\n" + SPACE4 "return (%s){ ", + xmatkm, xmatnm, xmatkn, xmatnm, xmatkn, xmatkm); for (int x = 0; x < k; x++) { if (x) VecU8_append_span(&res, cstr(",")); VecU8_append_span(&res, cstr("\n" SPACE8)); - string_append_mat_col_definition(&res, x); - VecU8_append_span(&res, cstr("{ ")); + + VecU8_append_vec(&res, VecU8_fmt(".%s = { ", vec_field_name(x))); for (int y = 0; y < m; y++) { if (y) VecU8_append_span(&res, cstr(", ")); for (int z = 0; z < n; z++) { if (z) VecU8_append_span(&res, cstr(" + ")); - VecU8_append_span(&res, cstr("A")); - string_append_mat_el_access(&res, z, y); - VecU8_append_span(&res, cstr(" * B")); - string_append_mat_el_access(&res, x, z); + VecU8_append_vec(&res, VecU8_fmt("A.%s.%s * B.%s.%s", + vec_field_name(z), vec_field_name(y), vec_field_name(x), vec_field_name(z))); } } VecU8_append_span(&res, cstr(" }")); } VecU8_append_span(&res, cstr(" };\n}\n\n")); + + VecU8_drop(g_xmatkm); + VecU8_drop(g_xmatnm); + VecU8_drop(g_xmatkn); return res; } -VecU8 generate_xmatnm_method_transpose(SpanU8 xmat, SpanU8 xvec, SpanU8 member, int n, int m) { +NODISCARD VecU8 generate_xvec234_structs_and_base_methods(SpanU8 xvec, SpanU8 memb) { VecU8 res = VecU8_new(); - string_append_xmatnm(&res, xmat, m, n); - VecU8_append(&res, ' '); - string_append_xmatnm(&res, xmat, n, m); - VecU8_append_span(&res, cstr("_transpose(")); - string_append_xmatnm(&res, xmat, n, m); - VecU8_append_span(&res, cstr(" A) {\n" SPACE4 "return (")); - string_append_xmatnm(&res, xmat, m, n); - VecU8_append_span(&res, cstr("){ ")); - for (int bx = 0; bx < m; bx++) { - if (bx) - VecU8_append_span(&res, cstr(", ")); - string_append_mat_col_definition(&res, bx); - VecU8_append_span(&res, cstr("{ ")); - for (int by = 0; by < n; by++) { - if (by) - VecU8_append_span(&res, cstr(", ")); - VecU8_append_span(&res, cstr("A")); - string_append_mat_el_access(&res, by, bx); - } - VecU8_append_span(&res, cstr(" }")); - } - VecU8_append_span(&res, cstr(" };\n}\n\n")); + for (int n = 2; n <= 4; n++) + VecU8_append_vec(&res, generate_xvecn_struct_and_base_methods(xvec, memb, n)); return res; } -NODISCARD VecU8 generate_xvec234_structs_and_important_methods(SpanU8 xvec, SpanU8 member) { +NODISCARD VecU8 generate_xvec234_structs_and_cool_methods(SpanU8 xvec, SpanU8 memb) { VecU8 res = VecU8_new(); - for (int cc = 2; cc <= 4; cc++) { - VecU8_append_vec(&res, generate_xvecy_struct_definition(xvec, member, cc)); - VecU8_append_vec(&res, generate_xvecy_method_add_xvecy(xvec, member, cc)); - VecU8_append_vec(&res, generate_xvecy_method_minus_xvecy(xvec, member, cc)); - VecU8_append_vec(&res, generate_xvecy_method_minus(xvec, member, cc)); - } - return res; -} - -NODISCARD VecU8 generate_xvec234_structs_and_methods(SpanU8 xvec, SpanU8 member) { - VecU8 res = generate_xvec234_structs_and_important_methods(xvec, member); - for (int cc = 2; cc <= 4; cc++) { - VecU8_append_vec(&res, generate_xvecy_method_mul_scal(xvec, member, cc)); - VecU8_append_vec(&res, generate_xvecy_method_div_by_scal(xvec, member, cc)); - VecU8_append_vec(&res, generate_xvecy_method_mul_xvecy(xvec, member, cc)); - VecU8_append_vec(&res, generate_xvecy_method_dot(xvec, member, cc)); - } + for (int n = 2; n <= 4; n++) + VecU8_append_vec(&res, generate_xvecn_struct_and_cool_methods(xvec, memb, n)); for (int n = 2; n <= 3; n++) - VecU8_append_vec(&res, generate_xvecy_method_and_one(xvec, n)); + VecU8_append_vec(&res, generate_xvecn_method_and_one(xvec, n)); VecU8_append_vec(&res, generate_xvec3_method_cross(xvec)); return res; } -NODISCARD VecU8 generate_xmat234x234_structs_and_methods(SpanU8 xmat, SpanU8 xvec, SpanU8 member, int sizeof_member) { +NODISCARD VecU8 generate_xmat234x234_structs_methods(SpanU8 xmat, SpanU8 xvec, SpanU8 memb, int sizeof_member) { VecU8 res = VecU8_new(); for (int cols = 2; cols <= 4; cols++) { for (int rows = 2; rows <= 4; rows++) { - VecU8_append_vec(&res, generate_xmatnm_structure_definition(xmat, xvec, cols, rows, sizeof_member)); + VecU8_append_vec(&res, generate_xmatnm_struct_and_methods(xmat, xvec, memb, cols, rows, sizeof_member)); } } for (int cols = 2; cols <= 4; cols++) { for (int rows = 2; rows <= 4; rows++) { - VecU8_append_vec(&res, generate_xmatnm_method_new(xmat, xvec, member, cols, rows)); - VecU8_append_vec(&res, generate_xmatnm_method_add_xmatnm(xmat, xvec, member, cols, rows)); - VecU8_append_vec(&res, generate_xmatnm_method_minus_xmatnm(xmat, xvec, member, cols, rows)); - VecU8_append_vec(&res, generate_xmatnm_method_minus(xmat, xvec, member, cols, rows)); - VecU8_append_vec(&res, generate_xmatnm_method_mul_scal(xmat, xvec, member, cols, rows)); - VecU8_append_vec(&res, generate_xmatnm_method_div_by_scal(xmat, xvec, member, cols, rows)); - VecU8_append_vec(&res, generate_xmatnm_method_transpose(xmat, xvec, member, cols, rows)); + VecU8_append_vec(&res, generate_xmatnm_transpose_method(xmat, xvec, memb, cols, rows)); } } for (int n = 2; n <= 4; n++) { - VecU8_append_vec(&res, generate_square_xmatnn_E_definition(xmat, n)); - } - for (int n = 2; n <= 4; n++) { - for (int m = 2; m <= 4; m++) { - VecU8_append_vec(&res, generate_xmatnm_method_mul_xvecn(xmat, xvec, n, m)); - } + VecU8_append_vec(&res, generate_square_xmatn_methods(xmat, xvec, memb, n)); } for (int n = 2; n <= 4; n++) { for (int m = 2; m <= 4; m++) { @@ -612,13 +406,13 @@ NODISCARD VecU8 generate_xmat234x234_structs_and_methods(SpanU8 xmat, SpanU8 xve void generate_geom_header() { VecU8 res = begin_header(cstr("PROTOTYPE1_GEN_L2_GEOM")); VecU8_append_span(&res, cstr("#include \"../../src/l1/core/int_primitives.h\"\n\n")); - VecU8_append_vec(&res, generate_xvec234_structs_and_important_methods(cstr("cvec"), cstr("U8"))); - VecU8_append_vec(&res, generate_xvec234_structs_and_important_methods(cstr("ivec"), cstr("S32"))); + VecU8_append_vec(&res, generate_xvec234_structs_and_base_methods(cstr("cvec"), cstr("U8"))); + VecU8_append_vec(&res, generate_xvec234_structs_and_base_methods(cstr("ivec"), cstr("S32"))); - VecU8_append_vec(&res, generate_xvec234_structs_and_methods(cstr("vec"), cstr("float"))); - VecU8_append_vec(&res, generate_xvec234_structs_and_methods(cstr("dvec"), cstr("double"))); - VecU8_append_vec(&res, generate_xmat234x234_structs_and_methods(cstr("mat"), cstr("vec"), cstr("float"), sizeof(float))); - VecU8_append_vec(&res, generate_xmat234x234_structs_and_methods(cstr("dmat"), cstr("dvec"), cstr("double"), sizeof(double))); + VecU8_append_vec(&res, generate_xvec234_structs_and_cool_methods(cstr("vec"), cstr("float"))); + VecU8_append_vec(&res, generate_xvec234_structs_and_cool_methods(cstr("dvec"), cstr("double"))); + VecU8_append_vec(&res, generate_xmat234x234_structs_methods(cstr("mat"), cstr("vec"), cstr("float"), sizeof(float))); + VecU8_append_vec(&res, generate_xmat234x234_structs_methods(cstr("dmat"), cstr("dvec"), cstr("double"), sizeof(double))); finish_header(res, "l2/geom.h"); } diff --git a/src/l2/codegen/pixel_masses.h b/src/l2/codegen/pixel_masses.h index 5777d64..4ba679c 100644 --- a/src/l2/codegen/pixel_masses.h +++ b/src/l2/codegen/pixel_masses.h @@ -3,180 +3,139 @@ #include "../../l1/codegen/codegen.h" -void VecU8_append_resoftexdatat(VecU8* str, SpanU8 texdatat) { - VecU8_append_span(str, cstr("Result")); - VecU8_append_span(str, texdatat); - VecU8_append_span(str, cstr("OrSpanU8")); -} - /* Used to generate both _at() and _cat() methods */ -VecU8 generate_texture_data_method_at(SpanU8 texdatat, SpanU8 member, bool const_access) { - VecU8 res = VecU8_from_span(member); - VecU8_append_span(&res, cstr("* ")); - VecU8_append_span(&res, texdatat); - VecU8_append_span(&res, const_access ? cstr("_cat") : cstr("_at")); - VecU8_append_span(&res, cstr("(")); - VecU8_append_span(&res, texdatat); - VecU8_append_span(&res, cstr("* self, size_t x, size_t y) {\n" SPACE4 "assert(x < self->width);\n" - SPACE4 "return ")); - VecU8_append_vecoft(&res, member); - VecU8_append_span(&res, const_access ? cstr("_cat") : cstr("_at")); - VecU8_append_span(&res, cstr("(&self->pixels, x + y * self->width);\n}\n\n")); - return res; +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" + "}\n\n", + cstr(const_access ? "const " : ""), memb, tex, cstr(const_access ? "" : "m"), + cstr(const_access ? "const " : ""), tex, pixvec, cstr(const_access ? "" : "m")); } -VecU8 generate_texture_data_struct_and_necc_methods(SpanU8 texdatat, SpanU8 member) { - VecU8 res = VecU8_from_cstr("typedef struct {\n" SPACE4); - VecU8_append_vecoft(&res, member); - VecU8_append_span(&res, cstr(" pixels;\n" SPACE4 "size_t width;\n} ")); - VecU8_append_span(&res, texdatat); - VecU8_append_span(&res, cstr(";\n\n")); +/* `tex` is the type name of texture data type + * `memb` is the type name of pixel data type */ +NODISCARD VecU8 generate_texture_data_struct_and_necc_methods(SpanU8 tex, SpanU8 memb) { + VecU8 g_pixvec = VecU8_fmt("Vec%s", memb); + SpanU8 pixvec = VecU8_to_span(&g_pixvec); + + VecU8 res = VecU8_fmt( + "typedef struct {\n" + SPACE4 "%s pixels;\n" + SPACE4 "size_t width;\n" + "} %s;\n\n", pixvec, tex); /* Method _new() */ - VecU8_append_span(&res, texdatat); - VecU8_append_span(&res, cstr(" ")); - VecU8_append_span(&res, texdatat); - VecU8_append_span(&res, cstr("_new(U32 width, U32 height) {\n" + 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 (")); - VecU8_append_span(&res, texdatat); - VecU8_append_span(&res, cstr("){.pixels = ")); - VecU8_append_vecoft(&res, member); - VecU8_append_span(&res, cstr("_new_zeroinit((size_t)width * height), .width = width};\n}\n\n")); + SPACE4 "return (%s){.pixels = %s_new_zeroinit((size_t)width * height), .width = width};\n" + "}\n\n", tex, tex, tex, pixvec)); /* Method _drop() */ - VecU8_append_span(&res, cstr("void ")); - VecU8_append_span(&res, texdatat); - VecU8_append_span(&res, cstr("_drop(")); - VecU8_append_span(&res, texdatat); - VecU8_append_span(&res, cstr(" self) {\n" SPACE4)); - VecU8_append_vecoft(&res, member); - VecU8_append_span(&res, cstr("_drop(self.pixels);\n}\n\n")); + VecU8_append_vec(&res, VecU8_fmt( + "void %s_drop(%s self) {\n" + SPACE4 "%s_drop(self.pixels);\n" + "}\n\n", tex, tex, pixvec)); /* Method _get_height() */ - VecU8_append_span(&res, cstr("size_t ")); - VecU8_append_span(&res, texdatat); - VecU8_append_span(&res, cstr("_get_height(const ")); - VecU8_append_span(&res, texdatat); - VecU8_append_span(&res, cstr("* self) {\n" SPACE4 "return self->pixels.len / self->width;\n}\n\n")); + VecU8_append_vec(&res, VecU8_fmt( + "size_t %s_get_height(const %s* self) {\n" + SPACE4 "return self->pixels.len / self->width;\n" + "}\n\n", tex, tex)); /* Methods _at and _cat */ - VecU8_append_vec(&res, generate_texture_data_method_at(texdatat, member, false)); - VecU8_append_span(&res, cstr("const ")); - VecU8_append_vec(&res, generate_texture_data_method_at(texdatat, member, true)); + VecU8_append_vec(&res, generate_texture_data_method_at(tex, pixvec, memb, false)); + VecU8_append_vec(&res, generate_texture_data_method_at(tex, pixvec, memb, true)); /* Method _get_size_in_bytes */ - VecU8_append_span(&res, cstr("size_t ")); - VecU8_append_span(&res, texdatat); - VecU8_append_span(&res, cstr("_get_size_in_bytes(const ")); - VecU8_append_span(&res, texdatat); - VecU8_append_span(&res, cstr("* self) {\n" SPACE4 "return self->pixels.len * sizeof(")); - VecU8_append_span(&res, member); - VecU8_append_span(&res, cstr(");\n}\n\n")); + 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" + "}\n\n", tex, tex, memb)); /* Method _to_bitmap_text() - * We use the assumption that bytes in type member are tightly packed */ - VecU8_append_span(&res, cstr("VecU8 ")); - VecU8_append_span(&res, texdatat); - VecU8_append_span(&res, cstr("_to_bitmap_text(const ")); - VecU8_append_span(&res, texdatat); - VecU8_append_span(&res, cstr("* self) {\n" + * We use the assumption that bytes in type member are tightly packed + * Actually, our current method of texture read/write is super inefficient + */ + 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(")); - VecU8_append_span(&res, member); - VecU8_append_span(&res, cstr(");\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_at(&res, 0 + i) = (width >> (8 * i)) & 0xff;\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_at(&res, 4 + i) = (height >> (8 * i)) & 0xff;\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" - "}\n\n")); + "}\n\n", tex, tex, memb)); /* Method _write_to_file * Aborts on failure */ - VecU8_append_span(&res, cstr("void ")); - VecU8_append_span(&res, texdatat); - VecU8_append_span(&res, cstr("_write_to_file(const ")); - VecU8_append_span(&res, texdatat); - VecU8_append_span(&res, cstr("* self, const char* path) {\n" SPACE4 "VecU8 data = ")); - VecU8_append_span(&res, texdatat); - VecU8_append_span(&res, cstr("_to_bitmap_text(self);\n" - SPACE4 "write_whole_file_or_abort(path, VecU8_to_SpanU8(&data));\n" + 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" - "}\n\n")); - /* Result stucture */ - VecU8_append_span(&res, cstr("typedef struct {\n" SPACE4 "Result_variant variant;\n" SPACE4 "union {\n" SPACE8 )); - VecU8_append_span(&res, texdatat); - VecU8_append_span(&res, cstr(" ok;\n" SPACE4 SPACE4 "SpanU8 err;\n" SPACE4 "};\n} ")); - VecU8_append_resoftexdatat(&res, texdatat); - VecU8_append_span(&res, cstr(";\n\n")); + "}\n\n", tex, tex, tex)); + /* Result structure */ + VecU8 g_resoftex = VecU8_fmt("Result%sOrSpanU8", tex); + SpanU8 resoftex = VecU8_to_span(&g_resoftex); + VecU8_append_vec(&res, VecU8_fmt( + "typedef struct {\n" + SPACE4 "Result_variant variant;\n" + SPACE4 "union {\n" + SPACE4 SPACE4 "%s ok;\n" + SPACE4 SPACE4 "SpanU8 err;\n" + SPACE4 "};\n" + "} %s;\n\n", tex, resoftex)); /* Method _from_bitmap_text() - * We assume that bytes are tightly packed in member type - */ - VecU8_append_resoftexdatat(&res, texdatat); - VecU8_append(&res, ' '); - VecU8_append_span(&res, texdatat); - VecU8_append_span(&res, cstr("_from_bitmap_text(SpanU8 text) {\n" + * 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 (")); - VecU8_append_resoftexdatat(&res, texdatat); - VecU8_append_span(&res, cstr("){.variant = Result_Err, " - ".err = cstr(\"No header *crying emoji*\")};\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 (")); - VecU8_append_resoftexdatat(&res, texdatat); - VecU8_append_span(&res, cstr("){.variant = Result_Err, " - ".err = cstr(\"Image is too big\")};\n" - SPACE4 "size_t len = width * height * sizeof(")); - VecU8_append_span(&res, member); - VecU8_append_span(&res, cstr(");\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 (")); - VecU8_append_resoftexdatat(&res, texdatat); - VecU8_append_span(&res, cstr("){.variant = Result_Err, " - ".err = cstr(\"Texture size and file size mismatch\")};\n" SPACE4)); - VecU8_append_span(&res, texdatat); - VecU8_append_span(&res, cstr(" res = ")); - VecU8_append_span(&res, texdatat); - VecU8_append_span(&res, cstr("_new(width, height);\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 (")); - VecU8_append_resoftexdatat(&res, texdatat); - VecU8_append_span(&res, cstr("){.variant = Result_Ok, .ok = res};\n}\n\n")); + SPACE4 "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_span(&res, texdatat); - VecU8_append(&res, ' '); - VecU8_append_span(&res, texdatat); - VecU8_append_span(&res, cstr("_read_from_file(const char* path) {\n" - SPACE4 "VecU8 data = read_whole_file_or_abort(path);\n" SPACE4)); - VecU8_append_resoftexdatat(&res, texdatat); - VecU8_append_span(&res, cstr(" res = ")); - VecU8_append_span(&res, texdatat); - VecU8_append_span(&res, cstr("_from_bitmap_text(VecU8_to_SpanU8(&data));\n" + 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" - SPACE8 "fprintf(stderr, \"Tried loading bitmap texture from file, but encountered decoding error: \");\n" - SPACE8 "SpanU8_fprint(res.err, stderr);\n" - SPACE8 "abortf(\"\\n\");\n" SPACE4 "}\n" SPACE4 "VecU8_drop(data);\n" SPACE4 "return res.ok;\n}\n\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" + "}\n\n", tex, tex, resoftex, tex)); /* Method _is_inside() */ - VecU8_append_span(&res, cstr("bool ")); - VecU8_append_span(&res, texdatat); - VecU8_append_span(&res, cstr("_is_inside(const ")); - VecU8_append_span(&res, texdatat); - VecU8_append_span(&res, cstr("* self, S32 x, S32 y) {\n" - SPACE4 "return x >= 0 && y >= 0 && x < self->width && self->width * y + x < self->pixels.len;\n" - "}\n\n")); + 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" + "}\n\n", tex, tex)); + + VecU8_drop(g_resoftex); + VecU8_drop(g_pixvec); return res; } void generate_pixel_masses_header() { VecU8 res = begin_header(cstr("PROTOTYPE1_GEN_L2_PIXEL_MASSES")); - VecU8_append_span(&res, cstr("#include \"geom.h\"\n\n")); - VecU8_append_span(&res, cstr("#include \"../../src/l1/core/VecSpan_int_primitives.h\"\n\n")); - VecU8_append_span(&res, cstr("#include \"../../src/l1/system/fileio.h\"\n\n")); - /// todo: include generated (by l2/codegen) headers with cvec3,4 Vec + VecU8_append_span(&res, cstr("#include \"../l1/VecAndSpan_int_primitives.h\"\n")); + VecU8_append_span(&res, cstr("#include \"../../src/l1/system/fileio.h\"\n")); + VecU8_append_span(&res, cstr("#include \"VecAndSpan_cvec.h\"\n\n")); VecU8_append_vec(&res, generate_texture_data_struct_and_necc_methods(cstr("TextureDataR8"), cstr("U8"))); VecU8_append_vec(&res, generate_texture_data_struct_and_necc_methods(cstr("TextureDataR8G8B8"), cstr("cvec3"))); VecU8_append_vec(&res, generate_texture_data_struct_and_necc_methods(cstr("TextureDataR8G8B8A8"), cstr("cvec4")));