summaryrefslogtreecommitdiff
path: root/bindgen
diff options
context:
space:
mode:
authoromniscient <17525998+omnisci3nce@users.noreply.github.com>2024-07-28 00:10:00 +1000
committeromniscient <17525998+omnisci3nce@users.noreply.github.com>2024-07-28 00:10:00 +1000
commit7b86e3251a28406862fe16d49f8533beb8ca3150 (patch)
treea90166418ada7ad88500843ce8881a453c1d4721 /bindgen
parent6b004c5ac6a25f1020774276803b62e8619ea61e (diff)
start on ocaml bindings
Diffstat (limited to 'bindgen')
-rw-r--r--bindgen/ocaml/bin/dune4
-rw-r--r--bindgen/ocaml/bin/main.ml1
-rw-r--r--bindgen/ocaml/bindings/bindings_sys.ml49
-rw-r--r--bindgen/ocaml/bindings/caml_bindings.c132
-rw-r--r--bindgen/ocaml/bindings/celeritas.h21
-rw-r--r--bindgen/ocaml/bindings/dune13
-rw-r--r--bindgen/ocaml/celeritas.opam31
-rw-r--r--bindgen/ocaml/dune-project26
-rw-r--r--bindgen/ocaml/lib/dune2
-rw-r--r--bindgen/ocaml/lib/lib.ml0
-rw-r--r--bindgen/ocaml/lib/maths.ml42
-rw-r--r--bindgen/ocaml/test/dune2
-rw-r--r--bindgen/ocaml/test/test_celeritas.ml0
13 files changed, 323 insertions, 0 deletions
diff --git a/bindgen/ocaml/bin/dune b/bindgen/ocaml/bin/dune
new file mode 100644
index 0000000..fd2576a
--- /dev/null
+++ b/bindgen/ocaml/bin/dune
@@ -0,0 +1,4 @@
+(executable
+ (public_name celeritas)
+ (name main)
+ (libraries celeritas))
diff --git a/bindgen/ocaml/bin/main.ml b/bindgen/ocaml/bin/main.ml
new file mode 100644
index 0000000..7bf6048
--- /dev/null
+++ b/bindgen/ocaml/bin/main.ml
@@ -0,0 +1 @@
+let () = print_endline "Hello, World!"
diff --git a/bindgen/ocaml/bindings/bindings_sys.ml b/bindgen/ocaml/bindings/bindings_sys.ml
new file mode 100644
index 0000000..1c100e9
--- /dev/null
+++ b/bindgen/ocaml/bindings/bindings_sys.ml
@@ -0,0 +1,49 @@
+(* automatically generated by ocaml-bindgen 0.0.1 *)
+
+type lifetime =
+ | Function
+ (** The value can live for the lifetime of the function call, which upon return will signal that the
+ value can be dropped (finalizer?) *)
+ | Ocaml (** The value is managed by the OCaml runtime *)
+ | C
+ (** The value is allocated and passed to C which is then in charge of cleaning it up *)
+
+type 'a cptr = { lifetime : lifetime; addr : nativeint }
+
+external bindgen_alloc : size:int -> nativeint = "bindgen_alloc"
+external bindgen_free : nativeint -> unit = "bindgen_free"
+external bindgen_alloc_string : string -> nativeint = "bindgen_alloc_string"
+
+let sizeof _ = 4 (* TODO: how to handle different types? *)
+
+let create_ptr (value : 'a) : 'a cptr =
+ let addr = bindgen_alloc ~size:(sizeof value) in
+ print_endline ("Addr: " ^ Nativeint.to_string addr);
+ Gc.finalise bindgen_free addr;
+ { lifetime = Ocaml; addr }
+
+let make_cstr (s: string) : char cptr =
+ let addr = bindgen_alloc_string s in
+ { lifetime = Ocaml; addr }
+
+type nonrec core
+type nonrec glfwwindow
+external get_global_core : unit -> core cptr = "caml_get_global_core"
+external core_Bringup :
+ optional_window:unit cptr -> unit = "caml_core_Bringup"
+external frame_Begin : unit -> unit = "caml_frame_Begin"
+external frame_Draw : unit -> unit = "caml_frame_Draw"
+external frame_End : unit -> unit = "caml_frame_End"
+type nonrec vec2 = {
+ x: float ;
+ y: float }
+type nonrec vec3 = {
+ x: float ;
+ y: float ;
+ z: float }
+type nonrec vec4 = {
+ x: float ;
+ y: float ;
+ z: float ;
+ w: float }
+external vec3_add : b:vec3 -> a:vec3 -> vec3 = "caml_vec3_add"
diff --git a/bindgen/ocaml/bindings/caml_bindings.c b/bindgen/ocaml/bindings/caml_bindings.c
new file mode 100644
index 0000000..4a7dc70
--- /dev/null
+++ b/bindgen/ocaml/bindings/caml_bindings.c
@@ -0,0 +1,132 @@
+/* automatically generated by ocaml-bindgen 0.0.1 */
+
+#include "celeritas.h"
+#include <caml/alloc.h>
+#include <caml/callback.h>
+#include <caml/fail.h>
+#include <caml/memory.h>
+#include <caml/mlvalues.h>
+#include <caml/unixsupport.h>
+Core* caml_get_global_core() {
+ CAMLparam0();
+ CAMLlocal1(result);
+ result = get_global_core();
+ CAMLreturn(result);
+}
+
+void caml_core_Bringup(value caml_optional_window) {
+ CAMLparam1(caml_optional_window);
+ void* optional_window = Nativeint_val(Field(caml_optional_window, 1));
+ core_Bringup(optional_window);
+ CAMLreturn0;
+}
+
+void caml_frame_Begin() {
+ CAMLparam0();
+ frame_Begin();
+ CAMLreturn0;
+}
+
+void caml_frame_Draw() {
+ CAMLparam0();
+ frame_Draw();
+ CAMLreturn0;
+}
+
+void caml_frame_End() {
+ CAMLparam0();
+ frame_End();
+ CAMLreturn0;
+}
+
+Vec2* caml_Vec2_of_value(value caml_x) {
+ Vec2* x = malloc(sizeof(struct Vec2));
+ x->x = Double_val(Field(caml_x, 0));
+ x->y = Double_val(Field(caml_x, 1));
+ return x;
+}
+
+value caml_Vec2_to_value(struct Vec2* x) {
+ CAMLparam0();
+ CAMLlocal1(caml_x);
+ caml_x = caml_alloc_tuple(2);
+ Store_field(caml_x, 0, caml_copy_double(x->x));
+ Store_field(caml_x, 1, caml_copy_double(x->y));
+ CAMLreturn(caml_x);
+}
+
+Vec3* caml_Vec3_of_value(value caml_x) {
+ Vec3* x = malloc(sizeof(struct Vec3));
+ x->x = Double_val(Field(caml_x, 0));
+ x->y = Double_val(Field(caml_x, 1));
+ x->z = Double_val(Field(caml_x, 2));
+ return x;
+}
+
+value caml_Vec3_to_value(struct Vec3* x) {
+ CAMLparam0();
+ CAMLlocal1(caml_x);
+ caml_x = caml_alloc_tuple(3);
+ Store_field(caml_x, 0, caml_copy_double(x->x));
+ Store_field(caml_x, 1, caml_copy_double(x->y));
+ Store_field(caml_x, 2, caml_copy_double(x->z));
+ CAMLreturn(caml_x);
+}
+
+Vec4* caml_Vec4_of_value(value caml_x) {
+ Vec4* x = malloc(sizeof(struct Vec4));
+ x->x = Double_val(Field(caml_x, 0));
+ x->y = Double_val(Field(caml_x, 1));
+ x->z = Double_val(Field(caml_x, 2));
+ x->w = Double_val(Field(caml_x, 3));
+ return x;
+}
+
+value caml_Vec4_to_value(struct Vec4* x) {
+ CAMLparam0();
+ CAMLlocal1(caml_x);
+ caml_x = caml_alloc_tuple(4);
+ Store_field(caml_x, 0, caml_copy_double(x->x));
+ Store_field(caml_x, 1, caml_copy_double(x->y));
+ Store_field(caml_x, 2, caml_copy_double(x->z));
+ Store_field(caml_x, 3, caml_copy_double(x->w));
+ CAMLreturn(caml_x);
+}
+
+Vec3 caml_vec3_add(value caml_a, value caml_b) {
+ CAMLparam2(caml_a, caml_b);
+ CAMLlocal1(result);
+ Vec3 a = caml_Vec3_of_value(caml_a);
+ Vec3 b = caml_Vec3_of_value(caml_b);
+ result = vec3_add(a, b);
+ CAMLreturn(result);
+}
+
+
+#include <stdlib.h>
+value bindgen_alloc(value caml_size) {
+ CAMLparam1(caml_size);
+
+ // Convert OCaml integer to C size
+ size_t size = Int_val(caml_size);
+ printf("Allocated size %ld \n", size);
+
+ void* ptr = malloc(sizeof(size));
+ if (ptr == NULL) {
+ // TODO: handle allocation failure
+ CAMLreturn(Val_unit);
+ }
+
+ // Wrap the pointer as an OCaml value
+ CAMLreturn(caml_copy_nativeint(ptr));
+}
+
+void bindgen_free(value caml_addr) {
+ free(Nativeint_val(caml_addr));
+}
+
+value bindgen_alloc_string(value caml_string) {
+ CAMLparam1(caml_string);
+ char* str = String_val(caml_string);
+ CAMLreturn(caml_copy_nativeint((intnat)str));
+}
diff --git a/bindgen/ocaml/bindings/celeritas.h b/bindgen/ocaml/bindings/celeritas.h
new file mode 100644
index 0000000..fce4d62
--- /dev/null
+++ b/bindgen/ocaml/bindings/celeritas.h
@@ -0,0 +1,21 @@
+/* The Goal of this file is to test ocaml-bindgen on it to start moving development over into OCaml */
+
+// #include <stdbool.h>
+// #include <stdint.h>
+
+typedef struct Core Core;
+typedef struct GLFWwindow GLFWwindow;
+
+Core* get_global_core();
+void core_Bringup(void* optional_window);
+
+void frame_Begin();
+void frame_Draw();
+void frame_End();
+
+
+struct Vec2 { float x; float y; };
+typedef struct Vec3 { float x; float y; float z; } Vec3;
+struct Vec4 { float x; float y; float z; float w; };
+
+Vec3 vec3_add(Vec3 a, Vec3 b); \ No newline at end of file
diff --git a/bindgen/ocaml/bindings/dune b/bindgen/ocaml/bindings/dune
new file mode 100644
index 0000000..673491d
--- /dev/null
+++ b/bindgen/ocaml/bindings/dune
@@ -0,0 +1,13 @@
+(library
+ (name bindings)
+ (libraries bindgen))
+
+(rule
+ (alias gen_bindings)
+ (deps celeritas.h)
+ (targets bindings_sys.ml caml_bindings.c)
+ (action
+ (run
+ %{bin:ocaml-bindgen} celeritas.h bindings)
+ )
+ (mode (promote (until-clean)))) \ No newline at end of file
diff --git a/bindgen/ocaml/celeritas.opam b/bindgen/ocaml/celeritas.opam
new file mode 100644
index 0000000..bd5c0c8
--- /dev/null
+++ b/bindgen/ocaml/celeritas.opam
@@ -0,0 +1,31 @@
+# This file is generated by dune, edit dune-project instead
+opam-version: "2.0"
+synopsis: "A short synopsis"
+description: "A longer description"
+maintainer: ["Maintainer Name"]
+authors: ["Author Name"]
+license: "LICENSE"
+tags: ["topics" "to describe" "your" "project"]
+homepage: "https://github.com/username/reponame"
+doc: "https://url/to/documentation"
+bug-reports: "https://github.com/username/reponame/issues"
+depends: [
+ "ocaml"
+ "dune" {>= "3.14"}
+ "odoc" {with-doc}
+]
+build: [
+ ["dune" "subst"] {dev}
+ [
+ "dune"
+ "build"
+ "-p"
+ name
+ "-j"
+ jobs
+ "@install"
+ "@runtest" {with-test}
+ "@doc" {with-doc}
+ ]
+]
+dev-repo: "git+https://github.com/username/reponame.git"
diff --git a/bindgen/ocaml/dune-project b/bindgen/ocaml/dune-project
new file mode 100644
index 0000000..3f94e1d
--- /dev/null
+++ b/bindgen/ocaml/dune-project
@@ -0,0 +1,26 @@
+(lang dune 3.14)
+
+(name celeritas)
+
+(generate_opam_files true)
+
+(source
+ (github username/reponame))
+
+(authors "Author Name")
+
+(maintainers "Maintainer Name")
+
+(license LICENSE)
+
+(documentation https://url/to/documentation)
+
+(package
+ (name celeritas)
+ (synopsis "A short synopsis")
+ (description "A longer description")
+ (depends ocaml dune)
+ (tags
+ (topics "to describe" your project)))
+
+; See the complete stanza docs at https://dune.readthedocs.io/en/stable/dune-files.html#dune-project
diff --git a/bindgen/ocaml/lib/dune b/bindgen/ocaml/lib/dune
new file mode 100644
index 0000000..6803cec
--- /dev/null
+++ b/bindgen/ocaml/lib/dune
@@ -0,0 +1,2 @@
+(library
+ (name celeritas))
diff --git a/bindgen/ocaml/lib/lib.ml b/bindgen/ocaml/lib/lib.ml
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/bindgen/ocaml/lib/lib.ml
diff --git a/bindgen/ocaml/lib/maths.ml b/bindgen/ocaml/lib/maths.ml
new file mode 100644
index 0000000..8810f48
--- /dev/null
+++ b/bindgen/ocaml/lib/maths.ml
@@ -0,0 +1,42 @@
+(** Maths and linear algebra.
+ Ideally we should avoid doing large amounts of math computation in OCaml,
+ and so exposing more functionality for batch processing via Core is preferred *)
+
+(** Base functions that a 2D Vector must support *)
+module type Vector = sig
+ type t
+
+ val add : t -> t -> t
+ val sub : t -> t -> t
+ val scalar_mul : float -> t -> t
+ val dot : t -> t -> float
+end
+
+(** Functor that takes a module implementing the Vector signature and returns
+ a module that implements most vector space operations *)
+module VectorSpace (V : Vector) = struct
+ include V
+
+ let scalar_div s v = scalar_mul (1. /. s) v
+ let neg v = scalar_mul (-1.0) v
+ let length_squared v = dot v v
+ let length v = sqrt (dot v v)
+ let magnitude = length
+
+ let normalize v =
+ let len = length v in
+ if len > 0.0 then scalar_mul (1.0 /. len) v else v
+
+ let distance u v = sub u v |> length
+end
+
+module Vec3Float = struct
+ type t = { x : float; y : float; z : float }
+
+ let add u v = { x = u.x +. v.x; y = u.y +. v.y; z = u.z +. v.z }
+ let sub u v = { x = u.x -. v.x; y = u.y -. v.y; z = u.z -. v.z }
+ let scalar_mul k v = { x = k *. v.x; y = k *. v.y; z = k *. v.z }
+ let dot u v = (u.x *. v.x) +. (u.y *. v.y) +. (u.z *. v.z)
+end
+
+module Vec3 = VectorSpace (Vec3Float) \ No newline at end of file
diff --git a/bindgen/ocaml/test/dune b/bindgen/ocaml/test/dune
new file mode 100644
index 0000000..bf9e4e1
--- /dev/null
+++ b/bindgen/ocaml/test/dune
@@ -0,0 +1,2 @@
+(test
+ (name test_celeritas))
diff --git a/bindgen/ocaml/test/test_celeritas.ml b/bindgen/ocaml/test/test_celeritas.ml
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/bindgen/ocaml/test/test_celeritas.ml