Version française
Home     About     Download     Resources     Contact us    
Browse thread
[Caml-list] C style for loop
[ Home ] [ Index: by date | by threads ]
[ Search: ]

[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
Date: -- (:)
From: Daniel de Rauglaudre <daniel.de_rauglaudre@i...>
Subject: Re: [Caml-list] C style for loop
Hi,

On Thu, Oct 11, 2001 at 01:47:07AM -0400, Jeff Henrikson wrote:

> Okay, so maybe I should be more specific about what I want in a
> "C-style for loop."  Its readablity merits are hopefully self
> evident.  Well, unless you're a compulsive CPS addict who wishes
> even his grocery list could be written to tail recurse. . .

> (*  loop var | init val | while | expr for next val *)
> for     c         0      (c<10)        (c+1)         do
>   (* bla *)
> done;

------------------------------------- file cloop.ml
#load "q_MLast.cmo";
#load "pa_extend.cmo";

open Pcaml;

value gensym =
  let cnt = ref 0 in
  fun var ->
    let x = do { incr cnt; cnt.val } in
    var ^ "_gensym" ^ string_of_int x
;

value gen_for loc v iv wh nx e =
  let loop_fun = gensym "iter" in
  <:expr<
    let rec $lid:loop_fun$ $lid:v$ =
      if $wh$ then do { $e$; $lid:loop_fun$ $nx$ } else ()
    in
    $lid:loop_fun$ $iv$ >>
;

EXTEND
  expr: LEVEL "expr1"
    [ [ "for"; v = LIDENT; iv = expr LEVEL "simple"; wh = expr LEVEL "simple";
        nx = expr LEVEL "simple"; "do"; e = expr; "done" ->
          gen_for loc v iv wh nx e ] ]
  ;
END;
-------------------------------------

Compilation:
   $ ocamlc -pp camlp4r -I `camlp4 -where` -c cloop.ml

Example under the toplevel:
   $ ocaml -I `camlp4 -where`
	   Objective Caml version 3.02+7 (2001-09-29)
   
   # #load "camlp4o.cma";;
	   Camlp4 Parsing version 3.02+7 (2001-09-29)
   
   # #load "cloop.cmo";;
   # for i = 0 to 10 do print_int i; done;; (* normal loop *)
   012345678910- : unit = ()
   # for c 0 (c<10) (c+1) do print_int c; done;;
   0123456789- : unit = ()
   # for c 0 (c<10) (c+3) do print_int c; done;;
   0369- : unit = ()

Compilation:
   $ cat foo.ml
   for c 0 (c<10) (c+2) do print_int c; done
   $ ocamlc -pp "camlp4o ./cloop.cmo" -c foo.ml
   $

Pretty print the resulting program:
   $ camlp4o ./cloop.cmo pr_o.cmo foo.ml
   let rec iter_gensym1 c =
     if c < 10 then begin print_int c; iter_gensym1 (c + 2) end
   in
   iter_gensym1 0;;

Hope this help.

-- 
Daniel de RAUGLAUDRE
daniel.de_rauglaudre@inria.fr
http://cristal.inria.fr/~ddr/
-------------------
Bug reports: http://caml.inria.fr/bin/caml-bugs  FAQ: http://caml.inria.fr/FAQ/
To unsubscribe, mail caml-list-request@inria.fr  Archives: http://caml.inria.fr