it's now done explicitely from the driver, which allows to do it before typing
and is more consistent; the information was already forwarded to the later
compilation stages separately from the program AST anyway.
Note that this is incomplete in the case of desugared/scopelang because we only
have typing for expressions yet, and the scope/program structure is different.
The code allows passing an environment of types for scope/subscope variables in
order to resolve `ELocation` terms, but that's unused until we implement
scopelang typing at the scope level.
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.
This gives further uniformity in their interfaces and allows more common
handling.
The next step will be for all the `Expr.make_*` functions to work on expressions
annotated with the `'a mark` type, correctly propagating type information when
it is present. Then we could even imagine early propagation of type
information (without complete inference), which could for example be used for
overloaded operator disambiguation.
This will allow to unify with types used earlier in the
pipeline (`Scopelang.Ast.typ`).
It seems cleaner! But some areas may warrant a later clean-up, in particular
handling of options and their types in the backends, or possible name conflicts
of structs/enums with built-in types when printing.
Handling code should now be reasonably well sorted between `Shared_ast.{Var,Expr,Scope,Program}`
The function parameters (e.g. `make_let_in`) could be removed from the
scope handling functions since now the types are compatible, which
makes them much easier to read.
The AST structures track annotations (e.g., at the moment, source code
position information) in a lot of places. This patch tidies up a bit and
removes some duplication, ensuring a single level of annotation wrapping
at each AST recursion level.
This will be important when adding type information in these
annotations, because there will be consitency constraints to be ensured
and duplication is a likely source of mistakes.
this patch is just a bunch of `sed` commands
```shell
cd compiler
sed -i 's/Pos.marked/Marked.pos/g' *.ml* **/*.ml*
sed -i 's/Pos.unmark/Marked.unmark/g' *.ml* **/*.ml*
sed -i 's/Pos\.get_position/Marked.get_mark/g' *.ml* **/*.ml*
sed -i 's/Pos\.same_pos_as/Marked.same_mark_as/g' *.ml* **/*.ml*
sed -i 's/Pos\.map_under_mark/Marked.map_under_mark/g' *.ml* **/*.ml*
sed -i 's/Pos\.mark/Marked.mark/g' *.ml* **/*.ml*
sed -i 's/Pos\.compare_marked/Marked.compare/g' *.ml* **/*.ml*
```
Closes#208 (implementing Solution 1, without adding an explicit syntax)
Two exceptions or more, e.g. `(j1 |- c1)` and `(j2 |- c2)` such that `c1
= c2`, are collapsed by this transformation into `((j1 |- c1) | j2 |-
c2)`, introducing an arbitrary precedence that avoids the conflict.
The transormation is not applied if any exceptions apply to the subterms
themselves: while these exceptions could be merged, that would turn more
conflicts into arbitrary outcomes than wanted.
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.