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