1
1
(************************************************************************)
2
2
(* v * The Coq Proof Assistant / The Coq Development Team *)
3
(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2010 *)
3
(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2011 *)
4
4
(* \VV/ **************************************************************)
5
5
(* // * This file is distributed under the terms of the *)
6
6
(* * GNU Lesser General Public License Version 2.1 *)
7
7
(************************************************************************)
9
(*i $Id: ocaml.ml 14010 2011-04-15 16:05:07Z letouzey $ i*)
9
(*i $Id: ocaml.ml 14641 2011-11-06 11:59:10Z herbelin $ i*)
11
11
(*s Production of Ocaml syntax. *)
113
113
let s = find_custom r in
114
114
String.sub s 1 (String.length s - 2)
118
let find_projections = function Record l -> l | _ -> raise NoRecord
116
let get_ind = function
118
| ConstructRef (ind,_) -> IndRef ind
121
let pp_one_field r i = function
122
| Some r -> pp_global Term r
123
| None -> pp_global Type (get_ind r) ++ str "__" ++ int i
125
let pp_field r fields i = pp_one_field r i (List.nth fields i)
127
let pp_fields r fields = list_map_i (pp_one_field r) 0 fields
120
129
(*s Pretty-printing of types. [par] is a boolean indicating whether parentheses
121
130
are needed or not. *)
202
211
| MLcons (_,r,[]) ->
203
212
assert (args=[]);
205
| MLcons ({c_kind = Record projs}, r, args') ->
214
| MLcons ({c_kind = Record fields}, r, args') ->
206
215
assert (args=[]);
207
pp_record_pat (projs, List.map (pp_expr true env []) args')
216
pp_record_pat (pp_fields r fields, List.map (pp_expr true env []) args')
208
217
| MLcons (_,r,[arg1;arg2]) when is_infix r ->
209
218
assert (args=[]);
234
243
(pp_expr false env [] t)
237
let projs = find_projections info.m_kind in
238
let (_, ids, c) = pv.(0) in
246
(* First, can this match be printed as a mere record projection ? *)
248
match info.m_kind with Record f -> f | _ -> raise Impossible
250
let (r, ids, c) = pv.(0) in
239
251
let n = List.length ids in
252
let free_of_patvar a = not (List.exists (ast_occurs_itvl 1 n) a) in
254
pp_expr true env [] t ++ str "." ++ pp_field r fields i
241
| MLrel i when i <= n ->
242
apply (pp_par par' (pp_expr true env [] t ++ str "." ++
243
pp_global Term (List.nth projs (n-i))))
244
| MLapp (MLrel i, a) when i <= n ->
245
if List.exists (ast_occurs_itvl 1 n) a
248
let ids,env' = push_vars (List.rev_map id_of_mlid ids) env
251
(pp_expr true env [] t ++ str "." ++
252
pp_global Term (List.nth projs (n-i)))
253
par ((List.map (pp_expr true env' []) a) @ args))
254
| _ -> raise NoRecord
257
| MLrel i when i <= n -> apply (pp_par par' (proj_hd (n-i)))
258
| MLapp (MLrel i, a) when (i <= n) && (free_of_patvar a) ->
259
let ids,env' = push_vars (List.rev_map id_of_mlid ids) env in
260
(pp_apply (proj_hd (n-i))
261
par ((List.map (pp_expr true env' []) a) @ args))
262
| _ -> raise Impossible
264
(* Second, can this match be printed as a let-in ? *)
256
265
if Array.length pv = 1 then
257
266
let s1,s2 = pp_one_pat env info pv.(0) in
283
293
pp_par par (str "failwith \"AXIOM TO BE REALIZED\"")
286
and pp_record_pat (projs, args) =
296
and pp_record_pat (fields, args) =
288
298
prlist_with_sep (fun () -> str ";" ++ spc ())
289
(fun (r,a) -> pp_global Term r ++ str " =" ++ spc () ++ a)
290
(List.combine projs args) ++
299
(fun (f,a) -> f ++ str " =" ++ spc () ++ a)
300
(List.combine fields args) ++
293
303
and pp_ifthenelse par env expr pv = match pv with
304
314
and pp_one_pat env info (r,ids,t) =
305
315
let ids,env' = push_vars (List.rev_map id_of_mlid ids) env in
306
316
let expr = pp_expr (expr_needs_par t) env' [] t in
308
let projs = find_projections info.m_kind in
309
pp_record_pat (projs, List.rev_map pr_id ids), expr
311
(match List.rev ids with
312
| [i1;i2] when is_infix r -> pr_id i1 ++ str (get_infix r) ++ pr_id i2
313
| [] -> pp_global Cons r
317
let patt = match info.m_kind with
319
pp_record_pat (pp_fields r fields, List.rev_map pr_id ids)
320
| _ -> match List.rev ids with
321
| [i1;i2] when is_infix r -> pr_id i1 ++ str (get_infix r) ++ pr_id i2
322
| [] -> pp_global Cons r
315
324
(* hack Extract Inductive prod *)
316
325
(if str_global Cons r = "" then mt () else pp_global Cons r ++ spc ())
317
++ pp_boxed_tuple pr_id ids),
326
++ pp_boxed_tuple pr_id ids
320
330
and pp_pat env info pv =
321
331
let factor_br, factor_set = try match info.m_same with
448
458
pp_comment (str "singleton inductive, whose constructor was " ++
449
459
pr_id packet.ip_consnames.(0)))
451
let pp_record kn projs ip_equiv packet =
452
let name = pp_global Type (IndRef (mind_of_kn kn,0)) in
453
let projnames = List.map (pp_global Term) projs in
454
let l = List.combine projnames packet.ip_types.(0) in
461
let pp_record kn fields ip_equiv packet =
462
let ind = IndRef (mind_of_kn kn,0) in
463
let name = pp_global Type ind in
464
let fieldnames = pp_fields ind fields in
465
let l = List.combine fieldnames packet.ip_types.(0) in
455
466
let pl = rename_tvars keywords packet.ip_vars in
456
467
str "type " ++ pp_parameters pl ++ name ++
457
468
pp_equiv pl name ip_equiv ++ str " = { "++
512
523
match i.ind_kind with
513
524
| Singleton -> pp_singleton kn i.ind_packets.(0)
514
525
| Coinductive -> pp_ind true kn i
516
pp_record kn projs (i.ind_equiv,0) i.ind_packets.(0)
526
| Record fields -> pp_record kn fields (i.ind_equiv,0) i.ind_packets.(0)
517
527
| Standard -> pp_ind false kn i
519
529
let pp_decl = function