In this assignment, you will add support for nested procedures, closures, and tail call elimination to the intermediate language.
First, carefully read all of compilerA6
in Transformations.scala. Then
implement these language features in compilerA6
.
Add support for nested procedures by doing the following.
depth
field of Procedure
in
ProgramRepresentation.scala.paramChunk
) by completing the implementation of
paramChunks
.computeStaticLink
.eliminateCalls
. Do not
concern yourself with closures or tail calls for now. You can mostly
copy your code from eliminateCalls
from Assignment 5, but
you will be modifying it substantially here in Assignment 6. Modify the
code to support nested procedures by computing an argument for the
static link.frame
from Assignment
5.phaseTwo
, copy your addEntryExit
from
Assignment 5. The identical code should work for now, but you will
modify it when you add support for closures.phaseTwo
, complete the implementation of
eliminateVarAccesses
to support accesses to variables and
parameters defined in outer procedures.Before implementing closures in Transformations.scala,
implement the allocate
method of the
SimpleHeapAllocator
in MemoryManagement.scala.
Then add support for closures in Transformations.scala by doing the following.
frameOnHeap
to determine which procedures
require that their frame be allocated on the heap. The frame of a
procedure must be allocated on the heap if:eliminateCalls
and
addEntryExit
to reflect the fact that the frames (and
parameter chunks) of some procedures need to be allocated on the heap
instead of the stack.eliminateCalls
to eliminate
ClosureCall
s in addition to direct Call
s.eliminateClosures
.Add support for tail calls by doing the following (in any order).
detectTailCalls
.copyChunk
in MemoryManagement.scala.eliminateCalls
to generate tail
calls for Call
s and CallClosure
s whose
isTail
is true.