This is a complex module. It is described in [App98b, Chapter 7]. One main client is the semantic module (cf. Section ??).
Different from what is stated in [App98b], I use symbols as argument for the new_level and not Temp.label. I reported it to Appel as potential error. This also required that the function new_level gives back the label, as well, since the Semant-module must store this in the environment.
In the end, it would be nice to make a it a functor over FRAME to get a retargetable compiler.
[L-value and r-value] What are l-values and r-values? What’s the difference on the level of the intermediate language?
[Integer constants] How are they concretely translated? I.e., what is the result of the function int_exp?
[Nil expression] How is the nil-expression translated?
[Sequence] How is a sequence of statements translated? Currently, what is kept is just the last element.
Currently, the construction is done in two phases, first, while type checking, the expressions are translated in isolation, and afterwards, they are glued together by the function seqlist. I’m not sure whether this is the best solution or even correct. Currently, the function seqlist, transforms a non-empty list of expressions e_{0},… e_{n}, into
Eseq(Seq(e_{0},Seq(… Seq(e_{n−2},e_{n−1})…)),e_{n}). |
In the process, the e_{i} except the last one are unwrapped into a Tree.stm, e_{n} into a Tree.exp.
[Complement] Why does page 161 mention unary complement? What is it anyway?
[Conditionals] How are the binary boolean operators of the abstract syntax translated?
[Conditionals] What would happen if we translated the boolean value not into a conditional expression but a value? Would this be possible? Is it less efficient code? What does Appel mean if he says that “the whole point” of the Cx-construction is easy combination with the & and |-operators? They are translated away already anyway?
[Conditionals] How are conditionals translated?
The whole expression is assumed to give back a value, i.e., the expression is translated into a Tree.exp, and not a Tree.stmt and the trailing temporary is the expression where the result is given back.[[c]]_{C} L_t L_f L_t: r <- [[e_{2}]]_{E}; jump L_join; L_f: r <- [[e_{3}]]_{E}; jump L_join L_join:: r
The problem is that the structure get’s rather spaghetti-like in case the expressions inside are not Translate.Ex’s, but conditional expressions, for instance in the following fragment:
Then converting 3<5 into an expression introduces an inner level of conditional jumps and the result will look as follows:
The translation distinguishes which form the translations of the branches e_{1} and e_{2} have. In case they are both conditional expressions themselves, i.e., Tree.Cx-expressions, then Figure 2.
λ L_t. λ L_f. [[c]]_{C} Lc_1 Lc_2; Lc_1: [[e_{2}]]_{C} L_t L_f; Lc_2: [[e_{3}]]_{C} L_t L_f;
In case neither branch returns a value, then the whole conditional expression does not return a value and is therefore translated into a Tree.Nx. In all other cases, a Tree.Ex is produced. The one-armed conditional does not generate a return value as enforced by the type system.
How is an ordinary expression interpreted as conditional?
t_r <- 1 [turn the Cx into a conditional expression: unCx] L_f t_r <- 0 L_t ) t_r