Skip to content

Commit ce27f52

Browse files
committed
Refactor Initial_check to remove some state
Previously we would had a variable incremental_ctx that we would be update for each parsed file. This is one of the last pieces of global state in the Sail frontend that needed to be removed. Turns out that doing this is a bit tricky because the prover_regstate is a bit special, so we need to thread the Initial_check context through the rewrites all the way to the backends. The targets were getting an unwieldy amount of arguments so now just use the Interactive.State.istate type which is a struct containing everything we need.
1 parent 9332898 commit ce27f52

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+456
-287
lines changed

src/bin/repl.ml

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -81,10 +81,11 @@ type mode = Evaluation of frame | Normal
8181
type display_options = { clear : bool; registers : IdSet.t }
8282

8383
type istate = {
84+
ctx : Initial_check.ctx;
8485
ast : Type_check.typed_ast;
8586
effect_info : Effects.side_effect_info;
8687
env : Type_check.Env.t;
87-
ref_state : Interactive.istate ref;
88+
ref_state : Interactive.State.istate ref;
8889
vs_ids : IdSet.t ref;
8990
options : (Arg.key * Arg.spec * Arg.doc) list;
9091
mode : mode;
@@ -94,21 +95,23 @@ type istate = {
9495
config : Yojson.Basic.t option;
9596
}
9697

97-
let shrink_istate istate : Interactive.istate =
98+
let shrink_istate istate : Interactive.State.istate =
9899
{
100+
ctx = istate.ctx;
99101
ast = istate.ast;
100102
effect_info = istate.effect_info;
101103
env = istate.env;
102104
default_sail_dir = istate.default_sail_dir;
103105
config = istate.config;
104106
}
105107

106-
let initial_istate config options env effect_info ast =
108+
let initial_istate config options ctx env effect_info ast =
107109
{
110+
ctx;
108111
ast;
109112
effect_info;
110113
env;
111-
ref_state = ref (Interactive.initial_istate config Locations.sail_dir);
114+
ref_state = ref (Interactive.State.initial_istate config Locations.sail_dir);
112115
vs_ids = ref (val_spec_ids ast.defs);
113116
options;
114117
mode = Normal;
@@ -121,6 +124,7 @@ let initial_istate config options env effect_info ast =
121124
let setup_interpreter_state istate =
122125
istate.ref_state :=
123126
{
127+
ctx = istate.ctx;
124128
ast = istate.ast;
125129
effect_info = istate.effect_info;
126130
env = istate.env;
@@ -632,19 +636,19 @@ let handle_input' istate input =
632636
| ":def" ->
633637
(* Add an extra blank line so we can handle directives that require a newline to be parsed. *)
634638
ignore (Sail_file.add_to_repl_contents ~command:"");
635-
let ast =
636-
Initial_check.ast_of_def_string_with ~inline:pos __POS__
639+
let ast, ctx =
640+
Initial_check.ast_of_def_string_with ~inline:pos __POS__ istate.ctx
637641
(Preprocess.preprocess istate.default_sail_dir None istate.options)
638642
(arg ^ "\n")
639643
in
640644
let ast, env = Type_check.check istate.env ast in
641-
{ istate with ast = append_ast istate.ast ast; env }
645+
{ istate with ast = append_ast istate.ast ast; env; ctx }
642646
| ":rewrite" ->
643647
let open Rewrites in
644648
let args = Str.split (Str.regexp " +") arg in
645649
let rec parse_args rw args =
646650
match (rw, args) with
647-
| Base_rewriter rw, [] -> rw
651+
| Full_rewriter rw, [] -> rw
648652
| Bool_rewriter rw, arg :: args -> parse_args (rw (bool_of_string arg)) args
649653
| String_rewriter rw, arg :: args -> parse_args (rw arg) args
650654
| Literal_rewriter rw, arg :: args -> begin
@@ -661,8 +665,8 @@ let handle_input' istate input =
661665
| rw :: args ->
662666
let rw = List.assoc rw Rewrites.all_rewriters in
663667
let rw = parse_args rw args in
664-
let ast', effect_info', env' = rw istate.effect_info istate.env istate.ast in
665-
{ istate with ast = ast'; effect_info = effect_info'; env = env' }
668+
let ctx', ast', effect_info', env' = rw istate.ctx istate.effect_info istate.env istate.ast in
669+
{ istate with ctx = ctx'; ast = ast'; effect_info = effect_info'; env = env' }
666670
| [] ->
667671
failwith "Must provide the name of a rewrite, use :list_rewrites for a list of possible rewrites"
668672
end
@@ -764,16 +768,16 @@ let handle_input istate input =
764768
print_endline (Printexc.to_string exn);
765769
istate
766770

767-
let start_repl ?(banner = true) ?commands:(script = []) ?auto_rewrites:(rewrites = true) ~config ~options env
771+
let start_repl ?(banner = true) ?commands:(script = []) ?auto_rewrites:(rewrites = true) ~config ~options ctx env
768772
effect_info ast =
769773
let istate =
770774
if rewrites then (
771-
let ast, effect_info, env =
772-
Rewrites.rewrite effect_info env (Rewrites.instantiate_rewrites Rewrites.rewrites_interpreter) ast
775+
let ctx, ast, effect_info, env =
776+
Rewrites.rewrite ctx effect_info env (Rewrites.instantiate_rewrites Rewrites.rewrites_interpreter) ast
773777
in
774-
initial_istate config options env effect_info ast
778+
initial_istate config options ctx env effect_info ast
775779
)
776-
else initial_istate config options env effect_info ast
780+
else initial_istate config options ctx env effect_info ast
777781
in
778782

779783
LNoise.set_completion_callback (fun line_so_far ln_completions ->

src/bin/repl.mli

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ val start_repl :
8585
?auto_rewrites:bool ->
8686
config:Yojson.Basic.t option ->
8787
options:(Arg.key * Arg.spec * Arg.doc) list ->
88+
Initial_check.ctx ->
8889
Env.t ->
8990
Effects.side_effect_info ->
9091
typed_ast ->

src/bin/sail.ml

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,8 @@
6767

6868
open Libsail
6969

70+
open Interactive.State
71+
7072
type version = { major : int; minor : int; patch : int }
7173

7274
(* Current version of Sail. Must be updated manually. CI checks this matches
@@ -415,7 +417,7 @@ let run_sail (config : Yojson.Basic.t option) tgt =
415417
List.partition (fun free -> Filename.check_suffix free ".sail_project") !opt_free_arguments
416418
in
417419

418-
let ast, env, effect_info =
420+
let ctx, ast, env, effect_info =
419421
match (project_files, !opt_project_files) with
420422
| [], [] ->
421423
(* If there are no provided project files, we concatenate all
@@ -467,19 +469,19 @@ let run_sail (config : Yojson.Basic.t option) tgt =
467469
)
468470
in
469471
let ast, env = Frontend.initial_rewrite effect_info env ast in
470-
let ast, env = match !opt_splice with [] -> (ast, env) | files -> Splice.splice_files ast (List.rev files) in
472+
let ast, env = match !opt_splice with [] -> (ast, env) | files -> Splice.splice_files ctx ast (List.rev files) in
471473
let effect_info = Effects.infer_side_effects (Target.asserts_termination tgt) ast in
472474

473475
(* Don't show warnings during re-writing for now *)
474476
Reporting.suppressed_warning_info ();
475477
Reporting.opt_warnings := false;
476478

477479
Target.run_pre_rewrites_hook tgt ast effect_info env;
478-
let ast, effect_info, env = Rewrites.rewrite effect_info env (Target.rewrites tgt) ast in
480+
let ctx, ast, effect_info, env = Rewrites.rewrite ctx effect_info env (Target.rewrites tgt) ast in
479481

480-
Target.action tgt config Locations.sail_dir !opt_file_out ast effect_info env;
482+
Target.action tgt !opt_file_out { ctx; ast; effect_info; env; default_sail_dir = Locations.sail_dir; config };
481483

482-
(ast, env, effect_info)
484+
(ctx, ast, env, effect_info)
483485

484486
let run_sail_format (config : Yojson.Basic.t option) =
485487
let is_format_file f = match !opt_format_only with [] -> true | files -> List.exists (fun f' -> f = f') files in
@@ -616,7 +618,7 @@ let main () =
616618

617619
if !opt_memo_z3 then Constraint.load_digests ();
618620

619-
let ast, env, effect_info =
621+
let ctx, ast, env, effect_info =
620622
match Target.get_the_target () with
621623
| Some target when not !opt_just_check -> run_sail config target
622624
| _ -> run_sail config default_target
@@ -640,7 +642,7 @@ let main () =
640642
with End_of_file -> List.rev !lines
641643
)
642644
in
643-
Repl.start_repl ~commands:script ~auto_rewrites:!opt_auto_interpreter_rewrites ~config ~options:!options env
645+
Repl.start_repl ~commands:script ~auto_rewrites:!opt_auto_interpreter_rewrites ~config ~options:!options ctx env
644646
effect_info ast
645647
)
646648

src/lib/ast_util.ml

Lines changed: 39 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,8 @@ let attribute_data_bool = function AD_aux (AD_bool b, _) -> Some b | _ -> None
108108

109109
let attribute_data_string = function AD_aux (AD_string s, _) -> Some s | _ -> None
110110

111+
let attribute_data_string_with_loc = function AD_aux (AD_string s, l) -> Some (s, l) | _ -> None
112+
111113
let json_of_attribute attr = function
112114
| None -> `String attr
113115
| Some data -> `List [`String attr; json_of_attribute_data data]
@@ -204,9 +206,9 @@ let rec is_gen_loc = function
204206

205207
let mk_id ?loc:(l = Parse_ast.Unknown) str = Id_aux (Id str, l)
206208

207-
let mk_nc nc_aux = NC_aux (nc_aux, Parse_ast.Unknown)
209+
let mk_nc ?loc:(l = Parse_ast.Unknown) nc_aux = NC_aux (nc_aux, l)
208210

209-
let mk_nexp nexp_aux = Nexp_aux (nexp_aux, Parse_ast.Unknown)
211+
let mk_nexp ?loc:(l = Parse_ast.Unknown) nexp_aux = Nexp_aux (nexp_aux, l)
210212

211213
let mk_exp ?loc:(l = Parse_ast.Unknown) exp_aux = E_aux (exp_aux, (l, empty_uannot))
212214
let unaux_exp (E_aux (exp_aux, _)) = exp_aux
@@ -221,36 +223,36 @@ let untyp_pat = function P_aux (P_typ (typ, pat), _) -> (pat, Some typ) | pat ->
221223

222224
let mk_pexp ?loc:(l = Parse_ast.Unknown) pexp_aux = Pat_aux (pexp_aux, (l, empty_uannot))
223225

224-
let mk_mpat mpat_aux = MP_aux (mpat_aux, no_annot)
225-
let mk_mpexp mpexp_aux = MPat_aux (mpexp_aux, no_annot)
226+
let mk_mpat ?loc:(l = Parse_ast.Unknown) mpat_aux = MP_aux (mpat_aux, (l, empty_uannot))
227+
let mk_mpexp ?loc:(l = Parse_ast.Unknown) mpexp_aux = MPat_aux (mpexp_aux, (l, empty_uannot))
226228

227-
let mk_lexp lexp_aux = LE_aux (lexp_aux, no_annot)
229+
let mk_lexp ?loc:(l = Parse_ast.Unknown) lexp_aux = LE_aux (lexp_aux, (l, empty_uannot))
228230

229-
let mk_typ_pat tpat_aux = TP_aux (tpat_aux, Parse_ast.Unknown)
231+
let mk_typ_pat ?loc:(l = Parse_ast.Unknown) tpat_aux = TP_aux (tpat_aux, l)
230232

231-
let mk_lit lit_aux = L_aux (lit_aux, Parse_ast.Unknown)
233+
let mk_lit ?loc:(l = Parse_ast.Unknown) lit_aux = L_aux (lit_aux, Parse_ast.Unknown)
232234

233-
let mk_lit_exp ?loc:(l = Parse_ast.Unknown) lit_aux = mk_exp ~loc:l (E_lit (mk_lit lit_aux))
235+
let mk_lit_exp ?loc:(l = Parse_ast.Unknown) lit_aux = mk_exp ~loc:l (E_lit (mk_lit ~loc:l lit_aux))
234236

235237
let mk_funcl ?loc:(l = Parse_ast.Unknown) id pat body =
236238
FCL_aux (FCL_funcl (id, Pat_aux (Pat_exp (pat, body), (l, empty_uannot))), (mk_def_annot l (), empty_uannot))
237239

238-
let mk_qi_nc nc = QI_aux (QI_constraint nc, Parse_ast.Unknown)
240+
let mk_qi_nc ?loc:(l = Parse_ast.Unknown) nc = QI_aux (QI_constraint nc, l)
239241

240-
let mk_qi_id k kid =
241-
let kopt = KOpt_aux (KOpt_kind (K_aux (k, Parse_ast.Unknown), kid), Parse_ast.Unknown) in
242-
QI_aux (QI_id kopt, Parse_ast.Unknown)
242+
let mk_qi_id ?loc:(l = Parse_ast.Unknown) k kid =
243+
let kopt = KOpt_aux (KOpt_kind (K_aux (k, l), kid), l) in
244+
QI_aux (QI_id kopt, l)
243245

244-
let mk_qi_kopt kopt = QI_aux (QI_id kopt, Parse_ast.Unknown)
246+
let mk_qi_kopt ?loc:(l = Parse_ast.Unknown) kopt = QI_aux (QI_id kopt, l)
245247

246-
let mk_fundef funcls =
247-
let tannot_opt = Typ_annot_opt_aux (Typ_annot_opt_none, Parse_ast.Unknown) in
248-
let rec_opt = Rec_aux (Rec_nonrec, Parse_ast.Unknown) in
249-
DEF_aux (DEF_fundef (FD_aux (FD_function (rec_opt, tannot_opt, funcls), no_annot)), mk_def_annot Parse_ast.Unknown ())
248+
let mk_fundef ?loc:(l = Parse_ast.Unknown) funcls =
249+
let tannot_opt = Typ_annot_opt_aux (Typ_annot_opt_none, l) in
250+
let rec_opt = Rec_aux (Rec_nonrec, l) in
251+
DEF_aux (DEF_fundef (FD_aux (FD_function (rec_opt, tannot_opt, funcls), no_annot)), mk_def_annot l ())
250252

251253
let mk_letbind ?loc:(l = Parse_ast.Unknown) pat exp = LB_aux (LB_val (pat, exp), (l, empty_uannot))
252254

253-
let mk_val_spec vs_aux = DEF_aux (DEF_val (VS_aux (vs_aux, no_annot)), mk_def_annot Parse_ast.Unknown ())
255+
let mk_val_spec ?loc:(l = Parse_ast.Unknown) vs_aux = DEF_aux (DEF_val (VS_aux (vs_aux, no_annot)), mk_def_annot l ())
254256

255257
let mk_def ?loc:(l = Parse_ast.Unknown) def env = DEF_aux (def, mk_def_annot l env)
256258

@@ -642,11 +644,11 @@ let rec constraint_conj (NC_aux (nc_aux, _) as nc) =
642644
let rec constraint_disj (NC_aux (nc_aux, _) as nc) =
643645
match nc_aux with NC_or (nc1, nc2) -> constraint_disj nc1 @ constraint_disj nc2 | _ -> [nc]
644646

645-
let mk_typ typ = Typ_aux (typ, Parse_ast.Unknown)
646-
let mk_typ_arg arg = A_aux (arg, Parse_ast.Unknown)
647-
let mk_kid str = Kid_aux (Var ("'" ^ str), Parse_ast.Unknown)
647+
let mk_typ ?loc:(l = Parse_ast.Unknown) typ = Typ_aux (typ, l)
648+
let mk_typ_arg ?loc:(l = Parse_ast.Unknown) arg = A_aux (arg, l)
649+
let mk_kid ?loc:(l = Parse_ast.Unknown) str = Kid_aux (Var ("'" ^ str), l)
648650

649-
let mk_id_typ id = Typ_aux (Typ_id id, Parse_ast.Unknown)
651+
let mk_id_typ ?loc:(l = Parse_ast.Unknown) id = Typ_aux (Typ_id id, l)
650652

651653
let mk_kopt ?loc:(l = Parse_ast.Unknown) kind_aux v =
652654
let l = match l with Parse_ast.Unknown -> kid_loc v | l -> l in
@@ -723,12 +725,12 @@ let arg_kopt (KOpt_aux (KOpt_kind (K_aux (k, _), v), _)) =
723725

724726
let nc_not nc = mk_nc (NC_app (mk_id "not", [arg_bool nc]))
725727

726-
let mk_typschm typq typ = TypSchm_aux (TypSchm_ts (typq, typ), Parse_ast.Unknown)
728+
let mk_typschm ?loc:(l = Parse_ast.Unknown) typq typ = TypSchm_aux (TypSchm_ts (typq, typ), l)
727729

728730
let mk_empty_typquant ~loc:l = TypQ_aux (TypQ_no_forall, l)
729-
let mk_typquant qis = TypQ_aux (TypQ_tq qis, Parse_ast.Unknown)
731+
let mk_typquant ?loc:(l = Parse_ast.Unknown) qis = TypQ_aux (TypQ_tq qis, l)
730732

731-
let mk_fexp id exp = FE_aux (FE_fexp (id, exp), no_annot)
733+
let mk_fexp ?loc:(l = Parse_ast.Unknown) id exp = FE_aux (FE_fexp (id, exp), (l, empty_uannot))
732734

733735
type effect = bool
734736

@@ -1980,6 +1982,18 @@ and locate_lexp : 'a. (l -> l) -> 'a lexp -> 'a lexp =
19801982
and locate_fexp : 'a. (l -> l) -> 'a fexp -> 'a fexp =
19811983
fun f (FE_aux (FE_fexp (id, exp), (l, annot))) -> FE_aux (FE_fexp (locate_id f id, locate f exp), (f l, annot))
19821984

1985+
let unknown_to into_l l =
1986+
let open Parse_ast in
1987+
let rec go l =
1988+
match l with
1989+
| Unknown -> into_l
1990+
| Hint (msg, l1, l2) -> Hint (msg, go l1, go l2)
1991+
| Generated l -> Generated (go l)
1992+
| Unique (n, l) -> Unique (n, go l)
1993+
| Range _ -> l
1994+
in
1995+
go l
1996+
19831997
let unique_ref = ref 0
19841998

19851999
let unique l =

src/lib/ast_util.mli

Lines changed: 27 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,8 @@ val attribute_data_bool : attribute_data -> bool option
102102

103103
val attribute_data_string : attribute_data -> string option
104104

105+
val attribute_data_string_with_loc : attribute_data -> (string * Parse_ast.l) option
106+
105107
(** Add an attribute to an annotation. Attributes are attached to expressions in Sail via:
106108
{@sail[
107109
$[attribute argument] expression
@@ -177,28 +179,28 @@ val is_order_dec : order -> bool
177179
(** {2 Functions for building untyped AST elements} *)
178180

179181
val mk_id : ?loc:l -> string -> id
180-
val mk_kid : string -> kid
181-
val mk_nc : n_constraint_aux -> n_constraint
182-
val mk_nexp : nexp_aux -> nexp
182+
val mk_kid : ?loc:l -> string -> kid
183+
val mk_nc : ?loc:l -> n_constraint_aux -> n_constraint
184+
val mk_nexp : ?loc:l -> nexp_aux -> nexp
183185
val mk_exp : ?loc:l -> uannot exp_aux -> uannot exp
184186
val mk_pat : ?loc:l -> uannot pat_aux -> uannot pat
185-
val mk_mpat : uannot mpat_aux -> uannot mpat
187+
val mk_mpat : ?loc:l -> uannot mpat_aux -> uannot mpat
186188
val mk_pexp : ?loc:l -> uannot pexp_aux -> uannot pexp
187-
val mk_mpexp : uannot mpexp_aux -> uannot mpexp
188-
val mk_lexp : uannot lexp_aux -> uannot lexp
189-
val mk_lit : lit_aux -> lit
189+
val mk_mpexp : ?loc:l -> uannot mpexp_aux -> uannot mpexp
190+
val mk_lexp : ?loc:l -> uannot lexp_aux -> uannot lexp
191+
val mk_lit : ?loc:l -> lit_aux -> lit
190192
val mk_lit_exp : ?loc:l -> lit_aux -> uannot exp
191-
val mk_typ_pat : typ_pat_aux -> typ_pat
193+
val mk_typ_pat : ?loc:l -> typ_pat_aux -> typ_pat
192194
val mk_funcl : ?loc:l -> id -> uannot pat -> uannot exp -> uannot funcl
193-
val mk_fundef : uannot funcl list -> untyped_def
194-
val mk_val_spec : val_spec_aux -> untyped_def
195-
val mk_typschm : typquant -> typ -> typschm
195+
val mk_fundef : ?loc:l -> uannot funcl list -> untyped_def
196+
val mk_val_spec : ?loc:l -> val_spec_aux -> untyped_def
197+
val mk_typschm : ?loc:l -> typquant -> typ -> typschm
196198
val mk_empty_typquant : loc:l -> typquant
197-
val mk_typquant : quant_item list -> typquant
198-
val mk_qi_id : kind_aux -> kid -> quant_item
199-
val mk_qi_nc : n_constraint -> quant_item
200-
val mk_qi_kopt : kinded_id -> quant_item
201-
val mk_fexp : id -> uannot exp -> uannot fexp
199+
val mk_typquant : ?loc:l -> quant_item list -> typquant
200+
val mk_qi_id : ?loc:l -> kind_aux -> kid -> quant_item
201+
val mk_qi_nc : ?loc:l -> n_constraint -> quant_item
202+
val mk_qi_kopt : ?loc:l -> kinded_id -> quant_item
203+
val mk_fexp : ?loc:l -> id -> uannot exp -> uannot fexp
202204
val mk_letbind : ?loc:l -> uannot pat -> uannot exp -> uannot letbind
203205
val mk_kopt : ?loc:l -> kind_aux -> kid -> kinded_id
204206
val mk_def : ?loc:l -> ('a, 'b) def_aux -> 'b -> ('a, 'b) def
@@ -235,9 +237,9 @@ val is_bool_kopt : kinded_id -> bool
235237

236238
(** {2 Utility functions for constructing types} *)
237239

238-
val mk_typ : typ_aux -> typ
239-
val mk_typ_arg : typ_arg_aux -> typ_arg
240-
val mk_id_typ : id -> typ
240+
val mk_typ : ?loc:l -> typ_aux -> typ
241+
val mk_typ_arg : ?loc:l -> typ_arg_aux -> typ_arg
242+
val mk_id_typ : ?loc:l -> id -> typ
241243

242244
val is_typ_arg_nexp : typ_arg -> bool
243245
val is_typ_arg_typ : typ_arg -> bool
@@ -585,6 +587,8 @@ val hex_to_bin : string -> string
585587

586588
val vector_string_to_bit_list : lit -> lit list
587589

590+
val extern_assoc : string -> extern option -> string option
591+
588592
(** {1 Manipulating locations} *)
589593

590594
(** locate takes an expression and recursively sets the location in
@@ -605,7 +609,10 @@ val locate_typ : (l -> l) -> typ -> typ
605609
a generated number. *)
606610
val unique : l -> l
607611

608-
val extern_assoc : string -> extern option -> string option
612+
(** Convert unknown locations into known ones by replacing any Unknown
613+
subparts of the second argument with the first argument. Set up so
614+
one can do: [locate (unknown_to l) exp] and similar. *)
615+
val unknown_to : l -> l -> l
609616

610617
(** Try to find the annotation closest to the provided location (which
611618
can be in any format, as long as we can tell if it is smaller than

0 commit comments

Comments
 (0)