Inlining C code in OCaml, part II

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 : 114 times
File : inlinec-0.42.tar.gz
Size: 1.4 ko

2 Responses to "Inlining C code in OCaml, part II"

Anocka says:

Intéressant ! J'avais trouvé la complexité de camlp4 assez décourageante, mais je ne pensais pas que c'était aussi puissant : inliner directement le c offre pas mal de possibilités (oui, j'ai pas grand chose à dire, mais c'est plutôt un message d'encouragement).

Adrien Friggeri says:

En fait ce n'est pas exactement ça : tout ce que fait camlp4 ici, c'est séparer le code caml du code C, générer les bonnes directives "external" de caml et mettre tout le code C dans un fichier temporaire qui sera compilé. Au final ca revient à inliner du C, mais la compilation est faite "plus tard".

Leave a Reply