You are currently browsing the archives for the c tag.
Olivier has been busy extending my previous work on inlining C in OCaml, and it is pretty cool. You can get it from the following darcs repository.
darcs get http://chadok.info/darcs/ciml/
Basically, it allows you to inline C in OCaml code, in a very fashionable way. Type conversion between OCaml and C is (almost always) automatically dealt with for base types (int, float, bool, string, etc.) and you can register and unregister custom converters. A few examples are shown in the test.ml.
letext hello
(s:string
) : unit = <<
printf
("Hello %s !\n", s
);
Return
();
>>
letext add
(a:int
) (b:int
) : int = <<
int c;
c = a + b;
Return
(c
);
>>
(* Unregister the converters for int *)
unregister_fromval : int
unregister_toval : int
(* Register converters *)
register_fromval "Int_val" "int" : int
register_toval "Val_int" : int
The idea behind all this syntaxic sugar for inlining C code in OCaml is to provide a natural way of using C and OCaml together to whoever wants to bind C libraries to OCaml. Of course, this is still under developement, and any ideas to improve it are welcome.
I finally managed to do what I was talking about this morning. There are a few awful things in the code, but it works.
Here is what one can write:
<:c<
#include <stdio.
h>
>>
ext add (a:int) (b:int) : int = <:cfun<
int c;
c = Int_val(a) + Int_val(b);
CAMLreturn(Val_int(c));
>>
ext hello (s:string) : unit = <:cfun<
printf("Hello %s !\n", String_val(s));
CAMLreturn(Val_unit);
>>
ext ping_pong (n:int) : int = <:cfun<
int c = Int_val(caml_callback( *caml_named_value("fact"), n));
printf("C : ping. fact 4 = %d\n", c);
CAMLreturn(Val_int(c));
>>
let fact n =
let rec fact acc = function
0 -> acc
| n -> fact (n*acc) (n-1)
in
fact 1 n
let _ =
Callback.register "fact" fact;
Printf.printf "%d\n%!" (add 1 5);
Printf.printf "Ocaml : pong. fact 4 = %d\n%!" (ping_pong 4);
hello "World";
The ext keyword is the equivalent of let to define external functions. All types must be specified (for the arguments and for the return value. Camlp4 the generates the C function, the external declaration etc.
Downloaded : 93 times
File : inlinec-0.42.tar.gz
Size: 1.4 ko
A great thing about OCaml is the possibility of creating bindings with C. The bad thing about it is that it's a pain to do. Olivier and I are currently thinking about a way to make that less painful. Here is a first draft : inlining C code in OCaml, in order to avoir multiple files.
Using camlp4, we extract the quotations containing C code and we dump that in a temporary .c file, and compile it. Here is an example:
<:c<
#include <caml/mlvalues.
h>
#include <caml/memory.
h>
#include <caml/alloc.
h>
#include <caml/custom.
h>
>>
external add: int -> int -> int = "add"
<:c<
value add(value a, value b) {
int c;
CAMLparam2(a,b);
c = Int_val(a) + Int_val(b);
CAMLreturn(Val_int(c));
}
>>
let _ =
Printf.printf "La réponse est %d\n%!" (add 21 21);
The thing we would like to do is the following:
let add a b = <:cfun<
int c = Int_val(a) + Int_val(b);
CAMLreturn(Val_int(c));
>>
Which would be converted to:
external add: int -> int -> int = "add"
value add (value a, value b) {
CAMLparams2(a,b);
int c = Int_val(a) + Int_val(b);
CAMLreturn(Val_int(c));
}
Downloaded : 88 times
File : inlinec.tar.gz
Size: 732 o