mirror of
https://github.com/CatalaLang/catala.git
synced 2024-09-20 00:41:05 +03:00
Merge branch 'master' into allocations_logement
This commit is contained in:
commit
7d9379e43c
2
.gitattributes
vendored
2
.gitattributes
vendored
@ -1,6 +1,4 @@
|
||||
*.catala* linguist-language=Markdown
|
||||
*.ml linguist-language=OCaml
|
||||
*.fst linguist-language=Fstar
|
||||
*.mld linguist-documentation
|
||||
*.md linguist-documentation
|
||||
*.hints linguist-generated
|
||||
|
38
.nix/cmdliner.nix
Normal file
38
.nix/cmdliner.nix
Normal file
@ -0,0 +1,38 @@
|
||||
{ lib, stdenv, fetchurl, ocaml, findlib, ocamlbuild, topkg, result }:
|
||||
|
||||
let
|
||||
pname = "cmdliner";
|
||||
in
|
||||
|
||||
assert lib.versionAtLeast ocaml.version "4.01.0";
|
||||
|
||||
let param =
|
||||
{
|
||||
version = "1.1.0";
|
||||
hash = "sha256-irWd4HTlJSYuz3HMgi1de2GVL2qus0QjeCe1WdsSs8Q=";
|
||||
}
|
||||
; in
|
||||
|
||||
stdenv.mkDerivation rec {
|
||||
name = "ocaml${ocaml.version}-${pname}-${version}";
|
||||
inherit (param) version;
|
||||
|
||||
src = fetchurl {
|
||||
url = "https://erratique.ch/software/${pname}/releases/${pname}-${version}.tbz";
|
||||
inherit (param) hash;
|
||||
};
|
||||
|
||||
nativeBuildInputs = [ ocaml ocamlbuild findlib ];
|
||||
buildInputs = [ topkg ];
|
||||
propagatedBuildInputs = [ result ];
|
||||
|
||||
inherit (topkg) buildPhase installPhase;
|
||||
|
||||
meta = with lib; {
|
||||
homepage = "https://erratique.ch/software/cmdliner";
|
||||
description = "An OCaml module for the declarative definition of command line interfaces";
|
||||
license = licenses.bsd3;
|
||||
platforms = ocaml.meta.platforms or [];
|
||||
maintainers = [ ];
|
||||
};
|
||||
}
|
@ -10,14 +10,14 @@ any questions about the project.
|
||||
If you want to contribute to the project on a longer-term basis, or if you have
|
||||
specific competences as a socio-fiscal lawyer or a programming language specialist,
|
||||
please [contact the authors](mailto:contact@catala-lang.org).
|
||||
The Catala team meets over visioconference once every two weeks.
|
||||
The Catala team meets over visioconference once every week.
|
||||
|
||||
Please note that the copyright of this code is owned by Inria;
|
||||
by contributing, you disclaim all copyright interests in favor of Inria.
|
||||
Both the code for the compiler and the examples in this repository are
|
||||
distributed under the Apache2 license.
|
||||
|
||||
### Writing Catala code
|
||||
## Writing Catala code
|
||||
|
||||
Before writing Catala code, please read the
|
||||
[tutorial](https://catala-lang.org/en/examples/tutorial). You can run the
|
||||
@ -47,6 +47,8 @@ using for instance
|
||||
|
||||
```
|
||||
make -C examples/foo foo.tex
|
||||
make -C examples/foo foo.py
|
||||
make -C examples/foo foo.ml
|
||||
```
|
||||
|
||||
to see if you've made any syntax errors. Once the text formatting is done, you
|
||||
@ -87,7 +89,7 @@ You can look at the
|
||||
[online OCaml documentation](https://catala-lang.org/ocaml_docs/) for the
|
||||
different modules' interfaces as well as high-level architecture documentation.
|
||||
|
||||
Please note that the `ocamlformat` version this project uses is `0.18.0`.
|
||||
Please note that the `ocamlformat` version this project uses is `0.19.0`.
|
||||
Using another version may cause spurious diffs to appear in your pull requests.
|
||||
|
||||
### Example: adding a builtin function
|
||||
@ -114,7 +116,7 @@ need more, here is how one can be added:
|
||||
- in `dcalc/interpreter.ml`, function `evaluate_operator`
|
||||
- Update the syntax guide in `doc/syntax/syntax.tex` with your new builtin
|
||||
|
||||
## Internationalization
|
||||
### Internationalization of the Catala syntax
|
||||
|
||||
The Catala language should be adapted to any legislative text that follows a
|
||||
general-to-specifics statutes order. Therefore, there exists multiple versions
|
||||
@ -124,12 +126,14 @@ Currently, Catala supports English, French and Polish legislative text via the
|
||||
`--language=en`, `--language=fr` or `--language=pl` options.
|
||||
|
||||
To add support for a new language:
|
||||
|
||||
- the basic syntax localisation is defined in
|
||||
`compiler/surface/lexer_xx.cppo.ml` where `xx` is the language code (`en`,
|
||||
`fr`...)
|
||||
- copy the files from another language, e.g.
|
||||
[english](compiler/surface/lexer_en.cppo.ml), then replace the strings with your
|
||||
translations. Be careful with the following:
|
||||
|
||||
- The file must be encoded in latin-1
|
||||
- For a given token `FOO`, define `MS_FOO` to be the string version of the
|
||||
keyword. Due to the encoding, use `\xNN` [escape
|
||||
@ -138,13 +142,12 @@ To add support for a new language:
|
||||
- If the string contains spaces or non-latin1 characters, you need to define
|
||||
`MR_FOO` as well with a regular expression in [sedlex
|
||||
format](https://github.com/ocaml-community/sedlex#lexer-specifications).
|
||||
Replace spaces with `", space_plus, "`, and unicode characters with `",
|
||||
0xNNNN, "` where `NNNN` is the hexadecimal unicode codepoint.
|
||||
Replace spaces with `", space_plus, "`, and unicode characters with `", 0xNNNN, "` where `NNNN` is the hexadecimal unicode codepoint.
|
||||
|
||||
**Hint:** You may get syntax errors with unhelpful locations because of
|
||||
`sedlex`. In that case the command `ocamlc
|
||||
_build/default/compiler/surface/lexer_xx.ml` may point you to the source of the
|
||||
`sedlex`. In that case the command `ocamlc _build/default/compiler/surface/lexer_xx.ml` may point you to the source of the
|
||||
error.
|
||||
|
||||
- add your translation to the compilation rules:
|
||||
- in `compiler/surface/dune`, copying another `parser_xx.cppo.ml` rule
|
||||
- in the `extensions` list in `compiler/driver.ml`
|
||||
|
49
README.md
49
README.md
@ -87,6 +87,12 @@ The Catala language is the only programming language to our knowledge that
|
||||
embeds default logic as a first-class feature, which is why it is the only
|
||||
language perfectly adapted to literate legislative programming.
|
||||
|
||||
## Getting started
|
||||
|
||||
To get started, the best place is the [tutorial](https://catala-lang.org/en/examples/tutorial)
|
||||
of the language. A [French version](https://catala-lang.org/fr/examples/tutoriel)
|
||||
is also available but might be out of sync with the latest language features.
|
||||
|
||||
## Building and installation
|
||||
|
||||
Catala is available as an [opam package](https://opam.ocaml.org/packages/catala/)!
|
||||
@ -108,7 +114,8 @@ want to compile it from the sources of this repository or use nix. For that, see
|
||||
### Catala
|
||||
|
||||
Use `catala --help` if you have installed it to get more information about the command line
|
||||
options available. To get the development version of the help, run `make help_catala`
|
||||
options available. The man page is also [available online](https://catala-lang.org/en/doc/catala).
|
||||
To get the development version of the help, run `make help_catala`
|
||||
after `make build`. The `catala` binary corresponds to the Catala compiler.
|
||||
|
||||
The top-level `Makefile` contains a lot of useful targets to run. To display
|
||||
@ -123,6 +130,29 @@ options available. To get the development version of the help, run `make help_cl
|
||||
after `make build`. The `clerk` binary corresponds to the Catala build system,
|
||||
responsible for testing among other things.
|
||||
|
||||
## Documentation
|
||||
|
||||
### Syntax cheat sheet
|
||||
|
||||
A complete and handy reference of the Catala syntax can be found in the
|
||||
[cheat sheet](doc/syntax/syntax.pdf) (for French and English versions
|
||||
of the syntax).
|
||||
|
||||
### Formal semantics
|
||||
|
||||
To audit the formal proof of the partial certification of the Catala compiler,
|
||||
see [the dedicated readme](doc/formalization/README.md).
|
||||
|
||||
### Compiler documentation
|
||||
|
||||
The compiler documentation is auto-generated from its source code using
|
||||
`dune` and `odoc`. Use
|
||||
|
||||
make doc
|
||||
|
||||
to generate the documentation, then open the `doc/odoc.html` file in any browser.
|
||||
The documentation is also accessible [online](https://catala-lang.org/ocaml_docs/).
|
||||
|
||||
## Examples
|
||||
|
||||
To explore the different programs written in Catala, see
|
||||
@ -143,23 +173,6 @@ To know how you can contribute to the project, see
|
||||
To know how to run or improve the Catala reference test suite,
|
||||
see [the dedicated readme](tests/README.md).
|
||||
|
||||
## Documentation
|
||||
|
||||
### Formal semantics
|
||||
|
||||
To audit the formal proof of the partial certification of the Catala compiler,
|
||||
see [the dedicated readme](doc/formalization/README.md).
|
||||
|
||||
### Compiler documentation
|
||||
|
||||
The compiler documentation is auto-generated from its source code using
|
||||
`dune` and `odoc`. Use
|
||||
|
||||
make doc
|
||||
|
||||
to generate the documentation, then open the `doc/odoc.html` file in any browser.
|
||||
The documentation is also accessible [online](https://catala-lang.org/ocaml_docs/).
|
||||
|
||||
## License
|
||||
|
||||
The compiler and all the code contained in this repository is released under
|
||||
|
@ -81,8 +81,8 @@ let info =
|
||||
`P "Please file bug reports at https://github.com/CatalaLang/catala/issues";
|
||||
]
|
||||
in
|
||||
let exits = Term.default_exits @ [ Term.exit_info ~doc:"on error." 1 ] in
|
||||
Term.info "clerk" ~version ~doc ~exits ~man
|
||||
let exits = Cmd.Exit.defaults @ [ Cmd.Exit.info ~doc:"on error." 1 ] in
|
||||
Cmd.info "clerk" ~version ~doc ~exits ~man
|
||||
|
||||
(**{1 Testing}*)
|
||||
|
||||
@ -98,6 +98,8 @@ let catala_backend_to_string (backend : Cli.backend_option) : string =
|
||||
| Cli.Html -> "Html"
|
||||
| Cli.Python -> "Python"
|
||||
| Cli.Typecheck -> "Typecheck"
|
||||
| Cli.Scalc -> "Scalc"
|
||||
| Cli.Lcalc -> "Lcalc"
|
||||
|
||||
type expected_output_descr = {
|
||||
base_filename : string;
|
||||
@ -204,8 +206,8 @@ let test_file (tested_file : string) (catala_exe : string) (catala_opts : string
|
||||
Format.asprintf "colordiff -u -b %s%s -" expected_output.output_dir
|
||||
expected_output.complete_filename;
|
||||
]
|
||||
| Cli.Python | Cli.OCaml | Cli.Dcalc | Cli.Scopelang | Cli.Latex | Cli.Html
|
||||
| Cli.Makefile ->
|
||||
| Cli.Python | Cli.OCaml | Cli.Dcalc | Cli.Scalc | Cli.Lcalc | Cli.Scopelang | Cli.Latex
|
||||
| Cli.Html | Cli.Makefile ->
|
||||
(* for those backends, the output of the Catala compiler will be written in a
|
||||
temporary file which later we're going to diff with the *)
|
||||
if reset_test_outputs then
|
||||
@ -328,7 +330,5 @@ let driver (file_or_folder : string) (command : string) (catala_exe : string opt
|
||||
1
|
||||
|
||||
let _ =
|
||||
let return_code = Cmdliner.Term.eval (clerk_t driver, info) in
|
||||
match return_code with
|
||||
| `Ok 0 -> Cmdliner.Term.exit (`Ok 0)
|
||||
| _ -> Cmdliner.Term.exit (`Error `Term)
|
||||
let return_code = Cmdliner.Cmd.eval' (Cmdliner.Cmd.v info (clerk_t driver)) in
|
||||
exit return_code
|
||||
|
@ -21,7 +21,7 @@ depends: [
|
||||
"menhirLib" {>= "20200211"}
|
||||
"unionFind" {>= "20200320"}
|
||||
"bindlib" {>= "5.0.1"}
|
||||
"cmdliner" {>= "1.0.4"}
|
||||
"cmdliner" {>= "1.1.0"}
|
||||
"re" {>= "1.9.0"}
|
||||
"zarith" {>= "1.12"}
|
||||
"zarith_stubs_js" {>= "v0.14.1"}
|
||||
|
@ -140,7 +140,8 @@ type binder = (expr, expr Pos.marked) Bindlib.binder
|
||||
type scope_let_kind =
|
||||
| DestructuringInputStruct (** [let x = input.field]*)
|
||||
| ScopeVarDefinition (** [let x = error_on_empty e]*)
|
||||
| SubScopeVarDefinition (** [let s.x = fun _ -> e] *)
|
||||
| SubScopeVarDefinition
|
||||
(** [let s.x = fun _ -> e] or [let s.x = error_on_empty e] for input-only subscope variables. *)
|
||||
| CallingSubScope (** [let result = s ({ x = s.x; y = s.x; ...}) ]*)
|
||||
| DestructuringSubScopeResults (** [let s.x = result.x ]**)
|
||||
| Assertion (** [let _ = assert e]*)
|
||||
|
@ -53,6 +53,9 @@ let format_punctuation (fmt : Format.formatter) (s : string) : unit =
|
||||
let format_operator (fmt : Format.formatter) (s : string) : unit =
|
||||
Format.fprintf fmt "%a" (Utils.Cli.format_with_style [ ANSITerminal.green ]) s
|
||||
|
||||
let format_lit_style (fmt : Format.formatter) (s : string) : unit =
|
||||
Format.fprintf fmt "%a" (Utils.Cli.format_with_style [ ANSITerminal.yellow ]) s
|
||||
|
||||
let format_tlit (fmt : Format.formatter) (l : typ_lit) : unit =
|
||||
format_base_type fmt
|
||||
(match l with
|
||||
@ -64,6 +67,11 @@ let format_tlit (fmt : Format.formatter) (l : typ_lit) : unit =
|
||||
| TDuration -> "duration"
|
||||
| TDate -> "date")
|
||||
|
||||
let format_enum_constructor (fmt : Format.formatter) (c : EnumConstructor.t) : unit =
|
||||
Format.fprintf fmt "%a"
|
||||
(Utils.Cli.format_with_style [ ANSITerminal.magenta ])
|
||||
(Format.asprintf "%a" EnumConstructor.format_t c)
|
||||
|
||||
let rec format_typ (ctx : Ast.decl_ctx) (fmt : Format.formatter) (typ : typ Pos.marked) : unit =
|
||||
let format_typ = format_typ ctx in
|
||||
let format_typ_with_parens (fmt : Format.formatter) (t : typ Pos.marked) =
|
||||
@ -75,37 +83,48 @@ let rec format_typ (ctx : Ast.decl_ctx) (fmt : Format.formatter) (typ : typ Pos.
|
||||
| TTuple (ts, None) ->
|
||||
Format.fprintf fmt "@[<hov 2>(%a)@]"
|
||||
(Format.pp_print_list
|
||||
~pp_sep:(fun fmt () -> Format.fprintf fmt "@ *@ ")
|
||||
~pp_sep:(fun fmt () -> Format.fprintf fmt "@ %a@ " format_operator "*")
|
||||
(fun fmt t -> Format.fprintf fmt "%a" format_typ t))
|
||||
ts
|
||||
| TTuple (args, Some s) ->
|
||||
Format.fprintf fmt "%a {%a}" Ast.StructName.format_t s
|
||||
(Format.pp_print_list ~pp_sep:(fun fmt () -> Format.fprintf fmt "@ ;@ ") format_typ)
|
||||
args
|
||||
| TEnum (_, e) -> Format.fprintf fmt "%a" Ast.EnumName.format_t e
|
||||
| TTuple (_args, Some s) ->
|
||||
Format.fprintf fmt "@[<hov 2>%a%a%a%a@]" Ast.StructName.format_t s format_punctuation "{"
|
||||
(Format.pp_print_list
|
||||
~pp_sep:(fun fmt () -> Format.fprintf fmt "%a@ " format_punctuation ";")
|
||||
(fun fmt (field, typ) ->
|
||||
Format.fprintf fmt "%a%a%a%a@ %a" format_punctuation "\"" StructFieldName.format_t
|
||||
field format_punctuation "\"" format_punctuation ":" format_typ typ))
|
||||
(StructMap.find s ctx.ctx_structs)
|
||||
format_punctuation "}"
|
||||
| TEnum (_, e) ->
|
||||
Format.fprintf fmt "@[<hov 2>%a%a%a%a@]" Ast.EnumName.format_t e format_punctuation "["
|
||||
(Format.pp_print_list
|
||||
~pp_sep:(fun fmt () -> Format.fprintf fmt "@ %a@ " format_punctuation "|")
|
||||
(fun fmt (case, typ) ->
|
||||
Format.fprintf fmt "%a%a@ %a" format_enum_constructor case format_punctuation ":"
|
||||
format_typ typ))
|
||||
(EnumMap.find e ctx.ctx_enums) format_punctuation "]"
|
||||
| TArrow (t1, t2) ->
|
||||
Format.fprintf fmt "@[<hov 2>%a %a@ %a@]" format_typ_with_parens t1 format_punctuation "→"
|
||||
Format.fprintf fmt "@[<hov 2>%a %a@ %a@]" format_typ_with_parens t1 format_operator "→"
|
||||
format_typ t2
|
||||
| TArray t1 -> Format.fprintf fmt "@[<hov 2>%a@ %a@]" format_base_type "array" format_typ t1
|
||||
| TAny -> Format.fprintf fmt "any"
|
||||
| TAny -> format_base_type fmt "any"
|
||||
|
||||
(* (EmileRolley) NOTE: seems to be factorizable with Lcalc.Print.format_lit. *)
|
||||
let format_lit (fmt : Format.formatter) (l : lit Pos.marked) : unit =
|
||||
match Pos.unmark l with
|
||||
| LBool b -> Format.fprintf fmt "%b" b
|
||||
| LInt i -> Format.fprintf fmt "%s" (Runtime.integer_to_string i)
|
||||
| LEmptyError -> Format.fprintf fmt "∅ "
|
||||
| LUnit -> Format.fprintf fmt "()"
|
||||
| LBool b -> format_lit_style fmt (string_of_bool b)
|
||||
| LInt i -> format_lit_style fmt (Runtime.integer_to_string i)
|
||||
| LEmptyError -> format_lit_style fmt "∅ "
|
||||
| LUnit -> format_lit_style fmt "()"
|
||||
| LRat i ->
|
||||
Format.fprintf fmt "%s"
|
||||
(Runtime.decimal_to_string ~max_prec_digits:!Utils.Cli.max_prec_digits i)
|
||||
format_lit_style fmt (Runtime.decimal_to_string ~max_prec_digits:!Utils.Cli.max_prec_digits i)
|
||||
| LMoney e -> (
|
||||
match !Utils.Cli.locale_lang with
|
||||
| En -> Format.fprintf fmt "$%s" (Runtime.money_to_string e)
|
||||
| Fr -> Format.fprintf fmt "%s €" (Runtime.money_to_string e)
|
||||
| Pl -> Format.fprintf fmt "%s PLN" (Runtime.money_to_string e))
|
||||
| LDate d -> Format.fprintf fmt "%s" (Runtime.date_to_string d)
|
||||
| LDuration d -> Format.fprintf fmt "%s" (Runtime.duration_to_string d)
|
||||
| En -> format_lit_style fmt (Format.asprintf "$%s" (Runtime.money_to_string e))
|
||||
| Fr -> format_lit_style fmt (Format.asprintf "%s €" (Runtime.money_to_string e))
|
||||
| Pl -> format_lit_style fmt (Format.asprintf "%s PLN" (Runtime.money_to_string e)))
|
||||
| LDate d -> format_lit_style fmt (Runtime.date_to_string d)
|
||||
| LDuration d -> format_lit_style fmt (Runtime.duration_to_string d)
|
||||
|
||||
let format_op_kind (fmt : Format.formatter) (k : op_kind) =
|
||||
Format.fprintf fmt "%s"
|
||||
@ -185,10 +204,10 @@ let rec format_expr ?(debug : bool = false) (ctx : Ast.decl_ctx) (fmt : Format.f
|
||||
Format.fprintf fmt "@[<hov 2>%a@ @[<hov 2>%a%a%a@]@]" Ast.StructName.format_t s
|
||||
format_punctuation "{"
|
||||
(Format.pp_print_list
|
||||
~pp_sep:(fun fmt () -> Format.fprintf fmt ",@ ")
|
||||
~pp_sep:(fun fmt () -> Format.fprintf fmt "%a@ " format_punctuation ";")
|
||||
(fun fmt (e, struct_field) ->
|
||||
Format.fprintf fmt "%a%a%a%a %a" format_punctuation "\"" Ast.StructFieldName.format_t
|
||||
struct_field format_punctuation "\"" format_punctuation ":" format_expr e))
|
||||
Format.fprintf fmt "%a%a%a%a@ %a" format_punctuation "\"" Ast.StructFieldName.format_t
|
||||
struct_field format_punctuation "\"" format_punctuation "=" format_expr e))
|
||||
(List.combine es (List.map fst (Ast.StructMap.find s ctx.ctx_structs)))
|
||||
format_punctuation "}"
|
||||
| EArray es ->
|
||||
@ -201,27 +220,24 @@ let rec format_expr ?(debug : bool = false) (ctx : Ast.decl_ctx) (fmt : Format.f
|
||||
match s with
|
||||
| None -> Format.fprintf fmt "%a%a%d" format_expr e1 format_punctuation "." n
|
||||
| Some s ->
|
||||
Format.fprintf fmt "%a%a%a%a%a" format_expr e1 format_punctuation "." format_punctuation
|
||||
"\"" Ast.StructFieldName.format_t
|
||||
Format.fprintf fmt "%a%a%a%a%a" format_expr e1 format_operator "." format_punctuation "\""
|
||||
Ast.StructFieldName.format_t
|
||||
(fst (List.nth (Ast.StructMap.find s ctx.ctx_structs) n))
|
||||
format_punctuation "\"")
|
||||
| EInj (e, n, en, _ts) ->
|
||||
Format.fprintf fmt "@[<hov 2>%a@ %a@]" Ast.EnumConstructor.format_t
|
||||
Format.fprintf fmt "@[<hov 2>%a@ %a@]" format_enum_constructor
|
||||
(fst (List.nth (Ast.EnumMap.find en ctx.ctx_enums) n))
|
||||
format_expr e
|
||||
| EMatch (e, es, e_name) ->
|
||||
Format.fprintf fmt "@[<hov 2>%a@ %a@ %a@ @[<hov 2>%a@]@]" format_keyword "match" format_expr e
|
||||
Format.fprintf fmt "@[<hov 0>%a@ @[<hov 2>%a@]@ %a@ %a@]" format_keyword "match" format_expr e
|
||||
format_keyword "with"
|
||||
(Format.pp_print_list
|
||||
~pp_sep:(fun fmt () -> Format.fprintf fmt "@\n| ")
|
||||
~pp_sep:(fun fmt () -> Format.fprintf fmt "@\n")
|
||||
(fun fmt (e, c) ->
|
||||
Format.fprintf fmt "@[<hov 2>%a%a@ %a@]" Ast.EnumConstructor.format_t c
|
||||
format_punctuation ":" format_expr e))
|
||||
Format.fprintf fmt "@[<hov 2>%a %a%a@ %a@]" format_punctuation "|"
|
||||
format_enum_constructor c format_punctuation ":" format_expr e))
|
||||
(List.combine es (List.map fst (Ast.EnumMap.find e_name ctx.ctx_enums)))
|
||||
| ELit l ->
|
||||
Format.fprintf fmt "%s"
|
||||
(Utils.Cli.print_with_style [ ANSITerminal.yellow ] "%s"
|
||||
(Format.asprintf "%a" format_lit (Pos.same_pos_as l e)))
|
||||
| ELit l -> format_lit fmt (Pos.same_pos_as l e)
|
||||
| EApp ((EAbs ((binder, _), taus), _), args) ->
|
||||
let xs, body = Bindlib.unmbind binder in
|
||||
let xs_tau = List.map2 (fun x tau -> (x, tau)) (Array.to_list xs) taus in
|
||||
@ -230,8 +246,8 @@ let rec format_expr ?(debug : bool = false) (ctx : Ast.decl_ctx) (fmt : Format.f
|
||||
(Format.pp_print_list
|
||||
~pp_sep:(fun fmt () -> Format.fprintf fmt "")
|
||||
(fun fmt (x, tau, arg) ->
|
||||
Format.fprintf fmt "@[<hov 2>%a@ @[<hov 2>%a@ %a@ %a@]@ %a@ %a@]@ %a@\n" format_keyword
|
||||
"let" format_var x format_punctuation ":" (format_typ ctx) tau format_punctuation "="
|
||||
Format.fprintf fmt "@[<hov 2>%a@ %a@ %a@ %a@ %a@ %a@ %a@]@\n" format_keyword "let"
|
||||
format_var x format_punctuation ":" (format_typ ctx) tau format_punctuation "="
|
||||
format_expr arg format_keyword "in"))
|
||||
xs_tau_arg format_expr body
|
||||
| EAbs ((binder, _), taus) ->
|
||||
@ -265,21 +281,23 @@ let rec format_expr ?(debug : bool = false) (ctx : Ast.decl_ctx) (fmt : Format.f
|
||||
| EOp (Unop op) -> Format.fprintf fmt "%a" format_unop (op, Pos.no_pos)
|
||||
| EDefault (exceptions, just, cons) ->
|
||||
if List.length exceptions = 0 then
|
||||
Format.fprintf fmt "@[<hov 2>%a%a@ %a@ %a@,%a@]" format_punctuation "⟨" format_expr just
|
||||
Format.fprintf fmt "@[<hov 2>%a%a@ %a@ %a%a@]" format_punctuation "⟨" format_expr just
|
||||
format_punctuation "⊢" format_expr cons format_punctuation "⟩"
|
||||
else
|
||||
Format.fprintf fmt "@[<hov 2>%a%a@ %a@ %a@ %a@ %a@,%a@]" format_punctuation "⟨"
|
||||
Format.fprintf fmt "@[<hov 2>%a%a@ %a@ %a@ %a@ %a%a@]" format_punctuation "⟨"
|
||||
(Format.pp_print_list
|
||||
~pp_sep:(fun fmt () -> Format.fprintf fmt "%a@ " format_punctuation ",")
|
||||
format_expr)
|
||||
exceptions format_punctuation "|" format_expr just format_punctuation "⊢" format_expr cons
|
||||
format_punctuation "⟩"
|
||||
| ErrorOnEmpty e' -> Format.fprintf fmt "error_empty@ %a" format_with_parens e'
|
||||
| ErrorOnEmpty e' ->
|
||||
Format.fprintf fmt "%a@ %a" format_operator "error_empty" format_with_parens e'
|
||||
| EAssert e' ->
|
||||
Format.fprintf fmt "@[<hov 2>%a@ %a%a%a@]" format_keyword "assert" format_punctuation "("
|
||||
format_expr e' format_punctuation ")"
|
||||
|
||||
let format_scope ?(debug : bool = false) (ctx : decl_ctx) (fmt : Format.formatter)
|
||||
((n, s) : Ast.ScopeName.t * scope_body) =
|
||||
Format.fprintf fmt "@[<hov 2>let %a =@ %a@]" Ast.ScopeName.format_t n (format_expr ctx ~debug)
|
||||
Format.fprintf fmt "@[<hov 2>%a %a =@ %a@]" format_keyword "let" Ast.ScopeName.format_t n
|
||||
(format_expr ctx ~debug)
|
||||
(Bindlib.unbox (Ast.build_whole_scope_expr ctx s (Pos.get_position (Ast.ScopeName.get_info n))))
|
||||
|
@ -22,10 +22,24 @@ val is_uppercase : CamomileLibraryDefault.Camomile.UChar.t -> bool
|
||||
|
||||
val begins_with_uppercase : string -> bool
|
||||
|
||||
(** {1 Common syntax highlighting helpers}*)
|
||||
|
||||
val format_base_type : Format.formatter -> string -> unit
|
||||
|
||||
val format_keyword : Format.formatter -> string -> unit
|
||||
|
||||
val format_punctuation : Format.formatter -> string -> unit
|
||||
|
||||
val format_operator : Format.formatter -> string -> unit
|
||||
|
||||
val format_lit_style : Format.formatter -> string -> unit
|
||||
|
||||
(** {1 Formatters} *)
|
||||
|
||||
val format_uid_list : Format.formatter -> Uid.MarkedString.info list -> unit
|
||||
|
||||
val format_enum_constructor : Format.formatter -> Ast.EnumConstructor.t -> unit
|
||||
|
||||
val format_tlit : Format.formatter -> Ast.typ_lit -> unit
|
||||
|
||||
val format_typ : Ast.decl_ctx -> Format.formatter -> Ast.typ Pos.marked -> unit
|
||||
|
@ -118,7 +118,7 @@ type scope_def = {
|
||||
scope_def_rules : rule RuleMap.t;
|
||||
scope_def_typ : Scopelang.Ast.typ Pos.marked;
|
||||
scope_def_is_condition : bool;
|
||||
scope_def_visibility : Scopelang.Ast.visibility;
|
||||
scope_def_io : Scopelang.Ast.io;
|
||||
scope_def_label_groups : RuleSet.t LabelMap.t;
|
||||
}
|
||||
|
||||
|
@ -79,7 +79,7 @@ type scope_def = {
|
||||
scope_def_rules : rule RuleMap.t;
|
||||
scope_def_typ : Scopelang.Ast.typ Pos.marked;
|
||||
scope_def_is_condition : bool;
|
||||
scope_def_visibility : Scopelang.Ast.visibility;
|
||||
scope_def_io : Scopelang.Ast.io;
|
||||
scope_def_label_groups : RuleSet.t LabelMap.t;
|
||||
}
|
||||
|
||||
|
@ -124,8 +124,8 @@ let rec rule_tree_to_expr ~(toplevel : bool) (def_pos : Pos.t)
|
||||
(** Translates a definition inside a scope, the resulting expression should be an {!constructor:
|
||||
Dcalc.Ast.EDefault} *)
|
||||
let translate_def (def_info : Ast.ScopeDef.t) (def : Ast.rule Ast.RuleMap.t)
|
||||
(typ : Scopelang.Ast.typ Pos.marked) ~(is_cond : bool) ~(is_subscope_var : bool) :
|
||||
Scopelang.Ast.expr Pos.marked =
|
||||
(typ : Scopelang.Ast.typ Pos.marked) (io : Scopelang.Ast.io) ~(is_cond : bool)
|
||||
~(is_subscope_var : bool) : Scopelang.Ast.expr Pos.marked =
|
||||
(* Here, we have to transform this list of rules into a default tree. *)
|
||||
let is_def_func = match Pos.unmark typ with Scopelang.Ast.TArrow (_, _) -> true | _ -> false in
|
||||
let is_rule_func _ (r : Ast.rule) : bool = Option.is_some r.Ast.rule_parameter in
|
||||
@ -161,7 +161,8 @@ let translate_def (def_info : Ast.ScopeDef.t) (def : Ast.rule Ast.RuleMap.t)
|
||||
(if is_cond then Ast.always_false_rule else Ast.empty_rule) Pos.no_pos is_def_func_param_typ
|
||||
in
|
||||
if
|
||||
Ast.RuleMap.cardinal def = 0 && is_subscope_var
|
||||
Ast.RuleMap.cardinal def = 0
|
||||
&& is_subscope_var
|
||||
(* Here we have a special case for the empty definitions. Indeed, we could use the code for the
|
||||
regular case below that would create a convoluted default always returning empty error, and
|
||||
this would be correct. But it gets more complicated with functions. Indeed, if we create an
|
||||
@ -176,6 +177,12 @@ let translate_def (def_info : Ast.ScopeDef.t) (def : Ast.rule Ast.RuleMap.t)
|
||||
To avoid this complication we special case here and put an empty error for all subscope
|
||||
variables that are not defined. It covers the subtlety with functions described above but
|
||||
also conditions with the false default value. *)
|
||||
&& not
|
||||
(is_cond
|
||||
&& match Pos.unmark io.Scopelang.Ast.io_input with OnlyInput -> true | _ -> false)
|
||||
(* However, this special case suffers from an exception: when a condition is defined as an
|
||||
OnlyInput to a subscope, since the [false] default value will not be provided by the calee
|
||||
scope, it has to be placed in the caller. *)
|
||||
then (ELit LEmptyError, Pos.no_pos)
|
||||
else
|
||||
Bindlib.unbox
|
||||
@ -198,29 +205,60 @@ let translate_scope (scope : Ast.scope) : Scopelang.Ast.scope_decl =
|
||||
(List.map
|
||||
(fun vertex ->
|
||||
match vertex with
|
||||
| Dependency.Vertex.Var (var : Scopelang.Ast.ScopeVar.t) ->
|
||||
| Dependency.Vertex.Var (var : Scopelang.Ast.ScopeVar.t) -> (
|
||||
let scope_def = Ast.ScopeDefMap.find (Ast.ScopeDef.Var var) scope.scope_defs in
|
||||
let var_def = scope_def.scope_def_rules in
|
||||
let var_typ = scope_def.scope_def_typ in
|
||||
let is_cond = scope_def.scope_def_is_condition in
|
||||
let expr_def =
|
||||
translate_def (Ast.ScopeDef.Var var) var_def var_typ ~is_cond
|
||||
~is_subscope_var:false
|
||||
in
|
||||
[
|
||||
Scopelang.Ast.Definition
|
||||
( ( Scopelang.Ast.ScopeVar
|
||||
(var, Pos.get_position (Scopelang.Ast.ScopeVar.get_info var)),
|
||||
Pos.get_position (Scopelang.Ast.ScopeVar.get_info var) ),
|
||||
var_typ,
|
||||
expr_def );
|
||||
]
|
||||
match Pos.unmark scope_def.Ast.scope_def_io.io_input with
|
||||
| OnlyInput when not (Ast.RuleMap.is_empty var_def) ->
|
||||
(* If the variable is tagged as input, then it shall not be redefined. *)
|
||||
Errors.raise_multispanned_error
|
||||
"It is impossible to give a definition to a scope variable tagged as input."
|
||||
(( Some "Incriminated variable:",
|
||||
Pos.get_position (Scopelang.Ast.ScopeVar.get_info var) )
|
||||
:: List.map
|
||||
(fun (rule, _) ->
|
||||
( Some "Incriminated variable definition:",
|
||||
Pos.get_position (Ast.RuleName.get_info rule) ))
|
||||
(Ast.RuleMap.bindings var_def))
|
||||
| OnlyInput -> [] (* we do not provide any definition for an input-only variable *)
|
||||
| _ ->
|
||||
let expr_def =
|
||||
translate_def (Ast.ScopeDef.Var var) var_def var_typ scope_def.Ast.scope_def_io
|
||||
~is_cond ~is_subscope_var:false
|
||||
in
|
||||
[
|
||||
Scopelang.Ast.Definition
|
||||
( ( Scopelang.Ast.ScopeVar
|
||||
(var, Pos.get_position (Scopelang.Ast.ScopeVar.get_info var)),
|
||||
Pos.get_position (Scopelang.Ast.ScopeVar.get_info var) ),
|
||||
var_typ,
|
||||
scope_def.Ast.scope_def_io,
|
||||
expr_def );
|
||||
])
|
||||
| Dependency.Vertex.SubScope sub_scope_index ->
|
||||
(* Before calling the sub_scope, we need to include all the re-definitions of
|
||||
subscope parameters*)
|
||||
let sub_scope =
|
||||
Scopelang.Ast.SubScopeMap.find sub_scope_index scope.scope_sub_scopes
|
||||
in
|
||||
let sub_scope_vars_redefs_candidates =
|
||||
Ast.ScopeDefMap.filter
|
||||
(fun def_key scope_def ->
|
||||
match def_key with
|
||||
| Ast.ScopeDef.Var _ -> false
|
||||
| Ast.ScopeDef.SubScopeVar (sub_scope_index', _) ->
|
||||
sub_scope_index = sub_scope_index'
|
||||
(* We exclude subscope variables that have 0 re-definitions and are not
|
||||
visible in the input of the subscope *)
|
||||
&& not
|
||||
((match Pos.unmark scope_def.Ast.scope_def_io.io_input with
|
||||
| Scopelang.Ast.NoInput -> true
|
||||
| _ -> false)
|
||||
&& Ast.RuleMap.is_empty scope_def.scope_def_rules))
|
||||
scope.scope_defs
|
||||
in
|
||||
let sub_scope_vars_redefs =
|
||||
Ast.ScopeDefMap.mapi
|
||||
(fun def_key scope_def ->
|
||||
@ -230,8 +268,41 @@ let translate_scope (scope : Ast.scope) : Scopelang.Ast.scope_decl =
|
||||
match def_key with
|
||||
| Ast.ScopeDef.Var _ -> assert false (* should not happen *)
|
||||
| Ast.ScopeDef.SubScopeVar (_, sub_scope_var) ->
|
||||
(* This definition redefines a variable of the correct subscope. But we
|
||||
have to check that this redefinition is allowed with respect to the io
|
||||
parameters of that subscope variable. *)
|
||||
(match Pos.unmark scope_def.Ast.scope_def_io.io_input with
|
||||
| Scopelang.Ast.NoInput ->
|
||||
Errors.raise_multispanned_error
|
||||
"It is impossible to give a definition to a subscope variable not \
|
||||
tagged as input or context."
|
||||
((Some "Incriminated subscope:", Ast.ScopeDef.get_position def_key)
|
||||
:: ( Some "Incriminated variable:",
|
||||
Pos.get_position (Scopelang.Ast.ScopeVar.get_info sub_scope_var)
|
||||
)
|
||||
:: List.map
|
||||
(fun (rule, _) ->
|
||||
( Some "Incriminated subscope variable definition:",
|
||||
Pos.get_position (Ast.RuleName.get_info rule) ))
|
||||
(Ast.RuleMap.bindings def))
|
||||
| OnlyInput when Ast.RuleMap.is_empty def && not is_cond ->
|
||||
(* If the subscope variable is tagged as input, then it shall be
|
||||
defined. *)
|
||||
Errors.raise_multispanned_error
|
||||
"This subscope variable is a mandatory input but no definition was \
|
||||
provided."
|
||||
[
|
||||
(Some "Incriminated subscope:", Ast.ScopeDef.get_position def_key);
|
||||
( Some "Incriminated variable:",
|
||||
Pos.get_position (Scopelang.Ast.ScopeVar.get_info sub_scope_var)
|
||||
);
|
||||
]
|
||||
| _ -> ());
|
||||
(* Now that all is good, we can proceed with translating this redefinition
|
||||
to a proper Scopelang term. *)
|
||||
let expr_def =
|
||||
translate_def def_key def def_typ ~is_cond ~is_subscope_var:true
|
||||
translate_def def_key def def_typ scope_def.Ast.scope_def_io ~is_cond
|
||||
~is_subscope_var:true
|
||||
in
|
||||
let subscop_real_name =
|
||||
Scopelang.Ast.SubScopeMap.find sub_scope_index scope.scope_sub_scopes
|
||||
@ -246,14 +317,9 @@ let translate_scope (scope : Ast.scope) : Scopelang.Ast.scope_decl =
|
||||
(sub_scope_var, var_pos) ),
|
||||
var_pos ),
|
||||
def_typ,
|
||||
scope_def.Ast.scope_def_io,
|
||||
expr_def ))
|
||||
(Ast.ScopeDefMap.filter
|
||||
(fun def_key _def ->
|
||||
match def_key with
|
||||
| Ast.ScopeDef.Var _ -> false
|
||||
| Ast.ScopeDef.SubScopeVar (sub_scope_index', _) ->
|
||||
sub_scope_index = sub_scope_index')
|
||||
scope.scope_defs)
|
||||
sub_scope_vars_redefs_candidates
|
||||
in
|
||||
let sub_scope_vars_redefs =
|
||||
List.map snd (Ast.ScopeDefMap.bindings sub_scope_vars_redefs)
|
||||
@ -269,8 +335,9 @@ let translate_scope (scope : Ast.scope) : Scopelang.Ast.scope_decl =
|
||||
let scope_sig =
|
||||
Scopelang.Ast.ScopeVarSet.fold
|
||||
(fun var acc ->
|
||||
let typ = (Ast.ScopeDefMap.find (Ast.ScopeDef.Var var) scope.scope_defs).scope_def_typ in
|
||||
Scopelang.Ast.ScopeVarMap.add var typ acc)
|
||||
let scope_def = Ast.ScopeDefMap.find (Ast.ScopeDef.Var var) scope.scope_defs in
|
||||
let typ = scope_def.scope_def_typ in
|
||||
Scopelang.Ast.ScopeVarMap.add var (typ, scope_def.scope_def_io) acc)
|
||||
scope.scope_vars Scopelang.Ast.ScopeVarMap.empty
|
||||
in
|
||||
{
|
||||
|
@ -72,6 +72,8 @@ let driver (source_file : Pos.input_file) (debug : bool) (unstyled : bool)
|
||||
else if backend = "python" then Cli.Python
|
||||
else if backend = "proof" then Cli.Proof
|
||||
else if backend = "typecheck" then Cli.Typecheck
|
||||
else if backend = "lcalc" then Cli.Lcalc
|
||||
else if backend = "scalc" then Cli.Scalc
|
||||
else
|
||||
Errors.raise_error
|
||||
(Printf.sprintf "The selected backend (%s) is not supported by Catala" backend)
|
||||
@ -205,7 +207,7 @@ let driver (source_file : Pos.input_file) (debug : bool) (unstyled : bool)
|
||||
in
|
||||
if Option.is_some ex_scope then
|
||||
Format.fprintf fmt "%a\n"
|
||||
(Dcalc.Print.format_scope prgm.decl_ctx)
|
||||
(Dcalc.Print.format_scope ~debug prgm.decl_ctx)
|
||||
(let _, _, s = List.find (fun (name, _, _) -> name = scope_uid) prgm.scopes in
|
||||
(scope_uid, s))
|
||||
else Format.fprintf fmt "%a\n" (Dcalc.Print.format_expr prgm.decl_ctx) prgrm_dcalc_expr;
|
||||
@ -251,7 +253,7 @@ let driver (source_file : Pos.input_file) (debug : bool) (unstyled : bool)
|
||||
result))
|
||||
results;
|
||||
0
|
||||
| Cli.OCaml | Cli.Python ->
|
||||
| Cli.OCaml | Cli.Python | Cli.Lcalc | Cli.Scalc ->
|
||||
Cli.debug_print "Compiling program into lambda calculus...";
|
||||
let prgm = Lcalc.Compile_with_exceptions.translate_program prgm in
|
||||
let prgm =
|
||||
@ -261,29 +263,79 @@ let driver (source_file : Pos.input_file) (debug : bool) (unstyled : bool)
|
||||
end
|
||||
else prgm
|
||||
in
|
||||
if backend = Cli.Lcalc then begin
|
||||
let fmt, at_end =
|
||||
match output_file with
|
||||
| Some f ->
|
||||
let oc = open_out f in
|
||||
(Format.formatter_of_out_channel oc, fun _ -> close_out oc)
|
||||
| None -> (Format.std_formatter, fun _ -> ())
|
||||
in
|
||||
if Option.is_some ex_scope then
|
||||
Format.fprintf fmt "%a\n"
|
||||
(Lcalc.Print.format_scope ~debug prgm.decl_ctx)
|
||||
(let body =
|
||||
List.find (fun body -> body.Lcalc.Ast.scope_body_name = scope_uid) prgm.scopes
|
||||
in
|
||||
body)
|
||||
else
|
||||
Format.fprintf fmt "%a\n"
|
||||
(Format.pp_print_list
|
||||
~pp_sep:(fun fmt () -> Format.fprintf fmt "\n\n")
|
||||
(fun fmt scope -> (Lcalc.Print.format_scope prgm.decl_ctx) fmt scope))
|
||||
prgm.scopes;
|
||||
at_end ();
|
||||
exit 0
|
||||
end;
|
||||
let source_file =
|
||||
match source_file with
|
||||
| FileName f -> f
|
||||
| Contents _ ->
|
||||
Errors.raise_error "This backend does not work if the input is not a file"
|
||||
in
|
||||
let output_file (extension : string) : string =
|
||||
let new_output_file (extension : string) : string =
|
||||
match output_file with
|
||||
| Some f -> f
|
||||
| None -> Filename.remove_extension source_file ^ extension
|
||||
in
|
||||
(match backend with
|
||||
| Cli.OCaml ->
|
||||
let output_file = output_file ".ml" in
|
||||
let output_file = new_output_file ".ml" in
|
||||
Cli.debug_print (Printf.sprintf "Writing to %s..." output_file);
|
||||
let oc = open_out output_file in
|
||||
let fmt = Format.formatter_of_out_channel oc in
|
||||
Cli.debug_print "Compiling program into OCaml...";
|
||||
Lcalc.To_ocaml.format_program fmt prgm type_ordering;
|
||||
close_out oc
|
||||
| Cli.Python ->
|
||||
| Cli.Python | Cli.Scalc ->
|
||||
let prgm = Scalc.Compile_from_lambda.translate_program prgm in
|
||||
let output_file = output_file ".py" in
|
||||
if backend = Cli.Scalc then begin
|
||||
let fmt, at_end =
|
||||
match output_file with
|
||||
| Some f ->
|
||||
let oc = open_out f in
|
||||
(Format.formatter_of_out_channel oc, fun _ -> close_out oc)
|
||||
| None -> (Format.std_formatter, fun _ -> ())
|
||||
in
|
||||
if Option.is_some ex_scope then
|
||||
Format.fprintf fmt "%a\n"
|
||||
(Scalc.Print.format_scope ~debug prgm.decl_ctx)
|
||||
(let body =
|
||||
List.find
|
||||
(fun body -> body.Scalc.Ast.scope_body_name = scope_uid)
|
||||
prgm.scopes
|
||||
in
|
||||
body)
|
||||
else
|
||||
Format.fprintf fmt "%a\n"
|
||||
(Format.pp_print_list
|
||||
~pp_sep:(fun fmt () -> Format.fprintf fmt "\n\n")
|
||||
(fun fmt scope -> (Scalc.Print.format_scope prgm.decl_ctx) fmt scope))
|
||||
prgm.scopes;
|
||||
at_end ();
|
||||
exit 0
|
||||
end;
|
||||
let output_file = new_output_file ".py" in
|
||||
Cli.debug_print "Compiling program into Python...";
|
||||
Cli.debug_print (Printf.sprintf "Writing to %s..." output_file);
|
||||
let oc = open_out output_file in
|
||||
@ -303,7 +355,7 @@ let driver (source_file : Pos.input_file) (debug : bool) (unstyled : bool)
|
||||
-1
|
||||
|
||||
let main () =
|
||||
let return_code = Cmdliner.Term.eval (Cli.catala_t (fun f -> driver (FileName f)), Cli.info) in
|
||||
match return_code with
|
||||
| `Ok 0 -> Cmdliner.Term.exit (`Ok 0)
|
||||
| _ -> Cmdliner.Term.exit (`Error `Term)
|
||||
let return_code =
|
||||
Cmdliner.Cmd.eval' (Cmdliner.Cmd.v Cli.info (Cli.catala_t (fun f -> driver (FileName f))))
|
||||
in
|
||||
exit return_code
|
||||
|
@ -88,4 +88,10 @@ let handle_default = Var.make ("handle_default", Pos.no_pos)
|
||||
|
||||
type binder = (expr, expr Pos.marked) Bindlib.binder
|
||||
|
||||
type program = { decl_ctx : D.decl_ctx; scopes : (Var.t * expr Pos.marked) list }
|
||||
type scope_body = {
|
||||
scope_body_name : Dcalc.Ast.ScopeName.t;
|
||||
scope_body_var : Var.t;
|
||||
scope_body_expr : expr Pos.marked;
|
||||
}
|
||||
|
||||
type program = { decl_ctx : D.decl_ctx; scopes : scope_body list }
|
||||
|
@ -94,4 +94,10 @@ val handle_default : Var.t
|
||||
|
||||
type binder = (expr, expr Pos.marked) Bindlib.binder
|
||||
|
||||
type program = { decl_ctx : Dcalc.Ast.decl_ctx; scopes : (Var.t * expr Pos.marked) list }
|
||||
type scope_body = {
|
||||
scope_body_name : Dcalc.Ast.ScopeName.t;
|
||||
scope_body_var : Var.t;
|
||||
scope_body_expr : expr Pos.marked;
|
||||
}
|
||||
|
||||
type program = { decl_ctx : Dcalc.Ast.decl_ctx; scopes : scope_body list }
|
||||
|
@ -138,13 +138,17 @@ let translate_program (prgm : D.program) : A.program =
|
||||
(fun ((acc, ctx) : _ * A.Var.t D.VarMap.t) (scope_name, n, e) ->
|
||||
let new_n = A.Var.make (Bindlib.name_of n, Pos.no_pos) in
|
||||
let new_acc =
|
||||
( new_n,
|
||||
Bindlib.unbox
|
||||
(translate_expr
|
||||
(D.VarMap.map (fun v -> A.make_var (v, Pos.no_pos)) ctx)
|
||||
(Bindlib.unbox
|
||||
(D.build_whole_scope_expr prgm.decl_ctx e
|
||||
(Pos.get_position (Dcalc.Ast.ScopeName.get_info scope_name))))) )
|
||||
{
|
||||
Ast.scope_body_name = scope_name;
|
||||
scope_body_var = new_n;
|
||||
scope_body_expr =
|
||||
Bindlib.unbox
|
||||
(translate_expr
|
||||
(D.VarMap.map (fun v -> A.make_var (v, Pos.no_pos)) ctx)
|
||||
(Bindlib.unbox
|
||||
(D.build_whole_scope_expr prgm.decl_ctx e
|
||||
(Pos.get_position (Dcalc.Ast.ScopeName.get_info scope_name)))));
|
||||
}
|
||||
:: acc
|
||||
in
|
||||
let new_ctx = D.VarMap.add n new_n ctx in
|
||||
|
@ -7,7 +7,7 @@ default term, which has been eliminated through diverse compilation schemes.
|
||||
|
||||
The module describing the abstract syntax tree is:
|
||||
|
||||
{!modules: Lcalc.Ast}
|
||||
{!modules: Lcalc.Ast Lcalc.Print}
|
||||
|
||||
This intermediate representation corresponds to the lambda calculus
|
||||
presented in the {{: https://arxiv.org/abs/2103.03198} Catala formalization}.
|
||||
|
@ -67,6 +67,16 @@ let rec peephole_expr (e : expr Pos.marked) : expr Pos.marked Bindlib.box =
|
||||
| ERaise _ | ELit _ | EOp _ -> Bindlib.box e
|
||||
|
||||
let peephole_optimizations (p : program) : program =
|
||||
{ p with scopes = List.map (fun (var, e) -> (var, Bindlib.unbox (peephole_expr e))) p.scopes }
|
||||
{
|
||||
p with
|
||||
scopes =
|
||||
List.map
|
||||
(fun scope_body ->
|
||||
{
|
||||
scope_body with
|
||||
scope_body_expr = Bindlib.unbox (peephole_expr scope_body.scope_body_expr);
|
||||
})
|
||||
p.scopes;
|
||||
}
|
||||
|
||||
let optimize_program (p : program) : program = peephole_optimizations p
|
||||
|
@ -30,33 +30,23 @@ let begins_with_uppercase (s : string) : bool =
|
||||
(** @note: (EmileRolley) seems to be factorizable with Dcalc.Print.format_lit. *)
|
||||
let format_lit (fmt : Format.formatter) (l : lit Pos.marked) : unit =
|
||||
match Pos.unmark l with
|
||||
| LBool b -> Format.fprintf fmt "%b" b
|
||||
| LInt i -> Format.fprintf fmt "%s" (Runtime.integer_to_string i)
|
||||
| LUnit -> Format.fprintf fmt "()"
|
||||
| LBool b -> Dcalc.Print.format_lit_style fmt (string_of_bool b)
|
||||
| LInt i -> Dcalc.Print.format_lit_style fmt (Runtime.integer_to_string i)
|
||||
| LUnit -> Dcalc.Print.format_lit_style fmt "()"
|
||||
| LRat i ->
|
||||
Format.fprintf fmt "%s"
|
||||
Dcalc.Print.format_lit_style fmt
|
||||
(Runtime.decimal_to_string ~max_prec_digits:!Utils.Cli.max_prec_digits i)
|
||||
| LMoney e -> (
|
||||
match !Utils.Cli.locale_lang with
|
||||
| En -> Format.fprintf fmt "$%s" (Runtime.money_to_string e)
|
||||
| Fr -> Format.fprintf fmt "%s €" (Runtime.money_to_string e)
|
||||
| Pl -> Format.fprintf fmt "%s PLN" (Runtime.money_to_string e))
|
||||
| LDate d -> Format.fprintf fmt "%s" (Runtime.date_to_string d)
|
||||
| LDuration d -> Format.fprintf fmt "%s" (Runtime.duration_to_string d)
|
||||
|
||||
let format_uid_list (fmt : Format.formatter) (infos : Uid.MarkedString.info list) : unit =
|
||||
Format.fprintf fmt "%a"
|
||||
(Format.pp_print_list
|
||||
~pp_sep:(fun fmt () -> Format.fprintf fmt ".")
|
||||
(fun fmt info ->
|
||||
Format.fprintf fmt "%a"
|
||||
(Utils.Cli.format_with_style
|
||||
(if begins_with_uppercase (Pos.unmark info) then [ ANSITerminal.red ] else []))
|
||||
(Format.asprintf "%a" Utils.Uid.MarkedString.format_info info)))
|
||||
infos
|
||||
| En -> Dcalc.Print.format_lit_style fmt (Format.asprintf "$%s" (Runtime.money_to_string e))
|
||||
| Fr -> Dcalc.Print.format_lit_style fmt (Format.asprintf "%s €" (Runtime.money_to_string e))
|
||||
| Pl ->
|
||||
Dcalc.Print.format_lit_style fmt (Format.asprintf "%s PLN" (Runtime.money_to_string e)))
|
||||
| LDate d -> Dcalc.Print.format_lit_style fmt (Runtime.date_to_string d)
|
||||
| LDuration d -> Dcalc.Print.format_lit_style fmt (Runtime.duration_to_string d)
|
||||
|
||||
let format_exception (fmt : Format.formatter) (exn : except) : unit =
|
||||
Format.fprintf fmt
|
||||
Dcalc.Print.format_operator fmt
|
||||
(match exn with
|
||||
| EmptyError -> "EmptyError"
|
||||
| ConflictError -> "ConflictError"
|
||||
@ -75,9 +65,9 @@ let needs_parens (e : expr Pos.marked) : bool =
|
||||
let format_var (fmt : Format.formatter) (v : Var.t) : unit =
|
||||
Format.fprintf fmt "%s" (Bindlib.name_of v)
|
||||
|
||||
let rec format_expr (ctx : Dcalc.Ast.decl_ctx) (fmt : Format.formatter) (e : expr Pos.marked) : unit
|
||||
=
|
||||
let format_expr = format_expr ctx in
|
||||
let rec format_expr (ctx : Dcalc.Ast.decl_ctx) ?(debug : bool = false) (fmt : Format.formatter)
|
||||
(e : expr Pos.marked) : unit =
|
||||
let format_expr = format_expr ctx ~debug in
|
||||
let format_with_parens (fmt : Format.formatter) (e : expr Pos.marked) =
|
||||
if needs_parens e then
|
||||
Format.fprintf fmt "%a%a%a" format_punctuation "(" format_expr e format_punctuation ")"
|
||||
@ -92,8 +82,8 @@ let rec format_expr (ctx : Dcalc.Ast.decl_ctx) (fmt : Format.formatter) (e : exp
|
||||
(fun fmt e -> Format.fprintf fmt "%a" format_expr e))
|
||||
es format_punctuation ")"
|
||||
| ETuple (es, Some s) ->
|
||||
Format.fprintf fmt "@[<hov 2>%a@ @[<hov 2>%a%a%a@]@]" Dcalc.Ast.StructName.format_t s
|
||||
format_punctuation "{"
|
||||
Format.fprintf fmt "@[<hov 2>%a@ %a%a%a@]" Dcalc.Ast.StructName.format_t s format_punctuation
|
||||
"{"
|
||||
(Format.pp_print_list
|
||||
~pp_sep:(fun fmt () -> Format.fprintf fmt ",@ ")
|
||||
(fun fmt (e, struct_field) ->
|
||||
@ -117,17 +107,17 @@ let rec format_expr (ctx : Dcalc.Ast.decl_ctx) (fmt : Format.formatter) (e : exp
|
||||
(fst (List.nth (Dcalc.Ast.StructMap.find s ctx.ctx_structs) n))
|
||||
format_punctuation "\"")
|
||||
| EInj (e, n, en, _ts) ->
|
||||
Format.fprintf fmt "@[<hov 2>%a@ %a@]" Dcalc.Ast.EnumConstructor.format_t
|
||||
Format.fprintf fmt "@[<hov 2>%a@ %a@]" Dcalc.Print.format_enum_constructor
|
||||
(fst (List.nth (Dcalc.Ast.EnumMap.find en ctx.ctx_enums) n))
|
||||
format_expr e
|
||||
| EMatch (e, es, e_name) ->
|
||||
Format.fprintf fmt "@[<hov 2>%a@ %a@ %a@ @[<hov 2>%a@]@]" format_keyword "match" format_expr e
|
||||
Format.fprintf fmt "@[<hov 0>%a@ @[<hov 2>%a@]@ %a@ %a@]" format_keyword "match" format_expr e
|
||||
format_keyword "with"
|
||||
(Format.pp_print_list
|
||||
~pp_sep:(fun fmt () -> Format.fprintf fmt "@\n| ")
|
||||
~pp_sep:(fun fmt () -> Format.fprintf fmt "@\n")
|
||||
(fun fmt (e, c) ->
|
||||
Format.fprintf fmt "@[<hov 2>%a%a@ %a@]" Dcalc.Ast.EnumConstructor.format_t c
|
||||
format_punctuation ":" format_expr e))
|
||||
Format.fprintf fmt "@[<hov 2>%a %a%a@ %a@]" format_punctuation "|"
|
||||
Dcalc.Print.format_enum_constructor c format_punctuation ":" format_expr e))
|
||||
(List.combine es (List.map fst (Dcalc.Ast.EnumMap.find e_name ctx.ctx_enums)))
|
||||
| ELit l -> Format.fprintf fmt "%a" format_lit (Pos.same_pos_as l e)
|
||||
| EApp ((EAbs ((binder, _), taus), _), args) ->
|
||||
@ -138,14 +128,14 @@ let rec format_expr (ctx : Dcalc.Ast.decl_ctx) (fmt : Format.formatter) (e : exp
|
||||
(Format.pp_print_list
|
||||
~pp_sep:(fun fmt () -> Format.fprintf fmt "")
|
||||
(fun fmt (x, tau, arg) ->
|
||||
Format.fprintf fmt "@[<hov 2>%a@ @[<hov 2>%a@ %a@ %a@]@ %a@ %a@]@ %a@\n" format_keyword
|
||||
"let" format_var x format_punctuation ":" (Dcalc.Print.format_typ ctx) tau
|
||||
Format.fprintf fmt "@[<hov 2>%a@ %a@ %a@ %a@ %a@ %a@ %a@]@\n" format_keyword "let"
|
||||
format_var x format_punctuation ":" (Dcalc.Print.format_typ ctx) tau
|
||||
format_punctuation "=" format_expr arg format_keyword "in"))
|
||||
xs_tau_arg format_expr body
|
||||
| EAbs ((binder, _), taus) ->
|
||||
let xs, body = Bindlib.unmbind binder in
|
||||
let xs_tau = List.map2 (fun x tau -> (x, tau)) (Array.to_list xs) taus in
|
||||
Format.fprintf fmt "@[<hov 2>%a @[<hov 2>%a@] %a@ %a@]" format_punctuation "λ"
|
||||
Format.fprintf fmt "@[<hov 2>%a %a %a@ %a@]" format_punctuation "λ"
|
||||
(Format.pp_print_list
|
||||
~pp_sep:(fun fmt () -> Format.fprintf fmt "@ ")
|
||||
(fun fmt (x, tau) ->
|
||||
@ -158,7 +148,7 @@ let rec format_expr (ctx : Dcalc.Ast.decl_ctx) (fmt : Format.formatter) (e : exp
|
||||
| EApp ((EOp (Binop op), _), [ arg1; arg2 ]) ->
|
||||
Format.fprintf fmt "@[<hov 2>%a@ %a@ %a@]" format_with_parens arg1 Dcalc.Print.format_binop
|
||||
(op, Pos.no_pos) format_with_parens arg2
|
||||
| EApp ((EOp (Unop (Log _)), _), [ arg1 ]) when not !Cli.debug_flag ->
|
||||
| EApp ((EOp (Unop (Log _)), _), [ arg1 ]) when not debug ->
|
||||
Format.fprintf fmt "%a" format_with_parens arg1
|
||||
| EApp ((EOp (Unop op), _), [ arg1 ]) ->
|
||||
Format.fprintf fmt "@[<hov 2>%a@ %a@]" Dcalc.Print.format_unop (op, Pos.no_pos)
|
||||
@ -174,9 +164,14 @@ let rec format_expr (ctx : Dcalc.Ast.decl_ctx) (fmt : Format.formatter) (e : exp
|
||||
| EOp (Binop op) -> Format.fprintf fmt "%a" Dcalc.Print.format_binop (op, Pos.no_pos)
|
||||
| EOp (Unop op) -> Format.fprintf fmt "%a" Dcalc.Print.format_unop (op, Pos.no_pos)
|
||||
| ECatch (e1, exn, e2) ->
|
||||
Format.fprintf fmt "@[<hov 2>try@ %a@ with@ %a ->@ %a@]" format_with_parens e1
|
||||
format_exception exn format_with_parens e2
|
||||
| ERaise exn -> Format.fprintf fmt "@[<hov 2>raise@ %a@]" format_exception exn
|
||||
Format.fprintf fmt "@[<hov 2>%a@ %a@ %a@ %a ->@ %a@]" format_keyword "try" format_with_parens
|
||||
e1 format_keyword "with" format_exception exn format_with_parens e2
|
||||
| ERaise exn -> Format.fprintf fmt "@[<hov 2>%a@ %a@]" format_keyword "raise" format_exception exn
|
||||
| EAssert e' ->
|
||||
Format.fprintf fmt "@[<hov 2>%a@ %a%a%a@]" format_keyword "assert" format_punctuation "("
|
||||
format_expr e' format_punctuation ")"
|
||||
|
||||
let format_scope (decl_ctx : Dcalc.Ast.decl_ctx) ?(debug : bool = false) (fmt : Format.formatter)
|
||||
(body : scope_body) : unit =
|
||||
Format.fprintf fmt "@[<hov 2>%a %a %a@ %a@]" format_keyword "let" format_var body.scope_body_var
|
||||
format_punctuation "=" (format_expr decl_ctx ~debug) body.scope_body_expr
|
||||
|
@ -22,10 +22,13 @@ val begins_with_uppercase : string -> bool
|
||||
|
||||
(** {1 Formatters} *)
|
||||
|
||||
val format_uid_list : Format.formatter -> Uid.MarkedString.info list -> unit
|
||||
|
||||
val format_lit : Format.formatter -> Ast.lit Pos.marked -> unit
|
||||
|
||||
val format_var : Format.formatter -> Ast.Var.t -> unit
|
||||
|
||||
val format_expr : Dcalc.Ast.decl_ctx -> Format.formatter -> Ast.expr Pos.marked -> unit
|
||||
val format_exception : Format.formatter -> Ast.except -> unit
|
||||
|
||||
val format_expr :
|
||||
Dcalc.Ast.decl_ctx -> ?debug:bool -> Format.formatter -> Ast.expr Pos.marked -> unit
|
||||
|
||||
val format_scope : Dcalc.Ast.decl_ctx -> ?debug:bool -> Format.formatter -> Ast.scope_body -> unit
|
||||
|
@ -433,6 +433,7 @@ let format_program (fmt : Format.formatter) (p : Ast.program)
|
||||
(format_ctx type_ordering) p.decl_ctx
|
||||
(Format.pp_print_list
|
||||
~pp_sep:(fun fmt () -> Format.fprintf fmt "@\n@\n")
|
||||
(fun fmt (name, e) ->
|
||||
Format.fprintf fmt "@[<hov 2>let@ %a@ =@ %a@]" format_var name (format_expr p.decl_ctx) e))
|
||||
(fun fmt body ->
|
||||
Format.fprintf fmt "@[<hov 2>let@ %a@ =@ %a@]" format_var body.scope_body_var
|
||||
(format_expr p.decl_ctx) body.scope_body_expr))
|
||||
p.scopes
|
||||
|
@ -51,4 +51,10 @@ and block = stmt Pos.marked list
|
||||
|
||||
and func = { func_params : (LocalName.t Pos.marked * D.typ Pos.marked) list; func_body : block }
|
||||
|
||||
type program = { decl_ctx : D.decl_ctx; scopes : (TopLevelName.t * func) list }
|
||||
type scope_body = {
|
||||
scope_body_name : Dcalc.Ast.ScopeName.t;
|
||||
scope_body_var : TopLevelName.t;
|
||||
scope_body_func : func;
|
||||
}
|
||||
|
||||
type program = { decl_ctx : D.decl_ctx; scopes : scope_body list }
|
||||
|
@ -244,14 +244,21 @@ let translate_program (p : L.program) : A.program =
|
||||
scopes =
|
||||
(let _, new_scopes =
|
||||
List.fold_left
|
||||
(fun (func_dict, new_scopes) (scope_name, scope_expr) ->
|
||||
(fun (func_dict, new_scopes) body ->
|
||||
let new_scope_params, new_scope_body =
|
||||
translate_scope p.decl_ctx func_dict scope_expr
|
||||
translate_scope p.decl_ctx func_dict body.Lcalc.Ast.scope_body_expr
|
||||
in
|
||||
let func_id = A.TopLevelName.fresh (Bindlib.name_of scope_name, Pos.no_pos) in
|
||||
let func_dict = L.VarMap.add scope_name func_id func_dict in
|
||||
let func_id =
|
||||
A.TopLevelName.fresh (Bindlib.name_of body.Lcalc.Ast.scope_body_var, Pos.no_pos)
|
||||
in
|
||||
let func_dict = L.VarMap.add body.Lcalc.Ast.scope_body_var func_id func_dict in
|
||||
( func_dict,
|
||||
(func_id, { A.func_params = new_scope_params; A.func_body = new_scope_body })
|
||||
{
|
||||
Ast.scope_body_name = body.Lcalc.Ast.scope_body_name;
|
||||
Ast.scope_body_var = func_id;
|
||||
scope_body_func =
|
||||
{ A.func_params = new_scope_params; A.func_body = new_scope_body };
|
||||
}
|
||||
:: new_scopes ))
|
||||
( L.VarMap.singleton L.handle_default
|
||||
(A.TopLevelName.fresh ("handle_default", Pos.no_pos)),
|
||||
|
162
compiler/scalc/print.ml
Normal file
162
compiler/scalc/print.ml
Normal file
@ -0,0 +1,162 @@
|
||||
(* This file is part of the Catala compiler, a specification language for tax and social benefits
|
||||
computation rules. Copyright (C) 2022 Inria, contributor: Denis Merigoux
|
||||
<denis.merigoux@inria.fr>
|
||||
|
||||
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. *)
|
||||
|
||||
open Utils
|
||||
open Ast
|
||||
|
||||
let needs_parens (_e : expr Pos.marked) : bool = false
|
||||
|
||||
let format_local_name (fmt : Format.formatter) (v : LocalName.t) : unit =
|
||||
Format.fprintf fmt "%a_%s" LocalName.format_t v (string_of_int (LocalName.hash v))
|
||||
|
||||
let rec format_expr (decl_ctx : Dcalc.Ast.decl_ctx) ?(debug : bool = false) (fmt : Format.formatter)
|
||||
(e : expr Pos.marked) : unit =
|
||||
let format_expr = format_expr decl_ctx ~debug in
|
||||
let format_with_parens (fmt : Format.formatter) (e : expr Pos.marked) =
|
||||
if needs_parens e then
|
||||
Format.fprintf fmt "%a%a%a" Dcalc.Print.format_punctuation "(" format_expr e
|
||||
Dcalc.Print.format_punctuation ")"
|
||||
else Format.fprintf fmt "%a" format_expr e
|
||||
in
|
||||
match Pos.unmark e with
|
||||
| EVar v -> Format.fprintf fmt "%a" format_local_name v
|
||||
| EFunc v -> Format.fprintf fmt "%a" TopLevelName.format_t v
|
||||
| EStruct (es, s) ->
|
||||
Format.fprintf fmt "@[<hov 2>%a@ %a%a%a@]" Dcalc.Ast.StructName.format_t s
|
||||
Dcalc.Print.format_punctuation "{"
|
||||
(Format.pp_print_list
|
||||
~pp_sep:(fun fmt () -> Format.fprintf fmt ",@ ")
|
||||
(fun fmt (e, struct_field) ->
|
||||
Format.fprintf fmt "%a%a%a%a %a" Dcalc.Print.format_punctuation "\""
|
||||
Dcalc.Ast.StructFieldName.format_t struct_field Dcalc.Print.format_punctuation "\""
|
||||
Dcalc.Print.format_punctuation ":" format_expr e))
|
||||
(List.combine es (List.map fst (Dcalc.Ast.StructMap.find s decl_ctx.ctx_structs)))
|
||||
Dcalc.Print.format_punctuation "}"
|
||||
| EArray es ->
|
||||
Format.fprintf fmt "@[<hov 2>%a%a%a@]" Dcalc.Print.format_punctuation "["
|
||||
(Format.pp_print_list
|
||||
~pp_sep:(fun fmt () -> Format.fprintf fmt ";@ ")
|
||||
(fun fmt e -> Format.fprintf fmt "%a" format_expr e))
|
||||
es Dcalc.Print.format_punctuation "]"
|
||||
| EStructFieldAccess (e1, field, s) ->
|
||||
Format.fprintf fmt "%a%a%a%a%a" format_expr e1 Dcalc.Print.format_punctuation "."
|
||||
Dcalc.Print.format_punctuation "\"" Dcalc.Ast.StructFieldName.format_t
|
||||
(fst
|
||||
(List.find
|
||||
(fun (field', _) -> Dcalc.Ast.StructFieldName.compare field' field = 0)
|
||||
(Dcalc.Ast.StructMap.find s decl_ctx.ctx_structs)))
|
||||
Dcalc.Print.format_punctuation "\""
|
||||
| EInj (e, case, enum) ->
|
||||
Format.fprintf fmt "@[<hov 2>%a@ %a@]" Dcalc.Print.format_enum_constructor
|
||||
(fst
|
||||
(List.find
|
||||
(fun (case', _) -> Dcalc.Ast.EnumConstructor.compare case' case = 0)
|
||||
(Dcalc.Ast.EnumMap.find enum decl_ctx.ctx_enums)))
|
||||
format_expr e
|
||||
| ELit l -> Format.fprintf fmt "%a" Lcalc.Print.format_lit (Pos.same_pos_as l e)
|
||||
| EApp ((EOp (Binop ((Dcalc.Ast.Map | Dcalc.Ast.Filter) as op)), _), [ arg1; arg2 ]) ->
|
||||
Format.fprintf fmt "@[<hov 2>%a@ %a@ %a@]" Dcalc.Print.format_binop (op, Pos.no_pos)
|
||||
format_with_parens arg1 format_with_parens arg2
|
||||
| EApp ((EOp (Binop op), _), [ arg1; arg2 ]) ->
|
||||
Format.fprintf fmt "@[<hov 2>%a@ %a@ %a@]" format_with_parens arg1 Dcalc.Print.format_binop
|
||||
(op, Pos.no_pos) format_with_parens arg2
|
||||
| EApp ((EOp (Unop (Log _)), _), [ arg1 ]) when not debug ->
|
||||
Format.fprintf fmt "%a" format_with_parens arg1
|
||||
| EApp ((EOp (Unop op), _), [ arg1 ]) ->
|
||||
Format.fprintf fmt "@[<hov 2>%a@ %a@]" Dcalc.Print.format_unop (op, Pos.no_pos)
|
||||
format_with_parens arg1
|
||||
| EApp (f, args) ->
|
||||
Format.fprintf fmt "@[<hov 2>%a@ %a@]" format_expr f
|
||||
(Format.pp_print_list ~pp_sep:(fun fmt () -> Format.fprintf fmt "@ ") format_with_parens)
|
||||
args
|
||||
| EOp (Ternop op) -> Format.fprintf fmt "%a" Dcalc.Print.format_ternop (op, Pos.no_pos)
|
||||
| EOp (Binop op) -> Format.fprintf fmt "%a" Dcalc.Print.format_binop (op, Pos.no_pos)
|
||||
| EOp (Unop op) -> Format.fprintf fmt "%a" Dcalc.Print.format_unop (op, Pos.no_pos)
|
||||
|
||||
let rec format_statement (decl_ctx : Dcalc.Ast.decl_ctx) ?(debug : bool = false)
|
||||
(fmt : Format.formatter) (stmt : stmt Pos.marked) : unit =
|
||||
if debug then () else ();
|
||||
match Pos.unmark stmt with
|
||||
| SInnerFuncDef (name, func) ->
|
||||
Format.fprintf fmt "@[<hov 2>%a@ %a@ %a@ %a@]@\n@[<v 2> %a@]" Dcalc.Print.format_keyword
|
||||
"let" LocalName.format_t (Pos.unmark name)
|
||||
(Format.pp_print_list
|
||||
~pp_sep:(fun fmt () -> Format.fprintf fmt "@ ")
|
||||
(fun fmt ((name, _), typ) ->
|
||||
Format.fprintf fmt "%a%a %a@ %a%a" Dcalc.Print.format_punctuation "("
|
||||
LocalName.format_t name Dcalc.Print.format_punctuation ":"
|
||||
(Dcalc.Print.format_typ decl_ctx) typ Dcalc.Print.format_punctuation ")"))
|
||||
func.func_params Dcalc.Print.format_punctuation "=" (format_block decl_ctx ~debug)
|
||||
func.func_body
|
||||
| SLocalDecl (name, typ) ->
|
||||
Format.fprintf fmt "@[<hov 2>%a %a %a@ %a@]" Dcalc.Print.format_keyword "decl"
|
||||
LocalName.format_t (Pos.unmark name) Dcalc.Print.format_punctuation ":"
|
||||
(Dcalc.Print.format_typ decl_ctx) typ
|
||||
| SLocalDef (name, expr) ->
|
||||
Format.fprintf fmt "@[<hov 2>%a %a@ %a@]" LocalName.format_t (Pos.unmark name)
|
||||
Dcalc.Print.format_punctuation "=" (format_expr decl_ctx ~debug) expr
|
||||
| STryExcept (b_try, except, b_with) ->
|
||||
Format.fprintf fmt "@[<v 2>%a%a@ %a@]@\n@[<v 2>%a %a%a@ %a@]" Dcalc.Print.format_keyword "try"
|
||||
Dcalc.Print.format_punctuation ":" (format_block decl_ctx ~debug) b_try
|
||||
Dcalc.Print.format_keyword "with" Lcalc.Print.format_exception except
|
||||
Dcalc.Print.format_punctuation ":" (format_block decl_ctx ~debug) b_with
|
||||
| SRaise except ->
|
||||
Format.fprintf fmt "@[<hov 2>%a %a@]" Dcalc.Print.format_keyword "raise"
|
||||
Lcalc.Print.format_exception except
|
||||
| SIfThenElse (e_if, b_true, b_false) ->
|
||||
Format.fprintf fmt "@[<v 2>%a @[<hov 2>%a@]%a@ %a@ @]@[<v 2>%a%a@ %a@]"
|
||||
Dcalc.Print.format_keyword "if" (format_expr decl_ctx ~debug) e_if
|
||||
Dcalc.Print.format_punctuation ":" (format_block decl_ctx ~debug) b_true
|
||||
Dcalc.Print.format_keyword "else" Dcalc.Print.format_punctuation ":"
|
||||
(format_block decl_ctx ~debug) b_false
|
||||
| SReturn ret ->
|
||||
Format.fprintf fmt "@[<hov 2>%a %a@]" Dcalc.Print.format_keyword "return"
|
||||
(format_expr decl_ctx ~debug)
|
||||
(ret, Pos.get_position stmt)
|
||||
| SAssert expr ->
|
||||
Format.fprintf fmt "@[<hov 2>%a %a@]" Dcalc.Print.format_keyword "assert"
|
||||
(format_expr decl_ctx ~debug)
|
||||
(expr, Pos.get_position stmt)
|
||||
| SSwitch (e_switch, enum, arms) ->
|
||||
Format.fprintf fmt "@[<v 0>%a @[<hov 2>%a@]%a@]%a" Dcalc.Print.format_keyword "switch"
|
||||
(format_expr decl_ctx ~debug) e_switch Dcalc.Print.format_punctuation ":"
|
||||
(Format.pp_print_list
|
||||
~pp_sep:(fun fmt () -> Format.fprintf fmt "@\n")
|
||||
(fun fmt ((case, _), (arm_block, payload_name)) ->
|
||||
Format.fprintf fmt "%a %a%a@ %a @[<v 2>%a@ %a@]" Dcalc.Print.format_punctuation "|"
|
||||
Dcalc.Print.format_enum_constructor case Dcalc.Print.format_punctuation ":"
|
||||
LocalName.format_t payload_name Dcalc.Print.format_punctuation "→"
|
||||
(format_block decl_ctx ~debug) arm_block))
|
||||
(List.combine (Dcalc.Ast.EnumMap.find enum decl_ctx.ctx_enums) arms)
|
||||
|
||||
and format_block (decl_ctx : Dcalc.Ast.decl_ctx) ?(debug : bool = false) (fmt : Format.formatter)
|
||||
(block : block) : unit =
|
||||
Format.pp_print_list
|
||||
~pp_sep:(fun fmt () -> Format.fprintf fmt "%a@ " Dcalc.Print.format_punctuation ";")
|
||||
(format_statement decl_ctx ~debug)
|
||||
fmt block
|
||||
|
||||
let format_scope (decl_ctx : Dcalc.Ast.decl_ctx) ?(debug : bool = false) (fmt : Format.formatter)
|
||||
(body : scope_body) : unit =
|
||||
if debug then () else ();
|
||||
Format.fprintf fmt "@[<hov 2>%a@ %a@ %a@ %a@]@\n@[<v 2> %a@]" Dcalc.Print.format_keyword "let"
|
||||
TopLevelName.format_t body.scope_body_var
|
||||
(Format.pp_print_list
|
||||
~pp_sep:(fun fmt () -> Format.fprintf fmt "@ ")
|
||||
(fun fmt ((name, _), typ) ->
|
||||
Format.fprintf fmt "%a%a %a@ %a%a" Dcalc.Print.format_punctuation "(" LocalName.format_t
|
||||
name Dcalc.Print.format_punctuation ":" (Dcalc.Print.format_typ decl_ctx) typ
|
||||
Dcalc.Print.format_punctuation ")"))
|
||||
body.scope_body_func.func_params Dcalc.Print.format_punctuation "="
|
||||
(format_block decl_ctx ~debug) body.scope_body_func.func_body
|
15
compiler/scalc/print.mli
Normal file
15
compiler/scalc/print.mli
Normal file
@ -0,0 +1,15 @@
|
||||
(* This file is part of the Catala compiler, a specification language for tax and social benefits
|
||||
computation rules. Copyright (C) 2022 Inria, contributor: Denis Merigoux
|
||||
<denis.merigoux@inria.fr>
|
||||
|
||||
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. *)
|
||||
|
||||
val format_scope : Dcalc.Ast.decl_ctx -> ?debug:bool -> Format.formatter -> Ast.scope_body -> unit
|
@ -8,7 +8,7 @@ rules in the language, every local variable has a unique id.
|
||||
|
||||
The module describing the abstract syntax tree is:
|
||||
|
||||
{!modules: Scalc.Ast}
|
||||
{!modules: Scalc.Ast Scalc.Print}
|
||||
|
||||
{1 Compilation from lambda calculus }
|
||||
|
||||
|
@ -327,11 +327,13 @@ let format_ctx (type_ordering : Scopelang.Dependency.TVertex.t list) (fmt : Form
|
||||
Format.fprintf fmt "\t\tself.%a = %a" format_struct_field_name struct_field
|
||||
format_struct_field_name struct_field))
|
||||
struct_fields format_struct_name struct_name
|
||||
(Format.pp_print_list
|
||||
(if List.length struct_fields > 0 then
|
||||
Format.pp_print_list
|
||||
~pp_sep:(fun fmt () -> Format.fprintf fmt " and@ ")
|
||||
(fun _fmt (struct_field, _) ->
|
||||
Format.fprintf fmt "self.%a == other.%a" format_struct_field_name struct_field
|
||||
format_struct_field_name struct_field))
|
||||
format_struct_field_name struct_field)
|
||||
else fun fmt _ -> Format.fprintf fmt "True")
|
||||
struct_fields format_struct_name struct_name
|
||||
(Format.pp_print_list
|
||||
~pp_sep:(fun fmt () -> Format.fprintf fmt ",")
|
||||
@ -418,8 +420,9 @@ let format_program (fmt : Format.formatter) (p : Ast.program)
|
||||
(format_ctx type_ordering) p.decl_ctx
|
||||
(Format.pp_print_list
|
||||
~pp_sep:(fun fmt () -> Format.fprintf fmt "@\n@\n")
|
||||
(fun fmt (name, { Ast.func_params; Ast.func_body }) ->
|
||||
Format.fprintf fmt "@[<hov 4>def %a(%a):@\n%a@]" format_toplevel_name name
|
||||
(fun fmt body ->
|
||||
let { Ast.func_params; Ast.func_body } = body.scope_body_func in
|
||||
Format.fprintf fmt "@[<hov 4>def %a(%a):@\n%a@]" format_toplevel_name body.scope_body_var
|
||||
(Format.pp_print_list
|
||||
~pp_sep:(fun fmt () -> Format.fprintf fmt ", ")
|
||||
(fun fmt (var, typ) ->
|
||||
|
@ -118,16 +118,18 @@ let rec locations_used (e : expr Pos.marked) : LocationSet.t =
|
||||
List.fold_left (fun acc e' -> LocationSet.union acc (locations_used e')) LocationSet.empty es
|
||||
| ErrorOnEmpty e' -> locations_used e'
|
||||
|
||||
type io_input = NoInput | OnlyInput | Reentrant
|
||||
|
||||
type io = { io_output : bool Pos.marked; io_input : io_input Pos.marked }
|
||||
|
||||
type rule =
|
||||
| Definition of location Pos.marked * typ Pos.marked * expr Pos.marked
|
||||
| Definition of location Pos.marked * typ Pos.marked * io * expr Pos.marked
|
||||
| Assertion of expr Pos.marked
|
||||
| Call of ScopeName.t * SubScopeName.t
|
||||
|
||||
type visibility = { visibility_output : bool; visibility_input : bool }
|
||||
|
||||
type scope_decl = {
|
||||
scope_decl_name : ScopeName.t;
|
||||
scope_sig : typ Pos.marked ScopeVarMap.t;
|
||||
scope_sig : (typ Pos.marked * io) ScopeVarMap.t;
|
||||
scope_decl_rules : rule list;
|
||||
}
|
||||
|
||||
|
@ -84,19 +84,31 @@ type expr =
|
||||
|
||||
val locations_used : expr Pos.marked -> LocationSet.t
|
||||
|
||||
(** This type characterizes the three levels of visibility for a given scope variable with regards
|
||||
to the scope's input and possible redefinitions inside the scope.. *)
|
||||
type io_input =
|
||||
| NoInput
|
||||
(** For an internal variable defined only in the scope, and does not appear in the input. *)
|
||||
| OnlyInput
|
||||
(** For variables that should not be redefined in the scope, because they appear in the input. *)
|
||||
| Reentrant
|
||||
(** For variables defined in the scope that can also be redefined by the caller as they appear
|
||||
in the input. *)
|
||||
|
||||
type io = {
|
||||
io_output : bool Pos.marked; (** [true] is present in the output of the scope. *)
|
||||
io_input : io_input Pos.marked;
|
||||
}
|
||||
(** Characterization of the input/output status of a scope variable. *)
|
||||
|
||||
type rule =
|
||||
| Definition of location Pos.marked * typ Pos.marked * expr Pos.marked
|
||||
| Definition of location Pos.marked * typ Pos.marked * io * expr Pos.marked
|
||||
| Assertion of expr Pos.marked
|
||||
| Call of ScopeName.t * SubScopeName.t
|
||||
|
||||
type visibility = {
|
||||
visibility_output : bool; (** True if present in the scope's output *)
|
||||
visibility_input : bool; (** True if present in the scope's input (reentrant) *)
|
||||
}
|
||||
|
||||
type scope_decl = {
|
||||
scope_decl_name : ScopeName.t;
|
||||
scope_sig : typ Pos.marked ScopeVarMap.t;
|
||||
scope_sig : (typ Pos.marked * io) ScopeVarMap.t;
|
||||
scope_decl_rules : rule list;
|
||||
}
|
||||
|
||||
|
@ -33,7 +33,9 @@ let typ_needs_parens (e : typ Pos.marked) : bool =
|
||||
|
||||
let rec format_typ (fmt : Format.formatter) (typ : typ Pos.marked) : unit =
|
||||
let format_typ_with_parens (fmt : Format.formatter) (t : typ Pos.marked) =
|
||||
if typ_needs_parens t then Format.fprintf fmt "(%a)" format_typ t
|
||||
if typ_needs_parens t then
|
||||
Format.fprintf fmt "%a%a%a" Dcalc.Print.format_punctuation "(" format_typ t
|
||||
Dcalc.Print.format_punctuation ")"
|
||||
else Format.fprintf fmt "%a" format_typ t
|
||||
in
|
||||
match Pos.unmark typ with
|
||||
@ -41,8 +43,11 @@ let rec format_typ (fmt : Format.formatter) (typ : typ Pos.marked) : unit =
|
||||
| TStruct s -> Format.fprintf fmt "%a" Ast.StructName.format_t s
|
||||
| TEnum e -> Format.fprintf fmt "%a" Ast.EnumName.format_t e
|
||||
| TArrow (t1, t2) ->
|
||||
Format.fprintf fmt "@[<hov 2>%a →@ %a@]" format_typ_with_parens t1 format_typ t2
|
||||
| TArray t1 -> Format.fprintf fmt "@[%a@ array@]" format_typ (Pos.same_pos_as t1 typ)
|
||||
Format.fprintf fmt "@[<hov 2>%a %a@ %a@]" format_typ_with_parens t1
|
||||
Dcalc.Print.format_operator "→" format_typ t2
|
||||
| TArray t1 ->
|
||||
Format.fprintf fmt "@[%a@ %a@]" format_typ (Pos.same_pos_as t1 typ)
|
||||
Dcalc.Print.format_base_type "array"
|
||||
| TAny -> Format.fprintf fmt "any"
|
||||
|
||||
let rec format_expr (fmt : Format.formatter) (e : expr Pos.marked) : unit =
|
||||
@ -55,23 +60,30 @@ let rec format_expr (fmt : Format.formatter) (e : expr Pos.marked) : unit =
|
||||
| EVar v -> Format.fprintf fmt "%a" format_var (Pos.unmark v)
|
||||
| ELit l -> Format.fprintf fmt "%a" Dcalc.Print.format_lit (Pos.same_pos_as l e)
|
||||
| EStruct (name, fields) ->
|
||||
Format.fprintf fmt "@[%a @[<hov 2>{@ %a@ }@]@]" Ast.StructName.format_t name
|
||||
Format.fprintf fmt " @[<hov 2>%a@ %a@ %a@ %a@]" Ast.StructName.format_t name
|
||||
Dcalc.Print.format_punctuation "{"
|
||||
(Format.pp_print_list
|
||||
~pp_sep:(fun fmt () -> Format.fprintf fmt ";@ ")
|
||||
~pp_sep:(fun fmt () -> Format.fprintf fmt "%a@ " Dcalc.Print.format_punctuation ";")
|
||||
(fun fmt (field_name, field_expr) ->
|
||||
Format.fprintf fmt "%a = %a" Ast.StructFieldName.format_t field_name format_expr
|
||||
field_expr))
|
||||
Format.fprintf fmt "%a%a%a%a@ %a" Dcalc.Print.format_punctuation "\""
|
||||
Ast.StructFieldName.format_t field_name Dcalc.Print.format_punctuation "\""
|
||||
Dcalc.Print.format_punctuation "=" format_expr field_expr))
|
||||
(Ast.StructFieldMap.bindings fields)
|
||||
Dcalc.Print.format_punctuation "}"
|
||||
| EStructAccess (e1, field, _) ->
|
||||
Format.fprintf fmt "%a.%a" format_expr e1 Ast.StructFieldName.format_t field
|
||||
Format.fprintf fmt "%a%a%a%a%a" format_expr e1 Dcalc.Print.format_punctuation "."
|
||||
Dcalc.Print.format_punctuation "\"" Ast.StructFieldName.format_t field
|
||||
Dcalc.Print.format_punctuation "\""
|
||||
| EEnumInj (e1, cons, _) ->
|
||||
Format.fprintf fmt "%a@ %a" Ast.EnumConstructor.format_t cons format_expr e1
|
||||
| EMatch (e1, _, cases) ->
|
||||
Format.fprintf fmt "@[<hov 2>@[match@ %a@ with@]@ %a@]" format_expr e1
|
||||
Format.fprintf fmt "@[<hov 0>%a@ @[<hov 2>%a@]@ %a@ %a@]" Dcalc.Print.format_keyword "match"
|
||||
format_expr e1 Dcalc.Print.format_keyword "with"
|
||||
(Format.pp_print_list
|
||||
~pp_sep:(fun fmt () -> Format.fprintf fmt "@ |@ ")
|
||||
~pp_sep:(fun fmt () -> Format.fprintf fmt "@\n")
|
||||
(fun fmt (cons_name, case_expr) ->
|
||||
Format.fprintf fmt "@[<hov 2>%a@ →@ %a@]" Ast.EnumConstructor.format_t cons_name
|
||||
Format.fprintf fmt "@[<hov 2>%a %a@ %a@ %a@]" Dcalc.Print.format_punctuation "|"
|
||||
Dcalc.Print.format_enum_constructor cons_name Dcalc.Print.format_punctuation "→"
|
||||
format_expr case_expr))
|
||||
(Ast.EnumConstructorMap.bindings cases)
|
||||
| EApp ((EAbs ((binder, _), taus), _), args) ->
|
||||
@ -82,17 +94,21 @@ let rec format_expr (fmt : Format.formatter) (e : expr Pos.marked) : unit =
|
||||
(Format.pp_print_list
|
||||
~pp_sep:(fun fmt () -> Format.fprintf fmt " ")
|
||||
(fun fmt (x, tau, arg) ->
|
||||
Format.fprintf fmt "@[@[<hov 2>let@ %a@ :@ %a@ =@ %a@]@ in@\n@]" format_var x
|
||||
format_typ tau format_expr arg))
|
||||
Format.fprintf fmt "@[<hov 2>%a@ %a@ %a@ %a@ %a@ %a@ %a@\n@]"
|
||||
Dcalc.Print.format_keyword "let" format_var x Dcalc.Print.format_punctuation ":"
|
||||
format_typ tau Dcalc.Print.format_punctuation "=" format_expr arg
|
||||
Dcalc.Print.format_keyword "in"))
|
||||
xs_tau_arg format_expr body
|
||||
| EAbs ((binder, _), taus) ->
|
||||
let xs, body = Bindlib.unmbind binder in
|
||||
let xs_tau = List.map2 (fun x tau -> (x, tau)) (Array.to_list xs) taus in
|
||||
Format.fprintf fmt "@[<hov 2>λ@ %a@ →@ %a@]"
|
||||
Format.fprintf fmt "@[<hov 2>%a@ %a@ %a@ %a@]" Dcalc.Print.format_punctuation "λ"
|
||||
(Format.pp_print_list
|
||||
~pp_sep:(fun fmt () -> Format.fprintf fmt " ")
|
||||
(fun fmt (x, tau) -> Format.fprintf fmt "@[(%a:@ %a)@]" format_var x format_typ tau))
|
||||
xs_tau format_expr body
|
||||
(fun fmt (x, tau) ->
|
||||
Format.fprintf fmt "@[%a%a%a@ %a%a@]" Dcalc.Print.format_punctuation "(" format_var x
|
||||
Dcalc.Print.format_punctuation ":" format_typ tau Dcalc.Print.format_punctuation ")"))
|
||||
xs_tau Dcalc.Print.format_punctuation "→" format_expr body
|
||||
| EApp ((EOp (Binop op), _), [ arg1; arg2 ]) ->
|
||||
Format.fprintf fmt "@[%a@ %a@ %a@]" format_with_parens arg1 Dcalc.Print.format_binop
|
||||
(op, Pos.no_pos) format_with_parens arg2
|
||||
@ -104,77 +120,111 @@ let rec format_expr (fmt : Format.formatter) (e : expr Pos.marked) : unit =
|
||||
(Format.pp_print_list ~pp_sep:(fun fmt () -> Format.fprintf fmt "@ ") format_with_parens)
|
||||
args
|
||||
| EIfThenElse (e1, e2, e3) ->
|
||||
Format.fprintf fmt "if@ @[<hov 2>%a@]@ then@ @[<hov 2>%a@]@ else@ @[<hov 2>%a@]" format_expr
|
||||
e1 format_expr e2 format_expr e3
|
||||
Format.fprintf fmt "@[<hov 2>%a@ %a@ %a@ %a@ %a@ %a@]" Dcalc.Print.format_keyword "if"
|
||||
format_expr e1 Dcalc.Print.format_keyword "then" format_expr e2 Dcalc.Print.format_keyword
|
||||
"else" format_expr e3
|
||||
| EOp (Ternop op) -> Format.fprintf fmt "%a" Dcalc.Print.format_ternop (op, Pos.no_pos)
|
||||
| EOp (Binop op) -> Format.fprintf fmt "%a" Dcalc.Print.format_binop (op, Pos.no_pos)
|
||||
| EOp (Unop op) -> Format.fprintf fmt "%a" Dcalc.Print.format_unop (op, Pos.no_pos)
|
||||
| EDefault (excepts, just, cons) ->
|
||||
if List.length excepts = 0 then
|
||||
Format.fprintf fmt "@[⟨%a ⊢ %a⟩@]" format_expr just format_expr cons
|
||||
Format.fprintf fmt "@[%a%a %a@ %a%a@]" Dcalc.Print.format_punctuation "⟨" format_expr just
|
||||
Dcalc.Print.format_punctuation "⊢" format_expr cons Dcalc.Print.format_punctuation "⟩"
|
||||
else
|
||||
Format.fprintf fmt "@[<hov 2>⟨%a@ |@ %a ⊢ %a⟩@]"
|
||||
Format.fprintf fmt "@[<hov 2>%a%a@ %a@ %a %a@ %a%a@]" Dcalc.Print.format_punctuation "⟨"
|
||||
(Format.pp_print_list ~pp_sep:(fun fmt () -> Format.fprintf fmt ",@ ") format_expr)
|
||||
excepts format_expr just format_expr cons
|
||||
excepts Dcalc.Print.format_punctuation "|" format_expr just Dcalc.Print.format_punctuation
|
||||
"⊢" format_expr cons Dcalc.Print.format_punctuation "⟩"
|
||||
| ErrorOnEmpty e' -> Format.fprintf fmt "error_empty@ %a" format_with_parens e'
|
||||
| EArray es ->
|
||||
Format.fprintf fmt "[%a]"
|
||||
Format.fprintf fmt "%a%a%a" Dcalc.Print.format_punctuation "["
|
||||
(Format.pp_print_list
|
||||
~pp_sep:(fun fmt () -> Format.fprintf fmt ";")
|
||||
~pp_sep:(fun fmt () -> Dcalc.Print.format_punctuation fmt ";")
|
||||
(fun fmt e -> Format.fprintf fmt "@[%a@]" format_expr e))
|
||||
es
|
||||
es Dcalc.Print.format_punctuation "]"
|
||||
|
||||
let format_struct (fmt : Format.formatter)
|
||||
((name, fields) : StructName.t * (StructFieldName.t * typ Pos.marked) list) : unit =
|
||||
Format.fprintf fmt "type %a = {@\n@[<hov 2> %a@]@\n}" StructName.format_t name
|
||||
Format.fprintf fmt "%a %a %a %a@\n@[<hov 2> %a@]@\n%a" Dcalc.Print.format_keyword "type"
|
||||
StructName.format_t name Dcalc.Print.format_punctuation "=" Dcalc.Print.format_punctuation "{"
|
||||
(Format.pp_print_list
|
||||
~pp_sep:(fun fmt () -> Format.fprintf fmt "@\n")
|
||||
(fun fmt (field_name, typ) ->
|
||||
Format.fprintf fmt "%a: %a" StructFieldName.format_t field_name format_typ typ))
|
||||
fields
|
||||
Format.fprintf fmt "%a%a %a" StructFieldName.format_t field_name
|
||||
Dcalc.Print.format_punctuation ":" format_typ typ))
|
||||
fields Dcalc.Print.format_punctuation "}"
|
||||
|
||||
let format_enum (fmt : Format.formatter)
|
||||
((name, cases) : EnumName.t * (EnumConstructor.t * typ Pos.marked) list) : unit =
|
||||
Format.fprintf fmt "type %a = @\n@[<hov 2> %a@]" EnumName.format_t name
|
||||
Format.fprintf fmt "%a %a %a @\n@[<hov 2> %a@]" Dcalc.Print.format_keyword "type"
|
||||
EnumName.format_t name Dcalc.Print.format_punctuation "="
|
||||
(Format.pp_print_list
|
||||
~pp_sep:(fun fmt () -> Format.fprintf fmt "@\n")
|
||||
(fun fmt (field_name, typ) ->
|
||||
Format.fprintf fmt "| %a: %a" EnumConstructor.format_t field_name format_typ typ))
|
||||
Format.fprintf fmt "%a %a%a %a" Dcalc.Print.format_punctuation "|" EnumConstructor.format_t
|
||||
field_name Dcalc.Print.format_punctuation ":" format_typ typ))
|
||||
cases
|
||||
|
||||
let format_scope (fmt : Format.formatter) ((name, decl) : ScopeName.t * scope_decl) : unit =
|
||||
Format.fprintf fmt "@[<hov 2>let scope %a@ %a@ =@]@\n@[<hov 2> %a@\nend scope@]"
|
||||
ScopeName.format_t name
|
||||
Format.fprintf fmt "@[<hov 2>%a@ %a@ %a@ %a@ %a@]@\n@[<v 2> %a@]" Dcalc.Print.format_keyword
|
||||
"let" Dcalc.Print.format_keyword "scope" ScopeName.format_t name
|
||||
(Format.pp_print_list
|
||||
~pp_sep:(fun fmt () -> Format.fprintf fmt "@ ")
|
||||
(fun fmt (scope_var, typ) ->
|
||||
Format.fprintf fmt "(%a: %a)" ScopeVar.format_t scope_var format_typ typ))
|
||||
(fun fmt (scope_var, (typ, vis)) ->
|
||||
Format.fprintf fmt "%a%a%a %a%a%a%a%a" Dcalc.Print.format_punctuation "(" ScopeVar.format_t
|
||||
scope_var Dcalc.Print.format_punctuation ":" format_typ typ
|
||||
Dcalc.Print.format_punctuation "|" Dcalc.Print.format_keyword
|
||||
(match Pos.unmark vis.io_input with
|
||||
| NoInput -> "internal"
|
||||
| OnlyInput -> "input"
|
||||
| Reentrant -> "context")
|
||||
(if Pos.unmark vis.io_output then fun fmt () ->
|
||||
Format.fprintf fmt "%a@,%a" Dcalc.Print.format_punctuation "|"
|
||||
Dcalc.Print.format_keyword "output"
|
||||
else fun fmt () -> Format.fprintf fmt "@<0>")
|
||||
() Dcalc.Print.format_punctuation ")"))
|
||||
(ScopeVarMap.bindings decl.scope_sig)
|
||||
Dcalc.Print.format_punctuation "="
|
||||
(Format.pp_print_list
|
||||
~pp_sep:(fun fmt () -> Format.fprintf fmt ";@\n")
|
||||
~pp_sep:(fun fmt () -> Format.fprintf fmt "%a@ " Dcalc.Print.format_punctuation ";")
|
||||
(fun fmt rule ->
|
||||
match rule with
|
||||
| Definition (loc, typ, e) ->
|
||||
Format.fprintf fmt "@[<hov 2>let %a : %a =@ @[<hov 2>%a@]@ in@]" format_location
|
||||
(Pos.unmark loc) format_typ typ
|
||||
| Definition (loc, typ, _, e) ->
|
||||
Format.fprintf fmt "@[<hov 2>%a %a %a %a %a@ %a@]" Dcalc.Print.format_keyword "let"
|
||||
format_location (Pos.unmark loc) Dcalc.Print.format_punctuation ":" format_typ typ
|
||||
Dcalc.Print.format_punctuation "="
|
||||
(fun fmt e ->
|
||||
match Pos.unmark loc with
|
||||
| SubScopeVar _ -> format_expr fmt e
|
||||
| ScopeVar _ -> Format.fprintf fmt "reentrant or by default@ %a" format_expr e)
|
||||
| ScopeVar v -> (
|
||||
match
|
||||
Pos.unmark (snd (ScopeVarMap.find (Pos.unmark v) decl.scope_sig)).io_input
|
||||
with
|
||||
| Reentrant ->
|
||||
Format.fprintf fmt "%a@ %a" Dcalc.Print.format_operator
|
||||
"reentrant or by default" format_expr e
|
||||
| _ -> Format.fprintf fmt "%a" format_expr e))
|
||||
e
|
||||
| Assertion e -> Format.fprintf fmt "assert (%a)" format_expr e
|
||||
| Assertion e ->
|
||||
Format.fprintf fmt "%a %a" Dcalc.Print.format_keyword "assert" format_expr e
|
||||
| Call (scope_name, subscope_name) ->
|
||||
Format.fprintf fmt "call %a[%a]" ScopeName.format_t scope_name SubScopeName.format_t
|
||||
subscope_name))
|
||||
Format.fprintf fmt "%a %a%a%a%a" Dcalc.Print.format_keyword "call" ScopeName.format_t
|
||||
scope_name Dcalc.Print.format_punctuation "[" SubScopeName.format_t subscope_name
|
||||
Dcalc.Print.format_punctuation "]"))
|
||||
decl.scope_decl_rules
|
||||
|
||||
let format_program (fmt : Format.formatter) (p : program) : unit =
|
||||
Format.fprintf fmt "%a%s%a%s%a"
|
||||
(Format.pp_print_list ~pp_sep:(fun fmt () -> Format.fprintf fmt "@\n@\n") format_struct)
|
||||
Format.fprintf fmt "%a%a%a%a%a"
|
||||
(Format.pp_print_list ~pp_sep:(fun fmt () -> Format.fprintf fmt "\n\n") format_struct)
|
||||
(StructMap.bindings p.program_structs)
|
||||
(if StructMap.is_empty p.program_structs then "" else "\n\n")
|
||||
(Format.pp_print_list ~pp_sep:(fun fmt () -> Format.fprintf fmt "@\n@\n") format_enum)
|
||||
(fun fmt () ->
|
||||
if StructMap.is_empty p.program_structs then Format.fprintf fmt ""
|
||||
else Format.fprintf fmt "\n\n")
|
||||
()
|
||||
(Format.pp_print_list ~pp_sep:(fun fmt () -> Format.fprintf fmt "\n\n") format_enum)
|
||||
(EnumMap.bindings p.program_enums)
|
||||
(if EnumMap.is_empty p.program_enums then "" else "\n\n")
|
||||
(Format.pp_print_list ~pp_sep:(fun fmt () -> Format.fprintf fmt "@\n@\n") format_scope)
|
||||
(fun fmt () ->
|
||||
if EnumMap.is_empty p.program_enums then Format.fprintf fmt "" else Format.fprintf fmt "\n\n")
|
||||
()
|
||||
(Format.pp_print_list ~pp_sep:(fun fmt () -> Format.fprintf fmt "\n\n") format_scope)
|
||||
(ScopeMap.bindings p.program_scopes)
|
||||
|
@ -17,7 +17,7 @@ open Utils
|
||||
type scope_var_ctx = {
|
||||
scope_var_name : Ast.ScopeVar.t;
|
||||
scope_var_typ : Dcalc.Ast.typ;
|
||||
scope_var_visibility : Ast.visibility;
|
||||
scope_var_io : Ast.io;
|
||||
}
|
||||
|
||||
type scope_sig_ctx = {
|
||||
@ -36,8 +36,8 @@ type ctx = {
|
||||
enums : Ast.enum_ctx;
|
||||
scope_name : Ast.ScopeName.t;
|
||||
scopes_parameters : scope_sigs_ctx;
|
||||
scope_vars : (Dcalc.Ast.Var.t * Dcalc.Ast.typ) Ast.ScopeVarMap.t;
|
||||
subscope_vars : (Dcalc.Ast.Var.t * Dcalc.Ast.typ) Ast.ScopeVarMap.t Ast.SubScopeMap.t;
|
||||
scope_vars : (Dcalc.Ast.Var.t * Dcalc.Ast.typ * Ast.io) Ast.ScopeVarMap.t;
|
||||
subscope_vars : (Dcalc.Ast.Var.t * Dcalc.Ast.typ * Ast.io) Ast.ScopeVarMap.t Ast.SubScopeMap.t;
|
||||
local_vars : Dcalc.Ast.Var.t Ast.VarMap.t;
|
||||
}
|
||||
|
||||
@ -262,21 +262,29 @@ let rec translate_expr (ctx : ctx) (e : Ast.expr Pos.marked) : Dcalc.Ast.expr Po
|
||||
(Bindlib.box_list (List.map (translate_expr ctx) excepts))
|
||||
just (translate_expr ctx cons)
|
||||
| ELocation (ScopeVar a) ->
|
||||
Bindlib.box_var (fst (Ast.ScopeVarMap.find (Pos.unmark a) ctx.scope_vars))
|
||||
let v, _, _ = Ast.ScopeVarMap.find (Pos.unmark a) ctx.scope_vars in
|
||||
Bindlib.box_var v
|
||||
| ELocation (SubScopeVar (_, s, a)) -> (
|
||||
try
|
||||
Bindlib.box_var
|
||||
(fst
|
||||
(Ast.ScopeVarMap.find (Pos.unmark a)
|
||||
(Ast.SubScopeMap.find (Pos.unmark s) ctx.subscope_vars)))
|
||||
let v, _, _ =
|
||||
Ast.ScopeVarMap.find (Pos.unmark a)
|
||||
(Ast.SubScopeMap.find (Pos.unmark s) ctx.subscope_vars)
|
||||
in
|
||||
Bindlib.box_var v
|
||||
with Not_found ->
|
||||
Errors.raise_spanned_error
|
||||
Errors.raise_multispanned_error
|
||||
(Format.asprintf
|
||||
"The variable %a.%a cannot be used here,\n\
|
||||
as subscope %a's results will not have been computed yet" Ast.SubScopeName.format_t
|
||||
(Pos.unmark s) Ast.ScopeVar.format_t (Pos.unmark a) Ast.SubScopeName.format_t
|
||||
(Pos.unmark s))
|
||||
(Pos.get_position e))
|
||||
"The variable %a.%a cannot be used here, as it is not part subscope %a's results. \
|
||||
Maybe you forgot to qualify it as an output?"
|
||||
Ast.SubScopeName.format_t (Pos.unmark s) Ast.ScopeVar.format_t (Pos.unmark a)
|
||||
Ast.SubScopeName.format_t (Pos.unmark s))
|
||||
[
|
||||
(Some "Incriminated variable usage:", Pos.get_position e);
|
||||
( Some "Incriminated subscope variable declaration:",
|
||||
Pos.get_position (Ast.ScopeVar.get_info (Pos.unmark a)) );
|
||||
( Some "Incriminated subscope declaration:",
|
||||
Pos.get_position (Ast.SubScopeName.get_info (Pos.unmark s)) );
|
||||
])
|
||||
| EIfThenElse (cond, et, ef) ->
|
||||
Bindlib.box_apply3
|
||||
(fun c t f -> Dcalc.Ast.EIfThenElse (c, t, f))
|
||||
@ -296,7 +304,7 @@ let rec translate_expr (ctx : ctx) (e : Ast.expr Pos.marked) : Dcalc.Ast.expr Po
|
||||
let translate_rule (ctx : ctx) (rule : Ast.rule)
|
||||
((sigma_name, pos_sigma) : Utils.Uid.MarkedString.info) : Dcalc.Ast.scope_let list * ctx =
|
||||
match rule with
|
||||
| Definition ((ScopeVar a, var_def_pos), tau, e) ->
|
||||
| Definition ((ScopeVar a, var_def_pos), tau, a_io, e) ->
|
||||
let a_name = Ast.ScopeVar.get_info (Pos.unmark a) in
|
||||
let a_var = Dcalc.Ast.Var.make a_name in
|
||||
let tau = translate_typ ctx tau in
|
||||
@ -305,7 +313,12 @@ let translate_rule (ctx : ctx) (rule : Ast.rule)
|
||||
let merged_expr =
|
||||
Bindlib.box_apply
|
||||
(fun merged_expr -> (Dcalc.Ast.ErrorOnEmpty merged_expr, Pos.get_position a_name))
|
||||
(merge_defaults a_expr new_e)
|
||||
(match Pos.unmark a_io.io_input with
|
||||
| OnlyInput ->
|
||||
failwith "should not happen"
|
||||
(* scopelang should not contain any definitions of input only variables *)
|
||||
| Reentrant -> merge_defaults a_expr new_e
|
||||
| NoInput -> new_e)
|
||||
in
|
||||
let merged_expr =
|
||||
tag_with_log_entry merged_expr
|
||||
@ -322,9 +335,10 @@ let translate_rule (ctx : ctx) (rule : Ast.rule)
|
||||
],
|
||||
{
|
||||
ctx with
|
||||
scope_vars = Ast.ScopeVarMap.add (Pos.unmark a) (a_var, Pos.unmark tau) ctx.scope_vars;
|
||||
scope_vars =
|
||||
Ast.ScopeVarMap.add (Pos.unmark a) (a_var, Pos.unmark tau, a_io) ctx.scope_vars;
|
||||
} )
|
||||
| Definition ((SubScopeVar (_subs_name, subs_index, subs_var), var_def_pos), tau, e) ->
|
||||
| Definition ((SubScopeVar (_subs_name, subs_index, subs_var), var_def_pos), tau, a_io, e) ->
|
||||
let a_name =
|
||||
Pos.map_under_mark
|
||||
(fun str -> str ^ "." ^ Pos.unmark (Ast.ScopeVar.get_info (Pos.unmark subs_var)))
|
||||
@ -338,19 +352,29 @@ let translate_rule (ctx : ctx) (rule : Ast.rule)
|
||||
[ (sigma_name, pos_sigma); a_name ]
|
||||
in
|
||||
let silent_var = Dcalc.Ast.Var.make ("_", Pos.no_pos) in
|
||||
let thunked_new_e =
|
||||
Dcalc.Ast.make_abs
|
||||
(Array.of_list [ silent_var ])
|
||||
new_e var_def_pos
|
||||
[ (Dcalc.Ast.TLit TUnit, var_def_pos) ]
|
||||
var_def_pos
|
||||
let thunked_or_nonempty_new_e =
|
||||
match Pos.unmark a_io.io_input with
|
||||
| NoInput -> failwith "should not happen"
|
||||
| OnlyInput ->
|
||||
Bindlib.box_apply
|
||||
(fun new_e -> (Dcalc.Ast.ErrorOnEmpty new_e, Pos.get_position subs_var))
|
||||
new_e
|
||||
| Reentrant ->
|
||||
Dcalc.Ast.make_abs
|
||||
(Array.of_list [ silent_var ])
|
||||
new_e var_def_pos
|
||||
[ (Dcalc.Ast.TLit TUnit, var_def_pos) ]
|
||||
var_def_pos
|
||||
in
|
||||
( [
|
||||
{
|
||||
Dcalc.Ast.scope_let_var = (a_var, Pos.get_position a_name);
|
||||
Dcalc.Ast.scope_let_typ =
|
||||
(Dcalc.Ast.TArrow ((TLit TUnit, var_def_pos), tau), var_def_pos);
|
||||
Dcalc.Ast.scope_let_expr = thunked_new_e;
|
||||
(match Pos.unmark a_io.io_input with
|
||||
| NoInput -> failwith "should not happen"
|
||||
| OnlyInput -> tau
|
||||
| Reentrant -> (Dcalc.Ast.TArrow ((TLit TUnit, var_def_pos), tau), var_def_pos));
|
||||
Dcalc.Ast.scope_let_expr = thunked_or_nonempty_new_e;
|
||||
Dcalc.Ast.scope_let_kind = Dcalc.Ast.SubScopeVarDefinition;
|
||||
};
|
||||
],
|
||||
@ -361,14 +385,26 @@ let translate_rule (ctx : ctx) (rule : Ast.rule)
|
||||
(fun map ->
|
||||
match map with
|
||||
| Some map ->
|
||||
Some (Ast.ScopeVarMap.add (Pos.unmark subs_var) (a_var, Pos.unmark tau) map)
|
||||
Some
|
||||
(Ast.ScopeVarMap.add (Pos.unmark subs_var) (a_var, Pos.unmark tau, a_io) map)
|
||||
| None ->
|
||||
Some (Ast.ScopeVarMap.singleton (Pos.unmark subs_var) (a_var, Pos.unmark tau)))
|
||||
Some
|
||||
(Ast.ScopeVarMap.singleton (Pos.unmark subs_var)
|
||||
(a_var, Pos.unmark tau, a_io)))
|
||||
ctx.subscope_vars;
|
||||
} )
|
||||
| Call (subname, subindex) ->
|
||||
let subscope_sig = Ast.ScopeMap.find subname ctx.scopes_parameters in
|
||||
let all_subscope_vars = subscope_sig.scope_sig_local_vars in
|
||||
let all_subscope_input_vars =
|
||||
List.filter
|
||||
(fun var_ctx ->
|
||||
match Pos.unmark var_ctx.scope_var_io.Ast.io_input with NoInput -> false | _ -> true)
|
||||
all_subscope_vars
|
||||
in
|
||||
let all_subscope_output_vars =
|
||||
List.filter (fun var_ctx -> Pos.unmark var_ctx.scope_var_io.Ast.io_output) all_subscope_vars
|
||||
in
|
||||
let scope_dcalc_var = subscope_sig.scope_sig_scope_var in
|
||||
let called_scope_input_struct = subscope_sig.scope_sig_input_struct in
|
||||
let called_scope_return_struct = subscope_sig.scope_sig_output_struct in
|
||||
@ -389,9 +425,9 @@ let translate_rule (ctx : ctx) (rule : Ast.rule)
|
||||
code) by the translation from desugared to the scope language. *)
|
||||
Bindlib.box Dcalc.Ast.empty_thunked_term
|
||||
else
|
||||
let a_var, _ = Ast.ScopeVarMap.find subvar.scope_var_name subscope_vars_defined in
|
||||
let a_var, _, _ = Ast.ScopeVarMap.find subvar.scope_var_name subscope_vars_defined in
|
||||
Dcalc.Ast.make_var (a_var, pos_call))
|
||||
all_subscope_vars
|
||||
all_subscope_input_vars
|
||||
in
|
||||
let subscope_struct_arg =
|
||||
Bindlib.box_apply
|
||||
@ -399,7 +435,7 @@ let translate_rule (ctx : ctx) (rule : Ast.rule)
|
||||
(Dcalc.Ast.ETuple (subscope_args, Some called_scope_input_struct), pos_call))
|
||||
(Bindlib.box_list subscope_args)
|
||||
in
|
||||
let all_subscope_vars_dcalc =
|
||||
let all_subscope_output_vars_dcalc =
|
||||
List.map
|
||||
(fun (subvar : scope_var_ctx) ->
|
||||
let sub_dcalc_var =
|
||||
@ -409,7 +445,7 @@ let translate_rule (ctx : ctx) (rule : Ast.rule)
|
||||
(Ast.ScopeVar.get_info subvar.scope_var_name))
|
||||
in
|
||||
(subvar, sub_dcalc_var))
|
||||
all_subscope_vars
|
||||
all_subscope_output_vars
|
||||
in
|
||||
let subscope_func =
|
||||
tag_with_log_entry
|
||||
@ -434,11 +470,12 @@ let translate_rule (ctx : ctx) (rule : Ast.rule)
|
||||
Ast.ScopeName.get_info subname;
|
||||
]
|
||||
in
|
||||
|
||||
let result_tuple_var = Dcalc.Ast.Var.make ("result", pos_sigma) in
|
||||
let result_tuple_typ =
|
||||
( Dcalc.Ast.TTuple
|
||||
( List.map (fun (subvar, _) -> (subvar.scope_var_typ, pos_sigma)) all_subscope_vars_dcalc,
|
||||
( List.map
|
||||
(fun (subvar, _) -> (subvar.scope_var_typ, pos_sigma))
|
||||
all_subscope_output_vars_dcalc,
|
||||
Some called_scope_return_struct ),
|
||||
pos_sigma )
|
||||
in
|
||||
@ -466,11 +503,11 @@ let translate_rule (ctx : ctx) (rule : Ast.rule)
|
||||
Some called_scope_return_struct,
|
||||
List.map
|
||||
(fun (var_ctx, _) -> (var_ctx.scope_var_typ, pos_sigma))
|
||||
all_subscope_vars_dcalc ),
|
||||
all_subscope_output_vars_dcalc ),
|
||||
pos_sigma ))
|
||||
(Dcalc.Ast.make_var (result_tuple_var, pos_sigma));
|
||||
})
|
||||
all_subscope_vars_dcalc
|
||||
all_subscope_output_vars_dcalc
|
||||
in
|
||||
( call_scope_let :: result_bindings_lets,
|
||||
{
|
||||
@ -479,8 +516,10 @@ let translate_rule (ctx : ctx) (rule : Ast.rule)
|
||||
Ast.SubScopeMap.add subindex
|
||||
(List.fold_left
|
||||
(fun acc (var_ctx, dvar) ->
|
||||
Ast.ScopeVarMap.add var_ctx.scope_var_name (dvar, var_ctx.scope_var_typ) acc)
|
||||
Ast.ScopeVarMap.empty all_subscope_vars_dcalc)
|
||||
Ast.ScopeVarMap.add var_ctx.scope_var_name
|
||||
(dvar, var_ctx.scope_var_typ, var_ctx.scope_var_io)
|
||||
acc)
|
||||
Ast.ScopeVarMap.empty all_subscope_output_vars_dcalc)
|
||||
ctx.subscope_vars;
|
||||
} )
|
||||
| Assertion e ->
|
||||
@ -509,23 +548,44 @@ let translate_rules (ctx : ctx) (rules : Ast.rule list)
|
||||
([], ctx) rules
|
||||
in
|
||||
let scope_variables = Ast.ScopeVarMap.bindings new_ctx.scope_vars in
|
||||
let scope_output_variables =
|
||||
List.filter (fun (_, (_, _, io)) -> Pos.unmark io.Ast.io_output) scope_variables
|
||||
in
|
||||
let return_exp =
|
||||
Bindlib.box_apply
|
||||
(fun args -> (Dcalc.Ast.ETuple (args, Some sigma_return_struct_name), pos_sigma))
|
||||
(Bindlib.box_list
|
||||
(List.map
|
||||
(fun (_, (dcalc_var, _)) -> Dcalc.Ast.make_var (dcalc_var, pos_sigma))
|
||||
scope_variables))
|
||||
(fun (_, (dcalc_var, _, _)) -> Dcalc.Ast.make_var (dcalc_var, pos_sigma))
|
||||
scope_output_variables))
|
||||
in
|
||||
(scope_lets, return_exp, new_ctx)
|
||||
|
||||
let translate_scope_decl (struct_ctx : Ast.struct_ctx) (enum_ctx : Ast.enum_ctx)
|
||||
(sctx : scope_sigs_ctx) (scope_name : Ast.ScopeName.t) (sigma : Ast.scope_decl) :
|
||||
Dcalc.Ast.scope_body * Dcalc.Ast.struct_ctx =
|
||||
let ctx = empty_ctx struct_ctx enum_ctx sctx scope_name in
|
||||
let sigma_info = Ast.ScopeName.get_info sigma.scope_decl_name in
|
||||
let scope_sig = Ast.ScopeMap.find sigma.scope_decl_name sctx in
|
||||
let scope_variables = scope_sig.scope_sig_local_vars in
|
||||
let ctx =
|
||||
(* the context must be initialized for fresh variables for all only-input scope variables *)
|
||||
List.fold_left
|
||||
(fun ctx scope_var ->
|
||||
match Pos.unmark scope_var.scope_var_io.io_input with
|
||||
| OnlyInput ->
|
||||
let scope_var_name = Ast.ScopeVar.get_info scope_var.scope_var_name in
|
||||
let scope_var_dcalc = Dcalc.Ast.Var.make scope_var_name in
|
||||
{
|
||||
ctx with
|
||||
scope_vars =
|
||||
Ast.ScopeVarMap.add scope_var.scope_var_name
|
||||
(scope_var_dcalc, scope_var.scope_var_typ, scope_var.scope_var_io)
|
||||
ctx.scope_vars;
|
||||
}
|
||||
| _ -> ctx)
|
||||
(empty_ctx struct_ctx enum_ctx sctx scope_name)
|
||||
scope_variables
|
||||
in
|
||||
let scope_input_var = scope_sig.scope_sig_input_var in
|
||||
let scope_input_struct_name = scope_sig.scope_sig_input_struct in
|
||||
let scope_return_struct_name = scope_sig.scope_sig_output_struct in
|
||||
@ -536,21 +596,35 @@ let translate_scope_decl (struct_ctx : Ast.struct_ctx) (enum_ctx : Ast.enum_ctx)
|
||||
let scope_variables =
|
||||
List.map
|
||||
(fun var_ctx ->
|
||||
let dcalc_x, _ = Ast.ScopeVarMap.find var_ctx.scope_var_name ctx.scope_vars in
|
||||
let dcalc_x, _, _ = Ast.ScopeVarMap.find var_ctx.scope_var_name ctx.scope_vars in
|
||||
(var_ctx, dcalc_x))
|
||||
scope_variables
|
||||
in
|
||||
(* first we create variables from the fields of the input struct *)
|
||||
let scope_input_variables =
|
||||
List.filter
|
||||
(fun (var_ctx, _) ->
|
||||
match Pos.unmark var_ctx.scope_var_io.io_input with NoInput -> false | _ -> true)
|
||||
scope_variables
|
||||
in
|
||||
let scope_output_variables =
|
||||
List.filter (fun (var_ctx, _) -> Pos.unmark var_ctx.scope_var_io.io_output) scope_variables
|
||||
in
|
||||
let input_var_typ (var_ctx : scope_var_ctx) =
|
||||
match Pos.unmark var_ctx.scope_var_io.io_input with
|
||||
| OnlyInput -> (var_ctx.scope_var_typ, pos_sigma)
|
||||
| Reentrant ->
|
||||
( Dcalc.Ast.TArrow ((Dcalc.Ast.TLit TUnit, pos_sigma), (var_ctx.scope_var_typ, pos_sigma)),
|
||||
pos_sigma )
|
||||
| NoInput -> failwith "should not happen"
|
||||
in
|
||||
let input_destructurings =
|
||||
List.mapi
|
||||
(fun i (var_ctx, v) ->
|
||||
{
|
||||
Dcalc.Ast.scope_let_kind = Dcalc.Ast.DestructuringInputStruct;
|
||||
Dcalc.Ast.scope_let_var = (v, pos_sigma);
|
||||
Dcalc.Ast.scope_let_typ =
|
||||
( Dcalc.Ast.TArrow
|
||||
((Dcalc.Ast.TLit TUnit, pos_sigma), (var_ctx.scope_var_typ, pos_sigma)),
|
||||
pos_sigma );
|
||||
Dcalc.Ast.scope_let_typ = input_var_typ var_ctx;
|
||||
Dcalc.Ast.scope_let_expr =
|
||||
Bindlib.box_apply
|
||||
(fun r ->
|
||||
@ -558,16 +632,11 @@ let translate_scope_decl (struct_ctx : Ast.struct_ctx) (enum_ctx : Ast.enum_ctx)
|
||||
( r,
|
||||
i,
|
||||
Some scope_input_struct_name,
|
||||
List.map
|
||||
(fun (var_ctx, _) ->
|
||||
( Dcalc.Ast.TArrow
|
||||
((Dcalc.Ast.TLit TUnit, pos_sigma), (var_ctx.scope_var_typ, pos_sigma)),
|
||||
pos_sigma ))
|
||||
scope_variables ),
|
||||
List.map (fun (var_ctx, _) -> input_var_typ var_ctx) scope_input_variables ),
|
||||
pos_sigma ))
|
||||
(Dcalc.Ast.make_var (scope_input_var, pos_sigma));
|
||||
})
|
||||
scope_variables
|
||||
scope_input_variables
|
||||
in
|
||||
let scope_return_struct_fields =
|
||||
List.map
|
||||
@ -576,7 +645,7 @@ let translate_scope_decl (struct_ctx : Ast.struct_ctx) (enum_ctx : Ast.enum_ctx)
|
||||
Ast.StructFieldName.fresh (Bindlib.name_of dvar ^ "_out", pos_sigma)
|
||||
in
|
||||
(struct_field_name, (var_ctx.scope_var_typ, pos_sigma)))
|
||||
scope_variables
|
||||
scope_output_variables
|
||||
in
|
||||
let scope_input_struct_fields =
|
||||
List.map
|
||||
@ -584,10 +653,8 @@ let translate_scope_decl (struct_ctx : Ast.struct_ctx) (enum_ctx : Ast.enum_ctx)
|
||||
let struct_field_name =
|
||||
Ast.StructFieldName.fresh (Bindlib.name_of dvar ^ "_in", pos_sigma)
|
||||
in
|
||||
( struct_field_name,
|
||||
( Dcalc.Ast.TArrow ((Dcalc.Ast.TLit TUnit, pos_sigma), (var_ctx.scope_var_typ, pos_sigma)),
|
||||
pos_sigma ) ))
|
||||
scope_variables
|
||||
(struct_field_name, input_var_typ var_ctx))
|
||||
scope_input_variables
|
||||
in
|
||||
let new_struct_ctx =
|
||||
Ast.StructMap.add scope_input_struct_name scope_input_struct_fields
|
||||
@ -644,17 +711,9 @@ let translate_program (prgm : Ast.program) : Dcalc.Ast.program * Dependency.TVer
|
||||
{
|
||||
scope_sig_local_vars =
|
||||
List.map
|
||||
(fun (scope_var, tau) ->
|
||||
(fun (scope_var, (tau, vis)) ->
|
||||
let tau = translate_typ (ctx_for_typ_translation scope_name) tau in
|
||||
{
|
||||
scope_var_name = scope_var;
|
||||
scope_var_typ = Pos.unmark tau;
|
||||
scope_var_visibility =
|
||||
{
|
||||
visibility_input = true;
|
||||
visibility_output = true (* TODO: change with info from desugared *);
|
||||
};
|
||||
})
|
||||
{ scope_var_name = scope_var; scope_var_typ = Pos.unmark tau; scope_var_io = vis })
|
||||
(Ast.ScopeVarMap.bindings scope.scope_sig);
|
||||
scope_sig_scope_var = scope_dvar;
|
||||
scope_sig_input_var = scope_input_var;
|
||||
|
@ -433,43 +433,65 @@ type scope_use = {
|
||||
name = "scope_use_iter";
|
||||
}]
|
||||
|
||||
type scope_decl_context_item_attribute = Context | Input | Output | Internal
|
||||
type io_input = Input | Context | Internal
|
||||
[@@deriving
|
||||
visitors { variety = "map"; name = "io_input_map" },
|
||||
visitors { variety = "iter"; name = "io_input_iter" }]
|
||||
|
||||
type scope_decl_context_scope = {
|
||||
scope_decl_context_scope_name : ident Pos.marked;
|
||||
scope_decl_context_scope_sub_scope : constructor Pos.marked;
|
||||
scope_decl_context_scope_attribute : (scope_decl_context_item_attribute[@opaque]) Pos.marked;
|
||||
type scope_decl_context_io = {
|
||||
scope_decl_context_io_input : io_input Pos.marked;
|
||||
scope_decl_context_io_output : bool Pos.marked;
|
||||
}
|
||||
[@@deriving
|
||||
visitors
|
||||
{
|
||||
variety = "map";
|
||||
ancestors = [ "ident_map"; "constructor_map"; "Pos.marked_map" ];
|
||||
ancestors = [ "io_input_map"; "Pos.marked_map" ];
|
||||
name = "scope_decl_context_io_map";
|
||||
},
|
||||
visitors
|
||||
{
|
||||
variety = "iter";
|
||||
ancestors = [ "io_input_iter"; "Pos.marked_iter" ];
|
||||
name = "scope_decl_context_io_iter";
|
||||
}]
|
||||
|
||||
type scope_decl_context_scope = {
|
||||
scope_decl_context_scope_name : ident Pos.marked;
|
||||
scope_decl_context_scope_sub_scope : constructor Pos.marked;
|
||||
scope_decl_context_scope_attribute : scope_decl_context_io;
|
||||
}
|
||||
[@@deriving
|
||||
visitors
|
||||
{
|
||||
variety = "map";
|
||||
ancestors = [ "ident_map"; "constructor_map"; "scope_decl_context_io_map"; "Pos.marked_map" ];
|
||||
name = "scope_decl_context_scope_map";
|
||||
},
|
||||
visitors
|
||||
{
|
||||
variety = "iter";
|
||||
ancestors = [ "ident_iter"; "constructor_iter"; "Pos.marked_iter" ];
|
||||
ancestors =
|
||||
[ "ident_iter"; "constructor_iter"; "scope_decl_context_io_iter"; "Pos.marked_iter" ];
|
||||
name = "scope_decl_context_scope_iter";
|
||||
}]
|
||||
|
||||
type scope_decl_context_data = {
|
||||
scope_decl_context_item_name : ident Pos.marked;
|
||||
scope_decl_context_item_typ : typ Pos.marked;
|
||||
scope_decl_context_item_attribute : (scope_decl_context_item_attribute[@opaque]) Pos.marked;
|
||||
scope_decl_context_item_attribute : scope_decl_context_io;
|
||||
}
|
||||
[@@deriving
|
||||
visitors
|
||||
{
|
||||
variety = "map";
|
||||
ancestors = [ "typ_map"; "ident_map" ];
|
||||
ancestors = [ "typ_map"; "scope_decl_context_io_map"; "ident_map" ];
|
||||
name = "scope_decl_context_data_map";
|
||||
},
|
||||
visitors
|
||||
{
|
||||
variety = "iter";
|
||||
ancestors = [ "typ_iter"; "ident_iter" ];
|
||||
ancestors = [ "typ_iter"; "scope_decl_context_io_iter"; "ident_iter" ];
|
||||
name = "scope_decl_context_data_iter";
|
||||
}]
|
||||
|
||||
|
@ -1069,6 +1069,19 @@ let process_scope_use (ctxt : Name_resolution.context) (prgm : Desugared.Ast.pro
|
||||
List.iter (check_unlabeled_exception scope_uid ctxt) use.scope_use_items;
|
||||
List.fold_left (process_scope_use_item precond scope_uid ctxt) prgm use.scope_use_items
|
||||
|
||||
let attribute_to_io (attr : Ast.scope_decl_context_io) : Scopelang.Ast.io =
|
||||
{
|
||||
Scopelang.Ast.io_output = attr.scope_decl_context_io_output;
|
||||
Scopelang.Ast.io_input =
|
||||
Pos.map_under_mark
|
||||
(fun io ->
|
||||
match io with
|
||||
| Ast.Input -> Scopelang.Ast.OnlyInput
|
||||
| Ast.Internal -> Scopelang.Ast.NoInput
|
||||
| Ast.Context -> Scopelang.Ast.Reentrant)
|
||||
attr.scope_decl_context_io_input;
|
||||
}
|
||||
|
||||
(** Main function of this module *)
|
||||
let desugar_program (ctxt : Name_resolution.context) (prgm : Ast.program) : Desugared.Ast.program =
|
||||
let empty_prgm =
|
||||
@ -1094,20 +1107,16 @@ let desugar_program (ctxt : Name_resolution.context) (prgm : Ast.program) : Desu
|
||||
(let scope_vars_defs =
|
||||
Desugared.Ast.IdentMap.fold
|
||||
(fun _ v acc ->
|
||||
let x, y = Scopelang.Ast.ScopeVarMap.find v ctxt.Name_resolution.var_typs in
|
||||
let v_sig = Scopelang.Ast.ScopeVarMap.find v ctxt.Name_resolution.var_typs in
|
||||
let def_key = Desugared.Ast.ScopeDef.Var v in
|
||||
Desugared.Ast.ScopeDefMap.add def_key
|
||||
{
|
||||
Desugared.Ast.scope_def_rules = Desugared.Ast.RuleMap.empty;
|
||||
Desugared.Ast.scope_def_typ = x;
|
||||
Desugared.Ast.scope_def_typ = v_sig.var_sig_typ;
|
||||
Desugared.Ast.scope_def_label_groups =
|
||||
Name_resolution.label_groups ctxt s_uid def_key;
|
||||
Desugared.Ast.scope_def_is_condition = y;
|
||||
Desugared.Ast.scope_def_visibility =
|
||||
{
|
||||
Scopelang.Ast.visibility_input = true;
|
||||
Scopelang.Ast.visibility_output = true;
|
||||
};
|
||||
Desugared.Ast.scope_def_is_condition = v_sig.var_sig_is_condition;
|
||||
Desugared.Ast.scope_def_io = attribute_to_io v_sig.var_sig_io;
|
||||
}
|
||||
acc)
|
||||
s_context.Name_resolution.var_idmap Desugared.Ast.ScopeDefMap.empty
|
||||
@ -1117,22 +1126,18 @@ let desugar_program (ctxt : Name_resolution.context) (prgm : Ast.program) : Desu
|
||||
(fun subscope_name subscope_uid acc ->
|
||||
Desugared.Ast.IdentMap.fold
|
||||
(fun _ v acc ->
|
||||
let x, y =
|
||||
let v_sig =
|
||||
Scopelang.Ast.ScopeVarMap.find v ctxt.Name_resolution.var_typs
|
||||
in
|
||||
let def_key = Desugared.Ast.ScopeDef.SubScopeVar (subscope_name, v) in
|
||||
Desugared.Ast.ScopeDefMap.add def_key
|
||||
{
|
||||
Desugared.Ast.scope_def_rules = Desugared.Ast.RuleMap.empty;
|
||||
Desugared.Ast.scope_def_typ = x;
|
||||
Desugared.Ast.scope_def_typ = v_sig.var_sig_typ;
|
||||
Desugared.Ast.scope_def_label_groups =
|
||||
Name_resolution.label_groups ctxt subscope_uid def_key;
|
||||
Desugared.Ast.scope_def_is_condition = y;
|
||||
Desugared.Ast.scope_def_visibility =
|
||||
{
|
||||
Scopelang.Ast.visibility_input = true;
|
||||
Scopelang.Ast.visibility_output = true;
|
||||
};
|
||||
Desugared.Ast.scope_def_is_condition = v_sig.var_sig_is_condition;
|
||||
Desugared.Ast.scope_def_io = attribute_to_io v_sig.var_sig_io;
|
||||
}
|
||||
acc)
|
||||
(Scopelang.Ast.ScopeMap.find subscope_uid ctxt.Name_resolution.scopes)
|
||||
|
@ -361,6 +361,15 @@ let rec lex_code (lexbuf : lexbuf) : token =
|
||||
| MR_CONTEXT ->
|
||||
L.update_acc lexbuf;
|
||||
CONTEXT
|
||||
| MR_INPUT ->
|
||||
L.update_acc lexbuf;
|
||||
INPUT
|
||||
| MR_OUTPUT ->
|
||||
L.update_acc lexbuf;
|
||||
OUTPUT
|
||||
| MR_INTERNAL ->
|
||||
L.update_acc lexbuf;
|
||||
INTERNAL
|
||||
| MR_DECREASING ->
|
||||
L.update_acc lexbuf;
|
||||
DECREASING
|
||||
|
@ -48,6 +48,12 @@ type struct_context = typ Pos.marked Scopelang.Ast.StructFieldMap.t
|
||||
type enum_context = typ Pos.marked Scopelang.Ast.EnumConstructorMap.t
|
||||
(** Types of the payloads of the cases of an enum *)
|
||||
|
||||
type var_sig = {
|
||||
var_sig_typ : typ Pos.marked;
|
||||
var_sig_is_condition : bool;
|
||||
var_sig_io : Ast.scope_decl_context_io;
|
||||
}
|
||||
|
||||
type context = {
|
||||
local_var_idmap : Scopelang.Ast.Var.t Desugared.Ast.IdentMap.t;
|
||||
(** Inside a definition, local variables can be introduced by functions arguments or pattern
|
||||
@ -65,8 +71,8 @@ type context = {
|
||||
scopes : scope_context Scopelang.Ast.ScopeMap.t; (** For each scope, its context *)
|
||||
structs : struct_context Scopelang.Ast.StructMap.t; (** For each struct, its context *)
|
||||
enums : enum_context Scopelang.Ast.EnumMap.t; (** For each enum, its context *)
|
||||
var_typs : (typ Pos.marked * bool) (* is it a condition? *) Scopelang.Ast.ScopeVarMap.t;
|
||||
(** The types of each scope variable declared *)
|
||||
var_typs : var_sig Scopelang.Ast.ScopeVarMap.t;
|
||||
(** The signatures of each scope variable declared *)
|
||||
}
|
||||
(** Main context used throughout {!module: Surface.Desugaring} *)
|
||||
|
||||
@ -87,10 +93,13 @@ let raise_unknown_identifier (msg : string) (ident : ident Pos.marked) =
|
||||
|
||||
(** Gets the type associated to an uid *)
|
||||
let get_var_typ (ctxt : context) (uid : Scopelang.Ast.ScopeVar.t) : typ Pos.marked =
|
||||
fst (Scopelang.Ast.ScopeVarMap.find uid ctxt.var_typs)
|
||||
(Scopelang.Ast.ScopeVarMap.find uid ctxt.var_typs).var_sig_typ
|
||||
|
||||
let is_var_cond (ctxt : context) (uid : Scopelang.Ast.ScopeVar.t) : bool =
|
||||
snd (Scopelang.Ast.ScopeVarMap.find uid ctxt.var_typs)
|
||||
(Scopelang.Ast.ScopeVarMap.find uid ctxt.var_typs).var_sig_is_condition
|
||||
|
||||
let get_var_io (ctxt : context) (uid : Scopelang.Ast.ScopeVar.t) : Ast.scope_decl_context_io =
|
||||
(Scopelang.Ast.ScopeVarMap.find uid ctxt.var_typs).var_sig_io
|
||||
|
||||
(** Get the variable uid inside the scope given in argument *)
|
||||
let get_var_uid (scope_uid : Scopelang.Ast.ScopeName.t) (ctxt : context)
|
||||
@ -256,7 +265,14 @@ let process_data_decl (scope : Scopelang.Ast.ScopeName.t) (ctxt : context)
|
||||
{
|
||||
ctxt with
|
||||
scopes = Scopelang.Ast.ScopeMap.add scope scope_ctxt ctxt.scopes;
|
||||
var_typs = Scopelang.Ast.ScopeVarMap.add uid (data_typ, is_cond) ctxt.var_typs;
|
||||
var_typs =
|
||||
Scopelang.Ast.ScopeVarMap.add uid
|
||||
{
|
||||
var_sig_typ = data_typ;
|
||||
var_sig_is_condition = is_cond;
|
||||
var_sig_io = decl.scope_decl_context_item_attribute;
|
||||
}
|
||||
ctxt.var_typs;
|
||||
}
|
||||
|
||||
(** Process an item declaration *)
|
||||
|
@ -48,6 +48,12 @@ type struct_context = typ Pos.marked Scopelang.Ast.StructFieldMap.t
|
||||
type enum_context = typ Pos.marked Scopelang.Ast.EnumConstructorMap.t
|
||||
(** Types of the payloads of the cases of an enum *)
|
||||
|
||||
type var_sig = {
|
||||
var_sig_typ : typ Pos.marked;
|
||||
var_sig_is_condition : bool;
|
||||
var_sig_io : Ast.scope_decl_context_io;
|
||||
}
|
||||
|
||||
type context = {
|
||||
local_var_idmap : Scopelang.Ast.Var.t Desugared.Ast.IdentMap.t;
|
||||
(** Inside a definition, local variables can be introduced by functions arguments or pattern
|
||||
@ -65,8 +71,8 @@ type context = {
|
||||
scopes : scope_context Scopelang.Ast.ScopeMap.t; (** For each scope, its context *)
|
||||
structs : struct_context Scopelang.Ast.StructMap.t; (** For each struct, its context *)
|
||||
enums : enum_context Scopelang.Ast.EnumMap.t; (** For each enum, its context *)
|
||||
var_typs : (typ Pos.marked * bool) (* is it a condition? *) Scopelang.Ast.ScopeVarMap.t;
|
||||
(** The types of each scope variable declared *)
|
||||
var_typs : var_sig Scopelang.Ast.ScopeVarMap.t;
|
||||
(** The signatures of each scope variable declared *)
|
||||
}
|
||||
(** Main context used throughout {!module: Surface.Desugaring} *)
|
||||
|
||||
@ -84,6 +90,8 @@ val get_var_typ : context -> Scopelang.Ast.ScopeVar.t -> typ Pos.marked
|
||||
|
||||
val is_var_cond : context -> Scopelang.Ast.ScopeVar.t -> bool
|
||||
|
||||
val get_var_io : context -> Scopelang.Ast.ScopeVar.t -> Ast.scope_decl_context_io
|
||||
|
||||
val get_var_uid :
|
||||
Scopelang.Ast.ScopeName.t -> context -> ident Pos.marked -> Scopelang.Ast.ScopeVar.t
|
||||
(** Get the variable uid inside the scope given in argument *)
|
||||
|
@ -1,6 +1,6 @@
|
||||
source_file: BEGIN_CODE DECLARATION ENUM CONSTRUCTOR COLON ALT CONSTRUCTOR CONTENT TEXT YEAR
|
||||
##
|
||||
## Ends in an error in state: 345.
|
||||
## Ends in an error in state: 349.
|
||||
##
|
||||
## nonempty_list(enum_decl_line) -> enum_decl_line . [ SCOPE END_CODE DECLARATION ]
|
||||
## nonempty_list(enum_decl_line) -> enum_decl_line . nonempty_list(enum_decl_line) [ SCOPE END_CODE DECLARATION ]
|
||||
@ -13,7 +13,7 @@ expected another enum case, or a new declaration or scope use
|
||||
|
||||
source_file: BEGIN_CODE DECLARATION ENUM CONSTRUCTOR COLON ALT CONSTRUCTOR CONTENT YEAR
|
||||
##
|
||||
## Ends in an error in state: 340.
|
||||
## Ends in an error in state: 344.
|
||||
##
|
||||
## enum_decl_line_payload -> CONTENT . typ [ SCOPE END_CODE DECLARATION ALT ]
|
||||
##
|
||||
@ -25,7 +25,7 @@ expected a content type
|
||||
|
||||
source_file: BEGIN_CODE DECLARATION ENUM CONSTRUCTOR COLON ALT CONSTRUCTOR YEAR
|
||||
##
|
||||
## Ends in an error in state: 339.
|
||||
## Ends in an error in state: 343.
|
||||
##
|
||||
## enum_decl_line -> ALT constructor . option(enum_decl_line_payload) [ SCOPE END_CODE DECLARATION ALT ]
|
||||
##
|
||||
@ -37,7 +37,7 @@ expected a payload for your enum case, or another case or declaration
|
||||
|
||||
source_file: BEGIN_CODE DECLARATION ENUM CONSTRUCTOR COLON ALT YEAR
|
||||
##
|
||||
## Ends in an error in state: 338.
|
||||
## Ends in an error in state: 342.
|
||||
##
|
||||
## enum_decl_line -> ALT . constructor option(enum_decl_line_payload) [ SCOPE END_CODE DECLARATION ALT ]
|
||||
##
|
||||
@ -49,7 +49,7 @@ expected the name of an enum case
|
||||
|
||||
source_file: BEGIN_CODE DECLARATION ENUM CONSTRUCTOR COLON YEAR
|
||||
##
|
||||
## Ends in an error in state: 337.
|
||||
## Ends in an error in state: 341.
|
||||
##
|
||||
## code_item -> DECLARATION ENUM constructor COLON . nonempty_list(enum_decl_line) [ SCOPE END_CODE DECLARATION ]
|
||||
##
|
||||
@ -61,7 +61,7 @@ expected an enum case
|
||||
|
||||
source_file: BEGIN_CODE DECLARATION ENUM CONSTRUCTOR YEAR
|
||||
##
|
||||
## Ends in an error in state: 336.
|
||||
## Ends in an error in state: 340.
|
||||
##
|
||||
## code_item -> DECLARATION ENUM constructor . COLON nonempty_list(enum_decl_line) [ SCOPE END_CODE DECLARATION ]
|
||||
##
|
||||
@ -73,7 +73,7 @@ expected a colon
|
||||
|
||||
source_file: BEGIN_CODE DECLARATION ENUM YEAR
|
||||
##
|
||||
## Ends in an error in state: 335.
|
||||
## Ends in an error in state: 339.
|
||||
##
|
||||
## code_item -> DECLARATION ENUM . constructor COLON nonempty_list(enum_decl_line) [ SCOPE END_CODE DECLARATION ]
|
||||
##
|
||||
@ -83,71 +83,12 @@ source_file: BEGIN_CODE DECLARATION ENUM YEAR
|
||||
|
||||
expected the name of your enum
|
||||
|
||||
source_file: BEGIN_CODE DECLARATION SCOPE CONSTRUCTOR COLON CONTEXT IDENT CONDITION YEAR
|
||||
##
|
||||
## Ends in an error in state: 330.
|
||||
##
|
||||
## scope_decl_item -> scope_decl_item_attribute ident CONDITION . option(struct_scope_func) [ SCOPE OUTPUT INTERNAL INPUT IDENT END_CODE DECLARATION CONTEXT ]
|
||||
##
|
||||
## The known suffix of the stack is as follows:
|
||||
## scope_decl_item_attribute ident CONDITION
|
||||
##
|
||||
|
||||
expected the next context item or a dependency declaration for this item
|
||||
|
||||
source_file: BEGIN_CODE DECLARATION SCOPE CONSTRUCTOR COLON CONTEXT IDENT CONTENT TEXT YEAR
|
||||
##
|
||||
## Ends in an error in state: 328.
|
||||
##
|
||||
## scope_decl_item -> scope_decl_item_attribute ident CONTENT typ . option(struct_scope_func) [ SCOPE OUTPUT INTERNAL INPUT IDENT END_CODE DECLARATION CONTEXT ]
|
||||
##
|
||||
## The known suffix of the stack is as follows:
|
||||
## scope_decl_item_attribute ident CONTENT typ
|
||||
##
|
||||
|
||||
expected the next context item or a dependency declaration for this item
|
||||
|
||||
source_file: BEGIN_CODE DECLARATION SCOPE CONSTRUCTOR COLON CONTEXT IDENT CONTENT YEAR
|
||||
##
|
||||
## Ends in an error in state: 327.
|
||||
##
|
||||
## scope_decl_item -> scope_decl_item_attribute ident CONTENT . typ option(struct_scope_func) [ SCOPE OUTPUT INTERNAL INPUT IDENT END_CODE DECLARATION CONTEXT ]
|
||||
##
|
||||
## The known suffix of the stack is as follows:
|
||||
## scope_decl_item_attribute ident CONTENT
|
||||
##
|
||||
|
||||
expected the type of this context item
|
||||
|
||||
|
||||
|
||||
source_file: BEGIN_CODE DECLARATION SCOPE CONSTRUCTOR COLON CONTEXT IDENT YEAR
|
||||
##
|
||||
## Ends in an error in state: 324.
|
||||
##
|
||||
## scope_decl_item -> scope_decl_item_attribute ident . CONTENT typ option(struct_scope_func) [ SCOPE OUTPUT INTERNAL INPUT IDENT END_CODE DECLARATION CONTEXT ]
|
||||
## scope_decl_item -> scope_decl_item_attribute ident . SCOPE constructor [ SCOPE OUTPUT INTERNAL INPUT IDENT END_CODE DECLARATION CONTEXT ]
|
||||
## scope_decl_item -> scope_decl_item_attribute ident . CONDITION option(struct_scope_func) [ SCOPE OUTPUT INTERNAL INPUT IDENT END_CODE DECLARATION CONTEXT ]
|
||||
##
|
||||
## The known suffix of the stack is as follows:
|
||||
## scope_decl_item_attribute ident
|
||||
##
|
||||
|
||||
expected the kind of this context item: is it a condition, a sub-scope or a data?
|
||||
|
||||
source_file: BEGIN_CODE DECLARATION SCOPE CONSTRUCTOR COLON CONTEXT YEAR
|
||||
##
|
||||
## Ends in an error in state: 323.
|
||||
##
|
||||
## scope_decl_item -> scope_decl_item_attribute . ident CONTENT typ option(struct_scope_func) [ SCOPE OUTPUT INTERNAL INPUT IDENT END_CODE DECLARATION CONTEXT ]
|
||||
## scope_decl_item -> scope_decl_item_attribute . ident SCOPE constructor [ SCOPE OUTPUT INTERNAL INPUT IDENT END_CODE DECLARATION CONTEXT ]
|
||||
## scope_decl_item -> scope_decl_item_attribute . ident CONDITION option(struct_scope_func) [ SCOPE OUTPUT INTERNAL INPUT IDENT END_CODE DECLARATION CONTEXT ]
|
||||
##
|
||||
## The known suffix of the stack is as follows:
|
||||
## scope_decl_item_attribute
|
||||
##
|
||||
|
||||
expected the name of this new context item
|
||||
|
||||
source_file: BEGIN_CODE DECLARATION SCOPE CONSTRUCTOR COLON YEAR
|
||||
##
|
||||
@ -1926,7 +1867,7 @@ expected the name of the scope being used
|
||||
|
||||
source_file: BEGIN_CODE YEAR
|
||||
##
|
||||
## Ends in an error in state: 363.
|
||||
## Ends in an error in state: 367.
|
||||
##
|
||||
## source_file_item -> BEGIN_CODE . code END_CODE [ LAW_TEXT LAW_HEADING EOF BEGIN_METADATA BEGIN_DIRECTIVE BEGIN_CODE ]
|
||||
##
|
||||
|
@ -495,12 +495,35 @@ struct_scope:
|
||||
}, Pos.from_lpos $sloc)
|
||||
}
|
||||
|
||||
scope_decl_item_attribute:
|
||||
scope_decl_item_attribute_input:
|
||||
| CONTEXT { Context, Pos.from_lpos $sloc }
|
||||
| INPUT { Input, Pos.from_lpos $sloc }
|
||||
| OUTPUT { Output, Pos.from_lpos $sloc }
|
||||
| INTERNAL { Internal, Pos.from_lpos $sloc }
|
||||
| { Context, Pos.from_lpos $sloc }
|
||||
|
||||
scope_decl_item_attribute_output:
|
||||
| OUTPUT { true, Pos.from_lpos $sloc }
|
||||
| { false, Pos.from_lpos $sloc }
|
||||
|
||||
scope_decl_item_attribute:
|
||||
| input = scope_decl_item_attribute_input
|
||||
output = scope_decl_item_attribute_output {
|
||||
{
|
||||
scope_decl_context_io_input = input;
|
||||
scope_decl_context_io_output = output
|
||||
}
|
||||
}
|
||||
| INTERNAL {
|
||||
{
|
||||
scope_decl_context_io_input = (Internal, Pos.from_lpos $sloc);
|
||||
scope_decl_context_io_output = (false, Pos.from_lpos $sloc)
|
||||
}
|
||||
}
|
||||
| OUTPUT {
|
||||
{
|
||||
scope_decl_context_io_input = (Internal, Pos.from_lpos $sloc);
|
||||
scope_decl_context_io_output = (true, Pos.from_lpos $sloc)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
scope_decl_item:
|
||||
| attr = scope_decl_item_attribute i = ident CONTENT t = typ func_typ = option(struct_scope_func) { (ContextData ({
|
||||
@ -516,14 +539,17 @@ scope_decl_item:
|
||||
}, Pos.from_lpos $sloc);
|
||||
}), Pos.from_lpos $sloc)
|
||||
}
|
||||
| attr = scope_decl_item_attribute i = ident SCOPE c = constructor {
|
||||
| i = ident SCOPE c = constructor {
|
||||
(ContextScope({
|
||||
scope_decl_context_scope_name = i;
|
||||
scope_decl_context_scope_sub_scope = c;
|
||||
scope_decl_context_scope_attribute = attr;
|
||||
scope_decl_context_scope_attribute = {
|
||||
scope_decl_context_io_input = (Internal, Pos.from_lpos $sloc);
|
||||
scope_decl_context_io_output = (false, Pos.from_lpos $sloc);
|
||||
};
|
||||
}), Pos.from_lpos $sloc)
|
||||
}
|
||||
| attr = scope_decl_item_attribute i = ident _condition = CONDITION func_typ = option(struct_scope_func) {
|
||||
| attr = scope_decl_item_attribute i = ident _condition = CONDITION func_typ = option(struct_scope_func) {
|
||||
(ContextData ({
|
||||
scope_decl_context_item_name = i;
|
||||
scope_decl_context_item_attribute = attr;
|
||||
|
@ -81,6 +81,8 @@ type backend_option =
|
||||
| Typecheck
|
||||
| OCaml
|
||||
| Python
|
||||
| Scalc
|
||||
| Lcalc
|
||||
| Dcalc
|
||||
| Scopelang
|
||||
| Proof
|
||||
@ -162,8 +164,17 @@ let info =
|
||||
Catala program. Use the $(b,-s) option to restrict the output to a particular scope." );
|
||||
`I
|
||||
( "$(b,Dcalc)",
|
||||
"Prints a debugging verbatim of the scope language intermediate representation of the \
|
||||
"Prints a debugging verbatim of the default calculus intermediate representation of the \
|
||||
Catala program. Use the $(b,-s) option to restrict the output to a particular scope." );
|
||||
`I
|
||||
( "$(b,Lcalc)",
|
||||
"Prints a debugging verbatim of the lambda calculus intermediate representation of the \
|
||||
Catala program. Use the $(b,-s) option to restrict the output to a particular scope." );
|
||||
`I
|
||||
( "$(b,Scalc)",
|
||||
"Prints a debugging verbatim of the statement calculus intermediate representation of \
|
||||
the Catala program. Use the $(b,-s) option to restrict the output to a particular \
|
||||
scope." );
|
||||
`S Manpage.s_authors;
|
||||
`P "The authors are listed by alphabetical order.";
|
||||
`P "Nicolas Chataing <nicolas.chataing@ens.fr>";
|
||||
@ -179,8 +190,8 @@ let info =
|
||||
`P "Please file bug reports at https://github.com/CatalaLang/catala/issues";
|
||||
]
|
||||
in
|
||||
let exits = Term.default_exits @ [ Term.exit_info ~doc:"on error." 1 ] in
|
||||
Term.info "catala" ~version ~doc ~exits ~man
|
||||
let exits = Cmd.Exit.defaults @ [ Cmd.Exit.info ~doc:"on error." 1 ] in
|
||||
Cmd.info "catala" ~version ~doc ~exits ~man
|
||||
|
||||
(**{1 Terminal formatting}*)
|
||||
|
||||
|
@ -60,6 +60,8 @@ type backend_option =
|
||||
| Typecheck
|
||||
| OCaml
|
||||
| Python
|
||||
| Scalc
|
||||
| Lcalc
|
||||
| Dcalc
|
||||
| Scopelang
|
||||
| Proof
|
||||
@ -92,7 +94,7 @@ val catala_t :
|
||||
|
||||
val version : string
|
||||
|
||||
val info : Cmdliner.Term.info
|
||||
val info : Cmdliner.Cmd.info
|
||||
|
||||
(**{1 Terminal formatting}*)
|
||||
|
||||
|
@ -75,7 +75,7 @@ let match_and_ignore_outer_reentrant_default (ctx : ctx) (e : expr Pos.marked) :
|
||||
(* scope variables*)
|
||||
cons
|
||||
| EAbs ((binder, _), [ (TLit TUnit, _) ]) -> (
|
||||
(* sub-scope variables *)
|
||||
(* context sub-scope variables *)
|
||||
let _, body = Bindlib.unmbind binder in
|
||||
match Pos.unmark body with
|
||||
| EApp ((EOp (Unop (Log _)), _), [ arg ]) -> arg
|
||||
@ -88,6 +88,9 @@ let match_and_ignore_outer_reentrant_default (ctx : ctx) (e : expr Pos.marked) :
|
||||
(Print.format_expr ~debug:true ctx.decl)
|
||||
e)
|
||||
(Pos.get_position e))
|
||||
| ErrorOnEmpty (EApp ((EOp (Unop (Log _)), _), [ d ]), _)
|
||||
| EApp ((EOp (Unop (Log _)), _), [ (ErrorOnEmpty d, _) ]) ->
|
||||
d (* input subscope variables and non-input scope variable *)
|
||||
| _ ->
|
||||
Errors.raise_spanned_error
|
||||
(Format.asprintf
|
||||
|
Binary file not shown.
@ -13,12 +13,12 @@
|
||||
\newcommand{\li}[1]{\texttt{#1}}
|
||||
\begin{document}
|
||||
\begin{center}
|
||||
2021-03-15
|
||||
2022-02-09
|
||||
\hfill
|
||||
{\Huge\bfseries\sffamily
|
||||
Catala Syntax Cheat Sheet}
|
||||
\hfill
|
||||
v.0.2.0
|
||||
v.0.5.0
|
||||
\end{center}
|
||||
\hrule
|
||||
|
||||
@ -156,9 +156,9 @@ déclaration énumeration Foo:
|
||||
\begin{minted}{catala_en}
|
||||
```catala
|
||||
declaration scope Foo:
|
||||
context bar content integer
|
||||
context baz condition
|
||||
context fizz scope Buzz
|
||||
internal bar content integer
|
||||
internal baz condition
|
||||
fizz scope Buzz
|
||||
```
|
||||
\end{minted}
|
||||
\vspace*{-1.75em}
|
||||
@ -167,10 +167,36 @@ declaration scope Foo:
|
||||
\begin{minted}{catala_fr}
|
||||
```catala
|
||||
déclaration champ d'application Foo:
|
||||
contexte bar contenu entier
|
||||
contexte baz condition
|
||||
interne bar contenu entier
|
||||
interne baz condition
|
||||
contexte fizz champ d'application Buzz
|
||||
```
|
||||
\end{minted}
|
||||
\vspace*{-1.75em} \\
|
||||
Input-output qualifiers &
|
||||
\vspace*{-1.75em}
|
||||
\begin{minted}{catala_en}
|
||||
```catala
|
||||
internal bar content ...
|
||||
output baz content ...
|
||||
input fizz content ...
|
||||
input output buzz content ...
|
||||
context biz content ...
|
||||
context output boz content ...
|
||||
```
|
||||
\end{minted}
|
||||
\vspace*{-1.75em}
|
||||
&
|
||||
\vspace*{-1.75em}
|
||||
\begin{minted}{catala_fr}
|
||||
```catala
|
||||
interne bar contenu ...
|
||||
sortie baz contenu ...
|
||||
entrée fizz contenu ...
|
||||
entrée sortie buzz contenu ...
|
||||
contexte biz contenu ...
|
||||
contexte sortie boz contenu ...
|
||||
```
|
||||
\end{minted}
|
||||
\vspace*{-1.75em} \\
|
||||
\bottomrule
|
||||
|
@ -43,7 +43,7 @@
|
||||
(bindlib
|
||||
(>= 5.0.1))
|
||||
(cmdliner
|
||||
(>= 1.0.4))
|
||||
(>= 1.1.0))
|
||||
(re
|
||||
(>= 1.9.0))
|
||||
(zarith
|
||||
|
@ -71,31 +71,31 @@ déclaration structure EnfantEntrée:
|
||||
donnée d_bénéficie_titre_personnel_aide_personnelle_logement contenu booléen
|
||||
|
||||
déclaration champ d'application InterfaceAllocationsFamiliales:
|
||||
contexte date_courante contenu date
|
||||
contexte enfants contenu collection EnfantEntrée
|
||||
contexte enfants_à_charge contenu collection Enfant
|
||||
contexte allocations_familiales champ d'application AllocationsFamiliales
|
||||
contexte ressources_ménage contenu argent
|
||||
contexte résidence contenu Collectivité
|
||||
contexte montant_versé contenu argent
|
||||
contexte personne_charge_effective_permanente_est_parent condition
|
||||
contexte personne_charge_effective_permanente_remplit_titre_I condition
|
||||
contexte avait_enfant_à_charge_avant_1er_janvier_2012 condition
|
||||
entrée i_date_courante contenu date
|
||||
entrée i_enfants contenu collection EnfantEntrée
|
||||
interne enfants_à_charge contenu collection Enfant
|
||||
allocations_familiales champ d'application AllocationsFamiliales
|
||||
entrée i_ressources_ménage contenu argent
|
||||
entrée i_résidence contenu Collectivité
|
||||
sortie i_montant_versé contenu argent
|
||||
entrée i_personne_charge_effective_permanente_est_parent condition
|
||||
entrée i_personne_charge_effective_permanente_remplit_titre_I condition
|
||||
entrée i_avait_enfant_à_charge_avant_1er_janvier_2012 condition
|
||||
|
||||
champ d'application InterfaceAllocationsFamiliales:
|
||||
définition allocations_familiales.date_courante égal à date_courante
|
||||
définition allocations_familiales.date_courante égal à i_date_courante
|
||||
définition allocations_familiales.enfants_à_charge égal à enfants_à_charge
|
||||
définition allocations_familiales.ressources_ménage égal à ressources_ménage
|
||||
définition allocations_familiales.résidence égal à résidence
|
||||
définition montant_versé égal à allocations_familiales.montant_versé
|
||||
définition allocations_familiales.ressources_ménage égal à i_ressources_ménage
|
||||
définition allocations_familiales.résidence égal à i_résidence
|
||||
définition i_montant_versé égal à allocations_familiales.montant_versé
|
||||
règle allocations_familiales.personne_charge_effective_permanente_est_parent
|
||||
sous condition personne_charge_effective_permanente_est_parent conséquence
|
||||
sous condition i_personne_charge_effective_permanente_est_parent conséquence
|
||||
rempli
|
||||
règle allocations_familiales.personne_charge_effective_permanente_remplit_titre_I
|
||||
sous condition personne_charge_effective_permanente_remplit_titre_I conséquence
|
||||
sous condition i_personne_charge_effective_permanente_remplit_titre_I conséquence
|
||||
rempli
|
||||
règle allocations_familiales.avait_enfant_à_charge_avant_1er_janvier_2012
|
||||
sous condition avait_enfant_à_charge_avant_1er_janvier_2012 conséquence
|
||||
sous condition i_avait_enfant_à_charge_avant_1er_janvier_2012 conséquence
|
||||
rempli
|
||||
```
|
||||
|
||||
@ -111,18 +111,18 @@ particulières imposant une scolarité plus longue.
|
||||
|
||||
```catala
|
||||
champ d'application InterfaceAllocationsFamiliales:
|
||||
définition enfants_à_charge égal à application pour enfant dans enfants de
|
||||
définition enfants_à_charge égal à application pour enfant dans i_enfants de
|
||||
Enfant {
|
||||
-- identifiant : enfant.d_identifiant
|
||||
-- rémuneration_mensuelle : enfant.d_rémuneration_mensuelle
|
||||
-- date_de_naissance : enfant.d_date_de_naissance
|
||||
-- prise_en_charge : enfant.d_prise_en_charge
|
||||
-- âge: accès_année de
|
||||
(|0000-01-01| +@ (date_courante -@ enfant.d_date_de_naissance))
|
||||
(|0000-01-01| +@ (i_date_courante -@ enfant.d_date_de_naissance))
|
||||
-- obligation_scolaire :
|
||||
(si enfant.d_date_de_naissance +@ 3 an >=@ date_courante alors
|
||||
(si enfant.d_date_de_naissance +@ 3 an >=@ i_date_courante alors
|
||||
Avant
|
||||
sinon (si enfant.d_date_de_naissance +@ 16 an >=@ date_courante alors
|
||||
sinon (si enfant.d_date_de_naissance +@ 16 an >=@ i_date_courante alors
|
||||
Pendant
|
||||
sinon Après))
|
||||
-- a_déjà_ouvert_droit_aux_allocations_familiales:
|
||||
|
@ -39,9 +39,9 @@ déclaration énumération Collectivité :
|
||||
-- Mayotte
|
||||
|
||||
déclaration champ d'application Smic :
|
||||
contexte date_courante contenu date
|
||||
contexte résidence contenu Collectivité
|
||||
contexte brut_horaire contenu argent
|
||||
entrée date_courante contenu date
|
||||
entrée résidence contenu Collectivité
|
||||
sortie brut_horaire contenu argent
|
||||
|
||||
déclaration énumération PriseEnCompte:
|
||||
-- Complète
|
||||
@ -63,98 +63,98 @@ déclaration énumération ÉlémentPrestationsFamiliales:
|
||||
-- AllocationJournalièrePresenceParentale
|
||||
|
||||
déclaration champ d'application PrestationsFamiliales:
|
||||
contexte droit_ouvert condition dépend de Enfant
|
||||
contexte conditions_hors_âge condition dépend de Enfant
|
||||
contexte plafond_l512_3_2 contenu argent
|
||||
contexte âge_l512_3_2 contenu entier
|
||||
contexte régime_outre_mer_l751_1 condition
|
||||
contexte date_courante contenu date
|
||||
contexte prestation_courante contenu ÉlémentPrestationsFamiliales
|
||||
contexte résidence contenu Collectivité
|
||||
contexte smic champ d'application Smic
|
||||
contexte base_mensuelle contenu argent
|
||||
sortie droit_ouvert condition dépend de Enfant
|
||||
sortie conditions_hors_âge condition dépend de Enfant
|
||||
interne plafond_l512_3_2 contenu argent
|
||||
sortie âge_l512_3_2 contenu entier
|
||||
sortie régime_outre_mer_l751_1 condition
|
||||
entrée date_courante contenu date
|
||||
entrée prestation_courante contenu ÉlémentPrestationsFamiliales
|
||||
entrée résidence contenu Collectivité
|
||||
smic champ d'application Smic
|
||||
sortie base_mensuelle contenu argent
|
||||
|
||||
champ d'application PrestationsFamiliales:
|
||||
définition smic.résidence égal à résidence
|
||||
définition smic.date_courante égal à date_courante
|
||||
|
||||
déclaration champ d'application AllocationFamilialesAvril2008:
|
||||
contexte âge_minimum_alinéa_1_l521_3 contenu entier
|
||||
sortie âge_minimum_alinéa_1_l521_3 contenu entier
|
||||
|
||||
déclaration champ d'application EnfantLePlusÂgé:
|
||||
contexte enfants contenu collection Enfant
|
||||
contexte le_plus_âgé contenu Enfant
|
||||
entrée enfants contenu collection Enfant
|
||||
sortie le_plus_âgé contenu Enfant
|
||||
|
||||
déclaration champ d'application AllocationsFamiliales:
|
||||
|
||||
# Variables concernant le ménage
|
||||
contexte personne_charge_effective_permanente_est_parent condition
|
||||
contexte personne_charge_effective_permanente_remplit_titre_I condition
|
||||
contexte ressources_ménage contenu argent
|
||||
contexte résidence contenu Collectivité
|
||||
entrée personne_charge_effective_permanente_est_parent condition
|
||||
entrée personne_charge_effective_permanente_remplit_titre_I condition
|
||||
entrée ressources_ménage contenu argent
|
||||
entrée résidence contenu Collectivité
|
||||
|
||||
# Date à laquelle le calcul est effectué
|
||||
contexte date_courante contenu date
|
||||
entrée date_courante contenu date
|
||||
|
||||
# Variables concernant les enfants du ménage
|
||||
contexte enfants_à_charge contenu collection Enfant
|
||||
contexte enfants_à_charge_droit_ouvert_prestation_familiale
|
||||
entrée enfants_à_charge contenu collection Enfant
|
||||
interne enfants_à_charge_droit_ouvert_prestation_familiale
|
||||
contenu collection Enfant
|
||||
contexte prise_en_compte contenu PriseEnCompte dépend de Enfant
|
||||
contexte versement contenu VersementAllocations dépend de Enfant
|
||||
interne prise_en_compte contenu PriseEnCompte dépend de Enfant
|
||||
interne versement contenu VersementAllocations dépend de Enfant
|
||||
|
||||
contexte montant_versé contenu argent
|
||||
sortie montant_versé contenu argent
|
||||
|
||||
# Variables liées à la base des allications familiales
|
||||
contexte droit_ouvert_base condition
|
||||
contexte montant_initial_base contenu argent
|
||||
contexte montant_initial_base_premier_enfant contenu argent
|
||||
contexte montant_initial_base_deuxième_enfant contenu argent
|
||||
contexte montant_initial_base_troisième_enfant_et_plus contenu argent
|
||||
contexte rapport_enfants_total_moyen contenu décimal
|
||||
contexte nombre_moyen_enfants contenu décimal
|
||||
contexte nombre_total_enfants contenu décimal
|
||||
contexte montant_avec_garde_alternée_base contenu argent
|
||||
contexte montant_versé_base contenu argent
|
||||
interne droit_ouvert_base condition
|
||||
interne montant_initial_base contenu argent
|
||||
interne montant_initial_base_premier_enfant contenu argent
|
||||
interne montant_initial_base_deuxième_enfant contenu argent
|
||||
interne montant_initial_base_troisième_enfant_et_plus contenu argent
|
||||
interne rapport_enfants_total_moyen contenu décimal
|
||||
interne nombre_moyen_enfants contenu décimal
|
||||
interne nombre_total_enfants contenu décimal
|
||||
interne montant_avec_garde_alternée_base contenu argent
|
||||
interne montant_versé_base contenu argent
|
||||
|
||||
# Variables liées à Mayotte
|
||||
contexte avait_enfant_à_charge_avant_1er_janvier_2012 condition
|
||||
contexte montant_initial_base_premier_enfant_mayotte contenu argent
|
||||
contexte montant_initial_base_deuxième_enfant_mayotte contenu argent
|
||||
contexte montant_initial_base_troisième_enfant_mayotte contenu argent
|
||||
contexte montant_initial_base_quatrième_enfant_et_plus_mayotte contenu argent
|
||||
entrée avait_enfant_à_charge_avant_1er_janvier_2012 condition
|
||||
interne montant_initial_base_premier_enfant_mayotte contenu argent
|
||||
interne montant_initial_base_deuxième_enfant_mayotte contenu argent
|
||||
interne montant_initial_base_troisième_enfant_mayotte contenu argent
|
||||
interne montant_initial_base_quatrième_enfant_et_plus_mayotte contenu argent
|
||||
|
||||
# Variables liées à l'allocation forfaitaire
|
||||
contexte droit_ouvert_forfaitaire condition dépend de Enfant
|
||||
contexte montant_versé_forfaitaire_par_enfant contenu argent
|
||||
contexte montant_versé_forfaitaire contenu argent
|
||||
interne droit_ouvert_forfaitaire condition dépend de Enfant
|
||||
interne montant_versé_forfaitaire_par_enfant contenu argent
|
||||
interne montant_versé_forfaitaire contenu argent
|
||||
|
||||
# Variables liées aux majorations des allocations familiales
|
||||
contexte droit_ouvert_majoration condition dépend de Enfant
|
||||
contexte montant_initial_métropole_majoration contenu argent dépend de Enfant
|
||||
contexte montant_initial_majoration contenu argent dépend de Enfant
|
||||
contexte montant_avec_garde_alternée_majoration contenu argent dépend de Enfant
|
||||
contexte montant_versé_majoration contenu argent
|
||||
interne droit_ouvert_majoration condition dépend de Enfant
|
||||
interne montant_initial_métropole_majoration contenu argent dépend de Enfant
|
||||
interne montant_initial_majoration contenu argent dépend de Enfant
|
||||
interne montant_avec_garde_alternée_majoration contenu argent dépend de Enfant
|
||||
interne montant_versé_majoration contenu argent
|
||||
|
||||
# Variables liées au complément dégressif
|
||||
contexte droit_ouvert_complément condition
|
||||
contexte montant_base_complément_pour_base_et_majoration contenu argent
|
||||
contexte complément_dégressif contenu argent dépend de argent
|
||||
contexte montant_versé_complément_pour_base_et_majoration contenu argent
|
||||
contexte montant_versé_complément_pour_forfaitaire contenu argent
|
||||
interne droit_ouvert_complément condition
|
||||
interne montant_base_complément_pour_base_et_majoration contenu argent
|
||||
interne complément_dégressif contenu argent dépend de argent
|
||||
interne montant_versé_complément_pour_base_et_majoration contenu argent
|
||||
interne montant_versé_complément_pour_forfaitaire contenu argent
|
||||
|
||||
# Sous-champs d'applications
|
||||
contexte prestations_familiales champ d'application PrestationsFamiliales
|
||||
contexte version_avril_2008 champ d'application AllocationFamilialesAvril2008
|
||||
contexte enfant_le_plus_âgé champ d'application EnfantLePlusÂgé
|
||||
prestations_familiales champ d'application PrestationsFamiliales
|
||||
version_avril_2008 champ d'application AllocationFamilialesAvril2008
|
||||
enfant_le_plus_âgé champ d'application EnfantLePlusÂgé
|
||||
|
||||
# Plafonds, âges limites et autres constantes
|
||||
contexte nombre_enfants_l521_1 contenu entier
|
||||
contexte âge_minimum_alinéa_1_l521_3 contenu entier dépend de Enfant
|
||||
contexte nombre_enfants_alinéa_2_l521_3 contenu entier
|
||||
contexte est_enfant_le_plus_âgé contenu booléen dépend de Enfant
|
||||
contexte plafond_I_d521_3 contenu argent
|
||||
contexte plafond_II_d521_3 contenu argent
|
||||
interne nombre_enfants_l521_1 contenu entier
|
||||
interne âge_minimum_alinéa_1_l521_3 contenu entier dépend de Enfant
|
||||
interne nombre_enfants_alinéa_2_l521_3 contenu entier
|
||||
interne est_enfant_le_plus_âgé contenu booléen dépend de Enfant
|
||||
interne plafond_I_d521_3 contenu argent
|
||||
interne plafond_II_d521_3 contenu argent
|
||||
|
||||
champ d'application AllocationsFamiliales:
|
||||
définition prestations_familiales.prestation_courante égal à
|
||||
|
@ -4,11 +4,11 @@
|
||||
|
||||
```catala
|
||||
déclaration champ d'application Données:
|
||||
contexte enfant1 contenu EnfantEntrée
|
||||
contexte enfant2 contenu EnfantEntrée
|
||||
contexte enfant3 contenu EnfantEntrée
|
||||
contexte enfant4 contenu EnfantEntrée
|
||||
contexte enfant5 contenu EnfantEntrée
|
||||
sortie enfant1 contenu EnfantEntrée
|
||||
sortie enfant2 contenu EnfantEntrée
|
||||
sortie enfant3 contenu EnfantEntrée
|
||||
sortie enfant4 contenu EnfantEntrée
|
||||
sortie enfant5 contenu EnfantEntrée
|
||||
|
||||
champ d'application Données:
|
||||
définition enfant1 égal à EnfantEntrée {
|
||||
@ -53,73 +53,73 @@ champ d'application Données:
|
||||
}
|
||||
|
||||
déclaration champ d'application Test1:
|
||||
contexte f champ d'application InterfaceAllocationsFamiliales
|
||||
contexte données champ d'application Données
|
||||
f champ d'application InterfaceAllocationsFamiliales
|
||||
données champ d'application Données
|
||||
|
||||
champ d'application Test1:
|
||||
définition f.enfants égal à
|
||||
définition f.i_enfants égal à
|
||||
[données.enfant1;données.enfant2;données.enfant3;données.enfant4]
|
||||
définition f.ressources_ménage égal à 30 000 €
|
||||
définition f.date_courante égal à |2020-05-01|
|
||||
définition f.résidence égal à Métropole
|
||||
règle f.personne_charge_effective_permanente_est_parent rempli
|
||||
assertion f.montant_versé = 351,26€
|
||||
définition f.i_ressources_ménage égal à 30 000 €
|
||||
définition f.i_date_courante égal à |2020-05-01|
|
||||
définition f.i_résidence égal à Métropole
|
||||
règle f.i_personne_charge_effective_permanente_est_parent rempli
|
||||
assertion f.i_montant_versé = 351,26€
|
||||
|
||||
déclaration champ d'application Test2:
|
||||
contexte f champ d'application InterfaceAllocationsFamiliales
|
||||
contexte données champ d'application Données
|
||||
f champ d'application InterfaceAllocationsFamiliales
|
||||
données champ d'application Données
|
||||
|
||||
champ d'application Test2:
|
||||
définition f.enfants égal à
|
||||
définition f.i_enfants égal à
|
||||
[données.enfant1;données.enfant2;données.enfant5]
|
||||
définition f.ressources_ménage égal à 30 000 €
|
||||
définition f.date_courante égal à |2020-05-01|
|
||||
définition f.résidence égal à Métropole
|
||||
règle f.personne_charge_effective_permanente_est_parent rempli
|
||||
assertion f.montant_versé = 216,27€
|
||||
définition f.i_ressources_ménage égal à 30 000 €
|
||||
définition f.i_date_courante égal à |2020-05-01|
|
||||
définition f.i_résidence égal à Métropole
|
||||
règle f.i_personne_charge_effective_permanente_est_parent rempli
|
||||
assertion f.i_montant_versé = 216,27€
|
||||
|
||||
|
||||
déclaration champ d'application Test3:
|
||||
contexte f champ d'application InterfaceAllocationsFamiliales
|
||||
contexte données champ d'application Données
|
||||
f champ d'application InterfaceAllocationsFamiliales
|
||||
données champ d'application Données
|
||||
|
||||
champ d'application Test3:
|
||||
définition f.enfants égal à [données.enfant1]
|
||||
définition f.ressources_ménage égal à 63540 €
|
||||
définition f.date_courante égal à |2020-05-01|
|
||||
définition f.résidence égal à Guyane
|
||||
règle f.personne_charge_effective_permanente_est_parent rempli
|
||||
assertion f.montant_versé = 24,35 €
|
||||
définition f.i_enfants égal à [données.enfant1]
|
||||
définition f.i_ressources_ménage égal à 63540 €
|
||||
définition f.i_date_courante égal à |2020-05-01|
|
||||
définition f.i_résidence égal à Guyane
|
||||
règle f.i_personne_charge_effective_permanente_est_parent rempli
|
||||
assertion f.i_montant_versé = 24,35 €
|
||||
|
||||
déclaration champ d'application Test4:
|
||||
contexte f champ d'application InterfaceAllocationsFamiliales
|
||||
contexte données champ d'application Données
|
||||
f champ d'application InterfaceAllocationsFamiliales
|
||||
données champ d'application Données
|
||||
|
||||
champ d'application Test4:
|
||||
définition f.enfants égal à [données.enfant1; données.enfant3]
|
||||
définition f.ressources_ménage égal à 67 250 €
|
||||
définition f.date_courante égal à |2020-05-01|
|
||||
définition f.résidence égal à Métropole
|
||||
règle f.personne_charge_effective_permanente_est_parent rempli
|
||||
assertion f.montant_versé = 99,37€
|
||||
définition f.i_enfants égal à [données.enfant1; données.enfant3]
|
||||
définition f.i_ressources_ménage égal à 67 250 €
|
||||
définition f.i_date_courante égal à |2020-05-01|
|
||||
définition f.i_résidence égal à Métropole
|
||||
règle f.i_personne_charge_effective_permanente_est_parent rempli
|
||||
assertion f.i_montant_versé = 99,37€
|
||||
|
||||
déclaration champ d'application Test5:
|
||||
contexte f champ d'application InterfaceAllocationsFamiliales
|
||||
contexte données champ d'application Données
|
||||
f champ d'application InterfaceAllocationsFamiliales
|
||||
données champ d'application Données
|
||||
|
||||
champ d'application Test5:
|
||||
définition f.enfants égal à [données.enfant1]
|
||||
définition f.ressources_ménage égal à 30 000 €
|
||||
définition f.date_courante égal à |2020-05-01|
|
||||
définition f.résidence égal à Métropole
|
||||
règle f.personne_charge_effective_permanente_est_parent rempli
|
||||
assertion f.montant_versé = 0,00€
|
||||
définition f.i_enfants égal à [données.enfant1]
|
||||
définition f.i_ressources_ménage égal à 30 000 €
|
||||
définition f.i_date_courante égal à |2020-05-01|
|
||||
définition f.i_résidence égal à Métropole
|
||||
règle f.i_personne_charge_effective_permanente_est_parent rempli
|
||||
assertion f.i_montant_versé = 0,00€
|
||||
|
||||
déclaration champ d'application Test6:
|
||||
contexte f champ d'application InterfaceAllocationsFamiliales
|
||||
f champ d'application InterfaceAllocationsFamiliales
|
||||
|
||||
champ d'application Test6:
|
||||
définition f.enfants égal à [EnfantEntrée {
|
||||
définition f.i_enfants égal à [EnfantEntrée {
|
||||
-- d_identifiant: 0
|
||||
-- d_date_de_naissance: |2009-11-10|
|
||||
-- d_rémuneration_mensuelle: 439€
|
||||
@ -134,30 +134,30 @@ champ d'application Test6:
|
||||
-- d_a_déjà_ouvert_droit_aux_allocations_familiales: vrai
|
||||
-- d_bénéficie_titre_personnel_aide_personnelle_logement: faux
|
||||
}]
|
||||
définition f.ressources_ménage égal à 78 830 €
|
||||
définition f.date_courante égal à |2020-05-01|
|
||||
définition f.résidence égal à Guadeloupe
|
||||
règle f.personne_charge_effective_permanente_est_parent rempli
|
||||
assertion f.montant_versé = 66,25€
|
||||
définition f.i_ressources_ménage égal à 78 830 €
|
||||
définition f.i_date_courante égal à |2020-05-01|
|
||||
définition f.i_résidence égal à Guadeloupe
|
||||
règle f.i_personne_charge_effective_permanente_est_parent rempli
|
||||
assertion f.i_montant_versé = 66,25€
|
||||
|
||||
déclaration champ d'application Test7:
|
||||
contexte f champ d'application InterfaceAllocationsFamiliales
|
||||
contexte données champ d'application Données
|
||||
f champ d'application InterfaceAllocationsFamiliales
|
||||
données champ d'application Données
|
||||
|
||||
champ d'application Test7:
|
||||
définition f.enfants égal à
|
||||
définition f.i_enfants égal à
|
||||
[données.enfant1;données.enfant2;données.enfant3;données.enfant4]
|
||||
définition f.ressources_ménage égal à 30 000 €
|
||||
définition f.date_courante égal à |2021-02-01|
|
||||
définition f.résidence égal à Métropole
|
||||
règle f.personne_charge_effective_permanente_est_parent rempli
|
||||
assertion f.montant_versé = 417,51€
|
||||
définition f.i_ressources_ménage égal à 30 000 €
|
||||
définition f.i_date_courante égal à |2021-02-01|
|
||||
définition f.i_résidence égal à Métropole
|
||||
règle f.i_personne_charge_effective_permanente_est_parent rempli
|
||||
assertion f.i_montant_versé = 417,51€
|
||||
|
||||
déclaration champ d'application Test8:
|
||||
contexte f champ d'application InterfaceAllocationsFamiliales
|
||||
f champ d'application InterfaceAllocationsFamiliales
|
||||
|
||||
champ d'application Test8:
|
||||
définition f.enfants égal à [EnfantEntrée {
|
||||
définition f.i_enfants égal à [EnfantEntrée {
|
||||
-- d_identifiant: 0
|
||||
-- d_date_de_naissance: |2004-01-01|
|
||||
-- d_rémuneration_mensuelle: 0€
|
||||
@ -172,17 +172,17 @@ champ d'application Test8:
|
||||
-- d_a_déjà_ouvert_droit_aux_allocations_familiales: vrai
|
||||
-- d_bénéficie_titre_personnel_aide_personnelle_logement: faux
|
||||
}]
|
||||
définition f.ressources_ménage égal à 69945 €
|
||||
définition f.date_courante égal à |2021-01-01|
|
||||
définition f.résidence égal à Métropole
|
||||
règle f.personne_charge_effective_permanente_est_parent rempli
|
||||
assertion f.montant_versé = 197,74€
|
||||
définition f.i_ressources_ménage égal à 69945 €
|
||||
définition f.i_date_courante égal à |2021-01-01|
|
||||
définition f.i_résidence égal à Métropole
|
||||
règle f.i_personne_charge_effective_permanente_est_parent rempli
|
||||
assertion f.i_montant_versé = 197,74€
|
||||
|
||||
déclaration champ d'application Test9:
|
||||
contexte f champ d'application InterfaceAllocationsFamiliales
|
||||
f champ d'application InterfaceAllocationsFamiliales
|
||||
|
||||
champ d'application Test9:
|
||||
définition f.enfants égal à [EnfantEntrée {
|
||||
définition f.i_enfants égal à [EnfantEntrée {
|
||||
-- d_identifiant: 0
|
||||
-- d_date_de_naissance: |2001-07-27|
|
||||
-- d_rémuneration_mensuelle: 1258€
|
||||
@ -197,17 +197,17 @@ champ d'application Test9:
|
||||
-- d_a_déjà_ouvert_droit_aux_allocations_familiales: vrai
|
||||
-- d_bénéficie_titre_personnel_aide_personnelle_logement: faux
|
||||
}]
|
||||
définition f.ressources_ménage égal à 75786 €
|
||||
définition f.date_courante égal à |2020-05-01|
|
||||
définition f.résidence égal à Guadeloupe
|
||||
règle f.personne_charge_effective_permanente_est_parent rempli
|
||||
assertion f.montant_versé = 0€
|
||||
définition f.i_ressources_ménage égal à 75786 €
|
||||
définition f.i_date_courante égal à |2020-05-01|
|
||||
définition f.i_résidence égal à Guadeloupe
|
||||
règle f.i_personne_charge_effective_permanente_est_parent rempli
|
||||
assertion f.i_montant_versé = 0€
|
||||
|
||||
déclaration champ d'application Test10:
|
||||
contexte f champ d'application InterfaceAllocationsFamiliales
|
||||
f champ d'application InterfaceAllocationsFamiliales
|
||||
|
||||
champ d'application Test10:
|
||||
définition f.enfants égal à [EnfantEntrée {
|
||||
définition f.i_enfants égal à [EnfantEntrée {
|
||||
-- d_identifiant: 0
|
||||
-- d_date_de_naissance: |2003-02-22|
|
||||
-- d_rémuneration_mensuelle: 0€
|
||||
@ -222,17 +222,17 @@ champ d'application Test10:
|
||||
-- d_a_déjà_ouvert_droit_aux_allocations_familiales: vrai
|
||||
-- d_bénéficie_titre_personnel_aide_personnelle_logement: faux
|
||||
}]
|
||||
définition f.ressources_ménage égal à 30000 €
|
||||
définition f.date_courante égal à |2020-04-20|
|
||||
définition f.résidence égal à Métropole
|
||||
règle f.personne_charge_effective_permanente_est_parent rempli
|
||||
assertion f.montant_versé = 99,37€
|
||||
définition f.i_ressources_ménage égal à 30000 €
|
||||
définition f.i_date_courante égal à |2020-04-20|
|
||||
définition f.i_résidence égal à Métropole
|
||||
règle f.i_personne_charge_effective_permanente_est_parent rempli
|
||||
assertion f.i_montant_versé = 99,37€
|
||||
|
||||
déclaration champ d'application Test11:
|
||||
contexte f champ d'application InterfaceAllocationsFamiliales
|
||||
f champ d'application InterfaceAllocationsFamiliales
|
||||
|
||||
champ d'application Test11:
|
||||
définition f.enfants égal à [EnfantEntrée {
|
||||
définition f.i_enfants égal à [EnfantEntrée {
|
||||
-- d_identifiant: 0
|
||||
-- d_date_de_naissance: |2003-02-22|
|
||||
-- d_rémuneration_mensuelle: 0€
|
||||
@ -255,17 +255,17 @@ champ d'application Test11:
|
||||
-- d_a_déjà_ouvert_droit_aux_allocations_familiales: vrai
|
||||
-- d_bénéficie_titre_personnel_aide_personnelle_logement: faux
|
||||
}]
|
||||
définition f.ressources_ménage égal à 30000 €
|
||||
définition f.date_courante égal à |2021-12-31|
|
||||
définition f.résidence égal à Métropole
|
||||
règle f.personne_charge_effective_permanente_est_parent rempli
|
||||
assertion f.montant_versé = 435,55€
|
||||
définition f.i_ressources_ménage égal à 30000 €
|
||||
définition f.i_date_courante égal à |2021-12-31|
|
||||
définition f.i_résidence égal à Métropole
|
||||
règle f.i_personne_charge_effective_permanente_est_parent rempli
|
||||
assertion f.i_montant_versé = 435,55€
|
||||
|
||||
déclaration champ d'application Test12:
|
||||
contexte f champ d'application InterfaceAllocationsFamiliales
|
||||
f champ d'application InterfaceAllocationsFamiliales
|
||||
|
||||
champ d'application Test12:
|
||||
définition f.enfants égal à [EnfantEntrée {
|
||||
définition f.i_enfants égal à [EnfantEntrée {
|
||||
-- d_identifiant: 0
|
||||
-- d_date_de_naissance: |2003-02-22|
|
||||
-- d_rémuneration_mensuelle: 0€
|
||||
@ -296,18 +296,18 @@ champ d'application Test12:
|
||||
-- d_a_déjà_ouvert_droit_aux_allocations_familiales: vrai
|
||||
-- d_bénéficie_titre_personnel_aide_personnelle_logement: faux
|
||||
}]
|
||||
définition f.ressources_ménage égal à 20000 €
|
||||
définition f.date_courante égal à |2019-08-26|
|
||||
définition f.résidence égal à Mayotte
|
||||
règle f.avait_enfant_à_charge_avant_1er_janvier_2012 rempli
|
||||
règle f.personne_charge_effective_permanente_est_parent rempli
|
||||
assertion f.montant_versé = 315,84€
|
||||
définition f.i_ressources_ménage égal à 20000 €
|
||||
définition f.i_date_courante égal à |2019-08-26|
|
||||
définition f.i_résidence égal à Mayotte
|
||||
règle f.i_avait_enfant_à_charge_avant_1er_janvier_2012 rempli
|
||||
règle f.i_personne_charge_effective_permanente_est_parent rempli
|
||||
assertion f.i_montant_versé = 315,84€
|
||||
|
||||
déclaration champ d'application Test13:
|
||||
contexte f champ d'application InterfaceAllocationsFamiliales
|
||||
f champ d'application InterfaceAllocationsFamiliales
|
||||
|
||||
champ d'application Test13:
|
||||
définition f.enfants égal à [EnfantEntrée {
|
||||
définition f.i_enfants égal à [EnfantEntrée {
|
||||
-- d_identifiant: 0
|
||||
-- d_date_de_naissance: |2008-02-22|
|
||||
-- d_rémuneration_mensuelle: 0€
|
||||
@ -315,9 +315,9 @@ champ d'application Test13:
|
||||
-- d_a_déjà_ouvert_droit_aux_allocations_familiales: vrai
|
||||
-- d_bénéficie_titre_personnel_aide_personnelle_logement: faux
|
||||
}]
|
||||
définition f.ressources_ménage égal à 65000 €
|
||||
définition f.date_courante égal à |2019-08-26|
|
||||
définition f.résidence égal à Mayotte
|
||||
règle f.personne_charge_effective_permanente_est_parent rempli
|
||||
assertion f.montant_versé = 34,99€
|
||||
définition f.i_ressources_ménage égal à 65000 €
|
||||
définition f.i_date_courante égal à |2019-08-26|
|
||||
définition f.i_résidence égal à Mayotte
|
||||
règle f.i_personne_charge_effective_permanente_est_parent rempli
|
||||
assertion f.i_montant_versé = 34,99€
|
||||
```
|
||||
|
@ -4,10 +4,10 @@
|
||||
|
||||
```catala
|
||||
déclaration champ d'application Données:
|
||||
contexte enfant1 contenu Enfant
|
||||
contexte enfant2 contenu Enfant
|
||||
contexte enfant3 contenu Enfant
|
||||
contexte enfant4 contenu Enfant
|
||||
sortie enfant1 contenu Enfant
|
||||
sortie enfant2 contenu Enfant
|
||||
sortie enfant3 contenu Enfant
|
||||
sortie enfant4 contenu Enfant
|
||||
|
||||
champ d'application Données:
|
||||
définition enfant1 égal à Enfant {
|
||||
@ -52,8 +52,8 @@ champ d'application Données:
|
||||
}
|
||||
|
||||
déclaration champ d'application Test1:
|
||||
contexte données champ d'application Données
|
||||
contexte f champ d'application PrestationsFamiliales
|
||||
données champ d'application Données
|
||||
f champ d'application PrestationsFamiliales
|
||||
|
||||
champ d'application Test1:
|
||||
définition f.date_courante égal à |2020-05-01|
|
||||
|
@ -30,16 +30,16 @@ déclaration structure BienUsufruitRenteViagère:
|
||||
donnée prise_en_compte_pour_réserve_héréditaire contenu booléen
|
||||
|
||||
déclaration champ d'application RéserveHéréditaire:
|
||||
contexte quotité_réserve_héréditaire contenu décimal
|
||||
contexte enfants contenu collection Enfant
|
||||
contexte enfant_pris_en_compte_réserve_héréditaire contenu booléen dépend de Enfant
|
||||
contexte enfants_réserve_héréditaire contenu collection Enfant
|
||||
contexte conjoint_survivant_non_divorcé condition
|
||||
sortie quotité_réserve_héréditaire contenu décimal
|
||||
entrée enfants contenu collection Enfant
|
||||
interne enfant_pris_en_compte_réserve_héréditaire contenu booléen dépend de Enfant
|
||||
interne enfants_réserve_héréditaire contenu collection Enfant
|
||||
entrée conjoint_survivant_non_divorcé condition
|
||||
|
||||
contexte patrimoine_total contenu argent
|
||||
contexte biens_usufruit_rente_viagère contenu collection BienUsufruitRenteViagère
|
||||
contexte patrimoine_assiette_réserve_héréditaire contenu argent
|
||||
contexte montant_réserve_héréditaire contenu argent
|
||||
entrée patrimoine_total contenu argent
|
||||
entrée biens_usufruit_rente_viagère contenu collection BienUsufruitRenteViagère
|
||||
sortie patrimoine_assiette_réserve_héréditaire contenu argent
|
||||
sortie montant_réserve_héréditaire contenu argent
|
||||
```
|
||||
|
||||
######## Article 913 | LEGIARTI000006435557
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
```catala
|
||||
déclaration champ d'application Enfants:
|
||||
contexte base contenu Enfant dépend de entier
|
||||
sortie base contenu Enfant dépend de entier
|
||||
|
||||
champ d'application Enfants:
|
||||
définition base de identifiant égal à
|
||||
@ -18,7 +18,7 @@ champ d'application Enfants:
|
||||
|
||||
```catala
|
||||
déclaration champ d'application Test1:
|
||||
contexte réserve_héréditaire champ d'application RéserveHéréditaire
|
||||
réserve_héréditaire champ d'application RéserveHéréditaire
|
||||
|
||||
champ d'application Test1:
|
||||
définition réserve_héréditaire.patrimoine_total égal à 300 000€
|
||||
@ -29,8 +29,8 @@ champ d'application Test1:
|
||||
|
||||
```catala
|
||||
déclaration champ d'application Test2:
|
||||
contexte réserve_héréditaire champ d'application RéserveHéréditaire
|
||||
contexte enfants champ d'application Enfants
|
||||
réserve_héréditaire champ d'application RéserveHéréditaire
|
||||
enfants champ d'application Enfants
|
||||
|
||||
champ d'application Test2:
|
||||
définition réserve_héréditaire.patrimoine_total égal à 300 000 €
|
||||
@ -41,8 +41,8 @@ champ d'application Test2:
|
||||
|
||||
```catala
|
||||
déclaration champ d'application Test3:
|
||||
contexte réserve_héréditaire champ d'application RéserveHéréditaire
|
||||
contexte enfants champ d'application Enfants
|
||||
réserve_héréditaire champ d'application RéserveHéréditaire
|
||||
enfants champ d'application Enfants
|
||||
|
||||
champ d'application Test3:
|
||||
définition réserve_héréditaire.patrimoine_total égal à 300 000 €
|
||||
@ -54,8 +54,8 @@ champ d'application Test3:
|
||||
|
||||
```catala
|
||||
déclaration champ d'application Test4:
|
||||
contexte réserve_héréditaire champ d'application RéserveHéréditaire
|
||||
contexte enfants champ d'application Enfants
|
||||
réserve_héréditaire champ d'application RéserveHéréditaire
|
||||
enfants champ d'application Enfants
|
||||
|
||||
champ d'application Test4:
|
||||
définition réserve_héréditaire.patrimoine_total égal à 300 000 €
|
||||
|
@ -13,7 +13,7 @@ deklaracja zakres UmowaSprzedazy:
|
||||
kontekst kwota typu pieniądze
|
||||
kontekst inne_prawa_majatkowe warunek
|
||||
kontekst stawka_podatku typu dziesiętny
|
||||
kontekst podatek typu pieniądze
|
||||
wyjście podatek typu pieniądze
|
||||
|
||||
zakres UmowaSprzedazy:
|
||||
definicja podatek wynosi
|
||||
@ -44,7 +44,7 @@ deklaracja zakres UmowaZamianyLubDarowizny:
|
||||
kontekst kwota typu pieniądze
|
||||
kontekst inne_prawa_majatkowe warunek
|
||||
kontekst stawka_podatku typu dziesiętny
|
||||
kontekst podatek typu pieniądze
|
||||
wyjście podatek typu pieniądze
|
||||
|
||||
zakres UmowaZamianyLubDarowizny:
|
||||
definicja podatek wynosi
|
||||
@ -71,7 +71,7 @@ zakres UmowaZamianyLubDarowizny:
|
||||
deklaracja zakres OdplatneUzytkowanie:
|
||||
kontekst kwota typu pieniądze
|
||||
kontekst stawka_podatku typu dziesiętny
|
||||
kontekst podatek typu pieniądze
|
||||
wyjście podatek typu pieniądze
|
||||
|
||||
zakres OdplatneUzytkowanie:
|
||||
definicja podatek wynosi
|
||||
@ -87,7 +87,7 @@ zakres OdplatneUzytkowanie:
|
||||
deklaracja zakres PozyczkaLubDepozytNieprawidlowy:
|
||||
kontekst kwota typu pieniądze
|
||||
kontekst stawka_podatku typu dziesiętny
|
||||
kontekst podatek typu pieniądze
|
||||
wyjście podatek typu pieniądze
|
||||
|
||||
zakres PozyczkaLubDepozytNieprawidlowy:
|
||||
definicja podatek wynosi
|
||||
@ -133,7 +133,7 @@ zakres Hipoteka:
|
||||
deklaracja zakres UmowaSpolki:
|
||||
kontekst kwota typu pieniądze
|
||||
kontekst stawka_podatku typu dziesiętny
|
||||
kontekst podatek typu pieniądze
|
||||
wyjście podatek typu pieniądze
|
||||
|
||||
zakres UmowaSpolki:
|
||||
definicja podatek wynosi
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
```catala
|
||||
deklaracja zakres Test_A7_U1_P1_PPa:
|
||||
kontekst sprzedaz zakres UmowaSprzedazy
|
||||
sprzedaz zakres UmowaSprzedazy
|
||||
|
||||
zakres Test_A7_U1_P1_PPa:
|
||||
definicja sprzedaz.kwota wynosi 100 PLN
|
||||
@ -13,7 +13,7 @@ zakres Test_A7_U1_P1_PPa:
|
||||
|
||||
|
||||
deklaracja zakres Test_A7_U1_P1_PPb:
|
||||
kontekst sprzedaz zakres UmowaSprzedazy
|
||||
sprzedaz zakres UmowaSprzedazy
|
||||
|
||||
zakres Test_A7_U1_P1_PPb:
|
||||
definicja sprzedaz.kwota wynosi 100 PLN
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
```catala
|
||||
deklaracja zakres Test_A7_U1_P2_PPa:
|
||||
kontekst sprzedaz zakres UmowaZamianyLubDarowizny
|
||||
sprzedaz zakres UmowaZamianyLubDarowizny
|
||||
|
||||
zakres Test_A7_U1_P2_PPa:
|
||||
definicja sprzedaz.kwota wynosi 100 PLN
|
||||
@ -13,7 +13,7 @@ zakres Test_A7_U1_P2_PPa:
|
||||
|
||||
|
||||
deklaracja zakres Test_A7_U1_P2_PPb:
|
||||
kontekst sprzedaz zakres UmowaZamianyLubDarowizny
|
||||
sprzedaz zakres UmowaZamianyLubDarowizny
|
||||
|
||||
zakres Test_A7_U1_P2_PPb:
|
||||
definicja sprzedaz.kwota wynosi 100 PLN
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
```catala
|
||||
deklaracja zakres Test_A7_U1_P3:
|
||||
kontekst sprzedaz zakres OdplatneUzytkowanie
|
||||
sprzedaz zakres OdplatneUzytkowanie
|
||||
|
||||
zakres Test_A7_U1_P3:
|
||||
definicja sprzedaz.kwota wynosi 100 PLN
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
```catala
|
||||
deklaracja zakres Test_A7_U1_P4:
|
||||
kontekst sprzedaz zakres PozyczkaLubDepozytNieprawidlowy
|
||||
sprzedaz zakres PozyczkaLubDepozytNieprawidlowy
|
||||
|
||||
zakres Test_A7_U1_P4:
|
||||
definicja sprzedaz.kwota wynosi 200 PLN
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
```catala
|
||||
deklaracja zakres Test_A7_U1_P7:
|
||||
kontekst sprzedaz zakres PozyczkaLubDepozytNieprawidlowy
|
||||
sprzedaz zakres PozyczkaLubDepozytNieprawidlowy
|
||||
|
||||
zakres Test_A7_U1_P7:
|
||||
definicja sprzedaz.kwota wynosi 200 PLN
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
```catala
|
||||
deklaracja zakres Test_A7_U1_P9:
|
||||
kontekst sprzedaz zakres UmowaSpolki
|
||||
sprzedaz zakres UmowaSpolki
|
||||
|
||||
zakres Test_A7_U1_P9:
|
||||
definicja sprzedaz.kwota wynosi 1000 PLN
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
```catala
|
||||
declaration scope UnitTest1:
|
||||
context tax_computation scope NewIncomeTaxComputation
|
||||
tax_computation scope NewIncomeTaxComputation
|
||||
|
||||
scope UnitTest1:
|
||||
definition
|
||||
@ -17,7 +17,7 @@ scope UnitTest1:
|
||||
assertion tax_computation.income_tax = $72,000
|
||||
|
||||
declaration scope UnitTest2:
|
||||
context tax_computation scope NewIncomeTaxComputationFixed
|
||||
tax_computation scope NewIncomeTaxComputationFixed
|
||||
|
||||
scope UnitTest2:
|
||||
definition tax_computation.individual equals Individual {
|
||||
|
@ -135,20 +135,26 @@ programming. Scopes also have to be declared in metadata, so here we go:
|
||||
```catala-metadata
|
||||
declaration scope IncomeTaxComputation:
|
||||
# Scope names use CamelCase.
|
||||
context individual content Individual
|
||||
# This line declares a context element of the scope, which is akin to
|
||||
input individual content Individual
|
||||
# This line declares a scope variable of the scope, which is akin to
|
||||
# a function parameter in computer science term. This is the piece of
|
||||
# data on which the scope will operate.
|
||||
context fixed_percentage content decimal
|
||||
context income_tax content money
|
||||
internal fixed_percentage content decimal
|
||||
output income_tax content money
|
||||
```
|
||||
|
||||
The scope is the basic abstraction unit in Catala programs, and the declaration
|
||||
of the scope is akin to a function signature: it contains a list of all the
|
||||
arguments along with their types. But in Catala, scopes' context elements stand
|
||||
for three things: arguments, local variables and outputs. The difference
|
||||
between these three categories will come from how the context elements are
|
||||
defined later in the code.
|
||||
arguments along with their types. But in Catala, scopes' variables stand
|
||||
for three things: input arguments, local variables and outputs. The difference
|
||||
between these three categories can be specified by the different input/output
|
||||
attributes preceding the variable names. "input" means that the variable has to
|
||||
be defined only when the scope IncomeTaxComputation is called. "internal" means
|
||||
that the variable cannot be seen from outside the scope: it is neither an input
|
||||
nor an output of the scope. "output" means that a caller scope can retrieve the
|
||||
computed value of the variable. Note that a variable can also be simulataneously
|
||||
an input and an output of the scope, in that case it should be annotated with
|
||||
"input output".
|
||||
|
||||
We now have everything to annotate the contents of article 1, which is copied
|
||||
over below.
|
||||
@ -235,8 +241,8 @@ do that later.
|
||||
|
||||
## Rules
|
||||
|
||||
So far, you've learnt how to declare a scope with some context elements, and
|
||||
give definitions to these context elements scattered accross the text of
|
||||
So far, you've learnt how to declare a scope with some variables, and
|
||||
give definitions to these variables scattered accross the text of
|
||||
the law at the relevant locations. But there is a pattern very frequent
|
||||
in legislative texts: what about conditions? A condition is a value that
|
||||
can be either true or false, like a boolean in programming. However, the
|
||||
@ -254,11 +260,11 @@ The children eligible for application of article 3
|
||||
```catala
|
||||
# To deal with children eligibility, we create a new scope.
|
||||
declaration scope Child:
|
||||
context age content integer
|
||||
input age content integer
|
||||
# The age of the child can be declared as before.
|
||||
context is_eligible_article_3 condition
|
||||
output is_eligible_article_3 condition
|
||||
# For we declare the eligibility using the special "condition" keyword
|
||||
# that stands for the content of the context element.
|
||||
# that stands for the content of the variable.
|
||||
|
||||
scope Child:
|
||||
rule is_eligible_article_3 under condition age < 18 consequence fulfilled
|
||||
@ -272,7 +278,7 @@ like boolean values.
|
||||
|
||||
## Functions
|
||||
|
||||
Catala lets you define functions anywhere in your context elements. Indeed,
|
||||
Catala lets you define functions anywhere in your scope variable. Indeed,
|
||||
Catala is a functional language and encourages using functions to describe
|
||||
relationships between data. Here's what it looks
|
||||
like in the metadata definition when we want to define a two-brackets tax
|
||||
@ -287,11 +293,11 @@ declaration structure TwoBrackets:
|
||||
# has two tax brackets, each with their own tax rate.
|
||||
|
||||
declaration scope TwoBracketsTaxComputation :
|
||||
context brackets content TwoBrackets
|
||||
# This context element is standard, and contains the description of the
|
||||
input brackets content TwoBrackets
|
||||
# This input variable contains the description of the
|
||||
# parameters of the tax formula.
|
||||
context tax_formula content money depends on money
|
||||
# But for declaring the tax_formula context element, we declare it as
|
||||
output tax_formula content money depends on money
|
||||
# But for declaring the tax_formula variable, we declare it as
|
||||
# a function: "content money depends on money" means a function that
|
||||
# returns money as output (the tax) and takes money as input (the income).
|
||||
```
|
||||
@ -332,12 +338,12 @@ income tax is 20% of the income.
|
||||
|
||||
```catala
|
||||
declaration scope NewIncomeTaxComputation:
|
||||
context two_brackets scope TwoBracketsTaxComputation
|
||||
two_brackets scope TwoBracketsTaxComputation
|
||||
# This line says that we add the item two_brackets to the context.
|
||||
# However, the "scope" keyword tells that this item is not a piece of data
|
||||
# but rather a subscope that we can use to compute things.
|
||||
context individual content Individual
|
||||
context income_tax content money
|
||||
input individual content Individual
|
||||
output income_tax content money
|
||||
|
||||
scope NewIncomeTaxComputation :
|
||||
# Since the subscope "two_brackets" is like a big function we can call,
|
||||
@ -347,10 +353,10 @@ scope NewIncomeTaxComputation :
|
||||
-- rate1: 20%
|
||||
-- rate2: 40%
|
||||
}
|
||||
# By defining the context element "brackets" of the subscope "two_brackets",
|
||||
# By defining the input variable "brackets" of the subscope "two_brackets",
|
||||
# we have changed how the subscope will execute. The subscope will execute
|
||||
# with all the values defined by the caller, then compute the value
|
||||
# of its other context elements.
|
||||
# of its other variables.
|
||||
|
||||
definition income_tax equals two_brackets.tax_formula of individual.income
|
||||
# After the subscope has executed, you can retrieve results from it. Here,
|
||||
@ -404,8 +410,8 @@ as another scope:
|
||||
```catala
|
||||
declaration scope Test1:
|
||||
# We include the scope to tax as a subscope.
|
||||
context tax_computation scope NewIncomeTaxComputation
|
||||
context income_tax content money
|
||||
tax_computation scope NewIncomeTaxComputation
|
||||
output income_tax content money
|
||||
|
||||
# To execute that test, assuming that the Catala compiler can be called
|
||||
# with "catala", enter the following command:
|
||||
@ -434,8 +440,8 @@ This test should pass. Let us now consider a failing test case:
|
||||
|
||||
```catala
|
||||
declaration scope Test2:
|
||||
context tax_computation scope NewIncomeTaxComputation
|
||||
context income_tax content money
|
||||
tax_computation scope NewIncomeTaxComputation
|
||||
output income_tax content money
|
||||
|
||||
scope Test2:
|
||||
definition tax_computation.individual equals Individual {
|
||||
@ -464,9 +470,13 @@ fixed version of the NewIncomeTaxComputation scope:
|
||||
|
||||
```catala
|
||||
declaration scope NewIncomeTaxComputationFixed:
|
||||
context two_brackets scope TwoBracketsTaxComputation
|
||||
context individual content Individual
|
||||
context income_tax content money
|
||||
two_brackets scope TwoBracketsTaxComputation
|
||||
input individual content Individual
|
||||
output tax_formula content money depends on money
|
||||
context output income_tax content money
|
||||
# This variable is tagged with "context", a new concept which we have not
|
||||
# introduced yet. For now, ignore it as we'll come back to it in the section
|
||||
# "Context scope variables".
|
||||
|
||||
scope NewIncomeTaxComputationFixed :
|
||||
definition two_brackets.brackets equals TwoBrackets {
|
||||
@ -474,6 +484,7 @@ scope NewIncomeTaxComputationFixed :
|
||||
-- rate1: 20%
|
||||
-- rate2: 40%
|
||||
}
|
||||
definition tax_formula of income equals two_brackets.tax_formula of income
|
||||
```
|
||||
|
||||
To define an exception to a rule, you have to first label the rule that
|
||||
@ -496,8 +507,8 @@ And the test that should now work:
|
||||
|
||||
```catala
|
||||
declaration scope Test3:
|
||||
context tax_computation scope NewIncomeTaxComputationFixed
|
||||
context income_tax content money
|
||||
tax_computation scope NewIncomeTaxComputationFixed
|
||||
output income_tax content money
|
||||
|
||||
scope Test3:
|
||||
definition tax_computation.individual equals Individual {
|
||||
@ -515,6 +526,68 @@ patterns. Sometimes, you want to declare an exception to a groupe of
|
||||
piecewise definitions. To do that, simply use the same label for all
|
||||
the piecewise definitions.
|
||||
|
||||
## Context scope variables
|
||||
|
||||
With its "input","output" and "internal" variables, Catala's scope are close
|
||||
to regular functions with arguments, local variables and output. However, the
|
||||
law can sometimes be adversarial to good programming practices and define
|
||||
provisions that break the abstraction barrier normally associated to a function.
|
||||
|
||||
This can be the case when an outside body of legislative text "reuses" a
|
||||
a legal concept but adding a twist on it. Consider the following fictionnal
|
||||
(but not quite pathological computational-wise) example.
|
||||
|
||||
### Article 7
|
||||
|
||||
The justice system delivers fines to individuals when they committed an offense.
|
||||
The fines are determined based on the amount of taxes paid by the individual.
|
||||
The more taxes the invidual pays, the higher the fine. However, the determination
|
||||
of the amount of taxes paid by an individual in this context shall include
|
||||
a flat tax fee of $500 for individuals earning less than $10,000.
|
||||
|
||||
```catala
|
||||
# To compute the basis determined for issuing the fines, we create a new scope.
|
||||
declaration scope BasisForFineDetermination:
|
||||
tax_computation scope NewIncomeTaxComputationFixed
|
||||
# This scope will call the NewIncomeTaxComputationFixed scope that defines
|
||||
# the proper tax computation.
|
||||
input individual content Individual
|
||||
output basis_for_fine content money
|
||||
|
||||
scope BasisForFineDetermination :
|
||||
# First, we link the inputs and outputs of the two scopes.
|
||||
definition tax_computation.individual equals individual
|
||||
definition basis_for_fine equals tax_computation.income_tax
|
||||
|
||||
# But then, how to account for the provision of the law that reverts the
|
||||
# mechanism canceling taxes for individuals earning less than $10,000 dollars?
|
||||
|
||||
# This is where the "context" concept comes into play. Indeed, we had annotated
|
||||
# the "income_tax" variable of "NewIncomeTaxComputationFixed" with the
|
||||
# "context" attribute. "context" is a variant of "input" that exposes the
|
||||
# variable as an input of the scope. However, it is more permissive than
|
||||
# "input" because it lets you re-define the "context" variable inside its
|
||||
# own scope. Then, you're faced with a choice for the value of "income_tax":
|
||||
# do you take the value coming from its definition inside
|
||||
# "NewIncomeTaxComputationFixed" or do you take the value coming from the
|
||||
# input of the scope? This dilemma is resolved in two ways. First, by looking
|
||||
# at the conditions of the definitions: only definitions that have a condition
|
||||
# evaluating to "true" at runtime will be considered. If there's only one,
|
||||
# the pick is easy. But what if two definitions trigger at the same time,
|
||||
# one from the input and one from the "NewIncomeTaxComputationFixed" scope?
|
||||
# Well, second, in that case we always prioritize the input definition for
|
||||
# picking. In Catala, the caller scope has priority over the callee scope
|
||||
# for "context" variable. It's as if the caller provided an extra exception
|
||||
# for the definition of the scope variable.
|
||||
|
||||
# Back to our little problem, the solution is here to provide from the outside
|
||||
# an exceptional definition for income tax for people earning less than
|
||||
# $10,0000.
|
||||
definition tax_computation.income_tax under condition
|
||||
individual.income <=$ $10,000
|
||||
consequence equals $500
|
||||
```
|
||||
|
||||
## Catala values
|
||||
|
||||
So far, this tutorial has introduced you to the basic structure of Catala
|
||||
@ -530,8 +603,8 @@ see the section about conditions above.
|
||||
|
||||
```catala
|
||||
declaration scope BooleanValues:
|
||||
context value1 condition
|
||||
context value2 content boolean
|
||||
internal value1 condition
|
||||
internal value2 content boolean
|
||||
|
||||
scope BooleanValues:
|
||||
rule value1 under condition false and true consequence fulfilled
|
||||
@ -549,8 +622,8 @@ due to them being stored in 32 or 64 bits. Integers can be negative.
|
||||
|
||||
```catala
|
||||
declaration scope IntegerValues:
|
||||
context value1 content integer
|
||||
context value2 content integer
|
||||
internal value1 content integer
|
||||
internal value2 content integer
|
||||
|
||||
scope IntegerValues:
|
||||
definition value1 under condition 12 - (5 * 3) < 65 consequence equals 45 / 9
|
||||
@ -566,8 +639,8 @@ approximate computations. Operators are suffixed with ".".
|
||||
|
||||
```catala
|
||||
declaration scope DecimalValues:
|
||||
context value1 content decimal
|
||||
context value2 content decimal
|
||||
internal value1 content decimal
|
||||
internal value2 content decimal
|
||||
|
||||
scope DecimalValues:
|
||||
definition value1 under condition
|
||||
@ -590,8 +663,8 @@ yielding a decimal.
|
||||
|
||||
```catala
|
||||
declaration scope MoneyValues:
|
||||
context value1 content decimal
|
||||
context value2 content money
|
||||
internal value1 content decimal
|
||||
internal value2 content money
|
||||
|
||||
scope MoneyValues:
|
||||
definition value1 under condition
|
||||
@ -616,8 +689,8 @@ duration operators are prefixed by "^".
|
||||
|
||||
```catala
|
||||
declaration scope DateValues:
|
||||
context value1 content date
|
||||
context value2 content duration
|
||||
internal value1 content date
|
||||
internal value2 content duration
|
||||
|
||||
scope DateValues:
|
||||
definition value1 equals |2000-01-01| +@ 1 year # yields |2001-01-01|
|
||||
@ -635,8 +708,8 @@ to compute all sorts of values.
|
||||
|
||||
```catala
|
||||
declaration scope CollectionValues:
|
||||
context value1 content collection integer
|
||||
context value2 content integer
|
||||
internal value1 content collection integer
|
||||
internal value2 content integer
|
||||
|
||||
scope CollectionValues:
|
||||
definition value1 equals [45;-6;3;4;0;2155]
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
```catala
|
||||
déclaration champ d'application TestUnitaire1:
|
||||
contexte calcul_impôt champ d'application NouveauCalculImpôtRevenu
|
||||
calcul_impôt champ d'application NouveauCalculImpôtRevenu
|
||||
|
||||
champ d'application TestUnitaire1:
|
||||
définition
|
||||
@ -17,7 +17,7 @@ champ d'application TestUnitaire1:
|
||||
assertion calcul_impôt.impôt_revenu = 72 000€
|
||||
|
||||
déclaration champ d'application TestUnitaire2:
|
||||
contexte calcul_impôt champ d'application NouveauCalculImpôtRevenuCorrect
|
||||
calcul_impôt champ d'application NouveauCalculImpôtRevenuCorrect
|
||||
|
||||
champ d'application TestUnitaire2:
|
||||
définition calcul_impôt.personne égal à Personne {
|
||||
|
@ -6,6 +6,13 @@ législatifs avec ce langage. Ce document s'adresse principalement à des dével
|
||||
ou des personnes ayant déjà programmé, même si des juristes avec des appétences
|
||||
en informatique devraient pouvoir s'en sortir.
|
||||
|
||||
```catala
|
||||
# Attention, ce tutoriel en français n'est peut-être pas à jour avec
|
||||
# les dernières fonctionnalités du langage. En effet, le tutoriel en anglais
|
||||
# disponible sur https://catala-lang.org/en/examples/tutorial constitue
|
||||
# la référence pour le langage.
|
||||
```
|
||||
|
||||
### Programmation littéraire
|
||||
|
||||
Pour commencer à écrire un programme Catala, vous devez partir du texte
|
||||
@ -110,12 +117,12 @@ préalablement dans les métadonnées, de la manière suivante:
|
||||
```catala-metadata
|
||||
déclaration champ d'application CalculImpôtRevenu:
|
||||
# Les champs d'application utilisent le CamelCase
|
||||
contexte personne contenu Personne
|
||||
entrée personne contenu Personne
|
||||
# Cette ligne déclare un élémént de contexte du champ d'application,
|
||||
# cela ressemble à un paramètre de fonction en informatique. C'est la
|
||||
# donnée sur laquelle le champ d'application va intervenir
|
||||
contexte pourcentage_fixe contenu décimal
|
||||
contexte impôt_revenu contenu argent
|
||||
interne pourcentage_fixe contenu décimal
|
||||
sortie impôt_revenu contenu argent
|
||||
```
|
||||
|
||||
Nous avons maintenant tout ce dont nous avons besoin pour annoter le contenu
|
||||
@ -216,8 +223,8 @@ déclaration structure DeuxTranches:
|
||||
donnée taux2 contenu décimal
|
||||
|
||||
déclaration champ d'application CalculImpôtDeuxTranches :
|
||||
contexte tranches contenu DeuxTranches
|
||||
contexte formule_imposition contenu argent dépend de argent
|
||||
entrée tranches contenu DeuxTranches
|
||||
sortie formule_imposition contenu argent dépend de argent
|
||||
```
|
||||
|
||||
Et dans le code :
|
||||
@ -253,13 +260,13 @@ l'impôt sur le revenu de l'article 1 est de 40% du revenu au-dessus de
|
||||
|
||||
```catala
|
||||
déclaration champ d'application NouveauCalculImpôtRevenu:
|
||||
contexte deux_tranches champ d'application CalculImpôtDeuxTranches
|
||||
deux_tranches champ d'application CalculImpôtDeuxTranches
|
||||
# Cette ligne indique que nous ajoutons l'élément deux_tranches au contexte.
|
||||
# Toutefois, les mots clé "champ d'application" indique que l'élément n'est
|
||||
# pas une donnée mais plutôt un sous-champ d'application qui peut être
|
||||
# utilisé pour calculer des choses.
|
||||
contexte personne contenu Personne
|
||||
contexte impôt_revenu contenu argent
|
||||
entrée personne contenu Personne
|
||||
sortie impôt_revenu contenu argent
|
||||
|
||||
champ d'application NouveauCalculImpôtRevenu :
|
||||
définition deux_tranches.tranches égal à DeuxTranches {
|
||||
@ -305,8 +312,8 @@ champ d'application :
|
||||
|
||||
```catala
|
||||
déclaration champ d'application Test1:
|
||||
contexte calcul_impôt champ d'application NouveauCalculImpôtRevenu
|
||||
contexte impôt_revenu contenu argent
|
||||
calcul_impôt champ d'application NouveauCalculImpôtRevenu
|
||||
sortie impôt_revenu contenu argent
|
||||
|
||||
champ d'application Test1:
|
||||
définition
|
||||
@ -332,8 +339,8 @@ Ce test devrait être bon. Maintenant étudions un test en échec :
|
||||
|
||||
```catala
|
||||
déclaration champ d'application Test2:
|
||||
contexte calcul_impôt champ d'application NouveauCalculImpôtRevenu
|
||||
contexte impôt_revenu contenu argent
|
||||
calcul_impôt champ d'application NouveauCalculImpôtRevenu
|
||||
sortie impôt_revenu contenu argent
|
||||
|
||||
champ d'application Test2:
|
||||
définition calcul_impôt.personne égal à Personne {
|
||||
@ -364,9 +371,9 @@ version correcte du champ d'application NouveauCalculImpotRevenu :
|
||||
|
||||
```catala
|
||||
déclaration champ d'application NouveauCalculImpôtRevenuCorrect:
|
||||
contexte deux_tranches champ d'application CalculImpôtDeuxTranches
|
||||
contexte personne contenu Personne
|
||||
contexte impôt_revenu contenu argent
|
||||
deux_tranches champ d'application CalculImpôtDeuxTranches
|
||||
entrée personne contenu Personne
|
||||
sortie impôt_revenu contenu argent
|
||||
|
||||
champ d'application NouveauCalculImpôtRevenuCorrect :
|
||||
définition deux_tranches.tranches égal à DeuxTranches {
|
||||
@ -394,8 +401,8 @@ Le test devrait désormais fonctionner :
|
||||
|
||||
```catala
|
||||
déclaration champ d'application Test3:
|
||||
contexte calcul_impôt champ d'application NouveauCalculImpôtRevenuCorrect
|
||||
contexte impôt_revenu contenu argent
|
||||
calcul_impôt champ d'application NouveauCalculImpôtRevenuCorrect
|
||||
sortie impôt_revenu contenu argent
|
||||
|
||||
champ d'application Test3:
|
||||
définition calcul_impôt.personne égal à Personne {
|
||||
|
@ -8,7 +8,7 @@ declaration structure Period:
|
||||
declaration scope PeriodMerge:
|
||||
context periods1 content collection Period
|
||||
context periods2 content collection Period
|
||||
context output content collection Period
|
||||
output output_periods content collection Period
|
||||
|
||||
scope PeriodMerge:
|
||||
# Placeholders, overwritten by caller
|
||||
@ -18,7 +18,7 @@ scope PeriodMerge:
|
||||
# TODO: find a way to implement the merging of two collections of date
|
||||
# periods into a single non-overlapping collection of date periods such
|
||||
# that the output covers both input date ranges.
|
||||
definition output equals []
|
||||
definition output_periods equals []
|
||||
|
||||
declaration structure PreviousSaleWhereSection121aApplied:
|
||||
data date_of_sale_or_exchange content date
|
||||
@ -30,23 +30,23 @@ declaration enumeration OtherSection121aSale:
|
||||
PreviousSaleWhereSection121aApplied
|
||||
|
||||
declaration scope Section121SinglePerson:
|
||||
context requirements_met condition
|
||||
context requirements_ownership_met condition
|
||||
context requirements_usage_met condition
|
||||
context date_of_sale_or_exchange content date
|
||||
context property_ownage content collection Period
|
||||
output requirements_met condition
|
||||
output requirements_ownership_met condition
|
||||
output requirements_usage_met condition
|
||||
input date_of_sale_or_exchange content date
|
||||
input property_ownage content collection Period
|
||||
# Invariant: the periods in the collection are disjoint
|
||||
context property_usage_as_principal_residence
|
||||
input property_usage_as_principal_residence
|
||||
content collection Period
|
||||
# Invariant: the periods in the collection are disjoint
|
||||
context aggregate_periods_from_last_five_years content duration
|
||||
internal aggregate_periods_from_last_five_years content duration
|
||||
depends on collection Period
|
||||
context gain_cap content money
|
||||
context gain_from_sale_or_exchange_of_property content money
|
||||
context income_excluded_from_gross_income_uncapped content money
|
||||
context income_excluded_from_gross_income content money
|
||||
context section_121_b_3_applies condition
|
||||
context other_section_121a_sale content OtherSection121aSale
|
||||
context output gain_cap content money
|
||||
input gain_from_sale_or_exchange_of_property content money
|
||||
output income_excluded_from_gross_income_uncapped content money
|
||||
output income_excluded_from_gross_income content money
|
||||
context output section_121_b_3_applies condition
|
||||
input other_section_121a_sale content OtherSection121aSale
|
||||
|
||||
declaration structure PersonalData:
|
||||
data property_ownage content collection Period
|
||||
@ -69,22 +69,22 @@ declaration enumeration ReturnType:
|
||||
-- SingleReturnSurvivingSpouse content DeadSpouseInfo
|
||||
|
||||
declaration scope Section121TwoPersons:
|
||||
context person1 content PersonalData
|
||||
context section121Person1 scope Section121SinglePerson
|
||||
context person2 content PersonalData
|
||||
context section121Person2 scope Section121SinglePerson
|
||||
context section121a_requirements_met condition
|
||||
context section_121_b_2_A_condition condition
|
||||
context gain_cap_person_1 content money
|
||||
context gain_cap_person_2 content money
|
||||
context output person1 content PersonalData
|
||||
section121Person1 scope Section121SinglePerson
|
||||
context output person2 content PersonalData
|
||||
section121Person2 scope Section121SinglePerson
|
||||
internal section121a_requirements_met condition
|
||||
output section_121_b_2_A_condition condition
|
||||
output gain_cap_person_1 content money
|
||||
output gain_cap_person_2 content money
|
||||
context gain_cap content money
|
||||
context return_type content ReturnType
|
||||
context return_date content date
|
||||
context date_of_sale_or_exchange content date
|
||||
context gain_from_sale_or_exchange_of_property content money
|
||||
context income_excluded_from_gross_income_uncapped content money
|
||||
context income_excluded_from_gross_income content money
|
||||
context period_merge scope PeriodMerge
|
||||
input return_type content ReturnType
|
||||
input return_date content date
|
||||
input date_of_sale_or_exchange content date
|
||||
input gain_from_sale_or_exchange_of_property content money
|
||||
output income_excluded_from_gross_income_uncapped content money
|
||||
output income_excluded_from_gross_income content money
|
||||
period_merge scope PeriodMerge
|
||||
|
||||
# Defining sub-scopes arguments
|
||||
scope Section121TwoPersons:
|
||||
@ -128,14 +128,14 @@ scope Section121TwoPersons:
|
||||
definition gain_cap_person_2 equals section121Person2.gain_cap
|
||||
|
||||
declaration scope Section121TwoPasses:
|
||||
context first_pass scope Section121TwoPersons
|
||||
context second_pass scope Section121TwoPersons
|
||||
context return_type content ReturnType
|
||||
context return_date content date
|
||||
context date_of_sale_or_exchange content date
|
||||
context gain_from_sale_or_exchange_of_property content money
|
||||
context period_merge scope PeriodMerge
|
||||
context income_excluded_from_gross_income content money
|
||||
first_pass scope Section121TwoPersons
|
||||
second_pass scope Section121TwoPersons
|
||||
input return_type content ReturnType
|
||||
input return_date content date
|
||||
input date_of_sale_or_exchange content date
|
||||
input gain_from_sale_or_exchange_of_property content money
|
||||
period_merge scope PeriodMerge
|
||||
output income_excluded_from_gross_income content money
|
||||
|
||||
# Defining sub-scopes arguments
|
||||
scope Section121TwoPasses:
|
||||
@ -323,13 +323,13 @@ scope Section121TwoPasses under condition
|
||||
-- SingleReturn of return : [] # does not happen
|
||||
|
||||
definition second_pass.person1 equals PersonalData {
|
||||
-- property_ownage: period_merge.output
|
||||
-- property_ownage: period_merge.output_periods
|
||||
-- property_usage_as_principal_residence:
|
||||
first_pass.person1.property_usage_as_principal_residence
|
||||
-- other_section_121a_sale: first_pass.person1.other_section_121a_sale
|
||||
}
|
||||
definition second_pass.person2 equals PersonalData {
|
||||
-- property_ownage: period_merge.output
|
||||
-- property_ownage: period_merge.output_periods
|
||||
-- property_usage_as_principal_residence:
|
||||
first_pass.person2.property_usage_as_principal_residence
|
||||
-- other_section_121a_sale: first_pass.person2.other_section_121a_sale
|
||||
|
@ -7,15 +7,15 @@ declaration enumeration DiscountType:
|
||||
-- Services
|
||||
|
||||
declaration scope QualifiedEmployeeDiscount:
|
||||
context customer_price content money
|
||||
context employee_price content money
|
||||
context gross_profit_percentage content decimal
|
||||
context qualified_employee_discount content money
|
||||
context employee_discount content money
|
||||
input customer_price content money
|
||||
input employee_price content money
|
||||
output gross_profit_percentage content decimal
|
||||
output qualified_employee_discount content money
|
||||
output employee_discount content money
|
||||
context aggregate_cost content money
|
||||
context discount_type content DiscountType
|
||||
context is_property content boolean
|
||||
context is_services content boolean
|
||||
input discount_type content DiscountType
|
||||
internal is_property content boolean
|
||||
internal is_services content boolean
|
||||
|
||||
scope QualifiedEmployeeDiscount:
|
||||
definition is_property equals match discount_type with pattern
|
||||
|
@ -4,16 +4,16 @@
|
||||
|
||||
```catala
|
||||
declaration scope Data:
|
||||
context period_four_years_recent content Period
|
||||
context period_one_year_recent content Period
|
||||
context period_two_years_middle content Period
|
||||
context date_of_sale_or_exchange content date
|
||||
context gain_from_sale_or_exchange_of_property content money
|
||||
context return_date content date
|
||||
context person_ok_1 content PersonalData
|
||||
context person_ok_2 content PersonalData
|
||||
context person_ko_1 content PersonalData
|
||||
context person_ko_2 content PersonalData
|
||||
output period_four_years_recent content Period
|
||||
output period_one_year_recent content Period
|
||||
output period_two_years_middle content Period
|
||||
output date_of_sale_or_exchange content date
|
||||
output gain_from_sale_or_exchange_of_property content money
|
||||
output return_date content date
|
||||
output person_ok_1 content PersonalData
|
||||
output person_ok_2 content PersonalData
|
||||
output person_ko_1 content PersonalData
|
||||
output person_ko_2 content PersonalData
|
||||
|
||||
scope Data:
|
||||
definition date_of_sale_or_exchange equals |2021-01-01|
|
||||
@ -60,8 +60,8 @@ scope Data:
|
||||
####################### Testing Section121SinglePerson #########################
|
||||
|
||||
declaration scope Test1:
|
||||
context scope121a scope Section121SinglePerson
|
||||
context data_ scope Data
|
||||
scope121a scope Section121SinglePerson
|
||||
data_ scope Data
|
||||
|
||||
scope Test1:
|
||||
definition scope121a.date_of_sale_or_exchange equals data_.date_of_sale_or_exchange
|
||||
@ -74,8 +74,8 @@ scope Test1:
|
||||
assertion scope121a.requirements_met
|
||||
|
||||
declaration scope Test2:
|
||||
context scope121a scope Section121SinglePerson
|
||||
context data_ scope Data
|
||||
scope121a scope Section121SinglePerson
|
||||
data_ scope Data
|
||||
|
||||
scope Test2:
|
||||
definition scope121a.date_of_sale_or_exchange equals data_.date_of_sale_or_exchange
|
||||
@ -88,8 +88,8 @@ scope Test2:
|
||||
assertion not scope121a.requirements_met
|
||||
|
||||
declaration scope Test3:
|
||||
context scope121a scope Section121SinglePerson
|
||||
context data_ scope Data
|
||||
scope121a scope Section121SinglePerson
|
||||
data_ scope Data
|
||||
|
||||
scope Test3:
|
||||
definition scope121a.date_of_sale_or_exchange equals data_.date_of_sale_or_exchange
|
||||
@ -102,8 +102,8 @@ scope Test3:
|
||||
assertion not scope121a.requirements_met
|
||||
|
||||
declaration scope Test4:
|
||||
context scope121a scope Section121SinglePerson
|
||||
context data_ scope Data
|
||||
scope121a scope Section121SinglePerson
|
||||
data_ scope Data
|
||||
|
||||
scope Test4:
|
||||
definition scope121a.date_of_sale_or_exchange equals data_.date_of_sale_or_exchange
|
||||
@ -118,8 +118,8 @@ scope Test4:
|
||||
###################### Testing Section121TwoPersons ############################
|
||||
|
||||
declaration scope Test5:
|
||||
context scope121 scope Section121TwoPersons
|
||||
context data_ scope Data
|
||||
scope121 scope Section121TwoPersons
|
||||
data_ scope Data
|
||||
|
||||
scope Test5:
|
||||
definition scope121.date_of_sale_or_exchange equals data_.date_of_sale_or_exchange
|
||||
@ -130,8 +130,8 @@ scope Test5:
|
||||
assertion scope121.income_excluded_from_gross_income = $250,000
|
||||
|
||||
declaration scope Test6:
|
||||
context scope121 scope Section121TwoPersons
|
||||
context data_ scope Data
|
||||
scope121 scope Section121TwoPersons
|
||||
data_ scope Data
|
||||
|
||||
scope Test6:
|
||||
definition scope121.date_of_sale_or_exchange equals data_.date_of_sale_or_exchange
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
```catala
|
||||
declaration scope TestSection132_1:
|
||||
context section_132 scope QualifiedEmployeeDiscount
|
||||
section_132 scope QualifiedEmployeeDiscount
|
||||
|
||||
scope TestSection132_1:
|
||||
definition section_132.customer_price equals $1500
|
||||
@ -18,7 +18,7 @@ scope TestSection132_1:
|
||||
|
||||
```catala
|
||||
declaration scope TestSection132_2:
|
||||
context section_132 scope QualifiedEmployeeDiscount
|
||||
section_132 scope QualifiedEmployeeDiscount
|
||||
|
||||
scope TestSection132_2:
|
||||
definition section_132.customer_price equals $1500
|
||||
@ -32,7 +32,7 @@ scope TestSection132_2:
|
||||
|
||||
```catala
|
||||
declaration scope TestSection132_3:
|
||||
context section_132 scope QualifiedEmployeeDiscount
|
||||
section_132 scope QualifiedEmployeeDiscount
|
||||
|
||||
scope TestSection132_3:
|
||||
definition section_132.customer_price equals $1500
|
||||
|
5092
french_law/js/french_law.js
generated
5092
french_law/js/french_law.js
generated
File diff suppressed because one or more lines are too long
34
french_law/js/package-lock.json
generated
34
french_law/js/package-lock.json
generated
@ -1,40 +1,8 @@
|
||||
{
|
||||
"name": "french_law",
|
||||
"version": "0.5.0",
|
||||
"lockfileVersion": 2,
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "french_law",
|
||||
"version": "0.5.0",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"benchmark": "^2.1.4",
|
||||
"lodash": "^4.17.21",
|
||||
"platform": "^1.3.6"
|
||||
},
|
||||
"devDependencies": {}
|
||||
},
|
||||
"node_modules/benchmark": {
|
||||
"version": "2.1.4",
|
||||
"resolved": "https://registry.npmjs.org/benchmark/-/benchmark-2.1.4.tgz",
|
||||
"integrity": "sha1-CfPeMckWQl1JjMLuVloOvzwqVik=",
|
||||
"dependencies": {
|
||||
"lodash": "^4.17.4",
|
||||
"platform": "^1.3.3"
|
||||
}
|
||||
},
|
||||
"node_modules/lodash": {
|
||||
"version": "4.17.21",
|
||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
|
||||
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
|
||||
},
|
||||
"node_modules/platform": {
|
||||
"version": "1.3.6",
|
||||
"resolved": "https://registry.npmjs.org/platform/-/platform-1.3.6.tgz",
|
||||
"integrity": "sha512-fnWVljUchTro6RiCFvCXBbNhJc2NijN7oIQxbwsyL0buWJPG85v81ehlHI9fXrJsMNgTofEoWIQeClKpgxFLrg=="
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"benchmark": {
|
||||
"version": "2.1.4",
|
||||
|
@ -22,15 +22,13 @@ let compute_allocations_familiales ~(current_date : Runtime.date)
|
||||
let result =
|
||||
AF.interface_allocations_familiales
|
||||
{
|
||||
AF.date_courante_in = (fun _ -> current_date);
|
||||
AF.enfants_in = (fun _ -> children);
|
||||
AF.enfants_a_charge_in = no_input;
|
||||
AF.ressources_menage_in = (fun _ -> money_of_units_int income);
|
||||
AF.residence_in = (fun _ -> residence);
|
||||
AF.montant_verse_in = no_input;
|
||||
AF.personne_charge_effective_permanente_est_parent_in = (fun _ -> is_parent);
|
||||
AF.personne_charge_effective_permanente_remplit_titre_I_in = (fun _ -> fills_title_I);
|
||||
AF.avait_enfant_a_charge_avant_1er_janvier_2012_in = (fun _ -> had_rights_open_before_2012);
|
||||
AF.i_date_courante_in = current_date;
|
||||
AF.i_enfants_in = children;
|
||||
AF.i_ressources_menage_in = money_of_units_int income;
|
||||
AF.i_residence_in = residence;
|
||||
AF.i_personne_charge_effective_permanente_est_parent_in = is_parent;
|
||||
AF.i_personne_charge_effective_permanente_remplit_titre_I_in = fills_title_I;
|
||||
AF.i_avait_enfant_a_charge_avant_1er_janvier_2012_in = had_rights_open_before_2012;
|
||||
}
|
||||
in
|
||||
money_to_float result.AF.montant_verse_out
|
||||
money_to_float result.AF.i_montant_verse_out
|
||||
|
@ -39,8 +39,6 @@ class type enfant_entree =
|
||||
- "Confié aux service sociaux, allocation versée aux services sociaux" *)
|
||||
|
||||
method aDejaOuvertDroitAuxAllocationsFamiliales : bool Js.t Js.readonly_prop
|
||||
|
||||
method beneficieATitrePersonnelAidePersonnelleAuLogement : bool Js.t Js.readonly_prop
|
||||
end
|
||||
|
||||
class type allocations_familiales_input =
|
||||
@ -201,70 +199,61 @@ let _ =
|
||||
let result =
|
||||
AF.interface_allocations_familiales
|
||||
{
|
||||
AF.personne_charge_effective_permanente_est_parent_in =
|
||||
(fun _ ->
|
||||
Js.to_bool input##.personneQuiAssumeLaChargeEffectivePermanenteEstParent);
|
||||
AF.personne_charge_effective_permanente_remplit_titre_I_in =
|
||||
(fun _ ->
|
||||
Js.to_bool
|
||||
input##.personneQuiAssumeLaChargeEffectivePermanenteRemplitConditionsTitreISecuriteSociale);
|
||||
AF.date_courante_in =
|
||||
(fun _ ->
|
||||
date_of_numbers
|
||||
input##.currentDate##getUTCFullYear
|
||||
input##.currentDate##getUTCMonth
|
||||
input##.currentDate##getUTCDate);
|
||||
AF.enfants_in =
|
||||
(fun _ ->
|
||||
Array.map
|
||||
(fun (child : enfant_entree Js.t) ->
|
||||
{
|
||||
AF.d_beneficie_titre_personnel_aide_personnelle_logement =
|
||||
Js.to_bool child##.beneficieATitrePersonnelAidePersonnelleAuLogement;
|
||||
AF.d_a_deja_ouvert_droit_aux_allocations_familiales =
|
||||
Js.to_bool child##.aDejaOuvertDroitAuxAllocationsFamiliales;
|
||||
AF.d_identifiant = integer_of_int child##.id;
|
||||
AF.d_date_de_naissance =
|
||||
date_of_numbers
|
||||
child##.dateNaissance##getUTCFullYear
|
||||
child##.dateNaissance##getUTCMonth
|
||||
child##.dateNaissance##getUTCDate;
|
||||
AF.d_prise_en_charge =
|
||||
(match Js.to_string child##.priseEnCharge with
|
||||
| "Effective et permanente" -> EffectiveEtPermanente ()
|
||||
| "Garde alternée, allocataire unique" ->
|
||||
GardeAlterneeAllocataireUnique ()
|
||||
| "Garde alternée, partage des allocations" ->
|
||||
GardeAlterneePartageAllocations ()
|
||||
| "Confié aux service sociaux, allocation versée à la famille" ->
|
||||
ServicesSociauxAllocationVerseeALaFamille ()
|
||||
| "Confié aux service sociaux, allocation versée aux services \
|
||||
sociaux" ->
|
||||
ServicesSociauxAllocationVerseeAuxServicesSociaux ()
|
||||
| _ -> failwith "Unknown prise en charge");
|
||||
AF.d_remuneration_mensuelle =
|
||||
money_of_units_int child##.remunerationMensuelle;
|
||||
})
|
||||
(Js.to_array input##.children));
|
||||
AF.enfants_a_charge_in = no_input;
|
||||
AF.ressources_menage_in = (fun _ -> money_of_units_int input##.income);
|
||||
AF.residence_in =
|
||||
(fun _ ->
|
||||
match Js.to_string input##.residence with
|
||||
| "Métropole" -> AF.Metropole ()
|
||||
| "Guyane" -> AF.Guyane ()
|
||||
| "Guadeloupe" -> AF.Guadeloupe ()
|
||||
| "Martinique" -> AF.Martinique ()
|
||||
| "La Réunion" -> AF.LaReunion ()
|
||||
| "Saint Barthélemy" -> AF.SaintBarthelemy ()
|
||||
| "Saint Pierre et Miquelon" -> AF.SaintPierreEtMiquelon ()
|
||||
| "Saint Martin" -> AF.SaintMartin ()
|
||||
| "Mayotte" -> AF.Mayotte ()
|
||||
| _ -> failwith "unknown collectivite!");
|
||||
AF.montant_verse_in = no_input;
|
||||
AF.avait_enfant_a_charge_avant_1er_janvier_2012_in =
|
||||
(fun _ -> Js.to_bool input##.avaitEnfantAChargeAvant1erJanvier2012);
|
||||
AF.i_personne_charge_effective_permanente_est_parent_in =
|
||||
Js.to_bool input##.personneQuiAssumeLaChargeEffectivePermanenteEstParent;
|
||||
AF.i_personne_charge_effective_permanente_remplit_titre_I_in =
|
||||
Js.to_bool
|
||||
input##.personneQuiAssumeLaChargeEffectivePermanenteRemplitConditionsTitreISecuriteSociale;
|
||||
AF.i_date_courante_in =
|
||||
date_of_numbers
|
||||
input##.currentDate##getUTCFullYear
|
||||
input##.currentDate##getUTCMonth
|
||||
input##.currentDate##getUTCDate;
|
||||
AF.i_enfants_in =
|
||||
Array.map
|
||||
(fun (child : enfant_entree Js.t) ->
|
||||
{
|
||||
AF.d_a_deja_ouvert_droit_aux_allocations_familiales =
|
||||
Js.to_bool child##.aDejaOuvertDroitAuxAllocationsFamiliales;
|
||||
AF.d_identifiant = integer_of_int child##.id;
|
||||
AF.d_date_de_naissance =
|
||||
date_of_numbers
|
||||
child##.dateNaissance##getUTCFullYear
|
||||
child##.dateNaissance##getUTCMonth
|
||||
child##.dateNaissance##getUTCDate;
|
||||
AF.d_prise_en_charge =
|
||||
(match Js.to_string child##.priseEnCharge with
|
||||
| "Effective et permanente" -> EffectiveEtPermanente ()
|
||||
| "Garde alternée, allocataire unique" ->
|
||||
GardeAlterneeAllocataireUnique ()
|
||||
| "Garde alternée, partage des allocations" ->
|
||||
GardeAlterneePartageAllocations ()
|
||||
| "Confié aux service sociaux, allocation versée à la famille" ->
|
||||
ServicesSociauxAllocationVerseeALaFamille ()
|
||||
| "Confié aux service sociaux, allocation versée aux services sociaux"
|
||||
->
|
||||
ServicesSociauxAllocationVerseeAuxServicesSociaux ()
|
||||
| _ -> failwith "Unknown prise en charge");
|
||||
AF.d_remuneration_mensuelle =
|
||||
money_of_units_int child##.remunerationMensuelle;
|
||||
})
|
||||
(Js.to_array input##.children);
|
||||
AF.i_ressources_menage_in = money_of_units_int input##.income;
|
||||
AF.i_residence_in =
|
||||
(match Js.to_string input##.residence with
|
||||
| "Métropole" -> AF.Metropole ()
|
||||
| "Guyane" -> AF.Guyane ()
|
||||
| "Guadeloupe" -> AF.Guadeloupe ()
|
||||
| "Martinique" -> AF.Martinique ()
|
||||
| "La Réunion" -> AF.LaReunion ()
|
||||
| "Saint Barthélemy" -> AF.SaintBarthelemy ()
|
||||
| "Saint Pierre et Miquelon" -> AF.SaintPierreEtMiquelon ()
|
||||
| "Saint Martin" -> AF.SaintMartin ()
|
||||
| "Mayotte" -> AF.Mayotte ()
|
||||
| _ -> failwith "unknown collectivite!");
|
||||
AF.i_avait_enfant_a_charge_avant_1er_janvier_2012_in =
|
||||
Js.to_bool input##.avaitEnfantAChargeAvant1erJanvier2012;
|
||||
}
|
||||
in
|
||||
money_to_float result.AF.montant_verse_out)
|
||||
money_to_float result.AF.i_montant_verse_out)
|
||||
end)
|
||||
|
9043
french_law/ocaml/law_source/allocations_familiales.ml
generated
9043
french_law/ocaml/law_source/allocations_familiales.ml
generated
File diff suppressed because it is too large
Load Diff
@ -64,28 +64,16 @@ type enfant = {
|
||||
beneficie_titre_personnel_aide_personnelle_logement : bool;
|
||||
}
|
||||
|
||||
type interface_allocations_familiales_out = {
|
||||
date_courante_out : date;
|
||||
enfants_out : enfant_entree array;
|
||||
enfants_a_charge_out : enfant array;
|
||||
ressources_menage_out : money;
|
||||
residence_out : collectivite;
|
||||
montant_verse_out : money;
|
||||
personne_charge_effective_permanente_est_parent_out : bool;
|
||||
personne_charge_effective_permanente_remplit_titre_I_out : bool;
|
||||
avait_enfant_a_charge_avant_1er_janvier_2012_out : bool;
|
||||
}
|
||||
type interface_allocations_familiales_out = { i_montant_verse_out : money }
|
||||
|
||||
type interface_allocations_familiales_in = {
|
||||
date_courante_in : unit -> date;
|
||||
enfants_in : unit -> enfant_entree array;
|
||||
enfants_a_charge_in : unit -> enfant array;
|
||||
ressources_menage_in : unit -> money;
|
||||
residence_in : unit -> collectivite;
|
||||
montant_verse_in : unit -> money;
|
||||
personne_charge_effective_permanente_est_parent_in : unit -> bool;
|
||||
personne_charge_effective_permanente_remplit_titre_I_in : unit -> bool;
|
||||
avait_enfant_a_charge_avant_1er_janvier_2012_in : unit -> bool;
|
||||
i_date_courante_in : date;
|
||||
i_enfants_in : enfant_entree array;
|
||||
i_ressources_menage_in : money;
|
||||
i_residence_in : collectivite;
|
||||
i_personne_charge_effective_permanente_est_parent_in : bool;
|
||||
i_personne_charge_effective_permanente_remplit_titre_I_in : bool;
|
||||
i_avait_enfant_a_charge_avant_1er_janvier_2012_in : bool;
|
||||
}
|
||||
|
||||
val interface_allocations_familiales :
|
||||
|
6882
french_law/python/src/allocations_familiales.py
generated
6882
french_law/python/src/allocations_familiales.py
generated
File diff suppressed because it is too large
Load Diff
@ -41,15 +41,13 @@ def allocations_familiales(
|
||||
avait_enfant_a_charge_avant_1er_janvier_2012: bool
|
||||
):
|
||||
out = interface_allocations_familiales(InterfaceAllocationsFamilialesIn(
|
||||
date_courante_in=lambda _: date_of_datetime(date_courante),
|
||||
enfants_in=lambda _: [enfant.to_allocations_familiales()
|
||||
for enfant in enfants],
|
||||
ressources_menage_in=lambda _: money_of_units_int(ressources_menage),
|
||||
residence_in=lambda _: Collectivite(residence, Unit()),
|
||||
personne_charge_effective_permanente_est_parent_in=lambda _: personne_charge_effective_permanente_est_parent,
|
||||
personne_charge_effective_permanente_remplit_titre_I_in=lambda _: personne_charge_effective_permanente_remplit_titre_I,
|
||||
enfants_a_charge_in=no_input(),
|
||||
montant_verse_in=no_input(),
|
||||
avait_enfant_a_charge_avant_1er_janvier_2012_in=lambda _: avait_enfant_a_charge_avant_1er_janvier_2012
|
||||
i_date_courante_in=date_of_datetime(date_courante),
|
||||
i_enfants_in=[enfant.to_allocations_familiales()
|
||||
for enfant in enfants],
|
||||
i_ressources_menage_in=money_of_units_int(ressources_menage),
|
||||
i_residence_in=Collectivite(residence, Unit()),
|
||||
i_personne_charge_effective_permanente_est_parent_in=personne_charge_effective_permanente_est_parent,
|
||||
i_personne_charge_effective_permanente_remplit_titre_I_in=personne_charge_effective_permanente_remplit_titre_I,
|
||||
i_avait_enfant_a_charge_avant_1er_janvier_2012_in=avait_enfant_a_charge_avant_1er_janvier_2012
|
||||
))
|
||||
return money_to_float(out.montant_verse_out)
|
||||
return money_to_float(out.i_montant_verse_out)
|
||||
|
@ -4,4 +4,5 @@ with pkgs;
|
||||
ocamlPackages.callPackage ./. {
|
||||
bindlib = ocamlPackages.callPackage ./.nix/bindlib.nix { };
|
||||
unionfind = ocamlPackages.callPackage ./.nix/unionfind.nix { };
|
||||
cmdliner = ocamlPackages.callPackage ./.nix/cmdliner.nix { };
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ let
|
||||
pkg = ocamlPackages.callPackage ./. {
|
||||
bindlib = ocamlPackages.callPackage ./.nix/bindlib.nix { };
|
||||
unionfind = ocamlPackages.callPackage ./.nix/unionfind.nix { };
|
||||
cmdliner = ocamlPackages.callPackage ./.nix/cmdliner.nix { };
|
||||
};
|
||||
in mkShell {
|
||||
inputsFrom = [ pkg ];
|
||||
|
@ -15,8 +15,8 @@ ace.define(
|
||||
function (require, exports, module) {
|
||||
"use strict";
|
||||
var oop = require("../lib/oop");
|
||||
var TextHighlightRules = require("./text_highlight_rules")
|
||||
.TextHighlightRules;
|
||||
var TextHighlightRules =
|
||||
require("./text_highlight_rules").TextHighlightRules;
|
||||
/* --------------------- START ----------------------------- */
|
||||
var CatalaEnHighlightRules = function () {
|
||||
this.$rules = {
|
||||
@ -63,9 +63,9 @@ ace.define(
|
||||
regex: "(\\s*\\#.*$)",
|
||||
},
|
||||
{
|
||||
token: ["keyword.other", "text", "entity.name.function"],
|
||||
token: ["keyword.other", "text", "keyword.other", "text", "entity.name.function"],
|
||||
regex:
|
||||
"(context)(\\s+)([a-z\u00e9\u00e8\u00e0\u00e2\u00f9\u00ee\u00ea\u0153\u00e7][a-z\u00e9\u00e8\u00e0\u00e2\u00f9\u00ee\u00ea\u0153\u00e7A-Z\u00c9\u00c8\u00c0\u00c2\u00d9\u00ce\u00ca\u0152\u00c70-9_\\']*)",
|
||||
"(context|input|output|internal)(\\s*)(|output)(\\s+)(\\s+)([a-z\u00e9\u00e8\u00e0\u00e2\u00f9\u00ee\u00ea\u0153\u00e7][a-z\u00e9\u00e8\u00e0\u00e2\u00f9\u00ee\u00ea\u0153\u00e7A-Z\u00c9\u00c8\u00c0\u00c2\u00d9\u00ce\u00ca\u0152\u00c70-9_\\']*)",
|
||||
},
|
||||
{
|
||||
token: "keyword.control",
|
||||
@ -75,7 +75,7 @@ ace.define(
|
||||
{
|
||||
token: "keyword.other",
|
||||
regex:
|
||||
"\\b(scope|depends\\s+on|declaration|includes|collection|content|optional|structure|enumeration|context|rule|under\\s+condition|condition|data|consequence|fulfilled|equals|assertion|definition|label|exception|anything)\\b",
|
||||
"\\b(scope|depends\\s+on|declaration|includes|collection|content|optional|structure|enumeration|context|input|output|internal|rule|under\\s+condition|condition|data|consequence|fulfilled|equals|assertion|definition|label|exception|anything)\\b",
|
||||
},
|
||||
{
|
||||
token: "constant.numeric",
|
||||
@ -179,8 +179,8 @@ ace.define(
|
||||
|
||||
var oop = require("../lib/oop");
|
||||
var TextMode = require("./text").Mode;
|
||||
var CatalaEnHighlightRules = require("./catala_en_highlighting_rules")
|
||||
.CatalaEnHighlightRules;
|
||||
var CatalaEnHighlightRules =
|
||||
require("./catala_en_highlighting_rules").CatalaEnHighlightRules;
|
||||
|
||||
var Mode = function () {
|
||||
this.HighlightRules = CatalaEnHighlightRules;
|
||||
|
@ -101,7 +101,7 @@
|
||||
'name' : 'comment.line.catala_en'
|
||||
}
|
||||
{
|
||||
'match' : '(context)(\\s+)([a-z\\x{00e9}\\x{00e8}\\x{00e0}\\x{00e2}\\x{00f9}\\x{00ee}\\x{00ea}\\x{0153}\\x{00e7}][a-z\\x{00e9}\\x{00e8}\\x{00e0}\\x{00e2}\\x{00f9}\\x{00ee}\\x{00ea}\\x{0153}\\x{00e7}A-Z\\x{00c9}\\x{00c8}\\x{00c0}\\x{00c2}\\x{00d9}\\x{00ce}\\x{00ca}\\x{0152}\\x{00c7}0-9_\\\']*)'
|
||||
'match' : '(context|input|output|internal)(\\s*)(|output)(\\s+)([a-z\\x{00e9}\\x{00e8}\\x{00e0}\\x{00e2}\\x{00f9}\\x{00ee}\\x{00ea}\\x{0153}\\x{00e7}][a-z\\x{00e9}\\x{00e8}\\x{00e0}\\x{00e2}\\x{00f9}\\x{00ee}\\x{00ea}\\x{0153}\\x{00e7}A-Z\\x{00c9}\\x{00c8}\\x{00c0}\\x{00c2}\\x{00d9}\\x{00ce}\\x{00ca}\\x{0152}\\x{00c7}0-9_\\\']*)'
|
||||
'captures' : {
|
||||
'1' : {
|
||||
'name' : 'keyword.other.catala_en'
|
||||
@ -110,6 +110,12 @@
|
||||
'name' : 'text.catala_en'
|
||||
}
|
||||
'3' : {
|
||||
'name' : 'keyword.other.catala_en'
|
||||
}
|
||||
'4' : {
|
||||
'name' : 'text.catala_en'
|
||||
}
|
||||
'5' : {
|
||||
'name' : 'entity.name.function.catala_en'
|
||||
}
|
||||
}
|
||||
@ -119,7 +125,7 @@
|
||||
'name' : 'keyword.control.catala_en'
|
||||
}
|
||||
{
|
||||
'match' : '\\b(scope|depends\\s+on|declaration|includes|collection|content|optional|structure|enumeration|context|rule|under\\s+condition|condition|data|consequence|fulfilled|equals|assertion|definition|label|exception|anything)\\b'
|
||||
'match' : '\\b(scope|depends\\s+on|declaration|includes|collection|content|optional|structure|enumeration|context|input|output|internal|rule|under\\s+condition|condition|data|consequence|fulfilled|equals|assertion|definition|label|exception|anything)\\b'
|
||||
'name' : 'keyword.other.catala_en'
|
||||
}
|
||||
{
|
||||
|
@ -193,8 +193,8 @@ code : context {
|
||||
}
|
||||
|
||||
: pattern {
|
||||
regex \= (context)(\s+)($${__SC_ID})
|
||||
styles [] = .keyword_rule, .whitespace, .sc_id_def;
|
||||
regex \= (context|input|output|internal)(\s*)(|output)(\s+)($${__SC_ID})
|
||||
styles [] = .keyword_rule, .whitespace, .keyword_rule, .whitespace, .sc_id_def;
|
||||
}
|
||||
|
||||
: pattern {
|
||||
@ -203,7 +203,7 @@ code : context {
|
||||
}
|
||||
|
||||
: pattern {
|
||||
regex \= \b(scope|depends\s+on|declaration|includes|collection|content|optional|structure|enumeration|context|rule|under\s+condition|condition|data|consequence|fulfilled|equals|assertion|definition|label|exception)\b
|
||||
regex \= \b(scope|depends\s+on|declaration|includes|collection|content|optional|structure|enumeration|context|input|output|internal|rule|under\s+condition|condition|data|consequence|fulfilled|equals|assertion|definition|label|exception)\b
|
||||
styles [] = .keyword_rule ;
|
||||
}
|
||||
|
||||
|
@ -25,11 +25,11 @@ class CatalaEnLexer(RegexLexer):
|
||||
'code': [
|
||||
(u'(```)', bygroups(Text), 'root'),
|
||||
(u'(\\s*\\#.*$)', bygroups(Comment.Single)),
|
||||
(u'(context)(\\s+)([a-z\xe9\xe8\xe0\xe2\xf9\xee\xea\u0153\xe7][a-z\xe9\xe8\xe0\xe2\xf9\xee\xea\u0153\xe7A-Z\xc9\xc8\xc0\xc2\xd9\xce\xca\u0152\xc70-9_\\\']*)',
|
||||
bygroups(Keyword.Declaration, Text, Name.Variable)),
|
||||
(u'(context|input|output|internal)(\\s*)(|output)(\\s+)([a-z\xe9\xe8\xe0\xe2\xf9\xee\xea\u0153\xe7][a-z\xe9\xe8\xe0\xe2\xf9\xee\xea\u0153\xe7A-Z\xc9\xc8\xc0\xc2\xd9\xce\xca\u0152\xc70-9_\\\']*)',
|
||||
bygroups(Keyword.Declaration, Text, Keyword.Declaration, Text, Name.Variable)),
|
||||
(u'\\b(match|with\\s+pattern|fixed|by|decreasing|increasing|varies|with|we\\s+have|in|such\\s+that|exists|for|all|of|if|then|else|initial)\\b',
|
||||
bygroups(Keyword.Reserved)),
|
||||
(u'\\b(scope|depends\\s+on|declaration|includes|collection|content|optional|structure|enumeration|context|rule|under\\s+condition|condition|data|consequence|fulfilled|equals|assertion|definition|label|exception|anything)\\b',
|
||||
(u'\\b(scope|depends\\s+on|declaration|includes|collection|content|optional|structure|enumeration|context|input|output|internal|rule|under\\s+condition|condition|data|consequence|fulfilled|equals|assertion|definition|label|exception|anything)\\b',
|
||||
bygroups(Keyword.Declaration)),
|
||||
(u'(\\|[0-9]+\\-[0-9]+\\-[0-9]+\\|)', bygroups(Number.Integer)),
|
||||
(u'\\b(true|false)\\b', bygroups(Keyword.Constant)),
|
||||
|
@ -34,7 +34,7 @@ syn match punctuation contained "\(--\|\;\|\.\|,\|\:\|(\|)\|\[\|\]\|{\|}\)"
|
||||
syn keyword Type contained integer boolean date duration money text decimal number sum
|
||||
|
||||
syn region ctxt contained
|
||||
\ matchgroup=Keyword start="\<context"
|
||||
\ matchgroup=Keyword start="\<\(context\|input\|output\|internal\)\(\|\s\+output\)"
|
||||
\ matchgroup=sc_id_def end="\s\+\([a-zéèàâùîôêœç][a-zéèàâùîôêœçA-ZÉÈÀÂÙÎÔÊŒÇ0-9_\']*\)\>"
|
||||
|
||||
syn region cc_id_dot_sc_id contained contains=punctuation
|
||||
|
@ -162,7 +162,7 @@
|
||||
</dict>
|
||||
<dict>
|
||||
<key>match</key>
|
||||
<string>(context)(\s+)([a-z\x{00e9}\x{00e8}\x{00e0}\x{00e2}\x{00f9}\x{00ee}\x{00ea}\x{0153}\x{00e7}][a-z\x{00e9}\x{00e8}\x{00e0}\x{00e2}\x{00f9}\x{00ee}\x{00ea}\x{0153}\x{00e7}A-Z\x{00c9}\x{00c8}\x{00c0}\x{00c2}\x{00d9}\x{00ce}\x{00ca}\x{0152}\x{00c7}0-9_\']*)</string>
|
||||
<string>(context|input|output|internal)(\s*)(|output)(\s+)([a-z\x{00e9}\x{00e8}\x{00e0}\x{00e2}\x{00f9}\x{00ee}\x{00ea}\x{0153}\x{00e7}][a-z\x{00e9}\x{00e8}\x{00e0}\x{00e2}\x{00f9}\x{00ee}\x{00ea}\x{0153}\x{00e7}A-Z\x{00c9}\x{00c8}\x{00c0}\x{00c2}\x{00d9}\x{00ce}\x{00ca}\x{0152}\x{00c7}0-9_\']*)</string>
|
||||
<key>captures</key>
|
||||
<dict>
|
||||
<key>1</key>
|
||||
@ -176,6 +176,16 @@
|
||||
<string>text.catala_en</string>
|
||||
</dict>
|
||||
<key>3</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>keyword.other.catala_en</string>
|
||||
</dict>
|
||||
<key>4</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>text.catala_en</string>
|
||||
</dict>
|
||||
<key>5</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>entity.name.function.catala_en</string>
|
||||
@ -190,7 +200,7 @@
|
||||
</dict>
|
||||
<dict>
|
||||
<key>match</key>
|
||||
<string>\b(scope|depends\s+on|declaration|includes|collection|content|optional|structure|enumeration|context|rule|under\s+condition|condition|data|consequence|fulfilled|equals|assertion|definition|label|exception|anything)\b</string>
|
||||
<string>\b(scope|depends\s+on|declaration|includes|collection|content|optional|structure|enumeration|context|input|output|internal|rule|under\s+condition|condition|data|consequence|fulfilled|equals|assertion|definition|label|exception|anything)\b</string>
|
||||
<key>name</key>
|
||||
<string>keyword.other.catala_en</string>
|
||||
</dict>
|
||||
|
@ -63,9 +63,9 @@ ace.define(
|
||||
regex: "(\\s*\\#.*$)",
|
||||
},
|
||||
{
|
||||
token: ["keyword.other", "text", "entity.name.function"],
|
||||
token: ["keyword.other", "text", "keyword.other", "text", "entity.name.function"],
|
||||
regex:
|
||||
"(contexte)(\\s+)([a-z\u00e9\u00e8\u00e0\u00e2\u00f9\u00ee\u00f4\u00ea\u0153\u00e7][a-z\u00e9\u00e8\u00e0\u00e2\u00f9\u00ee\u00f4\u00ea\u0153\u00e7A-Z\u00c9\u00c8\u00c0\u00c2\u00d9\u00ce\u00d4\u00ca\u0152\u00c70-9_\\']*)",
|
||||
"(contexte|entr\u00e9e|sortie|interne)(\\s*)(|sortie)(\\s+)([a-z\u00e9\u00e8\u00e0\u00e2\u00f9\u00ee\u00f4\u00ea\u0153\u00e7][a-z\u00e9\u00e8\u00e0\u00e2\u00f9\u00ee\u00f4\u00ea\u0153\u00e7A-Z\u00c9\u00c8\u00c0\u00c2\u00d9\u00ce\u00d4\u00ca\u0152\u00c70-9_\\']*)",
|
||||
},
|
||||
{
|
||||
token: "keyword.control",
|
||||
@ -75,7 +75,7 @@ ace.define(
|
||||
{
|
||||
token: "keyword.other",
|
||||
regex:
|
||||
"\\b(champ\\s+d'application|si\\s+et\\s+seulement\\s+si|d\u00e9pend\\s+de|d\u00e9claration|inclus|collection|contenu|optionnel|structure|\u00e9num\u00e9ration|contexte|r\u00e8gle|sous\\s+condition|condition|donn\u00e9e|cons\u00e9quence|rempli|\u00e9gal\\s+\u00e0|assertion|d\u00e9finition|\u00e9tiquette|exception|n'importe\\s+quel)\\b",
|
||||
"\\b(champ\\s+d'application|si\\s+et\\s+seulement\\s+si|d\u00e9pend\\s+de|d\u00e9claration|inclus|collection|contenu|optionnel|structure|\u00e9num\u00e9ration|contexte|entr\u00e9e|sortie|interne|r\u00e8gle|sous\\s+condition|condition|donn\u00e9e|cons\u00e9quence|rempli|\u00e9gal\\s+\u00e0|assertion|d\u00e9finition|\u00e9tiquette|exception|n'importe\\s+quel)\\b",
|
||||
},
|
||||
{
|
||||
token: "constant.numeric",
|
||||
|
@ -101,7 +101,7 @@
|
||||
'name' : 'comment.line.catala_fr'
|
||||
}
|
||||
{
|
||||
'match' : '(contexte)(\\s+)([a-z\\x{00e9}\\x{00e8}\\x{00e0}\\x{00e2}\\x{00f9}\\x{00ee}\\x{00f4}\\x{00ea}\\x{0153}\\x{00e7}][a-z\\x{00e9}\\x{00e8}\\x{00e0}\\x{00e2}\\x{00f9}\\x{00ee}\\x{00f4}\\x{00ea}\\x{0153}\\x{00e7}A-Z\\x{00c9}\\x{00c8}\\x{00c0}\\x{00c2}\\x{00d9}\\x{00ce}\\x{00d4}\\x{00ca}\\x{0152}\\x{00c7}0-9_\\\']*)'
|
||||
'match' : '(contexte|entr\\x{00e9}e|sortie|interne)(\\s*)(|sortie)(\\s+)([a-z\\x{00e9}\\x{00e8}\\x{00e0}\\x{00e2}\\x{00f9}\\x{00ee}\\x{00f4}\\x{00ea}\\x{0153}\\x{00e7}][a-z\\x{00e9}\\x{00e8}\\x{00e0}\\x{00e2}\\x{00f9}\\x{00ee}\\x{00f4}\\x{00ea}\\x{0153}\\x{00e7}A-Z\\x{00c9}\\x{00c8}\\x{00c0}\\x{00c2}\\x{00d9}\\x{00ce}\\x{00d4}\\x{00ca}\\x{0152}\\x{00c7}0-9_\\\']*)'
|
||||
'captures' : {
|
||||
'1' : {
|
||||
'name' : 'keyword.other.catala_fr'
|
||||
@ -110,6 +110,12 @@
|
||||
'name' : 'text.catala_fr'
|
||||
}
|
||||
'3' : {
|
||||
'name' : 'keyword.other.catala_fr'
|
||||
}
|
||||
'4' : {
|
||||
'name' : 'text.catala_fr'
|
||||
}
|
||||
'5' : {
|
||||
'name' : 'entity.name.function.catala_fr'
|
||||
}
|
||||
}
|
||||
@ -119,7 +125,7 @@
|
||||
'name' : 'keyword.control.catala_fr'
|
||||
}
|
||||
{
|
||||
'match' : '\\b(champ\\s+d\'application|si\\s+et\\s+seulement\\s+si|dépend\\s+de|déclaration|inclus|collection|contenu|optionnel|structure|énumération|contexte|règle|sous\\s+condition|condition|donnée|conséquence|rempli|égal\\s+à|assertion|définition|étiquette|exception|n\'importe\\s+quel)\\b'
|
||||
'match' : '\\b(champ\\s+d\'application|si\\s+et\\s+seulement\\s+si|dépend\\s+de|déclaration|inclus|collection|contenu|optionnel|structure|énumération|contexte|entrée|sortie|interne|règle|sous\\s+condition|condition|donnée|conséquence|rempli|égal\\s+à|assertion|définition|étiquette|exception|n\'importe\\s+quel)\\b'
|
||||
'name' : 'keyword.other.catala_fr'
|
||||
}
|
||||
{
|
||||
|
@ -193,8 +193,8 @@ code : context {
|
||||
}
|
||||
|
||||
: pattern {
|
||||
regex \= (contexte)(\s+)($${__SC_ID})
|
||||
styles [] = .keyword_rule, .whitespace, .sc_id_def;
|
||||
regex \= (contexte|entrée|sortie|interne)(\s*)(|sortie)(\s+)($${__SC_ID})
|
||||
styles [] = .keyword_rule, .whitespace, .keyword_rule, .whitespace, .sc_id_def;
|
||||
}
|
||||
|
||||
: pattern {
|
||||
@ -203,7 +203,7 @@ code : context {
|
||||
}
|
||||
|
||||
: pattern {
|
||||
regex \= \b(champ\s+d'application|si\s+et\s+seulement\s+si|dépend\s+de|déclaration|inclus|collection|contenu|optionnel|structure|énumération|contexte|règle|sous\s+condition|condition|donnée|conséquence|rempli|égal\s+à|assertion|définition|étiquette|exception)\b
|
||||
regex \= \b(champ\s+d'application|si\s+et\s+seulement\s+si|dépend\s+de|déclaration|inclus|collection|contenu|optionnel|structure|énumération|contexte|entrée|sortie|interne|règle|sous\s+condition|condition|donnée|conséquence|rempli|égal\s+à|assertion|définition|étiquette|exception)\b
|
||||
styles [] = .keyword_rule ;
|
||||
}
|
||||
|
||||
|
@ -26,11 +26,11 @@ class CatalaFrLexer(RegexLexer):
|
||||
'code': [
|
||||
(u'(```)', bygroups(Text), 'root'),
|
||||
(u'(\\s*\\#.*$)', bygroups(Comment.Single)),
|
||||
(u'(contexte)(\\s+)([a-z\xe9\xe8\xe0\xe2\xf9\xee\xf4\xea\u0153\xe7][a-z\xe9\xe8\xe0\xe2\xf9\xee\xf4\xea\u0153\xe7A-Z\xc9\xc8\xc0\xc2\xd9\xce\xd4\xca\u0152\xc70-9_\\\']*)',
|
||||
bygroups(Keyword.Declaration, Text, Name.Variable)),
|
||||
(u'(contexte|entr\xe9e|sortie|interne)(\\s*)(|sortie)(\\s+)([a-z\xe9\xe8\xe0\xe2\xf9\xee\xf4\xea\u0153\xe7][a-z\xe9\xe8\xe0\xe2\xf9\xee\xf4\xea\u0153\xe7A-Z\xc9\xc8\xc0\xc2\xd9\xce\xd4\xca\u0152\xc70-9_\\\']*)',
|
||||
bygroups(Keyword.Declaration, Text, Keyword.Declaration, Text, Name.Variable)),
|
||||
(u'\\b(selon|sous\\s+forme|fix\xe9|par|d\xe9croissante|croissante|varie|avec|on\\s+a|dans|tel\\s+que|existe|pour|tout|de|si|alors|sinon|initial)\\b',
|
||||
bygroups(Keyword.Reserved)),
|
||||
(u'\\b(champ\\s+d\'application|si\\s+et\\s+seulement\\s+si|d\xe9pend\\s+de|d\xe9claration|inclus|collection|contenu|optionnel|structure|\xe9num\xe9ration|contexte|r\xe8gle|sous\\s+condition|condition|donn\xe9e|cons\xe9quence|rempli|\xe9gal\\s+\xe0|assertion|d\xe9finition|\xe9tiquette|exception|n\'importe\\s+quel)\\b',
|
||||
(u'\\b(champ\\s+d\'application|si\\s+et\\s+seulement\\s+si|d\xe9pend\\s+de|d\xe9claration|inclus|collection|contenu|optionnel|structure|\xe9num\xe9ration|contexte|entr\xe9e|sortie|interne|r\xe8gle|sous\\s+condition|condition|donn\xe9e|cons\xe9quence|rempli|\xe9gal\\s+\xe0|assertion|d\xe9finition|\xe9tiquette|exception|n\'importe\\s+quel)\\b',
|
||||
bygroups(Keyword.Declaration)),
|
||||
(u'(\\|[0-9]+\\-[0-9]+\\-[0-9]+\\|)', bygroups(Number.Integer)),
|
||||
(u'\\b(vrai|faux)\\b', bygroups(Keyword.Constant)),
|
||||
|
@ -23,7 +23,7 @@ syn match Include "^\s*>\s*Inclusion:.*$"
|
||||
syn match sc_id_def contained "\<\([a-zéèàâùîôêœç][a-zéèàâùîôêœçA-ZÉÈÀÂÙÎÔÊŒÇ0-9_\']*\)\>"
|
||||
syn match cc_id contained "\<\([A-ZÉÈÀÂÙÎÔÊŒÇ][a-zéèàâùîôêœçA-ZÉÈÀÂÙÎÔÊŒÇ0-9_\']*\)\>"
|
||||
|
||||
syn match Keyword contained "\<\(contexte\|champ\s\+d'application\|collection\|structure\|donnée\|énumération\|définition\|déclaration\|si\s\+et\s\+seulement\s\+si\|dépend\s\+de\|inclus\|contenu\|optionnel\|règle\|sous\s\+condition\|condition\|conséquence\|rempli\|égal\s\+à\|assertion\|étiquette\|exception\|n'importe\s\+quel\)\>"
|
||||
syn match Keyword contained "\<\(contexte\|entrée\|sortie\|interne\|champ\s\+d'application\|collection\|structure\|donnée\|énumération\|définition\|déclaration\|si\s\+et\s\+seulement\s\+si\|dépend\s\+de\|inclus\|contenu\|optionnel\|règle\|sous\s\+condition\|condition\|conséquence\|rempli\|égal\s\+à\|assertion\|étiquette\|exception\|n'importe\s\+quel\)\>"
|
||||
syn match Statement contained "\<\(selon\|sous\s\+forme\|fixé\|par\|décroissante\|croissante\|varie\|avec\|on\s\+a\|dans\|tel\s\+que\|existe\|pour\|tout\|de\|initial\)\>"
|
||||
syn keyword Conditional contained si alors sinon
|
||||
syn match Comment contained "#.*$"
|
||||
@ -36,7 +36,7 @@ syn match punctuation contained "\(--\|\;\|\.\|,\|\:\|(\|)\|\[\|\]\|{\|}\)"
|
||||
syn keyword Type contained entier booléen date durée argent texte décimal décret loi nombre somme
|
||||
|
||||
syn region ctxt contained
|
||||
\ matchgroup=Keyword start="\<contexte"
|
||||
\ matchgroup=Keyword start="\<\(contexte\|entrée\|sortie\|interne\)\(|\s\+sortie\)"
|
||||
\ matchgroup=sc_id_def end="\s\+\([a-zéèàâùîôêœç][a-zéèàâùîôêœçA-ZÉÈÀÂÙÎÔÊŒÇ0-9_\']*\)\>"
|
||||
|
||||
syn region cc_id_dot_sc_id contained contains=punctuation
|
||||
|
@ -162,7 +162,7 @@
|
||||
</dict>
|
||||
<dict>
|
||||
<key>match</key>
|
||||
<string>(contexte)(\s+)([a-z\x{00e9}\x{00e8}\x{00e0}\x{00e2}\x{00f9}\x{00ee}\x{00f4}\x{00ea}\x{0153}\x{00e7}][a-z\x{00e9}\x{00e8}\x{00e0}\x{00e2}\x{00f9}\x{00ee}\x{00f4}\x{00ea}\x{0153}\x{00e7}A-Z\x{00c9}\x{00c8}\x{00c0}\x{00c2}\x{00d9}\x{00ce}\x{00d4}\x{00ca}\x{0152}\x{00c7}0-9_\']*)</string>
|
||||
<string>(contexte|entrée|sortie|interne)(\s*)(|sortie)(\s+)([a-z\x{00e9}\x{00e8}\x{00e0}\x{00e2}\x{00f9}\x{00ee}\x{00f4}\x{00ea}\x{0153}\x{00e7}][a-z\x{00e9}\x{00e8}\x{00e0}\x{00e2}\x{00f9}\x{00ee}\x{00f4}\x{00ea}\x{0153}\x{00e7}A-Z\x{00c9}\x{00c8}\x{00c0}\x{00c2}\x{00d9}\x{00ce}\x{00d4}\x{00ca}\x{0152}\x{00c7}0-9_\']*)</string>
|
||||
<key>captures</key>
|
||||
<dict>
|
||||
<key>1</key>
|
||||
@ -176,6 +176,16 @@
|
||||
<string>text.catala_fr</string>
|
||||
</dict>
|
||||
<key>3</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>keyword.other.catala_fr</string>
|
||||
</dict>
|
||||
<key>4</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>text.catala_fr</string>
|
||||
</dict>
|
||||
<key>5</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>entity.name.function.catala_fr</string>
|
||||
@ -190,7 +200,7 @@
|
||||
</dict>
|
||||
<dict>
|
||||
<key>match</key>
|
||||
<string>\b(champ\s+d'application|si\s+et\s+seulement\s+si|dépend\s+de|déclaration|inclus|collection|contenu|optionnel|structure|énumération|contexte|règle|sous\s+condition|condition|donnée|conséquence|rempli|égal\s+à|assertion|définition|étiquette|exception|n'importe\s+quel)\b</string>
|
||||
<string>\b(champ\s+d'application|si\s+et\s+seulement\s+si|dépend\s+de|déclaration|inclus|collection|contenu|optionnel|structure|énumération|contexte|entrée|sortie|interne|règle|sous\s+condition|condition|donnée|conséquence|rempli|égal\s+à|assertion|définition|étiquette|exception|n'importe\s+quel)\b</string>
|
||||
<key>name</key>
|
||||
<string>keyword.other.catala_fr</string>
|
||||
</dict>
|
||||
|
@ -71,7 +71,7 @@
|
||||
'name' : 'comment.line.catala_pl'
|
||||
}
|
||||
{
|
||||
'match' : '(kontekst)(\\s+)([a-z\\x{0105}\\x{0107}\\x{0119}\\x{0142}\\x{0144}\\x{00f3}\\x{015b}\\x{017c}\\x{017a}][a-z\\x{0105}\\x{0107}\\x{0119}\\x{0142}\\x{0144}\\x{00f3}\\x{015b}\\x{017c}\\x{017a}A-Z\\x{0104}\\x{0106}\\x{0118}\\x{0141}\\x{0143}\\x{00d3}\\x{015a}\\x{017b}\\x{0179}0-9_\\\']*)'
|
||||
'match' : '(kontekst|wejście|wyjście|wewnętrzny)(\\s*)(|wyjście)(\\s+)([a-z\\x{0105}\\x{0107}\\x{0119}\\x{0142}\\x{0144}\\x{00f3}\\x{015b}\\x{017c}\\x{017a}][a-z\\x{0105}\\x{0107}\\x{0119}\\x{0142}\\x{0144}\\x{00f3}\\x{015b}\\x{017c}\\x{017a}A-Z\\x{0104}\\x{0106}\\x{0118}\\x{0141}\\x{0143}\\x{00d3}\\x{015a}\\x{017b}\\x{0179}0-9_\\\']*)'
|
||||
'captures' : {
|
||||
'1' : {
|
||||
'name' : 'keyword.other.catala_pl'
|
||||
@ -80,6 +80,12 @@
|
||||
'name' : 'text.catala_pl'
|
||||
}
|
||||
'3' : {
|
||||
'name' : 'keyword.other.catala_pl'
|
||||
}
|
||||
'4' : {
|
||||
'name' : 'text.catala_pl'
|
||||
}
|
||||
'5' : {
|
||||
'name' : 'entity.name.function.catala_pl'
|
||||
}
|
||||
}
|
||||
@ -89,7 +95,7 @@
|
||||
'name' : 'keyword.control.catala_pl'
|
||||
}
|
||||
{
|
||||
'match' : '\\b(zakres|zalezy\\s+od|deklaracja|kolekcja|typu|opcjonalny|struktura|enumeracja|kontekst|zasada|pod\\s+warunkuem|czas|konsekwencja|spelnione|wynosi|asercja|definicja|etykieta|wyjątek|cokolwiek)\\b'
|
||||
'match' : '\\b(zakres|zalezy\\s+od|deklaracja|kolekcja|typu|opcjonalny|struktura|enumeracja|kontekst|wejście|wyjście|wewnętrzny|zasada|pod\\s+warunkuem|czas|konsekwencja|spelnione|wynosi|asercja|definicja|etykieta|wyjątek|cokolwiek)\\b'
|
||||
'name' : 'keyword.other.catala_pl'
|
||||
}
|
||||
{
|
||||
|
@ -193,8 +193,8 @@ code : context {
|
||||
}
|
||||
|
||||
: pattern {
|
||||
regex \= (kontekst)(\s+)($${__SC_ID})
|
||||
styles [] = .keyword_rule, .whitespace, .sc_id_def;
|
||||
regex \= (kontekst|wejście|wyjście|wewnętrzny)(\s*)(|wyjście)(\s+)($${__SC_ID})
|
||||
styles [] = .keyword_rule, .whitespace, .keyword_rule, .whitespace, .sc_id_def;
|
||||
}
|
||||
|
||||
: pattern {
|
||||
|
@ -24,9 +24,9 @@ class CatalaPlLexer(RegexLexer):
|
||||
'code' : [
|
||||
(u'(```)', bygroups(Text), 'root'),
|
||||
(u'(\\s*\\#.*$)', bygroups(Comment.Single)),
|
||||
(u'(kontekst)(\\s+)([a-z\u0105\u0107\u0119\u0142\u0144\xf3\u015b\u017c\u017a][a-z\u0105\u0107\u0119\u0142\u0144\xf3\u015b\u017c\u017aA-Z\u0104\u0106\u0118\u0141\u0143\xd3\u015a\u017b\u01790-9_\\\']*)', bygroups(Keyword.Declaration, Text, Name.Variable)),
|
||||
(u'(kontekst|wej\u015bcie|wyj\u015bcie|wewn\u0119trzny)(\\s*)(|wyj\u015bcie)(\\s+)([a-z\u0105\u0107\u0119\u0142\u0144\xf3\u015b\u017c\u017a][a-z\u0105\u0107\u0119\u0142\u0144\xf3\u015b\u017c\u017aA-Z\u0104\u0106\u0118\u0141\u0143\xd3\u015a\u017b\u01790-9_\\\']*)', bygroups(Keyword.Declaration, Text, Keyword.Declaration, Text, Name.Variable)),
|
||||
(u'\\b(pasuje|ze\\s+wzorem|staloprzecinkowa|przez|malejacy|rosnacy|rozna|wraz z|mamy|w|takich ze|istnieje|dla|wszystkie|z|jezeli|wtedy|inaczej|poczatkowy)\\b', bygroups(Keyword.Reserved)),
|
||||
(u'\\b(zakres|zalezy\\s+od|deklaracja|kolekcja|typu|opcjonalny|struktura|enumeracja|kontekst|zasada|pod\\s+warunkuem|czas|konsekwencja|spelnione|wynosi|asercja|definicja|etykieta|wyj\u0105tek|cokolwiek)\\b', bygroups(Keyword.Declaration)),
|
||||
(u'\\b(zakres|zalezy\\s+od|deklaracja|kolekcja|typu|opcjonalny|struktura|enumeracja|kontekst|wej\u015bcie|wyj\u015bcie|wewn\u0119trzny|zasada|pod\\s+warunkuem|czas|konsekwencja|spelnione|wynosi|asercja|definicja|etykieta|wyj\u0105tek|cokolwiek)\\b', bygroups(Keyword.Declaration)),
|
||||
(u'(\\|[0-9]+\\-[0-9]+\\-[0-9]+\\|)', bygroups(Number.Integer)),
|
||||
(u'\\b(prawda|falsz)\\b', bygroups(Keyword.Constant)),
|
||||
(u'\\b([0-9]+(,[0.9]*|))\\b', bygroups(Number.Integer)),
|
||||
|
@ -23,7 +23,7 @@ syn match Include "^\s*>\s*Include:.*$"
|
||||
|
||||
syn match sc_id_def contained "\<\([a-zéèàâùîôêœç][a-zéèàâùîôêœçA-ZÉÈÀÂÙÎÔÊŒÇ0-9_\']*\)\>"
|
||||
syn match cc_id contained "\<\([A-ZÉÈÀÂÙÎÔÊŒÇ][a-zéèàâùîôêœçA-ZÉÈÀÂÙÎÔÊŒÇ0-9_\']*\)\>"
|
||||
syn match Keyword contained "\<\(zakres\|zalezy\s\+od\|deklaracja\|kolekcja\|typu\|opcjonalny\|struktura\|enumeracja\|kontekst\|zasada\|pod\s\+warunkuem\|czas\|konsekwencja\|spelnione\|wynosi\|asercja\|definicja\|etykieta\|wyjątek\|cokolwiek\)\>"
|
||||
syn match Keyword contained "\<\(zakres\|zalezy\s\+od\|deklaracja\|kolekcja\|typu\|opcjonalny\|struktura\|enumeracja\|kontekst\|wejście\|wyjście\|wewnętrzny\|zasada\|pod\s\+warunkuem\|czas\|konsekwencja\|spelnione\|wynosi\|asercja\|definicja\|etykieta\|wyjątek\|cokolwiek\)\>"
|
||||
syn match Statement contained "\<\(pasuje\|ze\s\+wzorem\|staloprzecinkowa\|przez\|malejacy\|rosnacy\|rozna\|wraz z\|mamy\|w\|takich ze\|istnieje\|dla\|wszystkie\|z\|jezeli\|wtedy\|inaczej\|poczatkowy\)\>"
|
||||
syn keyword Conditional contained if then else
|
||||
syn match Comment contained "#.*$"
|
||||
@ -35,7 +35,7 @@ syn match punctuation contained "\(--\|\;\|\.\|,\|\:\|(\|)\|\[\|\]\|{\|}\)"
|
||||
syn keyword Type contained calkowita zerojedynkowy czas trwania pieniądze warunek tekst dziesiętny suma
|
||||
|
||||
syn region ctxt contained
|
||||
\ matchgroup=Keyword start="\<kontekst"
|
||||
\ matchgroup=Keyword start="\<\(kontekst\|wejście\|wyjście\|wewnętrzny\)\(\|\s\+wyjście\)"
|
||||
\ matchgroup=sc_id_def end="\s\+\([a-zéèàâùîôêœç][a-zéèàâùîôêœçA-ZÉÈÀÂÙÎÔÊŒÇ0-9_\']*\)\>"
|
||||
|
||||
syn region cc_id_dot_sc_id contained contains=punctuation
|
||||
|
@ -2,17 +2,17 @@
|
||||
|
||||
```catala
|
||||
declaration scope A:
|
||||
context x content collection money
|
||||
output x content collection money
|
||||
|
||||
scope A:
|
||||
definition x equals [$0; $4 +$ $5; $8 *$ 0.65]
|
||||
|
||||
declaration scope B:
|
||||
context a scope A
|
||||
context max content money
|
||||
context min content money
|
||||
context y content money
|
||||
context z content integer
|
||||
a scope A
|
||||
output max content money
|
||||
output min content money
|
||||
output y content money
|
||||
output z content integer
|
||||
|
||||
scope B:
|
||||
definition max equals maximum money initial $0 for m in a.x of m *$ 2.0
|
||||
|
@ -6,7 +6,7 @@ declaration structure S:
|
||||
data income content money
|
||||
|
||||
declaration scope A:
|
||||
context x content collection S
|
||||
context output x content collection S
|
||||
|
||||
scope A:
|
||||
definition x equals [
|
||||
@ -16,9 +16,9 @@ scope A:
|
||||
]
|
||||
|
||||
declaration scope B:
|
||||
context a scope A
|
||||
context argmax content S
|
||||
context argmin content S
|
||||
a scope A
|
||||
output argmax content S
|
||||
output argmin content S
|
||||
|
||||
scope B:
|
||||
definition argmax equals content maximum money initial S { -- id: -1 --income: $0 } for m in a.x of (m.income *$ 2.0)
|
||||
|
@ -2,8 +2,8 @@
|
||||
|
||||
```catala
|
||||
declaration scope A:
|
||||
context x content collection integer
|
||||
context y content collection integer
|
||||
output x content collection integer
|
||||
output y content collection integer
|
||||
|
||||
scope A:
|
||||
definition x equals [0; 1; 2] ++ [3; 4; 5; 6]
|
||||
|
@ -2,15 +2,15 @@
|
||||
|
||||
```catala
|
||||
declaration scope A:
|
||||
context x content collection money
|
||||
output x content collection money
|
||||
|
||||
scope A:
|
||||
definition x equals [$0; $4 +$ $5; $8 *$ 0.65]
|
||||
|
||||
declaration scope B:
|
||||
context a scope A
|
||||
context y content collection money
|
||||
context z content collection boolean
|
||||
a scope A
|
||||
output y content collection money
|
||||
output z content collection boolean
|
||||
|
||||
scope B:
|
||||
definition y equals filter for m in a.x of (m >=$ $4.95)
|
||||
|
@ -1,4 +1,4 @@
|
||||
[RESULT] Computation successful! Results:
|
||||
[RESULT] x =
|
||||
[S {"id": 0, "income": $0.00}; S {"id": 1, "income": $9.00};
|
||||
S {"id": 2, "income": $5.20}]
|
||||
[S {"id"= 0; "income"= $0.00}; S {"id"= 1; "income"= $9.00};
|
||||
S {"id"= 2; "income"= $5.20}]
|
||||
|
@ -1,3 +1,3 @@
|
||||
[RESULT] Computation successful! Results:
|
||||
[RESULT] argmax = S {"id": 1, "income": $9.00}
|
||||
[RESULT] argmin = S {"id": 0, "income": $0.00}
|
||||
[RESULT] argmax = S {"id"= 1; "income"= $9.00}
|
||||
[RESULT] argmin = S {"id"= 0; "income"= $0.00}
|
||||
|
@ -2,17 +2,17 @@
|
||||
|
||||
```catala
|
||||
declaration scope A:
|
||||
context x content collection integer
|
||||
output x content collection integer
|
||||
|
||||
scope A:
|
||||
definition x equals [0; 4+5; 8*8]
|
||||
|
||||
declaration scope B:
|
||||
context a scope A
|
||||
context v content integer
|
||||
context w content boolean
|
||||
context y content boolean
|
||||
context z content boolean
|
||||
a scope A
|
||||
output v content integer
|
||||
output w content boolean
|
||||
output y content boolean
|
||||
output z content boolean
|
||||
|
||||
scope B:
|
||||
definition v equals number of a.x
|
||||
|
@ -1,21 +1,18 @@
|
||||
let
|
||||
TestBool_6 :
|
||||
TestBool_in {unit → bool ; unit → integer} → TestBool_out {bool ;
|
||||
integer} =
|
||||
λ (TestBool_in_7: TestBool_in {unit → bool ; unit → integer}) →
|
||||
let foo_8 : unit → bool = TestBool_in_7."foo_in"
|
||||
in
|
||||
let bar_9 : unit → integer = TestBool_in_7."bar_in"
|
||||
in
|
||||
let TestBool_6 :
|
||||
TestBool_in{"foo_in": unit → bool; "bar_in": unit → integer} →
|
||||
TestBool_out{"foo_out": bool; "bar_out": integer} =
|
||||
λ (TestBool_in_7: TestBool_in{"foo_in": unit → bool; "bar_in":
|
||||
unit → integer}) →
|
||||
let foo_8 : unit → bool = TestBool_in_7."foo_in" in
|
||||
let bar_9 : unit → integer = TestBool_in_7."bar_in" in
|
||||
let bar_10 : integer = error_empty
|
||||
⟨bar_9 () | true ⊢
|
||||
⟨⟨true ⊢ ⟨⟨true ⊢ 1⟩ | false ⊢ ∅ ⟩⟩ | true ⊢
|
||||
⟨⟨false ⊢ ∅ ⟩ | false ⊢ ∅ ⟩⟩⟩
|
||||
in
|
||||
⟨⟨false ⊢ ∅ ⟩ | false ⊢ ∅ ⟩⟩⟩ in
|
||||
let foo_11 : bool = error_empty
|
||||
⟨foo_8 () | true ⊢
|
||||
⟨⟨true ⊢ ⟨⟨bar_10 < 0 ⊢ false⟩ | false ⊢ ∅ ⟩⟩,
|
||||
⟨true ⊢ ⟨⟨bar_10 >= 0 ⊢ true⟩ | false ⊢ ∅ ⟩⟩ |
|
||||
true ⊢ ⟨⟨false ⊢ ∅ ⟩ | false ⊢ ∅ ⟩⟩⟩
|
||||
in
|
||||
TestBool_out {"foo_out": foo_11, "bar_out": bar_10}
|
||||
true ⊢ ⟨⟨false ⊢ ∅ ⟩ | false ⊢ ∅ ⟩⟩⟩ in
|
||||
TestBool_out {"foo_out"= foo_11; "bar_out"= bar_10} in
|
||||
TestBool_6
|
||||
|
@ -1,11 +1,8 @@
|
||||
let scope TestBool (foo: bool) (bar: integer) =
|
||||
let bar : integer =
|
||||
reentrant or by default
|
||||
⟨⟨true ⊢ ⟨⟨true ⊢ 1⟩ | false ⊢ ∅ ⟩⟩ |
|
||||
true ⊢ ⟨⟨false ⊢ ∅ ⟩ | false ⊢ ∅ ⟩⟩ in;
|
||||
let foo : bool =
|
||||
reentrant or by default
|
||||
⟨⟨true ⊢ ⟨⟨bar < 0 ⊢ false⟩ | false ⊢ ∅ ⟩⟩,
|
||||
⟨true ⊢ ⟨⟨bar >= 0 ⊢ true⟩ | false ⊢ ∅ ⟩⟩ |
|
||||
true ⊢ ⟨⟨false ⊢ ∅ ⟩ | false ⊢ ∅ ⟩⟩ in
|
||||
end scope
|
||||
let scope TestBool (foo: bool|context|output) (bar: integer|context|output) =
|
||||
let bar : integer = reentrant or by default
|
||||
⟨⟨true ⊢ ⟨⟨true ⊢ 1⟩ | false ⊢ ∅ ⟩⟩ | true ⊢
|
||||
⟨⟨false ⊢ ∅ ⟩ | false ⊢ ∅ ⟩⟩;
|
||||
let foo : bool = reentrant or by default
|
||||
⟨⟨true ⊢ ⟨⟨bar < 0 ⊢ false⟩ | false ⊢ ∅ ⟩⟩,
|
||||
⟨true ⊢ ⟨⟨bar >= 0 ⊢ true⟩ | false ⊢ ∅ ⟩⟩ |
|
||||
true ⊢ ⟨⟨false ⊢ ∅ ⟩ | false ⊢ ∅ ⟩⟩
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user