130 lines
1.8 KiB
Markdown
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
|
|
|
|

|
|
|
|
**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)
|
|
```
|