-
Notifications
You must be signed in to change notification settings - Fork 77
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Module support: handle structs, enums and scope calls across modules #497
Conversation
This works for the `--reset` option, but I have some doubts about it.
(and obviously, the git history needs a rebase ;) ) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @AltGr for another massive PR! It still needs some work though, but that'll be after your holidays :)
(* Find a witness of a mark in the definitions *) | ||
match sigma.scope_decl_rules with | ||
| [] -> | ||
(* Todo: are we sure this can't happen in normal code ? E.g. is calling a |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah ideally a scope with only input variables should compile, you can maybe return Pos.no_pos
at this point.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's a bit more involved because of the GADT for annotations, we would need to take a type witness as parameter of the function. I'll see what I can do ^^
examples/aides_logement/dune
Outdated
;; (rule | ||
;; (targets aides_logement.ml aides_logement_api_web.ml) | ||
;; (deps | ||
;; (source_tree ..) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
dead code?
examples/dune
Outdated
@@ -0,0 +1 @@ | |||
(dirs :standard \ aides_logement) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah this is temporary and will be removed from the finalised PR, see 0a98f63
french_law/dune
Outdated
@@ -0,0 +1,3 @@ | |||
(dirs catala_legifrance) | |||
|
|||
;; ocaml js python |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(same as above, this disables most of french_law
)
Should now be regression-free and ready for final review; |
cf. ocaml/opam-repository#24342 on CI failure |
... and add a custom printer Since this is a very common bug, this patch should gain us a lot of time when debugging uncaught Not_found errors, because the element not found can now be printed straight away without the need for further debugging. The small cost is that one should remember to catch the correct specialised `Foo.Map.Not_found _` exception rather than the standard `Not_found` (which would type-check but not catch the exception). Using `find_opt` should be preferred anyway. Note that the other functions from the module `Map` that raise `Not_found` are not affected ; these functions are `choose`, `min/max_binding`, `find_first/last` which either take a predicate or fail on the empty map, so it wouldn't make sense for them (and we probably don't use them much).
(they use UIDs so this doesn't jeopardize proper name resolution ; and it allows resolution of subscope calls without further code modifications)
This makes sure `catala module` finds the local runtime when run from the catala source tree; and fixes lookup of the catala exec on custom uses of `clerk runtest`.
28fb39c
to
20eea70
Compare
Done cleaning up the git history a bit |
Half-baked because clerk doesn't know to order the tests properly at the moment, and we spit compiled files into the source test directory.
rather than scattered in structures The context is still hierarchical for defs though, so one needs to retrieve the path to lookup in the correct context for info. Exceptions are enums and struct defs, which are re-exposed at toplevel.
20eea70
to
4e9f738
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK to merge! While I'm thinking about it : the invariants checking phase that @adelaett made is only triggered by the Invariants
CLI target, but shouldn't they be checked more often and at least in the CI ?
@@ -136,7 +136,8 @@ let detect_unused_struct_fields (p : program) : unit = | |||
in | |||
StructName.Map.iter | |||
(fun s_name fields -> | |||
if | |||
if StructName.path s_name <> [] then () |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah so you don't check structs from other modules during linting. I guess that makes sense but that would be better with a little comment no?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In time we may also want to fine-tune the warnings when compiling modules: in some cases it makes sense that stuff is unused here.
let prg, _ = surface options in | ||
let prg = load_module_interfaces prg options link_modules in | ||
let prg, _ = surface options ~link_modules in | ||
Message.emit_debug "- DESUGARED -"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This breaks style with the other debug messages right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes: I see them as section titles, it makes it easy to see what stage you were in when there is a crash.
Example:
[DEBUG] - INIT -
[DEBUG] Could not read plugin directory /home/lg/inria/catala/_build/default/compiler/../lib/catala/plugins
[DEBUG] Loading plugins from _build/default/compiler/plugins
[DEBUG] Plugin "_build/default/compiler/plugins/api_web.cmxs" loaded
[DEBUG] Plugin "_build/default/compiler/plugins/python.cmxs" loaded
[DEBUG] Plugin "_build/default/compiler/plugins/modules.cmxs" loaded
[DEBUG] Plugin "_build/default/compiler/plugins/explain.cmxs" loaded
[DEBUG] Plugin "_build/default/compiler/plugins/lazy_interpreter.cmxs" loaded
[DEBUG] Plugin "_build/default/compiler/plugins/json_schema.cmxs" loaded
[DEBUG] - SURFACE -
[DEBUG] Parsing sources/impot_revenu.catala_fr
[DEBUG] Parsing sources/prologue.catala_fr
[DEBUG] Parsing sources/vérifications.catala_fr
[DEBUG] Parsing sources/cgi_revenus.catala_fr
[DEBUG] Parsing sources/lfr_2022.catala_fr
[DEBUG] Parsing sources/loi_2022-1158.catala_fr
[DEBUG] - DESUGARED -
[DEBUG] Name resolution...
[DEBUG] Desugaring...
[DEBUG] Disambiguating...
[DEBUG] Linting...
[DEBUG] - SCOPELANG -
[DEBUG] - DCALC -
[DEBUG] Typechecking...
[DEBUG] Translating to default calculus...
[DEBUG] Typechecking again...
[DEBUG] - LCALC -
[DEBUG] Catala runtime libraries found at /home/lg/.opam/latest/lib/catala/runtime.
[DEBUG] Compiling OCaml shared object file sources/impot_revenu.cmxs...
May add in some color as well 🤔
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay, looks good to me. Yep color would be perfect :)
@@ -245,11 +223,15 @@ let format_var (fmt : Format.formatter) (v : 'm Var.t) : unit = | |||
let lowercase_name = String.to_ascii lowercase_name in | |||
if | |||
List.mem lowercase_name ["handle_default"; "handle_default_opt"] | |||
|| String.begins_with_uppercase (Bindlib.name_of v) | |||
(* O_O *) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hm I don't exactly remember the mood I was in when I wrote this 🤣
But certainly there should be a better way of special-casing without matching the final ident strings.
@@ -529,7 +530,7 @@ let format_ctx | |||
format_to_module_name (`Ename enum_name) | |||
(Format.pp_print_list | |||
~pp_sep:(fun fmt () -> Format.fprintf fmt "@\n") | |||
(fun _fmt (enum_cons, enum_cons_type) -> | |||
(fun fmt (enum_cons, enum_cons_type) -> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well caught!
let rec dump ppf env = | ||
let pp_sep = Format.pp_print_space in | ||
Format.pp_open_vbox ppf 0; | ||
(* Format.fprintf ppf "structs: @[<hov>%a@]@," |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Dead code?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well technically this function is dead code, it shouldn't be used outside of debugging sessions — but pretty convenient nevertheless and we shouldn't need to rewrite it every time. The same applies to the commented code: while you generally wouldn't want all the typedecls listed here, I thought that having this available to be uncommented here could be helpful in debugging sessions where you might actually have use for it.
But well, since it's normally unused we may indeed prefer to uncomment to make sure the extended function continues to typecheck...
It may even make sense to enable it in tests by default, when applicable 🤔 |
Current state:
Works: modules compiled with
catala module --build foo.catala_en
then usedthrough
catala interpret --use foo.catala_en bar.catala_en
(this is the use-case for running the interpreter on tests that will actually
do a native-code computation)
Usage from native code
doesn't work yet (but it's a matter of bugfixing)works as well (usecatala module --link
for now)Desambiguation doesn't yet work cross-modules yet (but no technical
difficulty, just needs handling ; can be left for a later PR)
Code needs cleanup (debugs remaining here and there...)
On second thought storing the paths as part of theprogram_ctx
isn't thebest approach: I'll revert that part and add the paths to an expanded version
of
Uid.t
. The information will be closer to where it's needed, it will avoidlimitation in printers, and this just needs the current path to be passed along
during name resolution, when initialising the
(Q)Uids
.Done now, code is much simpler but one needs to remember to lookup the correct module context when querying scope or def info.
Now fixed, at least all tests and benches pass nowweb_api
andfrench_law
friends are broken and temporarily disabledno support yet for other backends (but that will be left for later PRs)