From 7c02d8953ef1f669e3dc7434d9e630bb111bcbe6 Mon Sep 17 00:00:00 2001 From: LeonardoBizzoni Date: Tue, 21 Oct 2025 11:51:44 +0200 Subject: [PATCH] renamed files + examples --- cbuild.h | 12 +- examples/e0-code-generation/cbuild.c | 150 +++++ examples/e0-code-generation/linear_algebra.h | 539 ++++++++++++++++++ examples/e0-code-generation/main.c | 38 ++ examples/e1-testing/cbuild.c | 17 + extra/{code_generation.h => cbuild_codegen.h} | 4 +- extra/{linear_algebra.h => cbuild_linagen.h} | 11 +- extra/{tests.h => cbuild_tests.h} | 4 +- 8 files changed, 759 insertions(+), 16 deletions(-) create mode 100644 examples/e0-code-generation/cbuild.c create mode 100644 examples/e0-code-generation/linear_algebra.h create mode 100644 examples/e0-code-generation/main.c create mode 100644 examples/e1-testing/cbuild.c rename extra/{code_generation.h => cbuild_codegen.h} (96%) rename extra/{linear_algebra.h => cbuild_linagen.h} (99%) rename extra/{tests.h => cbuild_tests.h} (97%) diff --git a/cbuild.h b/cbuild.h index b477321..14e2a1d 100644 --- a/cbuild.h +++ b/cbuild.h @@ -75,6 +75,7 @@ typedef enum {false, true} bool; # define WIN32_LEAN_AND_MEAN # include # include +# include # define win32_stdin stdin # undef stdin # define win32_stdout stdout @@ -519,12 +520,11 @@ static bool cb_file_rename(char *path, char *to) { } static bool cb_file_exists(char *path) { - CB_Handle file = cb_handle_open(path, CB_AccessFlag_Read); - if (file == CB_HANDLE_INVALID) { - return false; - } - cb_handle_close(file); - return true; +#if OS_WINDOWS +# define F_OK 0 +# define access _access +#endif + return access(path, F_OK) == 0; } diff --git a/examples/e0-code-generation/cbuild.c b/examples/e0-code-generation/cbuild.c new file mode 100644 index 0000000..c922a6e --- /dev/null +++ b/examples/e0-code-generation/cbuild.c @@ -0,0 +1,150 @@ +#include "../../cbuild.h" +#include "../../extra/cbuild_codegen.h" +#include "../../extra/cbuild_linagen.h" + +int32_t main(int32_t argc, char **argv) { + cb_rebuild_self(argc, argv); + + if (!cb_file_exists("linear_algebra.h")) { + CB_Generator vec = {0}; + cb_gen_push(&vec, "#ifndef CB_LINEAR_ALGEBRA_H\n" + "#define CB_LINEAR_ALGEBRA_H\n\n"); + + cb_gen_push(&vec, "#define linagen_fn static inline\n\n"); + cb_linagen_typedef_vecn_unnamed(&vec, "float", 2); + cb_linagen_typedef_vecn(&vec, "float", 3, "x", "y", "z"); + cb_linagen_typedef_vecn(&vec, "float", 5, "x", "y", "z", 0); + cb_linagen_typedef_matnn(&vec, "float", 3); + + cb_linagen_defun_vecn_add(&vec, "float", 2, false); + cb_linagen_defun_vecn_sub(&vec, "float", 2, false); + cb_linagen_defun_vecn_hadamard_prod(&vec, "float", 2, false); + cb_linagen_defun_vecn_hadamard_div(&vec, "float", 2, false); + cb_linagen_defun_vecn_scale(&vec, "float", 2, false); + cb_linagen_defun_vecn_equal(&vec, "float", 2, false); + cb_linagen_defun_vecn_near(&vec, "float", 2, false); + cb_linagen_defun_vecn_lerp(&vec, "float", 2, false); + cb_linagen_defun_vecn_normalize(&vec, "float", 2, false); + cb_linagen_defun_vecn_dot(&vec, "float", 2, false); + cb_linagen_defun_vecn_magnitude(&vec, "float", 2, false); + cb_linagen_defun_vecn_magnitude64(&vec, "float", 2, false); + cb_linagen_defun_vecn_distance(&vec, "float", 2, false); + cb_linagen_defun_vecn_distance2(&vec, "float", 2, false); + cb_gen_push(&vec, "\n"); + + cb_linagen_defun_vecn_add(&vec, "float", 3, false); + cb_linagen_defun_vecn_sub(&vec, "float", 3, false); + cb_linagen_defun_vecn_hadamard_prod(&vec, "float", 3, false); + cb_linagen_defun_vecn_hadamard_div(&vec, "float", 3, false); + cb_linagen_defun_vecn_scale(&vec, "float", 3, false); + cb_linagen_defun_vecn_equal(&vec, "float", 3, false); + cb_linagen_defun_vecn_near(&vec, "float", 3, false); + cb_linagen_defun_vecn_lerp(&vec, "float", 3, false); + cb_linagen_defun_vecn_normalize(&vec, "float", 3, false); + cb_linagen_defun_vec3_cross(&vec, "float", false); + cb_linagen_defun_vecn_dot(&vec, "float", 3, false); + cb_linagen_defun_vecn_mulm(&vec, "float", 3, false); + cb_linagen_defun_vecn_magnitude(&vec, "float", 3, false); + cb_linagen_defun_vecn_magnitude64(&vec, "float", 3, false); + cb_linagen_defun_vecn_distance(&vec, "float", 3, false); + cb_linagen_defun_vecn_distance2(&vec, "float", 3, false); + cb_gen_push(&vec, "\n"); + + cb_linagen_defun_vecn_add(&vec, "float", 5, false); + cb_linagen_defun_vecn_sub(&vec, "float", 5, false); + cb_linagen_defun_vecn_hadamard_prod(&vec, "float", 5, false); + cb_linagen_defun_vecn_hadamard_div(&vec, "float", 5, false); + cb_linagen_defun_vecn_scale(&vec, "float", 5, false); + cb_linagen_defun_vecn_equal(&vec, "float", 5, false); + cb_linagen_defun_vecn_near(&vec, "float", 5, false); + cb_linagen_defun_vecn_lerp(&vec, "float", 5, false); + cb_linagen_defun_vecn_normalize(&vec, "float", 5, false); + cb_linagen_defun_vecn_dot(&vec, "float", 5, false); + cb_linagen_defun_vecn_magnitude(&vec, "float", 5, false); + cb_linagen_defun_vecn_magnitude64(&vec, "float", 5, false); + cb_linagen_defun_vecn_distance(&vec, "float", 5, false); + cb_linagen_defun_vecn_distance2(&vec, "float", 5, false); + cb_gen_push(&vec, "\n"); + + cb_linagen_defun_matnn_add(&vec, "float", 3, false); + cb_linagen_defun_matnn_sub(&vec, "float", 3, false); + cb_linagen_defun_matnn_hadamard_prod(&vec, "float", 3, false); + cb_linagen_defun_matnn_hadamard_div(&vec, "float", 3, false); + cb_linagen_defun_matnn_scale(&vec, "float", 3, false); + cb_linagen_defun_matnn_dot(&vec, "float", 3, false); + cb_linagen_defun_matnn_mulv(&vec, "float", 3, false); + cb_linagen_defun_matnn_identity(&vec, "float", 3, false); + cb_gen_write(&vec, "linear_algebra.h", false); + + cb_gen_push(&vec, "\n#ifndef CB_LINEAR_ALGEBRA_NO_IMPL\n"); + cb_linagen_defun_vecn_add(&vec, "float", 2, true); + cb_linagen_defun_vecn_sub(&vec, "float", 2, true); + cb_linagen_defun_vecn_hadamard_prod(&vec, "float", 2, true); + cb_linagen_defun_vecn_hadamard_div(&vec, "float", 2, true); + cb_linagen_defun_vecn_scale(&vec, "float", 2, true); + cb_linagen_defun_vecn_equal(&vec, "float", 2, true); + cb_linagen_defun_vecn_near(&vec, "float", 2, true); + cb_linagen_defun_vecn_lerp(&vec, "float", 2, true); + cb_linagen_defun_vecn_normalize(&vec, "float", 2, true); + cb_linagen_defun_vecn_dot(&vec, "float", 2, true); + cb_linagen_defun_vecn_magnitude(&vec, "float", 2, true); + cb_linagen_defun_vecn_magnitude64(&vec, "float", 2, true); + cb_linagen_defun_vecn_distance(&vec, "float", 2, true); + cb_linagen_defun_vecn_distance2(&vec, "float", 2, true); + cb_gen_push(&vec, "\n"); + + cb_linagen_defun_vecn_add(&vec, "float", 3, true); + cb_linagen_defun_vecn_sub(&vec, "float", 3, true); + cb_linagen_defun_vecn_hadamard_prod(&vec, "float", 3, true); + cb_linagen_defun_vecn_hadamard_div(&vec, "float", 3, true); + cb_linagen_defun_vecn_scale(&vec, "float", 3, true); + cb_linagen_defun_vecn_equal(&vec, "float", 3, true); + cb_linagen_defun_vecn_near(&vec, "float", 3, true); + cb_linagen_defun_vecn_lerp(&vec, "float", 3, true); + cb_linagen_defun_vecn_normalize(&vec, "float", 3, true); + cb_linagen_defun_vec3_cross(&vec, "float", true); + cb_linagen_defun_vecn_dot(&vec, "float", 3, true); + cb_linagen_defun_vecn_mulm(&vec, "float", 3, true); + cb_linagen_defun_vecn_magnitude(&vec, "float", 3, true); + cb_linagen_defun_vecn_magnitude64(&vec, "float", 3, true); + cb_linagen_defun_vecn_distance(&vec, "float", 3, true); + cb_linagen_defun_vecn_distance2(&vec, "float", 3, true); + cb_gen_push(&vec, "\n"); + + cb_linagen_defun_vecn_add(&vec, "float", 5, true); + cb_linagen_defun_vecn_sub(&vec, "float", 5, true); + cb_linagen_defun_vecn_hadamard_prod(&vec, "float", 5, true); + cb_linagen_defun_vecn_hadamard_div(&vec, "float", 5, true); + cb_linagen_defun_vecn_scale(&vec, "float", 5, true); + cb_linagen_defun_vecn_equal(&vec, "float", 5, true); + cb_linagen_defun_vecn_near(&vec, "float", 5, true); + cb_linagen_defun_vecn_lerp(&vec, "float", 5, true); + cb_linagen_defun_vecn_normalize(&vec, "float", 5, true); + cb_linagen_defun_vecn_dot(&vec, "float", 5, true); + cb_linagen_defun_vecn_magnitude(&vec, "float", 5, true); + cb_linagen_defun_vecn_magnitude64(&vec, "float", 5, true); + cb_linagen_defun_vecn_distance(&vec, "float", 5, true); + cb_linagen_defun_vecn_distance2(&vec, "float", 5, true); + cb_gen_push(&vec, "\n"); + + cb_linagen_defun_matnn_add(&vec, "float", 3, true); + cb_linagen_defun_matnn_sub(&vec, "float", 3, true); + cb_linagen_defun_matnn_hadamard_prod(&vec, "float", 3, true); + cb_linagen_defun_matnn_hadamard_div(&vec, "float", 3, true); + cb_linagen_defun_matnn_scale(&vec, "float", 3, true); + cb_linagen_defun_matnn_dot(&vec, "float", 3, true); + cb_linagen_defun_matnn_mulv(&vec, "float", 3, true); + cb_linagen_defun_matnn_identity(&vec, "float", 3, true); + cb_gen_push(&vec, "#endif // CB_LINEAR_ALGEBRA_NO_IMPL\n"); + cb_gen_push(&vec, "#endif // CB_LINEAR_ALGEBRA_H\n"); + cb_gen_write(&vec, "linear_algebra.h", true); + } + + CB_Cmd cmd = {0}; +#if OS_WINDOWS + cb_cmd_append(&cmd, "cl", "/Fe:main", "main.c"); +#else + cb_cmd_append(&cmd, "gcc", "-o", "main", "main.c", "-lm"); +#endif + return cb_cmd_run(&cmd).status_code; +} diff --git a/examples/e0-code-generation/linear_algebra.h b/examples/e0-code-generation/linear_algebra.h new file mode 100644 index 0000000..019305e --- /dev/null +++ b/examples/e0-code-generation/linear_algebra.h @@ -0,0 +1,539 @@ +#ifndef CB_LINEAR_ALGEBRA_H +#define CB_LINEAR_ALGEBRA_H + +#define linagen_fn static inline + +typedef struct Vec2Float { + float values[2]; +} Vec2Float; + +typedef union { + float values[3]; + struct { + float x; float y; float z; + }; +} Vec3Float; + +typedef union { + float values[5]; + struct { + float x; float y; float z; float _3; + float _4; + }; +} Vec5Float; + +typedef union Mat3Float { + float values[3][3]; + Vec3Float cols[3]; + float arr[9]; +} Mat3Float; + +linagen_fn void vec2float_add(Vec2Float *res, const Vec2Float *v1, const Vec2Float *v2); +linagen_fn void vec2float_sub(Vec2Float *res, const Vec2Float *v1, const Vec2Float *v2); +linagen_fn void vec2float_hadamard_prod(Vec2Float *res, const Vec2Float *v1, const Vec2Float *v2); +linagen_fn void vec2float_hadamard_div(Vec2Float *res, const Vec2Float *v1, const Vec2Float *v2); +linagen_fn void vec2float_scale(Vec2Float *res, const Vec2Float *v1, float k); +linagen_fn bool vec2float_equal(const Vec2Float *restrict v1, const Vec2Float *restrict v2); +linagen_fn bool vec2float_near(const Vec2Float *restrict v1, const Vec2Float *restrict v2, float eps); +linagen_fn void vec2float_lerp(Vec2Float *restrict res, const Vec2Float *restrict start, const Vec2Float *restrict end, float t); +linagen_fn void vec2float_normalize(Vec2Float *res, const Vec2Float *v1); +linagen_fn float vec2float_dot(const Vec2Float *v1, const Vec2Float *v2); +linagen_fn float vec2float_magnitude(const Vec2Float *v1); +linagen_fn double vec2float_magnitude64(const Vec2Float *v1); +linagen_fn float vec2float_distance(const Vec2Float *restrict v1, const Vec2Float *restrict v2); +linagen_fn float vec2float_distance2(const Vec2Float *restrict v1, const Vec2Float *restrict v2); + +linagen_fn void vec3float_add(Vec3Float *res, const Vec3Float *v1, const Vec3Float *v2); +linagen_fn void vec3float_sub(Vec3Float *res, const Vec3Float *v1, const Vec3Float *v2); +linagen_fn void vec3float_hadamard_prod(Vec3Float *res, const Vec3Float *v1, const Vec3Float *v2); +linagen_fn void vec3float_hadamard_div(Vec3Float *res, const Vec3Float *v1, const Vec3Float *v2); +linagen_fn void vec3float_scale(Vec3Float *res, const Vec3Float *v1, float k); +linagen_fn bool vec3float_equal(const Vec3Float *restrict v1, const Vec3Float *restrict v2); +linagen_fn bool vec3float_near(const Vec3Float *restrict v1, const Vec3Float *restrict v2, float eps); +linagen_fn void vec3float_lerp(Vec3Float *restrict res, const Vec3Float *restrict start, const Vec3Float *restrict end, float t); +linagen_fn void vec3float_normalize(Vec3Float *res, const Vec3Float *v1); +linagen_fn void vec3float_cross(Vec3Float *restrict res, const Vec3Float *restrict v1, const Vec3Float *restrict v2); +linagen_fn float vec3float_dot(const Vec3Float *v1, const Vec3Float *v2); +linagen_fn void vec3float_mulm(Vec3Float *restrict res, const Vec3Float *restrict v, const Mat3Float *restrict m); +linagen_fn float vec3float_magnitude(const Vec3Float *v1); +linagen_fn double vec3float_magnitude64(const Vec3Float *v1); +linagen_fn float vec3float_distance(const Vec3Float *restrict v1, const Vec3Float *restrict v2); +linagen_fn float vec3float_distance2(const Vec3Float *restrict v1, const Vec3Float *restrict v2); + +linagen_fn void vec5float_add(Vec5Float *res, const Vec5Float *v1, const Vec5Float *v2); +linagen_fn void vec5float_sub(Vec5Float *res, const Vec5Float *v1, const Vec5Float *v2); +linagen_fn void vec5float_hadamard_prod(Vec5Float *res, const Vec5Float *v1, const Vec5Float *v2); +linagen_fn void vec5float_hadamard_div(Vec5Float *res, const Vec5Float *v1, const Vec5Float *v2); +linagen_fn void vec5float_scale(Vec5Float *res, const Vec5Float *v1, float k); +linagen_fn bool vec5float_equal(const Vec5Float *restrict v1, const Vec5Float *restrict v2); +linagen_fn bool vec5float_near(const Vec5Float *restrict v1, const Vec5Float *restrict v2, float eps); +linagen_fn void vec5float_lerp(Vec5Float *restrict res, const Vec5Float *restrict start, const Vec5Float *restrict end, float t); +linagen_fn void vec5float_normalize(Vec5Float *res, const Vec5Float *v1); +linagen_fn float vec5float_dot(const Vec5Float *v1, const Vec5Float *v2); +linagen_fn float vec5float_magnitude(const Vec5Float *v1); +linagen_fn double vec5float_magnitude64(const Vec5Float *v1); +linagen_fn float vec5float_distance(const Vec5Float *restrict v1, const Vec5Float *restrict v2); +linagen_fn float vec5float_distance2(const Vec5Float *restrict v1, const Vec5Float *restrict v2); + +linagen_fn void mat3float_add(Mat3Float *res, const Mat3Float *m1, const Mat3Float *m2); +linagen_fn void mat3float_sub(Mat3Float *res, const Mat3Float *m1, const Mat3Float *m2); +linagen_fn void mat3float_hadamard_prod(Mat3Float *res, const Mat3Float *m1, const Mat3Float *m2); +linagen_fn void mat3float_hadamard_div(Mat3Float *res, const Mat3Float *m1, const Mat3Float *m2); +linagen_fn void mat3float_scale(Mat3Float *res, const Mat3Float *m1, float k); +linagen_fn void mat3float_dot(Mat3Float *restrict res, const Mat3Float *m1, const Mat3Float *m2); +linagen_fn void mat3float_mulv(Vec3Float *restrict res, const Mat3Float *restrict m, const Vec3Float *restrict v); +linagen_fn void mat3float_identity(Mat3Float *res); + +#ifndef CB_LINEAR_ALGEBRA_NO_IMPL +linagen_fn void vec2float_add(Vec2Float *res, const Vec2Float *v1, const Vec2Float *v2) { + res->values[0] = v1->values[0] + v2->values[0]; + res->values[1] = v1->values[1] + v2->values[1]; +} + +linagen_fn void vec2float_sub(Vec2Float *res, const Vec2Float *v1, const Vec2Float *v2) { + res->values[0] = v1->values[0] - v2->values[0]; + res->values[1] = v1->values[1] - v2->values[1]; +} + +linagen_fn void vec2float_hadamard_prod(Vec2Float *res, const Vec2Float *v1, const Vec2Float *v2) { + res->values[0] = v1->values[0] * v2->values[0]; + res->values[1] = v1->values[1] * v2->values[1]; +} + +linagen_fn void vec2float_hadamard_div(Vec2Float *res, const Vec2Float *v1, const Vec2Float *v2) { + res->values[0] = v1->values[0] / v2->values[0]; + res->values[1] = v1->values[1] / v2->values[1]; +} + +linagen_fn void vec2float_scale(Vec2Float *res, const Vec2Float *v1, float k) { + res->values[0] = v1->values[0] * k; + res->values[1] = v1->values[1] * k; +} + +linagen_fn bool vec2float_equal(const Vec2Float *restrict v1, const Vec2Float *restrict v2) { + return v1->values[0] == v2->values[0] && + v1->values[1] == v2->values[1]; +} + +linagen_fn bool vec2float_near(const Vec2Float *restrict v1, const Vec2Float *restrict v2, float eps) { + return ((float)v1->values[0] + eps >= v2->values[0] && (float)v1->values[0] - eps <= v2->values[0]) && + ((float)v1->values[1] + eps >= v2->values[1] && (float)v1->values[1] - eps <= v2->values[1]); +} + +linagen_fn void vec2float_lerp(Vec2Float *restrict res, const Vec2Float *restrict start, const Vec2Float *restrict end, float t) { + res->values[0] = start->values[0] * (1 - t) + end->values[0] * t; + res->values[1] = start->values[1] * (1 - t) + end->values[1] * t; +} + +linagen_fn void vec2float_normalize(Vec2Float *res, const Vec2Float *v1) { + float dot = {0}; + dot += v1->values[0] * v1->values[0]; + dot += v1->values[1] * v1->values[1]; + float magnitude = sqrtf((float)dot); + if (magnitude == 0.f) { return; } + res->values[0] = v1->values[0] / magnitude; + res->values[1] = v1->values[1] / magnitude; +} + +linagen_fn float vec2float_dot(const Vec2Float *v1, const Vec2Float *v2) { + float res = {0}; + res += v1->values[0] * v2->values[0]; + res += v1->values[1] * v2->values[1]; + return res; +} + +linagen_fn float vec2float_magnitude(const Vec2Float *v1) { + float dot = {0}; + dot += v1->values[0] * v1->values[0]; + dot += v1->values[1] * v1->values[1]; + float res = sqrtf(dot); + return res; +} + +linagen_fn double vec2float_magnitude64(const Vec2Float *v1) { + double dot = {0}; + dot += v1->values[0] * v1->values[0]; + dot += v1->values[1] * v1->values[1]; + double res = sqrt(dot); + return res; +} + +linagen_fn float vec2float_distance(const Vec2Float *restrict v1, const Vec2Float *restrict v2) { + Vec2Float diff = {0}; + diff.values[0] = v1->values[0] - v2->values[0]; + diff.values[1] = v1->values[1] - v2->values[1]; + float dot = {0}; + dot += diff.values[0] * diff.values[0]; + dot += diff.values[1] * diff.values[1]; + float res = sqrtf(dot); + return res; +} + +linagen_fn float vec2float_distance2(const Vec2Float *restrict v1, const Vec2Float *restrict v2) { + Vec2Float diff = {0}; + diff.values[0] = v1->values[0] - v2->values[0]; + diff.values[1] = v1->values[1] - v2->values[1]; + float dot = {0}; + dot += diff.values[0] * diff.values[0]; + dot += diff.values[1] * diff.values[1]; + return dot; +} + + +linagen_fn void vec3float_add(Vec3Float *res, const Vec3Float *v1, const Vec3Float *v2) { + res->values[0] = v1->values[0] + v2->values[0]; + res->values[1] = v1->values[1] + v2->values[1]; + res->values[2] = v1->values[2] + v2->values[2]; +} + +linagen_fn void vec3float_sub(Vec3Float *res, const Vec3Float *v1, const Vec3Float *v2) { + res->values[0] = v1->values[0] - v2->values[0]; + res->values[1] = v1->values[1] - v2->values[1]; + res->values[2] = v1->values[2] - v2->values[2]; +} + +linagen_fn void vec3float_hadamard_prod(Vec3Float *res, const Vec3Float *v1, const Vec3Float *v2) { + res->values[0] = v1->values[0] * v2->values[0]; + res->values[1] = v1->values[1] * v2->values[1]; + res->values[2] = v1->values[2] * v2->values[2]; +} + +linagen_fn void vec3float_hadamard_div(Vec3Float *res, const Vec3Float *v1, const Vec3Float *v2) { + res->values[0] = v1->values[0] / v2->values[0]; + res->values[1] = v1->values[1] / v2->values[1]; + res->values[2] = v1->values[2] / v2->values[2]; +} + +linagen_fn void vec3float_scale(Vec3Float *res, const Vec3Float *v1, float k) { + res->values[0] = v1->values[0] * k; + res->values[1] = v1->values[1] * k; + res->values[2] = v1->values[2] * k; +} + +linagen_fn bool vec3float_equal(const Vec3Float *restrict v1, const Vec3Float *restrict v2) { + return v1->values[0] == v2->values[0] && + v1->values[1] == v2->values[1] && + v1->values[2] == v2->values[2]; +} + +linagen_fn bool vec3float_near(const Vec3Float *restrict v1, const Vec3Float *restrict v2, float eps) { + return ((float)v1->values[0] + eps >= v2->values[0] && (float)v1->values[0] - eps <= v2->values[0]) && + ((float)v1->values[1] + eps >= v2->values[1] && (float)v1->values[1] - eps <= v2->values[1]) && + ((float)v1->values[2] + eps >= v2->values[2] && (float)v1->values[2] - eps <= v2->values[2]); +} + +linagen_fn void vec3float_lerp(Vec3Float *restrict res, const Vec3Float *restrict start, const Vec3Float *restrict end, float t) { + res->values[0] = start->values[0] * (1 - t) + end->values[0] * t; + res->values[1] = start->values[1] * (1 - t) + end->values[1] * t; + res->values[2] = start->values[2] * (1 - t) + end->values[2] * t; +} + +linagen_fn void vec3float_normalize(Vec3Float *res, const Vec3Float *v1) { + float dot = {0}; + dot += v1->values[0] * v1->values[0]; + dot += v1->values[1] * v1->values[1]; + dot += v1->values[2] * v1->values[2]; + float magnitude = sqrtf((float)dot); + if (magnitude == 0.f) { return; } + res->values[0] = v1->values[0] / magnitude; + res->values[1] = v1->values[1] / magnitude; + res->values[2] = v1->values[2] / magnitude; +} + +linagen_fn void vec3float_cross(Vec3Float *restrict res, const Vec3Float *restrict v1, const Vec3Float *restrict v2) { + res->values[0] = v1->values[1] * v2->values[2] - v1->values[2] * v2->values[1]; + res->values[1] = v1->values[2] * v2->values[0] - v1->values[0] * v2->values[2]; + res->values[2] = v1->values[0] * v2->values[1] - v1->values[1] * v2->values[0]; +} + +linagen_fn float vec3float_dot(const Vec3Float *v1, const Vec3Float *v2) { + float res = {0}; + res += v1->values[0] * v2->values[0]; + res += v1->values[1] * v2->values[1]; + res += v1->values[2] * v2->values[2]; + return res; +} + +linagen_fn void vec3float_mulm(Vec3Float *restrict res, const Vec3Float *restrict v, const Mat3Float *restrict m) { + res->values[0] = (v->values[0] * m->values[0][0]) + (v->values[1] * m->values[0][1]) + (v->values[2] * m->values[0][2]); + res->values[1] = (v->values[0] * m->values[1][0]) + (v->values[1] * m->values[1][1]) + (v->values[2] * m->values[1][2]); + res->values[2] = (v->values[0] * m->values[2][0]) + (v->values[1] * m->values[2][1]) + (v->values[2] * m->values[2][2]); +} + +linagen_fn float vec3float_magnitude(const Vec3Float *v1) { + float dot = {0}; + dot += v1->values[0] * v1->values[0]; + dot += v1->values[1] * v1->values[1]; + dot += v1->values[2] * v1->values[2]; + float res = sqrtf(dot); + return res; +} + +linagen_fn double vec3float_magnitude64(const Vec3Float *v1) { + double dot = {0}; + dot += v1->values[0] * v1->values[0]; + dot += v1->values[1] * v1->values[1]; + dot += v1->values[2] * v1->values[2]; + double res = sqrt(dot); + return res; +} + +linagen_fn float vec3float_distance(const Vec3Float *restrict v1, const Vec3Float *restrict v2) { + Vec3Float diff = {0}; + diff.values[0] = v1->values[0] - v2->values[0]; + diff.values[1] = v1->values[1] - v2->values[1]; + diff.values[2] = v1->values[2] - v2->values[2]; + float dot = {0}; + dot += diff.values[0] * diff.values[0]; + dot += diff.values[1] * diff.values[1]; + dot += diff.values[2] * diff.values[2]; + float res = sqrtf(dot); + return res; +} + +linagen_fn float vec3float_distance2(const Vec3Float *restrict v1, const Vec3Float *restrict v2) { + Vec3Float diff = {0}; + diff.values[0] = v1->values[0] - v2->values[0]; + diff.values[1] = v1->values[1] - v2->values[1]; + diff.values[2] = v1->values[2] - v2->values[2]; + float dot = {0}; + dot += diff.values[0] * diff.values[0]; + dot += diff.values[1] * diff.values[1]; + dot += diff.values[2] * diff.values[2]; + return dot; +} + + +linagen_fn void vec5float_add(Vec5Float *res, const Vec5Float *v1, const Vec5Float *v2) { + res->values[0] = v1->values[0] + v2->values[0]; + res->values[1] = v1->values[1] + v2->values[1]; + res->values[2] = v1->values[2] + v2->values[2]; + res->values[3] = v1->values[3] + v2->values[3]; + res->values[4] = v1->values[4] + v2->values[4]; +} + +linagen_fn void vec5float_sub(Vec5Float *res, const Vec5Float *v1, const Vec5Float *v2) { + res->values[0] = v1->values[0] - v2->values[0]; + res->values[1] = v1->values[1] - v2->values[1]; + res->values[2] = v1->values[2] - v2->values[2]; + res->values[3] = v1->values[3] - v2->values[3]; + res->values[4] = v1->values[4] - v2->values[4]; +} + +linagen_fn void vec5float_hadamard_prod(Vec5Float *res, const Vec5Float *v1, const Vec5Float *v2) { + res->values[0] = v1->values[0] * v2->values[0]; + res->values[1] = v1->values[1] * v2->values[1]; + res->values[2] = v1->values[2] * v2->values[2]; + res->values[3] = v1->values[3] * v2->values[3]; + res->values[4] = v1->values[4] * v2->values[4]; +} + +linagen_fn void vec5float_hadamard_div(Vec5Float *res, const Vec5Float *v1, const Vec5Float *v2) { + res->values[0] = v1->values[0] / v2->values[0]; + res->values[1] = v1->values[1] / v2->values[1]; + res->values[2] = v1->values[2] / v2->values[2]; + res->values[3] = v1->values[3] / v2->values[3]; + res->values[4] = v1->values[4] / v2->values[4]; +} + +linagen_fn void vec5float_scale(Vec5Float *res, const Vec5Float *v1, float k) { + res->values[0] = v1->values[0] * k; + res->values[1] = v1->values[1] * k; + res->values[2] = v1->values[2] * k; + res->values[3] = v1->values[3] * k; + res->values[4] = v1->values[4] * k; +} + +linagen_fn bool vec5float_equal(const Vec5Float *restrict v1, const Vec5Float *restrict v2) { + return v1->values[0] == v2->values[0] && + v1->values[1] == v2->values[1] && + v1->values[2] == v2->values[2] && + v1->values[3] == v2->values[3] && + v1->values[4] == v2->values[4]; +} + +linagen_fn bool vec5float_near(const Vec5Float *restrict v1, const Vec5Float *restrict v2, float eps) { + return ((float)v1->values[0] + eps >= v2->values[0] && (float)v1->values[0] - eps <= v2->values[0]) && + ((float)v1->values[1] + eps >= v2->values[1] && (float)v1->values[1] - eps <= v2->values[1]) && + ((float)v1->values[2] + eps >= v2->values[2] && (float)v1->values[2] - eps <= v2->values[2]) && + ((float)v1->values[3] + eps >= v2->values[3] && (float)v1->values[3] - eps <= v2->values[3]) && + ((float)v1->values[4] + eps >= v2->values[4] && (float)v1->values[4] - eps <= v2->values[4]); +} + +linagen_fn void vec5float_lerp(Vec5Float *restrict res, const Vec5Float *restrict start, const Vec5Float *restrict end, float t) { + res->values[0] = start->values[0] * (1 - t) + end->values[0] * t; + res->values[1] = start->values[1] * (1 - t) + end->values[1] * t; + res->values[2] = start->values[2] * (1 - t) + end->values[2] * t; + res->values[3] = start->values[3] * (1 - t) + end->values[3] * t; + res->values[4] = start->values[4] * (1 - t) + end->values[4] * t; +} + +linagen_fn void vec5float_normalize(Vec5Float *res, const Vec5Float *v1) { + float dot = {0}; + dot += v1->values[0] * v1->values[0]; + dot += v1->values[1] * v1->values[1]; + dot += v1->values[2] * v1->values[2]; + dot += v1->values[3] * v1->values[3]; + dot += v1->values[4] * v1->values[4]; + float magnitude = sqrtf((float)dot); + if (magnitude == 0.f) { return; } + res->values[0] = v1->values[0] / magnitude; + res->values[1] = v1->values[1] / magnitude; + res->values[2] = v1->values[2] / magnitude; + res->values[3] = v1->values[3] / magnitude; + res->values[4] = v1->values[4] / magnitude; +} + +linagen_fn float vec5float_dot(const Vec5Float *v1, const Vec5Float *v2) { + float res = {0}; + res += v1->values[0] * v2->values[0]; + res += v1->values[1] * v2->values[1]; + res += v1->values[2] * v2->values[2]; + res += v1->values[3] * v2->values[3]; + res += v1->values[4] * v2->values[4]; + return res; +} + +linagen_fn float vec5float_magnitude(const Vec5Float *v1) { + float dot = {0}; + dot += v1->values[0] * v1->values[0]; + dot += v1->values[1] * v1->values[1]; + dot += v1->values[2] * v1->values[2]; + dot += v1->values[3] * v1->values[3]; + dot += v1->values[4] * v1->values[4]; + float res = sqrtf(dot); + return res; +} + +linagen_fn double vec5float_magnitude64(const Vec5Float *v1) { + double dot = {0}; + dot += v1->values[0] * v1->values[0]; + dot += v1->values[1] * v1->values[1]; + dot += v1->values[2] * v1->values[2]; + dot += v1->values[3] * v1->values[3]; + dot += v1->values[4] * v1->values[4]; + double res = sqrt(dot); + return res; +} + +linagen_fn float vec5float_distance(const Vec5Float *restrict v1, const Vec5Float *restrict v2) { + Vec5Float diff = {0}; + diff.values[0] = v1->values[0] - v2->values[0]; + diff.values[1] = v1->values[1] - v2->values[1]; + diff.values[2] = v1->values[2] - v2->values[2]; + diff.values[3] = v1->values[3] - v2->values[3]; + diff.values[4] = v1->values[4] - v2->values[4]; + float dot = {0}; + dot += diff.values[0] * diff.values[0]; + dot += diff.values[1] * diff.values[1]; + dot += diff.values[2] * diff.values[2]; + dot += diff.values[3] * diff.values[3]; + dot += diff.values[4] * diff.values[4]; + float res = sqrtf(dot); + return res; +} + +linagen_fn float vec5float_distance2(const Vec5Float *restrict v1, const Vec5Float *restrict v2) { + Vec5Float diff = {0}; + diff.values[0] = v1->values[0] - v2->values[0]; + diff.values[1] = v1->values[1] - v2->values[1]; + diff.values[2] = v1->values[2] - v2->values[2]; + diff.values[3] = v1->values[3] - v2->values[3]; + diff.values[4] = v1->values[4] - v2->values[4]; + float dot = {0}; + dot += diff.values[0] * diff.values[0]; + dot += diff.values[1] * diff.values[1]; + dot += diff.values[2] * diff.values[2]; + dot += diff.values[3] * diff.values[3]; + dot += diff.values[4] * diff.values[4]; + return dot; +} + + +linagen_fn void mat3float_add(Mat3Float *res, const Mat3Float *m1, const Mat3Float *m2) { + res->values[0][0] = m1->values[0][0] + m2->values[0][0]; + res->values[0][1] = m1->values[0][1] + m2->values[0][1]; + res->values[0][2] = m1->values[0][2] + m2->values[0][2]; + res->values[1][0] = m1->values[1][0] + m2->values[1][0]; + res->values[1][1] = m1->values[1][1] + m2->values[1][1]; + res->values[1][2] = m1->values[1][2] + m2->values[1][2]; + res->values[2][0] = m1->values[2][0] + m2->values[2][0]; + res->values[2][1] = m1->values[2][1] + m2->values[2][1]; + res->values[2][2] = m1->values[2][2] + m2->values[2][2]; +} + +linagen_fn void mat3float_sub(Mat3Float *res, const Mat3Float *m1, const Mat3Float *m2) { + res->values[0][0] = m1->values[0][0] - m2->values[0][0]; + res->values[0][1] = m1->values[0][1] - m2->values[0][1]; + res->values[0][2] = m1->values[0][2] - m2->values[0][2]; + res->values[1][0] = m1->values[1][0] - m2->values[1][0]; + res->values[1][1] = m1->values[1][1] - m2->values[1][1]; + res->values[1][2] = m1->values[1][2] - m2->values[1][2]; + res->values[2][0] = m1->values[2][0] - m2->values[2][0]; + res->values[2][1] = m1->values[2][1] - m2->values[2][1]; + res->values[2][2] = m1->values[2][2] - m2->values[2][2]; +} + +linagen_fn void mat3float_hadamard_prod(Mat3Float *res, const Mat3Float *m1, const Mat3Float *m2) { + res->values[0][0] = m1->values[0][0] * m2->values[0][0]; + res->values[0][1] = m1->values[0][1] * m2->values[0][1]; + res->values[0][2] = m1->values[0][2] * m2->values[0][2]; + res->values[1][0] = m1->values[1][0] * m2->values[1][0]; + res->values[1][1] = m1->values[1][1] * m2->values[1][1]; + res->values[1][2] = m1->values[1][2] * m2->values[1][2]; + res->values[2][0] = m1->values[2][0] * m2->values[2][0]; + res->values[2][1] = m1->values[2][1] * m2->values[2][1]; + res->values[2][2] = m1->values[2][2] * m2->values[2][2]; +} + +linagen_fn void mat3float_hadamard_div(Mat3Float *res, const Mat3Float *m1, const Mat3Float *m2) { + res->values[0][0] = m1->values[0][0] / m2->values[0][0]; + res->values[0][1] = m1->values[0][1] / m2->values[0][1]; + res->values[0][2] = m1->values[0][2] / m2->values[0][2]; + res->values[1][0] = m1->values[1][0] / m2->values[1][0]; + res->values[1][1] = m1->values[1][1] / m2->values[1][1]; + res->values[1][2] = m1->values[1][2] / m2->values[1][2]; + res->values[2][0] = m1->values[2][0] / m2->values[2][0]; + res->values[2][1] = m1->values[2][1] / m2->values[2][1]; + res->values[2][2] = m1->values[2][2] / m2->values[2][2]; +} + +linagen_fn void mat3float_scale(Mat3Float *res, const Mat3Float *m1, float k) { + res->values[0][0] = m1->values[0][0] * k; + res->values[0][1] = m1->values[0][1] * k; + res->values[0][2] = m1->values[0][2] * k; + res->values[1][0] = m1->values[1][0] * k; + res->values[1][1] = m1->values[1][1] * k; + res->values[1][2] = m1->values[1][2] * k; + res->values[2][0] = m1->values[2][0] * k; + res->values[2][1] = m1->values[2][1] * k; + res->values[2][2] = m1->values[2][2] * k; +} + +linagen_fn void mat3float_dot(Mat3Float *restrict res, const Mat3Float *m1, const Mat3Float *m2) { + res->values[0][0] = (m1->values[0][0] * m2->values[0][0]) + (m1->values[1][0] * m2->values[0][1]) + (m1->values[2][0] * m2->values[0][2]); + res->values[0][1] = (m1->values[0][1] * m2->values[0][0]) + (m1->values[1][1] * m2->values[0][1]) + (m1->values[2][1] * m2->values[0][2]); + res->values[0][2] = (m1->values[0][2] * m2->values[0][0]) + (m1->values[1][2] * m2->values[0][1]) + (m1->values[2][2] * m2->values[0][2]); + res->values[1][0] = (m1->values[0][0] * m2->values[1][0]) + (m1->values[1][0] * m2->values[1][1]) + (m1->values[2][0] * m2->values[1][2]); + res->values[1][1] = (m1->values[0][1] * m2->values[1][0]) + (m1->values[1][1] * m2->values[1][1]) + (m1->values[2][1] * m2->values[1][2]); + res->values[1][2] = (m1->values[0][2] * m2->values[1][0]) + (m1->values[1][2] * m2->values[1][1]) + (m1->values[2][2] * m2->values[1][2]); + res->values[2][0] = (m1->values[0][0] * m2->values[2][0]) + (m1->values[1][0] * m2->values[2][1]) + (m1->values[2][0] * m2->values[2][2]); + res->values[2][1] = (m1->values[0][1] * m2->values[2][0]) + (m1->values[1][1] * m2->values[2][1]) + (m1->values[2][1] * m2->values[2][2]); + res->values[2][2] = (m1->values[0][2] * m2->values[2][0]) + (m1->values[1][2] * m2->values[2][1]) + (m1->values[2][2] * m2->values[2][2]); +} + +linagen_fn void mat3float_mulv(Vec3Float *restrict res, const Mat3Float *restrict m, const Vec3Float *restrict v) { + res->values[0] = (m->values[0][0] * v->values[0]) + (m->values[1][0] * v->values[1]) + (m->values[2][0] * v->values[2]); + res->values[1] = (m->values[0][1] * v->values[0]) + (m->values[1][1] * v->values[1]) + (m->values[2][1] * v->values[2]); + res->values[2] = (m->values[0][2] * v->values[0]) + (m->values[1][2] * v->values[1]) + (m->values[2][2] * v->values[2]); +} + +linagen_fn void mat3float_identity(Mat3Float *res) { + memset(res, 0, sizeof *res); + res->values[0][0] = 1; + res->values[1][1] = 1; + res->values[2][2] = 1; +} + +#endif // CB_LINEAR_ALGEBRA_NO_IMPL +#endif // CB_LINEAR_ALGEBRA_H diff --git a/examples/e0-code-generation/main.c b/examples/e0-code-generation/main.c new file mode 100644 index 0000000..7fb82a6 --- /dev/null +++ b/examples/e0-code-generation/main.c @@ -0,0 +1,38 @@ +#include +#include +#include +#include +#include + +#include "linear_algebra.h" + +int main(void) { + Vec3Float v1 = { 12, 2 }; + Vec3Float v2 = { 8, 3, 6 }; + vec3float_add(&v1, &v1, &v2); + for (int i = 0; i < 3; ++i) { + printf("%.2f, ", v1.values[i]); + } + printf("\b\b\n\n"); + + Mat3Float m1 = { + 2, 3, 5, // col 0 + 1, 4, 2, // col 1 + 3, 1, 3, // col 2 + }; + Mat3Float m2 = { + 1, 4, 3, // col 0 + 2, 1, 2, // col 1 + 0, 2, 1, // col 2 + }; + Mat3Float m3 = {0}; + mat3float_dot(&m3, &m1, &m2); + printf("M1 ⋅ M2:\n"); + for (int i = 0; i < 3; ++i) { + printf("\tCol %d: ", i); + for (int j = 0; j < 3; ++j) { + printf("%.2f ", m3.values[i][j]); + } + printf("\n"); + } +} diff --git a/examples/e1-testing/cbuild.c b/examples/e1-testing/cbuild.c new file mode 100644 index 0000000..2e2a130 --- /dev/null +++ b/examples/e1-testing/cbuild.c @@ -0,0 +1,17 @@ +#include "../../cbuild.h" +#include "../../extra/cbuild_tests.h" + +CB_TEST(t1) { + cb_assert(!"🎂" && "The cake is a lie"); +} + +CB_TEST(t2) { + int res = 0; + for (int i = 1; i <= 100; ++i) { res += i; } + cb_assert(res == (100 * 101)/2 && "You shouldn't see this message"); +} + +int32_t main(int32_t argc, char **argv) { + cb_rebuild_self(argc, argv); + cb_test_run(); +} diff --git a/extra/code_generation.h b/extra/cbuild_codegen.h similarity index 96% rename from extra/code_generation.h rename to extra/cbuild_codegen.h index f9202c5..88855f2 100644 --- a/extra/code_generation.h +++ b/extra/cbuild_codegen.h @@ -1,5 +1,5 @@ -#ifndef CBUILD_EXTRA_CODE_GENERATION_H -#define CBUILD_EXTRA_CODE_GENERATION_H +#ifndef CBUILD_EXTRA_CODEGEN_H +#define CBUILD_EXTRA_CODEGEN_H typedef struct { char **values; diff --git a/extra/linear_algebra.h b/extra/cbuild_linagen.h similarity index 99% rename from extra/linear_algebra.h rename to extra/cbuild_linagen.h index c00390b..5f6a796 100644 --- a/extra/linear_algebra.h +++ b/extra/cbuild_linagen.h @@ -1,5 +1,5 @@ -#ifndef CBUILD_EXTRA_LINEAR_ALGEBRA_H -#define CBUILD_EXTRA_LINEAR_ALGEBRA_H +#ifndef CBUILD_EXTRA_LINAGEN_H +#define CBUILD_EXTRA_LINAGEN_H #include @@ -19,7 +19,6 @@ static void cb_linagen_typedef_vecn(CB_Generator *gen, char *type, int32_t n, ...); static void cb_linagen_typedef_vecn_unnamed(CB_Generator *gen, char *type, int32_t n); - static void cb_linagen_typedef_matnn(CB_Generator *gen, char *type, int32_t n); @@ -44,15 +43,12 @@ cb_linagen_defun_vecn_near(CB_Generator *gen, char *type, static inline void cb_linagen_defun_vecn_lerp(CB_Generator *gen, char *type, int32_t n, bool implementation); -static inline void -cb_linagen_defun_vec3_cross(CB_Generator *gen, char *type, bool implementation); static void cb_linagen_defun_vecn_scale(CB_Generator *gen, char *type, int32_t n, bool implementation); static void cb_linagen_defun_vecn_normalize(CB_Generator *gen, char *type, int32_t n, bool implementation); - static void cb_linagen_defun_vecn_dot(CB_Generator *gen, char *type, int32_t n, bool implementation); @@ -72,6 +68,9 @@ static void cb_linagen_defun_vecn_distance2(CB_Generator *gen, char *type, int32_t n, bool implementation); +static inline void +cb_linagen_defun_vec3_cross(CB_Generator *gen, char *type, bool implementation); + static void cb_linagen_defun_matnn_scale(CB_Generator *gen, char *type, int32_t n, bool implementation); diff --git a/extra/tests.h b/extra/cbuild_tests.h similarity index 97% rename from extra/tests.h rename to extra/cbuild_tests.h index d1cc27c..49708a7 100644 --- a/extra/tests.h +++ b/extra/cbuild_tests.h @@ -1,5 +1,5 @@ -#ifndef TESTS_H -#define TESTS_H +#ifndef CBUILD_EXTRA_TESTS_H +#define CBUILD_EXTRA_TESTS_H #include -- 2.52.0