Files
notes/docs/lectures/compilers/03_TAM.md
T

130 lines
1.8 KiB
Markdown

# Triangle Abstract Machine
**TAM** instruction set
```assembly
LOADL (int)
NEG
ADD
SUB
MUL
DIV
```
TAM works on a stack of integers.
##### Executing a TAM program
```assembly
LOADL 7
ADD --adds top two numbers on the stack
LOADL 2
SUB -- note its 15-2
LOADL 4
DIV --integer division
```
The stack during this program:
$$
\begin{bmatrix}
{8} \\
{5}
\end{bmatrix}
\implies
\begin{bmatrix}
{7} \\
{8} \\
{5}
\end{bmatrix}
\implies
\begin{bmatrix}
{15} \\
{5}
\end{bmatrix}
\implies
\begin{bmatrix}
{2} \\
{15} \\
{5}
\end{bmatrix}
\implies
\begin{bmatrix}
{13} \\
{5}
\end{bmatrix}
\implies
\begin{bmatrix}
{4} \\
{13} \\
{5}
\end{bmatrix}
\implies
\begin{bmatrix}
{3} \\
{5}
\end{bmatrix}
$$
## Compiler Complete Example
Program in **Arith**
```c
5 * ((8 + 7) - 2) / 4
```
**A**bstract **S**yntax **T**ree
![img](img/h.png)
**TAM** program
```assembly
LOADL 5
LOADL 8
LOADL 7
ADD
LOADL 2
SUB
LOADL 4
DIV
MUL
```
## Implementing TAM in Haskell
```haskell
module TAM where
data TamInstruction = LOADL Int
| ADD | SUB
| MUL | DIV
| NEG
deriving(Eq, Show)
type Stack = [Int]
execute :: [TamInstruction] -> Stack -> Stack
execute [] s = s --if stack empty, then return the stack
execute (LOADL n : tp) s = execute tp (n : s) --push n to top of stack
execute (ADD : tp) (a : b : s) = execute tp ((a+b):s) --push a+b
...
execute (DIV : tp) (a : b : s) = execute tp ((a`div`b):s)
```
Quicker way to write the execute function using `absOpToConcrOp`
```haskell
convOp :: TamInstruction -> Int -> Int -> Int
convOp ADD = (+)
convOp SUB = (-)
convOp MUL = (*)
convOp DIV = (`div`)
execute :: [TamInstruction] -> Stack -> Stack
execute [] s = s
execute (LOADL n : tp) s = execute tp (n : s)
execute (NEG : tp) (a : s) = execute tp (-a : s)
execute (op : tp) (a : b : s) = execute tp ((convOp op a b) : s)
```