2.5 KiB
Compiling Branches
Mini Triangle Programs -$parse$-> AST -$Code\space Generation$-> TAM Programs -execute -> Output
Before we could generate a list of instructions to be executed in sequence, now we need to implement code thats conditionally executed or executed multiple times.
--Code for dealing with functions and commands
commCode :: VarEnv -> Command -> TAMProg
We will assume an if statement looks like this
IF e THEN c_1 ELSE c_2
if e then c1 else c2
IfThenElse e c1 c2
expCode ve e
commCode ve c1
commCode ve c2
-- We dont want to execute both
-
We can use
JUMPIFZ R1, a branching function supplied by the TAM language. -
This means
commCode ve c1&commCode ve c2need labels and aJUMPAafter
MINI TRIANGLE PROGRAM
let var := 5
in
begin
if 1
then n := 6
else n := 7;
if 0
then n := 8
else n := 9;
end
COMPILED VERSION
LOADL 5
LOAD 1 --if 1
JUMPIFZ "label1" --jump to else
LOAD 6 --load the number
STORE 0 --store 0 (stack[0] is 6 from line above) in the place of variable n, for other variables you would have to check the variable enviroment to get the stack address
JUMP "label2"
Label "label1"
LOAD 7
STORE 0
Label "label2"
LOAD 0
JUMPIFZ "label3"
Generating Labels
Labels must always be unique.
This would require a global variable in our compiler to count the number of labels, haskell doesnt not allow global variables.
We can use the stateMonad instead.
type LabelName = String
fresh :: ST Int LabelName
-- Whenever we call fresh, it generates a new label name
-- We can use do (because fresh is element of ST Monad)
fresh = do
n <- stGet --checks current state (which is num of labels)
stUpdate(n+1) --update number of labels
return ("#" : (show n)) -- # symbol to denote labels
-- show converts integer to string (fresh returns string)
commCode :: VarEnv -> Command -> ST Int [TAMInsrt]
-- TAMPrgm is interchangable with [TAMInstr]
commCode ve (IFTHENELSE e c1 c2) =
do l1 <- fresh
l2 <- fresh --generate the two labels needed for an if
let te = expCode ve e --the condition expression
tc1 <- commCode ve c1 --compile success branch
tc2 <- commCode ve c2 --compile else branch
return (te ++ [JUMPIFZ l1] ++ tc1 ++ [JUMP l2]
++ [Label l1] ++ tc2 ++ [Label l2])
--then return the tam instructions
REMINDER: expCode is a function that takes a variable environment ve and an expression e and generates a list of TAM instructions.
