caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
* small Camlp4 code : get a free name
@ 2008-01-23 19:59 blue storm
  2008-01-23 20:30 ` [Caml-list] " Martin Jambon
  2008-02-09 19:13 ` Nicolas Pouillard
  0 siblings, 2 replies; 5+ messages in thread
From: blue storm @ 2008-01-23 19:59 UTC (permalink / raw)
  To: caml-list

>> I deduce that there is no standard way of introducing
>> `fresh' (w.r.t. the abstract syntax tree) variables
>> within a camlp4 syntax extension? Wouldn't that be nice? =)

>> Has anybody every implemented a solution to that problem?

> That  would be nice, but doing it cleanly would require a large amount of work
> and user visible changes.

I'm not sure it's a "clean" way of doing it, but i think this may works :
you can fold the AST to get every bound variable names, and then look
for conflicts.

I tried to do that. See my camlp4 code at the end of the message.

The folder is very simple : it collects every identifier name, even
not-really-bounded ones (eg. in patterns). I don't think it's a
problem : the important thing is to get no false positive.

Is there a problem with this method ?
Do you have any comment or advice ?

------------------
open Camlp4;

module Make (Syntax : Sig.Camlp4Syntax) = struct
  open Syntax;

  value get_bound_vars =
    let folder = object (self)
      inherit Ast.fold as super;

      value binds = [];
      method binds = binds;

      method ident = fun
        [ <:ident< $lid:id$ >> | <:ident< $uid:id$ >> ->
          {< binds = [id::binds] >}
        | other -> super#ident other ];
    end in
    fun expr -> (folder#expr expr)#binds;

  value get_free_var suffix binds =
    let rec generate var =
      if List.mem var binds
      then generate ("_" ^ var ^ "_")
      else var
    in generate suffix;
end;
------------------


You can test it with this example code (for example) :
------------------
open Camlp4
open PreCast

module FV = Freevars.Make(Syntax)

let _loc = Loc.ghost
let expr = <:expr< match foo with bar -> foo2 | _ -> 1 + 2 >>

let binds = FV.get_bound_vars expr
let fv = FV.get_free_var "foo" binds
(* fv is "_foo_" *)
------------------

Thanks for your comments.


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

end of thread, other threads:[~2008-02-09 19:15 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-01-23 19:59 small Camlp4 code : get a free name blue storm
2008-01-23 20:30 ` [Caml-list] " Martin Jambon
2008-01-23 21:35   ` Edgar Friendly
2008-02-09 19:01     ` Nicolas Pouillard
2008-02-09 19:13 ` Nicolas Pouillard

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