From 0732f2e06993eae672d9ef9cf3b942ffdd5c4b5f Mon Sep 17 00:00:00 2001 From: Omniscient Date: Sat, 2 Mar 2024 14:20:52 +1100 Subject: [PATCH 01/12] add public_name stanza --- bindgen/dune | 1 + 1 file changed, 1 insertion(+) diff --git a/bindgen/dune b/bindgen/dune index 980ff1b..cc0caf2 100644 --- a/bindgen/dune +++ b/bindgen/dune @@ -1,4 +1,5 @@ (library + (public_name bindgen) (name bindgen) (preprocess (pps ppxlib.metaquot)) From d832014d2d1310684379d7413e76dc5caceaa7cc Mon Sep 17 00:00:00 2001 From: Omniscient Date: Sat, 2 Mar 2024 15:02:23 +1100 Subject: [PATCH 02/12] add dog weight as float to example --- examples/doggo.c | 4 ++-- examples/doggo.h | 1 + examples/main.ml | 10 ++++++++-- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/examples/doggo.c b/examples/doggo.c index 60a4784..6df51ff 100644 --- a/examples/doggo.c +++ b/examples/doggo.c @@ -11,5 +11,5 @@ static const char* BreedToString[4] = { void eleven_out_of_ten_majestic_af(Doggo* pupper) { printf("doggo says %d\n", pupper->many); printf("doggo is a %s\n", BreedToString[pupper->breed]); -} - + printf("doggo weighs %.1fkg\n", pupper->weight); +} \ No newline at end of file diff --git a/examples/doggo.h b/examples/doggo.h index ea8d8dd..6a04634 100644 --- a/examples/doggo.h +++ b/examples/doggo.h @@ -9,6 +9,7 @@ typedef struct Doggo { int many; breed breed; char wow; + float weight; } Doggo; void eleven_out_of_ten_majestic_af(Doggo* pupper); diff --git a/examples/main.ml b/examples/main.ml index 120443f..0398f08 100644 --- a/examples/main.ml +++ b/examples/main.ml @@ -1,5 +1,11 @@ -Doggo.eleven_out_of_ten_majestic_af ~pupper:{ +open Doggo + +let pupper = { many=2112; wow='x'; - breed=C_Labrador + breed=C_Labrador; + weight=18.9; } + +let () = + Doggo.eleven_out_of_ten_majestic_af ~pupper \ No newline at end of file From 292906ac1aa0f1129d665f06b2bf375fb131a0a2 Mon Sep 17 00:00:00 2001 From: Omniscient Date: Sat, 2 Mar 2024 15:03:00 +1100 Subject: [PATCH 03/12] float primitive first pass --- bindgen/c.ml | 63 ++++++++++++++++++++++++++++++------------------- bindgen/caml.ml | 1 + bindgen/ir.ml | 3 ++- 3 files changed, 42 insertions(+), 25 deletions(-) diff --git a/bindgen/c.ml b/bindgen/c.ml index 20b4b41..cbee800 100644 --- a/bindgen/c.ml +++ b/bindgen/c.ml @@ -1,7 +1,7 @@ let caml_ = "caml_" type c_type = Prim of string | Struct of string | Ptr of c_type | Void -type c_prim = Int of int | Str of string +type c_prim = Int of int | Float of float | Str of string type t = | C_function of { @@ -23,7 +23,6 @@ type t = type program = t list - let pp_list sep pp_el fmt t = Format.pp_print_list ~pp_sep:(fun fmt () -> Format.fprintf fmt "%s" sep) @@ -66,6 +65,7 @@ and pp_type fmt (ctype : c_type) = and pp_prim fmt (prim : c_prim) = match prim with | Int d -> Format.fprintf fmt "%d" d + | Float f -> Format.fprintf fmt "%f" f | Str s -> Format.fprintf fmt "%s" s let decl dcl_type dcl_name dcl_value = C_decl { dcl_name; dcl_type; dcl_value } @@ -73,6 +73,7 @@ let call cc_name cc_args = C_call { cc_name; cc_args } let var x = C_variable x let assign asg_var asg_value = C_assign { asg_var; asg_value } let int x = C_prim (Int x) +let float f = C_prim (Float f) let string x = C_prim (Str x) let ptr_field pfa_name pfa_field = C_ptr_field_access { pfa_name; pfa_field } let typ t = C_type t @@ -90,7 +91,11 @@ let caml_alloc_tuple fields = let store_field var idx value = call "Store_field" [ var; int idx; value ] let val_int var name = call "Val_int" [ ptr_field var name ] -let int_val var idx = call "Int_val" [ call "Field" [ var; int idx] ] +let int_val var idx = call "Int_val" [ call "Field" [ var; int idx ] ] + +(* Unlike Int, Float must be re-boxed before returning to the OCaml runtime thus a copy*) +let val_float var name = call "caml_copy_double" [ ptr_field var name ] +let float_val var idx = call "Double_val" [ call "Field" [ var; int idx ] ] (* from_ir *) let rec ctype_of_ir (ir_type : Ir.ir_type) = @@ -99,6 +104,7 @@ let rec ctype_of_ir (ir_type : Ir.ir_type) = | Ir.Record { rec_name; _ } -> Prim rec_name | Ir.Enum { enum_name; _ } -> Prim enum_name | Ir.Prim Ir.Int -> Prim "int" + | Ir.Prim Ir.Float -> Prim "float" | Ir.Prim Ir.Bool -> Prim "bool" | Ir.Prim Ir.Char -> Prim "char" | Ir.Prim Ir.Void -> Void @@ -127,9 +133,13 @@ module Shims = struct ] @ Ir.( List.mapi - (fun idx field -> - store_field (var "caml_x") idx - (val_int (var "x") field.fld_name)) + (fun idx fld -> + let fld_caml_value = + match fld.fld_type with + | Prim Float -> val_float (var "x") fld.fld_name + | _ -> val_int (var "x") fld.fld_name + in + store_field (var "caml_x") idx fld_caml_value) fields) @ [ caml_return (var "caml_x") ]; } @@ -148,9 +158,12 @@ module Shims = struct @ Ir.( List.mapi (fun idx fld -> - assign - (ptr_field (var "x") fld.fld_name) - (int_val (var "caml_x") idx)) + let field_c_value = + match fld.fld_type with + | Prim Float -> float_val (var "caml_x") idx + | _ -> int_val (var "caml_x") idx + in + assign (ptr_field (var "x") fld.fld_name) field_c_value) fields) @ [ return (var "x") ]; } @@ -162,7 +175,10 @@ module Shims = struct let fn_body = let declare_params = - [ caml_params (List.map (fun (name, _type) -> var (caml_^name)) fn_params ) ] + [ + caml_params + (List.map (fun (name, _type) -> var (caml_ ^ name)) fn_params); + ] in let maybe_declare_result = match fn_ret with @@ -224,17 +240,16 @@ let from_ir (ir : Ir.t) : program = C_include ""; C_include ""; ] - @ - (List.filter_map - (fun node -> - match node with - | Ir.Ir_fun_decl fun_decl -> Some [ Shims.wrap_fun fun_decl ] - | Ir.Ir_type (Record { rec_name; rec_fields }) -> - Some - [ - Shims.of_value rec_name rec_fields; - Shims.to_value rec_name rec_fields; - ] - | _ -> None) - ir.items - |> List.flatten) + @ (List.filter_map + (fun node -> + match node with + | Ir.Ir_fun_decl fun_decl -> Some [ Shims.wrap_fun fun_decl ] + | Ir.Ir_type (Record { rec_name; rec_fields }) -> + Some + [ + Shims.of_value rec_name rec_fields; + Shims.to_value rec_name rec_fields; + ] + | _ -> None) + ir.items + |> List.flatten) diff --git a/bindgen/caml.ml b/bindgen/caml.ml index 6f8ca97..eb7942b 100644 --- a/bindgen/caml.ml +++ b/bindgen/caml.ml @@ -28,6 +28,7 @@ let rec core_type_from_ir typ = | Ir.Enum { enum_name; _ } -> Typ.constr (lid enum_name) [] | Ir.Record { rec_name; _ } -> Typ.constr (lid rec_name) [] | Ir.Prim Int -> Typ.constr (lid "int") [] + | Ir.Prim Float -> Typ.constr (lid "float") [] | Ir.Prim Bool -> Typ.constr (lid "bool") [] | Ir.Prim Char -> Typ.constr (lid "char") [] | Ir.Prim Void -> Typ.constr (lid "unit") [] diff --git a/bindgen/ir.ml b/bindgen/ir.ml index 13b4b8e..b0d021c 100644 --- a/bindgen/ir.ml +++ b/bindgen/ir.ml @@ -1,4 +1,4 @@ -type ir_prim_type = Int | Bool | Char | Void +type ir_prim_type = Int | Float | Bool | Char | Void type ir_type = | Abstract of string @@ -23,6 +23,7 @@ module Lift = struct (* Format.printf "lift_type: %S\n" (Clang.Type.show typ); *) match typ.desc with | Clang.Ast.BuiltinType Int -> Prim Int + | Clang.Ast.BuiltinType Float -> Prim Float | Clang.Ast.BuiltinType Bool -> Prim Bool | Clang.Ast.BuiltinType Char_S -> Prim Char | Clang.Ast.BuiltinType Void -> Prim Void From 66affc7af2ca97eb413447091a63685dfce0b3c1 Mon Sep 17 00:00:00 2001 From: Omniscient Date: Sat, 2 Mar 2024 15:03:12 +1100 Subject: [PATCH 04/12] generated output for floating point --- examples/caml_doggo.c | 4 +++- examples/doggo.ml | 3 ++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/examples/caml_doggo.c b/examples/caml_doggo.c index 73f3e38..468cba1 100644 --- a/examples/caml_doggo.c +++ b/examples/caml_doggo.c @@ -11,16 +11,18 @@ Doggo* caml_Doggo_of_value(value caml_x) { x->many = Int_val(Field(caml_x, 0)); x->breed = Int_val(Field(caml_x, 1)); x->wow = Int_val(Field(caml_x, 2)); + x->weight = Double_val(Field(caml_x, 3)); return x; } value caml_Doggo_to_value(struct Doggo* x) { CAMLparam0(); CAMLlocal1(caml_x); - caml_x = caml_alloc_tuple(3); + caml_x = caml_alloc_tuple(4); Store_field(caml_x, 0, Val_int(x->many)); Store_field(caml_x, 1, Val_int(x->breed)); Store_field(caml_x, 2, Val_int(x->wow)); + Store_field(caml_x, 3, caml_copy_double(x->weight)); CAMLreturn(caml_x); } diff --git a/examples/doggo.ml b/examples/doggo.ml index 9b9bbe2..3d21fa7 100644 --- a/examples/doggo.ml +++ b/examples/doggo.ml @@ -7,6 +7,7 @@ type nonrec breed = type nonrec doggo = { many: int ; breed: breed ; - wow: char } + wow: char ; + weight: float } external eleven_out_of_ten_majestic_af : pupper:doggo -> unit = "caml_eleven_out_of_ten_majestic_af" From 725e1306ec407c0cf03c7c06889bf98d71489402 Mon Sep 17 00:00:00 2001 From: Omniscient Date: Sat, 2 Mar 2024 15:02:23 +1100 Subject: [PATCH 05/12] add dog weight as float to example --- examples/doggo.c | 4 ++-- examples/doggo.h | 1 + examples/main.ml | 10 ++++++++-- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/examples/doggo.c b/examples/doggo.c index 60a4784..6df51ff 100644 --- a/examples/doggo.c +++ b/examples/doggo.c @@ -11,5 +11,5 @@ static const char* BreedToString[4] = { void eleven_out_of_ten_majestic_af(Doggo* pupper) { printf("doggo says %d\n", pupper->many); printf("doggo is a %s\n", BreedToString[pupper->breed]); -} - + printf("doggo weighs %.1fkg\n", pupper->weight); +} \ No newline at end of file diff --git a/examples/doggo.h b/examples/doggo.h index ea8d8dd..6a04634 100644 --- a/examples/doggo.h +++ b/examples/doggo.h @@ -9,6 +9,7 @@ typedef struct Doggo { int many; breed breed; char wow; + float weight; } Doggo; void eleven_out_of_ten_majestic_af(Doggo* pupper); diff --git a/examples/main.ml b/examples/main.ml index 120443f..0398f08 100644 --- a/examples/main.ml +++ b/examples/main.ml @@ -1,5 +1,11 @@ -Doggo.eleven_out_of_ten_majestic_af ~pupper:{ +open Doggo + +let pupper = { many=2112; wow='x'; - breed=C_Labrador + breed=C_Labrador; + weight=18.9; } + +let () = + Doggo.eleven_out_of_ten_majestic_af ~pupper \ No newline at end of file From 89bc86401afe95cb3659c053069bcb5e859fee68 Mon Sep 17 00:00:00 2001 From: Omniscient Date: Sat, 2 Mar 2024 15:03:00 +1100 Subject: [PATCH 06/12] float primitive first pass --- bindgen/c.ml | 63 ++++++++++++++++++++++++++++++------------------- bindgen/caml.ml | 1 + bindgen/ir.ml | 3 ++- 3 files changed, 42 insertions(+), 25 deletions(-) diff --git a/bindgen/c.ml b/bindgen/c.ml index 20b4b41..cbee800 100644 --- a/bindgen/c.ml +++ b/bindgen/c.ml @@ -1,7 +1,7 @@ let caml_ = "caml_" type c_type = Prim of string | Struct of string | Ptr of c_type | Void -type c_prim = Int of int | Str of string +type c_prim = Int of int | Float of float | Str of string type t = | C_function of { @@ -23,7 +23,6 @@ type t = type program = t list - let pp_list sep pp_el fmt t = Format.pp_print_list ~pp_sep:(fun fmt () -> Format.fprintf fmt "%s" sep) @@ -66,6 +65,7 @@ and pp_type fmt (ctype : c_type) = and pp_prim fmt (prim : c_prim) = match prim with | Int d -> Format.fprintf fmt "%d" d + | Float f -> Format.fprintf fmt "%f" f | Str s -> Format.fprintf fmt "%s" s let decl dcl_type dcl_name dcl_value = C_decl { dcl_name; dcl_type; dcl_value } @@ -73,6 +73,7 @@ let call cc_name cc_args = C_call { cc_name; cc_args } let var x = C_variable x let assign asg_var asg_value = C_assign { asg_var; asg_value } let int x = C_prim (Int x) +let float f = C_prim (Float f) let string x = C_prim (Str x) let ptr_field pfa_name pfa_field = C_ptr_field_access { pfa_name; pfa_field } let typ t = C_type t @@ -90,7 +91,11 @@ let caml_alloc_tuple fields = let store_field var idx value = call "Store_field" [ var; int idx; value ] let val_int var name = call "Val_int" [ ptr_field var name ] -let int_val var idx = call "Int_val" [ call "Field" [ var; int idx] ] +let int_val var idx = call "Int_val" [ call "Field" [ var; int idx ] ] + +(* Unlike Int, Float must be re-boxed before returning to the OCaml runtime thus a copy*) +let val_float var name = call "caml_copy_double" [ ptr_field var name ] +let float_val var idx = call "Double_val" [ call "Field" [ var; int idx ] ] (* from_ir *) let rec ctype_of_ir (ir_type : Ir.ir_type) = @@ -99,6 +104,7 @@ let rec ctype_of_ir (ir_type : Ir.ir_type) = | Ir.Record { rec_name; _ } -> Prim rec_name | Ir.Enum { enum_name; _ } -> Prim enum_name | Ir.Prim Ir.Int -> Prim "int" + | Ir.Prim Ir.Float -> Prim "float" | Ir.Prim Ir.Bool -> Prim "bool" | Ir.Prim Ir.Char -> Prim "char" | Ir.Prim Ir.Void -> Void @@ -127,9 +133,13 @@ module Shims = struct ] @ Ir.( List.mapi - (fun idx field -> - store_field (var "caml_x") idx - (val_int (var "x") field.fld_name)) + (fun idx fld -> + let fld_caml_value = + match fld.fld_type with + | Prim Float -> val_float (var "x") fld.fld_name + | _ -> val_int (var "x") fld.fld_name + in + store_field (var "caml_x") idx fld_caml_value) fields) @ [ caml_return (var "caml_x") ]; } @@ -148,9 +158,12 @@ module Shims = struct @ Ir.( List.mapi (fun idx fld -> - assign - (ptr_field (var "x") fld.fld_name) - (int_val (var "caml_x") idx)) + let field_c_value = + match fld.fld_type with + | Prim Float -> float_val (var "caml_x") idx + | _ -> int_val (var "caml_x") idx + in + assign (ptr_field (var "x") fld.fld_name) field_c_value) fields) @ [ return (var "x") ]; } @@ -162,7 +175,10 @@ module Shims = struct let fn_body = let declare_params = - [ caml_params (List.map (fun (name, _type) -> var (caml_^name)) fn_params ) ] + [ + caml_params + (List.map (fun (name, _type) -> var (caml_ ^ name)) fn_params); + ] in let maybe_declare_result = match fn_ret with @@ -224,17 +240,16 @@ let from_ir (ir : Ir.t) : program = C_include ""; C_include ""; ] - @ - (List.filter_map - (fun node -> - match node with - | Ir.Ir_fun_decl fun_decl -> Some [ Shims.wrap_fun fun_decl ] - | Ir.Ir_type (Record { rec_name; rec_fields }) -> - Some - [ - Shims.of_value rec_name rec_fields; - Shims.to_value rec_name rec_fields; - ] - | _ -> None) - ir.items - |> List.flatten) + @ (List.filter_map + (fun node -> + match node with + | Ir.Ir_fun_decl fun_decl -> Some [ Shims.wrap_fun fun_decl ] + | Ir.Ir_type (Record { rec_name; rec_fields }) -> + Some + [ + Shims.of_value rec_name rec_fields; + Shims.to_value rec_name rec_fields; + ] + | _ -> None) + ir.items + |> List.flatten) diff --git a/bindgen/caml.ml b/bindgen/caml.ml index 6f8ca97..eb7942b 100644 --- a/bindgen/caml.ml +++ b/bindgen/caml.ml @@ -28,6 +28,7 @@ let rec core_type_from_ir typ = | Ir.Enum { enum_name; _ } -> Typ.constr (lid enum_name) [] | Ir.Record { rec_name; _ } -> Typ.constr (lid rec_name) [] | Ir.Prim Int -> Typ.constr (lid "int") [] + | Ir.Prim Float -> Typ.constr (lid "float") [] | Ir.Prim Bool -> Typ.constr (lid "bool") [] | Ir.Prim Char -> Typ.constr (lid "char") [] | Ir.Prim Void -> Typ.constr (lid "unit") [] diff --git a/bindgen/ir.ml b/bindgen/ir.ml index 13b4b8e..b0d021c 100644 --- a/bindgen/ir.ml +++ b/bindgen/ir.ml @@ -1,4 +1,4 @@ -type ir_prim_type = Int | Bool | Char | Void +type ir_prim_type = Int | Float | Bool | Char | Void type ir_type = | Abstract of string @@ -23,6 +23,7 @@ module Lift = struct (* Format.printf "lift_type: %S\n" (Clang.Type.show typ); *) match typ.desc with | Clang.Ast.BuiltinType Int -> Prim Int + | Clang.Ast.BuiltinType Float -> Prim Float | Clang.Ast.BuiltinType Bool -> Prim Bool | Clang.Ast.BuiltinType Char_S -> Prim Char | Clang.Ast.BuiltinType Void -> Prim Void From 44d7a3a7d5f4c4c8a8633dac498da1ece2a5c081 Mon Sep 17 00:00:00 2001 From: Omniscient Date: Sat, 2 Mar 2024 15:03:12 +1100 Subject: [PATCH 07/12] generated output for floating point --- examples/caml_doggo.c | 4 +++- examples/doggo.ml | 3 ++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/examples/caml_doggo.c b/examples/caml_doggo.c index 73f3e38..468cba1 100644 --- a/examples/caml_doggo.c +++ b/examples/caml_doggo.c @@ -11,16 +11,18 @@ Doggo* caml_Doggo_of_value(value caml_x) { x->many = Int_val(Field(caml_x, 0)); x->breed = Int_val(Field(caml_x, 1)); x->wow = Int_val(Field(caml_x, 2)); + x->weight = Double_val(Field(caml_x, 3)); return x; } value caml_Doggo_to_value(struct Doggo* x) { CAMLparam0(); CAMLlocal1(caml_x); - caml_x = caml_alloc_tuple(3); + caml_x = caml_alloc_tuple(4); Store_field(caml_x, 0, Val_int(x->many)); Store_field(caml_x, 1, Val_int(x->breed)); Store_field(caml_x, 2, Val_int(x->wow)); + Store_field(caml_x, 3, caml_copy_double(x->weight)); CAMLreturn(caml_x); } diff --git a/examples/doggo.ml b/examples/doggo.ml index 9b9bbe2..3d21fa7 100644 --- a/examples/doggo.ml +++ b/examples/doggo.ml @@ -7,6 +7,7 @@ type nonrec breed = type nonrec doggo = { many: int ; breed: breed ; - wow: char } + wow: char ; + weight: float } external eleven_out_of_ten_majestic_af : pupper:doggo -> unit = "caml_eleven_out_of_ten_majestic_af" From 223ab376543b625d57446f39ad9a0cf5914f03a4 Mon Sep 17 00:00:00 2001 From: Omniscient Date: Sat, 2 Mar 2024 17:48:50 +1100 Subject: [PATCH 08/12] handle libclang double as well --- bindgen/ir.ml | 1 + 1 file changed, 1 insertion(+) diff --git a/bindgen/ir.ml b/bindgen/ir.ml index b0d021c..e2b06d9 100644 --- a/bindgen/ir.ml +++ b/bindgen/ir.ml @@ -24,6 +24,7 @@ module Lift = struct match typ.desc with | Clang.Ast.BuiltinType Int -> Prim Int | Clang.Ast.BuiltinType Float -> Prim Float + | Clang.Ast.BuiltinType Double -> Prim Float | Clang.Ast.BuiltinType Bool -> Prim Bool | Clang.Ast.BuiltinType Char_S -> Prim Char | Clang.Ast.BuiltinType Void -> Prim Void From 84028353fc60675412173980ebd6bfabffd2b97c Mon Sep 17 00:00:00 2001 From: Omniscient Date: Sat, 2 Mar 2024 17:55:03 +1100 Subject: [PATCH 09/12] remove comment --- bindgen/c.ml | 1 - 1 file changed, 1 deletion(-) diff --git a/bindgen/c.ml b/bindgen/c.ml index cbee800..b7c5bad 100644 --- a/bindgen/c.ml +++ b/bindgen/c.ml @@ -93,7 +93,6 @@ let store_field var idx value = call "Store_field" [ var; int idx; value ] let val_int var name = call "Val_int" [ ptr_field var name ] let int_val var idx = call "Int_val" [ call "Field" [ var; int idx ] ] -(* Unlike Int, Float must be re-boxed before returning to the OCaml runtime thus a copy*) let val_float var name = call "caml_copy_double" [ ptr_field var name ] let float_val var idx = call "Double_val" [ call "Field" [ var; int idx ] ] From 3ae761389878ea4c281a50500e1f2a2a884d9e66 Mon Sep 17 00:00:00 2001 From: omnisci3nce <17525998+omnisci3nce@users.noreply.github.com> Date: Sat, 9 Mar 2024 18:15:21 +1100 Subject: [PATCH 10/12] Empty function parameters become unit param Directly match out an empty list rather than using empty string "" for label. --- bindgen/caml.ml | 21 ++++++++++++++------- examples/caml_doggo.c | 6 ++++++ examples/doggo.c | 3 +++ examples/doggo.h | 2 ++ examples/doggo.ml | 1 + 5 files changed, 26 insertions(+), 7 deletions(-) diff --git a/bindgen/caml.ml b/bindgen/caml.ml index 6f8ca97..50353aa 100644 --- a/bindgen/caml.ml +++ b/bindgen/caml.ml @@ -32,13 +32,20 @@ let rec core_type_from_ir typ = | Ir.Prim Char -> Typ.constr (lid "char") [] | Ir.Prim Void -> Typ.constr (lid "unit") [] | Ir.Ptr t -> core_type_from_ir t - | Ir.Func { fn_ret; fn_params } -> - List.fold_left - (fun acc (name, typ) -> - let label = Asttypes.Labelled name in - let typ = core_type_from_ir typ in - Typ.arrow label typ acc) - (core_type_from_ir fn_ret) fn_params + | Ir.Func { fn_ret; fn_params } -> ( + match fn_params with + | [] -> + (* If the C function declaration has no parameters we must introduce a `unit` param *) + Typ.arrow Asttypes.Nolabel + (core_type_from_ir (Ir.Prim Void)) + (core_type_from_ir fn_ret) + | params -> + List.fold_left + (fun acc (name, typ) -> + let label = Asttypes.Labelled name in + let typ = core_type_from_ir typ in + Typ.arrow label typ acc) + (core_type_from_ir fn_ret) params) let type_from_ir typ = match typ with diff --git a/examples/caml_doggo.c b/examples/caml_doggo.c index 73f3e38..35536cb 100644 --- a/examples/caml_doggo.c +++ b/examples/caml_doggo.c @@ -31,4 +31,10 @@ void caml_eleven_out_of_ten_majestic_af(value caml_pupper) { CAMLreturn0; } +void caml_no_input_no_output() { + CAMLparam0(); + no_input_no_output(); + CAMLreturn0; +} + diff --git a/examples/doggo.c b/examples/doggo.c index 60a4784..bbf5c9d 100644 --- a/examples/doggo.c +++ b/examples/doggo.c @@ -13,3 +13,6 @@ void eleven_out_of_ten_majestic_af(Doggo* pupper) { printf("doggo is a %s\n", BreedToString[pupper->breed]); } +void no_input_no_output(void) { + printf("We are doing nothing (of importance)\n"); +} \ No newline at end of file diff --git a/examples/doggo.h b/examples/doggo.h index ea8d8dd..cc65fe9 100644 --- a/examples/doggo.h +++ b/examples/doggo.h @@ -12,3 +12,5 @@ typedef struct Doggo { } Doggo; void eleven_out_of_ten_majestic_af(Doggo* pupper); + +void no_input_no_output(void); \ No newline at end of file diff --git a/examples/doggo.ml b/examples/doggo.ml index 9b9bbe2..ca1434a 100644 --- a/examples/doggo.ml +++ b/examples/doggo.ml @@ -10,3 +10,4 @@ type nonrec doggo = { wow: char } external eleven_out_of_ten_majestic_af : pupper:doggo -> unit = "caml_eleven_out_of_ten_majestic_af" +external no_input_no_output : unit -> unit = "caml_no_input_no_output" From 82d651cc63daa5ddb8b982bb145740f2f00734db Mon Sep 17 00:00:00 2001 From: omnisci3nce <17525998+omnisci3nce@users.noreply.github.com> Date: Sun, 10 Mar 2024 23:21:15 +1100 Subject: [PATCH 11/12] brainstorming how to do pointer arguments --- bindgen/caml.ml | 2 +- bindgen/codegen.ml | 6 ++++++ bindgen/experimental.ml | 19 +++++++++++++++++++ bindgen/ir.ml | 2 +- examples/caml_doggo.c | 34 ++++------------------------------ examples/doggo.c | 34 +++++++++++++++++++++------------- examples/doggo.h | 31 +++++++++++++++++-------------- examples/doggo.ml | 31 ++++++++++++++++++------------- examples/dune | 1 + examples/main.ml | 9 +++++++-- 10 files changed, 95 insertions(+), 74 deletions(-) create mode 100644 bindgen/experimental.ml diff --git a/bindgen/caml.ml b/bindgen/caml.ml index cc4be8b..9de625a 100644 --- a/bindgen/caml.ml +++ b/bindgen/caml.ml @@ -32,7 +32,7 @@ let rec core_type_from_ir typ = | Ir.Prim Bool -> Typ.constr (lid "bool") [] | Ir.Prim Char -> Typ.constr (lid "char") [] | Ir.Prim Void -> Typ.constr (lid "unit") [] - | Ir.Ptr t -> core_type_from_ir t + | Ir.Ptr t -> Typ.constr (lid "ptr") [(core_type_from_ir t)] | Ir.Func { fn_ret; fn_params } -> ( match fn_params with | [] -> diff --git a/bindgen/codegen.ml b/bindgen/codegen.ml index c4935d1..a974ef5 100644 --- a/bindgen/codegen.ml +++ b/bindgen/codegen.ml @@ -5,6 +5,9 @@ let with_file file fn = close_out oc; () +let read_file file = + In_channel.with_open_bin file In_channel.input_all + let write_dune_file (dune : Dunefile.t) = with_file "dune" @@ fun fmt -> Format.fprintf fmt @@ -22,8 +25,11 @@ let write_dune_file (dune : Dunefile.t) = Format.fprintf fmt "\n%!" let write_caml_files caml (dune : Dunefile.t) = + let experimental = read_file "../bindgen/experimental.ml" in with_file dune.caml_file_name @@ fun fmt -> Format.fprintf fmt "(* automatically generated by ocaml-bindgen 0.0.1 *)\n"; + (* Format.fprintf fmt "open Bindgen.Experimental\n"; *) + Format.fprintf fmt "%s\n" experimental; Format.fprintf fmt "%s\n%!" (Format.asprintf "%a" Pprintast.structure caml) let write_c_files (c : C.program) (dune : Dunefile.t) = diff --git a/bindgen/experimental.ml b/bindgen/experimental.ml new file mode 100644 index 0000000..9553fe9 --- /dev/null +++ b/bindgen/experimental.ml @@ -0,0 +1,19 @@ +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 ptr = { + lifetime: lifetime; + value: 'a; +} + +(* The easiest way to call a function that requires a int ptr is to do *) + +(* basically we need a funtion + string -> char ptr that we can then pass to the function +*) + + +(* let char_ptr (s: string) : char ptr = {} *) \ No newline at end of file diff --git a/bindgen/ir.ml b/bindgen/ir.ml index b0d021c..f484931 100644 --- a/bindgen/ir.ml +++ b/bindgen/ir.ml @@ -20,7 +20,7 @@ module Lift = struct match name with Clang.Ast.IdentifierName x -> x | _ -> assert false let rec lift_type (typ : Clang.Type.t) = - (* Format.printf "lift_type: %S\n" (Clang.Type.show typ); *) + Format.printf "lift_type: %S\n" (Clang.Type.show typ); flush stdout; match typ.desc with | Clang.Ast.BuiltinType Int -> Prim Int | Clang.Ast.BuiltinType Float -> Prim Float diff --git a/examples/caml_doggo.c b/examples/caml_doggo.c index 60072d0..90cd74a 100644 --- a/examples/caml_doggo.c +++ b/examples/caml_doggo.c @@ -6,36 +6,10 @@ #include #include #include -Doggo* caml_Doggo_of_value(value caml_x) { - Doggo* x = malloc(sizeof(struct Doggo)); - x->many = Int_val(Field(caml_x, 0)); - x->breed = Int_val(Field(caml_x, 1)); - x->wow = Int_val(Field(caml_x, 2)); - x->weight = Double_val(Field(caml_x, 3)); - return x; -} - -value caml_Doggo_to_value(struct Doggo* x) { - CAMLparam0(); - CAMLlocal1(caml_x); - caml_x = caml_alloc_tuple(4); - Store_field(caml_x, 0, Val_int(x->many)); - Store_field(caml_x, 1, Val_int(x->breed)); - Store_field(caml_x, 2, Val_int(x->wow)); - Store_field(caml_x, 3, caml_copy_double(x->weight)); - CAMLreturn(caml_x); -} - -void caml_eleven_out_of_ten_majestic_af(value caml_pupper) { - CAMLparam1(caml_pupper); - Doggo* pupper = caml_Doggo_of_value(caml_pupper); - eleven_out_of_ten_majestic_af(pupper); - CAMLreturn0; -} - -void caml_no_input_no_output() { - CAMLparam0(); - no_input_no_output(); +void caml_print_age(value caml_age) { + CAMLparam1(caml_age); + int* age = caml_int_of_value(caml_age); + print_age(age); CAMLreturn0; } diff --git a/examples/doggo.c b/examples/doggo.c index 76c33c0..473d63b 100644 --- a/examples/doggo.c +++ b/examples/doggo.c @@ -1,19 +1,27 @@ #include #include "doggo.h" -static const char* BreedToString[4] = { - "Labrador", - "Golden Retriever", - "Pug", - "Poodle" -}; +// static const char* BreedToString[4] = { +// "Labrador", +// "Golden Retriever", +// "Pug", +// "Poodle" +// }; -void eleven_out_of_ten_majestic_af(Doggo* pupper) { - printf("doggo says %d\n", pupper->many); - printf("doggo is a %s\n", BreedToString[pupper->breed]); - printf("doggo weighs %.1fkg\n", pupper->weight); +// void eleven_out_of_ten_majestic_af(Doggo* pupper) { +// printf("doggo says %d\n", pupper->many); +// printf("doggo is a %s\n", BreedToString[pupper->breed]); +// printf("doggo weighs %.1fkg\n", pupper->weight); +// } + +// void no_input_no_output(void) { +// printf("We are doing nothing (of importance)\n"); +// } + +void print_age(int* age) { + printf("Age: %d\n", *age); } -void no_input_no_output(void) { - printf("We are doing nothing (of importance)\n"); -} \ No newline at end of file +// void greet_dog(char* dog_name) { +// printf("Hey %s\n", dog_name); +// } \ No newline at end of file diff --git a/examples/doggo.h b/examples/doggo.h index b19ff07..128c42d 100644 --- a/examples/doggo.h +++ b/examples/doggo.h @@ -1,17 +1,20 @@ -typedef enum breed { - Labrador, - _GoldenRetriever, - pug, - _poodle -} breed; +// typedef enum breed { +// Labrador, +// _GoldenRetriever, +// pug, +// _poodle +// } breed; -typedef struct Doggo { - int many; - breed breed; - char wow; - float weight; -} Doggo; +// typedef struct Doggo { +// int many; +// breed breed; +// char wow; +// float weight; +// } Doggo; -void eleven_out_of_ten_majestic_af(Doggo* pupper); +// void eleven_out_of_ten_majestic_af(Doggo* pupper); -void no_input_no_output(void); \ No newline at end of file +// void no_input_no_output(void); + +void print_age(int* age); +// void greet_dog(char* dog_name); \ No newline at end of file diff --git a/examples/doggo.ml b/examples/doggo.ml index 8278468..d4ffa20 100644 --- a/examples/doggo.ml +++ b/examples/doggo.ml @@ -1,14 +1,19 @@ (* automatically generated by ocaml-bindgen 0.0.1 *) -type nonrec breed = - | C_Labrador - | C__GoldenRetriever - | C_pug - | C__poodle -type nonrec doggo = { - many: int ; - breed: breed ; - wow: char ; - weight: float } -external eleven_out_of_ten_majestic_af : - pupper:doggo -> unit = "caml_eleven_out_of_ten_majestic_af" -external no_input_no_output : unit -> unit = "caml_no_input_no_output" +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 ptr = { + lifetime: lifetime; + value: 'a; +} + +(* basically we need a funtion + string -> char ptr that we can then pass to the function +*) + + +(* let char_ptr (s: string) : char ptr = {} *) +external print_age : age:int ptr -> unit = "caml_print_age" diff --git a/examples/dune b/examples/dune index e31905b..6f247d7 100644 --- a/examples/dune +++ b/examples/dune @@ -1,5 +1,6 @@ (executable (name main) + (libraries bindgen) (foreign_stubs (language c) (names doggo caml_doggo) diff --git a/examples/main.ml b/examples/main.ml index 0398f08..b1a6565 100644 --- a/examples/main.ml +++ b/examples/main.ml @@ -1,6 +1,6 @@ open Doggo -let pupper = { +(* let pupper = { many=2112; wow='x'; breed=C_Labrador; @@ -8,4 +8,9 @@ let pupper = { } let () = - Doggo.eleven_out_of_ten_majestic_af ~pupper \ No newline at end of file + Doggo.eleven_out_of_ten_majestic_af ~pupper *) + +let char_ptr_of_string = + +let () = + greet_dog ~dog_name:"Puppy" \ No newline at end of file From 701106b08db6c19ad01caa5d27ae877d68d0272c Mon Sep 17 00:00:00 2001 From: Omniscient Date: Sat, 16 Mar 2024 16:48:38 +1100 Subject: [PATCH 12/12] experiment with ptr concept for arguments --- bindgen/c.ml | 20 ++++++++++++++------ bindgen/caml.ml | 2 +- bindgen/codegen.ml | 32 ++++++++++++++++++++++++++------ bindgen/dunefile.ml | 2 +- bindgen/experimental.ml | 19 ------------------- bindgen/ir.ml | 8 +++++++- bindgen/runtime.ml | 20 ++++++++++++++++++++ examples/caml_doggo.c | 24 +++++++++++++++++++++++- examples/doggo.c | 11 +++++++---- examples/doggo.h | 7 +++---- examples/doggo.ml | 19 ------------------- examples/doggo_sys.ml | 23 +++++++++++++++++++++++ examples/dune | 12 ++++-------- examples/main.ml | 20 +++++++------------- 14 files changed, 136 insertions(+), 83 deletions(-) delete mode 100644 bindgen/experimental.ml create mode 100644 bindgen/runtime.ml delete mode 100644 examples/doggo.ml create mode 100644 examples/doggo_sys.ml diff --git a/bindgen/c.ml b/bindgen/c.ml index cbee800..990638c 100644 --- a/bindgen/c.ml +++ b/bindgen/c.ml @@ -190,12 +190,20 @@ module Shims = struct List.map (fun (name, param_type) -> let c_type = ctype_of_ir param_type in - let c_type_name = ctype_name c_type in - decl c_type name - (Some - (call - (caml_ ^ c_type_name ^ "_of_value") - [ var (caml_ ^ name) ]))) + match c_type with + | Ptr _t -> + let _c_type_name = ctype_name c_type in + decl c_type name + (Some + (call "Nativeint_val" + [ call "Field" [ var (caml_ ^ name); int 1 ] ])) + | _ -> + let c_type_name = ctype_name c_type in + decl c_type name + (Some + (call + (caml_ ^ c_type_name ^ "_of_value") + [ var (caml_ ^ name) ]))) fn_params in diff --git a/bindgen/caml.ml b/bindgen/caml.ml index 9de625a..b1821b5 100644 --- a/bindgen/caml.ml +++ b/bindgen/caml.ml @@ -32,7 +32,7 @@ let rec core_type_from_ir typ = | Ir.Prim Bool -> Typ.constr (lid "bool") [] | Ir.Prim Char -> Typ.constr (lid "char") [] | Ir.Prim Void -> Typ.constr (lid "unit") [] - | Ir.Ptr t -> Typ.constr (lid "ptr") [(core_type_from_ir t)] + | Ir.Ptr t -> Typ.constr (lid "cptr") [ core_type_from_ir t ] | Ir.Func { fn_ret; fn_params } -> ( match fn_params with | [] -> diff --git a/bindgen/codegen.ml b/bindgen/codegen.ml index a974ef5..a46b595 100644 --- a/bindgen/codegen.ml +++ b/bindgen/codegen.ml @@ -5,8 +5,7 @@ let with_file file fn = close_out oc; () -let read_file file = - In_channel.with_open_bin file In_channel.input_all +let read_file file = In_channel.with_open_bin file In_channel.input_all let write_dune_file (dune : Dunefile.t) = with_file "dune" @@ fun fmt -> @@ -25,14 +24,35 @@ let write_dune_file (dune : Dunefile.t) = Format.fprintf fmt "\n%!" let write_caml_files caml (dune : Dunefile.t) = - let experimental = read_file "../bindgen/experimental.ml" in + let runtime_ocaml = read_file "../bindgen/runtime.ml" in with_file dune.caml_file_name @@ fun fmt -> Format.fprintf fmt "(* automatically generated by ocaml-bindgen 0.0.1 *)\n"; - (* Format.fprintf fmt "open Bindgen.Experimental\n"; *) - Format.fprintf fmt "%s\n" experimental; + Format.fprintf fmt "%s\n" runtime_ocaml; Format.fprintf fmt "%s\n%!" (Format.asprintf "%a" Pprintast.structure caml) let write_c_files (c : C.program) (dune : Dunefile.t) = with_file dune.c_file_name @@ fun fmt -> Format.fprintf fmt "/* automatically generated by ocaml-bindgen 0.0.1 */\n"; - Format.fprintf fmt "%s\n%!" (Format.asprintf "%a" C.pp c) + Format.fprintf fmt "\n%s\n%!" (Format.asprintf "%a" C.pp c); + Format.fprintf fmt + {|#include +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)); +} |} diff --git a/bindgen/dunefile.ml b/bindgen/dunefile.ml index 4ea3f3e..3caedd7 100644 --- a/bindgen/dunefile.ml +++ b/bindgen/dunefile.ml @@ -3,6 +3,6 @@ type t = { lib_name : string; caml_file_name : string; c_file_name : string } let from_ir (ir : Ir.t) : t = { lib_name = ir.lib_name; - caml_file_name = ir.lib_name ^ ".ml"; + caml_file_name = ir.lib_name ^ "_sys" ^ ".ml"; c_file_name = "caml_" ^ ir.lib_name ^ ".c"; } diff --git a/bindgen/experimental.ml b/bindgen/experimental.ml deleted file mode 100644 index 9553fe9..0000000 --- a/bindgen/experimental.ml +++ /dev/null @@ -1,19 +0,0 @@ -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 ptr = { - lifetime: lifetime; - value: 'a; -} - -(* The easiest way to call a function that requires a int ptr is to do *) - -(* basically we need a funtion - string -> char ptr that we can then pass to the function -*) - - -(* let char_ptr (s: string) : char ptr = {} *) \ No newline at end of file diff --git a/bindgen/ir.ml b/bindgen/ir.ml index f484931..6c052f9 100644 --- a/bindgen/ir.ml +++ b/bindgen/ir.ml @@ -20,7 +20,7 @@ module Lift = struct match name with Clang.Ast.IdentifierName x -> x | _ -> assert false let rec lift_type (typ : Clang.Type.t) = - Format.printf "lift_type: %S\n" (Clang.Type.show typ); flush stdout; + (* Format.printf "lift_type: %S\n" (Clang.Type.show typ); flush stdout; *) match typ.desc with | Clang.Ast.BuiltinType Int -> Prim Int | Clang.Ast.BuiltinType Float -> Prim Float @@ -106,3 +106,9 @@ module Lift = struct end let lift = Lift.lift + +let string_of_prim prim = + match prim with + | Int -> "Int" + | Char -> "Char" + | Float | Bool | Void -> "Other (TODO)" diff --git a/bindgen/runtime.ml b/bindgen/runtime.ml new file mode 100644 index 0000000..75acbcf --- /dev/null +++ b/bindgen/runtime.ml @@ -0,0 +1,20 @@ +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" + +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 } diff --git a/examples/caml_doggo.c b/examples/caml_doggo.c index 90cd74a..cb7e28b 100644 --- a/examples/caml_doggo.c +++ b/examples/caml_doggo.c @@ -1,4 +1,5 @@ /* automatically generated by ocaml-bindgen 0.0.1 */ + #include "doggo.h" #include #include @@ -8,9 +9,30 @@ #include void caml_print_age(value caml_age) { CAMLparam1(caml_age); - int* age = caml_int_of_value(caml_age); + int* age = Nativeint_val(Field(caml_age, 1)); print_age(age); CAMLreturn0; } +#include +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)); +} \ No newline at end of file diff --git a/examples/doggo.c b/examples/doggo.c index 473d63b..9f1fe0a 100644 --- a/examples/doggo.c +++ b/examples/doggo.c @@ -21,7 +21,10 @@ void print_age(int* age) { printf("Age: %d\n", *age); } - -// void greet_dog(char* dog_name) { -// printf("Hey %s\n", dog_name); -// } \ No newline at end of file +// void print_name(char* name) { +// printf("Name: %s\n", name); +// } +// void print_doggo(Doggo *dog) { +// printf("wow: %c\n", dog->wow); +// print_age(&dog->many); +// } diff --git a/examples/doggo.h b/examples/doggo.h index 128c42d..c241b6d 100644 --- a/examples/doggo.h +++ b/examples/doggo.h @@ -7,14 +7,13 @@ // typedef struct Doggo { // int many; -// breed breed; +// // breed breed; // char wow; // float weight; // } Doggo; // void eleven_out_of_ten_majestic_af(Doggo* pupper); -// void no_input_no_output(void); - void print_age(int* age); -// void greet_dog(char* dog_name); \ No newline at end of file +// void print_name(char* name); +// void print_doggo(Doggo *dog); \ No newline at end of file diff --git a/examples/doggo.ml b/examples/doggo.ml deleted file mode 100644 index d4ffa20..0000000 --- a/examples/doggo.ml +++ /dev/null @@ -1,19 +0,0 @@ -(* 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 ptr = { - lifetime: lifetime; - value: 'a; -} - -(* basically we need a funtion - string -> char ptr that we can then pass to the function -*) - - -(* let char_ptr (s: string) : char ptr = {} *) -external print_age : age:int ptr -> unit = "caml_print_age" diff --git a/examples/doggo_sys.ml b/examples/doggo_sys.ml new file mode 100644 index 0000000..7882677 --- /dev/null +++ b/examples/doggo_sys.ml @@ -0,0 +1,23 @@ +(* 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" + +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 } + +external print_age : age:int cptr -> unit = "caml_print_age" diff --git a/examples/dune b/examples/dune index 6f247d7..aedeb7c 100644 --- a/examples/dune +++ b/examples/dune @@ -1,6 +1,6 @@ (executable - (name main) - (libraries bindgen) + (name main) + (libraries bindgen) (foreign_stubs (language c) (names doggo caml_doggo) @@ -9,13 +9,9 @@ (rule (alias all) - (targets - doggo.ml - caml_doggo.c - ) + (targets doggo_sys.ml caml_doggo.c) (deps doggo.h) (action - (run - %{bin:ocaml-bindgen} doggo.h doggo)) + (run %{bin:ocaml-bindgen} doggo.h doggo)) (mode (promote (until-clean)))) diff --git a/examples/main.ml b/examples/main.ml index b1a6565..53cb9e6 100644 --- a/examples/main.ml +++ b/examples/main.ml @@ -1,16 +1,10 @@ -open Doggo +(* open Doggo *) -(* let pupper = { - many=2112; - wow='x'; - breed=C_Labrador; - weight=18.9; -} +module Doggo = struct + include Doggo_sys + (** Here is where we would write our wrappers around the raw bindings *) -let () = - Doggo.eleven_out_of_ten_majestic_af ~pupper *) + let wrapper_print_age (age : int) = print_age ~age:(create_ptr age) +end -let char_ptr_of_string = - -let () = - greet_dog ~dog_name:"Puppy" \ No newline at end of file +let () = Doggo.wrapper_print_age 25