diff options
Diffstat (limited to 'compiler/Translate.ml')
-rw-r--r-- | compiler/Translate.ml | 166 |
1 files changed, 115 insertions, 51 deletions
diff --git a/compiler/Translate.ml b/compiler/Translate.ml index 39b169c9..5827b4a8 100644 --- a/compiler/Translate.ml +++ b/compiler/Translate.ml @@ -783,11 +783,20 @@ let extract_definitions (fmt : Format.formatter) (config : gen_config) if wrap_in_sig then Format.pp_close_box fmt () -let extract_file (config : gen_config) (ctx : gen_ctx) (filename : string) - (rust_module_name : string) (module_name : string) (custom_msg : string) - (custom_imports : string list) (custom_includes : string list) : unit = +type extract_file_info = { + filename : string; + crate_name : string; + rust_module_name : string; + module_name : string; + custom_msg : string; + custom_imports : string list; + custom_includes : string list; +} + +let extract_file (config : gen_config) (ctx : gen_ctx) (fi : extract_file_info) + : unit = (* Open the file and create the formatter *) - let out = open_out filename in + let out = open_out fi.filename in let fmt = Format.formatter_of_out_channel out in (* Print the headers. @@ -801,19 +810,22 @@ let extract_file (config : gen_config) (ctx : gen_ctx) (filename : string) (match !Config.backend with | Lean -> Printf.fprintf out "-- THIS FILE WAS AUTOMATICALLY GENERATED BY AENEAS\n"; - Printf.fprintf out "-- [%s]%s\n" rust_module_name custom_msg + Printf.fprintf out "-- [%s]%s\n" fi.rust_module_name fi.custom_msg | Coq | FStar | HOL4 -> Printf.fprintf out "(** THIS FILE WAS AUTOMATICALLY GENERATED BY AENEAS *)\n"; - Printf.fprintf out "(** [%s]%s *)\n" rust_module_name custom_msg); + Printf.fprintf out "(** [%s]%s *)\n" fi.rust_module_name fi.custom_msg); + (* Generate the imports *) (match !Config.backend with | FStar -> - Printf.fprintf out "module %s\n" module_name; + Printf.fprintf out "module %s\n" fi.module_name; Printf.fprintf out "open Primitives\n"; (* Add the custom imports *) - List.iter (fun m -> Printf.fprintf out "open %s\n" m) custom_imports; + List.iter (fun m -> Printf.fprintf out "open %s\n" m) fi.custom_imports; (* Add the custom includes *) - List.iter (fun m -> Printf.fprintf out "include %s\n" m) custom_includes; + List.iter + (fun m -> Printf.fprintf out "include %s\n" m) + fi.custom_includes; (* Z3 options - note that we use fuel 1 because it its useful for the decrease clauses *) Printf.fprintf out "\n#set-options \"--z3rlimit 50 --fuel 1 --ifuel 1\"\n" | Coq -> @@ -825,26 +837,28 @@ let extract_file (config : gen_config) (ctx : gen_ctx) (filename : string) (* Add the custom imports *) List.iter (fun m -> Printf.fprintf out "Require Import %s.\n" m) - custom_imports; + fi.custom_imports; (* Add the custom includes *) List.iter (fun m -> Printf.fprintf out "Require Export %s.\n" m; Printf.fprintf out "Import %s.\n" m) - custom_includes; - Printf.fprintf out "Module %s.\n" module_name + fi.custom_includes; + Printf.fprintf out "Module %s.\n" fi.module_name | Lean -> Printf.fprintf out "import Base\n"; (* Add the custom imports *) - List.iter (fun m -> Printf.fprintf out "import %s\n" m) custom_imports; + List.iter (fun m -> Printf.fprintf out "import %s\n" m) fi.custom_imports; (* Add the custom includes *) - List.iter (fun m -> Printf.fprintf out "import %s\n" m) custom_includes; + List.iter (fun m -> Printf.fprintf out "import %s\n" m) fi.custom_includes; (* Always open the Primitives namespace *) - Printf.fprintf out "open Primitives\n" + Printf.fprintf out "open Primitives\n\n"; + (* Open the namespace *) + Printf.fprintf out "namespace %s\n" fi.crate_name | HOL4 -> Printf.fprintf out "open primitivesLib divDefLib\n"; (* Add the custom imports and includes *) - let imports = custom_imports @ custom_includes in + let imports = fi.custom_imports @ fi.custom_includes in (* The imports are a list of module names: we need to add a "Theory" suffix *) let imports = List.map (fun s -> s ^ "Theory") imports in if imports <> [] then @@ -852,7 +866,7 @@ let extract_file (config : gen_config) (ctx : gen_ctx) (filename : string) Printf.fprintf out "open %s\n\n" imports else Printf.fprintf out "\n"; (* Initialize the theory *) - Printf.fprintf out "val _ = new_theory \"%s\"\n\n" module_name); + Printf.fprintf out "val _ = new_theory \"%s\"\n\n" fi.module_name); (* From now onwards, we use the formatter *) (* Set the margin *) Format.pp_set_margin fmt 80; @@ -869,12 +883,13 @@ let extract_file (config : gen_config) (ctx : gen_ctx) (filename : string) (* Close the module *) (match !Config.backend with - | FStar | Lean -> () + | FStar -> () + | Lean -> Printf.fprintf out "end %s\n" fi.crate_name | HOL4 -> Printf.fprintf out "val _ = export_theory ()\n" - | Coq -> Printf.fprintf out "End %s .\n" module_name); + | Coq -> Printf.fprintf out "End %s .\n" fi.module_name); (* Some logging *) - log#linfo (lazy ("Generated: " ^ filename)); + log#linfo (lazy ("Generated: " ^ fi.filename)); (* Flush and close the file *) close_out out @@ -971,7 +986,7 @@ let translate_crate (filename : string) (dest_dir : string) (crate : A.crate) : (* Open the output file *) (* First compute the filename by replacing the extension and converting the * case (rust module names are snake case) *) - let module_name, extract_filebasename = + let crate_name, extract_filebasename = match Filename.chop_suffix_opt ~suffix:".llbc" filename with | None -> (* Note that we already checked the suffix upon opening the file *) @@ -980,14 +995,14 @@ let translate_crate (filename : string) (dest_dir : string) (crate : A.crate) : (* Retrieve the file basename *) let basename = Filename.basename filename in (* Convert the case *) - let module_name = StringUtils.to_camel_case basename in - let module_name = + let crate_name = StringUtils.to_camel_case basename in + let crate_name = if !Config.backend = HOL4 then - StringUtils.lowercase_first_letter module_name - else module_name + StringUtils.lowercase_first_letter crate_name + else crate_name in (* Concatenate *) - (module_name, Filename.concat dest_dir module_name) + (crate_name, Filename.concat dest_dir crate_name) in (* Put the translated definitions in maps *) @@ -1022,10 +1037,10 @@ let translate_crate (filename : string) (dest_dir : string) (crate : A.crate) : create more directories *) if !Config.backend = Lean then ( let ( ^^ ) = Filename.concat in - if !Config.split_files then mkdir_if (dest_dir ^^ module_name); + if !Config.split_files then mkdir_if (dest_dir ^^ crate_name); if needs_clauses_module then ( assert !Config.split_files; - mkdir_if (dest_dir ^^ module_name ^^ "Clauses"))); + mkdir_if (dest_dir ^^ crate_name ^^ "Clauses"))); (* Copy the "Primitives" file, if necessary *) let _ = @@ -1129,7 +1144,7 @@ let translate_crate (filename : string) (dest_dir : string) (crate : A.crate) : let types_filename = extract_filebasename ^ file_delimiter ^ "Types" ^ types_filename_ext in - let types_module = module_name ^ module_delimiter ^ "Types" in + let types_module = crate_name ^ module_delimiter ^ "Types" in let types_config = { base_gen_config with @@ -1139,8 +1154,18 @@ let translate_crate (filename : string) (dest_dir : string) (crate : A.crate) : interface = has_opaque_types; } in - extract_file types_config gen_ctx types_filename crate.A.name types_module - ": type definitions" [] []; + let file_info = + { + filename = types_filename; + crate_name; + rust_module_name = crate.A.name; + module_name = types_module; + custom_msg = ": type definitions"; + custom_imports = []; + custom_includes = []; + } + in + extract_file types_config gen_ctx file_info; (* Extract the template clauses *) (if needs_clauses_module && !Config.extract_template_decreases_clauses then @@ -1149,15 +1174,24 @@ let translate_crate (filename : string) (dest_dir : string) (crate : A.crate) : ^ "Template" ^ ext in let template_clauses_module = - module_name ^ module_delimiter ^ "Clauses" ^ module_delimiter + crate_name ^ module_delimiter ^ "Clauses" ^ module_delimiter ^ "Template" in let template_clauses_config = { base_gen_config with extract_template_decreases_clauses = true } in - extract_file template_clauses_config gen_ctx template_clauses_filename - crate.A.name template_clauses_module - ": templates for the decreases clauses" [ types_module ] []); + let file_info = + { + filename = template_clauses_filename; + crate_name; + rust_module_name = crate.A.name; + module_name = template_clauses_module; + custom_msg = ": templates for the decreases clauses"; + custom_imports = [ types_module ]; + custom_includes = []; + } + in + extract_file template_clauses_config gen_ctx file_info); (* Extract the opaque functions, if needed *) let opaque_funs_module = @@ -1165,7 +1199,7 @@ let translate_crate (filename : string) (dest_dir : string) (crate : A.crate) : let opaque_filename = extract_filebasename ^ file_delimiter ^ "Opaque" ^ opaque_ext in - let opaque_module = module_name ^ module_delimiter ^ "Opaque" in + let opaque_module = crate_name ^ module_delimiter ^ "Opaque" in let opaque_imported_module = (* In the case of Lean, we declare an interface (a record) containing the opaque definitions, and we leave it to the user to provide an @@ -1175,7 +1209,7 @@ let translate_crate (filename : string) (dest_dir : string) (crate : A.crate) : TODO: do the same for the type definitions. *) if !Config.backend = Lean then - module_name ^ module_delimiter ^ "ExternalFuns" + crate_name ^ module_delimiter ^ "ExternalFuns" else opaque_module in let opaque_config = @@ -1193,15 +1227,26 @@ let translate_crate (filename : string) (dest_dir : string) (crate : A.crate) : extract_ctx = { gen_ctx.extract_ctx with use_opaque_pre = false }; } in - extract_file opaque_config gen_ctx opaque_filename crate.A.name - opaque_module ": opaque function definitions" [] [ types_module ]; + let file_info = + { + filename = opaque_filename; + crate_name; + rust_module_name = crate.A.name; + module_name = opaque_module; + custom_msg = ": opaque function definitions"; + custom_imports = []; + custom_includes = [ types_module ]; + } + in + extract_file opaque_config gen_ctx file_info; + (* Return the additional dependencies *) [ opaque_imported_module ]) else [] in (* Extract the functions *) let fun_filename = extract_filebasename ^ file_delimiter ^ "Funs" ^ ext in - let fun_module = module_name ^ module_delimiter ^ "Funs" in + let fun_module = crate_name ^ module_delimiter ^ "Funs" in let fun_config = { base_gen_config with @@ -1215,12 +1260,22 @@ let translate_crate (filename : string) (dest_dir : string) (crate : A.crate) : let clauses_submodule = if !Config.backend = Lean then module_delimiter ^ "Clauses" else "" in - [ module_name ^ clauses_submodule ^ module_delimiter ^ "Clauses" ] + [ crate_name ^ clauses_submodule ^ module_delimiter ^ "Clauses" ] else [] in - extract_file fun_config gen_ctx fun_filename crate.A.name fun_module - ": function definitions" [] - ([ types_module ] @ opaque_funs_module @ clauses_module)) + let file_info = + { + filename = fun_filename; + crate_name; + rust_module_name = crate.A.name; + module_name = fun_module; + custom_msg = ": function definitions"; + custom_imports = []; + custom_includes = + [ types_module ] @ opaque_funs_module @ clauses_module; + } + in + extract_file fun_config gen_ctx file_info) else let gen_config = { @@ -1237,10 +1292,19 @@ let translate_crate (filename : string) (dest_dir : string) (crate : A.crate) : test_trans_unit_functions = !Config.test_trans_unit_functions; } in + let file_info = + { + filename = extract_filebasename ^ ext; + crate_name; + rust_module_name = crate.A.name; + module_name = crate_name; + custom_msg = ""; + custom_imports = []; + custom_includes = []; + } + in (* Add the extension for F* *) - let extract_filename = extract_filebasename ^ ext in - extract_file gen_config gen_ctx extract_filename crate.A.name module_name - "" [] []); + extract_file gen_config gen_ctx file_info); (* Generate the build file *) match !Config.backend with @@ -1258,10 +1322,10 @@ let translate_crate (filename : string) (dest_dir : string) (crate : A.crate) : * different files. *) if !Config.split_files then ( - let filename = Filename.concat dest_dir (module_name ^ ".lean") in + let filename = Filename.concat dest_dir (crate_name ^ ".lean") in let out = open_out filename in (* Write *) - Printf.fprintf out "import %s.Funs\n" module_name; + Printf.fprintf out "import %s.Funs\n" crate_name; (* Flush and close the file, log *) close_out out; log#linfo (lazy ("Generated: " ^ filename))); @@ -1280,10 +1344,10 @@ let translate_crate (filename : string) (dest_dir : string) (crate : A.crate) : Printf.fprintf out " \"https://github.com/leanprover-community/mathlib4.git\"\n\n"; - let package_name = StringUtils.to_snake_case module_name in + let package_name = StringUtils.to_snake_case crate_name in Printf.fprintf out "package «%s» {}\n\n" package_name; - Printf.fprintf out "@[default_target]\nlean_lib «%s» {}\n" module_name; + Printf.fprintf out "@[default_target]\nlean_lib «%s» {}\n" crate_name; (* No default target for now. Format would be: |