Files
notes/docs/lectures/compilers/10_if_then_else.md
T

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 c2 need labels and a JUMPA after

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"

img

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.