diff --git a/src/defaults.ts b/src/defaults.ts index 8f51577..6b24e64 100644 --- a/src/defaults.ts +++ b/src/defaults.ts @@ -6,8 +6,9 @@ export function getDefaultValue(typ: Typ): RuntimeValue { case 'TBool': return { kind: 'Bool', value: false }; case 'TInt': - case 'TMoney': return { kind: 'Integer', value: 0 }; + case 'TMoney': + return { kind: 'Money', value: 0 }; case 'TRat': return { kind: 'Decimal', value: 0 }; case 'TDate': { diff --git a/test-case-parser/examples/francais.catala_fr b/test-case-parser/examples/francais.catala_fr new file mode 100644 index 0000000..00b10a0 --- /dev/null +++ b/test-case-parser/examples/francais.catala_fr @@ -0,0 +1,20 @@ +> Module Francais + +```catala-metadata +déclaration champ d'application TestFrançais: + entrée durée_promotion contenu durée + entrée début_promotion contenu date + entrée jour_achat contenu date + entrée prix contenu argent + entrée taux_promo contenu décimal + résultat prix_final contenu argent +``` + +```catala +champ d'application TestFrançais: + définition prix_final égal à + si jour_achat <= début_promotion + ou jour_achat > début_promotion + durée_promotion alors + prix + sinon prix * (1,0 - taux_promo) +``` diff --git a/test-case-parser/examples/test_case_french.catala_fr b/test-case-parser/examples/test_case_french.catala_fr new file mode 100644 index 0000000..f3421f6 --- /dev/null +++ b/test-case-parser/examples/test_case_french.catala_fr @@ -0,0 +1,14 @@ +> Usage de Francais + +```catala +déclaration champ d'application French_test: + résultat test_francais champ d'application Francais.TestFrançais + +champ d'application French_test: + définition test_francais.durée_promotion égal à 7 jour + définition test_francais.début_promotion égal à |2024-01-07| + définition test_francais.jour_achat égal à |2024-01-10| + définition test_francais.prix égal à 100,00 € + définition test_francais.taux_promo égal à 0,2 + assertion (test_francais.prix_final = 80,00 €) +``` diff --git a/test-case-parser/test_case_parser_lib_atd.ml b/test-case-parser/test_case_parser_lib_atd.ml index 5cc7d18..c57e100 100644 --- a/test-case-parser/test_case_parser_lib_atd.ml +++ b/test-case-parser/test_case_parser_lib_atd.ml @@ -339,43 +339,123 @@ let read_test include_dirs options = let tests = import_catala_tests prg in write_stdout Test_case_j.write_test_list tests -let rec print_catala_value ppf = +type lang_strings = { + declaration_scope : string; + output_scope : string; + using_module : string; + definition : string; + assertion : string; + equals : string; + content : string; + scope : string; +} + +let get_lang_strings = function + | Catala_utils.Global.Fr -> { + declaration_scope = "déclaration champ d'application"; + output_scope = "résultat"; + using_module = "Usage de"; + definition = "définition"; + assertion = "assertion"; + equals = "égal à"; + content = "contenu"; + scope = "champ d'application"; + } + | En -> { + declaration_scope = "declaration scope"; + output_scope = "output"; + using_module = "Using"; + definition = "definition"; + assertion = "assertion"; + equals = "equals"; + content = "content"; + scope = "scope"; + } + | _ -> raise (unsupported "unsupported language") + +type duration_units = { + day: string; + month: string; + year: string; + } + +type value_strings = { + true_str: string; + false_str: string; + money_fmt: (int -> int -> unit, Format.formatter, unit) format; (* Format string for money values *) + decimal_sep: char; (* Decimal separator for floating point numbers *) + content_str: string; + duration_units: duration_units; +} + +let get_value_strings = function + | Catala_utils.Global.Fr -> { + true_str = "vrai"; + false_str = "faux"; + money_fmt = format_of_string "%01d,%02d €"; + decimal_sep = ','; + content_str = "contenu"; + duration_units = { + day = "jour"; + month = "mois"; + year = "an"; + }; + } + | En -> { + true_str = "true"; + false_str = "false"; + money_fmt = format_of_string "$%01d.%02d"; + decimal_sep = '.'; + content_str = "content"; + duration_units = { + day = "day"; + month = "month"; + year = "year"; + }; + } + | _ -> raise (unsupported "unsupported language") + +let rec print_catala_value ~lang ppf = let open Format in + let strings = get_value_strings lang in function - | O.Bool b -> pp_print_bool ppf b - | O.Money m -> fprintf ppf "$%01d.%02d" (m/100) (m mod 100) + | O.Bool b -> pp_print_string ppf (if b then strings.true_str else strings.false_str) + | O.Money m -> fprintf ppf strings.money_fmt (m/100) (m mod 100) | O.Integer i -> pp_print_int ppf i - | O.Decimal f -> pp_print_float ppf f + | O.Decimal f -> + let s = sprintf "%g" f in + pp_print_string ppf (String.map (function '.' -> strings.decimal_sep | c -> c) s) | O.Date { year; month; day } -> - fprintf ppf "|%04d-%02d-%02d|" year month day + fprintf ppf "|%04d-%02d-%02d|" year month day | O.Duration { years = 0; months = 0; days = 0 } -> - pp_print_string ppf "0 day" + fprintf ppf "0 %s" strings.duration_units.day | O.Duration { years; months; days } -> - pp_print_list ~pp_sep:(fun ppf () -> fprintf ppf " +@ ") - (fun ppf t -> t ppf) - ppf - (List.filter_map Fun.id - [ if years > 0 then Some (fun ppf -> fprintf ppf "%d year" years) else None; - if months > 0 then Some (fun ppf -> fprintf ppf "%d month" months) else None; - if days > 0 then Some (fun ppf -> fprintf ppf "%d day" days) else None; ]) + pp_print_list ~pp_sep:(fun ppf () -> fprintf ppf " +@ ") + (fun ppf t -> t ppf) + ppf + (List.filter_map Fun.id + [ if years > 0 then Some (fun ppf -> fprintf ppf "%d %s" years strings.duration_units.year) else None; + if months > 0 then Some (fun ppf -> fprintf ppf "%d %s" months strings.duration_units.month) else None; + if days > 0 then Some (fun ppf -> fprintf ppf "%d %s" days strings.duration_units.day) else None; ]) | O.Enum (_, (constr, Some v)) -> - fprintf ppf "@[%s content %a@]" constr print_catala_value v + fprintf ppf "@[%s %s %a@]" constr strings.content_str (print_catala_value ~lang) v | O.Enum (_, (constr, None)) -> - pp_print_string ppf constr + pp_print_string ppf constr | O.Struct (st, fields) -> fprintf ppf "@[%s {@ %a@;<1 -2>}@]" st.struct_name (pp_print_list ~pp_sep:pp_print_space - (fun ppf (fld, v) -> fprintf ppf "-- %s: %a@," fld print_catala_value v)) + (fun ppf (fld, v) -> fprintf ppf "-- %s: %a@," fld (print_catala_value ~lang) v)) fields | O.Array vl -> fprintf ppf "@[[%a]@]" - (pp_print_seq ~pp_sep:(fun ppf () -> fprintf ppf ";@ ") print_catala_value) + (pp_print_seq ~pp_sep:(fun ppf () -> fprintf ppf ";@ ") (print_catala_value ~lang)) (Array.to_seq vl) -let write_catala_test ppf t = +let write_catala_test ppf t lang = let open Format in let open O in + let strings = get_lang_strings lang in let sscope_var = let sname = match Filename.extension t.tested_scope.name with | "" -> t.tested_scope.name @@ -385,28 +465,33 @@ let write_catala_test ppf t = in pp_open_vbox ppf 0; fprintf ppf "@,```catala@,"; - fprintf ppf "@[declaration scope %s:@," t.testing_scope; - fprintf ppf "output %s scope %s@," sscope_var t.tested_scope.name; + fprintf ppf "@[%s %s:@," strings.declaration_scope t.testing_scope; + fprintf ppf "%s %s %s %s@," strings.output_scope sscope_var strings.scope t.tested_scope.name; fprintf ppf "@]@,"; - fprintf ppf "@[scope %s:" t.testing_scope; + fprintf ppf "@[%s %s:" strings.scope t.testing_scope; List.iter (fun (tvar, t_in) -> match t_in.value with | None -> () | Some { value; _ } -> - fprintf ppf "@,@[definition %s.%s equals@ %a@]" - sscope_var tvar print_catala_value value;) + fprintf ppf "@,@[%s %s.%s %s@ %a@]" + strings.definition sscope_var tvar strings.equals + (print_catala_value ~lang) value;) t.test_inputs; List.iter (fun (tvar, t_out) -> match t_out.value with | None -> () | Some { value; _ } -> - fprintf ppf "@,assertion (@[%s.%s =@ %a)@]" - sscope_var tvar print_catala_value value;) + fprintf ppf "@,%s (@[%s.%s =@ %a)@]" + strings.assertion sscope_var tvar (print_catala_value ~lang) value;) t.test_outputs; fprintf ppf "@]@,```@," let write_catala options outfile = let tests = Test_case_j.read_test_list (Yojson.init_lexer ()) (Lexing.from_channel stdin) in + let lang = Catala_utils.Cli.file_lang (match options.Global.input_src with + | Global.FileName f -> f + | Global.Contents (_, f) -> f + | Global.Stdin _ -> "") in let _fname, with_out = File.get_formatter_of_out_channel () ~source_file:(Global.Stdin "") @@ -421,10 +506,10 @@ let write_catala options outfile = else let modname = Filename.chop_extension test.O.tested_scope.name in if not (String.Set.mem modname opened) then - Format.fprintf ppf "> Using %s@," modname; + Format.fprintf ppf "> %s %s@," (get_lang_strings lang).using_module modname; String.Set.add modname opened in - write_catala_test ppf test; + write_catala_test ppf test lang; Format.pp_close_box ppf (); opened) String.Set.empty tests