diff --git a/.gitignore b/.gitignore index 3d3d15407..37782e1fe 100644 --- a/.gitignore +++ b/.gitignore @@ -23,3 +23,4 @@ build.ninja .catleg_secrets.toml *.tmp/ perf.data* +.DS_Store diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index fb0776ec1..65c0985b0 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -106,8 +106,8 @@ The Catala language should be adapted to any legislative text that follows a general-to-specifics statutes order. Therefore, there exists multiple versions of the Catala surface syntax, adapted to the language of the legislative text. -Currently, Catala supports English, French and Polish legislative text via the -`--language=en`, `--language=fr` or `--language=pl` options. +Currently, Catala supports English, French, Polish and Romanian legislative text via the +`--language=en`, `--language=fr`, `--language=pl` or `--language=ro` options. To add support for a new language: diff --git a/Makefile b/Makefile index 5c080dcfb..96074f219 100644 --- a/Makefile +++ b/Makefile @@ -40,7 +40,8 @@ $(PY_VENV_DIR)/stamp: \ runtimes/python/pyproject.toml \ syntax_highlighting/en/pygments/pyproject.toml \ syntax_highlighting/fr/pygments/pyproject.toml \ - syntax_highlighting/pl/pygments/pyproject.toml + syntax_highlighting/pl/pygments/pyproject.toml \ + syntax_highlighting/ro/pygments/pyproject.toml test -d $(PY_VENV_DIR) || python3 -m venv $(PY_VENV_DIR) $(PY_VENV_ACTIVATE) python3 -m pip install -U pip $(PY_VENV_ACTIVATE) python3 -m pip install -U \ @@ -48,7 +49,8 @@ $(PY_VENV_DIR)/stamp: \ -e runtimes/python \ -e syntax_highlighting/en/pygments \ -e syntax_highlighting/fr/pygments \ - -e syntax_highlighting/pl/pygments + -e syntax_highlighting/pl/pygments \ + -e syntax_highlighting/ro/pygments touch $@ dependencies-python: $(PY_VENV_DIR) @@ -358,7 +360,7 @@ clean: rm -rf artifacts inspect: - gitinspector -f ml,mli,mly,iro,tex,catala,catala_en,catala_pl,catala_fr,md,fst,mld --grading + gitinspector -f ml,mli,mly,iro,tex,catala,catala_en,catala_pl,catala_fr,catala_ro,md,fst,mld --grading #> help_clerk : Display the clerk man page help_clerk: diff --git a/build_system/clerk_driver.ml b/build_system/clerk_driver.ml index b6b31fe98..28e890576 100644 --- a/build_system/clerk_driver.ml +++ b/build_system/clerk_driver.ml @@ -132,7 +132,7 @@ let backend_src_extensions = Clerk_rules.OCaml, ["ml"; "mli"]; Clerk_rules.Python, ["py"]; Clerk_rules.Java, ["java"]; - Clerk_rules.Tests, ["catala_en"; "catala_fr"; "catala_pl"]; + Clerk_rules.Tests, ["catala_en"; "catala_fr"; "catala_pl"; "catala_ro"]; ] let backend_obj_extensions = @@ -627,7 +627,8 @@ let build_direct_targets let is_module = ext = "" in match List.assoc_opt ext extensions_backend, ext with | Some bk, _ -> Left (ensure_target_dir (backend_subdir bk) t) - | None, ("catala_en" | "catala_fr" | "catala_pl") -> Left t + | None, ("catala_en" | "catala_fr" | "catala_pl" | "catala_ro") -> + Left t | None, ("exe" | "jar") -> let t, backend = match ext, lastdirname t with @@ -1050,7 +1051,7 @@ let typecheck_cmd = Clerk_rules.run_ninja ~config ~enabled_backends:[Clerk_rules.Tests] ~autotest:false ~ninja_flags (fun nin_ppf items var_bindings -> Nj.format_def nin_ppf - (Nj.Default (Nj.Default.make ["Stdlib_fr@src"; "Stdlib_en@src"])); + (Nj.Default (Nj.Default.make ["Stdlib_fr@src"; "Stdlib_en@src"; "Stdlib_ro@src"])); items, var_bindings) in let catala_flags = get_var var_bindings Var.catala_flags in @@ -1330,6 +1331,7 @@ let start_cmd = "@runtime-ocaml"; "Stdlib_fr@ocaml-module"; "Stdlib_en@ocaml-module"; + "Stdlib_ro@ocaml-module"; ])); 0) in diff --git a/build_system/dune b/build_system/dune index 8c683cc31..bf55edacc 100644 --- a/build_system/dune +++ b/build_system/dune @@ -63,7 +63,7 @@ (run sh -c - "for page in '' $(%{bin:clerk} 2>&1 | sed -n \"s/\\(^\\|'\\)[^']*\\('\\|$\\)/ /gp;q\"); do\n echo '(rule (alias man) (action (with-stdout-to clerk'${page:+-$page}'.1 (run \%{bin:clerk} '$page' --help=groff))))'\n done")))) + "for page in '' $(%{bin:clerk} 2>&1 | sed -E \"s/[^']*'([^']*)'[^']*/\\1 /g\" | head -1); do\n echo '(rule (alias man) (action (with-stdout-to clerk'${page:+-$page}'.1 (run \%{bin:clerk} '$page' --help=groff))))'\n done")))) (install (section man) diff --git a/compiler/catala_utils/cli.ml b/compiler/catala_utils/cli.ml index e934171ea..3e92ab0e6 100644 --- a/compiler/catala_utils/cli.ml +++ b/compiler/catala_utils/cli.ml @@ -21,7 +21,7 @@ module G = Global (* Manipulation of types used by flags & options *) (** Associates a {!type: Global.backend_lang} with its string represtation. *) -let languages = ["en", En; "fr", Fr; "pl", Pl] +let languages = ["en", En; "fr", Fr; "pl", Pl; "ro", Ro] let language_code = let rl = List.map (fun (a, b) -> b, a) languages in @@ -43,7 +43,8 @@ let raw_file = (* Some helpers for catala sources *) -let extensions = [".catala_fr", Fr; ".catala_en", En; ".catala_pl", Pl] +let extensions = + [".catala_fr", Fr; ".catala_en", En; ".catala_pl", Pl; ".catala_ro", Ro] let file_lang filename = List.assoc_opt (Filename.extension filename) extensions diff --git a/compiler/catala_utils/global.ml b/compiler/catala_utils/global.ml index 68c9c88d5..cedcdc3c3 100644 --- a/compiler/catala_utils/global.ml +++ b/compiler/catala_utils/global.ml @@ -16,7 +16,7 @@ type file = string type raw_file = file -type backend_lang = En | Fr | Pl +type backend_lang = En | Fr | Pl | Ro type when_enum = Auto | Always | Never type message_format_enum = Human | GNU | Lsp type trace_format_enum = Human | JSON @@ -113,4 +113,4 @@ let enforce_options let input_src_file = function FileName f | Contents (_, f) | Stdin f -> f let raw_file f = f -let has_localised_stdlib = function En | Fr -> true | _ -> false +let has_localised_stdlib = function En | Fr | Ro -> true | _ -> false diff --git a/compiler/catala_utils/global.mli b/compiler/catala_utils/global.mli index 261a31ff4..424248668 100644 --- a/compiler/catala_utils/global.mli +++ b/compiler/catala_utils/global.mli @@ -24,7 +24,7 @@ type raw_file = private file (** A file name that has not yet been resolved, [options.path_rewrite] must be called on it *) -type backend_lang = En | Fr | Pl +type backend_lang = En | Fr | Pl | Ro (** The usual auto/always/never option argument *) type when_enum = Auto | Always | Never diff --git a/compiler/desugared/name_resolution.ml b/compiler/desugared/name_resolution.ml index 52b2ef84c..0e86591ed 100644 --- a/compiler/desugared/name_resolution.ml +++ b/compiler/desugared/name_resolution.ml @@ -1331,12 +1331,20 @@ let process_use_item (** {1 API} *) -let empty_module_ctxt _lang = +let empty_module_ctxt lang = { current_revpath = []; typedefs = Ident.Map.empty; field_idmap = Ident.Map.empty; - constructor_idmap = Ident.Map.empty; + constructor_idmap = + (let present = EnumName.Map.singleton Expr.option_enum Expr.some_constr in + let absent = EnumName.Map.singleton Expr.option_enum Expr.none_constr in + Ident.Map.of_list + (match lang with + | Global.En -> ["Present", present; "Absent", absent] + | Global.Fr -> ["Présent", present; "Absent", absent] + | Global.Pl -> ["Obecny", present; "Nieobecny", absent] + | Global.Ro -> ["Prezent", present; "Absent", absent])); topdefs = Ident.Map.empty; used_modules = Ident.Map.empty; is_external = false; diff --git a/compiler/driver.ml b/compiler/driver.ml index 856b41aff..72e22b82d 100644 --- a/compiler/driver.ml +++ b/compiler/driver.ml @@ -20,7 +20,13 @@ open Shared_ast (** Associates a file extension with its corresponding {!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"; + ".catala_ro", "ro"; + ] let load_modules options diff --git a/compiler/literate/html.ml b/compiler/literate/html.ml index f42cdcf92..fd33a9b5e 100644 --- a/compiler/literate/html.ml +++ b/compiler/literate/html.ml @@ -243,6 +243,7 @@ let ast_to_html | C.Fr -> "Sommaire" | C.En -> "Table of contents" | C.Pl -> "Spis treści." + | C.Ro -> "Cuprins" in Format.fprintf fmt diff --git a/compiler/literate/latex.ml b/compiler/literate/latex.ml index 8298842b4..f6796d217 100644 --- a/compiler/literate/latex.ml +++ b/compiler/literate/latex.ml @@ -161,7 +161,11 @@ codes={\catcode`\$=3\catcode`\^=7} \[\star\star\star\] \clearpage |latex} - (match language with Fr -> "french" | En -> "english" | Pl -> "polish") + (match language with + | Fr -> "french" + | En -> "english" + | Pl -> "polish" + | Ro -> "romanian") (match language with Fr -> "\\setmainfont{Marianne}" | _ -> "") (* for France, we use the official font of the French state design system https://gouvfr.atlassian.net/wiki/spaces/DB/pages/223019527/Typographie+-+Typography *) @@ -172,7 +176,8 @@ codes={\catcode`\$=3\catcode`\^=7} (pre_latexify (literal_disclaimer_and_link language)) (literal_source_files language) (String.concat - ((match language with Fr -> " ;" | En -> ";" | Pl -> ";") ^ "\n") + ((match language with Fr -> " ;" | En -> ";" | Pl -> ";" | Ro -> ";") + ^ "\n") (List.map (fun filename -> let mtime = (Unix.stat filename).Unix.st_mtime in @@ -308,6 +313,7 @@ let rec law_structure_to_latex | Fr -> "Métadonnées" | En -> "Metadata" | Pl -> "Metadane" + | Ro -> "Metadate" in let start_line = Pos.get_start_line (Mark.get c) + 1 in let filename = Pos.get_file (Mark.get c) in diff --git a/compiler/literate/literate_common.ml b/compiler/literate/literate_common.ml index 8fd04f066..9c68d4863 100644 --- a/compiler/literate/literate_common.ml +++ b/compiler/literate/literate_common.ml @@ -21,16 +21,19 @@ let literal_title = function | En -> "Legislative text implementation" | Fr -> "Implémentation de texte législatif" | Pl -> "Implementacja tekstów legislacyjnych" + | Ro -> "Implementarea textului legislativ" let literal_generated_by = function | En -> "Document generated by" | Fr -> "Document généré par" | Pl -> "Dokument wygenerowany przez" + | Ro -> "Document generat de" let literal_source_files = function | En -> "Source files weaved in this document" | Fr -> "Fichiers sources tissés dans ce document" | Pl -> "Pliki źródłowe w tym dokumencie" + | Ro -> "Fișiere sursă integrate în acest document" let literal_disclaimer_and_link = function | En -> @@ -52,16 +55,24 @@ let literal_disclaimer_and_link = function legislacyjny z kodem komputerowym, który go tłumaczy. Więcej informacji \ na temat metodologii i sposobu odczytywania kodu można znaleźć na stronie \ [https://catala-lang.org](https://catala-lang.org)" + | Ro -> + "Acest document a fost produs dintr-un set de fișiere sursă scrise în \ + limbajul de programare Catala, care combină textul legislativ cu codul \ + informatic care îl traduce. Pentru mai multe informații despre \ + metodologie și despre cum să citiți codul, vă rugăm să vizitați \ + [https://catala-lang.org](https://catala-lang.org)." let literal_last_modification = function | En -> "last modification" | Fr -> "dernière modification le" | Pl -> "ostatnia modyfikacja" + | Ro -> "ultima modificare" let get_language_extension = function | Fr -> "catala_fr" | En -> "catala_en" | Pl -> "catala_pl" + | Ro -> "catala_ro" let raise_failed_pandoc (command : string) (error_code : int) : 'a = Message.error diff --git a/compiler/literate/pygmentize.ml b/compiler/literate/pygmentize.ml index 5f46b50c7..97759d029 100644 --- a/compiler/literate/pygmentize.ml +++ b/compiler/literate/pygmentize.ml @@ -23,6 +23,7 @@ let lang_of_ext s = | "catala_en" -> Some Global.En | "catala_fr" -> Some Global.Fr | "catala_pl" -> Some Global.Pl + | "catala_ro" -> Some Global.Ro | _ -> failwith "Unknown Catala dialect" else None diff --git a/compiler/plugins/explain.ml b/compiler/plugins/explain.ml index 797cd9c5d..2548e3e79 100644 --- a/compiler/plugins/explain.ml +++ b/compiler/plugins/explain.ml @@ -1210,8 +1210,12 @@ let expr_to_dot_label0 : (a, 't) gexpr -> unit = fun lang ctx env -> - let xlang ~en ?(pl = en) ~fr () = - match lang with Global.Fr -> fr | Global.En -> en | Global.Pl -> pl + let xlang ~en ?(pl = en) ?(ro = en) ~fr () = + match lang with + | Global.Fr -> fr + | Global.En -> en + | Global.Pl -> pl + | Global.Ro -> ro in let rec aux_value : type a t. Format.formatter -> (a, t) gexpr -> unit = fun ppf e -> Print.UserFacing.value ~fallback lang ppf e diff --git a/compiler/shared_ast/print.ml b/compiler/shared_ast/print.ml index 2b44cb609..2576c04e6 100644 --- a/compiler/shared_ast/print.ml +++ b/compiler/shared_ast/print.ml @@ -1005,10 +1005,10 @@ module UserFacing = struct https://en.wikipedia.org/wiki/Wikipedia:Manual_of_Style/Dates_and_numbers#Grouping_of_digits https://fr.wikipedia.org/wiki/Wikip%C3%A9dia:Conventions_concernant_les_nombres#Pour_un_comptage_ou_une_mesure *) let bigsep (lang : Global.backend_lang) = - match lang with En -> ",", 3 | Fr -> " ", 3 | Pl -> ",", 3 + match lang with En -> ",", 3 | Fr -> " ", 3 | Pl -> ",", 3 | Ro -> ".", 3 let decsep (lang : Global.backend_lang) = - match lang with En -> "." | Fr -> "," | Pl -> "." + match lang with En -> "." | Fr -> "," | Pl -> "." | Ro -> "," let unit (_lang : Global.backend_lang) ppf () = Format.pp_print_string ppf "()" @@ -1022,6 +1022,8 @@ module UserFacing = struct | Fr, false -> "faux" | Pl, true -> "prawda" | Pl, false -> "falsz" + | Ro, true -> "adevărat" + | Ro, false -> "fals" in Format.pp_print_string ppf s @@ -1042,7 +1044,9 @@ module UserFacing = struct let num = Z.abs n in let units, cents = Z.div_rem num (Z.of_int 100) in if Z.sign n < 0 then Format.pp_print_char ppf '-'; - (match lang with En -> Format.pp_print_string ppf "$" | Fr | Pl -> ()); + (match lang with + | En -> Format.pp_print_string ppf "$" + | Fr | Pl | Ro -> ()); integer lang ppf units; Format.pp_print_string ppf (decsep lang); Format.fprintf ppf "%02d" (Z.to_int (Z.abs cents)); @@ -1050,6 +1054,7 @@ module UserFacing = struct | En -> () | Fr -> Format.pp_print_string ppf " €" | Pl -> Format.pp_print_string ppf " PLN" + | Ro -> Format.pp_print_string ppf " RON" let decimal (lang : Global.backend_lang) ppf r = let den = Q.den r in @@ -1094,7 +1099,7 @@ module UserFacing = struct let y, m, d = Catala_runtime.date_to_years_months_days d in match lang with | En | Pl -> Format.fprintf ppf "%04d-%02d-%02d" y m d - | Fr -> Format.fprintf ppf "%02d/%02d/%04d" d m y + | Fr | Ro -> Format.fprintf ppf "%02d/%02d/%04d" d m y let duration (lang : Global.backend_lang) ppf dr = let y, m, d = Catala_runtime.duration_to_years_months_days dr in @@ -1104,11 +1109,13 @@ module UserFacing = struct | [] -> [] in let splur n s = if abs n > 1 then n, s ^ "s" else n, s in + let ro_plur n s_sing s_plur = if abs n > 1 then n, s_plur else n, s_sing in Format.pp_print_char ppf '['; (match lang with | En -> [splur y "year"; splur m "month"; splur d "day"] | Fr -> [splur y "an"; m, "mois"; splur d "jour"] - | Pl -> [y, "rok"; m, "miesiac"; d, "dzien"]) + | Pl -> [y, "rok"; m, "miesiac"; d, "dzien"] + | Ro -> [ro_plur y "an" "ani"; ro_plur m "lună" "luni"; ro_plur d "zi" "zile"]) |> filter0 |> Format.pp_print_list ~pp_sep:(fun ppf () -> Format.pp_print_string ppf ", ") diff --git a/compiler/surface/dune b/compiler/surface/dune index a0a89c876..cfa2c8506 100644 --- a/compiler/surface/dune +++ b/compiler/surface/dune @@ -7,7 +7,8 @@ ((pps sedlex.ppx) lexer_en lexer_fr - lexer_pl)))) + lexer_pl + lexer_ro)))) (rule (copy ast.mli ast.ml)) @@ -27,6 +28,11 @@ lexer_pl.ml (run %{bin:cppo} %{dep:lexer_pl.cppo.ml} %{dep:lexer.cppo.ml}))) +(rule + (with-stdout-to + lexer_ro.ml + (run %{bin:cppo} %{dep:lexer_ro.cppo.ml} %{dep:lexer.cppo.ml}))) + (menhir (modules tokens) (explain false) diff --git a/compiler/surface/lexer_ro.cppo.ml b/compiler/surface/lexer_ro.cppo.ml new file mode 100644 index 000000000..5de643183 --- /dev/null +++ b/compiler/surface/lexer_ro.cppo.ml @@ -0,0 +1,164 @@ +(* This file is part of the Catala compiler, a specification language for tax and social benefits + computation rules. Copyright (C) 2020 Inria, contributor: Jan Cavel + + Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + in compliance with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software distributed under the License + is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + or implied. See the License for the specific language governing permissions and limitations under + the License. *) + +(* Defining the lexer macros for Romanian *) + +(* Tokens and their corresponding sedlex regexps *) + +#define MS_SCOPE "scop" +#define MS_CONSEQUENCE "consecință" +#define MR_CONSEQUENCE "consecin", 0x021B, 0x0103 +#define MS_DATA "date" +#define MS_DEPENDS "depinde de" +#define MR_DEPENDS "depinde", space_plus, "de" +#define MS_DECLARATION "declarație" +#define MR_DECLARATION "declara", 0x021B, "ie" +#define MS_CONTEXT "context" +#define MS_DECREASING "descrescător" +#define MR_DECREASING "descresc", 0x0103, "tor" +#define MS_INCREASING "crescător" +#define MR_INCREASING "cresc", 0x0103, "tor" +#define MS_OF "de" +#define MS_LIST "listă de" +#define MR_LIST "list", 0x0103, space_plus, "de" +#define MS_OPTION "opțional de" +#define MR_OPTION "op", 0x021B, "ional", space_plus, "de" +#define MS_CONTAINS "conține" +#define MR_CONTAINS "con", 0x021B, "ine" +#define MS_ENUM "enumerare" +#define MS_SUM "sumă" +#define MR_SUM "sum", 0x0103 +#define MS_FILLED "îndeplinit" +#define MR_FILLED 0x00EE, "ndeplinit" +#define MS_DEFINITION "definiție" +#define MR_DEFINITION "defini", 0x021B, "ie" +#define MS_STATE "stare" +#define MS_LABEL "etichetă" +#define MR_LABEL "etichet", 0x0103 +#define MS_EXCEPTION "excepție" +#define MR_EXCEPTION "excep", 0x021B, "ie" +#define MS_DEFINED_AS "egal" +#define MS_MATCH "potrivește" +#define MR_MATCH "potrive", 0x0219, "te" +#define MS_WILDCARD "orice" +#define MS_TYPE "tip" +#define MS_WITH "cu model" +#define MR_WITH "cu", space_plus, "model" +#define MS_UNDER_CONDITION "în condiția" +#define MR_UNDER_CONDITION 0x00EE, "n", space_plus, "condi", 0x021B, "ia" +#define MS_IF "dacă" +#define MR_IF "dac", 0x0103 +#define MS_THEN "atunci" +#define MS_ELSE "altfel" +#define MS_CONDITION "condiție" +#define MR_CONDITION "condi", 0x021B, "ie" +#define MS_CONTENT "conținut" +#define MR_CONTENT "con", 0x021B, "inut" +#define MS_STRUCT "structură" +#define MR_STRUCT "structur", 0x0103 +#define MS_ASSERTION "aserțiune" +#define MR_ASSERTION "aser", 0x021B, "iune" +#define MS_WITH_V "cu" +#define MS_FOR "pentru" +#define MS_ALL "toți" +#define MR_ALL "to", 0x021B, "i" +#define MS_WE_HAVE "avem" +#define MS_RULE "regulă" +#define MR_RULE "regul", 0x0103 +#define MS_LET "fie" +#define MS_EXISTS "există" +#define MR_EXISTS "exist", 0x0103 +#define MS_IN "în" +#define MR_IN 0x00EE, "n" +#define MS_AMONG "printre" +#define MS_COMBINE "combină" +#define MR_COMBINE "combin", 0x0103 +#define MS_MAP_EACH "aplică fiecare" +#define MR_MAP_EACH "aplic", 0x0103, space_plus, "fiecare" +#define MS_TO "la" +#define MS_SUCH "astfel" +#define MS_THAT "că" +#define MR_THAT "c", 0x0103 +#define MS_AND "și" +#define MR_AND 0x0219, "i" +#define MS_OR "sau" +#define MS_XOR "sau exclusiv" +#define MR_XOR "sau", space_plus, "exclusiv" +#define MS_NOT "nu" +#define MS_MAXIMUM "maxim" +#define MS_MINIMUM "minim" +#define MS_IS "este" +#define MS_OR_IF_LIST_EMPTY "sau dacă lista este goală" +#define MR_OR_IF_LIST_EMPTY "sau", space_plus, "dac", 0x0103, space_plus, "lista", space_plus, "este", space_plus, "goal", 0x0103 +#define MS_BUT_REPLACE "dar înlocuiește" +#define MR_BUT_REPLACE "dar", space_plus, 0x00EE, "nlocuie", 0x0219, "te" +#define MS_INITIALLY "inițial" +#define MR_INITIALLY "ini", 0x021B, "ial" +#define MS_YEAR "an" +#define MS_MONTH "lună" +#define MR_MONTH "lun", 0x0103 +#define MS_DAY "zi" +#define MS_TRUE "adevărat" +#define MR_TRUE "adev", 0x0103, "rat" +#define MS_FALSE "fals" +#define MS_INPUT "intrare" +#define MS_OUTPUT "ieșire" +#define MR_OUTPUT "ie", 0x0219, "ire" +#define MS_INTERNAL "intern" + +(* Specific delimiters *) + +#define MS_MONEY_OP_SUFFIX "RON" +#define MC_DECIMAL_SEPARATOR ',' +#define MR_MONEY_PREFIX "" +#define MR_MONEY_DELIM '.' +#define MR_MONEY_SUFFIX Star hspace, "RON" + +(* Builtin types *) + +#define MS_INTEGER "întreg" +#define MR_INTEGER 0x00EE, "ntreg" +#define MS_MONEY "bani" +#define MS_DECIMAL "zecimal" +#define MS_DATE "dată" +#define MR_DATE "dat", 0x0103 +#define MS_DURATION "durată" +#define MR_DURATION "durat", 0x0103 +#define MS_BOOLEAN "boolean" +#define MS_POSITION "position_source" + +(* Builtin constructors *) + +#define MS_PRESENT "Prezent" +#define MS_ABSENT "Absent" + +(* Builtin functions *) + +#define MS_Round "rotunjește" +#define MR_Round "rotunje", 0x0219, "te" +#define MS_Impossible "imposibil" +#define MS_Cardinal "număr" +#define MR_Cardinal "num", 0x0103, "r" + +(* Directives *) + +#define MR_LAW_INCLUDE "Include" +#define MR_MODULE_DEF "Modul" +#define MR_MODULE_USE "Folosind" +#define MR_MODULE_ALIAS "ca" +#define MR_EXTERNAL "extern" +#define MX_AT_PAGE \ + '@', Star hspace, "p.", Star hspace, Plus digit -> \ + let s = Utf8.lexeme lexbuf in \ + let i = String.index s '.' in \ + AT_PAGE (int_of_string (String.trim (String.sub s i (String.length s - i)))) diff --git a/compiler/surface/lexer_ro.mli b/compiler/surface/lexer_ro.mli new file mode 100644 index 000000000..5a0fa01df --- /dev/null +++ b/compiler/surface/lexer_ro.mli @@ -0,0 +1,17 @@ +(* This file is part of the Catala compiler, a specification language for tax + and social benefits computation rules. Copyright (C) 2020 Inria, + contributor: Jan Cavel + + Licensed under the Apache License, Version 2.0 (the "License"); you may not + use this file except in compliance with the License. You may obtain a copy of + the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + License for the specific language governing permissions and limitations under + the License. *) + +include Lexer_common.LocalisedLexer diff --git a/compiler/surface/parser_driver.ml b/compiler/surface/parser_driver.ml index c077becb9..6f9c8dbbb 100644 --- a/compiler/surface/parser_driver.ml +++ b/compiler/surface/parser_driver.ml @@ -288,12 +288,14 @@ end module Parser_En = ParserAux (Lexer_en) module Parser_Fr = ParserAux (Lexer_fr) module Parser_Pl = ParserAux (Lexer_pl) +module Parser_Ro = ParserAux (Lexer_ro) let localised_parser : Global.backend_lang -> lexbuf -> Ast.source_file = function | En -> Parser_En.commands_or_includes | Fr -> Parser_Fr.commands_or_includes | Pl -> Parser_Pl.commands_or_includes + | Ro -> Parser_Ro.commands_or_includes (** Lightweight lexer for dependency *) @@ -303,6 +305,7 @@ let lines (file : File.t) (language : Global.backend_lang) = | En -> Lexer_en.lex_line | Fr -> Lexer_fr.lex_line | Pl -> Lexer_pl.lex_line + | Ro -> Lexer_ro.lex_line in let input = open_in file in try diff --git a/doc/syntax/Makefile b/doc/syntax/Makefile index 4459d8c38..c8dd6a1ca 100644 --- a/doc/syntax/Makefile +++ b/doc/syntax/Makefile @@ -1,4 +1,4 @@ -TARGETS = syntax.pdf syntax_en.pdf syntax_fr.pdf +TARGETS = syntax.pdf syntax_en.pdf syntax_fr.pdf syntax_ro.pdf TYPST_FLAGS = --font-path fonts/ --ignore-system-fonts diff --git a/doc/syntax/syntax_ro.catala_ro b/doc/syntax/syntax_ro.catala_ro new file mode 100644 index 000000000..2264a042f --- /dev/null +++ b/doc/syntax/syntax_ro.catala_ro @@ -0,0 +1,278 @@ +Verificarea corectitudinii tuturor exemplelor din cheat-sheet. + +Acest fișier ar trebui să corespundă cât mai aproape cu syntax_ro.tex. +Este de asemenea util pentru verificarea evidențierii sintaxei. + +# Programare literată + +(nu ajungem să definim module fictive doar pentru a testa aceste 3 cazuri) + +``` +# > Modul ModulBar +# > Folosind ModulFoo +# > Include: foo.catala_ro +``` + +```catala-test-cli +$ catala typecheck +┌─[RESULT]─ +│ Typechecking successful! +└─ +``` + +# Literale și tipuri + +```catala +declarație x conținut boolean egal adevărat +declarație x conținut boolean egal fals +declarație x conținut întreg egal 65536 +declarație x conținut zecimal egal 65536,262144 +declarație x conținut zecimal egal 37% +declarație x conținut bani egal 1.234.567,89 RON +declarație x conținut dată egal |2024-04-01| +declarație x conținut durată egal 254 zi + -4 lună + 1 an +declarație x conținut opțional de bani egal Prezent conținut 34 RON +declarație x conținut opțional de bani egal Absent +declarație x conținut listă de întreg egal [ 12; 24; 36 ] +declarație x conținut listă de orice de tip t depinde de a conținut întreg egal [] +declarație x conținut (dată,bani,zecimal) egal (|2024-04-01|, 30 RON, 1%) +declarație f conținut zecimal depinde de + x conținut bani, + y conținut zecimal + egal y * x / 12,0 RON + +declarație x conținut Struct1 egal Struct1 { -- fld1: 9 -- fld2: 7% } +declarație x conținut Enum1 egal Case1 conținut 12 +declarație x conținut Enum1 egal Case2 +``` + +# Operatori și funcții predefinite + +```catala +declarație x conținut întreg egal + fie x egal ( + nu a, a și b, + a sau b, # "sau altfel" + a sau exclusiv b # sau exclusiv + ) în + fie x egal ( + - a, a + b, a - b, + a * b, a / b + ) în + fie x egal ( + a = b, a < b, a <= b, + a != b, a > b, a >= b + ) în + fie x egal ( + zecimal de 44, + bani de 23,15 + ) în + fie x egal ( + rotunjește de 9,99 RON + ) în + fie x egal ( + Date.accesează_lună de |2003-01-02|, + Date.prima_zi_a_lunii de |2003-01-02| + ) în + fie x egal ( + a +! b, # întreg + a +. b, # zecimal + a +RON b, # bani + a +^ b # durată + ) în + 0 +``` + +# Declararea metadatelor + +```catala +declarație structură Struct1: + date fld1 conținut întreg + date fld2 conținut zecimal + +declarație enumerare Enum1: + -- Case1 conținut întreg + -- Case2 + +# #[test] +## Documentație pentru Scope1 +declarație scop Scope1: + intern var1 conținut întreg + stare before + stare after + intern var2 condiție + sub1 scop Scope0 + + ieșire var3 conținut întreg + intrare var4 conținut întreg + intrare ieșire var5 conținut întreg + context var6 conținut întreg + context ieșire var7 conținut întreg + ieșire sub2 scop Scope0 + +declarație const conținut zecimal + egal 17,1 + +declarație square conținut zecimal + depinde de x conținut zecimal + egal x * x +``` + +# Expresii + +```catala +declarație x conținut întreg egal + fie x egal fie x egal 36 - 5 în 0 + în + fie x egal + potrivește expr cu model + -- Case1 conținut x : 0 + -- Case2 : 0 + -- orice : 0 + în + fie x egal imposibil în + fie x egal #[debug.print = "message"] 0 în + fie x egal + expr cu model Case1 + în + fie x egal + expr cu model Case1 conținut x + și x >= 2 + în + fie x egal + struc1 dar înlocuiește { -- fld2: 8% } + în + fie x egal + struc1.fld2 + în + fie x egal + tuple1.2 + în + fie x egal + sub1.var0 + în + fie x egal + f de 44,50 RON, 1/3 + în + fie x egal + ieșire de Scope1 cu + { -- fld1: 9 -- fld2: 15% } + în + fie x egal + dacă 0 atunci 0 altfel 0 + în + fie x egal + var1 stare before + în + 0 +``` + +# Definiția scopului + +```catala +scop Scope1: + definiție x egal 0 + +scop Scope1 + în condiția var1 >= 2: + + definiție var1 egal 0 + + definiție var1 + în condiția 0 + consecință egal 0 + + regulă var2 + în condiția var1 >= 2 + consecință îndeplinit + + regulă var2 în condiția fals + consecință nu îndeplinit + + definiție f de x, y egal 0 + + etichetă lbl1 definiție var1 egal 0 + + excepție lbl1 definiție var1 egal 0 + + excepție definiție var1 egal 0 + + definiție var1 + stare before + egal 0 + + aserțiune 0 + + dată rotunjește descrescător + dată rotunjește crescător +``` + +# Operații pe liste + +```catala +declarație x conținut întreg egal + fie x egal + lst conține 3 + în + fie x egal + există x printre lst astfel că x > 2 + în + fie x egal + pentru toți x printre lst avem x > 2 + în + fie x egal + aplică fiecare x printre lst la x + 2 + în + fie x egal + listă de x printre lst astfel că x > 2 + în + fie x egal + aplică fiecare x printre lst astfel că x > 2 + la x - 2 + în + fie x egal + aplică fiecare (x, y) printre (lst1, lst2) la x + y + în + fie x egal + lst1 ++ lst2 + în + fie x egal + sumă întreg de lst + în + fie x egal + număr de lst + în + fie x egal + maxim de lst + sau dacă lista este goală atunci -1 + în + fie x egal + conținut de x printre lst + astfel că x * x este minim + sau dacă lista este goală atunci -1 + în + fie x egal + combină toți x printre lst + în acc inițial 0 + cu acc + x + în + 0 +``` + + +Este normal ca testul de mai jos să returneze o eroare de rezoluție sau de tip, vrem doar +să ne asigurăm că *sintaxa* este corectă. + +```catala-test-cli +$ catala typecheck +┌─[ERROR]─ +│ +│ No scope named Scope0 found +│ +├─➤ doc/syntax/syntax_ro.catala_ro:105.13-105.19: +│ │ +│ 105 │ sub1 scop Scope0 +│ │ ‾‾‾‾‾‾ +└─ Declararea metadatelor +#return code 123# +``` diff --git a/doc/syntax/syntax_ro.typ b/doc/syntax/syntax_ro.typ new file mode 100644 index 000000000..e41966fab --- /dev/null +++ b/doc/syntax/syntax_ro.typ @@ -0,0 +1,148 @@ +#import "cheat-sheet.typ" + +#import "catala_syntax_hl.typ": setup +#show: setup + +#let prog_lit = cheat-sheet.syntax-doc([Programare literată], +```catala-ro +# Titlu +### Sub-subtitlu +```, [Titlu], +raw("```catala ```catala-metadata\n``` ```"), +[Bloc cod / metadata], +```catala-ro +> Modul Mdl +```, [Declarație modul], +```catala-ro +> Folosind Mdl ca M +```, [Import+alias modul], +```catala-ro +> Include: foo.catala_ro, +```, [Includere fișier], +{ + show raw: text.with(size: 0.9em) + raw("```catala-test-cli\n$ catala interpret --scope Scop1\n```") +}, [Test interfață linie comandă], +) + +#let lit_types = cheat-sheet.syntax-doc([Literali și tipuri], +```catala-ro-code +adevărat fals +```, +```catala-ro-code +boolean +```, +```catala-ro-code +65.536 +```, +```catala-ro-code +întreg +```, +```catala-ro-code +65536,262144 37% +```, +```catala-ro-code +zecimal +```, +```catala-ro-code +1.234.567,89 RON +```, +```catala-ro-code +bani +```, +```catala-ro-code +|2024-04-01| +```, +```catala-ro-code +dată +```, +```catala-ro-code +254 zi 3 lună +```, +```catala-ro-code +durată +```, +```catala-ro-code +"Bună ziua!" +```, +```catala-ro-code +text +```, +) + +#let stmt_struct = cheat-sheet.syntax-doc([Instrucțiuni și structuri], +```catala-ro-code +fie x egal 36 + 5 în ... +```, [Legare locală], +```catala-ro-code +potrivește expr cu model +-- Cons1: ... +-- Cons2 de x: ... +-- orice: ... +```, [Potrivire model], +```catala-ro-code +expr cu Model1 +dar înlocuiește { + -- fld: val; + -- fld1: val1 +} +```, [Actualizare struct], +```catala-ro-code +dacă expr +atunci expr +altfel expr +```, [Condiție], +```catala-ro-code +nume_structură { + -- câmp1: val1 + -- câmp2: val2 +} +```, [Constructor struct], +```catala-ro-code +Nume_enumerare conținut valoare +```, [Injecție enumerare], +) + +#let collections = cheat-sheet.syntax-doc([Colecții], +```catala-ro-code +[ 12; 24; 36 ] +```, [Liste (literal)], +```catala-ro-code +x printre [ 1; 2; 3 ] +```, [Apartenență la listă], +```catala-ro-code +listă goală +```, [Test listă goală], +```catala-ro-code +aplică fiecare f la list +```, [Funcția `map`], +```catala-ro-code +combină f cu e inițial pentru list +```, [Fold: `f(f(f(e,x1),x2),x3)`], +```catala-ro-code +listă de întreg +```, [Tip listă], +```catala-ro-code +număr de elems +```, [Cardinal (dimensiune listă)], +```catala-ro-code +sumă întreg de elems +```, [Suma elementelor din listă], +```catala-ro-code +maxim de coll + sau dacă lista este goală -1 +```, [Maxim, cu valoare implicită], +```catala-ro-code +minim de ... +```, [Minim], +```catala-ro-code +arg_maxim de f printre elems +```, [Cel mai mare argument], +```catala-ro-code +arg_minim de ... +```, [Cel mai mic argument], +) + +// Continuarea ar fi similară pentru restul elementelor de sintaxă... + +#cheat-sheet.cheat-sheet(none, prog_lit, lit_types, stmt_struct, collections) \ No newline at end of file diff --git a/stdlib/date_ro.catala_ro b/stdlib/date_ro.catala_ro new file mode 100644 index 000000000..51e040b9a --- /dev/null +++ b/stdlib/date_ro.catala_ro @@ -0,0 +1,248 @@ +# Date + +> Modul Date_ro + +> Folosind Date_internal ca D + +## Funcții utilitare + +```catala-metadata +## Returnează cea mai veche dintre cele două date. +declarație min + conținut dată + depinde de x conținut dată, + y conținut dată + egal + dacă x <= y atunci x altfel y + +## Returnează cea mai recentă dintre cele două date. +declarație max + conținut dată + depinde de x conținut dată, + y conținut dată + egal + dacă x >= y atunci x altfel y +``` + +## Date și ani, luni și zile + +```catala-metadata +## Construiește o dată din numărul anului, al lunii (de la 1) +## și al zilei (de la 1). +declarație din_an_lună_zi + conținut dată + depinde de + #[implicit_position_argument] + pos conținut position_source, + dyear conținut întreg, + dmonth conținut întreg, + dday conținut întreg + egal D.of_ymd de pos, dyear, dmonth, dday + +## Returnează numărul anului, al lunii (de la 1) și al zilei +## (de la 1) ale datei transmise ca argument. +declarație către_an_lună_zi + conținut (întreg, întreg, întreg) + depinde de d conținut dată + egal + D.to_ymd de d + +## Returnează numărul anului unei date. +declarație accesează_an + conținut întreg + depinde de d conținut dată + egal (către_an_lună_zi de d).1 + +## Returnează numărul lunii (de la 1) unei date. +declarație accesează_lună + conținut întreg + depinde de d conținut dată + egal (către_an_lună_zi de d).2 + +## Returnează numărul zilei (de la 1) unei date. +declarație accesează_zi + conținut întreg + depinde de d conținut dată + egal (către_an_lună_zi de d).3 +``` + +## Navigare către trecut sau viitor + +```catala-metadata +## Returnează prima zi a lunii datei transmise ca argument. De +## exemplu, `prima_zi_a_lunii de |21-01-2024| = |01-01-2024|`. +declarație prima_zi_a_lunii + conținut dată + depinde de d conținut dată + egal + fie ymd egal către_an_lună_zi de d în + din_an_lună_zi de (ymd.1, ymd.2, 1) + +## Returnează ultima zi a lunii datei transmise ca argument. De +## exemplu, `ultima_zi_a_lunii de |21-01-2024| = |31-01-2024|`. +declarație ultima_zi_a_lunii + conținut dată + depinde de d conținut dată + egal D.last_day_of_month de d + +## Returnează prima zi a anului datei transmise ca argument. De +## exemplu, `prima_zi_a_anului de |21-03-2024| = |01-01-2024|`. +declarație prima_zi_a_anului + conținut dată + depinde de d conținut dată + egal + fie ymd egal (către_an_lună_zi de d) în + din_an_lună_zi de (ymd.1, (1), (1)) + +## Returnează ultima zi a anului datei transmise ca argument. De +## exemplu, `ultima_zi_a_anului de |21-03-2024| = |31-12-2024|`. +declarație ultima_zi_a_anului + conținut dată + depinde de d conținut dată + egal + fie ymd egal către_an_lună_zi de d în + din_an_lună_zi de (ymd.1, (12), (31)) +``` + +## Luni denumite și luni din ani specifici + +```catala-metadata +declarație enumerare Lună: + -- Ianuarie + -- Februarie + -- Martie + -- Aprilie + -- Mai + -- Iunie + -- Iulie + -- August + -- Septembrie + -- Octombrie + -- Noiembrie + -- Decembrie + +## Returnează numărul lunii (de la 1) asociat unei luni denumite. +declarație month_to_int + conținut întreg + depinde de m conținut Lună + egal + potrivește m cu model + -- Ianuarie : 1 + -- Februarie : 2 + -- Martie : 3 + -- Aprilie : 4 + -- Mai : 5 + -- Iunie : 6 + -- Iulie : 7 + -- August : 8 + -- Septembrie : 9 + -- Octombrie : 10 + -- Noiembrie : 11 + -- Decembrie : 12 + +declarație structură LunaInAn: + date număr_an conținut întreg + date nume_lună conținut Lună + +## Returnează luna denumită corespunzătoare numărului lunii (de la 1). +## Dacă argumentul nu este între 1 și 12, eșuează cu eroarea `imposibil`. +declarație month_of_int + conținut Lună + depinde de i conținut întreg + egal + dacă i = 1 atunci Ianuarie + altfel dacă i = 2 atunci Februarie + altfel dacă i = 3 atunci Martie + altfel dacă i = 4 atunci Aprilie + altfel dacă i = 5 atunci Mai + altfel dacă i = 6 atunci Iunie + altfel dacă i = 7 atunci Iulie + altfel dacă i = 8 atunci August + altfel dacă i = 9 atunci Septembrie + altfel dacă i = 10 atunci Octombrie + altfel dacă i = 11 atunci Noiembrie + altfel dacă i = 12 atunci Decembrie + altfel imposibil + +## Transformă o `LunaInAn` către o `dată` alegând prima zi +## a lunii. +declarație luna_in_an_către_prima_zi_a_lunii + conținut dată + depinde de m conținut LunaInAn + egal + din_an_lună_zi de (m.număr_an, (month_to_int de m.nume_lună), 1) + +## Extrage luna denumită și numărul anului dintr-o dată. +declarație to_month_of_year + conținut LunaInAn + depinde de d conținut dată + egal + LunaInAn { + -- număr_an: accesează_an de d + -- nume_lună: month_of_int de (accesează_lună de d) + } +``` + +## Comparații de date + +```catala-metadata +## `este_după_dată_plus_interval de dată_comparată, dată_de_referință, interval` +## verifică dacă `dată_comparată` este după `dată_de_referință + interval`. +## De exemplu, +## `este_după_dată_plus_interval de |15-06-2024|, |01-01-2024|, 6 lună` returnează +## `adevărat` dar +## `este_după_dată_plus_interval de |15-05-2024|, |01-01-2024|, 6 lună` returnează +## `fals`. +declarație este_după_dată_plus_interval + conținut boolean + depinde de dată_comparată conținut dată, + dată_de_referință conținut dată, + interval conținut durată + egal + dată_comparată >= dată_de_referință + interval + +## `este_suficient_de_bătrân de dată_curentă, dată_nașterii, vârstă_țintă` +## verifică dacă `dată_curentă` este după `dată_nașterii + vârstă_țintă`. +## De exemplu, +## `este_suficient_de_bătrân de |15-06-2024|, |01-06-2000|, 24 an` returnează +## `adevărat` dar +## `este_suficient_de_bătrân de |15-05-2024|, |01-06-2024|, 24 an` returnează +## `fals`. +declarație este_suficient_de_bătrân + conținut boolean + depinde de dată_curentă conținut dată, + dată_nașterii conținut dată, + vârstă_țintă conținut durată + egal + dată_curentă >= dată_nașterii + vârstă_țintă + +## `este_înainte_de_dată_plus_interval de dată_comparată, dată_de_referință, interval` +## verifică dacă `dată_comparată` este înainte de `dată_de_referință + interval`. +## De exemplu, +## `este_înainte_de_dată_plus_interval de |15-06-2024|, |01-01-2024|, 6 lună` returnează +## `fals` dar +## `este_înainte_de_dată_plus_interval de |15-05-2024|, |01-01-2024|, 6 lună` returnează +## `adevărat`. +declarație este_înainte_de_dată_plus_interval + conținut boolean + depinde de dată_comparată conținut dată, + dată_de_referință conținut dată, + interval conținut durată + egal + dată_comparată <= dată_de_referință + interval + +## `este_suficient_de_tânăr de dată_curentă, dată_nașterii, vârstă_țintă` +## verifică dacă `dată_curentă` este înainte de `dată_nașterii + vârstă_țintă`. +## De exemplu, +## `este_suficient_de_tânăr de |15-06-2024|, |01-06-2000|, 24 an` returnează +## `fals` dar +## `este_suficient_de_tânăr de |15-05-2024|, |01-06-2024|, 24 an` returnează +## `adevărat`. +declarație este_suficient_de_tânăr + conținut boolean + depinde de dată_curentă conținut dată, + dată_nașterii conținut dată, + target_age conținut durată + egal + dată_curentă <= dată_nașterii + target_age +``` diff --git a/stdlib/decimal_ro.catala_ro b/stdlib/decimal_ro.catala_ro new file mode 100644 index 000000000..e226d2661 --- /dev/null +++ b/stdlib/decimal_ro.catala_ro @@ -0,0 +1,96 @@ +# Zecimale + +> Modul Decimal_ro + +> Folosind Decimal_internal ca D + +## Funcții utilitare + +```catala-metadata +## Returnează cel mai mic dintre cele două argumente. +declarație min + conținut zecimal + depinde de m1 conținut zecimal, + m2 conținut zecimal + egal + dacă m1 > m2 atunci m2 altfel m1 + +## Returnează cel mai mare dintre cele două argumente. +declarație max + conținut zecimal + depinde de m1 conținut zecimal, + m2 conținut zecimal + egal + dacă m1 > m2 atunci m1 altfel m2 + +## `plafon de variabilă, valoare_max` stabilește o limită superioară pentru `variabilă` +## și returnează o valoare care nu depășește niciodată `valoare_max`. +declarație plafon + conținut zecimal + depinde de variabilă conținut zecimal, + valoare_max conținut zecimal + egal min de variabilă, valoare_max + +## `prag de variabilă, valoare_min` stabilește o limită inferioară pentru `variabilă` +## și returnează o valoare care nu este niciodată mai mică decât `valoare_min`. +declarație prag + conținut zecimal + depinde de variabilă conținut zecimal, + valoare_min conținut zecimal + egal max de variabilă, valoare_min + +## Returnează argumentul dacă este pozitiv, 0,0 altfel. +declarație pozitiv + conținut zecimal + depinde de variabilă conținut zecimal + egal prag de variabilă, 0,0 + +## Elimină cifrele unui număr după virgulă. De exemplu, +## `trunchiază de 7,61 = 7,0` și `trunchiază de -7,61 = -7,0`. +declarație trunchiază + conținut zecimal + depinde de variabilă conținut zecimal + egal + dacă variabilă = 0,0 atunci + 0,0 + altfel dacă variabilă > 0,0 atunci + rotunjește de (variabilă - 0,5) + altfel + rotunjește de (variabilă + 0,5) + +## Rotunjește un număr la întregul superior. De exemplu, +## `rotunjește_în_sus de 4,34 = 5,0` și `rotunjește_în_sus de -4,34 = -4,0`. +declarație rotunjește_în_sus + conținut zecimal + depinde de variabilă conținut zecimal + egal + dacă variabilă >= 0,0 atunci + dacă trunchiază de variabilă = variabilă atunci + variabilă + altfel + trunchiază de (variabilă + 1,0) + altfel rotunjește de (variabilă + 0,5) + +## Rotunjește un număr la întregul inferior. De exemplu, +## `rotunjește_în_jos de 3,78 = 3,0` și `rotunjește_în_jos de -3,78 = -4,0`. +declarație rotunjește_în_jos + conținut zecimal + depinde de variabilă conținut zecimal + egal + dacă variabilă > 0,0 atunci + trunchiază de variabilă + altfel dacă trunchiază de variabilă = variabilă atunci + variabilă + altfel + trunchiază de (variabilă - 1,0) + +## Rotunjește un număr la [a_n_ulea_zecimală] specificată. +## [a_n_ulea_zecimală] poate fi o valoare negativă. De exemplu, +## `rotunjește_la_zecimala de 123,4567, 3 = 123,457` și +## `rotunjește_la_zecimala de 123,4567, -2 = 100,0`. +declarație rotunjește_la_zecimala + conținut zecimal + depinde de variabilă conținut zecimal, + a_n_ulea_zecimală conținut întreg + egal D.round_to_decimal de variabilă, a_n_ulea_zecimală +``` diff --git a/stdlib/integer_ro.catala_ro b/stdlib/integer_ro.catala_ro new file mode 100644 index 000000000..efddd50e7 --- /dev/null +++ b/stdlib/integer_ro.catala_ro @@ -0,0 +1,45 @@ +# Întregi + +> Modul Integer_ro + +## Funcții utilitare + +```catala-metadata +## Returnează cel mai mic dintre cele două argumente. +declarație min + conținut întreg + depinde de m1 conținut întreg, + m2 conținut întreg + egal + dacă m1 > m2 atunci m2 altfel m1 + +## Returnează cel mai mare dintre cele două argumente. +declarație max + conținut întreg + depinde de m1 conținut întreg, + m2 conținut întreg + egal + dacă m1 > m2 atunci m1 altfel m2 + +## `plafon de variabilă, valoare_max` stabilește o limită superioară pentru `variabilă` +## și returnează o valoare care nu depășește niciodată `valoare_max`. +declarație plafon + conținut întreg + depinde de variabilă conținut întreg, + valoare_max conținut întreg + egal min de variabilă, valoare_max + +## `prag de variabilă, valoare_min` stabilește o limită inferioară pentru `variabilă` +## și returnează o valoare care nu este niciodată mai mică decât `valoare_min`. +declarație prag + conținut întreg + depinde de variabilă conținut întreg, + valoare_min conținut întreg + egal max de variabilă, valoare_min + +## Returnează argumentul dacă este pozitiv, 0 altfel. +declarație pozitiv + conținut întreg + depinde de variabilă conținut întreg + egal prag de variabilă, 0 +``` diff --git a/stdlib/list_ro.catala_ro b/stdlib/list_ro.catala_ro new file mode 100644 index 000000000..a01bc4cbb --- /dev/null +++ b/stdlib/list_ro.catala_ro @@ -0,0 +1,77 @@ +# Liste + +> Modul List_ro +> Folosind List_internal + +## Funcții utilitare + +```catala-metadata +## Oferă lista formată din întregi consecutivi de la `început` (inclus) la +## `sfârșit` (exclus). +## **Exemplu**: `secvență de 3, 6` oferă lista `[3; 4; 5]` +## **Caz limită**: dacă `sfârșit <= început`, rezultatul este o listă goală +declarație secvență + conținut listă de întreg + depinde de început conținut întreg, + sfârșit conținut întreg + egal + List_internal.sequence de început, sfârșit + +## Oferă elementul listei la `indexul` dat, încapsulat în +## constructorul `Prezent`. +## **Exemplu**: `element_n de [101 RON; 102 RON; 103 RON], 2` oferă +## `Prezent conținut 102 RON` +## **Caz limită**: dacă indexul este mai mic de 1, sau în afara +## listei, valoarea `Absent` este returnată +declarație element_n + conținut opțional de orice de tip t + depinde de lst conținut listă de orice de tip t, + index conținut întreg + egal + List_internal.nth_element de lst, index + +## Oferă primul element al listei, dacă există, încapsulat în +## constructorul `Prezent`. +## **Caz limită**: dacă lista este goală, returnează `Absent` +declarație primul_element + conținut opțional de orice de tip t + depinde de lst conținut listă de orice de tip t + egal + element_n de lst, 1 + +## Oferă ultimul element al listei, dacă există, încapsulat în +## constructorul `Prezent`. +## **Caz limită**: dacă lista este goală, returnează `Absent` +declarație ultimul_element + conținut opțional de orice de tip t + depinde de lst conținut listă de orice de tip t + egal + element_n de lst, (număr de lst) + +## Elimină elementul de la `indexul` dat din listă. Indexurile elementelor +## următoare sunt deplasate. +## **Caz limită**: dacă indexul dat este invalid, returnează lista fără +## modificare +declarație elimină_element_n + conținut listă de orice de tip t + depinde de lst conținut listă de orice de tip t, + index conținut întreg + egal + List_internal.remove_nth_element de lst, index + +## Returnează lista fără primul său element +## **Caz limită**: lista goală este returnată neschimbată +declarație elimină_primul_element + conținut listă de orice de tip t + depinde de lst conținut listă de orice de tip t + egal + List_internal.remove_nth_element de lst, 1 + +## Returnează lista fără ultimul său element +## **Caz limită**: lista goală este returnată neschimbată +declarație elimină_ultimul_element + conținut listă de orice de tip t + depinde de lst conținut listă de orice de tip t + egal + List_internal.remove_nth_element de lst, (număr de lst) +``` diff --git a/stdlib/money_ro.catala_ro b/stdlib/money_ro.catala_ro new file mode 100644 index 000000000..05c38d19e --- /dev/null +++ b/stdlib/money_ro.catala_ro @@ -0,0 +1,110 @@ +# Bani + +> Modul Money_ro + +> Folosind Money_internal ca M + +## Funcții utilitare + +```catala-metadata +## Returnează cel mai mic dintre cele două argumente. +declarație min + conținut bani + depinde de m1 conținut bani, + m2 conținut bani + egal + dacă m1 > m2 atunci m2 altfel m1 + +## Returnează cel mai mare dintre cele două argumente. +declarație max + conținut bani + depinde de m1 conținut bani, + m2 conținut bani + egal + dacă m1 > m2 atunci m1 altfel m2 + +## `plafon de variabilă, valoare_max` stabilește o limită superioară pentru `variabilă` +## și returnează o valoare care nu depășește niciodată `valoare_max`. +declarație plafon + conținut bani + depinde de variabilă conținut bani, + valoare_max conținut bani + egal min de variabilă, valoare_max + +## `prag de variabilă, valoare_min` stabilește o limită inferioară pentru `variabilă` +## și returnează o valoare care nu este niciodată mai mică decât `valoare_min`. +declarație prag + conținut bani + depinde de variabilă conținut bani, + valoare_min conținut bani + egal max de variabilă, valoare_min + +## Returnează argumentul dacă este pozitiv, 0 RON altfel. +declarație pozitiv + conținut bani + depinde de variabilă conținut bani + egal prag de variabilă, 0 RON + +## Elimină cifrele unei sume de bani după virgulă. De exemplu, +## `trunchiază de 7,61 RON = 7 RON` și `trunchiază de -7,61 RON = -7 RON`. +declarație trunchiază + conținut bani + depinde de variabilă conținut bani + egal + dacă variabilă = 0 RON atunci 0 RON + altfel dacă variabilă > 0 RON atunci + rotunjește de (variabilă - 0,5 RON) + altfel + rotunjește de (variabilă + 0,5 RON) + +## Rotunjește o sumă de bani la RON-ul superior. De exemplu, +## `rotunjește_în_sus de 4,34 RON = 5 RON` și `rotunjește_în_sus de -4,34 RON = -4 RON`. +declarație rotunjește_în_sus + conținut bani + depinde de variabilă conținut bani + egal + dacă variabilă >= 0 RON atunci + rotunjește de (variabilă + 0,49 RON) + altfel + rotunjește de (variabilă + 0,5 RON) + +## Rotunjește o sumă de bani la RON-ul inferior. De exemplu, +## `rotunjește_în_jos de 3,78 RON = 3 RON` și `rotunjește_în_jos de -3,78 RON = -4 RON`. +declarație rotunjește_în_jos + conținut bani + depinde de variabilă conținut bani + egal + dacă variabilă > 0 RON atunci + rotunjește de (variabilă - 0,5 RON) + altfel rotunjește de (variabilă - 0,49 RON) + +## Rotunjește o sumă de bani la [a_n_ulea_zecimală] specificată. +## [a_n_ulea_zecimală] poate fi o valoare negativă. De exemplu, +## `rotunjește_la_zecimala de 123,45 RON, 1 = 123,5 RON` și +## `rotunjește_la_zecimala de 123,45 RON, -2 = 100 RON`. +declarație rotunjește_la_zecimala + conținut bani + depinde de variabilă conținut bani, + a_n_ulea_zecimală conținut întreg + egal M.round_to_decimal de variabilă, a_n_ulea_zecimală +``` + +## Operații financiare + +```catala-metadata +## Returnează suma pozitivă cu care `variabilă` depășește `referință` +## (altfel 0 RON) +declarație în_exces + conținut bani + depinde de variabilă conținut bani, + referință conținut bani + egal max de (0 RON, variabilă - referință) + +## Returnează suma pozitivă cu care `variabilă` este sub `referință` +## (altfel 0 RON) +declarație în_deficit + conținut bani + depinde de variabilă conținut bani, + referință conținut bani + egal max de (0 RON, referință - variabilă) +``` diff --git a/stdlib/period_ro.catala_ro b/stdlib/period_ro.catala_ro new file mode 100644 index 000000000..aa73e1b5d --- /dev/null +++ b/stdlib/period_ro.catala_ro @@ -0,0 +1,159 @@ +# Perioade de timp + +> Modul Period_ro +> Folosind Period_internal +> Folosind Date_ro ca Dată + +## Definiții și operații + +O perioadă este conjuncția unei date de început și sfârșit. + +```catala-metadata +declarație structură Perioadă: + date început conținut dată + # Data de sfârșit este exclusă din perioadă prin convenție. + date sfârșit conținut dată + +## Verifică dacă perioada este coerentă (începe înainte de sfârșit). +declarație validă + conținut boolean + depinde de p conținut Perioadă + egal + dacă p.sfârșit <= p.început atunci fals + altfel adevărat + +## Durata unei perioade, în număr de zile. +declarație durată + conținut durată + depinde de p conținut Perioadă + egal p.sfârșit - p.început + +## Două perioade sunt adiacente dacă una se termină când cealaltă începe. +declarație sunt_adiacente + conținut boolean + depinde de p1 conținut Perioadă, + p2 conținut Perioadă + egal + p1.sfârșit = p2.început + +## Returnează perioada care cuprinde `p1` și `p2`. +declarație uniune + conținut Perioadă + depinde de p1 conținut Perioadă, + p2 conținut Perioadă + egal + Perioadă { + -- început: Dată.min de p1.început, p2.început + -- sfârșit: Dată.max de p1.sfârșit, p2.sfârșit + } + +## Returnează perioada conținută atât în p1 cât și în p2, dacă există. +declarație intersecție + conținut opțional de Perioadă + depinde de p1 conținut Perioadă, + p2 conținut Perioadă + egal + fie intersecție egal + Perioadă { + -- început: Dată.max de p1.început, p2.început + -- sfârșit: Dată.min de p1.sfârșit, p2.sfârșit + } + în + dacă validă de intersecție atunci Prezent conținut intersecție + altfel Absent + +## Returnează `adevărat` dacă data aparține perioadei. +declarație conținută + conținut boolean + depinde de p conținut Perioadă, + d conținut dată + egal + p.început <= d și d < p.sfârșit + +## Găsește prima perioadă din lista `l` care conține data `d`. +declarație găsește_perioada + conținut opțional de Perioadă + depinde de l conținut listă de Perioadă, + d conținut dată + egal + combină toți p printre l + în found inițial Absent + cu + potrivește found cu model + -- Prezent : found + -- Absent : dacă conținută de p, d atunci Prezent conținut p altfel Absent +``` + +## Operații pe liste asociate indexate prin perioade + +```catala-metadata +## Sortează lista de perioade în funcție de data de început. +declarație sortează_după_dată + conținut listă de (Perioadă, orice de tip t) + depinde de l conținut listă de (Perioadă, orice de tip t) + egal + fie tuple_associated_list egal către_tuplu_listă_asociată de l în + fie sorted_tuple_associated_list egal + Period_internal.sort de tuple_associated_list + în + din_tuplu_listă_asociată de sorted_tuple_associated_list +``` + +## Împărțirea perioadelor + +```catala-metadata +## Împarte perioada în câte sub-perioade conține luni din +## calendar. Primele și ultimele elemente returnate pot fi deci +## luni incomplete. +declarație împarte_pe_luni + conținut listă de Perioadă + depinde de p conținut Perioadă + egal din_tuplu_listă de Period_internal.split_by_month de către_tuplu de p + +## Împarte perioada în câte sub-perioade conține ani din +## calendar. Primele și ultimele elemente returnate pot fi deci +## ani incompleți. +declarație împarte_pe_ani + conținut listă de Perioadă + depinde de starting_month conținut Dată.Lună, + p conținut Perioadă + egal + din_tuplu_listă de + Period_internal.split_by_year de + (Dată.month_to_int de starting_month), + către_tuplu de p +``` + +## Funcții interne +```catala +declarație către_tuplu + conținut (dată, dată) + depinde de p conținut Perioadă + egal (p.început, p.sfârșit) + +declarație către_tuplu_listă_asociată + conținut listă de ((dată, dată), orice de tip t) + depinde de l conținut listă de (Perioadă, orice de tip t) + egal aplică fiecare p printre l la ((către_tuplu de p.1), p.2) + +declarație către_tuplu_listă + conținut listă de (dată, dată) + depinde de l conținut listă de Perioadă + egal aplică fiecare p printre l la către_tuplu de p + +declarație din_tuplu + conținut Perioadă + depinde de început conținut dată, + sfârșit conținut dată + egal Perioadă { -- început: început -- sfârșit: sfârșit } + +declarație din_tuplu_listă_asociată + conținut listă de (Perioadă, orice de tip t) + depinde de l conținut listă de ((dată, dată), orice de tip t) + egal aplică fiecare tpl printre l la ((din_tuplu de tpl.1), tpl.2) + +declarație din_tuplu_listă + conținut listă de Perioadă + depinde de l conținut listă de (dată, dată) + egal aplică fiecare tpl printre l la din_tuplu de tpl +``` diff --git a/stdlib/stdlib_ro.catala_ro b/stdlib/stdlib_ro.catala_ro new file mode 100644 index 000000000..d1b8e789b --- /dev/null +++ b/stdlib/stdlib_ro.catala_ro @@ -0,0 +1,26 @@ +> Modul Stdlib_ro + +```catala-metadata +# This file is part of the Catala compiler, a specification language for tax +# and social benefits computation rules. Copyright (C) 2025 Inria, contributor: +# Jan Cavel +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may not +# use this file except in compliance with the License. You may obtain a copy of +# the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations under +# the License. +``` + +> Folosind Date_ro ca Dată +> Folosind Period_ro ca Perioadă +> Folosind Money_ro ca Bani +> Folosind Integer_ro ca Întreg +> Folosind Decimal_ro ca Zecimal +> Folosind List_ro ca Listă diff --git a/syntax_highlighting/ro/pygments/catala_ro_lexer/__init__.py b/syntax_highlighting/ro/pygments/catala_ro_lexer/__init__.py new file mode 100644 index 000000000..5dbd250cf --- /dev/null +++ b/syntax_highlighting/ro/pygments/catala_ro_lexer/__init__.py @@ -0,0 +1,3 @@ +from .lexer import CustomLexer + +__all__ = ['CustomLexer'] diff --git a/syntax_highlighting/ro/pygments/catala_ro_lexer/lexer.py b/syntax_highlighting/ro/pygments/catala_ro_lexer/lexer.py new file mode 100644 index 000000000..95680c585 --- /dev/null +++ b/syntax_highlighting/ro/pygments/catala_ro_lexer/lexer.py @@ -0,0 +1,53 @@ +from pygments.lexer import RegexLexer, bygroups +from pygments.token import * + +import re + +__all__=['CustomLexer'] + +class CustomLexer(RegexLexer): + name = 'CatalaRo' + aliases = ['catala_ro'] + filenames = ['*.catala_ro'] + flags = re.MULTILINE | re.UNICODE + + tokens = { + 'root' : [ + (u'(^\\s*[\\#]+.*)', bygroups(Generic.Heading)), + (u'(^\\s*[\\#]+\\s*\\[[^\\]\\n\\r]\\s*].*)', bygroups(Generic.Heading)), + (u'([^`\\n\\r])', bygroups(Text)), + (u'(^```catala$)', bygroups(Text), 'code'), + (u'(^```catala-metadata$)', bygroups(Text), 'code'), + (u'(^```catala-test-cli$)', bygroups(Text), 'test'), + ('(\n|\r|\r\n)', Whitespace), + ('.', Text), + ], + 'code' : [ + (u'(^```$)', bygroups(Text), 'root'), + (u'(\\s*\\#(|[^[].*)$)', bygroups(Comment.Single)), + (u'(\\s*\\#\\[([\\\\](.|\n)|[^]\\\\])*\\])', bygroups(Comment.Multi)), + (u'(context|intrare|ieșire|intern)(\\s*)(|ieșire)(\\s+)([a-zăâîșțĂÂÎȘȚA-Z0-9_\\\']*)', bygroups(Keyword.Declaration, Whitespace, Keyword.Declaration, Whitespace, Name.Variable)), + (u'\\b(potrivește|cu\\s+model|dar\\s+înlocuiește|fixat|de|descrescător|crescător|variază|cu|avem|fie|în|scop|depinde\\s+de|declarație|include|conținut|tip|regulă|în\\s+condiția|condiție|date|consecință|îndeplinit|egal|aserțiune|definiție|stare|etichetă|excepție|orice)\\b', bygroups(Keyword.Reserved)), + (u'\\b(conține|număr|sumă|astfel\\s+că|există|pentru|toți|de|dacă|atunci|altfel|este|listă\\s+goală|printre|maxim|minim|rotunjește|combină|aplică\\s+fiecare|la|inițial)\\b', bygroups(Keyword.Declaration)), + (u'(\\|[0-9]+\\-[0-9]+\\-[0-9]+\\|)', bygroups(Number.Integer)), + (u'\\b(adevărat|fals)\\b', bygroups(Keyword.Constant)), + (u'\\b([0-9]{1,3}(\\.[0-9]{3})*,[0-9]+)\\b', bygroups(Number.Float)), + (u'\\b([0-9]{1,3}(\\.[0-9]{3})+)\\b', bygroups(Number.Integer)), + (u'\\b([0-9]+)\\b', bygroups(Number.Integer)), + (u'(\\-\\-|\\;|\\.|\\,|\\:|\\(|\\)|\\[|\\]|\\{|\\})', bygroups(Operator)), + (u'(\\-\\>|\\+\\.|\\+\\@|\\+\\^|\\+\\$|\\+|\\-\\.|\\-\\@|\\-\\^|\\-\\$|\\-|\\*\\.|\\*\\@|\\*\\^|\\*\\$|\\*|/\\.|/\\@|/\\$|/|\\!|>\\.|>=\\.|<=\\.|<\\.|>\\@|>=\\@|<=\\@|<\\@|>\\$|>=\\$|<=\\$|<\\$|>\\^|>=\\^|<=\\^|<\\^|>|>=|<=|<|=|nu|sau|sau\\s+exclusiv|și|\\$|RON|%|an|lună|zi)', bygroups(Operator)), + (u'\\b(structură|enumerare|listă\\s+de|întreg|boolean|dată|durată|bani|text|zecimal|position_source)\\b', bygroups(Keyword.Type)), + (u'\\b([A-ZĂÂÎȘȚ][a-zăâîșțA-ZĂÂÎȘȚ0-9_\\\']*)(\\.)([a-zăâîșț][a-zăâîșțA-ZĂÂÎȘȚ0-9_\\\']*)\\b', bygroups(Name.Class, Operator, Name.Variable)), + (u'\\b([a-zăâîșț][a-zăâîșțA-ZĂÂÎȘȚ0-9_\\\']*)(\\.)([a-zăâîșț][a-zăâîșțA-ZĂÂÎȘȚ0-9_\\\'\\.]*)\\b', bygroups(Name.Variable, Operator, Text)), + (u'\\b([a-zăâîșț][a-zăâîșțA-ZĂÂÎȘȚ0-9_\\\']*)\\b', bygroups(Name.Variable)), + (u'\\b([A-ZĂÂÎȘȚ][a-zăâîșțA-ZĂÂÎȘȚ0-9_\\\']*)\\b', bygroups(Name.Class)), + ('(\n|\r|\r\n)', Whitespace), + ('.', Text), + ], + 'test' : [ + (u'(^```$)', bygroups(Text), 'root'), + (u'(^[$] catala \\S*)', bygroups(Keyword.Constant)), + ('(\n|\r|\r\n)', Whitespace), + ('.', Text), + ] + } diff --git a/syntax_highlighting/ro/pygments/pyproject.toml b/syntax_highlighting/ro/pygments/pyproject.toml new file mode 100644 index 000000000..6afef91f6 --- /dev/null +++ b/syntax_highlighting/ro/pygments/pyproject.toml @@ -0,0 +1,11 @@ +[build-system] +requires = ["setuptools"] +build-backend = "setuptools.build_meta" + +[project] +name = "catala_ro_lexer" +version = "0.8" +dependencies = ["pygments"] + +[project.entry-points."pygments.lexers"] +catala-ro-lexer = "catala_ro_lexer.lexer:CustomLexer" diff --git a/syntax_highlighting/ro/pygments/setup.py b/syntax_highlighting/ro/pygments/setup.py new file mode 100644 index 000000000..1030e4330 --- /dev/null +++ b/syntax_highlighting/ro/pygments/setup.py @@ -0,0 +1,3 @@ +from setuptools import setup, find_packages + +setup() diff --git a/syntax_highlighting/ro/vim/catala_ro.vim b/syntax_highlighting/ro/vim/catala_ro.vim new file mode 100644 index 000000000..642677954 --- /dev/null +++ b/syntax_highlighting/ro/vim/catala_ro.vim @@ -0,0 +1,62 @@ +" In order to enable the syntax highlighting: +" +" 1. Copy or link the current file into $VIMCONFIG/syntax +" +" 2. Enable file type detection by adding to $VIMCONFIG/filetype.vim: +" +" augroup filetypedetect +" au! BufRead,BufNewFile *.catala_ro setfiletype catala_ro +" augroup END +" +" More informations could be found at: +" +" https://elias.rhi.hi.is/vim/syntax.html#:syn-files +" + +if exists("b:current_syntax") + finish +endif + +syn match PreProc "^\s*#.*$" +syn match Include "^\s*>\s*Include:.*$" + +syn match sc_id_def contained "\<\([a-zăâîșțĂÂÎȘȚ][a-zăâîșțĂÂÎȘȚA-Z0-9_\']*\)\>" +syn match cc_id contained "\<\([A-ZĂÂÎȘȚ][a-zăâîșțĂÂÎȘȚA-Z0-9_\']*\)\>" +syn match Keyword contained "\<\(scop\|depinde\s\+de\|declarație\|include\|listă\s\+de\|conținut\|tip\|opțional\|structură\|enumerare\|context\|regulă\|în\s\+condiția\|condiție\|date\|consecință\|îndeplinit\|egal\|aserțiune\|definiție\|stare\|etichetă\|excepție\|orice\|listă\s+goală\)\>" +syn match Statement contained "\<\(potrivește\|cu\s\+model\|dar\s\+înlocuiește\|fixat\|de\|descrescător\|crescător\|variază\|cu\|avem\|fie\|în\|astfel\s\+că\|există\|pentru\|toți\|de\|dacă\|atunci\|altfel\|inițial\|printre\|este\s+maxim\|este\s+minim\|combină\|aplică\s+fiecare\|la\|inițial\)\>" +syn keyword Conditional contained dacă atunci altfel +syn match Comment contained "#.*$" +syn match Number contained "|[0-9]\+-[0-9]\+-[0-9]\+|" +syn match Float contained "\<\([0-9]\+\(\.[0-9]*\)*\(\,[0-9]*\)\{0,1}\)\>" +syn keyword Boolean contained adevărat fals +syn match Operator contained "\(->\|+\.\|+@\|+\^\|+\$\|+\|-\.\|-@\|-\^\|-\$\|-\|\*\.\|\*@\|\*\^\|\*\$\|\*\|/\.\|/@\|/\$\|/\|\!\|>\.\|>=\.\|<=\.\|<\.\|>@\|>=@\|<=@\|<@\|>\$\|>=\$\|<=\$\|<\$\|>\^\|>=\^\|<=\^\|<\^\|>\|>=\|<=\|<\|=\|nu\|sau\|sau\s\+exclusiv\|și\|\$\|RON\|%\|lună\|an\|zi\)" +syn match punctuation contained "\(--\|\;\|\.\|,\|\:\|(\|)\|\[\|\]\|{\|}\)" +syn keyword Type contained întreg boolean dată durată bani text zecimal număr sumă position_source + +syn region ctxt contained + \ matchgroup=Keyword start="\<\(context\|intrare\|ieșire\|intern\)\(\|\s\+ieșire\)" + \ matchgroup=sc_id_def end="\s\+\([a-zăâîșțĂÂÎȘȚ][a-zăâîșțĂÂÎȘȚA-Z0-9_\']*\)\>" + +syn region cc_id_dot_sc_id contained contains=punctuation + \ matchgroup=cc_id start="\<\([A-ZĂÂÎȘȚ][a-zăâîșțĂÂÎȘȚA-Z0-9_\']*\)\."rs=e-1 + \ matchgroup=sc_id_def end="\([a-zăâîșțĂÂÎȘȚ][a-zăâîșțĂÂÎȘȚA-Z0-9_\']*\)\>" + +syn region sc_id_def_dot_sc_id contained contains=punctuation + \ matchgroup=sc_id_def start="\<\([a-zăâîșțĂÂÎȘȚ][a-zăâîșțĂÂÎȘȚA-Z0-9_\']*\)\."rs=e-1 + \ matchgroup=sc_id end="\([a-zăâîșțĂÂÎȘȚ][a-zăâîșțĂÂÎȘȚA-Z0-9_\']*\)\>" + +syn region code transparent matchgroup=Ignore start="```catala" matchgroup=Ignore end="```" + \ contains=ALLBUT, PreProc, Include + +syn region metadata transparent matchgroup=Ignore start="```catala-metadata" matchgroup=Ignore end="```" + \ contains=ALLBUT, PreProc, Include + +" Synchronizes the position where redrawing start at the start of a code block. +syntax sync match codeSync grouphere code "```catala\w*" + +hi link sc_id_def Identifier +hi link sc_id Function +hi link cc_id Type +hi link punctuation Ignore + +let b:current_syntax = "catala_ro"