Or, more accurately, by not doing a thing that's a waste of time. After
evaluating a local, if the result isn't applied to a stack, there's no
more reduction to do, so stop there.
Still go to the explicit named representation afterwards, since that's
an easier API for a code generator, and by then the names are guaranteed
unique.
(without adding syntax for them)
Somewhat of a surgical change, changing the AST and elaboration to
support it
Seems to pass all tests (including Frex)
Changes in `Idris/Desugar.idr` seem to be a bit challenging for the
type-checker in do-blocks, so I added type annotations.
Hopefully we could remove them in `idris2sh`.
The `isLet` check is essentially the disjunction of the `Maybe Bool`
and the function looking up the value to check whether it is a `Let`.
But:
* `getBinder` does the same lookup & then dispatches on Let
* the non-let cases in both branches of the if-then-else are equal
So we can actually get rid of that `isLet` and it should compute the
same result. We still use the `Maybe Bool` to potentially avoid running
`getBinder` if we already know the local value is not a let.
Instead of essentially interleaving the proof that `reverseOnto`
and ̀`reverse _ ++ _` are equivalent, we embrace `reverseOnto` and
perform a single rewrite at the end.
Apologies to anyone who's working on a back end independently!
You can still use CExp for now, but I'm shortly going to try using
NamedCExp in inlining, to save the fairly large cost of maintaining the
de Bruijn indices when going under binders.
Names are kept unique in the translation, so you can assume you don't
need to worry about them.
Use a variant of MkVar which has the name in the type and therefore
means it can be erased to a newtype, so just an Integer. Then use
'insertNames' rather than repeatedly thinning.
A bit of reorganisation to ensure that the context membership proofs are
erased. It's only a small overhead in general to keep the proofs, but
there are places where it's really noticeable, particularly when
compiling large programs.
Source and build directory are seperate.
References and footnotes are named.
Other than that, tried to do no changes in the docs.
Fixed multi label in proofs-index.
Fixed most of the warnings in make html.
HTML and PDF are building.
It's still too slow, but better than it was. Instead of all the
weakening, invent a new name when evaluating under a lambda and
substitute later.
Possibly we can improve this later by substituting in batches, like the
main evaluator does.
e.g. in a C file. This means we don't accidentally treat things as
empty, since previously we just defined these as empty types, but that
broke coverage checking. Fixes#240
The names the locals were being applied to weren't being updated
properly, so applications of local functions inside case blocks were
sometimes given the wrong arguments. This is one of the few places where
it's hard to keep track of names in the type system! So naturally that'd
be where things go wrong I suppose...
We never inspect it, so it carries no information - it just needs to be
there as a token to make sure that IO operations run at the right time.
So, IORes can be a newtype now and therefore optimised away.
Data types with one constructor, that has one unerased argument, are
translated to that argument for runtime. This doesn't have a huge effect
on its own, but doing this will expose other optimisations later (e.g.
increasing effect of inlining).
Specialisation happens on the run time case tree, so we need to know
separately which names occur at compile time, and which at run time.
Hence, we now have 'refersToRuntime' in addition to 'refersTo' since
they will be different. (In fact there's more differences, because
there's a lot of metavariable names which are needed at compile time but
erased at run time)
The important building-block here is constructing the parameter
telescope
A minor benefit is that we're not recalculating this telescope
multiple times.
where clause
(1) It was calculated twice previously, once in body of `elabRecord`
and once inside `elabAsData`.
(2) It was passed around globally as a parameter despite not changing
in this context.