As part of making tuples first-class citizens, expliciting the arity upon
function application was needed (so that a function of two args can
transparently -- in the surface language -- be applied to either two arguments
or a pair).
It was decided to actually explicit the whole type of arguments because the cost
is the same, and this is consistent with lambda definitions.
A related change done here is the replacement of the `EOp` node for operators by
an "operator application" `EAppOp` node, enforcing a pervasive invariant that
operators are always directly applied. This makes matches terser, and highlights
the fact that the treatment of operator application is almost always different
from function application in practice.
This changes the `decl_ctx` to be toplevel only, with flattened references to
uids for most elements. The module hierarchy, which is still useful in a few
places, is kept separately.
Module names are also changed to UIDs early on, and support for module aliases
has been added (needs testing).
This resolves some issues with lookup, and should be much more robust, as well
as more convenient for most lookups.
The `decl_ctx` was also extended for string ident lookups, which avoids having
to keep the desugared resolution structure available throughout the compilation
chain.
* Obsolete code for included tests has been removed
* The engine uses a proper lexer and is much simplified
* An inline test in the middle of the file now only "sees" the file up to that
point. This fixes an issue where we had spurious errors when a type error was
added at the end of a file, and it would pop up in tests before it. This makes
files including many tests much more practical.
* diffing and resetting the tests has been reintroduced (done at the moment in
Ninja, but for more control (count number of failed tests, etc.) we could put it
back into Clerk at some point
* The Catala CLI can now take an input from stdin (with the possibility to link
a (possibly fake) on-disk file for error reporting and file locations ; this
is useful for running tests)
We need a concrete intermediate target for e.g. transitive uses of `> Include`
for Ninja to correctly handle them.
Of course we could also unroll all transitive dependencies, but meh.
Note also that now tests now just generate the outputs but facilities for
diffing and resetting are temporarily absent.
Rather than require all files to be listed on the command-line (and having to
check consistency with `> Using` directives), the main catala CLI is now a bit
more clever.
⇒ There is a new assumption that a module name definition must match the file
name (up to case and extension) — with appropriate error handling to enforce it.
In exchange, `> Using` directives are now used to more transparently lookup the
appropriate `.catala_*` interfaces and the compiled artifacts for the used modules (handling transitive dependencies), with just standard `-I` flags for when they need to be looked up in different places.
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.
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`.
... 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).
This patch functorises the generic expression printer, in order to be able to
re-use it for end-user printing.
It makes it possible to have an end-user, localised printer that shares the code
for e.g. priority and automatic parens handling.
A generic AST rewriting that disambiguates variables (very simple to write with
bindlib) is also added and used in the OCaml backend for something safer than
just appending `_user` (-- this also handles clashing variables that could be
introduced during compilation which would have generated wrong code before this)
Finally, the `explain` plugin is adapted to use the new printer.
Ah, and `String.format_t` was tweaked to correctly print strings that might
contain unicode without breaking alignment, and should be used instead of
`format_string` or `%s` whenever unicode can be expected.
- Use separate functions for successive passes in module `Driver.Passes`
- Use other functions for end results printing in module `Driver.Commands`
As a consequence, it is much more flexible to use by plugins or libs and we no
longer need the complex polymorphic variant parameter.
This patch leverages previous changes to use Cmdliner subcommands and
effectively specialises the flags of each Catala subcommand.
Other changes include:
- an attempt to normalise the generic options and reduce the number of global
references. Some are ok, like `debug` ; some would better be further cleaned up,
e.g. the ones used by Proof backend were moved to a `Proof.globals` module and
need discussion. The printer no longer relies on the global languages and prints
money amounts in an agnostic way.
- the plugin directory is automatically guessed and loaded even in dev setups.
Plugins are shown by the main `catala` command and listed in `catala --help`
- exception catching at the toplevel has been refactored a bit as well; return
codes are normalised to follow the manpage and avoid codes >= 128 that are
generally reserved for shells.
Update tests
The upside of this is that each command can define specific flags ; there is a
small loss of backwards-compatibility in that the command needs to be the first
argument.
`catala --help` will now only show a summary of commands, with more specific
manpages shown on `catala CMD --help`.
Another point is that the plugin interface is extended to allow plugins to be
registered as subcommands and have their own flags (this will be very useful for
adding flags to the lazy/dot/explanation plugin that has many options).
Note that no efforts has yet been made to specialise the options, the previous
type was just made global for all subcommands.
(first working dynload test with compilation done by manual calls to ocaml)
A few pieces of the puzzle:
* Loading of interfaces only from Catala files
* Registration of toplevel values in modules compiled to OCaml, to allow access
using dynlink
* Shady conversion from OCaml runtime values to/from Catala expressions, to
allow interop (ffi) of compiled modules and the interpreter