]> git.leonardobizzoni.com Git - CBuild/commitdiff
renamed files + examples
authorLeonardoBizzoni <leo2002714@gmail.com>
Tue, 21 Oct 2025 09:51:44 +0000 (11:51 +0200)
committerLeonardoBizzoni <leo2002714@gmail.com>
Tue, 21 Oct 2025 09:51:44 +0000 (11:51 +0200)
cbuild.h
examples/e0-code-generation/cbuild.c [new file with mode: 0644]
examples/e0-code-generation/linear_algebra.h [new file with mode: 0644]
examples/e0-code-generation/main.c [new file with mode: 0644]
examples/e1-testing/cbuild.c [new file with mode: 0644]
extra/cbuild_codegen.h [moved from extra/code_generation.h with 96% similarity]
extra/cbuild_linagen.h [moved from extra/linear_algebra.h with 99% similarity]
extra/cbuild_tests.h [moved from extra/tests.h with 97% similarity]

index b477321676e6f5918e5107ee0396cdd567c31342..14e2a1d78b598a215c422c0f1815463dc3d0a11e 100644 (file)
--- a/cbuild.h
+++ b/cbuild.h
@@ -75,6 +75,7 @@ typedef enum {false, true} bool;
 #  define WIN32_LEAN_AND_MEAN
 #  include <windows.h>
 #  include <direct.h>
+#  include <io.h>
 #  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 (file)
index 0000000..c922a6e
--- /dev/null
@@ -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 (file)
index 0000000..019305e
--- /dev/null
@@ -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 (file)
index 0000000..7fb82a6
--- /dev/null
@@ -0,0 +1,38 @@
+#include <stdio.h>
+#include <math.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#include <string.h>
+
+#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 (file)
index 0000000..2e2a130
--- /dev/null
@@ -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();
+}
similarity index 96%
rename from extra/code_generation.h
rename to extra/cbuild_codegen.h
index f9202c51292726d07061dcb33879686b9fce0c92..88855f28e1aefcd570e33dea988b11a537a36746 100644 (file)
@@ -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;
similarity index 99%
rename from extra/linear_algebra.h
rename to extra/cbuild_linagen.h
index c00390b5c72eb09884ba9b14e0ccdfac8f14a8c1..5f6a7964bcb133f5eb54d9c7f1d2ff4e8ae9e963 100644 (file)
@@ -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 <stdarg.h>
 
@@ -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);
similarity index 97%
rename from extra/tests.h
rename to extra/cbuild_tests.h
index d1cc27c89c368a68d37fba44a15863531cc95720..49708a75fec112076542d7dbb27e4c7cef91339e 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef TESTS_H
-#define TESTS_H
+#ifndef CBUILD_EXTRA_TESTS_H
+#define CBUILD_EXTRA_TESTS_H
 
 #include <setjmp.h>