[#279] add intermediate compilation representation for optimization
Problem: performing analysis and modification of Indigo's code for the
purpose of optimization during compilation is not robust, nor
convenient. The problem resides in the fact that to manipulate the
frontend freer monad before it is compiled to the backend we have to
interpret it and break the bindings.
This was circumvented based on predictability of the Var
s resulting
from statements, but we need something better to have a wider and more
stable machinery for optimization.
Solution: add an intermediate representation that is not a Monad, but a data-type that also contains (as "argument") the resulting vars (if any). The variable are all assigned in the conversion between the frontend and this new representation. This in turns frees the backend from generating variables, making its function without a return value as well (and allowing a conversion to happen). Additinally, because it was easier to solve these now instead of updating them and solve them later, this also solves some exising TODOs.