Fixes for linking modules in the backends (in particular, Python)

This commit is contained in:
Louis Gesbert 2024-03-08 17:32:47 +01:00
parent 26c28bbd35
commit dc6bfae75c
5 changed files with 46 additions and 22 deletions

View File

@ -727,6 +727,13 @@ let commands = if commands = [] then entry_scopes else commands
name format_var var name)
scopes_with_no_input
let reexport_used_modules fmt modules =
List.iter
(fun m ->
Format.fprintf fmt "@[<hv 2>module %a@ = %a@]@," ModuleName.format m
ModuleName.format m)
modules
let format_module_registration
fmt
(bnd : ('m Ast.expr Var.t * _) String.Map.t)
@ -772,17 +779,22 @@ let format_program
?(exec_args = true)
(p : 'm Ast.program)
(type_ordering : Scopelang.Dependency.TVertex.t list) : unit =
Format.pp_open_vbox fmt 0;
Format.pp_print_string fmt header;
reexport_used_modules fmt (Program.modules_to_list p.decl_ctx.ctx_modules);
format_ctx type_ordering fmt p.decl_ctx;
let bnd = format_code_items p.decl_ctx fmt p.code_items in
Format.pp_print_newline fmt ();
match p.module_name, exec_scope with
| Some modname, None -> format_module_registration fmt bnd modname
| None, Some scope_name ->
let scope_body = Program.get_scope_body p scope_name in
format_scope_exec p.decl_ctx fmt bnd scope_name scope_body
| None, None -> if exec_args then format_scope_exec_args p.decl_ctx fmt bnd
| Some _, Some _ ->
Message.raise_error
"OCaml generation: both module registration and top-level scope \
execution where required at the same time."
Format.pp_print_cut fmt ();
let () =
match p.module_name, exec_scope with
| Some modname, None -> format_module_registration fmt bnd modname
| None, Some scope_name ->
let scope_body = Program.get_scope_body p scope_name in
format_scope_exec p.decl_ctx fmt bnd scope_name scope_body
| None, None -> if exec_args then format_scope_exec_args p.decl_ctx fmt bnd
| Some _, Some _ ->
Message.raise_error
"OCaml generation: both module registration and top-level scope \
execution where required at the same time."
in
Format.pp_close_box fmt ()

View File

@ -433,7 +433,7 @@ module To_jsoo = struct
Format.fprintf fmt "%sLib"
(Option.fold ~none:""
~some:(fun name ->
List.nth (String.split_on_char ' ' name) 1
name
|> String.split_on_char '_'
|> List.map String.capitalize_ascii
|> String.concat "")
@ -458,7 +458,7 @@ module To_jsoo = struct
@[<v 2>let () =@ @[<hov 2> Js.export \"%a\"@\n\
@[<v 2>(object%%js@ %a@]@\n\
end)@]@]@?"
(Option.fold ~none:"" ~some:(fun name -> name) module_name)
(Option.fold ~none:"" ~some:(fun name -> "open " ^ name) module_name)
(format_ctx type_ordering) prgm.decl_ctx
(format_scopes_to_fun prgm.decl_ctx)
prgm.code_items fmt_lib_name ()
@ -487,9 +487,16 @@ let run
with_formatter (fun fmt ->
Message.emit_debug "Writing JSOO API code to %s..."
(Option.value ~default:"stdout" jsoo_output_file);
To_jsoo.format_program fmt
(Option.map (fun m -> "open " ^ ModuleName.to_string m) prg.module_name)
prg type_ordering)
let modname =
match prg.module_name with
| Some m -> ModuleName.to_string m
| None ->
String.capitalize_ascii
Filename.(
basename
(remove_extension (Cli.input_src_file options.Cli.input_src)))
in
To_jsoo.format_program fmt (Some modname) prg type_ordering)
let term =
let open Cmdliner.Term in

View File

@ -644,7 +644,13 @@ let translate_program ~(config : translation_config) (p : 'm L.program) :
let modules =
List.fold_left
(fun acc m ->
ModuleName.Map.add m (A.VarName.fresh (ModuleName.get_info m)) acc)
let vname = Mark.map (( ^ ) "Module_") (ModuleName.get_info m) in
(* The "Module_" prefix is a workaround name clashes for same-name
structs and modules, Python in particular mixes everything in one
namespaces. It can be removed once we have full clash-free variable
renaming in the Python backend (requiring all idents to go through
one stage of being bindlib vars) *)
ModuleName.Map.add m (A.VarName.fresh vname) acc)
ModuleName.Map.empty
(Program.modules_to_list p.decl_ctx.ctx_modules)
in

View File

@ -136,12 +136,10 @@ end)
let format_name_cleaned (fmt : Format.formatter) (s : string) : unit =
s
|> String.to_ascii
|> String.to_snake_case
|> Re.Pcre.substitute ~rex:(Re.Pcre.regexp "\\.") ~subst:(fun _ -> "_dot_")
|> String.to_ascii
|> avoid_keywords
|> Format.fprintf fmt "%s"
|> Format.pp_print_string fmt
(** For each `VarName.t` defined by its string and then by its hash, we keep
track of which local integer id we've given it. This is used to keep
@ -666,7 +664,8 @@ let format_program
Format.pp_print_list Format.pp_print_string fmt header;
ModuleName.Map.iter
(fun m v ->
Format.fprintf fmt "import %a as %a@," ModuleName.format m format_var v)
Format.fprintf fmt "from . import %a as %a@," ModuleName.format m
format_var v)
p.ctx.modules;
Format.pp_print_cut fmt ();
format_ctx type_ordering fmt p.ctx;

View File

@ -25,6 +25,7 @@ $ catala Typecheck --check-invariants
```catala-test-inline
$ catala OCaml -O
Generating entry points for scopes: ScopeA ScopeB
(** This file has been generated by the Catala compiler, do not edit! *)
@ -60,7 +61,6 @@ let scope_b (scope_b_in: ScopeB_in.t) : ScopeB.t =
let a_: bool = scope_a_dot_a_ in
{ScopeB.a = a_}
Generating entry points for scopes: ScopeA ScopeB
let entry_scopes = [
"ScopeA";