caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
* [Caml-list] camlp4 syntax extension for hashtbl
@ 2003-06-26 22:52 Stefano Zacchiroli
  2003-06-28 10:57 ` Stefano Zacchiroli
  0 siblings, 1 reply; 2+ messages in thread
From: Stefano Zacchiroli @ 2003-06-26 22:52 UTC (permalink / raw)
  To: caml-list

[-- Attachment #1: Type: text/plain, Size: 2148 bytes --]

Just to practice a bit with camlp4 I've written a simple syntax
extension for hashtbl usage.

I will attach the .ml hoping that it will be useful and hoping in some
feedback from camlp4 gurus :-)

Intended usage (more infos at the beginning of the source file):

  let tbl = {}                              (* empty tbl *)
  let tbl = {}|12|                          (* as above, size 12 *)
  let tbl = {["foo", 1; "bar", 2]}          (* filled tbl, size 2 *)
  let tbl = {["foo", 1; "bar", 2]}|17|      (* filled tbl, size 17 *)
  tbl{"foo"}                                (* Hashtbl.find *)
  tbl{["foo"]}                              (* Hashtbl.find_all *)
  tbl{?"foo"}                               (* Hashtbl.mem *)
  tbl{"foo"} <- 1                           (* Hashtbl.replace *)
  tbl{"foo"} <= 1                           (* Hashtbl.add *)
  tbl{"foo"} ->                             (* Hashtbl.remove *)
  keys tbl                                  (* Perl "keys" operator *)
  values tbl                                (* Perl "values" operator *)

If anybody wants to have a look at it, I need some advice/feedback on
the following issues:
- how to cope with errors (now they are _really_ strange :-)
- I've used everywhere expressions of LEVEL "simple" to avoid conflicts
  with bigarray pattern syntax, any other solution?
- my extension of standard "expr1" level now begins with a fallback on
  "simple" expression. What I want to do is to put those rules after the
  rules for "simple" expressions, but I had not found a better way to do
  it ...
- what about the chosen syntax? suggestions?
- I had not found a way to define an integer constant and use it inside
  a quotation, the only solution I had found is to pass from strings:

    let foo = "10" in
    <:expr< $int:foo$ >>

  what am I missing?

TIA for the feedback,
Cheers.

-- 
Stefano Zacchiroli  --  Master in Computer Science @ Uni. Bologna, Italy
zack@{cs.unibo.it,debian.org,bononia.it}  -  http://www.bononia.it/zack/
"  I know you believe you understood what you think I said, but I am not
sure you realize that what you heard is not what I meant!  " -- G.Romney

[-- Attachment #2: hashtbl_ext.ml --]
[-- Type: text/plain, Size: 4030 bytes --]


(*
  Hashtbl creation

      (* create an hashtbl of with (initial size = magic_size) *)
    let tbl = {}

      (* create an hashtbl of initial size 12 *)
    let tbl = {}|12|

      (* create an hashbbl of size 3, with bindings specified in an
      associative-list-like manner. If a key occurs more than once the first one
      appearing in the list will be the more recent one. Every expression
      returning an associative list could be used inside braces *)
    let tbl = {["foo", 1; "bar", 2; "quux", 3]}

      (* as above, with initial size 17 *)
    let tbl = {["foo", 1; "bar", 2; "quux", 3]}|17|

  Hashtbl lookup

    tbl{"foo"}            (* Hashtbl.find tbl "foo" *)
    tbl{["foo"]}          (* Hashtbl.find_all tbl "foo" *)
    tbl{?"foo"}           (* Hashtbl.mem tbl "foo" *)

  Hashtbl insertion

    tbl{"foo"} <- 1       (* Hashtbl.replace tbl "foo" 1 *)
    tbl{"foo"} <= 1       (* Hashtbl.add tbl "foo" 1 *)

  Hashtbl deletion

    tbl{"foo"} ->         (* Hashtbl.remove tbl "foo" *)

  Perl-like operators

    keys tbl              (* list all keys in tbl *)
    values tbl            (* list all values in tbl, multiple binding are
                          reported more than once *)

  Usage (assuming that the .cmo is in a directory that is in the camlp4 path,
        otherwise you need to add -I to camlp4{o,r} as needed):

    ocaml{c,opt} -pp "camlp4{o,r} hashtbl_ext.cmo" <source.ml>
*)

open Pcaml

let magic_size = 1024

let hashtbl_find loc tbl k = <:expr< Hashtbl.find $tbl$ $k$ >>
let hashtbl_find_all loc tbl k = <:expr< Hashtbl.find_all $tbl$ $k$ >>
let hashtbl_mem loc tbl k = <:expr< Hashtbl.mem $tbl$ $k$ >>
let hashtbl_add loc tbl k v = <:expr< Hashtbl.add $tbl$ $k$ $v$ >>
let hashtbl_replace loc tbl k v = <:expr< Hashtbl.replace $tbl$ $k$ $v$ >>
let hashtbl_remove loc tbl k = <:expr< Hashtbl.remove $tbl$ $k$ >>

let hashtbl_keys loc tbl =
  <:expr< Hashtbl.fold (fun k _ acc -> [k :: acc]) $tbl$ [] >>
let hashtbl_values loc tbl =
  <:expr< Hashtbl.fold (fun _ v acc -> [v :: acc]) $tbl$ [] >>

let magic_size = string_of_int magic_size
let hashtbl_create loc size content =
  <:expr<
    let size =
      match $int:size$ with
      [ 0 ->
          match $content$ with
          [ [] -> $int:magic_size$
          | _ -> List.length $content$ ]
      | v -> v ]
    in
    let table = Hashtbl.create size in
    do {
      List.iter (fun (k,v) -> Hashtbl.add table k v) $content$;
      table
    }
  >>

EXTEND

  expr: LEVEL "expr1"
    [
      [ e = expr LEVEL "simple" -> e
      | table = expr LEVEL "simple"; "{"; key = expr LEVEL "simple"; "}" ->
          hashtbl_find loc table key
      | table = expr LEVEL "simple";
        "{"; "["; key = expr LEVEL "simple"; "]"; "}" ->
          hashtbl_find_all loc table key
      | table = expr LEVEL "simple"; "{"; "?"; key = expr LEVEL "simple"; "}" ->
          hashtbl_mem loc table key
      | table = expr LEVEL "simple"; "{"; key = expr LEVEL "simple"; "}";
        "<-"; value = expr LEVEL "simple" ->
          hashtbl_replace loc table key value
      | table = expr LEVEL "simple"; "{"; key = expr LEVEL "simple"; "}";
        "<="; value = expr LEVEL "simple" ->
          hashtbl_add loc table key value
      | table = expr LEVEL "simple"; "{"; key = expr LEVEL "simple"; "}";
        "->" ->
          hashtbl_remove loc table key
      ]
    ];

  expr: LEVEL "simple"
    [
      [ "keys"; e = SELF -> hashtbl_keys loc e
      | "values"; e = SELF -> hashtbl_values loc e
      ]
    ];

  let_binding: FIRST
    [
      [ id = [ id = LIDENT -> id | "_" -> "" ]; "=";
        "{"; content = OPT [ e = expr LEVEL "simple" -> e ]; "}";
        size = OPT [ "|"; size = INT; "|" -> size ] ->
          let size = match size with None -> "0" | Some v -> v in
          let content =
            match content with None -> <:expr< [] >> | Some c -> c
          in
          ((match id with "" -> <:patt< _ >> | id -> <:patt< $lid:id$ >>),
           hashtbl_create loc size content)
      ]
    ];

END


^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: [Caml-list] camlp4 syntax extension for hashtbl
  2003-06-26 22:52 [Caml-list] camlp4 syntax extension for hashtbl Stefano Zacchiroli
@ 2003-06-28 10:57 ` Stefano Zacchiroli
  0 siblings, 0 replies; 2+ messages in thread
From: Stefano Zacchiroli @ 2003-06-28 10:57 UTC (permalink / raw)
  To: caml-list

Uhm ... not yet :-)

There is a problem with let_binding definition that I'm trying to solve
...

BTW where is the camlp4 grammar for the ocaml abstract syntax?

Right now I've looked in the ocaml sources in camlp4/etc/pa_o.ml, but
not all syntactic classes found there are exported in the Pcaml module
(e.g.  "fun_binding").

TIA,
Cheers.

-- 
Stefano Zacchiroli  --  Master in Computer Science @ Uni. Bologna, Italy
zack@{cs.unibo.it,debian.org,bononia.it}  -  http://www.bononia.it/zack/
"  I know you believe you understood what you think I said, but I am not
sure you realize that what you heard is not what I meant!  " -- G.Romney

-------------------
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


^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2003-06-28 10:57 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2003-06-26 22:52 [Caml-list] camlp4 syntax extension for hashtbl Stefano Zacchiroli
2003-06-28 10:57 ` Stefano Zacchiroli

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).