Version française
Home     About     Download     Resources     Contact us    
Browse thread
[Caml-list] Inline operators in the revised syntax
[ Home ] [ Index: by date | by threads ]
[ Search: ]

[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
Date: -- (:)
From: Virgile Prevosto <virgile.prevosto@l...>
Subject: Re: [Caml-list] Inline operators in the revised syntax
Le mardi 13 mai, à 13h21 CEST, Jim Farrand a écrit:

> Is there a simple way to define and use an inline operator in the revised
> syntax?  It seems they can be defined but not used.
> 
> The equivelent in the old syntax works fine.  (I realise it's probably
> possible to use camlp4's grammar extension features to do the same, but
> I don't know how to do this, and it seems like overkill when it was so
> easy in the old syntax.)

Unfortunately for you, the camlp4 manual suggests to use syntax extensions for
infix operators (http://caml.inria.fr/camlp4/manual/manual007.html)... 
But this doesn't mean that you have to write one syntax extension for
every infix operator you want to create: you may extend the syntax once with a
rule which will itself make the necessary extensions, such as the following
example:
---
(* file infix.ml4. compile it with
   ocamlc -c -pp 'camlp4o pa_extend.cmo q_MLast.cmo -impl' -I +camlp4 
   -impl infix.ml4

   usage: infix id x y = ... ; creates an infix operator.
*)
open Pcaml

if !Sys.interactive then print_endline "infix definitions";;
EXTEND str_item:
[ [ "infix"; p = LIDENT; argts = LIST0 LIDENT; "="; e=expr ->
      let def = List.fold_right (fun arg e -> <:expr< fun $lid:arg$ -> $e$>>)
                  argts e
      in 
        (* we create a new extension which recognizes the expression
           e1 'p' e2, where 'p' is our new operator. Unfortunately, the
        EXTEND ... END syntactic sugar cannot help here, since p would be 
        considered as an entry of the grammar and not as a new keyword*)
        Grammar.extend
          [Grammar.Entry.obj expr, Some (Gramext.Before "apply"),
           [None, None, 
            [[Gramext.Sself; Gramext.Stoken ("",p);Gramext.Sself],
             Gramext.action
               (fun e2  _ e1 loc  -> 
                  (MLast.ExApp 
                     (loc, MLast.ExApp (loc, <:expr< $lid:p$>>, e1), e2)))]]];
        (* definition of the operator itself. *)
        <:str_item< value $lid:p$ = $exp:def$ >>]];
END 
---- 
Note that this is far from being perfect, since for instance it does not 
allow you to give the type of the arguments of your operator. Anyway, it 
works on simple examples:
        Objective Caml version 3.06
# #load "camlp4r.cma";;
        Camlp4 Parsing version 3.06

# #load "infix.cmo";
infix definitions
# infix \=== x y = x = y;
value ( === ) : 'a -> 'a -> bool = <fun>
# \=== 1 1;
- : bool = True
# 1 === 1;
- : bool = True
# infix foo x y = x + y;
value foo : int -> int -> int = <fun>
# 1 foo 1;
- : int = 2
# \foo 1 1;
- : int = 2

Hope this helps,
-- 
E tutto per oggi, a la prossima volta
Virgile

-------------------
To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners