@@ -378,7 +378,18 @@ let main () =
378378 begin let open EcUserMessages in register () end ;
379379
380380 (* Initialize I/O + interaction module *)
381- let (prvopts, input, terminal, interactive, eco) =
381+ let module State = struct
382+ type t = {
383+ prvopts : prv_options ;
384+ input : string option ;
385+ terminal : T .terminal lazy_t ;
386+ interactive : bool ;
387+ eco : bool ;
388+ gccompact : int option ;
389+ }
390+ end in
391+
392+ let state : State.t =
382393 match options.o_command with
383394 | `Config ->
384395 let config = {
@@ -422,7 +433,15 @@ let main () =
422433 then lazy (T. from_emacs () )
423434 else lazy (T. from_tty () )
424435
425- in (cliopts.clio_provers, None , terminal, true , false )
436+ in
437+
438+ { prvopts = cliopts.clio_provers
439+ ; input = None
440+ ; terminal = terminal
441+ ; interactive = true
442+ ; eco = false
443+ ; gccompact = None }
444+
426445 end
427446
428447 | `Compile cmpopts -> begin
@@ -442,8 +461,13 @@ let main () =
442461 let terminal =
443462 lazy (T. from_channel ~name ~gcstats ~progress (open_in name))
444463 in
445- ({cmpopts.cmpo_provers with prvo_iterate = true },
446- Some name, terminal, false , cmpopts.cmpo_noeco)
464+
465+ { prvopts = {cmpopts.cmpo_provers with prvo_iterate = true }
466+ ; input = Some name
467+ ; terminal = terminal
468+ ; interactive = false
469+ ; eco = cmpopts.cmpo_noeco
470+ ; gccompact = cmpopts.cmpo_compact }
447471
448472 end
449473
@@ -452,7 +476,7 @@ let main () =
452476 assert false
453477 in
454478
455- (match input with
479+ (match state. input with
456480 | Some input -> EcCommands. addidir (Filename. dirname input)
457481 | None ->
458482 match relocdir with
@@ -462,7 +486,7 @@ let main () =
462486 (* Check if the .eco is up-to-date and exit if so *)
463487 oiter
464488 (fun input -> if EcCommands. check_eco input then exit 0 )
465- input;
489+ state. input;
466490
467491 let finalize_input input scope =
468492 match input with
@@ -512,13 +536,13 @@ let main () =
512536 | _ -> fun _ _ -> () in
513537
514538 (* Instantiate terminal *)
515- let lazy terminal = terminal in
539+ let lazy terminal = state. terminal in
516540
517541 (* Initialize PRNG *)
518542 Random. self_init () ;
519543
520544 (* Connect to external Why3 server if requested *)
521- prvopts.prvo_why3server |> oiter (fun server ->
545+ state. prvopts.prvo_why3server |> oiter (fun server ->
522546 try
523547 Why3.Prove_client. connect_external server
524548 with Why3.Prove_client. ConnectionError e ->
@@ -534,6 +558,7 @@ let main () =
534558
535559 (* Interaction loop *)
536560 let first = ref `Init in
561+ let cmdcounter = ref 0 in
537562
538563 while true do
539564 let terminate = ref false in
@@ -545,19 +570,19 @@ let main () =
545570
546571 (* Initialize global scope *)
547572 let checkmode = {
548- EcCommands. cm_checkall = prvopts.prvo_checkall;
549- EcCommands. cm_timeout = odfl 3 (prvopts.prvo_timeout);
550- EcCommands. cm_cpufactor = odfl 1 (prvopts.prvo_cpufactor);
551- EcCommands. cm_nprovers = odfl 4 (prvopts.prvo_maxjobs);
552- EcCommands. cm_provers = prvopts.prvo_provers;
553- EcCommands. cm_profile = prvopts.prvo_profile;
554- EcCommands. cm_iterate = prvopts.prvo_iterate;
573+ EcCommands. cm_checkall = state. prvopts.prvo_checkall;
574+ EcCommands. cm_timeout = odfl 3 (state. prvopts.prvo_timeout);
575+ EcCommands. cm_cpufactor = odfl 1 (state. prvopts.prvo_cpufactor);
576+ EcCommands. cm_nprovers = odfl 4 (state. prvopts.prvo_maxjobs);
577+ EcCommands. cm_provers = state. prvopts.prvo_provers;
578+ EcCommands. cm_profile = state. prvopts.prvo_profile;
579+ EcCommands. cm_iterate = state. prvopts.prvo_iterate;
555580 } in
556581
557582 EcCommands. initialize ~restart
558- ~undo: interactive ~boot: ldropts.ldro_boot ~checkmode ;
583+ ~undo: state. interactive ~boot: ldropts.ldro_boot ~checkmode ;
559584 (try
560- List. iter EcCommands. apply_pragma prvopts.prvo_pragmas
585+ List. iter EcCommands. apply_pragma state. prvopts.prvo_pragmas
561586 with EcCommands. InvalidPragma x ->
562587 EcScope. hierror " invalid pragma: `%s'\n %!" x);
563588
@@ -569,7 +594,7 @@ let main () =
569594 oiter (fun ppwidth ->
570595 let gs = EcEnv. gstate (EcScope. env (EcCommands. current () )) in
571596 EcGState. setvalue " PP:width" (`Int ppwidth) gs)
572- prvopts.prvo_ppwidth;
597+ state. prvopts.prvo_ppwidth;
573598 first := `Loop
574599
575600 | `Loop -> ()
@@ -624,10 +649,19 @@ let main () =
624649 terminate := true
625650 end ;
626651 T. finish `ST_Ok terminal;
652+
653+ state.gccompact |> Option. iter (fun i ->
654+ incr cmdcounter;
655+ if i = ! cmdcounter then begin
656+ cmdcounter := 0 ;
657+ Gc. compact ()
658+ end
659+ );
660+
627661 if ! terminate then begin
628662 T. finalize terminal;
629- if not eco then
630- finalize_input input (EcCommands. current () );
663+ if not state. eco then
664+ finalize_input state. input (EcCommands. current () );
631665 exit 0
632666 end ;
633667 with
0 commit comments