Skip to content

Commit

Permalink
Extend ifdef example, with a compile-time getenv.
Browse files Browse the repository at this point in the history
git-svn-id: http://caml.inria.fr/svn/ocaml/trunk@12655 f963ae5c-01c2-4b8c-9fe0-0dff7051ff02
  • Loading branch information
alainfrisch committed Jun 29, 2012
1 parent 9d32d89 commit 07a3f52
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 7 deletions.
9 changes: 8 additions & 1 deletion experimental/frisch/ast_mapper.ml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ open Asttypes
(* First, some helpers to build AST fragments *)

let map_flatten f l = List.flatten (List.map f l)
let map_snd f (x, y) = (x, f y)

module SI = struct
(* Structure items *)
Expand Down Expand Up @@ -33,7 +34,8 @@ module E = struct
let ident ?loc x = mk ?loc (Pexp_ident x)
let lid ?(loc = Location.none) lid = ident ~loc (mkloc (Longident.parse lid) loc)
let let_ ?loc r pel e = mk ?loc (Pexp_let (r, pel, e))
let app ?loc f el = mk ?loc (Pexp_apply (f, List.map (fun e -> ("", e)) el))
let apply_with_labels ?loc f el = mk ?loc (Pexp_apply (f, el))
let apply ?loc f el = apply_with_labels ?loc f (List.map (fun e -> ("", e)) el)
let const ?loc x = mk ?loc (Pexp_constant x)
let strconst ?loc x = const ?loc (Const_string x)
end
Expand Down Expand Up @@ -235,6 +237,7 @@ class create =
match desc with
| Pexp_ident x -> this # exp_ident ~loc x
| Pexp_let (r, pel, e) -> this # exp_let ~loc r pel e
| Pexp_apply (e, l) -> this # exp_apply ~loc e l
(* ... *)
| _ -> x

Expand All @@ -247,6 +250,10 @@ class create =
(List.map (fun (p, e) -> this # pat p, this # expr e) pel)
(this # expr e)

method exp_apply = this # default_exp_apply
method default_exp_apply ~loc e l =
E.apply_with_labels ~loc (this # expr e) (List.map (map_snd (this # expr)) l)

(* module exprs *)

method module_expr = this # default_module_expr
Expand Down
23 changes: 22 additions & 1 deletion experimental/frisch/ifdef.ml
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,20 @@
IFDEF(X)(<m1>)(<m2>)
---> <m1> if the environment variable X is defined
---> <m2> otherwise
And, on expressions:
GETENV X ---> the string literal representing the compile-time value
of environment variable X
*)

open Ast_mapper
open Parsetree
open Longident
open Location

let getenv s = try Sys.getenv s with Not_found -> ""

let ifdef =
object(this)
inherit Ast_mapper.create as super
Expand All @@ -22,7 +30,7 @@ let ifdef =
)},
body_def)},
body_not_def)} ->
if (try Sys.getenv sym <> "" with Not_found -> false) then
if getenv sym <> "" then
this # module_expr body_def
else
this # module_expr body_not_def
Expand All @@ -32,6 +40,19 @@ let ifdef =
Location.print_loc loc;
exit 2
| x -> super # module_expr x

method! expr = function
| {pexp_desc = Pexp_construct (
{txt = Lident "GETENV"},
Some {pexp_loc = loc; pexp_desc = Pexp_construct (
{txt = Lident sym},
None,
_
)},
_
)} ->
E.strconst ~loc (getenv sym)
| x -> super # expr x
end

let () = ifdef # main
9 changes: 7 additions & 2 deletions experimental/frisch/test_ifdef.ml
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
include IFDEF(XHOME)(struct
let () = print_endline "Defined!"
end)
(*(struct
(struct
let () = print_endline "Not defined!"
end)
*)


let () =
Printf.printf "compiled by user %s in directory %s\n%!"
(GETENV USER)
(GETENV PWD)
4 changes: 1 addition & 3 deletions experimental/frisch/tracer.ml
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
open Ast_mapper
open Longident
open Location
open Parsetree

(* To define a concrete AST rewriter, we can inherit from the generic
mapper, and redefine the cases we are interested in. In the
Expand All @@ -10,7 +8,7 @@ open Parsetree
the compilation unit. *)

let trace s =
SI.eval E.(app (lid "Pervasives.print_endline") [strconst s])
SI.eval E.(apply (lid "Pervasives.print_endline") [strconst s])

let tracer =
object
Expand Down

0 comments on commit 07a3f52

Please sign in to comment.