From: "Nicolas Pouillard" <nicolas.pouillard@gmail.com>
To: micha <micha-1@fantasymail.de>
Cc: caml-list@inria.fr
Subject: Re: [Caml-list] using camlp4
Date: Tue, 8 May 2007 11:19:11 +0200 [thread overview]
Message-ID: <cd67f63a0705080219t4f026055t12196e9f8e2ff150@mail.gmail.com> (raw)
In-Reply-To: <20070508001706.32a70243@hmmm.de>
[-- Attachment #1: Type: text/plain, Size: 978 bytes --]
On 5/8/07, micha <micha-1@fantasymail.de> wrote:
> hi,
>
> I have classes which have many getter/setter methods. At the moment I
> use two naming schemes intermixed: get_property / set_property and
> property / set_property and I don't like that very much.
> I would like to integrate one camlp4 extension which allows to define
> the getter and setter methods for members, to be able to write:
>
> obj#prob <- xxx;
> print_endline obj#prob;
The pa_oo extension from Jacques Garrigue does exactly this kind of things:
http://www.math.nagoya-u.ac.jp/~garrigue/code/ocaml.html
I attach the upgraded to 3.10 extension.
> Is this a good idea to integrate camlp4 macros in my project?
No in particular when using clean and simple extensions pa_oo.
> If someone who might use my lib also uses a camlp4 extension, can this
> lead to trouble?
No since people use a compiled version of your library, so all the
sugar provided by macros is gone.
Regards,
--
Nicolas Pouillard
[-- Attachment #2: pa_oo.ml --]
[-- Type: text/plain, Size: 3143 bytes --]
(*
With ocamlbuild:
To compile (using this _tags file):
ocamlbuild pa_oo.cmo
To use:
ocaml camlp4o.cma ./_build/pa_oo.cmo
or
ocamlc -pp 'camlp4o ./_build/pa_oo.cmo'
Without:
To compile:
ocamlc -I +camlp4 -c -pp camlp4orf pa_oo.ml
To use:
ocaml camlp4o.cma pa_oo.cmo
or
ocamlc -pp 'camlp4o -I . pa_oo.cmo'
*)
open Camlp4.PreCast
module Caml = Syntax
let expand_access _loc mut id e kind =
let id' = id^"'" in
let reader = <:class_str_item< method $id$ = $lid:id$ >>
and writer =
<:class_str_item< method $"set_"^id$ $lid:id'$ = $lid:id$ := $lid:id'$ >>
in
let accessors =
match kind with None -> <:class_str_item<>>
| Some k -> match k with
| `R -> reader
| `W -> writer
| `RW -> <:class_str_item< $reader$; $writer$ >>
in
<:class_str_item<
value $mutable:mut$ $lid:id$ = $e$;
$accessors$
>>
(* Copied from camlp4/Camlp4Parsers/Camlp4OCamlRevisedParser.ml *)
let bigarray_set _loc var newval =
match var with
| <:expr< Bigarray.Array1.get $arr$ $c1$ >> ->
Some <:expr< Bigarray.Array1.set $arr$ $c1$ $newval$ >>
| <:expr< Bigarray.Array2.get $arr$ $c1$ $c2$ >> ->
Some <:expr< Bigarray.Array2.set $arr$ $c1$ $c2$ $newval$ >>
| <:expr< Bigarray.Array3.get $arr$ $c1$ $c2$ $c3$ >> ->
Some <:expr< Bigarray.Array3.set $arr$ $c1$ $c2$ $c3$ $newval$ >>
| <:expr< Bigarray.Genarray.get $arr$ [| $coords$ |] >> ->
Some <:expr< Bigarray.Genarray.set $arr$ [| $coords$ |] $newval$ >>
| _ -> None
let expand_set _loc e1 e2 =
match bigarray_set _loc e1 e2 with
| Some e -> e
| None -> match e1 with
| <:expr< $o$ # $x$ >> -> <:expr< $o$ # $"set_"^x$ $e2$ >>
| _ -> <:expr< $e1$ := $e2$ >>
DELETE_RULE Caml.Gram Caml.expr: SELF; "<-"; Caml.expr LEVEL "top" END;;
EXTEND Caml.Gram
GLOBAL: Caml.class_str_item Caml.expr Caml.opt_mutable Caml.ctyp;
Caml.class_str_item: [
[ "val"; "mutable"; `LIDENT lab; e = cvalue_binding; kind = cvalue_kind ->
expand_access _loc Ast.BTrue lab e kind
| "val"; `LIDENT lab; e = cvalue_binding; kind = cvalue_kind ->
expand_access _loc Ast.BFalse lab e kind ]
];
cvalue_kind: [
[ kind = OPT [ "with"; k =
[ "reader" -> `R | "writer" -> `W | "accessor" -> `RW ] -> k] ->
kind ]
];
cvalue_binding: [
[ "="; e = Caml.expr -> e
| ":"; t = Caml.ctyp; "="; e = Caml.expr -> <:expr< ($e$ : $t$) >> ]
];
Caml.expr: LEVEL ":=" [
[ e1 = SELF; "<-"; e2 = Caml.expr LEVEL "top" -> expand_set _loc e1 e2 ]
];
Caml.expr: LEVEL "simple" [
[ "{|"; cf = LIST1 obj_record SEP ";"; "|}" ->
(* self = OPT
[ "("; p = patt; ":"; t = ctyp; ")" -> <:patt< ($p$ : $t$) >>
| "("; p = patt; ")" -> <:patt< $p$ >> ]; *)
<:expr< object $Ast.crSem_of_list cf$ end >> ]
];
obj_record: [
[ "inherit"; ce = Caml.class_expr -> <:class_str_item< inherit $ce$ >>
| mf = Caml.opt_mutable; `LIDENT lab; ty = OPT [ ":"; t = Caml.ctyp -> t];
"="; e = Caml.expr LEVEL "top" ->
expand_access _loc mf lab e (Some(if mf = Ast.BFalse then `R else `RW)) ]
];
END;;
prev parent reply other threads:[~2007-05-08 9:19 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-05-07 22:17 micha
2007-05-08 9:19 ` Nicolas Pouillard [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=cd67f63a0705080219t4f026055t12196e9f8e2ff150@mail.gmail.com \
--to=nicolas.pouillard@gmail.com \
--cc=caml-list@inria.fr \
--cc=micha-1@fantasymail.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox