From: "blue storm" <bluestorm.dylc@gmail.com>
To: caml-list@yquem.inria.fr
Subject: small Camlp4 code : get a free name
Date: Wed, 23 Jan 2008 20:59:59 +0100 [thread overview]
Message-ID: <527cf6bc0801231159o7c001a73lddd74e5b3cb30061@mail.gmail.com> (raw)
>> 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.
next reply other threads:[~2008-01-23 20:00 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-01-23 19:59 blue storm [this message]
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
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=527cf6bc0801231159o7c001a73lddd74e5b3cb30061@mail.gmail.com \
--to=bluestorm.dylc@gmail.com \
--cc=caml-list@yquem.inria.fr \
/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;
as well as URLs for NNTP newsgroup(s).