ocaml/camlp4/meta/pa_ifdef.ml

86 lines
3.0 KiB
OCaml

(* camlp4r pa_extend.cmo q_MLast.cmo *)
(* $Id$ *)
type item_or_def 'a =
[ SdStr of 'a | SdDef of string | SdUnd of string | SdNop ]
;
value list_remove x l =
List.fold_right (fun e l -> if e = x then l else [e :: l]) l []
;
value defined = ref ["OCAML_305"; "CAMLP4_300"; "NEWSEQ"];
value define x = defined.val := [x :: defined.val];
value undef x = defined.val := list_remove x defined.val;
EXTEND
GLOBAL: Pcaml.expr Pcaml.str_item Pcaml.sig_item;
Pcaml.expr: LEVEL "top"
[ [ "ifdef"; c = UIDENT; "then"; e1 = Pcaml.expr; "else";
e2 = Pcaml.expr ->
if List.mem c defined.val then e1 else e2
| "ifndef"; c = UIDENT; "then"; e1 = Pcaml.expr; "else";
e2 = Pcaml.expr ->
if List.mem c defined.val then e2 else e1 ] ]
;
Pcaml.str_item: FIRST
[ [ x = def_undef_str ->
match x with
[ SdStr si -> si
| SdDef x -> do { define x; <:str_item< declare end >> }
| SdUnd x -> do { undef x; <:str_item< declare end >> }
| SdNop -> <:str_item< declare end >> ] ] ]
;
def_undef_str:
[ [ "ifdef"; c = UIDENT; "then"; e1 = str_item_def_undef;
"else"; e2 = str_item_def_undef ->
if List.mem c defined.val then e1 else e2
| "ifdef"; c = UIDENT; "then"; e1 = str_item_def_undef ->
if List.mem c defined.val then e1 else SdNop
| "ifndef"; c = UIDENT; "then"; e1 = str_item_def_undef;
"else"; e2 = str_item_def_undef ->
if List.mem c defined.val then e2 else e1
| "ifndef"; c = UIDENT; "then"; e1 = str_item_def_undef ->
if List.mem c defined.val then SdNop else e1
| "define"; c = UIDENT -> SdDef c
| "undef"; c = UIDENT -> SdUnd c ] ]
;
str_item_def_undef:
[ [ d = def_undef_str -> d
| si = Pcaml.str_item -> SdStr si ] ]
;
Pcaml.sig_item: FIRST
[ [ x = def_undef_sig ->
match x with
[ SdStr si -> si
| SdDef x -> do { define x; <:sig_item< declare end >> }
| SdUnd x -> do { undef x; <:sig_item< declare end >> }
| SdNop -> <:sig_item< declare end >> ] ] ]
;
def_undef_sig:
[ [ "ifdef"; c = UIDENT; "then"; e1 = sig_item_def_undef;
"else"; e2 = sig_item_def_undef ->
if List.mem c defined.val then e1 else e2
| "ifdef"; c = UIDENT; "then"; e1 = sig_item_def_undef ->
if List.mem c defined.val then e1 else SdNop
| "ifndef"; c = UIDENT; "then"; e1 = sig_item_def_undef;
"else"; e2 = sig_item_def_undef ->
if List.mem c defined.val then e2 else e1
| "ifndef"; c = UIDENT; "then"; e1 = sig_item_def_undef ->
if List.mem c defined.val then SdNop else e1
| "define"; c = UIDENT -> SdDef c
| "undef"; c = UIDENT -> SdUnd c ] ]
;
sig_item_def_undef:
[ [ d = def_undef_sig -> d
| si = Pcaml.sig_item -> SdStr si ] ]
;
END;
Pcaml.add_option "-D" (Arg.String define)
"<string> Define for ifdef instruction."
;
Pcaml.add_option "-U" (Arg.String undef)
"<string> Undefine for ifdef instruction."
;