This commit is contained in:
Louis Gesbert 2024-03-19 15:23:06 +01:00
parent 1a17098297
commit 619cafebb8
15 changed files with 66 additions and 38 deletions

View File

@ -37,7 +37,7 @@ let when_opt = Arg.enum ["auto", Auto; "always", Always; "never", Never]
let raw_file = let raw_file =
Arg.conv ~docv:"FILE" Arg.conv ~docv:"FILE"
( (fun f -> Result.map raw_file (Arg.conv_parser Arg.string f)), ( (fun f -> Result.map raw_file (Arg.conv_parser Arg.string f)),
(fun ppf f -> Format.pp_print_string ppf (f :> string)) ) fun ppf f -> Format.pp_print_string ppf (f :> string) )
(* Some helpers for catala sources *) (* Some helpers for catala sources *)
@ -79,7 +79,10 @@ module Flags = struct
conv ~docv:"FILE" conv ~docv:"FILE"
( (fun s -> ( (fun s ->
if s = "-" then Ok (Stdin (Global.raw_file "-stdin-")) if s = "-" then Ok (Stdin (Global.raw_file "-stdin-"))
else Result.map (fun f -> FileName (Global.raw_file f)) (conv_parser non_dir_file s)), else
Result.map
(fun f -> FileName (Global.raw_file f))
(conv_parser non_dir_file s)),
fun ppf -> function fun ppf -> function
| Stdin _ -> Format.pp_print_string ppf "-" | Stdin _ -> Format.pp_print_string ppf "-"
| FileName f -> conv_printer non_dir_file ppf (f :> file) | FileName f -> conv_printer non_dir_file ppf (f :> file)
@ -209,12 +212,12 @@ module Flags = struct
if debug then Printexc.record_backtrace true; if debug then Printexc.record_backtrace true;
let path_rewrite = let path_rewrite =
match directory with match directory with
| None -> fun (f: Global.raw_file) -> (f :> file) | None -> fun (f : Global.raw_file) -> (f :> file)
| Some to_dir -> ( | Some to_dir -> (
fun (f: Global.raw_file) -> fun (f : Global.raw_file) ->
match (f :> file) with match (f :> file) with
| "-" -> "-" | "-" -> "-"
| f -> File.reverse_path ~to_dir f) | f -> File.reverse_path ~to_dir f)
in in
(* This sets some global refs for convenience, but most importantly (* This sets some global refs for convenience, but most importantly
returns the options record. *) returns the options record. *)

View File

@ -23,12 +23,12 @@ val language_code : backend_lang -> string
(** Returns the lowercase two-letter language code *) (** Returns the lowercase two-letter language code *)
val file_lang : file -> backend_lang val file_lang : file -> backend_lang
(** Associates a file extension with its corresponding {!type: Global.backend_lang} (** Associates a file extension with its corresponding
string representation. *) {!type: Global.backend_lang} string representation. *)
(** {2 CLI flags and options} *) (** {2 CLI flags and options} *)
val when_opt: when_enum Cmdliner.Arg.conv val when_opt : when_enum Cmdliner.Arg.conv
module Flags : sig module Flags : sig
open Cmdliner open Cmdliner
@ -70,7 +70,7 @@ module Flags : sig
val lcalc : bool Term.t val lcalc : bool Term.t
(** for the 'interpret' command *) (** for the 'interpret' command *)
val extension : string option Term.t val extension : string list Term.t
(** for the 'depends' command *) (** for the 'depends' command *)
val prefix : string option Term.t val prefix : string option Term.t

View File

@ -70,8 +70,7 @@ let rec ensure_dir dir =
match Sys.is_directory dir with match Sys.is_directory dir with
| true -> () | true -> ()
| false -> | false ->
Message.raise_error "Directory %a exists but is not a directory" Message.raise_error "Directory %a exists but is not a directory" format dir
format dir
| exception Sys_error _ -> | exception Sys_error _ ->
let pdir = parent dir in let pdir = parent dir in
if pdir <> dir then ensure_dir pdir; if pdir <> dir then ensure_dir pdir;
@ -79,7 +78,8 @@ let rec ensure_dir dir =
0o777 (* will be affected by umask, most likely restricted to 0o755 *) 0o777 (* will be affected by umask, most likely restricted to 0o755 *)
let reverse_path ?(from_dir = Sys.getcwd ()) ~to_dir f = let reverse_path ?(from_dir = Sys.getcwd ()) ~to_dir f =
clean_path @@ clean_path
@@
if Filename.is_relative from_dir then invalid_arg "File.reverse_path" if Filename.is_relative from_dir then invalid_arg "File.reverse_path"
else if not (Filename.is_relative f) then f else if not (Filename.is_relative f) then f
else if not (Filename.is_relative to_dir) then Filename.concat from_dir f else if not (Filename.is_relative to_dir) then Filename.concat from_dir f

View File

@ -86,7 +86,8 @@ val check_directory : t -> t option
[Unix.realpath]). *) [Unix.realpath]). *)
val ensure_dir : t -> unit val ensure_dir : t -> unit
(** Creates the directory (and parents recursively) if it doesn't exist already. Errors out if the file exists but is not a directory *) (** Creates the directory (and parents recursively) if it doesn't exist already.
Errors out if the file exists but is not a directory *)
val check_file : t -> t option val check_file : t -> t option
(** Returns its argument if it exists and is a plain file, [None] otherwise. (** Returns its argument if it exists and is a plain file, [None] otherwise.

View File

@ -19,6 +19,7 @@ type raw_file = file
type backend_lang = En | Fr | Pl type backend_lang = En | Fr | Pl
type when_enum = Auto | Always | Never type when_enum = Auto | Always | Never
type message_format_enum = Human | GNU type message_format_enum = Human | GNU
type 'file input_src = type 'file input_src =
| FileName of 'file | FileName of 'file
| Contents of string * 'file | Contents of string * 'file
@ -82,5 +83,4 @@ let enforce_options
options options
let input_src_file = function FileName f | Contents (_, f) | Stdin f -> f let input_src_file = function FileName f | Contents (_, f) | Stdin f -> f
let raw_file f = f let raw_file f = f

View File

@ -14,7 +14,8 @@
License for the specific language governing permissions and limitations under License for the specific language governing permissions and limitations under
the License. *) the License. *)
(** This module contains definitions of global flags and types used throughout. They should be defined from the command-line and never modified afterwards. *) (** This module contains definitions of global flags and types used throughout.
They should be defined from the command-line and never modified afterwards. *)
type file = string type file = string
(** File names ; equal to [File.t] but let's avoid cyclic dependencies *) (** File names ; equal to [File.t] but let's avoid cyclic dependencies *)
@ -78,8 +79,9 @@ val enforce_options :
unit -> unit ->
options options
(** Sets up the global options (side-effect); for specific use-cases only, this (** Sets up the global options (side-effect); for specific use-cases only, this
should never be called from the compiler outside of the [Cli] module. Other proper uses include setting up the compiler library should never be called from the compiler outside of the [Cli] module. Other
when using it directly through a specific front-end. *) proper uses include setting up the compiler library when using it directly
through a specific front-end. *)
val input_src_file : file input_src -> file val input_src_file : file input_src -> file

View File

@ -18,8 +18,8 @@
open Catala_utils open Catala_utils
open Shared_ast open Shared_ast
(** Associates a file extension with its corresponding {!type: Global.backend_lang} (** Associates a file extension with its corresponding
string representation. *) {!type: Global.backend_lang} string representation. *)
let extensions = [".catala_fr", "fr"; ".catala_en", "en"; ".catala_pl", "pl"] let extensions = [".catala_fr", "fr"; ".catala_en", "en"; ".catala_pl", "pl"]
let modname_of_file f = let modname_of_file f =
@ -403,7 +403,8 @@ module Commands = struct
let get_output ?ext options output_file = let get_output ?ext options output_file =
let output_file = Option.map options.Global.path_rewrite output_file in let output_file = Option.map options.Global.path_rewrite output_file in
File.get_out_channel ~source_file:options.Global.input_src ~output_file ?ext () File.get_out_channel ~source_file:options.Global.input_src ~output_file ?ext
()
let get_output_format ?ext options output_file = let get_output_format ?ext options output_file =
let output_file = Option.map options.Global.path_rewrite output_file in let output_file = Option.map options.Global.path_rewrite output_file in
@ -444,7 +445,9 @@ module Commands = struct
in in
with_output with_output
@@ fun fmt -> @@ fun fmt ->
let language = Cli.file_lang (Global.input_src_file options.Global.input_src) in let language =
Cli.file_lang (Global.input_src_file options.Global.input_src)
in
let weave_output = Literate.Html.ast_to_html language ~print_only_law in let weave_output = Literate.Html.ast_to_html language ~print_only_law in
Message.emit_debug "Writing to %s" Message.emit_debug "Writing to %s"
(Option.value ~default:"stdout" output_file); (Option.value ~default:"stdout" output_file);
@ -480,7 +483,9 @@ module Commands = struct
in in
with_output with_output
@@ fun fmt -> @@ fun fmt ->
let language = Cli.file_lang (Global.input_src_file options.Global.input_src) in let language =
Cli.file_lang (Global.input_src_file options.Global.input_src)
in
let weave_output = Literate.Latex.ast_to_latex language ~print_only_law in let weave_output = Literate.Latex.ast_to_latex language ~print_only_law in
Message.emit_debug "Writing to %s" Message.emit_debug "Writing to %s"
(Option.value ~default:"stdout" output_file); (Option.value ~default:"stdout" output_file);
@ -694,7 +699,9 @@ module Commands = struct
in in
Message.emit_result "Computation successful!%s" Message.emit_result "Computation successful!%s"
(if List.length results > 0 then " Results:" else ""); (if List.length results > 0 then " Results:" else "");
let language = Cli.file_lang (Global.input_src_file options.Global.input_src) in let language =
Cli.file_lang (Global.input_src_file options.Global.input_src)
in
List.iter List.iter
(fun ((var, _), result) -> (fun ((var, _), result) ->
Message.emit_result "@[<hov 2>%s@ =@ %a@]" var Message.emit_result "@[<hov 2>%s@ =@ %a@]" var

View File

@ -416,8 +416,8 @@ let rec format_expr (ctx : decl_ctx) (fmt : Format.formatter) (e : 'm expr) :
(Pos.get_file pos) (Pos.get_start_line pos) (Pos.get_start_column pos) (Pos.get_file pos) (Pos.get_start_line pos) (Pos.get_start_column pos)
(Pos.get_end_line pos) (Pos.get_end_column pos) format_string_list (Pos.get_end_line pos) (Pos.get_end_column pos) format_string_list
(Pos.get_law_info pos) format_with_parens arg1 (Pos.get_law_info pos) format_with_parens arg1
| EAppOp { op = Log (EndCall, info); args = [arg1]; _ } when Global.options.trace | EAppOp { op = Log (EndCall, info); args = [arg1]; _ }
-> when Global.options.trace ->
Format.fprintf fmt "(log_end_call@ %a@ %a)" format_uid_list info Format.fprintf fmt "(log_end_call@ %a@ %a)" format_uid_list info
format_with_parens arg1 format_with_parens arg1
| EAppOp { op = Log _; args = [arg1]; _ } -> | EAppOp { op = Log _; args = [arg1]; _ } ->

View File

@ -494,7 +494,8 @@ let run
String.capitalize_ascii String.capitalize_ascii
Filename.( Filename.(
basename basename
(remove_extension (Global.input_src_file options.Global.input_src))) (remove_extension
(Global.input_src_file options.Global.input_src)))
in in
To_jsoo.format_program fmt (Some modname) prg type_ordering) To_jsoo.format_program fmt (Some modname) prg type_ordering)

View File

@ -1369,7 +1369,9 @@ let run includes optimize ex_scope explain_options global_options =
graph_cleanup explain_options g base_vars graph_cleanup explain_options g base_vars
else g else g
in in
let lang = Cli.file_lang (Global.input_src_file global_options.Global.input_src) in let lang =
Cli.file_lang (Global.input_src_file global_options.Global.input_src)
in
let dot_content = let dot_content =
to_dot lang Format.str_formatter prg.decl_ctx env base_vars g to_dot lang Format.str_formatter prg.decl_ctx env base_vars g
~base_src_url:explain_options.base_src_url; ~base_src_url:explain_options.base_src_url;

View File

@ -343,7 +343,8 @@ let rec format_expression ctx (fmt : Format.formatter) (e : expr) : unit =
(Pos.get_file pos) (Pos.get_start_line pos) (Pos.get_start_column pos) (Pos.get_file pos) (Pos.get_start_line pos) (Pos.get_start_column pos)
(Pos.get_end_line pos) (Pos.get_end_column pos) format_string_list (Pos.get_end_line pos) (Pos.get_end_column pos) format_string_list
(Pos.get_law_info pos) (format_expression ctx) arg1 (Pos.get_law_info pos) (format_expression ctx) arg1
| EAppOp { op = Log (EndCall, info); args = [arg1] } when Global.options.trace -> | EAppOp { op = Log (EndCall, info); args = [arg1] } when Global.options.trace
->
Format.fprintf fmt "log_end_call(%a,@ %a)" format_uid_list info Format.fprintf fmt "log_end_call(%a,@ %a)" format_uid_list info
(format_expression ctx) arg1 (format_expression ctx) arg1
| EAppOp { op = Log _; args = [arg1] } -> | EAppOp { op = Log _; args = [arg1] } ->

View File

@ -180,7 +180,8 @@ let lit (fmt : Format.formatter) (l : lit) : unit =
| LUnit -> lit_style fmt "()" | LUnit -> lit_style fmt "()"
| LRat i -> | LRat i ->
lit_style fmt lit_style fmt
(Runtime.decimal_to_string ~max_prec_digits:Global.options.max_prec_digits i) (Runtime.decimal_to_string ~max_prec_digits:Global.options.max_prec_digits
i)
| LMoney e -> | LMoney e ->
lit_style fmt (Format.asprintf "¤%s" (Runtime.money_to_string e)) lit_style fmt (Format.asprintf "¤%s" (Runtime.money_to_string e))
| LDate d -> lit_style fmt (Runtime.date_to_string d) | LDate d -> lit_style fmt (Runtime.date_to_string d)
@ -964,7 +965,8 @@ module UserFacing = struct
let decsep (lang : Global.backend_lang) = let decsep (lang : Global.backend_lang) =
match lang with En -> "." | Fr -> "," | Pl -> "." match lang with En -> "." | Fr -> "," | Pl -> "."
let unit (_lang : Global.backend_lang) ppf () = Format.pp_print_string ppf "()" let unit (_lang : Global.backend_lang) ppf () =
Format.pp_print_string ppf "()"
let bool (lang : Global.backend_lang) ppf b = let bool (lang : Global.backend_lang) ppf b =
let s = let s =

View File

@ -98,8 +98,13 @@ val program : ?debug:bool -> Format.formatter -> ('a, 'm) gexpr program -> unit
module UserFacing : sig module UserFacing : sig
val unit : Global.backend_lang -> Format.formatter -> Runtime.unit -> unit val unit : Global.backend_lang -> Format.formatter -> Runtime.unit -> unit
val bool : Global.backend_lang -> Format.formatter -> Runtime.bool -> unit val bool : Global.backend_lang -> Format.formatter -> Runtime.bool -> unit
val integer : Global.backend_lang -> Format.formatter -> Runtime.integer -> unit
val decimal : Global.backend_lang -> Format.formatter -> Runtime.decimal -> unit val integer :
Global.backend_lang -> Format.formatter -> Runtime.integer -> unit
val decimal :
Global.backend_lang -> Format.formatter -> Runtime.decimal -> unit
val money : Global.backend_lang -> Format.formatter -> Runtime.money -> unit val money : Global.backend_lang -> Format.formatter -> Runtime.money -> unit
val date : Global.backend_lang -> Format.formatter -> Runtime.date -> unit val date : Global.backend_lang -> Format.formatter -> Runtime.date -> unit

View File

@ -234,7 +234,8 @@ let handle_type_error ctx (A.AnyExpr e) t1 t2 =
( (fun ppf -> ( (fun ppf ->
Format.fprintf ppf "@[<hv 2>@[<hov>%a@ %a@]:" Format.pp_print_text Format.fprintf ppf "@[<hv 2>@[<hov>%a@ %a@]:" Format.pp_print_text
"This expression has type" (format_typ ctx) t1; "This expression has type" (format_typ ctx) t1;
if Global.options.debug then Format.fprintf ppf "@ %a@]" Expr.format e if Global.options.debug then
Format.fprintf ppf "@ %a@]" Expr.format e
else Format.pp_close_box ppf ()), else Format.pp_close_box ppf ()),
e_pos ); e_pos );
( (fun ppf -> ( (fun ppf ->
@ -248,7 +249,8 @@ let handle_type_error ctx (A.AnyExpr e) t1 t2 =
( (fun ppf -> ( (fun ppf ->
Format.fprintf ppf "@[<hv 2>@[<hov>%a:@]" Format.pp_print_text Format.fprintf ppf "@[<hv 2>@[<hov>%a:@]" Format.pp_print_text
"While typechecking the following expression"; "While typechecking the following expression";
if Global.options.debug then Format.fprintf ppf "@ %a@]" Expr.format e if Global.options.debug then
Format.fprintf ppf "@ %a@]" Expr.format e
else Format.pp_close_box ppf ()), else Format.pp_close_box ppf ()),
e_pos ); e_pos );
( (fun ppf -> ( (fun ppf ->

View File

@ -198,7 +198,8 @@ module Parser_En = ParserAux (Lexer_en)
module Parser_Fr = ParserAux (Lexer_fr) module Parser_Fr = ParserAux (Lexer_fr)
module Parser_Pl = ParserAux (Lexer_pl) module Parser_Pl = ParserAux (Lexer_pl)
let localised_parser : Global.backend_lang -> lexbuf -> Ast.source_file = function let localised_parser : Global.backend_lang -> lexbuf -> Ast.source_file =
function
| En -> Parser_En.commands_or_includes | En -> Parser_En.commands_or_includes
| Fr -> Parser_Fr.commands_or_includes | Fr -> Parser_Fr.commands_or_includes
| Pl -> Parser_Pl.commands_or_includes | Pl -> Parser_Pl.commands_or_includes
@ -418,7 +419,8 @@ let load_interface ?default_module_name source_file =
let modname = let modname =
match program.Ast.program_module_name, default_module_name with match program.Ast.program_module_name, default_module_name with
| Some mname, _ -> mname | Some mname, _ -> mname
| None, Some n -> n, Pos.from_info (Global.input_src_file source_file) 0 0 0 0 | None, Some n ->
n, Pos.from_info (Global.input_src_file source_file) 0 0 0 0
| None, None -> | None, None ->
Message.raise_error Message.raise_error
"%a doesn't define a module name. It should contain a '@{<cyan>> \ "%a doesn't define a module name. It should contain a '@{<cyan>> \