@@ -257,14 +257,82 @@ let string_of_exp_con (E_aux (e, _)) =
257
257
| E_vector _ -> " E_vector"
258
258
| E_let _ -> " E_let"
259
259
260
+ let string_of_pat_con (P_aux (p , _ )) =
261
+ match p with
262
+ | P_app _ -> " P_app"
263
+ | P_wild -> " P_wild"
264
+ | P_lit _ -> " P_lit"
265
+ | P_or _ -> " P_or"
266
+ | P_not _ -> " P_not"
267
+ | P_as _ -> " P_as"
268
+ | P_typ _ -> " P_typ"
269
+ | P_id _ -> " P_id"
270
+ | P_var _ -> " P_var"
271
+ | P_vector _ -> " P_vector"
272
+ | P_vector_concat _ -> " P_vector_concat"
273
+ | P_vector_subrange _ -> " P_vector_subrange"
274
+ | P_tuple _ -> " P_tuple"
275
+ | P_list _ -> " P_list"
276
+ | P_cons _ -> " P_cons"
277
+ | P_string_append _ -> " P_string_append"
278
+ | P_struct _ -> " P_struct"
279
+
280
+ let rec doc_pat ctxt apat_needed (P_aux (p , (l , annot )) as pat ) =
281
+ let env = env_of_annot (l, annot) in
282
+ let typ = Env. expand_synonyms env (typ_of_annot (l, annot)) in
283
+ match p with
284
+ | P_typ (ptyp , p ) ->
285
+ let doc_p = doc_pat ctxt true p in
286
+ doc_p
287
+ | P_id id -> doc_id_ctor id
288
+ | _ -> failwith (" Pattern " ^ string_of_pat_con pat ^ " " ^ string_of_pat pat ^ " not translatable yet." )
289
+
290
+ (* Copied from the Coq PP *)
291
+ let rebind_cast_pattern_vars pat typ exp =
292
+ let rec aux pat typ =
293
+ match (pat, typ) with
294
+ | P_aux (P_typ (target_typ , P_aux (P_id id , (l , ann ))), _ ), source_typ when not (is_enum (env_of exp) id) ->
295
+ if Typ. compare target_typ source_typ == 0 then []
296
+ else (
297
+ let l = Parse_ast. Generated l in
298
+ let cast_annot = Type_check. replace_typ source_typ ann in
299
+ let e_annot = Type_check. mk_tannot (env_of exp) source_typ in
300
+ [LB_aux (LB_val (pat, E_aux (E_id id, (l, e_annot))), (l, ann))]
301
+ )
302
+ | P_aux (P_tuple pats , _ ), Typ_aux (Typ_tuple typs , _ ) -> List. concat (List. map2 aux pats typs)
303
+ | _ -> []
304
+ in
305
+ let add_lb (E_aux (_ , ann ) as exp ) lb = E_aux (E_let (lb, exp), ann) in
306
+ (* Don't introduce new bindings at the top-level, we'd just go into a loop. *)
307
+ let lbs =
308
+ match (pat, typ) with
309
+ | P_aux (P_tuple pats , _ ), Typ_aux (Typ_tuple typs , _ ) -> List. concat (List. map2 aux pats typs)
310
+ | _ -> []
311
+ in
312
+ List. fold_left add_lb exp lbs
313
+
260
314
let rec doc_exp ctxt (E_aux (e , (l , annot )) as full_exp ) =
261
315
let env = env_of_tannot annot in
262
316
match e with
263
317
| E_id id -> string (string_of_id id) (* TODO replace by a translating via a binding map *)
264
318
| E_lit l -> doc_lit l
265
319
| E_app (Id_aux (Id "internal_pick" , _ ), _ ) ->
266
320
string " sorry" (* TODO replace by actual implementation of internal_pick *)
267
- | E_internal_plet _ -> string " sorry" (* TODO replace by actual implementation of internal_plet *)
321
+ | E_internal_plet (pat , e1 , e2 ) ->
322
+ (* doc_exp ctxt e1 ^^ hardline ^^ doc_exp ctxt e2 *)
323
+ let e0 = doc_pat ctxt false pat in
324
+ let e1_pp = doc_exp ctxt e1 in
325
+ let e2' = rebind_cast_pattern_vars pat (typ_of e1) e2 in
326
+ let e2_pp = doc_exp ctxt e2' in
327
+ (* infix 0 1 middle e1_pp e2_pp *)
328
+ let e0_pp =
329
+ begin
330
+ match pat with
331
+ | P_aux (P_typ (_ , P_aux (P_wild, _ )), _ ) -> string " "
332
+ | _ -> separate space [string " let" ; e0; string " :=" ] ^^ space
333
+ end
334
+ in
335
+ e0_pp ^^ e1_pp ^^ hardline ^^ e2_pp
268
336
| E_app (f , args ) ->
269
337
let d_id =
270
338
if Env. is_extern f env " lean" then string (Env. get_extern f env " lean" )
@@ -273,7 +341,13 @@ let rec doc_exp ctxt (E_aux (e, (l, annot)) as full_exp) =
273
341
let d_args = List. map (doc_exp ctxt) args in
274
342
nest 2 (parens (flow (break 1 ) (d_id :: d_args)))
275
343
| E_vector vals -> failwith " vector found"
276
- | E_typ (typ , e ) -> parens (separate space [doc_exp ctxt e; colon; doc_typ ctxt typ])
344
+ | E_typ (typ , e ) -> (
345
+ match e with
346
+ | E_aux (E_assign _ , _ ) -> doc_exp ctxt e
347
+ | E_aux (E_app (Id_aux (Id "internal_pick" , _ ), _ ), _ ) ->
348
+ string " return " ^^ nest 7 (parens (separate space [doc_exp ctxt e; colon; doc_typ ctxt typ]))
349
+ | _ -> parens (separate space [doc_exp ctxt e; colon; doc_typ ctxt typ])
350
+ )
277
351
| E_tuple es -> parens (separate_map (comma ^^ space) (doc_exp ctxt) es)
278
352
| E_let (LB_aux (LB_val (lpat , lexp ), _ ), e ) ->
279
353
let id =
@@ -290,6 +364,13 @@ let rec doc_exp ctxt (E_aux (e, (l, annot)) as full_exp) =
290
364
| E_struct_update (exp , fexps ) ->
291
365
let args = List. map (doc_fexp ctxt) fexps in
292
366
braces (space ^^ doc_exp ctxt exp ^^ string " with " ^^ separate (comma ^^ space) args ^^ space)
367
+ | E_assign ((LE_aux (le_act , tannot ) as le ), e ) -> (
368
+ match le_act with
369
+ | LE_id id | LE_typ (_ , id ) -> string " set_" ^^ doc_id_ctor id ^^ space ^^ doc_exp ctxt e
370
+ | LE_deref e -> string " sorry /- deref -/"
371
+ | _ -> failwith (" assign " ^ string_of_lexp le ^ " not implemented yet" )
372
+ )
373
+ | E_internal_return e -> nest 2 (string " return" ^^ space ^^ nest 5 (doc_exp ctxt e))
293
374
| _ -> failwith (" Expression " ^ string_of_exp_con full_exp ^ " " ^ string_of_exp full_exp ^ " not translatable yet." )
294
375
295
376
and doc_fexp ctxt (FE_aux (FE_fexp (field , exp ), _ )) = doc_id_ctor field ^^ string " := " ^^ doc_exp ctxt exp
@@ -353,8 +434,7 @@ let doc_funcl_init (FCL_aux (FCL_funcl (id, pexp), annot)) =
353
434
354
435
let doc_funcl_body (FCL_aux (FCL_funcl (id , pexp ), annot )) =
355
436
let _, _, exp, _ = destruct_pexp pexp in
356
- let is_monadic = effectful (effect_of exp) in
357
- if is_monadic then nest 2 (flow (break 1 ) [string " return" ; doc_exp empty_context exp]) else doc_exp empty_context exp
437
+ doc_exp empty_context exp
358
438
359
439
let doc_funcl funcl =
360
440
let comment, signature = doc_funcl_init funcl in
@@ -415,6 +495,10 @@ let rec remove_imports (defs : (Libsail.Type_check.tannot, Libsail.Type_check.en
415
495
416
496
let pp_ast_lean ({ defs; _ } as ast : Libsail.Type_check.typed_ast ) o =
417
497
let defs = remove_imports defs 0 in
498
+ let regs = State. find_registers defs in
499
+ let register_refs =
500
+ match regs with [] -> empty | _ -> State. register_refs_lean doc_id_ctor (doc_typ empty_context) regs ^^ hardline
501
+ in
418
502
let output : document = separate_map empty (doc_def empty_context) defs in
419
- print o output;
503
+ print o (register_refs ^^ output) ;
420
504
()
0 commit comments