@@ -407,15 +407,36 @@ let main () =
407407 (* Initialize I/O + interaction module *)
408408 let module State = struct
409409 type t = {
410- prvopts : prv_options ;
411- input : string option ;
412- terminal : T .terminal lazy_t ;
413- interactive : bool ;
414- eco : bool ;
415- gccompact : int option ;
416- docgen : bool ;
417- outdirp : string option ;
410+ (* ---*) prvopts : prv_options ;
411+ (* ---*) input : string option ;
412+ (* ---*) terminal : T .terminal lazy_t ;
413+ (* ---*) interactive : bool ;
414+ (* ---*) eco : bool ;
415+ (* ---*) gccompact : int option ;
416+ (* ---*) docgen : bool ;
417+ (* ---*) outdirp : string option ;
418+ mutable trace : trace1 list option ;
418419 }
420+
421+ and trace1 =
422+ { position : int
423+ ; goal : string option
424+ ; messages : (EcGState .loglevel * string ) list }
425+
426+ module Trace = struct
427+ let trace0 : trace1 =
428+ { position = 0 ; goal = None ; messages = [] ; }
429+
430+ let push1_message (trace1 : trace1 ) (msg , lvl ) : trace1 =
431+ { trace1 with messages = (msg, lvl) :: trace1.messages }
432+
433+ let push_message (trace : trace1 list ) msg =
434+ match trace with
435+ | [] ->
436+ [push1_message trace0 msg]
437+ | trace1 :: trace ->
438+ push1_message trace1 msg :: trace
439+ end
419440 end in
420441
421442 let state : State.t =
@@ -471,7 +492,8 @@ let main () =
471492 ; eco = false
472493 ; gccompact = None
473494 ; docgen = false
474- ; outdirp = None }
495+ ; outdirp = None
496+ ; trace = None }
475497
476498 end
477499
@@ -493,14 +515,17 @@ let main () =
493515 lazy (T. from_channel ~name ~gcstats ~progress (open_in name))
494516 in
495517
518+ let trace0 = State. { position = 0 ; goal = None ; messages = [] } in
519+
496520 { prvopts = {cmpopts.cmpo_provers with prvo_iterate = true }
497521 ; input = Some name
498522 ; terminal = terminal
499523 ; interactive = false
500524 ; eco = cmpopts.cmpo_noeco
501525 ; gccompact = cmpopts.cmpo_compact
502526 ; docgen = false
503- ; outdirp = None }
527+ ; outdirp = None
528+ ; trace = Some [trace0] }
504529
505530 end
506531
@@ -543,7 +568,8 @@ let main () =
543568 ; eco = true
544569 ; gccompact = None
545570 ; docgen = true
546- ; outdirp = docopts.doco_outdirp }
571+ ; outdirp = docopts.doco_outdirp
572+ ; trace = None }
547573 end
548574
549575 in
@@ -571,7 +597,20 @@ let main () =
571597
572598 assert (nameo <> input);
573599
574- let eco = EcEco. {
600+ let eco =
601+ let mktrace (trace : State.trace1 list ) : EcEco.ecotrace =
602+ let mktrace1 (trace1 : State.trace1 ) : int * EcEco.ecotrace1 =
603+ let goal = Option. value ~default: " " trace1.goal in
604+ let messages =
605+ let for1 (lvl , msg ) =
606+ Format. sprintf " %s: %s"
607+ (EcGState. string_of_loglevel lvl)
608+ msg in
609+ String. concat " \n " (List. rev_map for1 trace1.messages) in
610+ (trace1.position, EcEco. { goal; messages; })
611+ in List. rev_map mktrace1 trace in
612+
613+ EcEco. {
575614 eco_root = EcEco. {
576615 eco_digest = Digest. file input;
577616 eco_kind = kind;
@@ -584,6 +623,7 @@ let main () =
584623 eco_kind = x.rqd_kind;
585624 } in (x.rqd_name, (ecr, x.rqd_direct)))
586625 (EcScope.Theory. required scope));
626+ eco_trace = Option. map mktrace state.trace;
587627 } in
588628
589629 let out = open_out nameo in
@@ -665,7 +705,10 @@ let main () =
665705 EcScope. hierror " invalid pragma: `%s'\n %!" x);
666706
667707 let notifier (lvl : EcGState.loglevel ) (lazy msg ) =
668- T. notice ~immediate: true lvl msg terminal
708+ state.trace < - state.trace |> Option. map (fun trace ->
709+ State.Trace. push_message trace (lvl, msg)
710+ );
711+ T. notice ~immediate: true lvl msg terminal;
669712 in
670713
671714 EcCommands. addnotifier notifier;
@@ -694,8 +737,30 @@ let main () =
694737 let timed = p.EP. gl_debug = Some `Timed in
695738 let break = p.EP. gl_debug = Some `Break in
696739 let ignore_fail = ref false in
740+
741+ state.trace < - state.trace |> Option. map (fun trace ->
742+ { State.Trace. trace0 with position = loc.loc_echar } :: trace
743+ );
744+
697745 try
698746 let tdelta = EcCommands. process ~src ~timed ~break p.EP. gl_action in
747+
748+ state.trace < - state.trace |> Option. map (fun trace ->
749+ match trace with
750+ | [] -> assert false
751+ | trace1 :: trace ->
752+ assert (Option. is_none trace1.State. goal);
753+ let goal =
754+ let buffer = Buffer. create 0 in
755+ Format. fprintf
756+ (Format. formatter_of_buffer buffer)
757+ " %t@?" (EcCommands. pp_current_goal ~all: false );
758+ Buffer. contents buffer in
759+ let goal = if String. is_empty goal then None else Some goal in
760+ let trace1 = { trace1 with goal } in
761+ trace1 :: trace
762+ );
763+
699764 if p.EP. gl_fail then begin
700765 ignore_fail := true ;
701766 raise (EcScope. HiScopeError (None , " this command is expected to fail" ))
@@ -713,10 +778,10 @@ let main () =
713778 raise (EcScope. toperror_of_exn ~gloc: loc e)
714779 end ;
715780 if T. interactive terminal then begin
716- let error =
717- Format. asprintf
718- " The following error has been ignored:@.@.@%a"
719- EcPException. exn_printer e in
781+ let error =
782+ Format. asprintf
783+ " The following error has been ignored:@.@.@%a"
784+ EcPException. exn_printer e in
720785 T. notice ~immediate: true `Info error terminal
721786 end
722787 end )
0 commit comments