The phantom polymorphic variant qualifying AST nodes is reversed:
- previously, we were explicitely restricting each AST node to the passes where it belonged using a closed type (e.g. `[< dcalc | lcalc]`)
- now, each node instead declares the "feature" it provides using an open type (e.g. `[> 'Exceptions ]`)
- then the AST for a specific pass limits the features it allows with a closed type
The result is that you can mix and match all features if you wish,
even if the result is not a valid AST for any given pass. More
interestingly, it's now easier to write a function that works on
different ASTs at once (it's the inferred default if you don't write a
type restriction).
The opportunity was also taken to simplify the encoding of the
operators, which don't need a second type parameter anymore.
Changelog:
---
A lot has been going on, with more than 530 patches and 70 PRs merged since
0.7.0 last summer. In summary:
- Quite a lot of syntax improvements and changes. Checkout the latest
[cheat-sheet](https://catalalang.github.io/catala/syntax.pdf) for an overview
- Allow local `let ... equals ... in ...` definitions
- Better error messages and positions throughout
- Added the ability to directly call a scope and retrieve its outputs, like a
function
- Added disambiguation, allowing to access structure fields without specifying
the structure type each time
- Added automated resolution of operators, allowing e.g. to write just `+` in
place of all the type-specific operators `+.`, `+$`, `+@`, `+^`, etc.
- More consistent priority for operators. It is no longer allowed to write `a
and b or c` without parenthesis.
- Added and changed some operators (`date + duration` now allowed either way,
`int / int` now returns a decimal, added `duration / duration`)
- Added the ability to have variables and functions defined at
top-level (outside of any scope). See annex A of the tutorial for details.
- Added support for functions with multiple arguments
- Some big refactors in the compiler, allowing much better code sharing between
the different passes, and making it much easier to extend. Also added the
possibility to run the type-checker earlier, etc.
- Countless bug-fixes
- Improvements to our proof backend with Z3
- A tool to automatically synchronise with the upstream French law from
Legifrance
Closes#373
This forbids expressions such as `a and b or c`, avoiding the need to set an
implicit priority between `and`, `or` and `xor`, which I find error-prone.
Instead, when that appears, a message asking for explicit parentheses will be
shown to the user.
Implementation note: since that would be extremely tedious to do in the parser
directly, the parser is set to allow right-associativity without discrimination
for the logical operators, and the check is done during desugaring. This
required to explicit parentheses in the surface AST to discriminate the case
where the priority was explicit.
Command used: `sed -i 's/\([-+*/><=]=\?\)[.$@^€$]/\1/g' **/*/*.catala_*`
The overload test, of course, is kept unchanged and ensures that explicit
operators still work.
This uses the same disambiguation mechanism put in place for
structures, calling the typer on individual rules on the desugared AST
to propagate types, in order to resolve ambiguous operators like `+`
to their strongly typed counterparts (`+!`, `+.`, `+$`, `+@`, `+$`) in
the translation to scopelang.
The patch includes some normalisation of the definition of all the
operators, and classifies them based on their typing policy instead of
their arity. It also adds a little more flexibility:
- a couple new operators, like `-` on date and duration
- optional type annotation on some aggregation constructions
The `Shared_ast` lib is also lightly restructured, with the `Expr`
module split into `Type`, `Operator` and `Expr`.
Also add some safeguards against bad propagation of types (e.g. checking the
arrow type of functions upon application); partly disabled at the moment since
they don't pass yet but that'll be further work.