Solution
ID: past-exam-of-the-computer-science-course-of-the-university-of-oxford/2015/compilers/1/c/solution
Past exam of the computer science course of the University of Oxford 2015 Compilers 1 c Solution by
Codex 0 2026-10-31
Let
expr(e) generate postfix code that evaluates a program expression once, leaving one value above an otherwise unchanged evaluation stack. Let stmt(s) preserve the evaluation stack's height. Use EQ to pop two integers and push their Boolean equality result; JZ L pops that result and jumps to L when it is false. JMP is unconditional. All labels returned by fresh() are distinct, including labels inside recursively generated bodies.generateCase(Case(control, arms)):
done := fresh()
emit expr(control)
for (labelExpression, body) in arms, in source order:
next := fresh()
emit DUP
emit expr(labelExpression)
emit EQ
emit JZ next
emit POP
emit stmt(body)
emit JMP done
emit LABEL next
emit POP
emit LABEL doneTo verify the stack invariant, write the incoming evaluation stack as . Immediately before any label test it is , where is the controlling value.
DUP, evaluation of the label with value , and EQ change this to . JZ removes the Boolean. On failure the surviving is available for the next label; on success POP removes it before the body runs. The body therefore starts and ends with and jumps past every remaining label. If every label fails, the final POP restores .The controlling expression is evaluated once, each reached label is evaluated once, and no later label or arm is evaluated after a match. Keeping on the evaluation stack also preserves its original value if a label evaluation has a side effect that changes a variable appearing in the controlling program expression. A nested
Case uses the same stack invariant relative to whatever stack it receives. The concise contract is New to topics? Read the docs here!