Refactored most of l1 using brand new VecU8_append_fmt method and brand new %r VecU8_fmt specifier
This commit is contained in:
parent
0c41f3dd3e
commit
f99e673d79
@ -2,8 +2,6 @@
|
||||
|
||||
#include "../codegen/codegen.h"
|
||||
|
||||
// todo: rewrite all of this
|
||||
|
||||
SpanU8 vec_field_name(int ci) {
|
||||
assert(0 <= ci && ci < 4);
|
||||
return ci == 0 ? cstr("x") : (ci == 1 ? cstr("y") : (ci == 2 ? cstr("z") : cstr("w")));
|
||||
@ -14,147 +12,137 @@ NODISCARD VecU8 codegen_name_xvecn(SpanU8 xvec, int n) {
|
||||
return VecU8_fmt("%s%c", xvec, '0' + n);
|
||||
}
|
||||
|
||||
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();
|
||||
void codegen_append_xvecn_struct_and_base_methods(VecU8* res, SpanU8 xvec, SpanU8 memb, int n) {
|
||||
VecU8 xvecn = codegen_name_xvecn(xvec, n);
|
||||
/* Structure definition */
|
||||
VecU8_append_span(&res, cstr("typedef struct {\n"));
|
||||
VecU8_append_cstr(res, "typedef struct {\n");
|
||||
for (int ci = 0; ci < n; ci++) {
|
||||
VecU8_append_vec(&res, VecU8_fmt(SPACE "%s %s;\n", memb, vec_field_name(ci)));
|
||||
VecU8_append_fmt(res, SPACE "%s %s;\n", memb, vec_field_name(ci));
|
||||
}
|
||||
VecU8_append_vec(&res, VecU8_fmt("} %s;\n\n", xvecn));
|
||||
VecU8_append_fmt(res, "} %r;\n\n", xvecn);
|
||||
/* xvecn_add_xvecn method */
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"%s %s_add_%s(%s A, %s B) {\n"
|
||||
SPACE "return(%s){ ",
|
||||
xvecn, xvecn, xvecn, xvecn, xvecn, xvecn));
|
||||
VecU8_append_fmt(res,
|
||||
"%r %r_add_%r(%r A, %r B) {\n"
|
||||
SPACE "return(%r){ ",
|
||||
xvecn, xvecn, xvecn, xvecn, xvecn, xvecn);
|
||||
for (int ci = 0; ci < n; ci++) {
|
||||
if (ci)
|
||||
VecU8_append_span(&res, cstr(", "));
|
||||
VecU8_append_vec(&res, VecU8_fmt("A.%s + B.%s", vec_field_name(ci), vec_field_name(ci)));
|
||||
VecU8_append_cstr(res, ", ");
|
||||
VecU8_append_fmt(res, "A.%s + B.%s", vec_field_name(ci), vec_field_name(ci));
|
||||
}
|
||||
VecU8_append_span(&res, cstr(" };\n}\n\n"));
|
||||
VecU8_append_cstr(res, " };\n}\n\n");
|
||||
/* xvecn_minus_xvecn method */
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"%s %s_minus_%s(%s A, %s B) {\n"
|
||||
SPACE "return (%s){ ",
|
||||
VecU8_append_vec(res, VecU8_fmt(
|
||||
"%r %r_minus_%r(%r A, %r B) {\n"
|
||||
SPACE "return (%r){ ",
|
||||
xvecn, xvecn, xvecn, xvecn, xvecn, xvecn));
|
||||
for (int ci = 0; ci < n; ci++) {
|
||||
if (ci)
|
||||
VecU8_append_span(&res, cstr(", "));
|
||||
VecU8_append_vec(&res, VecU8_fmt("A.%s - B.%s", vec_field_name(ci), vec_field_name(ci)));
|
||||
VecU8_append_cstr(res, ", ");
|
||||
VecU8_append_fmt(res, "A.%s - B.%s", vec_field_name(ci), vec_field_name(ci));
|
||||
}
|
||||
VecU8_append_span(&res, cstr(" };\n}\n\n"));
|
||||
VecU8_append_cstr(res, " };\n}\n\n");
|
||||
/* xvecn_minus method */
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"%s %s_minus(%s A) {\n"
|
||||
SPACE "return (%s){ ",
|
||||
xvecn, xvecn, xvecn, xvecn));
|
||||
VecU8_append_fmt(res,
|
||||
"%r %r_minus(%r A) {\n"
|
||||
SPACE "return (%r){ ",
|
||||
xvecn, xvecn, xvecn, xvecn);
|
||||
for (int ci = 0; ci < n; ci++) {
|
||||
if (ci)
|
||||
VecU8_append_span(&res, cstr(", "));
|
||||
VecU8_append_vec(&res, VecU8_fmt("-A.%s", vec_field_name(ci)));
|
||||
VecU8_append_cstr(res, ", ");
|
||||
VecU8_append_fmt(res, "-A.%s", vec_field_name(ci));
|
||||
}
|
||||
VecU8_append_span(&res, cstr(" };\n}\n\n"));
|
||||
VecU8_append_cstr(res, " };\n}\n\n");
|
||||
/* xvecn_mul_scal method */
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"%s %s_mul_scal(%s A, %s B) {\n"
|
||||
SPACE "return (%s) { ",
|
||||
xvecn, xvecn, xvecn, memb, xvecn));
|
||||
VecU8_append_fmt(res,
|
||||
"%r %r_mul_scal(%r A, %s B) {\n"
|
||||
SPACE "return (%r) { ",
|
||||
xvecn, xvecn, xvecn, memb, xvecn);
|
||||
for (int ci = 0; ci < n; ci++) {
|
||||
if (ci)
|
||||
VecU8_append_span(&res, cstr(", "));
|
||||
VecU8_append_vec(&res, VecU8_fmt("A.%s * B", vec_field_name(ci)));
|
||||
VecU8_append_cstr(res, ", ");
|
||||
VecU8_append_fmt(res, "A.%s * B", vec_field_name(ci));
|
||||
}
|
||||
VecU8_append_span(&res, cstr(" };\n}\n\n"));
|
||||
VecU8_append_cstr(res, " };\n}\n\n");
|
||||
|
||||
VecU8_drop(g_xvecn);
|
||||
return res;
|
||||
VecU8_drop(xvecn);
|
||||
}
|
||||
|
||||
NODISCARD VecU8 generate_xvecn_struct_and_cool_methods(SpanU8 xvec, SpanU8 memb, int n, SpanU8 sqrt_func) {
|
||||
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);
|
||||
void codegen_append_xvecn_struct_and_cool_methods(VecU8* res, SpanU8 xvec, SpanU8 memb, int n, SpanU8 sqrt_func) {
|
||||
VecU8 xvecn = codegen_name_xvecn(xvec, n);
|
||||
codegen_append_xvecn_struct_and_base_methods(res, xvec, memb, n);
|
||||
/* xvecn_length method */
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"%s %s_length(%s A) {\n"
|
||||
VecU8_append_fmt(res,
|
||||
"%s %r_length(%r A) {\n"
|
||||
SPACE "return %s(",
|
||||
memb, xvecn, xvecn, sqrt_func));
|
||||
memb, xvecn, xvecn, sqrt_func);
|
||||
for (int i = 0; i < n; i++) {
|
||||
if (i)
|
||||
VecU8_append_span(&res, cstr(" + "));
|
||||
VecU8_append_vec(&res, VecU8_fmt("A.%s * A.%s", vec_field_name(i), vec_field_name(i)));
|
||||
VecU8_append_cstr(res, " + ");
|
||||
VecU8_append_fmt(res, "A.%s * A.%s", vec_field_name(i), vec_field_name(i));
|
||||
}
|
||||
VecU8_append_span(&res, cstr(");\n}\n\n"));
|
||||
VecU8_append_cstr(res, ");\n}\n\n");
|
||||
/* xvecn_div_by_scal method */
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"%s %s_div_by_scal(%s A, %s B) {\n"
|
||||
SPACE "return %s_mul_scal(A, 1/B);\n"
|
||||
"}\n\n", xvecn, xvecn, xvecn, memb, xvecn));
|
||||
VecU8_append_fmt(res,
|
||||
"%r %r_div_by_scal(%r A, %s B) {\n"
|
||||
SPACE "return %r_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"
|
||||
SPACE "return (%s){ ",
|
||||
xvecn, xvecn, xvecn, xvecn, xvecn, xvecn));
|
||||
VecU8_append_fmt(res,
|
||||
"%r %r_mul_%r(%r A, %r B) {\n"
|
||||
SPACE "return (%r){ ",
|
||||
xvecn, xvecn, xvecn, xvecn, xvecn, xvecn);
|
||||
for (int ci = 0; ci < n; ci++) {
|
||||
if (ci)
|
||||
VecU8_append_span(&res, cstr(", "));
|
||||
VecU8_append_vec(&res, VecU8_fmt("A.%s * B.%s", vec_field_name(ci), vec_field_name(ci)));
|
||||
VecU8_append_cstr(res, ", ");
|
||||
VecU8_append_fmt(res, "A.%s * B.%s", vec_field_name(ci), vec_field_name(ci));
|
||||
}
|
||||
VecU8_append_span(&res, cstr(" };\n}\n\n"));
|
||||
VecU8_append_cstr(res, " };\n}\n\n");
|
||||
/* xvecn_dot method */
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"%s %s_dot(%s A, %s B) {\n"
|
||||
VecU8_append_fmt(res,
|
||||
"%s %r_dot(%r A, %r B) {\n"
|
||||
SPACE "return ",
|
||||
memb, xvecn, xvecn, xvecn));
|
||||
memb, xvecn, xvecn, xvecn);
|
||||
for (int i = 0; i < n; i++) {
|
||||
if (i)
|
||||
VecU8_append_span(&res, cstr(" + "));
|
||||
VecU8_append_vec(&res, VecU8_fmt("A.%s * B.%s", vec_field_name(i), vec_field_name(i)));
|
||||
VecU8_append_cstr(res, " + ");
|
||||
VecU8_append_fmt(res, "A.%s * B.%s", vec_field_name(i), vec_field_name(i));
|
||||
}
|
||||
VecU8_append_span(&res, cstr(";\n}\n\n"));
|
||||
VecU8_append_cstr(res, ";\n}\n\n");
|
||||
/* xvecn_normalize method */
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"%s %s_normalize(%s A) {\n"
|
||||
SPACE "return %s_div_by_scal(A, %s_length(A));\n"
|
||||
"}\n\n", xvecn, xvecn, xvecn, xvecn, xvecn));
|
||||
VecU8_append_fmt(res,
|
||||
"%r %r_normalize(%r A) {\n"
|
||||
SPACE "return %r_div_by_scal(A, %r_length(A));\n"
|
||||
"}\n\n", xvecn, xvecn, xvecn, xvecn, xvecn);
|
||||
|
||||
VecU8_drop(g_xvecn);
|
||||
return res;
|
||||
VecU8_drop(xvecn);
|
||||
}
|
||||
|
||||
NODISCARD VecU8 generate_xvecn_method_and_one(SpanU8 xvec, int n) {
|
||||
void codegen_append_xvecn_method_and_one(VecU8* res, 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 xvecn = codegen_name_xvecn(xvec, n);
|
||||
VecU8 xvecn_pp = codegen_name_xvecn(xvec, n + 1);
|
||||
|
||||
VecU8 res = VecU8_fmt(
|
||||
"%s %s_and_one(%s A) {\n"
|
||||
SPACE "return (%s){ ",
|
||||
VecU8_append_fmt(res,
|
||||
"%r %r_and_one(%r A) {\n"
|
||||
SPACE "return (%r){ ",
|
||||
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_fmt(res, "A.%s, ", vec_field_name(i));
|
||||
}
|
||||
VecU8_append_span(&res, cstr("1 };\n}\n\n"));
|
||||
VecU8_append_cstr(res, "1 };\n}\n\n");
|
||||
|
||||
VecU8_drop(g_xvecn_pp);
|
||||
VecU8_drop(g_xvecn);
|
||||
return res;
|
||||
VecU8_drop(xvecn_pp);
|
||||
VecU8_drop(xvecn);
|
||||
}
|
||||
|
||||
NODISCARD VecU8 generate_xvec3_method_cross(SpanU8 xvec) {
|
||||
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"
|
||||
SPACE "return (%s){A.y * B.z - A.z * B.y, -A.x * B.z + A.z * B.x, A.x * B.y - A.y * B.x};\n"
|
||||
void codegen_append_xvec3_method_cross(VecU8* res, SpanU8 xvec) {
|
||||
VecU8 xvec3 = codegen_name_xvecn(xvec, 3);
|
||||
VecU8_append_fmt(res,
|
||||
"%r %r_cross(%r A, %r B) {\n"
|
||||
SPACE "return (%r){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;
|
||||
VecU8_drop(xvec3);
|
||||
}
|
||||
|
||||
NODISCARD VecU8 codegen_name_xmatnm(SpanU8 xmat, int cols, int rows) {
|
||||
@ -164,186 +152,179 @@ NODISCARD VecU8 codegen_name_xmatnm(SpanU8 xmat, int cols, int rows) {
|
||||
return VecU8_fmt("%s%cx%c", xmat, '0' + cols, '0' + rows);
|
||||
}
|
||||
|
||||
NODISCARD VecU8 generate_xmatnm_struct_and_methods(
|
||||
void codegen_append_xmatnm_struct_and_methods(VecU8* res,
|
||||
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();
|
||||
VecU8 xmatnm = codegen_name_xmatnm(xmat, cols, rows);
|
||||
VecU8 xvecm = codegen_name_xvecn(xvec, rows);
|
||||
|
||||
/* Structure xmatnm
|
||||
/* Structure xmatnm. todo: NO, std140 is NOT OUR EVERYTHING. TODO: get rid of padding
|
||||
* With columns padded to 16 bytes (for std140, std140 is our everything) */
|
||||
int sv = (rows * sizeof_member) % 16;
|
||||
VecU8_append_span(&res, cstr("typedef struct {\n"));
|
||||
VecU8_append_cstr(res, "typedef struct {\n");
|
||||
for (int x = 0; x < cols; x++) {
|
||||
VecU8_append_vec(&res, VecU8_fmt(SPACE "%s %s;\n", xvecm, vec_field_name(x)));
|
||||
VecU8_append_fmt(res, SPACE "%r %s;\n", xvecm, vec_field_name(x));
|
||||
if (sv) {
|
||||
VecU8_append_vec(&res, VecU8_fmt(SPACE "char _padding_%u[%u];\n", (U64)x, (U64)(16 - sv)));
|
||||
VecU8_append_fmt(res, SPACE "char _padding_%u[%u];\n", (U64)x, (U64)(16 - sv));
|
||||
}
|
||||
}
|
||||
VecU8_append_vec(&res, VecU8_fmt("} %s;\n\n", xmatnm));
|
||||
VecU8_append_fmt(res, "} %r;\n\n", xmatnm);
|
||||
/* xmatnm_new method */
|
||||
VecU8_append_vec(&res, VecU8_fmt("%s %s_new(", xmatnm, xmatnm));
|
||||
VecU8_append_fmt(res, "%r %r_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_vec(&res, VecU8_fmt("%s %s%s", memb, vec_field_name(x), vec_field_name(y)));
|
||||
VecU8_append_cstr(res, ", ");
|
||||
VecU8_append_fmt(res, "%s %s%s", memb, vec_field_name(x), vec_field_name(y));
|
||||
}
|
||||
}
|
||||
VecU8_append_vec(&res, VecU8_fmt(") {\n" SPACE "return (%s){ ", xmatnm));
|
||||
VecU8_append_fmt(res, ") {\n" SPACE "return (%r){ ", xmatnm);
|
||||
for (int x = 0; x < cols; x++) {
|
||||
if (x)
|
||||
VecU8_append_span(&res, cstr(", "));
|
||||
VecU8_append_vec(&res, VecU8_fmt(".%s = { ", vec_field_name(x)));
|
||||
VecU8_append_cstr(res, ", ");
|
||||
VecU8_append_fmt(res, ".%s = { ", vec_field_name(x));
|
||||
for (int y = 0; y < rows; y++) {
|
||||
if (y)
|
||||
VecU8_append_span(&res, cstr(", "));
|
||||
VecU8_append_vec(&res, VecU8_fmt("%s%s", vec_field_name(x), vec_field_name(y)));
|
||||
VecU8_append_cstr(res, ", ");
|
||||
VecU8_append_fmt(res, "%s%s", vec_field_name(x), vec_field_name(y));
|
||||
}
|
||||
VecU8_append_span(&res, cstr(" }"));
|
||||
VecU8_append_cstr(res, " }");
|
||||
}
|
||||
VecU8_append_span(&res, cstr(" };\n}\n\n"));
|
||||
VecU8_append_cstr(res, " };\n}\n\n");
|
||||
/* xmatnm_add_xmatnm method */
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"%s %s_add_%s(%s A, %s B) {\n"
|
||||
SPACE "return (%s){ ",
|
||||
xmatnm, xmatnm, xmatnm, xmatnm, xmatnm, xmatnm));
|
||||
VecU8_append_fmt(res,
|
||||
"%r %r_add_%r(%r A, %r B) {\n"
|
||||
SPACE "return (%r){ ",
|
||||
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_cstr(res, ", ");
|
||||
VecU8_append_fmt(res, ".%s = %r_add_%r(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"));
|
||||
VecU8_append_cstr(res, " };\n}\n\n");
|
||||
/* xmatnm_minus_xmatnm method */
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"%s %s_minus_%s(%s A, %s B) {\n"
|
||||
SPACE "return (%s){ ",
|
||||
xmatnm, xmatnm, xmatnm, xmatnm, xmatnm, xmatnm));
|
||||
VecU8_append_fmt(res,
|
||||
"%r %r_minus_%r(%r A, %r B) {\n"
|
||||
SPACE "return (%r){ ",
|
||||
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_cstr(res, ", ");
|
||||
VecU8_append_fmt(res, ".%s = %r_minus_%r(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"));
|
||||
VecU8_append_cstr(res, " };\n}\n\n");
|
||||
/* xmatnm_minus method */
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"%s %s_minus(%s A) {\n"
|
||||
SPACE "return (%s){ ",
|
||||
xmatnm, xmatnm, xmatnm, xmatnm));
|
||||
VecU8_append_fmt(res,
|
||||
"%r %r_minus(%r A) {\n"
|
||||
SPACE "return (%r){ ",
|
||||
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_cstr(res, ", ");
|
||||
VecU8_append_fmt(res, ".%s = %r_minus(A.%s)",
|
||||
vec_field_name(x), xvecm, vec_field_name(x));
|
||||
}
|
||||
VecU8_append_span(&res, cstr(" };\n}\n\n"));
|
||||
VecU8_append_cstr(res, " };\n}\n\n");
|
||||
/* xmatnm_mul_scal method */
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"%s %s_mul_scal(%s A, %s B) {\n"
|
||||
SPACE "return (%s){ ",
|
||||
xmatnm, xmatnm, xmatnm, memb, xmatnm));
|
||||
VecU8_append_fmt(res,
|
||||
"%r %r_mul_scal(%r A, %s B) {\n"
|
||||
SPACE "return (%r){ ",
|
||||
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_cstr(res, ", ");
|
||||
VecU8_append_fmt(res, ".%s = %r_mul_scal(A.%s, B)",
|
||||
vec_field_name(x), xvecm, vec_field_name(x));
|
||||
}
|
||||
VecU8_append_span(&res, cstr(" };\n}\n\n"));
|
||||
VecU8_append_cstr(res, " };\n}\n\n");
|
||||
/* xmatnm_div_by_scal method */
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"%s %s_div_by_scal(%s A, %s B) {\n"
|
||||
SPACE "return %s_mul_scal(A, 1/B);\n"
|
||||
"}\n\n", xmatnm, xmatnm, xmatnm, memb, xmatnm));
|
||||
VecU8_append_fmt(res,
|
||||
"%r %r_div_by_scal(%r A, %s B) {\n"
|
||||
SPACE "return %r_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);
|
||||
VecU8 xvecn = codegen_name_xvecn(xvec, cols);
|
||||
|
||||
/* xmatnm_mul_xvecn */
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"%s %s_mul_%s(%s A, %s B) {\n"
|
||||
SPACE "return (%s){ ",
|
||||
xvecm, xmatnm, xvecn, xmatnm, xvecn, xvecm));
|
||||
VecU8_append_fmt(res,
|
||||
"%r %r_mul_%r(%r A, %r B) {\n"
|
||||
SPACE "return (%r){ ",
|
||||
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));
|
||||
VecU8_append(res, ',');
|
||||
VecU8_append_cstr(res, "\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_cstr(res, " + ");
|
||||
VecU8_append_fmt(res, "A.%s.%s * B.%s", vec_field_name(x), vec_field_name(y), vec_field_name(x));
|
||||
}
|
||||
}
|
||||
VecU8_append_span(&res, cstr("\n" SPACE "};\n}\n\n"));
|
||||
VecU8_append_cstr(res, "\n" SPACE "};\n}\n\n");
|
||||
|
||||
VecU8_drop(g_xvecn);
|
||||
VecU8_drop(g_xvecm);
|
||||
VecU8_drop(g_xmatnm);
|
||||
return res;
|
||||
VecU8_drop(xvecn);
|
||||
VecU8_drop(xvecm);
|
||||
VecU8_drop(xmatnm);
|
||||
}
|
||||
|
||||
/* 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"
|
||||
SPACE "return (%s){ ",
|
||||
void codegen_append_xmatnm_transpose_method(VecU8* res, SpanU8 xmat, SpanU8 xvec, SpanU8 memb, int cols, int rows) {
|
||||
VecU8 xmatnm = codegen_name_xmatnm(xmat, cols, rows);
|
||||
VecU8 xmatmn = codegen_name_xmatnm(xmat, rows, cols);
|
||||
|
||||
VecU8_append_fmt(res,
|
||||
"%r %r_transpose(%r A) {\n"
|
||||
SPACE "return (%r){ ",
|
||||
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)));
|
||||
VecU8_append_cstr(res, ", ");
|
||||
VecU8_append_fmt(res, ".%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_cstr(res, ", ");
|
||||
VecU8_append_fmt(res, "A.%s.%s", vec_field_name(by), vec_field_name(bx));
|
||||
}
|
||||
VecU8_append_span(&res, cstr(" }"));
|
||||
VecU8_append_cstr(res, " }");
|
||||
}
|
||||
VecU8_append_span(&res, cstr(" };\n}\n\n"));
|
||||
VecU8_append_cstr(res, " };\n}\n\n");
|
||||
|
||||
VecU8_drop(g_xmatmn);
|
||||
VecU8_drop(g_xmatnm);
|
||||
return res;
|
||||
VecU8_drop(xmatmn);
|
||||
VecU8_drop(xmatnm);
|
||||
}
|
||||
|
||||
NODISCARD VecU8 generate_xmat234_det_method(SpanU8 xmat, SpanU8 xvec, SpanU8 memb){
|
||||
VecU8 res = VecU8_new();
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
void codegen_append_xmat234_det_method(VecU8* res, SpanU8 xmat, SpanU8 xvec, SpanU8 memb){
|
||||
VecU8_append_fmt(res,
|
||||
"%s %s2_det(%s2 a){\n"
|
||||
SPACE "return a.x.x * a.y.y - a.x.y * a.y.x;\n"
|
||||
"}\n\n", memb, xmat, xmat));
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"}\n\n", memb, xmat, xmat);
|
||||
VecU8_append_fmt(res,
|
||||
"%s %s3_det(%s3 a){\n"
|
||||
SPACE "return", memb, xmat, xmat));
|
||||
SPACE "return", memb, xmat, xmat);
|
||||
for (int i = 0; i < 3; i++) {
|
||||
if (i)
|
||||
VecU8_append_span(&res, cstr("\n" SPACE SPACE));
|
||||
VecU8_append_cstr(res, "\n" SPACE SPACE);
|
||||
for (int j = 0; j < 3; j++) {
|
||||
if (j == i)
|
||||
continue;
|
||||
int k = 3 - i - j;
|
||||
assert(k != i && k != j);
|
||||
bool minused = ((i > j) + (j > k) + (i > k)) % 2;
|
||||
VecU8_append_vec(&res, VecU8_fmt(" %c a.x.%s * a.y.%s * a.z.%s",
|
||||
minused ? '-' : '+', vec_field_name(i), vec_field_name(j), vec_field_name(k)));
|
||||
VecU8_append_fmt(res, " %c a.x.%s * a.y.%s * a.z.%s",
|
||||
minused ? '-' : '+', vec_field_name(i), vec_field_name(j), vec_field_name(k));
|
||||
}
|
||||
}
|
||||
VecU8_append_span(&res, cstr(";\n}\n\n"));
|
||||
VecU8_append_cstr(res, ";\n}\n\n");
|
||||
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
VecU8_append_fmt(res,
|
||||
"%s %s4_det(%s4 a){\n"
|
||||
SPACE "return", memb, xmat, xmat));
|
||||
SPACE "return", memb, xmat, xmat);
|
||||
for (int i = 0; i < 4; i++) {
|
||||
if (i)
|
||||
VecU8_append_span(&res, cstr("\n" SPACE SPACE));
|
||||
VecU8_append_cstr(res, "\n" SPACE SPACE);
|
||||
for (int j = 0; j < 4; j++) {
|
||||
if (j == i)
|
||||
continue;
|
||||
@ -353,77 +334,74 @@ NODISCARD VecU8 generate_xmat234_det_method(SpanU8 xmat, SpanU8 xvec, SpanU8 mem
|
||||
int u = 6 - i - j - k;
|
||||
assert(u != i && u != j && u != k);
|
||||
bool minused = ((i > j) + (j > k) + (i > k) + (i > u) + (j > u) + (k > u)) % 2;
|
||||
VecU8_append_vec(&res, VecU8_fmt(" %c a.x.%s * a.y.%s * a.z.%s * a.w.%s",
|
||||
minused ? '-' : '+', vec_field_name(i), vec_field_name(j), vec_field_name(k), vec_field_name(u)));
|
||||
VecU8_append_fmt(res, " %c a.x.%s * a.y.%s * a.z.%s * a.w.%s",
|
||||
minused ? '-' : '+', vec_field_name(i), vec_field_name(j), vec_field_name(k), vec_field_name(u));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
VecU8_append_span(&res, cstr(";\n}\n\n"));
|
||||
return res;
|
||||
VecU8_append_cstr(res, ";\n}\n\n");
|
||||
}
|
||||
|
||||
void codegen_append_square_xmatn_methods(VecU8* res, 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 g_xvecn = codegen_name_xvecn(xvec, n);
|
||||
SpanU8 xvecn = VecU8_to_span(&g_xvecn);
|
||||
VecU8 xmatn = codegen_name_xmatnm(xmat, n, n);
|
||||
VecU8 xvecn = codegen_name_xvecn(xvec, n);
|
||||
|
||||
VecU8_append_vec(res, VecU8_fmt(
|
||||
"const %s %s_E = { ", xmatn, xmatn));
|
||||
VecU8_append_fmt(res,
|
||||
"const %r %r_E = { ", xmatn, xmatn);
|
||||
for (int x = 0; x < n; x++) {
|
||||
if (x)
|
||||
VecU8_append_span(res, cstr(", "));
|
||||
VecU8_append_vec(res, VecU8_fmt(".%s = {", vec_field_name(x)));
|
||||
VecU8_append_cstr(res, ", ");
|
||||
VecU8_append_fmt(res, ".%s = {", vec_field_name(x));
|
||||
for (int y = 0; y < n; y++) {
|
||||
if (y)
|
||||
VecU8_append_span(res, cstr(", "));
|
||||
VecU8_append_cstr(res, ", ");
|
||||
VecU8_append(res, '0' + (x == y));
|
||||
}
|
||||
VecU8_append_span(res, cstr(" }"));
|
||||
VecU8_append_cstr(res, " }");
|
||||
}
|
||||
VecU8_append_span(res, cstr(" };\n\n"));
|
||||
VecU8_append_cstr(res, " };\n\n");
|
||||
|
||||
VecU8_append_vec(res, VecU8_fmt(
|
||||
"%s %s_new_for_proj(%s v){\n" /* xmatn, xmatn, xvecn */
|
||||
SPACE "return (%s){ ", /* xmatn */
|
||||
xmatn, xmatn, xvecn, xmatn));
|
||||
VecU8_append_fmt(res,
|
||||
"%r %r_new_for_proj(%r v){\n" /* xmatn, xmatn, xvecn */
|
||||
SPACE "return (%r){ ", /* xmatn */
|
||||
xmatn, xmatn, xvecn, xmatn);
|
||||
for (int x = 0; x < n; x++) {
|
||||
VecU8_append_span(res, cstr("\n" SPACE SPACE));
|
||||
VecU8_append_vec(res, VecU8_fmt(".%s={", vec_field_name(x)));
|
||||
VecU8_append_cstr(res, "\n" SPACE SPACE);
|
||||
VecU8_append_fmt(res, ".%s={", vec_field_name(x));
|
||||
for (int y = 0; y < n; y++) {
|
||||
if (y)
|
||||
VecU8_append_span(res, cstr(", "));
|
||||
VecU8_append_vec(res, VecU8_fmt("v.%s * v.%s", vec_field_name(x), vec_field_name(y)));
|
||||
VecU8_append_cstr(res, ", ");
|
||||
VecU8_append_fmt(res, "v.%s * v.%s", vec_field_name(x), vec_field_name(y));
|
||||
}
|
||||
VecU8_append_span(res, cstr("},"));
|
||||
VecU8_append_cstr(res, "},");
|
||||
}
|
||||
VecU8_append_span(res, cstr("};\n}\n\n"));
|
||||
VecU8_drop(g_xmatn);
|
||||
VecU8_drop(g_xvecn);
|
||||
VecU8_append_cstr(res, "};\n}\n\n");
|
||||
VecU8_drop(xmatn);
|
||||
VecU8_drop(xvecn);
|
||||
}
|
||||
|
||||
NODISCARD VecU8 generate_xmat_inverse_methods(SpanU8 xmat, SpanU8 xvec, SpanU8 memb){
|
||||
VecU8 res = VecU8_fmt("%s4 %s4_inverse(%s4 A) {\n", xmat, xmat, xmat);
|
||||
VecU8_append_vec(&res, VecU8_fmt(SPACE "%s m2[6][6] = {\n", memb));
|
||||
void codegen_append_xmat_inverse_methods(VecU8* res, SpanU8 xmat, SpanU8 xvec, SpanU8 memb){
|
||||
VecU8_append_fmt(res, "%s4 %s4_inverse(%s4 A) {\n", xmat, xmat, xmat);
|
||||
VecU8_append_fmt(res, SPACE "%s m2[6][6] = {\n", memb);
|
||||
SpanU8 first_of_pair[6] = {cstr("x"), cstr("x"), cstr("x"), cstr("y"), cstr("y"), cstr("z")};
|
||||
SpanU8 second_of_pair[6] = {cstr("y"), cstr("z"), cstr("w"), cstr("z"), cstr("w"), cstr("w")};
|
||||
for (int w_col = 0; w_col < 6; w_col++) {
|
||||
VecU8_append_span(&res, cstr(SPACE SPACE "{ "));
|
||||
VecU8_append_cstr(res, SPACE SPACE "{ ");
|
||||
for (int w_row = 0; w_row < 6; w_row++) {
|
||||
if (w_row)
|
||||
VecU8_append_span(&res, cstr(", "));
|
||||
VecU8_append_cstr(res, ", ");
|
||||
/* first first = A second first = B
|
||||
* first second = C second second = D
|
||||
* A * D - B * C */
|
||||
VecU8_append_vec(&res, VecU8_fmt("A.%s.%s * A.%s.%s - A.%s.%s * A.%s.%s",
|
||||
VecU8_append_fmt(res, "A.%s.%s * A.%s.%s - A.%s.%s * A.%s.%s",
|
||||
first_of_pair[w_col], first_of_pair[w_row], second_of_pair[w_col], second_of_pair[w_row],
|
||||
second_of_pair[w_col], first_of_pair[w_row], first_of_pair[w_col], second_of_pair[w_row]
|
||||
));
|
||||
);
|
||||
}
|
||||
VecU8_append_span(&res, cstr(" },\n"));
|
||||
VecU8_append_cstr(res, " },\n");
|
||||
}
|
||||
VecU8_append_span(&res, cstr(SPACE "};\n"));
|
||||
VecU8_append_cstr(res, SPACE "};\n");
|
||||
|
||||
U64 a0_contr[4] = {5, 5, 4, 3};
|
||||
U64 a1_contr[4] = {4, 2, 2, 1};
|
||||
@ -431,160 +409,152 @@ NODISCARD VecU8 generate_xmat_inverse_methods(SpanU8 xmat, SpanU8 xvec, SpanU8 m
|
||||
SpanU8 a0[4] = {cstr("y"), cstr("x"), cstr("x"), cstr("x")};
|
||||
SpanU8 a1[4] = {cstr("z"), cstr("z"), cstr("y"), cstr("y")};
|
||||
SpanU8 a2[4] = {cstr("w"), cstr("w"), cstr("w"), cstr("z")};
|
||||
VecU8_append_vec(&res, VecU8_fmt(SPACE "%s m3[4][4] = {\n", memb));
|
||||
VecU8_append_fmt(res, SPACE "%s m3[4][4] = {\n", memb);
|
||||
for (int no_col = 0; no_col < 4; no_col++) {
|
||||
SpanU8 walking_column = a0[no_col];
|
||||
U64 minor_col_pair = a0_contr[no_col];
|
||||
VecU8_append_span(&res, cstr(SPACE SPACE "{ "));
|
||||
VecU8_append_cstr(res, SPACE SPACE "{ ");
|
||||
for (int no_row = 0; no_row < 4; no_row++) {
|
||||
if (no_row)
|
||||
VecU8_append_span(&res, cstr(", \n" SPACE SPACE));
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
VecU8_append_cstr(res, ", \n" SPACE SPACE);
|
||||
VecU8_append_fmt(res,
|
||||
"A.%s.%s * m2[%u][%u] - A.%s.%s * m2[%u][%u] + A.%s.%s * m2[%u][%u]",
|
||||
walking_column, a0[no_row], minor_col_pair, a0_contr[no_row],
|
||||
walking_column, a1[no_row], minor_col_pair, a1_contr[no_row],
|
||||
walking_column, a2[no_row], minor_col_pair, a2_contr[no_row]));
|
||||
walking_column, a2[no_row], minor_col_pair, a2_contr[no_row]);
|
||||
}
|
||||
VecU8_append_span(&res, cstr(" },\n"));
|
||||
VecU8_append_cstr(res, " },\n");
|
||||
}
|
||||
VecU8_append_span(&res, cstr(SPACE "};\n"));
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
VecU8_append_cstr(res, SPACE "};\n");
|
||||
VecU8_append_fmt(res,
|
||||
SPACE "%s d = 1 / (A.x.x * m3[0][0] - A.x.y * m3[0][1] + A.x.z * m3[0][2] - A.x.w * m3[0][3]);\n"
|
||||
SPACE "return (mat4){ "
|
||||
, memb));
|
||||
SPACE "return (mat4){ ",
|
||||
memb);
|
||||
for (U64 i = 0; i < 4; i++) {
|
||||
if (i)
|
||||
VecU8_append_span(&res, cstr(",\n" SPACE SPACE ));
|
||||
VecU8_append_vec(&res, VecU8_fmt(".%s={ ", vec_field_name((int)i)));
|
||||
VecU8_append_cstr(res, ",\n" SPACE SPACE );
|
||||
VecU8_append_fmt(res, ".%s={ ", vec_field_name((int)i));
|
||||
for (U64 j = 0; j < 4; j++) {
|
||||
if (j)
|
||||
VecU8_append_span(&res, cstr(", "));
|
||||
VecU8_append_vec(&res, VecU8_fmt("%sm3[%u][%u] * d",
|
||||
(i + j) % 2 ? cstr("-") : cstr(""), j, i));
|
||||
VecU8_append_cstr(res,", ");
|
||||
VecU8_append_fmt(res, "%sm3[%u][%u] * d",
|
||||
(i + j) % 2 ? cstr("-") : cstr(""), j, i);
|
||||
}
|
||||
VecU8_append_span(&res, cstr(" }"));
|
||||
VecU8_append_cstr(res, " }");
|
||||
}
|
||||
VecU8_append_span(&res, cstr(" };\n}\n\n"));
|
||||
VecU8_append_cstr(res, " };\n}\n\n");
|
||||
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
VecU8_append_fmt(res,
|
||||
"%s2 %s2_inverse(%s2 A) {\n" /* xmat, xmat, xmat */
|
||||
SPACE "%s d = 1 / (A.x.x * A.y.y - A.y.x * A.x.y);\n" /* memb */
|
||||
SPACE "return (%s2){ .x = { A.y.y * d, -A.x.y * d}, .y = {-A.y.x * d, A.x.x * d}};\n" /* xmat */
|
||||
"}\n\n", xmat, xmat, xmat, memb, xmat));
|
||||
"}\n\n", xmat, xmat, xmat, memb, xmat);
|
||||
|
||||
/* No inverse for mat3 yet :( */
|
||||
// VecU8_append_vec(&res, VecU8_fmt( "%s3 %s3_inverse(%s3 A) {\n", xmat, xmat, xmat));
|
||||
// VecU8_append_vec(&res, VecU8_fmt(SPACE "%s d = 1 / ("));
|
||||
// VecU8_append_span(&res, cstr("}\n"));
|
||||
return res;
|
||||
}
|
||||
|
||||
NODISCARD VecU8 generate_xmatnm_method_mul_xmatkn(SpanU8 xmat, int n, int m, int k) {
|
||||
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);
|
||||
void codegen_append_xmatnm_method_mul_xmatkn(VecU8* res, SpanU8 xmat, int n, int m, int k) {
|
||||
VecU8 xmatkm = codegen_name_xmatnm(xmat, k, m);
|
||||
VecU8 xmatnm = codegen_name_xmatnm(xmat, n, m);
|
||||
VecU8 xmatkn = codegen_name_xmatnm(xmat, k, n);
|
||||
|
||||
VecU8 res = VecU8_fmt(
|
||||
"%s %s_mul_%s(%s A, %s B) {\n"
|
||||
SPACE "return (%s){ ",
|
||||
VecU8_append_fmt(res,
|
||||
"%r %r_mul_%r(%r A, %r B) {\n"
|
||||
SPACE "return (%r){ ",
|
||||
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));
|
||||
VecU8_append_cstr(res, ",");
|
||||
VecU8_append_cstr(res, "\n" SPACE8);
|
||||
|
||||
VecU8_append_vec(&res, VecU8_fmt(".%s = { ", vec_field_name(x)));
|
||||
VecU8_append_fmt(res, ".%s = { ", vec_field_name(x));
|
||||
for (int y = 0; y < m; y++) {
|
||||
if (y)
|
||||
VecU8_append_span(&res, cstr(", "));
|
||||
VecU8_append_cstr(res, ", ");
|
||||
for (int z = 0; z < n; z++) {
|
||||
if (z)
|
||||
VecU8_append_span(&res, cstr(" + "));
|
||||
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_cstr(res, " + ");
|
||||
VecU8_append_fmt(res, "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_cstr(res, " }");
|
||||
}
|
||||
VecU8_append_span(&res, cstr(" };\n}\n\n"));
|
||||
VecU8_append_cstr(res, " };\n}\n\n");
|
||||
|
||||
VecU8_drop(g_xmatkm);
|
||||
VecU8_drop(g_xmatnm);
|
||||
VecU8_drop(g_xmatkn);
|
||||
return res;
|
||||
VecU8_drop(xmatkm);
|
||||
VecU8_drop(xmatnm);
|
||||
VecU8_drop(xmatkn);
|
||||
}
|
||||
|
||||
NODISCARD VecU8 generate_xvec234_structs_and_base_methods(SpanU8 xvec, SpanU8 memb) {
|
||||
VecU8 res = VecU8_new();
|
||||
void codegen_append_xvec234_structs_and_base_methods(VecU8* res, SpanU8 xvec, SpanU8 memb) {
|
||||
for (int n = 2; n <= 4; n++)
|
||||
VecU8_append_vec(&res, generate_xvecn_struct_and_base_methods(xvec, memb, n));
|
||||
return res;
|
||||
codegen_append_xvecn_struct_and_base_methods(res, xvec, memb, n);
|
||||
}
|
||||
|
||||
NODISCARD VecU8 generate_xvec234_structs_and_cool_methods(SpanU8 xvec, SpanU8 memb, SpanU8 sqrt_func) {
|
||||
VecU8 res = VecU8_new();
|
||||
void codegen_append_xvec234_structs_and_cool_methods(VecU8* res, SpanU8 xvec, SpanU8 memb, SpanU8 sqrt_func) {
|
||||
for (int n = 2; n <= 4; n++)
|
||||
VecU8_append_vec(&res, generate_xvecn_struct_and_cool_methods(xvec, memb, n, sqrt_func));
|
||||
codegen_append_xvecn_struct_and_cool_methods(res, xvec, memb, n, sqrt_func);
|
||||
for (int n = 2; n <= 3; n++)
|
||||
VecU8_append_vec(&res, generate_xvecn_method_and_one(xvec, n));
|
||||
VecU8_append_vec(&res, generate_xvec3_method_cross(xvec));
|
||||
return res;
|
||||
codegen_append_xvecn_method_and_one(res, xvec, n);
|
||||
codegen_append_xvec3_method_cross(res, xvec);
|
||||
}
|
||||
|
||||
NODISCARD VecU8 generate_xmat234x234_structs_and_base_methods(SpanU8 xmat, SpanU8 xvec, SpanU8 memb, int sizeof_member){
|
||||
VecU8 res = VecU8_new();
|
||||
void codegen_append_xmat234x234_structs_and_base_methods(VecU8* res,
|
||||
SpanU8 xmat, SpanU8 xvec, SpanU8 memb, int sizeof_member
|
||||
){
|
||||
for (int cols = 2; cols <= 4; cols++) {
|
||||
for (int rows = 2; rows <= 4; rows++) {
|
||||
VecU8_append_vec(&res, generate_xmatnm_struct_and_methods(xmat, xvec, memb, cols, rows, sizeof_member));
|
||||
codegen_append_xmatnm_struct_and_methods(res, 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_transpose_method(xmat, xvec, memb, cols, rows));
|
||||
codegen_append_xmatnm_transpose_method(res, xmat, xvec, memb, cols, rows);
|
||||
}
|
||||
}
|
||||
for (int n = 2; n <= 4; n++) {
|
||||
codegen_append_square_xmatn_methods(&res, xmat, xvec, memb, n);
|
||||
codegen_append_square_xmatn_methods(res, xmat, xvec, memb, n);
|
||||
}
|
||||
for (int n = 2; n <= 4; n++) {
|
||||
for (int m = 2; m <= 4; m++) {
|
||||
for (int k = 2; k <= 4; k++) {
|
||||
VecU8_append_vec(&res, generate_xmatnm_method_mul_xmatkn(xmat, n, m, k));
|
||||
codegen_append_xmatnm_method_mul_xmatkn(res, xmat, n, m, k);
|
||||
}
|
||||
}
|
||||
}
|
||||
VecU8_append_vec(&res, generate_xmat234_det_method(xmat, xvec, memb));
|
||||
return res;
|
||||
codegen_append_xmat234_det_method(res, xmat, xvec, memb);
|
||||
}
|
||||
|
||||
NODISCARD VecU8 generate_xmat234x234_structs_and_cool_methods(SpanU8 xmat, SpanU8 xvec, SpanU8 memb, int sizeof_member){
|
||||
VecU8 res = VecU8_new();
|
||||
VecU8_append_vec(&res, generate_xmat234x234_structs_and_base_methods(xmat, xvec, memb, sizeof_member));
|
||||
VecU8_append_vec(&res, generate_xmat_inverse_methods(xmat, xvec, memb));
|
||||
return res;
|
||||
void codegen_append_xmat234x234_structs_and_cool_methods(VecU8* res,
|
||||
SpanU8 xmat, SpanU8 xvec, SpanU8 memb, int sizeof_member
|
||||
){
|
||||
codegen_append_xmat234x234_structs_and_base_methods(res, xmat, xvec, memb, sizeof_member);
|
||||
codegen_append_xmat_inverse_methods(res, xmat, xvec, memb);
|
||||
}
|
||||
|
||||
void generate_geom_header() {
|
||||
GeneratedHeader res = begin_header(cstr("l1/geom.h"));
|
||||
VecU8_append_span(&res.result, cstr("#include \"../../src/l1/core/int_primitives.h\"\n"));
|
||||
VecU8_append_span(&res.result, cstr("#include <math.h>\n\n"));
|
||||
VecU8_append_vec(&res.result, generate_xvec234_structs_and_base_methods(cstr("cvec"), cstr("U8")));
|
||||
VecU8_append_vec(&res.result, generate_xvec234_structs_and_base_methods(cstr("uvec"), cstr("U32")));
|
||||
VecU8_append_vec(&res.result, generate_xvec234_structs_and_base_methods(cstr("s64vec"), cstr("S64")));
|
||||
VecU8_append_vec(&res.result, generate_xvec234_structs_and_base_methods(cstr("ivec"), cstr("S32")));
|
||||
codegen_append_xvec234_structs_and_base_methods(&res.result, cstr("cvec"), cstr("U8"));
|
||||
codegen_append_xvec234_structs_and_base_methods(&res.result, cstr("uvec"), cstr("U32"));
|
||||
codegen_append_xvec234_structs_and_base_methods(&res.result, cstr("s64vec"), cstr("S64"));
|
||||
codegen_append_xvec234_structs_and_base_methods(&res.result, cstr("ivec"), cstr("S32"));
|
||||
for (U64 i = 2; i <= 4; i++) {
|
||||
VecU8_append_vec(&res.result, VecU8_fmt("typedef ivec%u s32vec%u;\n", i, i));
|
||||
}
|
||||
VecU8_append_span(&res.result, cstr("\n"));
|
||||
|
||||
VecU8_append_vec(&res.result, generate_xvec234_structs_and_cool_methods(cstr("vec"), cstr("float"), cstr("sqrtf")));
|
||||
VecU8_append_vec(&res.result, generate_xvec234_structs_and_cool_methods(cstr("dvec"), cstr("double"), cstr("sqrt")));
|
||||
codegen_append_xvec234_structs_and_cool_methods(&res.result, cstr("vec"), cstr("float"), cstr("sqrtf"));
|
||||
codegen_append_xvec234_structs_and_cool_methods(&res.result, cstr("dvec"), cstr("double"), cstr("sqrt"));
|
||||
|
||||
// todo: remove padding from matrix structure. VERY IMPORTANT!!! Add padding on the fly when transferring to vulkan
|
||||
VecU8_append_vec(&res.result, generate_xmat234x234_structs_and_cool_methods(cstr("mat"), cstr("vec"), cstr("float"), sizeof(float)));
|
||||
VecU8_append_vec(&res.result, generate_xmat234x234_structs_and_base_methods(cstr("s64mat"), cstr("s64vec"), cstr("S64"), sizeof(S64)));
|
||||
codegen_append_xmat234x234_structs_and_cool_methods(&res.result, cstr("mat"), cstr("vec"), cstr("float"), sizeof(float));
|
||||
codegen_append_xmat234x234_structs_and_base_methods(&res.result, cstr("s64mat"), cstr("s64vec"), cstr("S64"), sizeof(S64));
|
||||
|
||||
finish_header(res);
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
// todo: refactor (with VecU8_append_fmt)
|
||||
#include "../../codegen/util_template_inst.h"
|
||||
|
||||
typedef struct {
|
||||
|
||||
@ -4,57 +4,57 @@
|
||||
#include "../codegen/util_template_inst.h"
|
||||
|
||||
/* Used to generate both _at() and _cat() methods */
|
||||
NODISCARD VecU8 generate_texture_data_method_at(SpanU8 tex, SpanU8 pixvec, SpanU8 memb, bool const_access) {
|
||||
return VecU8_fmt(
|
||||
void codegen_append_texture_data_method_at(VecU8* res, SpanU8 tex, SpanU8 memb, bool const_access) {
|
||||
VecU8_append_fmt(res,
|
||||
"%s%s* %s_%sat(%s%s* self, size_t x, size_t y) {\n"
|
||||
SPACE "assert(x < self->width);\n"
|
||||
SPACE "return %s_%sat(&self->pixels, x + y * self->width);\n"
|
||||
SPACE "return Vec%s_%sat(&self->pixels, x + y * self->width);\n"
|
||||
"}\n\n",
|
||||
const_access ? cstr("const ") : cstr(""), memb, tex, const_access ? cstr("") : cstr("m"),
|
||||
const_access ? cstr("const ") : cstr(""), tex, pixvec, const_access ? cstr("") : cstr("m"));
|
||||
const_access ? cstr("const ") : cstr(""), tex, memb, const_access ? cstr("") : cstr("m"));
|
||||
}
|
||||
|
||||
/* `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, SpanU8 luminosity_formula) {
|
||||
VecU8 g_pixvec = VecU8_fmt("Vec%s", memb);
|
||||
SpanU8 pixvec = VecU8_to_span(&g_pixvec);
|
||||
VecU8 res = VecU8_fmt(
|
||||
void codegen_append_texture_data_struct_and_necc_methods(VecU8* res,
|
||||
SpanU8 tex, SpanU8 memb, SpanU8 luminosity_formula
|
||||
) {
|
||||
VecU8_append_fmt(res,
|
||||
"typedef struct {\n"
|
||||
SPACE "%s pixels;\n"
|
||||
SPACE "Vec%s pixels;\n"
|
||||
SPACE "size_t width;\n"
|
||||
SPACE "size_t height;\n"
|
||||
"} %s;\n\n", pixvec, tex);
|
||||
"} %s;\n\n", memb, tex);
|
||||
/* Method _new() */
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
VecU8_append_fmt(res,
|
||||
"%s %s_new(U32 width, U32 height) {\n"
|
||||
SPACE "assert(width == 0 || height == 0 ||\n"
|
||||
SPACE SPACE "!(SIZE_MAX / width / height < 100 || UINT32_MAX / width < 10 || UINT32_MAX / height < 10));\n"
|
||||
SPACE "return (%s){.pixels = %s_new_zeroinit((size_t)width * height), .width = width, .height = height};\n"
|
||||
"}\n\n", tex, tex, tex, pixvec));
|
||||
SPACE "return (%s){.pixels = Vec%s_new_zeroinit((size_t)width * height), .width = width, .height = height};\n"
|
||||
"}\n\n", tex, tex, tex, memb);
|
||||
/* Method _drop() */
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
VecU8_append_fmt(res,
|
||||
"void %s_drop(%s self) {\n"
|
||||
SPACE "%s_drop(self.pixels);\n"
|
||||
"}\n\n", tex, tex, pixvec));
|
||||
SPACE "Vec%s_drop(self.pixels);\n"
|
||||
"}\n\n", tex, tex, memb);
|
||||
/* Methods _at and _cat */
|
||||
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));
|
||||
codegen_append_texture_data_method_at(res, tex, memb, false);
|
||||
codegen_append_texture_data_method_at(res, tex, memb, true);
|
||||
/* Method _get_size_in_bytes */
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
VecU8_append_fmt(res,
|
||||
"size_t %s_get_size_in_bytes(const %s* self) {\n"
|
||||
SPACE "return self->pixels.len * sizeof(%s);\n"
|
||||
"}\n\n", tex, tex, memb));
|
||||
"}\n\n", tex, tex, memb);
|
||||
/* Result<tex, VecU8> structure */
|
||||
VecU8_append_vec(&res, generate_result_template_inst(tex, cstr("VecU8"), false, false));
|
||||
VecU8_append_vec(res, generate_result_template_inst(tex, cstr("VecU8"), false, false));
|
||||
/* Method _from_bitmap_text()
|
||||
/* Method _is_inside() */
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
VecU8_append_fmt(res,
|
||||
"bool %s_is_inside(const %s* self, S32 x, S32 y) {\n"
|
||||
SPACE "return x >= 0 && y >= 0 && x < (S32)self->width && self->width * y + x < self->pixels.len;\n"
|
||||
"}\n\n", tex, tex));
|
||||
"}\n\n", tex, tex);
|
||||
/* Method _print() */
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
VecU8_append_fmt(res,
|
||||
"void %s_print(const %s* self) {\n" /* tex, tex */
|
||||
SPACE "U64 width = self->width;\n"
|
||||
SPACE "U64 height = self->height;\n"
|
||||
@ -80,10 +80,7 @@ NODISCARD VecU8 generate_texture_data_struct_and_necc_methods(SpanU8 tex, SpanU8
|
||||
SPACE SPACE "}\n"
|
||||
SPACE SPACE "putc('\\n', stdout);\n"
|
||||
SPACE "}\n"
|
||||
"}\n\n", tex, tex, memb, tex, luminosity_formula));
|
||||
|
||||
VecU8_drop(g_pixvec);
|
||||
return res;
|
||||
"}\n\n", tex, tex, memb, tex, luminosity_formula);
|
||||
}
|
||||
|
||||
void generate_pixel_masses_header() {
|
||||
@ -92,11 +89,13 @@ void generate_pixel_masses_header() {
|
||||
VecU8_append_span(&res.result, cstr("#include \"../../src/l1/system/fileio.h\"\n"));
|
||||
VecU8_append_span(&res.result, cstr("#include \"VecAndSpan_cvec3.h\"\n"));
|
||||
VecU8_append_span(&res.result, cstr("#include \"VecAndSpan_cvec4.h\"\n\n"));
|
||||
VecU8_append_vec(&res.result, generate_texture_data_struct_and_necc_methods(cstr("TextureDataR8"), cstr("U8"),
|
||||
cstr("(float)pix / 255")));
|
||||
VecU8_append_vec(&res.result, generate_texture_data_struct_and_necc_methods(cstr("TextureDataR8G8B8"), cstr("cvec3"),
|
||||
cstr("(float)pix.x / 255 * 0.21f + (float)pix.y / 255 * 0.71f + (float)pix.z / 255 * 0.08f")));
|
||||
VecU8_append_vec(&res.result, generate_texture_data_struct_and_necc_methods(cstr("TextureDataR8G8B8A8"), cstr("cvec4"),
|
||||
cstr("(float)pix.x / 255 * 0.21f + (float)pix.y / 255 * 0.71f + (float)pix.z / 255 * 0.08f")));
|
||||
codegen_append_texture_data_struct_and_necc_methods(&res.result,
|
||||
cstr("TextureDataR8"), cstr("U8"), cstr("(float)pix / 255"));
|
||||
codegen_append_texture_data_struct_and_necc_methods(&res.result,
|
||||
cstr("TextureDataR8G8B8"), cstr("cvec3"),
|
||||
cstr("(float)pix.x / 255 * 0.21f + (float)pix.y / 255 * 0.71f + (float)pix.z / 255 * 0.08f"));
|
||||
codegen_append_texture_data_struct_and_necc_methods(&res.result,
|
||||
cstr("TextureDataR8G8B8A8"), cstr("cvec4"),
|
||||
cstr("(float)pix.x / 255 * 0.21f + (float)pix.y / 255 * 0.71f + (float)pix.z / 255 * 0.08f"));
|
||||
finish_header(res);
|
||||
}
|
||||
|
||||
@ -15,21 +15,21 @@ NODISCARD VecU8 generate_List_template_instantiation(list_instantiation_op op, b
|
||||
|
||||
VecU8 res = VecU8_new();
|
||||
if (gen_node_declaration) {
|
||||
VecU8_append_vec(&res, VecU8_fmt("typedef struct ListNode%s ListNode%s;\n", op.T, op.T));
|
||||
VecU8_append_fmt(&res, "typedef struct ListNode%s ListNode%s;\n", op.T, op.T);
|
||||
}
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
VecU8_append_fmt(&res,
|
||||
"struct ListNode%s {\n" /* op.T */
|
||||
SPACE "ListNode%s* prev;\n" /* op.T */
|
||||
SPACE "ListNode%s* next;\n" /* op.T */
|
||||
SPACE "%s el;\n" /* op.T */
|
||||
"};\n\n", op.T, op.T, op.T, op.T));
|
||||
"};\n\n", op.T, op.T, op.T, op.T);
|
||||
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
VecU8_append_fmt(&res,
|
||||
"typedef struct {\n"
|
||||
SPACE "ListNode%s* first;\n" /* op.T */
|
||||
"} List%s;\n\n", /* op.T */
|
||||
op.T, op.T));
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
op.T, op.T);
|
||||
VecU8_append_fmt(&res,
|
||||
"#define List%s_new() {0}\n\n" /* op.T */
|
||||
"void List%s_drop(List%s self) {\n" /* op.T, op.T */
|
||||
SPACE "ListNode%s* cur = self.first;\n" /* op.T */
|
||||
@ -41,8 +41,8 @@ NODISCARD VecU8 generate_List_template_instantiation(list_instantiation_op op, b
|
||||
SPACE "}\n"
|
||||
"}\n\n",
|
||||
op.T, op.T, op.T, op.T, op.T,
|
||||
op.t_primitive ? vcstr("") : VecU8_fmt(SPACE SPACE "%s_drop(cur->el);\n", op.T)));
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
op.t_primitive ? vcstr("") : VecU8_fmt(SPACE SPACE "%s_drop(cur->el);\n", op.T));
|
||||
VecU8_append_fmt(&res,
|
||||
"ListNode%s* List%s_insert(List%s* self, %s el) {\n" /* op.T, op.T, op.T, op.T */
|
||||
SPACE "ListNode%s* new_node = safe_malloc(sizeof(ListNode%s));\n" /* op.T, op.T */
|
||||
SPACE "new_node->prev = NULL;\n"
|
||||
@ -52,16 +52,16 @@ NODISCARD VecU8 generate_List_template_instantiation(list_instantiation_op op, b
|
||||
SPACE SPACE "self->first->prev = new_node;\n"
|
||||
SPACE "self->first = new_node;\n"
|
||||
SPACE "return new_node;\n"
|
||||
"}\n\n", op.T, op.T, op.T, op.T, op.T, op.T));
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"}\n\n", op.T, op.T, op.T, op.T, op.T, op.T);
|
||||
VecU8_append_fmt(&res,
|
||||
"void List%s_insert_node(List%s* self, ListNode%s* new_node) {\n" /* op.T, op.T, op.T */
|
||||
SPACE "new_node->prev = NULL;\n"
|
||||
SPACE "new_node->next = self->first;\n"
|
||||
SPACE "if (self->first)\n"
|
||||
SPACE SPACE "self->first->prev = new_node;\n"
|
||||
SPACE "self->first = new_node;\n"
|
||||
"}\n\n", op.T, op.T, op.T));
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"}\n\n", op.T, op.T, op.T);
|
||||
VecU8_append_fmt(&res,
|
||||
"void List%s_erase_by_it(List%s* self, ListNode%s* it) {\n" /* op.T, op.T, op.T */
|
||||
SPACE "if (it->prev)\n"
|
||||
SPACE SPACE "it->prev->next = it->next;\n"
|
||||
@ -73,8 +73,8 @@ NODISCARD VecU8 generate_List_template_instantiation(list_instantiation_op op, b
|
||||
SPACE "free(it);\n"
|
||||
"}\n\n",
|
||||
op.T, op.T, op.T,
|
||||
op.t_primitive ? vcstr("") : VecU8_fmt(SPACE "%s_drop(it->el);\n", op.T)));
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
op.t_primitive ? vcstr("") : VecU8_fmt(SPACE "%s_drop(it->el);\n", op.T));
|
||||
VecU8_append_fmt(&res,
|
||||
"void List%s_sink(List%s* self) {\n" /* op.T, op.T */
|
||||
SPACE "ListNode%s* cur = self->first;\n" /* op.T */
|
||||
SPACE "while (cur){\n"
|
||||
@ -86,7 +86,7 @@ NODISCARD VecU8 generate_List_template_instantiation(list_instantiation_op op, b
|
||||
SPACE "self->first = NULL;\n"
|
||||
"}\n\n",
|
||||
op.T, op.T, op.T, op.T,
|
||||
op.t_primitive ? vcstr("") : VecU8_fmt(SPACE SPACE "%s_drop(cur->el);\n", op.T)));
|
||||
op.t_primitive ? vcstr("") : VecU8_fmt(SPACE SPACE "%s_drop(cur->el);\n", op.T));
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
@ -6,42 +6,39 @@
|
||||
// todo: add _less_ method
|
||||
// todo: rewrite this crap
|
||||
|
||||
NODISCARD VecU8 generate_VecT_struct(SpanU8 T, bool skip_declaration_gen){
|
||||
VecU8 res = VecU8_new();
|
||||
void codegen_append_VecT_struct(VecU8* res, SpanU8 T, bool skip_declaration_gen){
|
||||
if (!skip_declaration_gen) {
|
||||
VecU8_append_vec(&res, VecU8_fmt("typedef struct Vec%s Vec%s;\n\n", T, T));
|
||||
VecU8_append_fmt(res, "typedef struct Vec%s Vec%s;\n\n", T, T);
|
||||
}
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
VecU8_append_fmt(res,
|
||||
"struct Vec%s {\n"
|
||||
SPACE "%s* buf;\n"
|
||||
SPACE "size_t len;\n"
|
||||
SPACE "size_t capacity;\n"
|
||||
"};\n\n", T, T));
|
||||
return res;
|
||||
"};\n\n", T, T);
|
||||
}
|
||||
|
||||
// todo: add resize method
|
||||
/* if !primitive, requires methods T_drop, and, if also clonable, requires method T_clone */
|
||||
NODISCARD VecU8 generate_VecT_base_methods(SpanU8 T, bool primitive, bool clonable) {
|
||||
VecU8 res = VecU8_new();
|
||||
void codegen_append_VecT_base_methods(VecU8* res, SpanU8 T, bool primitive, bool clonable) {
|
||||
VecU8_append_fmt(res, "#define Vec%s_new() ((Vec%s){ 0 })\n\n", T, T);
|
||||
|
||||
VecU8_append_vec(&res, VecU8_fmt("#define Vec%s_new() ((Vec%s){ 0 })\n\n", T, T));
|
||||
|
||||
VecU8_append_vec(&res, VecU8_fmt("void Vec%s_drop(Vec%s self) {\n", T, T));
|
||||
VecU8_append_fmt(res, "void Vec%s_drop(Vec%s self) {\n", T, T);
|
||||
if (!primitive) {
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
VecU8_append_fmt(res,
|
||||
SPACE "for (size_t i = 0; i < self.len; i++) \n"
|
||||
SPACE SPACE "%s_drop(self.buf[i]);\n", T));
|
||||
SPACE SPACE "%s_drop(self.buf[i]);\n", T);
|
||||
}
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
SPACE "free(self.buf);\n"
|
||||
"}\n\n"));
|
||||
VecU8_append_cstr(res,
|
||||
SPACE "free(self.buf);\n"
|
||||
"}\n\n");
|
||||
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
VecU8_append_fmt(res,
|
||||
"NODISCARD Vec%s Vec%s_new_reserved(size_t n) {\n"
|
||||
SPACE "return (Vec%s){ .buf = (%s*)safe_calloc(n, sizeof(%s)), .len = 0, .capacity = n };\n"
|
||||
"}\n\n", T, T, T, T, T));
|
||||
"}\n\n", T, T, T, T, T);
|
||||
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
VecU8_append_fmt(res,
|
||||
"void Vec%s_append(Vec%s* self, %s el) {\n" /* T, T, T */
|
||||
SPACE "size_t new_length = self->len + 1;\n"
|
||||
SPACE "if (new_length > self->capacity) {\n"
|
||||
@ -51,21 +48,21 @@ NODISCARD VecU8 generate_VecT_base_methods(SpanU8 T, bool primitive, bool clonab
|
||||
SPACE "}\n"
|
||||
SPACE "self->buf[self->len] = el;\n"
|
||||
SPACE "self->len = new_length;\n"
|
||||
"}\n\n", T, T, T, T, T));
|
||||
"}\n\n", T, T, T, T, T);
|
||||
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
VecU8_append_fmt(res,
|
||||
"%s* Vec%s_mat(Vec%s* self, size_t i) {\n"
|
||||
SPACE "assert(i < self->len);\n"
|
||||
SPACE "return &self->buf[i];\n"
|
||||
"}\n\n", T, T, T));
|
||||
"}\n\n", T, T, T);
|
||||
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
VecU8_append_fmt(res,
|
||||
"const %s* Vec%s_at(const Vec%s* self, size_t i) {\n"
|
||||
SPACE "assert(i < self->len);\n"
|
||||
SPACE "return &self->buf[i];\n"
|
||||
"}\n\n", T, T, T));
|
||||
"}\n\n", T, T, T);
|
||||
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
VecU8_append_fmt(res,
|
||||
"void Vec%s_sink(Vec%s* self, size_t new_len) {\n" /* T, T */
|
||||
SPACE "assert(new_len <= self->len);\n"
|
||||
"%v" /* dropping */
|
||||
@ -74,25 +71,25 @@ NODISCARD VecU8 generate_VecT_base_methods(SpanU8 T, bool primitive, bool clonab
|
||||
primitive ? vcstr("") : VecU8_fmt(
|
||||
SPACE "for (size_t i = new_len; i < self->len; i++)\n"
|
||||
SPACE SPACE "%s_drop(self->buf[i]);\n", /* T */
|
||||
T)));
|
||||
T));
|
||||
|
||||
if (clonable) {
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
VecU8_append_fmt(res,
|
||||
"NODISCARD Vec%s Vec%s_clone(const Vec%s* self) {\n" /* T, T, T */
|
||||
SPACE "Vec%s res = (Vec%s){.buf = (%s*)safe_calloc(self->len, sizeof(%s)),\n" /* T, T, T, T */
|
||||
SPACE SPACE ".len = self->len, .capacity = self->len};\n",
|
||||
T, T, T, T, T, T, T));
|
||||
T, T, T, T, T, T, T);
|
||||
if (primitive) {
|
||||
VecU8_append_vec(&res, VecU8_fmt(SPACE "memcpy(res.buf, self->buf, self->len * sizeof(%s));\n", T));
|
||||
VecU8_append_fmt(res, SPACE "memcpy(res.buf, self->buf, self->len * sizeof(%s));\n", T);
|
||||
} else {
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
VecU8_append_fmt(res,
|
||||
SPACE "for (size_t i = 0; i < self->len; i++)\n"
|
||||
SPACE SPACE "res.buf[i] = %s_clone(&self->buf[i]);\n", T));
|
||||
SPACE SPACE "res.buf[i] = %s_clone(&self->buf[i]);\n", T);
|
||||
}
|
||||
VecU8_append_span(&res, cstr(SPACE "return res;\n}\n\n"));
|
||||
VecU8_append_cstr(res, SPACE "return res;\n}\n\n");
|
||||
}
|
||||
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
VecU8_append_fmt(res,
|
||||
"void Vec%s_append_vec(Vec%s* self, Vec%s b) {\n" /* T, T, T */
|
||||
SPACE "size_t new_length = self->len + b.len;\n"
|
||||
SPACE "if (new_length > self->capacity) {\n"
|
||||
@ -105,128 +102,114 @@ NODISCARD VecU8 generate_VecT_base_methods(SpanU8 T, bool primitive, bool clonab
|
||||
SPACE "}\n"
|
||||
SPACE "self->len = new_length;\n"
|
||||
SPACE "free(b.buf);\n"
|
||||
"}\n\n", T, T, T, T, T));
|
||||
"}\n\n", T, T, T, T, T);
|
||||
|
||||
if (primitive) {
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
VecU8_append_fmt(res,
|
||||
"NODISCARD Vec%s Vec%s_new_zeroinit(size_t len) {\n" /* T, T */
|
||||
SPACE "return (Vec%s){.buf = (%s*)safe_calloc(len, sizeof(%s)), .len = len, .capacity = len};\n" /* T, T, T */
|
||||
"}\n\n",
|
||||
T, T, T, T, T));
|
||||
T, T, T, T, T);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/* if !primitive, requires methods T_clone, T_drop */
|
||||
NODISCARD VecU8 generate_VecT_trivmove_extended_methods(SpanU8 T, bool primitive, bool clonable) {
|
||||
VecU8 g_VecT = VecU8_fmt("Vec%s", T);
|
||||
SpanU8 VecT = VecU8_to_span(&g_VecT);
|
||||
VecU8 res = VecU8_new();
|
||||
void codegen_append_VecT_trivmove_extended_methods(VecU8* res, SpanU8 T, bool primitive, bool clonable) {
|
||||
VecU8 VecT = VecU8_fmt("Vec%s", T);
|
||||
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"%s%s %s_pop(%s* self) {\n"
|
||||
VecU8_append_fmt(res,
|
||||
"%s%s %r_pop(%r* self) {\n"
|
||||
SPACE "assert(self->len > 0);\n"
|
||||
SPACE "self->len--;\n"
|
||||
SPACE "return self->buf[self->len];\n"
|
||||
"}\n\n", primitive ? cstr("") : cstr("NODISCARD "), T, VecT, VecT));
|
||||
"}\n\n", primitive ? cstr("") : cstr("NODISCARD "), T, VecT, VecT);
|
||||
|
||||
if (!primitive) {
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"void %s_pop_and_drop(%s* self) {\n"
|
||||
VecU8_append_fmt(res,
|
||||
"void %r_pop_and_drop(%r* self) {\n"
|
||||
SPACE "assert(self->len > 0);\n"
|
||||
SPACE "%s_drop(self->buf[self->len - 1]);\n"
|
||||
SPACE "self->len--;\n"
|
||||
"}\n\n", VecT, VecT, T));
|
||||
"}\n\n", VecT, VecT, T);
|
||||
}
|
||||
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"%s%s %s_unordered_pop(%s* self, size_t ind) {\n"
|
||||
VecU8_append_fmt(res,
|
||||
"%s%s %r_unordered_pop(%r* self, size_t ind) {\n"
|
||||
SPACE "assert(ind < self->len);\n"
|
||||
SPACE "%s res = self->buf[ind];\n"
|
||||
SPACE "self->buf[ind] = self->buf[self->len - 1];\n"
|
||||
SPACE "self->len--;\n"
|
||||
SPACE "return res;\n"
|
||||
"}\n\n", primitive ? cstr("") : cstr("NODISCARD "), T, VecT, VecT, T));
|
||||
"}\n\n", primitive ? cstr("") : cstr("NODISCARD "), T, VecT, VecT, T);
|
||||
|
||||
if (!primitive) {
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"void %s_unordered_pop_and_drop(%s* self, size_t ind) {\n"
|
||||
VecU8_append_fmt(res,
|
||||
"void %r_unordered_pop_and_drop(%r* self, size_t ind) {\n"
|
||||
SPACE "assert(ind < self->len);\n"
|
||||
SPACE "%s_drop(self->buf[ind]);\n"
|
||||
SPACE "self->buf[ind] = self->buf[self->len - 1];\n"
|
||||
SPACE "self->len--;\n"
|
||||
"}\n\n", VecT, VecT, T));
|
||||
"}\n\n", VecT, VecT, T);
|
||||
}
|
||||
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"NODISCARD %s %s_swap_with_empty(%s* cell) {\n"
|
||||
SPACE "%s val = *cell;\n"
|
||||
SPACE "*cell = (%s){NULL, 0, 0};\n"
|
||||
SPACE "return val;\n"
|
||||
"}\n\n", VecT, VecT, VecT, VecT, VecT));
|
||||
|
||||
if (primitive) {
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"NODISCARD %s %s_new_filled(size_t len, %s el) {\n" /* VecT, VecT, T */
|
||||
SPACE "%s res = (%s){.buf = (%s*)safe_calloc(len, sizeof(%s)), .len = len, .capacity = len};\n" /* VecT, VecT, T, T */
|
||||
VecU8_append_fmt(res,
|
||||
"NODISCARD %r %r_new_filled(size_t len, %s el) {\n" /* VecT, VecT, T */
|
||||
SPACE "%r res = (%r){.buf = (%s*)safe_calloc(len, sizeof(%s)), .len = len, .capacity = len};\n" /* VecT, VecT, T, T */
|
||||
SPACE "for (size_t i = 0; i < len; i++)\n"
|
||||
SPACE SPACE "res.buf[i] = el;\n"
|
||||
SPACE "return res;\n"
|
||||
"}\n\n", VecT, VecT, T, VecT, VecT, T, T));
|
||||
"}\n\n", VecT, VecT, T, VecT, VecT, T, T);
|
||||
} else if (clonable) {
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"NODISCARD %s %s_new_filled(size_t len, const %s* el) {\n" /* VecT, VecT, T */
|
||||
SPACE "%s res = (%s){.buf = (%s*)safe_calloc(len, sizeof(%s)), .len = len, .capacity = len};\n" /* VecT, VecT, T, T */
|
||||
VecU8_append_fmt(res,
|
||||
"NODISCARD %r %r_new_filled(size_t len, const %s* el) {\n" /* VecT, VecT, T */
|
||||
SPACE "%r res = (%r){.buf = (%s*)safe_calloc(len, sizeof(%s)), .len = len, .capacity = len};\n" /* VecT, VecT, T, T */
|
||||
SPACE "for (size_t i = 0; i < len; i++)\n"
|
||||
SPACE SPACE "res.buf[i] = %s_clone(el);\n" /* T */
|
||||
SPACE "return res;\n"
|
||||
"}\n\n", VecT, VecT, T, VecT, VecT, T, T, T));
|
||||
"}\n\n", VecT, VecT, T, VecT, VecT, T, T, T);
|
||||
}
|
||||
|
||||
VecU8_drop(g_VecT); // VecT invalidated
|
||||
return res;
|
||||
VecU8_drop(VecT);
|
||||
}
|
||||
|
||||
// todo: add _less_ method
|
||||
|
||||
/* if !integer requires method T_equal_T */
|
||||
NODISCARD VecU8 generate_VecT_equal_method(SpanU8 T, bool integer) {
|
||||
VecU8 g_VecT = VecU8_fmt("Vec%s", T);
|
||||
SpanU8 VecT = VecU8_to_span(&g_VecT);
|
||||
VecU8 res = VecU8_fmt(
|
||||
"bool %s_equal_%s(const %s* A, const %s* B) {\n"
|
||||
SPACE "if (A->len != B->len)\n"
|
||||
SPACE SPACE "return false;\n"
|
||||
SPACE "for (size_t i = 0; i < A->len; i++) {\n", VecT, VecT, VecT, VecT);
|
||||
void codegen_append_VecT_equal_method(VecU8* res, SpanU8 T, bool integer) {
|
||||
VecU8 VecT = VecU8_fmt("Vec%s", T);
|
||||
|
||||
VecU8_append_fmt(res,
|
||||
"bool %r_equal_%r(const %r* A, const %r* B) {\n"
|
||||
SPACE "if (A->len != B->len)\n"
|
||||
SPACE SPACE "return false;\n"
|
||||
SPACE "for (size_t i = 0; i < A->len; i++) {\n", VecT, VecT, VecT, VecT);
|
||||
if (integer) {
|
||||
VecU8_append_span(&res, cstr(SPACE8 "if (A->buf[i] != B->buf[i])\n"));
|
||||
VecU8_append_cstr(res, SPACE8 "if (A->buf[i] != B->buf[i])\n");
|
||||
} else {
|
||||
VecU8_append_vec(&res, VecU8_fmt(SPACE8 "if (!%s_equal_%s(A->buf + i, B->buf + i))\n", T, T));
|
||||
VecU8_append_fmt(res, SPACE8 "if (!%s_equal_%s(A->buf + i, B->buf + i))\n", T, T);
|
||||
}
|
||||
VecU8_append_span(&res, cstr(
|
||||
VecU8_append_cstr(res,
|
||||
SPACE SPACE SPACE "return false;\n"
|
||||
SPACE "}\n"
|
||||
SPACE "return true;\n"
|
||||
"}\n\n"
|
||||
));
|
||||
);
|
||||
|
||||
VecU8_drop(g_VecT);
|
||||
return res;
|
||||
VecU8_drop(VecT);
|
||||
}
|
||||
|
||||
/* requires method T_new */
|
||||
NODISCARD VecU8 generate_VecT_new_of_size_method(SpanU8 T) {
|
||||
VecU8 g_VecT = VecU8_fmt("Vec%s", T);
|
||||
SpanU8 VecT = VecU8_to_span(&g_VecT);
|
||||
VecU8 res = VecU8_fmt(
|
||||
"NODISCARD %s %s_new_of_size(size_t len) {\n" /* VecT, VecT */
|
||||
SPACE "%s res = (%s){.buf = (%s*)safe_calloc(len, sizeof(%s)), .len = len, .capacity = len};\n" /* VecT, VecT, T, T */
|
||||
SPACE "for (size_t i = 0; i < len; i++)\n"
|
||||
SPACE SPACE "res.buf[i] = %s_new();\n" /* T */
|
||||
SPACE "return res;\n"
|
||||
"}\n", VecT, VecT, VecT, VecT, T, T, T);
|
||||
|
||||
VecU8_drop(g_VecT);
|
||||
return res;
|
||||
void codegen_append_VecT_new_of_size_method(VecU8* res, SpanU8 T) {
|
||||
VecU8 VecT = VecU8_fmt("Vec%s", T);
|
||||
VecU8_append_fmt(res,
|
||||
"NODISCARD %r %r_new_of_size(size_t len) {\n" /* VecT, VecT */
|
||||
SPACE "%r res = (%r){.buf = (%s*)safe_calloc(len, sizeof(%s)), .len = len, .capacity = len};\n" /* VecT, VecT, T, T */
|
||||
SPACE "for (size_t i = 0; i < len; i++)\n"
|
||||
SPACE SPACE "res.buf[i] = %s_new();\n" /* T */
|
||||
SPACE "return res;\n"
|
||||
"}\n", VecT, VecT, VecT, VecT, T, T, T);
|
||||
VecU8_drop(VecT);
|
||||
}
|
||||
|
||||
/* helper function. SpanT is either SpanT or MutSpanT */
|
||||
@ -268,158 +251,143 @@ void codegen_append_some_span_span_method(VecU8* res, SpanU8 SpanT) {
|
||||
"}\n\n", SpanT, SpanT, SpanT, SpanT));
|
||||
}
|
||||
|
||||
NODISCARD VecU8 generate_SpanT_structures(SpanU8 T, bool add_mutable, bool skip_declaration_gen){
|
||||
VecU8 res = VecU8_new();
|
||||
codegen_append_some_span_struct(&res, T, cstr(""), cstr("const "), skip_declaration_gen);
|
||||
void codegen_append_SpanT_structures(VecU8* res, SpanU8 T, bool add_mutable, bool skip_declaration_gen){
|
||||
codegen_append_some_span_struct(res, T, cstr(""), cstr("const "), skip_declaration_gen);
|
||||
if (add_mutable)
|
||||
codegen_append_some_span_struct(&res, T, cstr("Mut"), cstr(""), skip_declaration_gen);
|
||||
return res;
|
||||
codegen_append_some_span_struct(res, T, cstr("Mut"), cstr(""), skip_declaration_gen);
|
||||
}
|
||||
|
||||
/* T must be sized. Option `add_sort` requires option `add_mutable` and method T_less
|
||||
* add_mutable option generates MutSpanT.
|
||||
* add_equal option generates equal method. add_extended option generated extended methods
|
||||
*/
|
||||
NODISCARD VecU8 generate_SpanT_base_methods(
|
||||
void codegen_append_SpanT_base_methods(VecU8* res,
|
||||
SpanU8 T, bool integer, bool add_mutable, bool add_equal, bool add_extended
|
||||
) {
|
||||
VecU8 g_SpanT = VecU8_fmt("Span%s", T);
|
||||
VecU8 g_MutSpanT = VecU8_fmt("MutSpan%s", T);
|
||||
SpanU8 SpanT = VecU8_to_span(&g_SpanT);
|
||||
SpanU8 MutSpanT = VecU8_to_span(&g_MutSpanT);
|
||||
VecU8 res = VecU8_new();
|
||||
VecU8 SpanT = VecU8_fmt("Span%s", T);
|
||||
VecU8 MutSpanT = VecU8_fmt("MutSpan%s", T);
|
||||
|
||||
if (add_equal) {
|
||||
codegen_append_some_span_equal_method(&res, SpanT);
|
||||
codegen_append_some_span_equal_method(res, VecU8_to_span(&SpanT));
|
||||
if (add_mutable)
|
||||
codegen_append_some_span_equal_method(&res, MutSpanT);
|
||||
codegen_append_some_span_equal_method(res, VecU8_to_span(&MutSpanT));
|
||||
}
|
||||
if (add_mutable) {
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"%s %s_to_%s(%s self) {\n"
|
||||
SPACE "return (%s){.data = self.data, .len = self.len};\n"
|
||||
"}\n\n", SpanT, MutSpanT, SpanT, MutSpanT, SpanT));
|
||||
VecU8_append_fmt(res,
|
||||
"%r %r_to_%r(%r self) {\n"
|
||||
SPACE "return (%r){.data = self.data, .len = self.len};\n"
|
||||
"}\n\n", SpanT, MutSpanT, SpanT, MutSpanT, SpanT);
|
||||
}
|
||||
codegen_append_some_span_at_method(&res, T, SpanT, cstr("const "));
|
||||
codegen_append_some_span_at_method(res, T, VecU8_to_span(&SpanT), cstr("const "));
|
||||
if (add_mutable)
|
||||
codegen_append_some_span_at_method(&res, T, MutSpanT, cstr(""));
|
||||
codegen_append_some_span_at_method(res, T, VecU8_to_span(&MutSpanT), cstr(""));
|
||||
if (add_extended) {
|
||||
codegen_append_some_span_span_method(&res, SpanT);
|
||||
codegen_append_some_span_span_method(res, VecU8_to_span(&SpanT));
|
||||
if (add_mutable)
|
||||
codegen_append_some_span_span_method(&res, MutSpanT);
|
||||
codegen_append_some_span_span_method(res, VecU8_to_span(&MutSpanT));
|
||||
}
|
||||
|
||||
VecU8_drop(g_MutSpanT);
|
||||
VecU8_drop(g_SpanT);
|
||||
return res;
|
||||
VecU8_drop(MutSpanT);
|
||||
VecU8_drop(SpanT);
|
||||
}
|
||||
|
||||
NODISCARD VecU8 generate_span_company_sort_methods(SpanU8 T, bool t_integer, bool mut_span, bool vec){
|
||||
VecU8 res = VecU8_new();
|
||||
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
void codegen_append_span_company_sort_methods(VecU8* res, SpanU8 T, bool t_integer, bool mut_span, bool vec){
|
||||
VecU8_append_fmt(res,
|
||||
"int %s_qcompare(const void* a, const void* b) {\n" /* T */
|
||||
SPACE "const %s* A = a;\n" /* T */
|
||||
SPACE "const %s* B = b;\n" /* T */
|
||||
SPACE "return %v;\n" /* we return stuff */
|
||||
"}\n\n",
|
||||
T, T, T, t_integer ? vcstr("(int)(*B < *A) - (int)(*A < *B)") :
|
||||
VecU8_fmt("(int)%s_less_%s(B, A) - (int)%s_less_%s(A, B)", T, T, T, T)));
|
||||
VecU8_fmt("(int)%s_less_%s(B, A) - (int)%s_less_%s(A, B)", T, T, T, T));
|
||||
|
||||
if (mut_span) {
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
VecU8_append_fmt(res,
|
||||
"void MutSpan%s_sort(MutSpan%s self) {\n"
|
||||
SPACE "qsort(self.data, self.len, sizeof(%s), %s_qcompare);\n"
|
||||
"}\n\n", T, T, T, T));
|
||||
"}\n\n", T, T, T, T);
|
||||
}
|
||||
if (vec) {
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
VecU8_append_fmt(res,
|
||||
"void Vec%s_sort(Vec%s* self) {\n"
|
||||
SPACE "qsort(self->buf, self->len, sizeof(%s), %s_qcompare);\n"
|
||||
"}\n\n", T, T, T, T));
|
||||
"}\n\n", T, T, T, T);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/* T must be trivially movable. If !primitive, requires methods T_drop (implicitly) and, if clonable, requires T_clone */
|
||||
NODISCARD VecU8 generate_SpanT_VecT_trivmove_collab(SpanU8 T, bool primitive, bool clonable, bool add_mutable, bool add_extended) {
|
||||
VecU8 g_SpanT = VecU8_fmt("Span%s", T);
|
||||
VecU8 g_MutSpanT = VecU8_fmt("MutSpan%s", T);
|
||||
VecU8 g_VecT = VecU8_fmt("Vec%s", T);
|
||||
SpanU8 SpanT = VecU8_to_span(&g_SpanT);
|
||||
SpanU8 MutSpanT = VecU8_to_span(&g_MutSpanT);
|
||||
SpanU8 VecT = VecU8_to_span(&g_VecT);
|
||||
VecU8 res = VecU8_new();
|
||||
void codegen_append_SpanT_VecT_trivmove_collab(VecU8* res,
|
||||
SpanU8 T, bool primitive, bool clonable, bool add_mutable, bool add_extended) {
|
||||
VecU8 SpanT = VecU8_fmt("Span%s", T);
|
||||
VecU8 MutSpanT = VecU8_fmt("MutSpan%s", T);
|
||||
VecU8 VecT = VecU8_fmt("Vec%s", T);
|
||||
|
||||
if (clonable) {
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"NODISCARD %s %s_from_span(%s src){\n" /* VecT, VecT, SpanT */
|
||||
SPACE "%s res = (%s){ .buf = (%s*)safe_calloc(src.len, sizeof(%s)), .len = src.len, .capacity = src.len };\n", /* VecT, VecT, T, T */
|
||||
VecT, VecT, SpanT, VecT, VecT, T, T));
|
||||
VecU8_append_fmt(res,
|
||||
"NODISCARD %r %r_from_span(%r src){\n" /* VecT, VecT, SpanT */
|
||||
SPACE "%r res = (%r){ .buf = (%s*)safe_calloc(src.len, sizeof(%s)), .len = src.len, .capacity = src.len };\n", /* VecT, VecT, T, T */
|
||||
VecT, VecT, SpanT, VecT, VecT, T, T);
|
||||
if (primitive) {
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
SPACE "memcpy(res.buf, src.data, src.len * sizeof(%s));\n", T));
|
||||
VecU8_append_fmt(res, SPACE "memcpy(res.buf, src.data, src.len * sizeof(%s));\n", T);
|
||||
} else {
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
VecU8_append_fmt(res,
|
||||
SPACE "for (size_t i = 0; i < src.len; i++)\n"
|
||||
SPACE8 "res.buf[i] = %s_clone(&src.data[i]);\n", T));
|
||||
SPACE8 "res.buf[i] = %s_clone(&src.data[i]);\n", T);
|
||||
}
|
||||
VecU8_append_span(&res, cstr(SPACE "return res;\n}\n\n"));
|
||||
VecU8_append_cstr(res, SPACE "return res;\n}\n\n");
|
||||
|
||||
}
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"%s %s_to_span(const %s* vec){\n"
|
||||
SPACE "return (%s){vec->buf, vec->len};\n"
|
||||
"}\n\n", SpanT, VecT, VecT, SpanT));
|
||||
VecU8_append_fmt(res,
|
||||
"%r %r_to_span(const %r* vec){\n"
|
||||
SPACE "return (%r){vec->buf, vec->len};\n"
|
||||
"}\n\n", SpanT, VecT, VecT, SpanT);
|
||||
if (add_mutable) {
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"%s %s_to_mspan(%s* vec){\n"
|
||||
SPACE "return (%s){vec->buf, vec->len};\n"
|
||||
"}\n\n", MutSpanT, VecT, VecT, MutSpanT));
|
||||
VecU8_append_fmt(res,
|
||||
"%r %r_to_mspan(%r* vec){\n"
|
||||
SPACE "return (%r){vec->buf, vec->len};\n"
|
||||
"}\n\n", MutSpanT, VecT, VecT, MutSpanT);
|
||||
}
|
||||
|
||||
if (clonable) {
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"void %s_append_span(%s* self, %s b) {\n" /* VecT, VecT, SpanT */
|
||||
VecU8_append_fmt(res,
|
||||
"void %r_append_span(%r* self, %r b) {\n" /* VecT, VecT, SpanT */
|
||||
SPACE "size_t new_length = self->len + b.len;\n"
|
||||
SPACE "if (new_length > self->capacity) {\n"
|
||||
SPACE SPACE "size_t new_capacity = Vec_get_new_capacity(self->capacity, new_length);\n"
|
||||
SPACE SPACE "self->buf = (%s*)safe_realloc(self->buf, new_capacity * sizeof(%s));\n" /* T, T */
|
||||
SPACE SPACE "self->capacity = new_capacity;\n"
|
||||
SPACE "}\n", VecT, VecT, SpanT, T, T));
|
||||
SPACE "}\n", VecT, VecT, SpanT, T, T);
|
||||
if (primitive) {
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
SPACE "memcpy(self->buf + self->len, b.data, b.len * sizeof(%s));\n", T));
|
||||
VecU8_append_fmt(res,
|
||||
SPACE "memcpy(self->buf + self->len, b.data, b.len * sizeof(%s));\n", T);
|
||||
} else {
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
SPACE "for (size_t i = 0; i < b.len; i++)\n"
|
||||
SPACE SPACE "self->buf[self->len + i] = %s_clone(&b.data[i]);\n", T));
|
||||
VecU8_append_fmt(res,
|
||||
SPACE "for (size_t i = 0; i < b.len; i++)\n"
|
||||
SPACE SPACE "self->buf[self->len + i] = %s_clone(&b.data[i]);\n", T);
|
||||
}
|
||||
VecU8_append_span(&res, cstr(
|
||||
VecU8_append_cstr(res,
|
||||
SPACE "self->len = new_length;\n"
|
||||
"}\n\n"));
|
||||
"}\n\n");
|
||||
}
|
||||
|
||||
if (add_extended) {
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"%s %s_span(const %s* vec, size_t start, size_t len) {\n"
|
||||
VecU8_append_fmt(res,
|
||||
"%r %r_span(const %r* vec, size_t start, size_t len) {\n"
|
||||
SPACE "assert(start < SIZE_MAX - len && start + len <= vec->len);\n"
|
||||
SPACE "return (%s){.data = vec->buf + start, .len = len};\n"
|
||||
"}\n\n", SpanT, VecT, VecT, SpanT));
|
||||
SPACE "return (%r){.data = vec->buf + start, .len = len};\n"
|
||||
"}\n\n", SpanT, VecT, VecT, SpanT);
|
||||
if (add_mutable) {
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"%s %s_mspan(%s* vec, size_t start, size_t len) {\n"
|
||||
VecU8_append_fmt(res,
|
||||
"%r %r_mspan(%r* vec, size_t start, size_t len) {\n"
|
||||
SPACE "assert(start < SIZE_MAX - len && start + len <= vec->len);\n"
|
||||
SPACE "return (%s){.data = vec->buf + start, .len = len};\n"
|
||||
"}\n\n", MutSpanT, VecT, VecT, MutSpanT));
|
||||
SPACE "return (%r){.data = vec->buf + start, .len = len};\n"
|
||||
"}\n\n", MutSpanT, VecT, VecT, MutSpanT);
|
||||
}
|
||||
}
|
||||
|
||||
VecU8_drop(g_VecT);
|
||||
VecU8_drop(g_MutSpanT);
|
||||
VecU8_drop(g_SpanT);
|
||||
return res;
|
||||
VecU8_drop(VecT);
|
||||
VecU8_drop(MutSpanT);
|
||||
VecU8_drop(SpanT);
|
||||
}
|
||||
|
||||
/* The only reason this function exists is because in C it is easier to supply a lot of brace list arguments,
|
||||
@ -478,37 +446,38 @@ NODISCARD VecU8 generate_util_templates_instantiation(util_templates_instantiati
|
||||
|
||||
if (generate_structures) {
|
||||
if (op.vec) {
|
||||
VecU8_append_vec(&res, generate_VecT_struct(op.T, op.skip_declaration_gen));
|
||||
codegen_append_VecT_struct(&res, op.T, op.skip_declaration_gen);
|
||||
}
|
||||
if (op.span) {
|
||||
VecU8_append_vec(&res, generate_SpanT_structures(op.T, op.mut_span, op.skip_declaration_gen));
|
||||
codegen_append_SpanT_structures(&res, op.T, op.mut_span, op.skip_declaration_gen);
|
||||
}
|
||||
}
|
||||
if (generate_methods) {
|
||||
if (op.vec) {
|
||||
VecU8_append_vec(&res, generate_VecT_base_methods(op.T, op.t_primitive, op.t_clonable));
|
||||
codegen_append_VecT_base_methods(&res, op.T, op.t_primitive, op.t_clonable);
|
||||
}
|
||||
if (op.vec_extended) {
|
||||
assert(op.vec);
|
||||
VecU8_append_vec(&res, generate_VecT_trivmove_extended_methods(op.T, op.t_primitive, op.t_clonable));
|
||||
codegen_append_VecT_trivmove_extended_methods(&res, op.T, op.t_primitive, op.t_clonable);
|
||||
}
|
||||
if (op.vec_equal) {
|
||||
assert(op.vec);
|
||||
VecU8_append_vec(&res, generate_VecT_equal_method(op.T, op.t_integer));
|
||||
codegen_append_VecT_equal_method(&res, op.T, op.t_integer);
|
||||
}
|
||||
if (op.vec_new_of_size) {
|
||||
assert(op.vec);
|
||||
VecU8_append_vec(&res, generate_VecT_new_of_size_method(op.T));
|
||||
codegen_append_VecT_new_of_size_method(&res, op.T);
|
||||
}
|
||||
if (op.span) {
|
||||
VecU8_append_vec(&res, generate_SpanT_base_methods(op.T, op.t_integer, op.mut_span, false, op.span_extended));
|
||||
codegen_append_SpanT_base_methods(&res, op.T, op.t_integer, op.mut_span, false, op.span_extended);
|
||||
}
|
||||
if (op.sort) {
|
||||
VecU8_append_vec(&res, generate_span_company_sort_methods(op.T, op.t_integer, op.mut_span, op.vec));
|
||||
codegen_append_span_company_sort_methods(&res, op.T, op.t_integer, op.mut_span, op.vec);
|
||||
}
|
||||
if (op.collab_vec_span) {
|
||||
assert(op.vec && op.span);
|
||||
VecU8_append_vec(&res, generate_SpanT_VecT_trivmove_collab(op.T, op.t_primitive, op.t_clonable, op.mut_span, op.collab_vec_span_extended));
|
||||
codegen_append_SpanT_VecT_trivmove_collab(&res,
|
||||
op.T, op.t_primitive, op.t_clonable, op.mut_span, op.collab_vec_span_extended);
|
||||
}
|
||||
}
|
||||
return res;
|
||||
@ -611,48 +580,48 @@ NODISCARD VecU8 generate_result_template_inst(SpanU8 OkT, SpanU8 ErrT, bool ok_t
|
||||
assert(!ok_t_void || ok_t_primitive);
|
||||
assert(!err_t_void || err_t_primitive);
|
||||
|
||||
VecU8 g_ResultT = get_ResultType_inst_name(OkT, ErrT);
|
||||
SpanU8 ResultT = VecU8_to_span(&g_ResultT);
|
||||
VecU8 ResultT = get_ResultType_inst_name(OkT, ErrT);
|
||||
|
||||
VecU8 res = VecU8_new();
|
||||
|
||||
VecU8_append_span(&res, cstr(
|
||||
VecU8_append_cstr(&res,
|
||||
"typedef struct {\n"
|
||||
SPACE "Result_variant variant;\n"));
|
||||
SPACE "Result_variant variant;\n");
|
||||
if (ok_t_void && !err_t_void) {
|
||||
VecU8_append_vec(&res, VecU8_fmt(SPACE "%s err;\n", ErrT));
|
||||
VecU8_append_fmt(&res, SPACE "%s err;\n", ErrT);
|
||||
} else if (!ok_t_void && err_t_void) {
|
||||
VecU8_append_vec(&res, VecU8_fmt(SPACE "%s ok;\n", OkT));
|
||||
VecU8_append_fmt(&res, SPACE "%s ok;\n", OkT);
|
||||
} else {
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
VecU8_append_fmt(&res,
|
||||
SPACE "union {\n"
|
||||
SPACE SPACE "%s ok;\n"
|
||||
SPACE SPACE "%s err;\n"
|
||||
SPACE "};\n", OkT, ErrT));
|
||||
SPACE "};\n", OkT, ErrT);
|
||||
}
|
||||
VecU8_append_vec(&res, VecU8_fmt("} %s;\n\n", ResultT));
|
||||
VecU8_append_fmt(&res, "} %r;\n\n", ResultT);
|
||||
|
||||
/* This method is 100% useless */
|
||||
if (!ok_t_primitive || !err_t_primitive) {
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"void %s_drop(%s self) {\n", ResultT, ResultT));
|
||||
VecU8_append_fmt(&res,
|
||||
"void %r_drop(%r self) {\n", ResultT, ResultT);
|
||||
if (ok_t_primitive && !err_t_primitive) {
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
VecU8_append_fmt(&res,
|
||||
SPACE "if (self.variant == Result_Err)\n"
|
||||
SPACE SPACE "%s_drop(self.err);\n", ErrT));
|
||||
SPACE SPACE "%s_drop(self.err);\n", ErrT);
|
||||
} else if (!ok_t_primitive && err_t_primitive) {
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
VecU8_append_fmt(&res,
|
||||
SPACE "if (self.variant == Result_Ok)\n"
|
||||
SPACE SPACE "%s_drop(self.ok);\n", OkT));
|
||||
SPACE SPACE "%s_drop(self.ok);\n", OkT);
|
||||
} else {
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
VecU8_append_fmt(&res,
|
||||
SPACE "if (self.variant == Result_Ok)\n"
|
||||
SPACE SPACE "%s_drop(self.ok);\n"
|
||||
SPACE "else\n"
|
||||
SPACE SPACE "%s_drop(self.err);\n", OkT, ErrT));
|
||||
SPACE SPACE "%s_drop(self.err);\n", OkT, ErrT);
|
||||
}
|
||||
VecU8_append_span(&res, cstr("}\n\n"));
|
||||
VecU8_append_cstr(&res, "}\n\n");
|
||||
}
|
||||
VecU8_drop(g_ResultT); /* ResultT variable invalidated */
|
||||
VecU8_drop(ResultT); /* ResultT variable invalidated */
|
||||
return res;
|
||||
}
|
||||
|
||||
@ -691,52 +660,53 @@ void option_template_instantiation_op_fix(option_template_instantiation_op* self
|
||||
|
||||
NODISCARD VecU8 generate_OptionT_struct_and_methods(option_template_instantiation_op op) {
|
||||
option_template_instantiation_op_fix(&op);
|
||||
VecU8 g_OptionT = VecU8_fmt("Option%s", op.T);
|
||||
SpanU8 OptionT = VecU8_to_span(&g_OptionT);
|
||||
VecU8 OptionT = VecU8_fmt("Option%s", op.T);
|
||||
|
||||
VecU8 res = VecU8_new();
|
||||
if (op.t_ptr) {
|
||||
VecU8_append_vec(&res, VecU8_fmt("typedef %s %s;\n", op.T, OptionT));
|
||||
VecU8_append_vec(&res, VecU8_fmt("#define None_%s() NULL\n", op.T));
|
||||
VecU8_append_vec(&res, VecU8_fmt("%s Some_%s(%s ref) {\n" SPACE "return ref;\n}\n\n", OptionT, op.T, op.T));
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"%s %s_expect(%s self) {\n"
|
||||
VecU8_append_fmt(&res, "typedef %s %r;\n", op.T, OptionT);
|
||||
VecU8_append_fmt(&res, "#define None_%s() NULL\n", op.T);
|
||||
VecU8_append_fmt(&res, "%r Some_%s(%s ref) {\n" SPACE "return ref;\n}\n\n", OptionT, op.T, op.T);
|
||||
VecU8_append_fmt(&res,
|
||||
"%s %r_expect(%r self) {\n"
|
||||
SPACE "if (self == NULL){\n"
|
||||
SPACE SPACE "abortf(\"Expected something in %r got NULL\\n\");\n"
|
||||
SPACE "return self;\n"
|
||||
"}\n\n", op.T, OptionT, OptionT));
|
||||
"}\n\n", op.T, OptionT, OptionT, OptionT);
|
||||
} else {
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
VecU8_append_fmt(&res,
|
||||
"typedef struct {\n"
|
||||
SPACE "Option_variant variant;\n"
|
||||
SPACE "%s some;\n"
|
||||
"} %s;\n\n", op.T, OptionT));
|
||||
VecU8_append_vec(&res, VecU8_fmt("#define None_%s() (%s){ .variant = Option_None }\n\n", op.T, OptionT));
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"NODISCARD %s Some_%s(%s obj) {\n"
|
||||
SPACE "return (%s){ .variant = Option_Some, .some = obj };\n"
|
||||
"}\n\n", OptionT, op.T, op.T, OptionT));
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"NODISCARD %s %s_expect(%s self){\n"
|
||||
"} %r;\n\n", op.T, OptionT);
|
||||
VecU8_append_fmt(&res, "#define None_%s() (%r){ .variant = Option_None }\n\n", op.T, OptionT);
|
||||
VecU8_append_fmt(&res,
|
||||
"NODISCARD %r Some_%s(%s obj) {\n"
|
||||
SPACE "return (%r){ .variant = Option_Some, .some = obj };\n"
|
||||
"}\n\n", OptionT, op.T, op.T, OptionT);
|
||||
VecU8_append_fmt(&res,
|
||||
"NODISCARD %s %r_expect(%r self){\n"
|
||||
SPACE "if (self.variant == Option_None)\n"
|
||||
SPACE SPACE "abortf(\"Expected something in %s got None\\n\");\n"
|
||||
SPACE SPACE "abortf(\"Expected something in %r got None\\n\");\n"
|
||||
SPACE "return self.some;\n"
|
||||
"}\n\n", op.T, OptionT, OptionT, OptionT));
|
||||
"}\n\n", op.T, OptionT, OptionT, OptionT);
|
||||
if (!op.t_primitive) {
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"void %s_drop(%s self) {\n"
|
||||
VecU8_append_fmt(&res,
|
||||
"void %r_drop(%r self) {\n"
|
||||
SPACE "if (self.variant == Option_None)\n"
|
||||
SPACE SPACE "%s_drop(self.some);\n"
|
||||
"}\n\n", OptionT, OptionT, op.T));
|
||||
"}\n\n", OptionT, OptionT, op.T);
|
||||
if (op.t_clonable) {
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"NODISCARD %s %s_clone(const %s* self) {\n"
|
||||
VecU8_append_fmt(&res,
|
||||
"NODISCARD %r %r_clone(const %r* self) {\n"
|
||||
SPACE "if (self->variant == Option_None)\n"
|
||||
SPACE SPACE "return (%s) { .variant = Option_None };\n"
|
||||
SPACE "return (%s){ .variant = Option_Some, .some = %s_clone(&self->some) };\n"
|
||||
"}\n\n", OptionT, OptionT, OptionT, OptionT, OptionT, op.T));
|
||||
SPACE SPACE "return (%r) { .variant = Option_None };\n"
|
||||
SPACE "return (%r){ .variant = Option_Some, .some = %s_clone(&self->some) };\n"
|
||||
"}\n\n", OptionT, OptionT, OptionT, OptionT, OptionT, op.T);
|
||||
}
|
||||
}
|
||||
}
|
||||
VecU8_drop(g_OptionT);
|
||||
VecU8_drop(OptionT);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
// todo: refactor (with VecU8_append_fmt)
|
||||
#include "all_set_map_templ_util_inst.h"
|
||||
|
||||
/* Assuming A nd B are passed as intended */
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
// todo: refactor (with VecU8_append_fmt)
|
||||
#include "all_set_map_templ_util_inst.h"
|
||||
|
||||
NODISCARD VecU8 codegen_rbtree__node_struct_name(map_instantiation_op op){
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
// todo: refactor (with VecU8_append_fmt)
|
||||
#include "../../l1/codegen/codegen.h"
|
||||
|
||||
typedef struct {
|
||||
|
||||
@ -32,6 +32,13 @@ GenericMeshTopology GenericMeshTopology_clone(const GenericMeshTopology* self) {
|
||||
return (GenericMeshTopology){.vertices = VecGenericMeshVertexInc_clone(&self->vertices), .indexes = VecU32_clone(&self->indexes)};
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
GenericMeshTopology topology;
|
||||
VecU8 diffuse_texture_path;
|
||||
VecU8 normal_texture_path;
|
||||
VecU8 specular_texture_path;
|
||||
} AliceGenericMeshTopology_TexturePaths;
|
||||
|
||||
typedef struct {
|
||||
VecU8 topology_path;
|
||||
VecU8 diffuse_texture_path;
|
||||
|
||||
@ -1,6 +1,17 @@
|
||||
#include "../../l2/core/glb_file.h"
|
||||
#include "../../l2/alice/engine.h"
|
||||
|
||||
typedef struct {
|
||||
float mass;
|
||||
} RigidBodyConfig;
|
||||
|
||||
typedef struct {
|
||||
vec3 pos;
|
||||
vec3 speed;
|
||||
vec3 rot;
|
||||
vec3 rot_speed;
|
||||
} RigidBodyState;
|
||||
|
||||
AliceGenericMeshPath AliceGenericMeshPath_for_log(SpanU8 root_dir, U64 w, U64 r, U64 k) {
|
||||
return (AliceGenericMeshPath){
|
||||
.topology_path = VecU8_fmt("%s/gen/l2/models/log_%u_%u_%u.AliceGenericMesh", root_dir, w, r, k),
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user