Version française
Home     About     Download     Resources     Contact us    
Browse thread
Where are the AST specs?
[ Home ] [ Index: by date | by threads ]
[ Search: ]

[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
Date: -- (:)
From: Loup Vaillant <loup.vaillant@g...>
Subject: Re: [Caml-list] Where are the AST specs?
Here is the promised snipet of code. this is emacs lisp. One can
evaluate these from the *scratch* buffer. (C-xC-e at the end of the
expression). Of course, I assume here that '+' accept only two
arguments, or else these macros are useless. (Actually, they are.)

; This macro is right associative
(defmacro plus (first &rest tail)
  (if (null tail)
    first
    `(+ ,first
	(plus ,@tail))))

; This one is left associative
(defmacro sulp (first &rest tail)
  (if (null tail)
    first
    `(sulp (+ ,first ,(car tail))
	   ,@(cdr tail))))

; some examples
(plus 1 2 3 4 5)
(sulp 1 2 3 4 5)

I have not defined the macro definfing macros (I am no expert), yet I
belive they do not take more than six lines each. Note that I will
need read macros as well as regulars ones.

That is the kind of power I want from Ocaml. If I succeed, I will
consider solved (at least for my personnal usage) many syntax problems
I read about in this list.


2007/3/19, Nicolas Pouillard <nicolas.pouillard@gmail.com>:
> On 3/19/07, Loup Vaillant <loup.vaillant@gmail.com> wrote:
> > 2007/3/19, Nicolas Pouillard <nicolas.pouillard@gmail.com>:
> > > [...camlp4code...]
> > > $ cat test_macros.ml
> > > let cons x xs = x :: xs;;
> > >
> > > foldl(( + ), 1, 2, 3, 4);;
> > > foldr(cons, 1, 2, 3, []);;
> > >
> > > $ camlp4o ./macros.cmo test_macros.ml
> > > let cons x xs = x :: xs
> > > let _ = ((1 + 2) + 3) + 4
> > > let _ = cons 1 (cons 2 (cons 3 []))
> >
> > Impressive.
> > If it is possible, It would be best would be to be able to write something like:
> > (def_foldl + plus)
> >
> > and then just
> > (+ x y z)
> > (+ x y z w)
> > ...
> > The same for cons:
> > (def_foldr :: cons)
> >
> > (:: x y z L)
> > (:: x y z t [])
>
> $ cat macros.ml
> open Camlp4.PreCast;;
> let foldr_funs = ref [];;
> let foldl_funs = ref [];;
> AstFilters.register_str_item_filter begin
>   Ast.map_expr begin function
>   | <:expr@loc< def_foldr $lid:name$ $e$ >> ->
>       foldr_funs := (name, e) :: !foldr_funs; <:expr@loc<()>>
>   | <:expr@loc< def_foldl $lid:name$ $e$ >> ->
>       foldl_funs := (name, e) :: !foldl_funs; <:expr@loc<()>>
>   | e -> e
>   end
> end#str_item;;
> AstFilters.register_str_item_filter begin
>   Ast.map_expr begin function
>   | <:expr@loc< $lid:name$($tup:e$) >> when List.mem_assoc name !foldl_funs ->
>       let op = List.assoc name !foldl_funs in
>       let rec foldl =
>         function
>         | [] -> assert false
>         | [x] -> x
>         | x :: xs -> <:expr@loc< $op$ $foldl xs$ $x$ >>
>       in foldl (List.rev (Ast.list_of_expr e []))
>   | <:expr@loc< $lid:name$($tup:e$) >> when List.mem_assoc name !foldr_funs ->
>       let op = List.assoc name !foldr_funs in
>       let rec foldr =
>         function
>         | [] -> assert false
>         | [x] -> x
>         | x :: xs -> <:expr@loc< $op$ $x$ $foldr xs$ >>
>       in foldr (Ast.list_of_expr e [])
>   | e -> e
>   end
> end#str_item;;
>
> $ cat test_macros.ml
> let cons x xs = x :: xs;;
>
> def_foldl ( !+ ) ( + );;
> def_foldr ( !:: ) cons;;
>
> !+ (1, 2, 3, 4);;
> !:: (1, 2, 3, []);;
>
> $ camlp4of ./macros.cmo test_macros.ml
> let cons x xs = x :: xs
> let _ = ()
> let _ = ()
> let _ = ((1 + 2) + 3) + 4
> let _ = cons 1 (cons 2 (cons 3 []))
>
> > > What's wrong with the current anti quotation system?
> > Err, actually, nothing... I just found the '$' ugly. But it is one
> > character, and I may as well use it "as is".
>
> I don't like the sacrifice of $ for that purpose but that's just a
> matter of taste.
>
> --
> Nicolas Pouillard
>