mirror of
https://github.com/CatalaLang/catala.git
synced 2024-11-09 22:16:10 +03:00
Add the possibility to override inputs of included files
This commit is contained in:
parent
26077d60e1
commit
601dc80e3d
@ -323,13 +323,28 @@ let with_sedlex_file file f =
|
|||||||
Sedlexing.set_filename lexbuf file;
|
Sedlexing.set_filename lexbuf file;
|
||||||
Fun.protect ~finally:(fun () -> close_in ic) (fun () -> f lexbuf)
|
Fun.protect ~finally:(fun () -> close_in ic) (fun () -> f lexbuf)
|
||||||
|
|
||||||
|
let with_sedlex_source source_file f =
|
||||||
|
match source_file with
|
||||||
|
| Global.FileName file -> with_sedlex_file file f
|
||||||
|
| Global.Contents (str, file) ->
|
||||||
|
let lexbuf = Sedlexing.Utf8.from_string str in
|
||||||
|
Sedlexing.set_filename lexbuf file;
|
||||||
|
f lexbuf
|
||||||
|
| Global.Stdin file ->
|
||||||
|
let lexbuf = Sedlexing.Utf8.from_channel stdin in
|
||||||
|
Sedlexing.set_filename lexbuf file;
|
||||||
|
f lexbuf
|
||||||
|
|
||||||
(** Parses a single source file *)
|
(** Parses a single source file *)
|
||||||
let rec parse_source (lexbuf : Sedlexing.lexbuf) : Ast.program =
|
let rec parse_source ?resolve_included_file (lexbuf : Sedlexing.lexbuf) :
|
||||||
|
Ast.program =
|
||||||
let source_file_name = lexbuf_file lexbuf in
|
let source_file_name = lexbuf_file lexbuf in
|
||||||
Message.debug "Parsing %a" File.format source_file_name;
|
Message.debug "Parsing %a" File.format source_file_name;
|
||||||
let language = Cli.file_lang source_file_name in
|
let language = Cli.file_lang source_file_name in
|
||||||
let commands = localised_parser language lexbuf in
|
let commands = localised_parser language lexbuf in
|
||||||
let program = expand_includes source_file_name commands in
|
let program =
|
||||||
|
expand_includes ?resolve_included_file source_file_name commands
|
||||||
|
in
|
||||||
{
|
{
|
||||||
program with
|
program with
|
||||||
program_source_files = source_file_name :: program.Ast.program_source_files;
|
program_source_files = source_file_name :: program.Ast.program_source_files;
|
||||||
@ -338,8 +353,10 @@ let rec parse_source (lexbuf : Sedlexing.lexbuf) : Ast.program =
|
|||||||
|
|
||||||
(** Expands the include directives in a parsing result, thus parsing new source
|
(** Expands the include directives in a parsing result, thus parsing new source
|
||||||
files *)
|
files *)
|
||||||
and expand_includes (source_file : string) (commands : Ast.law_structure list) :
|
and expand_includes
|
||||||
Ast.program =
|
?(resolve_included_file = fun path -> Catala_utils.Global.FileName path)
|
||||||
|
(source_file : string)
|
||||||
|
(commands : Ast.law_structure list) : Ast.program =
|
||||||
let language = Cli.file_lang source_file in
|
let language = Cli.file_lang source_file in
|
||||||
let rprg =
|
let rprg =
|
||||||
List.fold_left
|
List.fold_left
|
||||||
@ -379,9 +396,10 @@ and expand_includes (source_file : string) (commands : Ast.law_structure list) :
|
|||||||
"Included file '%s' is not a regular file or does not exist."
|
"Included file '%s' is not a regular file or does not exist."
|
||||||
sub_source
|
sub_source
|
||||||
else
|
else
|
||||||
with_sedlex_file sub_source
|
let sub_source = resolve_included_file sub_source in
|
||||||
|
with_sedlex_source sub_source
|
||||||
@@ fun lexbuf ->
|
@@ fun lexbuf ->
|
||||||
let includ_program = parse_source lexbuf in
|
let includ_program = parse_source ~resolve_included_file lexbuf in
|
||||||
let () =
|
let () =
|
||||||
includ_program.Ast.program_module
|
includ_program.Ast.program_module
|
||||||
|> Option.iter
|
|> Option.iter
|
||||||
@ -481,18 +499,6 @@ let get_interface program =
|
|||||||
|
|
||||||
(** {1 API} *)
|
(** {1 API} *)
|
||||||
|
|
||||||
let with_sedlex_source source_file f =
|
|
||||||
match source_file with
|
|
||||||
| Global.FileName file -> with_sedlex_file file f
|
|
||||||
| Global.Contents (str, file) ->
|
|
||||||
let lexbuf = Sedlexing.Utf8.from_string str in
|
|
||||||
Sedlexing.set_filename lexbuf file;
|
|
||||||
f lexbuf
|
|
||||||
| Global.Stdin file ->
|
|
||||||
let lexbuf = Sedlexing.Utf8.from_channel stdin in
|
|
||||||
Sedlexing.set_filename lexbuf file;
|
|
||||||
f lexbuf
|
|
||||||
|
|
||||||
let check_modname program source_file =
|
let check_modname program source_file =
|
||||||
match program.Ast.program_module, source_file with
|
match program.Ast.program_module, source_file with
|
||||||
| ( Some { module_name = mname, pos; _ },
|
| ( Some { module_name = mname, pos; _ },
|
||||||
@ -537,10 +543,14 @@ let load_interface ?default_module_name source_file =
|
|||||||
Ast.intf_submodules = used_modules;
|
Ast.intf_submodules = used_modules;
|
||||||
}
|
}
|
||||||
|
|
||||||
let parse_top_level_file (source_file : File.t Global.input_src) : Ast.program =
|
let parse_top_level_file
|
||||||
|
?resolve_included_file
|
||||||
|
(source_file : File.t Global.input_src) : Ast.program =
|
||||||
Message.with_delayed_errors
|
Message.with_delayed_errors
|
||||||
@@ fun () ->
|
@@ fun () ->
|
||||||
let program = with_sedlex_source source_file parse_source in
|
let program =
|
||||||
|
with_sedlex_source source_file (parse_source ?resolve_included_file)
|
||||||
|
in
|
||||||
check_modname program source_file;
|
check_modname program source_file;
|
||||||
{
|
{
|
||||||
program with
|
program with
|
||||||
|
@ -32,7 +32,11 @@ val load_interface :
|
|||||||
keeps type information. The list of submodules is initialised with names
|
keeps type information. The list of submodules is initialised with names
|
||||||
only and empty contents. *)
|
only and empty contents. *)
|
||||||
|
|
||||||
val parse_top_level_file : File.t Global.input_src -> Ast.program
|
val parse_top_level_file :
|
||||||
|
?resolve_included_file:(string -> string Global.input_src) ->
|
||||||
|
File.t Global.input_src ->
|
||||||
|
Ast.program
|
||||||
(** Parses a catala file (handling file includes) and returns a program.
|
(** Parses a catala file (handling file includes) and returns a program.
|
||||||
Interfaces of the used modules are returned empty, use [load_interface] to
|
Interfaces of the used modules are returned empty, use [load_interface] to
|
||||||
fill them. *)
|
fill them. When provided [resolve_included_file] replaces file includes with
|
||||||
|
an user provided input source. *)
|
||||||
|
Loading…
Reference in New Issue
Block a user