Saving. During big refactoring. Rewrote l2/codegen/pixel_masses.h and l2/codegen/geom.h

This commit is contained in:
Андреев Григорий 2025-08-16 04:45:31 +03:00
parent 3a062e768b
commit d55592503c
9 changed files with 431 additions and 632 deletions

View File

@ -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,
}));
}

View File

@ -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

View File

@ -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 {

View File

@ -1,4 +1,4 @@
#include "../../../gen/l1/VecAndSpanAndOption_int_primitives.h"
#include "../../../gen/l1/VecAndSpan_int_primitives.h"
int main() {
VecU8 a = VecU8_new();

View File

@ -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() {

View File

@ -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;

View File

@ -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();

View File

@ -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");
}

View File

@ -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<texdatat, SpanU8> 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<texdatat, SpanU8> 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")));