summaryrefslogtreecommitdiff
path: root/src/sail.ml
diff options
context:
space:
mode:
Diffstat (limited to 'src/sail.ml')
-rw-r--r--src/sail.ml171
1 files changed, 128 insertions, 43 deletions
diff --git a/src/sail.ml b/src/sail.ml
index 905f03d7..519ec916 100644
--- a/src/sail.ml
+++ b/src/sail.ml
@@ -52,48 +52,111 @@ open Process_file
let lib = ref ([] : string list)
let opt_file_out : string option ref = ref None
+let opt_interactive = ref false
let opt_print_version = ref false
let opt_print_initial_env = ref false
let opt_print_verbose = ref false
let opt_print_lem_ast = ref false
let opt_print_lem = ref false
+let opt_print_sil = ref false
let opt_print_ocaml = ref false
+let opt_convert = ref false
+let opt_memo_z3 = ref false
+let opt_sanity = ref false
let opt_libs_lem = ref ([]:string list)
let opt_libs_ocaml = ref ([]:string list)
let opt_file_arguments = ref ([]:string list)
+let opt_mono_split = ref ([]:((string * int) * string) list)
+
let options = Arg.align ([
( "-o",
Arg.String (fun f -> opt_file_out := Some f),
"<prefix> select output filename prefix");
+ ( "-i",
+ Arg.Set opt_interactive,
+ " start interactive interpreter");
+ ( "-ocaml",
+ Arg.Tuple [Arg.Set opt_print_ocaml; Arg.Set Initial_check.opt_undefined_gen],
+ " output an OCaml translated version of the input");
+ ( "-ocaml_trace",
+ Arg.Tuple [Arg.Set opt_print_ocaml; Arg.Set Initial_check.opt_undefined_gen; Arg.Set Ocaml_backend.opt_trace_ocaml],
+ " output an OCaml translated version of the input with tracing instrumentation, implies -ocaml");
+ ( "-ocaml_lib",
+ Arg.String (fun l -> opt_libs_ocaml := l::!opt_libs_ocaml),
+ "<filename> provide additional library to open in OCaml output");
( "-lem_ast",
Arg.Set opt_print_lem_ast,
" output a Lem AST representation of the input");
+ ( "-sil",
+ Arg.Tuple [Arg.Set opt_print_sil; Arg.Set Initial_check.opt_undefined_gen],
+ " output a SIL translated version of the input");
( "-lem",
Arg.Set opt_print_lem,
" output a Lem translated version of the input");
- ( "-ocaml",
- Arg.Set opt_print_ocaml,
- " output an OCaml translated version of the input");
( "-lem_lib",
Arg.String (fun l -> opt_libs_lem := l::!opt_libs_lem),
"<filename> provide additional library to open in Lem output");
- ( "-ocaml_lib",
- Arg.String (fun l -> opt_libs_ocaml := l::!opt_libs_ocaml),
- "<filename> provide additional library to open in OCaml output");
-(*
- ( "-i",
- Arg.String (fun l -> lib := l::!lib),
- "<library_filename> treat this file as input only and generate no output for it");
-*)
- ( "-print_initial_env",
- Arg.Set opt_print_initial_env,
- " print the built-in initial type environment and terminate");
+ ( "-lem_sequential",
+ Arg.Set Process_file.opt_lem_sequential,
+ " use sequential state monad for Lem output");
+ ( "-lem_mwords",
+ Arg.Set Process_file.opt_lem_mwords,
+ " use native machine word library for Lem output");
+ ( "-mono-split",
+ Arg.String (fun s ->
+ let l = Util.split_on_char ':' s in
+ match l with
+ | [fname;line;var] -> opt_mono_split := ((fname,int_of_string line),var)::!opt_mono_split
+ | _ -> raise (Arg.Bad (s ^ " not of form <filename>:<line>:<variable>"))),
+ "<filename>:<line>:<variable> to case split for monomorphisation");
+ ( "-memo_z3",
+ Arg.Set opt_memo_z3,
+ " memoize calls to z3, improving performance when typechecking repeatedly");
+ ( "-undefined_gen",
+ Arg.Set Initial_check.opt_undefined_gen,
+ " generate undefined_type functions for types in the specification");
+ ( "-no_effects",
+ Arg.Set Type_check.opt_no_effects,
+ " (experimental) turn off effect checking");
+ ( "-new_parser",
+ Arg.Set Process_file.opt_new_parser,
+ " (experimental) use new parser");
+ ( "-convert",
+ Arg.Set opt_convert,
+ " (experimental) convert sail to new syntax for use with -new_parser");
+ ( "-just_check",
+ Arg.Set opt_just_check,
+ " (experimental) terminate immediately after typechecking");
+ ( "-ddump_raw_mono_ast",
+ Arg.Set opt_ddump_raw_mono_ast,
+ " (debug) dump the monomorphised ast before type-checking");
+ ( "-dmono_analysis",
+ Arg.Set_int opt_dmono_analysis,
+ " (debug) dump information about monomorphisation analysis: 0 silent, 3 max");
+ ( "-auto_mono",
+ Arg.Set opt_auto_mono,
+ " automatically infer how to monomorphise code");
( "-verbose",
Arg.Set opt_print_verbose,
" (debug) pretty-print the input to standard output");
- ( "-skip_constraints",
- Arg.Clear Type_internal.do_resolve_constraints,
- " (debug) skip constraint resolution in type-checking");
+ ( "-ddump_tc_ast",
+ Arg.Set opt_ddump_tc_ast,
+ " (debug) dump the typechecked ast to stdout");
+ ( "-ddump_rewrite_ast",
+ Arg.String (fun l -> opt_ddump_rewrite_ast := Some (l, 0)),
+ "<prefix> (debug) dump the ast after each rewriting step to <prefix>_<i>.lem");
+ ( "-dtc_verbose",
+ Arg.Int (fun verbosity -> Type_check.opt_tc_debug := verbosity),
+ "<verbosity> (debug) verbose typechecker output: 0 is silent");
+ ( "-dno_cast",
+ Arg.Set opt_dno_cast,
+ " (debug) typecheck without any implicit casting");
+ ( "-dsanity",
+ Arg.Set opt_sanity,
+ " (debug) sanity check the AST (slow)");
+ ( "-dmagic_hash",
+ Arg.Set Initial_check.opt_magic_hash,
+ " (debug) allow special character # in identifiers");
( "-v",
Arg.Set opt_print_version,
" print version");
@@ -110,50 +173,72 @@ let _ =
opt_file_arguments := (!opt_file_arguments) @ [s])
usage_msg
+let interactive_ast = ref (Ast.Defs [])
+let interactive_env = ref Type_check.initial_env
let main() =
- if !(opt_print_version)
+ if !opt_print_version
then Printf.printf "Sail private release \n"
- else if !(opt_print_initial_env) then
- let ppd_initial_typ_env =
- String.concat ""
- (List.map
- (function (comment,tenv) ->
- "(* "^comment^" *)\n" ^
- String.concat ""
- (List.map
- (function (id,tannot) ->
- id ^ " : " ^
- Pretty_print.pp_format_annot_ascii tannot
- ^ "\n")
- tenv))
- Type_internal.initial_typ_env_list) in
- Printf.printf "%s" ppd_initial_typ_env ;
- else
+ else
+ if !opt_memo_z3 then Constraint.load_digests () else ();
let parsed = (List.map (fun f -> (f,(parse_file f))) !opt_file_arguments) in
- let ast =
+ let ast =
List.fold_right (fun (_,(Parse_ast.Defs ast_nodes)) (Parse_ast.Defs later_nodes)
-> Parse_ast.Defs (ast_nodes@later_nodes)) parsed (Parse_ast.Defs []) in
- let (ast,kenv,ord) = convert_ast ast in
- let (ast,type_envs) = check_ast ast kenv ord in
- let ast = rewrite_ast ast in
+ let ast = convert_ast Ast_util.inc_ord ast in
+
+ if !opt_convert
+ then (Pretty_print_sail2.pp_defs stdout ast; exit 0)
+ else ();
+
+ let (ast, type_envs) = check_ast ast in
+
+ let (ast, type_envs) =
+ match !opt_mono_split, !opt_auto_mono with
+ | [], false -> ast, type_envs
+ | locs, _ -> monomorphise_ast locs type_envs ast
+ in
+
+ let ast =
+ if !Initial_check.opt_undefined_gen then
+ rewrite_undefined (rewrite_ast ast)
+ else rewrite_ast ast in
+
let out_name = match !opt_file_out with
+ | None when parsed = [] -> "out.sail"
| None -> fst (List.hd parsed)
| Some f -> f ^ ".sail" in
+
+ if !opt_memo_z3 then Constraint.save_digests () else ();
+
(*let _ = Printf.eprintf "Type checked, next to pretty print" in*)
- begin
+ begin
+ (if !(opt_interactive)
+ then
+ (interactive_ast := ast; interactive_env := type_envs)
+ else ());
+ (if !(opt_sanity)
+ then
+ let _ = rewrite_ast_check ast in
+ ()
+ else ());
(if !(opt_print_verbose)
then ((Pretty_print.pp_defs stdout) ast)
else ());
(if !(opt_print_lem_ast)
then output "" Lem_ast_out [out_name,ast]
else ());
+ (if !(opt_print_sil)
+ then
+ let ast = rewrite_ast_sil ast in
+ Pretty_print_sail2.pp_defs stdout ast
+ else ());
(if !(opt_print_ocaml)
- then let ast_ocaml = rewrite_ast_ocaml ast in
- if !(opt_libs_ocaml) = []
- then output "" (Ocaml_out None) [out_name,ast_ocaml]
- else output "" (Ocaml_out (Some (List.hd !opt_libs_ocaml))) [out_name,ast_ocaml]
+ then
+ let ast_ocaml = rewrite_ast_ocaml ast in
+ let out = match !opt_file_out with None -> "out" | Some s -> s in
+ Ocaml_backend.ocaml_compile out ast_ocaml
else ());
(if !(opt_print_lem)
then let ast_lem = rewrite_ast_lem ast in