Add the rest of university notes
This commit is contained in:
366 files changed
+9844
-110
No files matched your search
@@ -0,0 +1,104 @@
|
||||
# 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.
|
||||
|
||||
```haskell
|
||||
--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$
|
||||
|
||||
```python
|
||||
if e then c1 else c2
|
||||
IfThenElse e c1 c2
|
||||
```
|
||||
|
||||
```haskell
|
||||
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
|
||||
```
|
||||
|
||||
```assembly
|
||||
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.
|
||||
|
||||
```haskell
|
||||
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.
|
||||
Reference in new issue
Block a user