ocaml/camlp4/etc/pr_rp_main.ml

207 lines
6.8 KiB
OCaml

(* camlp4r q_MLast.cmo ./pa_extfun.cmo *)
(***********************************************************************)
(* *)
(* Camlp4 *)
(* *)
(* Daniel de Rauglaudre, projet Cristal, INRIA Rocquencourt *)
(* *)
(* Copyright 1998 Institut National de Recherche en Informatique et *)
(* Automatique. Distributed only by permission. *)
(* *)
(***********************************************************************)
(* $Id$ *)
open Pcaml;
open Spretty;
value _loc = (Token.nowhere, Token.nowhere);
value expr e dg k = pr_expr.pr_fun "top" e dg k;
value patt e dg k = pr_patt.pr_fun "top" e dg k;
(* Streams *)
value stream e dg k =
let rec get =
fun
[ <:expr< Stream.iapp $x$ $y$ >> -> [(False, x) :: get y]
| <:expr< Stream.icons $x$ $y$ >> -> [(True, x) :: get y]
| <:expr< Stream.ising $x$ >> -> [(True, x)]
| <:expr< Stream.lapp (fun _ -> $x$) $y$ >> -> [(False, x) :: get y]
| <:expr< Stream.lcons (fun _ -> $x$) $y$ >> -> [(True, x) :: get y]
| <:expr< Stream.lsing (fun _ -> $x$) >> -> [(True, x)]
| <:expr< Stream.sempty >> -> []
| <:expr< Stream.slazy (fun _ -> $x$) >> -> [(False, x)]
| <:expr< Stream.slazy $x$ >> -> [(False, <:expr< $x$ () >>)]
| e -> [(False, e)] ]
in
let elem e k =
match e with
[ (True, e) -> [: `HOVbox [: `S LO "`"; `expr e "" k :] :]
| (False, e) -> [: `expr e "" k :] ]
in
let rec glop e k =
match e with
[ [] -> k
| [e] -> [: elem e k :]
| [e :: el] -> [: elem e [: `S RO ";" :]; glop el k :] ]
in
HOVbox [: `S LR "[:"; glop (get e) [: `S LR ":]"; k :] :]
;
(* Parsers *)
open Parserify;
value parser_cases b spel k =
let rec parser_cases b spel k =
match spel with
[ [] -> [: `HVbox [: b; k :] :]
| [(sp, epo, e)] -> [: `parser_case b sp epo e k :]
| [(sp, epo, e) :: spel] ->
[: `parser_case b sp epo e [: :];
parser_cases [: `S LR "|" :] spel k :] ]
and parser_case b sp epo e k =
let epo =
match epo with
[ Some p -> [: `patt p "" [: `S LR "->" :] :]
| _ -> [: `S LR "->" :] ]
in
HVbox
[: b;
`HOVbox
[: `HOVbox
[: `S LR "[:";
stream_patt [: :] sp [: `S LR ":]"; epo :] :];
`expr e "" k :] :]
and stream_patt b sp k =
match sp with
[ [] -> [: `HVbox [: b; k :] :]
| [(spc, None)] -> [: `stream_patt_comp b spc k :]
| [(spc, Some e)] ->
[: `HVbox
[: `stream_patt_comp b spc [: :];
`HVbox [: `S LR "?"; `expr e "" k :] :] :]
| [(spc, None) :: spcl] ->
[: `stream_patt_comp b spc [: `S RO ";" :];
stream_patt [: :] spcl k :]
| [(spc, Some e) :: spcl] ->
[: `HVbox
[: `stream_patt_comp b spc [: :];
`HVbox [: `S LR "?"; `expr e "" [: `S RO ";" :] :] :];
stream_patt [: :] spcl k :] ]
and stream_patt_comp b spc k =
match spc with
[ SPCterm (p, w) ->
HVbox [: b; `S LO "`"; `patt p "" [: :]; `HVbox [: when_opt w k :] :]
| SPCnterm p e ->
HVbox [: b; `HVbox [: `patt p "" [: `S LR "=" :]; `expr e "" k :] :]
| SPCsterm p -> HVbox [: b; `patt p "" k :] ]
and when_opt wo k =
match wo with
[ Some e -> [: `S LR "when"; `expr e "" k :]
| _ -> k ]
in
parser_cases b spel k
;
value parser_body e dg k =
let (bp, e) =
match e with
[ <:expr< let $bp$ = Stream.count strm__ in $e$ >> -> (Some bp, e)
| e -> (None, e) ]
in
match parser_of_expr e with
[ [] ->
HVbox
[: `HVbox
[: `S LR "parser";
match bp with
[ Some p -> [: `patt p "" [: :] :]
| _ -> [: :] ] :];
`HVbox [: `S LR "[]"; k :] :]
| [spe] ->
HVbox
[: `HVbox
[: `S LR "parser";
match bp with
[ Some p -> [: `patt p "" [: :] :]
| _ -> [: :] ] :];
parser_cases [: :] [spe] k :]
| spel ->
Vbox
[: `HVbox [: :];
`HVbox
[: `S LR "parser";
match bp with
[ Some p -> [: `patt p "" [: :] :]
| _ -> [: :] ] :];
parser_cases [: `S LR "[" :] spel [: `S LR "]"; k :] :] ]
;
value pmatch e dg k =
let (me, e) =
match e with
[ <:expr< let (strm__ : Stream.t _) = $me$ in $e$ >> -> (me, e)
| _ -> failwith "Pr_rp.pmatch" ]
in
let (bp, e) =
match e with
[ <:expr< let $bp$ = Stream.count strm__ in $e$ >> -> (Some bp, e)
| e -> (None, e) ]
in
let spel = parser_of_expr e in
Vbox
[: `HVbox [: :];
`HVbox
[: `S LR "match"; `expr me "" [: `S LR "with" :]; `S LR "parser";
match bp with
[ Some p -> [: `patt p "" [: :] :]
| _ -> [: :] ] :];
parser_cases [: `S LR "[" :] spel [: `S LR "]"; k :] :]
;
(* Printer extensions *)
pr_expr_fun_args.val :=
extfun pr_expr_fun_args.val with
[ <:expr< fun strm__ -> $_$ >> as ge -> ([], ge)
| <:expr< fun [(strm__ : $_$) -> $_$] >> as ge -> ([], ge) ];
let lev = find_pr_level "top" pr_expr.pr_levels in
lev.pr_rules :=
extfun lev.pr_rules with
[ <:expr< let (strm__ : Stream.t _) = $_$ in $_$ >> as e ->
fun curr next _ k -> [: `pmatch e "" k :]
| <:expr< fun strm__ -> $x$ >> ->
fun curr next _ k -> [: `parser_body x "" k :]
| <:expr< fun (strm__ : $_$) -> $x$ >> ->
fun curr next _ k -> [: `parser_body x "" k :] ];
let lev = find_pr_level "apply" pr_expr.pr_levels in
lev.pr_rules :=
extfun lev.pr_rules with
[ <:expr< Stream.iapp $_$ $_$ >> | <:expr< Stream.icons $_$ $_$ >> |
<:expr< Stream.ising $_$ >> | <:expr< Stream.lapp (fun _ -> $_$) $_$ >> |
<:expr< Stream.lcons (fun _ -> $_$) $_$ >> |
<:expr< Stream.lsing (fun _ -> $_$) >> | <:expr< Stream.sempty >> |
<:expr< Stream.slazy $_$ >> as e ->
fun curr next _ k -> [: `next e "" k :] ];
let lev = find_pr_level "dot" pr_expr.pr_levels in
lev.pr_rules :=
extfun lev.pr_rules with
[ <:expr< Stream.sempty >> as e ->
fun curr next _ k -> [: `next e "" k :] ];
let lev = find_pr_level "simple" pr_expr.pr_levels in
lev.pr_rules :=
extfun lev.pr_rules with
[ <:expr< Stream.iapp $_$ $_$ >> | <:expr< Stream.icons $_$ $_$ >> |
<:expr< Stream.ising $_$ >> | <:expr< Stream.lapp (fun _ -> $_$) $_$ >> |
<:expr< Stream.lcons (fun _ -> $_$) $_$ >> |
<:expr< Stream.lsing (fun _ -> $_$) >> | <:expr< Stream.sempty >> |
<:expr< Stream.slazy $_$ >> as e ->
fun curr next _ k -> [: `stream e "" k :] ];