Many changes got bundled in here and would be too tedious to separate.
Closes#330
See changes in `shared_ast/definitions.ml` to check the main point.
- the biggest change is a modification of the struct and enum types in
expressions: they are now stored as `Map`s throughout passes, and no longer
converted to indexed lists after scopelang. Their accessors are also changed,
and tuples only exist in Lcalc (they're used for closure conversion).
This implied adding some more information in the contexts, to keep the mapping
between struct fields and scope output variables. It should also be much more
robust (no longer relying on assumptions upon different orderings).
- another very pervasive change is more cosmetic: the rewrite of the main AST to
use inline records, labelling individual subfields.
- moved the checks for correct definitions and accesses of structures from
`Scope_to_dcalc` to `Typing`
- defining some new shallow iterators in module `Shared_ast.Expr`, and
factorising a few same-pass rewriting functions accordingly (closure
conversion, optimisations, etc.)
- some smaller style improvements (ensuring we use the proper compare/equal
functions instead of `=` in a few `when` closes, for example)
- pass Catala options correctly in "clerk run-test"
- filter "OCAMLRUNPARAM" out of the environment (avoids backtraces getting
included in test outputs)
I use the following function in Emacs to live-update a test output:
```elisp
(defun clerk-test-update ()
(interactive nil)
(let ((pos (point)))
(delete-region (point-min) (point-max))
(call-process
"dune" nil t t
"exec" "--display=quiet" "--no-print-directory" "--no-build" "clerk" "--"
"runtest" "-e" "dune" "-c" "exec catala --no-build --"
(buffer-file-name))
(goto-char pos)))
```
I removed the '.out' extension for now to preserve the test output file names and avoid a million file renames.
This makes the patch easier to read, and we can do the rename easily in another patch afterwards, without mixing with semantic changes.
(beautiful script àlarrache:
```bash
for f in */*/output/*; do
target_base=${f##*/}
target_base=${target_base%%.*}
echo $f | awk -F. '{
f=$1"."$2; if ($4 == "") { mode=$3; id=$3 } else { scope="-s "$3; mode=$4; id=$3"."$4}
printf "\n```catala-test {id=\"%s\"}\ncatala %s %s\n```\n",id,mode,scope;
}' >> $(dirname $f)/../${target_base}.*; done
```
This avoids many intermediate calls to e.g. `Format.asprintf`; should result in
some cases in "more correct" use of `Format`¹, avoid the computation of unused
debug strings, and make the code more readable.
¹ for `Format` to work as expected, all intermediate calls need to go through
it. Some cases of formatting to an intermediate string then printing through Format
again are still present, but this makes the situation better.