Skip to content

Commit fcc77ce

Browse files
Allow Catala files with a .md suffix (#916)
2 parents cf4bea1 + b8985ca commit fcc77ce

File tree

12 files changed

+114
-67
lines changed

12 files changed

+114
-67
lines changed

build_system/clerk_cli.ml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -372,6 +372,7 @@ let init
372372
color
373373
debug
374374
whole_program =
375+
if debug then Printexc.record_backtrace true;
375376
let _options = Catala_utils.Global.enforce_options ~debug ~color () in
376377
let default_config_file = "clerk.toml" in
377378
let set_root_dir dir =

build_system/clerk_driver.ml

Lines changed: 29 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,7 @@ let linking_command ~build_dir ~backend ~var_bindings link_deps item target =
191191
(link_deps item)
192192
@ [
193193
target -.- "cmx";
194-
Filename.remove_extension target ^ "+main.cmx";
194+
File.remove_extension target ^ "+main.cmx";
195195
"-o";
196196
target -.- "exe";
197197
]
@@ -205,7 +205,7 @@ let linking_command ~build_dir ~backend ~var_bindings link_deps item target =
205205
(build_dir / dirname f / "c" / basename f) ^ ".o")
206206
(link_deps item)
207207
@ ["-lgmp"]
208-
@ [target -.- "o"; Filename.remove_extension target ^ "+main.o"]
208+
@ [target -.- "o"; File.remove_extension target ^ "+main.o"]
209209
@ get_var var_bindings Var.c_flags
210210
@ get_var var_bindings Var.c_include
211211
@ ["-o"; target -.- "exe"]
@@ -242,7 +242,7 @@ let linking_command ~build_dir ~backend ~var_bindings link_deps item target =
242242
(* 'javac' generates one file per inner class. Sadly, we do generate a lot
243243
of those. We need to pack those in the jar as well. *)
244244
let fetch_inner_classes class_file =
245-
let basename = Filename.(basename class_file |> chop_extension) in
245+
let basename = File.(remove_extension (basename class_file)) in
246246
let dirname = Filename.dirname class_file in
247247
let dir_classes =
248248
Hashtbl.find_opt h dirname
@@ -346,7 +346,7 @@ let string_of_backend = function
346346

347347
let make_target ~build_dir ~backend item =
348348
let open File in
349-
let f = Scan.target_file_name item ^ Filename.extension item.Scan.file_name in
349+
let f = Scan.target_file_name item -.- File.extension item.Scan.file_name in
350350
let dir = dirname f in
351351
let base = basename f in
352352
let base =
@@ -489,8 +489,8 @@ let build_clerk_target
489489
(fun acc ((item, tg, backend), _) ->
490490
let targets =
491491
let f =
492-
Scan.target_file_name item
493-
^ Filename.extension item.Scan.file_name
492+
File.(
493+
Scan.target_file_name item -.- extension item.Scan.file_name)
494494
in
495495
let tf =
496496
File.(build_dir / dirname f / backend_subdir backend / basename f)
@@ -724,7 +724,7 @@ let build_direct_targets
724724
let t = make_target ~build_dir ~backend item in
725725
match backend with
726726
| `Java | `Python | `Custom _ -> t
727-
| _ -> Filename.remove_extension t ^ "+main" ^ Filename.extension t)
727+
| _ -> File.((remove_extension t ^ "+main") -.- File.extension t))
728728
exec_targets
729729
in
730730
let final_ninja_targets =
@@ -880,7 +880,7 @@ let run_artifact config ~backend ~var_bindings ?scope src =
880880
| `Python ->
881881
let build_dir = config.Cli.options.global.build_dir in
882882
let cmd =
883-
let base = Filename.(basename (remove_extension src)) in
883+
let base = Filename.basename (File.remove_extension src) in
884884
get_var var_bindings Var.python @ ["-m"; base ^ "." ^ base]
885885
in
886886
let pythonpath =
@@ -895,7 +895,7 @@ let run_artifact config ~backend ~var_bindings ?scope src =
895895
(String.concat " " cmd);
896896
run_command ~setenv:["PYTHONPATH", pythonpath] cmd
897897
| `Java ->
898-
let target_main = Filename.basename src |> Filename.chop_extension in
898+
let target_main = File.remove_extension (Filename.basename src) in
899899
let cmd =
900900
get_var var_bindings Var.java @ ["-cp"; src -.- "jar"; target_main]
901901
in
@@ -923,7 +923,7 @@ let build_test_deps ~config ~backend files_or_folders nin_ppf items var_bindings
923923
Option.map Mark.remove item.Scan.module_def
924924
= Some (File.basename file)
925925
|| item.Scan.file_name = file
926-
|| Filename.remove_extension item.Scan.file_name = file
926+
|| File.remove_extension item.Scan.file_name = file
927927
in
928928
let items = List.filter filter items in
929929
if items = [] then
@@ -955,10 +955,7 @@ let build_test_deps ~config ~backend files_or_folders nin_ppf items var_bindings
955955
@@ String.Set.add
956956
(match backend with
957957
| `Java | `Python -> t
958-
| _ ->
959-
Filename.remove_extension t
960-
^ "+main"
961-
^ Filename.extension t)
958+
| _ -> File.(remove_extension t ^ ("+main" -.- extension t)))
962959
acc
963960
in
964961
List.fold_left
@@ -1463,34 +1460,30 @@ let main_cmd =
14631460
]
14641461

14651462
let main () =
1463+
let[@inline] exit_with_error excode emit =
1464+
let bt = Printexc.get_raw_backtrace () in
1465+
emit ();
1466+
if Global.options.debug then Printexc.print_raw_backtrace stderr bt;
1467+
exit excode
1468+
in
14661469
Sys.catch_break true;
14671470
try exit (Cmdliner.Cmd.eval' ~catch:false main_cmd) with
14681471
| Catala_utils.Cli.Exit_with n -> exit n
14691472
| Message.CompilerError content ->
1470-
let bt = Printexc.get_raw_backtrace () in
1471-
Message.Content.emit content Error;
1472-
if Catala_utils.Global.options.debug then
1473-
Printexc.print_raw_backtrace stderr bt;
1474-
exit Cmd.Exit.some_error
1473+
exit_with_error Cmd.Exit.some_error
1474+
@@ fun () -> Message.Content.emit content Error
14751475
| Message.CompilerErrors contents ->
1476-
Message.Content.emit_n contents Error;
1477-
exit Cmd.Exit.some_error
1476+
exit_with_error Cmd.Exit.some_error
1477+
@@ fun () -> Message.Content.emit_n contents Error
14781478
| Sys.Break ->
1479-
let bt = Printexc.get_raw_backtrace () in
14801479
Format.fprintf (Message.err_ppf ()) "@.- Interrupted -@.";
1481-
if Printexc.backtrace_status () then Printexc.print_raw_backtrace stderr bt;
1482-
exit 130
1480+
exit_with_error 130 (fun () -> ())
14831481
| Sys_error msg ->
1484-
let bt = Printexc.get_raw_backtrace () in
1485-
Message.Content.emit
1486-
(Message.Content.of_string ("System error: " ^ msg))
1487-
Error;
1488-
if Printexc.backtrace_status () then Printexc.print_raw_backtrace stderr bt;
1489-
exit Cmd.Exit.internal_error
1482+
exit_with_error Cmd.Exit.internal_error
1483+
@@ fun () ->
1484+
Message.Content.(emit (of_string ("System error: " ^ msg)) Error)
14901485
| e ->
1491-
let bt = Printexc.get_raw_backtrace () in
1492-
Message.Content.emit
1493-
(Message.Content.of_string ("Unexpected error: " ^ Printexc.to_string e))
1494-
Error;
1495-
if Printexc.backtrace_status () then Printexc.print_raw_backtrace stderr bt;
1496-
exit Cmd.Exit.internal_error
1486+
exit_with_error Cmd.Exit.internal_error
1487+
@@ fun () ->
1488+
Message.Content.(
1489+
emit (of_string ("Unexpected error: " ^ Printexc.to_string e)) Error)

build_system/clerk_scan.ml

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,9 @@ type item = {
2828
}
2929

3030
let catala_suffix_regex =
31-
Re.(compile (seq [str ".catala_"; group (seq [alpha; alpha]); eos]))
31+
Re.(
32+
compile
33+
(seq [str ".catala_"; group (seq [alpha; alpha]); opt (str ".md"); eos]))
3234

3335
let test_command_args =
3436
let open Re in
@@ -111,7 +113,13 @@ let catala_file (file : File.t) (lang : Catala_utils.Global.backend_lang) : item
111113
((* If there are includes, they must be checked for test scopes as well *)
112114
Lazy.force item.has_scope_tests
113115
|| List.exists
114-
(fun l -> find_test_scope ~lang (Mark.remove l))
116+
(fun l ->
117+
let included_file = Mark.remove l in
118+
if File.check_file included_file = None then
119+
Message.error ~kind:Parsing ~pos:(Mark.get l)
120+
"Included file '%s' is not a regular file or does not exist."
121+
included_file;
122+
find_test_scope ~lang included_file)
115123
item.included_files)
116124
in
117125
{ item with has_scope_tests }
@@ -132,4 +140,4 @@ let target_file_name t =
132140
in
133141
match t.module_def with
134142
| Some m -> dir / String.to_id (Mark.remove m)
135-
| None -> dir / String.to_id (basename t.file_name -.- "")
143+
| None -> dir / String.to_id (remove_extension (basename t.file_name))

compiler/catala_utils/cli.ml

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,10 +43,18 @@ let raw_file =
4343

4444
(* Some helpers for catala sources *)
4545

46-
let extensions = [".catala_fr", Fr; ".catala_en", En; ".catala_pl", Pl]
46+
let extensions =
47+
[
48+
"catala_fr", Fr;
49+
"catala_fr.md", Fr;
50+
"catala_en", En;
51+
"catala_en.md", En;
52+
"catala_pl", Pl;
53+
"catala_pl.md", Pl;
54+
]
4755

4856
let file_lang filename =
49-
List.assoc_opt (Filename.extension filename) extensions
57+
List.assoc_opt (File.extension filename) extensions
5058
|> function
5159
| Some lang -> lang
5260
| None -> (
@@ -152,8 +160,7 @@ module Flags = struct
152160
conv ~docv:"FILE"
153161
( (fun s ->
154162
if s = "-" then Ok `Stdout
155-
else if
156-
Filename.extension s |> String.starts_with ~prefix:".catala"
163+
else if File.extension s |> String.starts_with ~prefix:"catala"
157164
then
158165
Error (`Msg "Output trace file cannot have a .catala extension")
159166
else Ok (`FileName (Global.raw_file s))),

compiler/catala_utils/file.ml

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -212,9 +212,34 @@ let with_formatter_of_opt_file filename_opt f =
212212
| None -> finally (fun () -> flush stdout) (fun () -> f Format.std_formatter)
213213
| Some filename -> with_formatter_of_file filename f
214214

215+
let extension filename =
216+
let file_ext = Filename.extension filename in
217+
let full_extension =
218+
if file_ext = ".md" then
219+
let sub_ext = Filename.extension (Filename.remove_extension filename) in
220+
if sub_ext = "" then "md" else sub_ext ^ ".md"
221+
else file_ext
222+
in
223+
String.remove_prefix ~prefix:"." full_extension
224+
215225
let ( -.- ) file ext =
216-
let base = Filename.remove_extension file in
217-
match ext with "" -> base | ext -> base ^ "." ^ ext
226+
(* file_ext may be empty, "<ext>" when non-md, "md" if only ".md" is present
227+
and "<ext>.md" if a double-extension is present *)
228+
let file_ext = extension file in
229+
if ext = "" then
230+
(* No extension given *)
231+
if file_ext = "" then (* Nothing to do *) file
232+
else
233+
(* Remove the extension and the dot *)
234+
String.(sub file 0 (length file - length file_ext - 1))
235+
else if file_ext = "" then
236+
(* File has no extension, append the new one *)
237+
file ^ "." ^ ext
238+
else
239+
(* Remove the existing extension (minus the dot) and append the new one *)
240+
String.(sub file 0 (length file - length file_ext)) ^ ext
241+
242+
let remove_extension filename = filename -.- ""
218243

219244
let get_main_out_channel ~source_file ~output_file ?ext () =
220245
match output_file, ext with
@@ -241,7 +266,7 @@ let with_secondary_out_channel ~output_file ~ext f =
241266
let file =
242267
match ext.[0] with
243268
| 'a' .. 'z' | 'A' .. 'Z' | '0' .. '9' -> file -.- ext
244-
| _ -> Filename.remove_extension file ^ ext
269+
| _ -> remove_extension file ^ ext
245270
in
246271
Message.debug "Secondary output to %a" format file;
247272
with_formatter_of_file file (fun ppf -> f (Some file) ppf)
@@ -424,7 +449,6 @@ let check_exec t =
424449
425450
let dirname = Filename.dirname
426451
let basename = Filename.basename
427-
let extension t = String.remove_prefix ~prefix:"." (Filename.extension t)
428452
let ( /../ ) a b = parent a / b
429453
430454
let equal a b =

compiler/catala_utils/file.mli

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,9 @@ val dirname : t -> t
148148

149149
val extension : t -> string
150150
(** Like [Filename.extension], but without the leading dot (doesn't, therefore,
151-
differenciate between empty extension and no extension) *)
151+
differenciate between empty extension and no extension). It also considers
152+
catala + md extensions as a single extension, hence
153+
[extension "a_file.catala_en.md"] will return ["catala_en.md"] *)
152154

153155
val parent : t -> t
154156
(** Similar to [dirname], except it strips the last **non-"." or ".."** element
@@ -199,6 +201,9 @@ val ( -.- ) : t -> string -> t
199201
with the given one (which shouldn't start with a dot). No dot is appended if
200202
the provided extension is empty. *)
201203

204+
val remove_extension : t -> string
205+
(** [remove_extension filename] is equivalent to [filename -.- ""] *)
206+
202207
val path_to_list : t -> string list
203208
(** Empty elements or current-directory (".") are skipped in the resulting list *)
204209

compiler/catala_utils/pos.ml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,12 @@ let to_string_short (pos : t) : string =
154154

155155
let to_string_shorter (pos : t) : string =
156156
let s, e = pos.code_pos in
157-
let f = Filename.(remove_extension (basename s.Lexing.pos_fname)) in
157+
let f =
158+
if Filename.extension s.Lexing.pos_fname = ".md" then
159+
Filename.(
160+
remove_extension (remove_extension (basename s.Lexing.pos_fname)))
161+
else Filename.(remove_extension (basename s.Lexing.pos_fname))
162+
in
158163
if s.Lexing.pos_lnum = e.Lexing.pos_lnum then
159164
Printf.sprintf "%s:%d.%d-%d" f s.Lexing.pos_lnum
160165
(s.Lexing.pos_cnum - s.Lexing.pos_bol + 1)

compiler/driver.ml

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,15 @@ open Shared_ast
2020

2121
(** Associates a file extension with its corresponding
2222
{!type: Global.backend_lang} string representation. *)
23-
let extensions = [".catala_fr", "fr"; ".catala_en", "en"; ".catala_pl", "pl"]
23+
let extensions =
24+
[
25+
".catala_fr", "fr";
26+
".catala_fr.md", "fr";
27+
".catala_en", "en";
28+
".catala_en.md", "en";
29+
".catala_pl", "pl";
30+
".catala_pl.md", "pl";
31+
]
2432

2533
let load_modules
2634
options
@@ -122,7 +130,7 @@ let load_modules
122130
(* This preserves the filename capitalisation, which corresponds
123131
to the convention for files related to not-module compilation
124132
artifacts and is used by [depends] below *)
125-
Some Filename.(basename (remove_extension f))
133+
Some (Filename.basename (File.remove_extension f))
126134
else None
127135
in
128136
let module_content =
@@ -544,7 +552,7 @@ module Commands = struct
544552
(String.concat "\\\n"
545553
(Option.value ~default:"stdout" output_file
546554
:: List.map
547-
(fun ext -> Filename.remove_extension source_file ^ ext)
555+
(fun ext -> File.remove_extension source_file ^ ext)
548556
backend_extensions_list))
549557
(String.concat "\\\n" prg.Surface.Ast.program_source_files)
550558
(String.concat "\\\n" prg.Surface.Ast.program_source_files)
@@ -1248,9 +1256,9 @@ module Commands = struct
12481256
match output_file, options.Global.input_src with
12491257
| Some file, _
12501258
| None, (FileName (file : File.t) | Contents (_, (file : File.t))) ->
1251-
let name = Filename.(remove_extension file |> basename) in
1259+
let name = File.remove_extension file |> Filename.basename in
12521260
if Global.options.gen_external then
1253-
String.capitalize_ascii (Filename.remove_extension name)
1261+
String.capitalize_ascii (File.remove_extension name)
12541262
else name
12551263
| None, Stdin _ -> "AnonymousClass"
12561264
in
@@ -1314,7 +1322,7 @@ module Commands = struct
13141322
(fun f ->
13151323
let name =
13161324
String.capitalize_ascii
1317-
(String.to_id Filename.(basename (remove_extension f)))
1325+
(String.to_id (Filename.basename (File.remove_extension f)))
13181326
in
13191327
{
13201328
mod_use_name = name, Pos.void;

compiler/lcalc/to_ocaml.ml

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -712,9 +712,7 @@ let commands = if commands = [] then test_scopes else commands
712712
let modname =
713713
match p.module_name with
714714
| Some (n, _) -> ModuleName.to_string n
715-
| None ->
716-
String.capitalize_ascii
717-
(File.basename (Filename.remove_extension filename))
715+
| None -> String.capitalize_ascii File.(basename filename -.- "")
718716
in
719717
Format.pp_open_vbox fmt 0;
720718
Format.fprintf fmt "open Catala_runtime@,";

compiler/literate/pygmentize.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ let exec () =
4040
| None ->
4141
List.find_map
4242
(fun s ->
43-
match Filename.extension s with
43+
match File.extension s with
4444
| "" -> None
4545
| e -> lang_of_ext (String.sub e 1 (String.length e - 1)))
4646
args

0 commit comments

Comments
 (0)