1
(************************************************************************)
2
(* v * The Coq Proof Assistant / The Coq Development Team *)
3
(* <O___,, * CNRS-Ecole Polytechnique-INRIA Futurs-Universite Paris Sud *)
4
(* \VV/ **************************************************************)
5
(* // * This file is distributed under the terms of the *)
6
(* * GNU Lesser General Public License Version 2.1 *)
7
(************************************************************************)
9
(*i $Id: scheme.ml 11559 2008-11-07 22:03:34Z letouzey $ i*)
11
(*s Production of Scheme syntax. *)
23
(*s Scheme renaming issues. *)
26
List.fold_right (fun s -> Idset.add (id_of_string s))
27
[ "define"; "let"; "lambda"; "lambdas"; "match";
28
"apply"; "car"; "cdr";
29
"error"; "delay"; "force"; "_"; "__"]
32
let preamble _ _ usf =
33
str ";; This extracted scheme code relies on some additional macros\n" ++
34
str ";; available at http://www.pps.jussieu.fr/~letouzey/scheme\n" ++
35
str "(load \"macros_extr.scm\")\n\n" ++
36
(if usf.mldummy then str "(define __ (lambda (_) __))\n\n" else mt ())
39
let s = string_of_id id in
40
for i = 0 to String.length s - 1 do
41
if s.[i] = '\'' then s.[i] <- '~'
45
let paren = pp_par true
47
let pp_abst st = function
49
| [id] -> paren (str "lambda " ++ paren (pr_id id) ++ spc () ++ st)
51
(str "lambdas " ++ paren (prlist_with_sep spc pr_id l) ++ spc () ++ st)
53
let pp_apply st _ = function
55
| [a] -> hov 2 (paren (st ++ spc () ++ a))
56
| args -> hov 2 (paren (str "@ " ++ st ++
57
(prlist_strict (fun x -> spc () ++ x) args)))
59
(*s The pretty-printer for Scheme syntax *)
61
let pp_global k r = str (Common.pp_global k r)
63
(*s Pretty-printing of expressions. *)
65
let rec pp_expr env args =
66
let apply st = pp_apply st true args in
69
let id = get_db_name n env in apply (pr_id id)
71
let stl = List.map (pp_expr env []) args' in
72
pp_expr env (stl @ args) f
74
let fl,a' = collect_lams a in
75
let fl,env' = push_vars fl env in
76
apply (pp_abst (pp_expr env' [] a') (List.rev fl))
77
| MLletin (id,a1,a2) ->
78
let i,env' = push_vars [id] env in
86
(pr_id (List.hd i) ++ spc () ++ pp_expr env [] a1))
87
++ spc () ++ hov 0 (pp_expr env' [] a2)))))
89
apply (pp_global Term r)
90
| MLcons (i,r,args') ->
94
paren (pp_global Cons r ++
95
(if args' = [] then mt () else spc ()) ++
96
prlist_with_sep spc (pp_cons_args env) args')
98
if i = Coinductive then paren (str "delay " ++ st) else st
99
| MLcase ((i,_),t, pv) ->
101
if i <> Coinductive then pp_expr env [] t
102
else paren (str "force" ++ spc () ++ pp_expr env [] t)
104
apply (v 3 (paren (str "match " ++ e ++ fnl () ++ pp_pat env pv)))
105
| MLfix (i,ids,defs) ->
106
let ids',env' = push_vars (List.rev (Array.to_list ids)) env in
107
pp_fix env' i (Array.of_list (List.rev ids'),defs) args
109
(* An [MLexn] may be applied, but I don't really care. *)
110
paren (str "error" ++ spc () ++ qs s)
112
str "__" (* An [MLdummy] may be applied, but I don't really care. *)
115
| MLaxiom -> paren (str "error \"AXIOM TO BE REALIZED\"")
117
and pp_cons_args env = function
118
| MLcons (i,r,args) when i<>Coinductive ->
119
paren (pp_global Cons r ++
120
(if args = [] then mt () else spc ()) ++
121
prlist_with_sep spc (pp_cons_args env) args)
122
| e -> str "," ++ pp_expr env [] e
125
and pp_one_pat env (r,ids,t) =
126
let ids,env' = push_vars (List.rev ids) env in
128
if ids = [] then mt ()
129
else (str " " ++ prlist_with_sep spc pr_id (List.rev ids))
131
(pp_global Cons r ++ args), (pp_expr env' [] t)
135
(fun x -> let s1,s2 = pp_one_pat env x in
136
hov 2 (str "((" ++ s1 ++ str ")" ++ spc () ++ s2 ++ str ")")) pv
138
(*s names of the functions ([ids]) are already pushed in [env],
139
and passed here just for convenience. *)
141
and pp_fix env j (ids,bl) args =
147
paren ((pr_id fi) ++ spc () ++ (pp_expr env [] ti)))
148
(array_map2 (fun id b -> (id,b)) ids bl)) ++
150
hov 2 (pp_apply (pr_id (ids.(j))) true args))))
152
(*s Pretty-printing of a declaration. *)
154
let pp_decl = function
157
| Dfix (rv, defs,_) ->
158
let ppv = Array.map (pp_global Term) rv in
162
(paren (str "define " ++ pi ++ spc () ++
163
(pp_expr (empty_env ()) [] ti))
165
(array_map2 (fun p b -> (p,b)) ppv defs) ++
168
if is_inline_custom r then mt ()
171
hov 2 (paren (str "define " ++ pp_global Term r ++ spc () ++
172
str (find_custom r))) ++ fnl () ++ fnl ()
174
hov 2 (paren (str "define " ++ pp_global Term r ++ spc () ++
175
pp_expr (empty_env ()) [] a)) ++ fnl () ++ fnl ()
177
let pp_structure_elem = function
178
| (l,SEdecl d) -> pp_decl d
180
failwith "TODO: Scheme extraction of modules not implemented yet"
182
failwith "TODO: Scheme extraction of modules not implemented yet"
185
let pp_sel (mp,sel) =
186
push_visible mp None;
187
let p = prlist_strict pp_structure_elem sel in
194
file_suffix = ".scm";
195
capital_file = false;
197
pp_struct = pp_struct;
199
sig_preamble = (fun _ _ _ -> mt ());
200
pp_sig = (fun _ -> mt ());