module CodeGen (
generateAssembly,
) where
import AST
generateAssembly :: AST -> String
generateAssembly :: AST -> String
generateAssembly AST
ast =
String
generateHeader String -> String -> String
forall a. [a] -> [a] -> [a]
++ (String, Int) -> String
forall a b. (a, b) -> a
fst (AST -> Int -> (String, Int)
astToAsm AST
ast Int
0) String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
generateFooter
astToAsm :: AST -> Int -> (String, Int)
astToAsm :: AST -> Int -> (String, Int)
astToAsm [] Int
countr = (String
"", Int
countr)
astToAsm (Cmd
cmd : AST
restoDaAst) Int
countr =
case Cmd -> Int -> (String, Int)
translateCmd Cmd
cmd Int
countr of
(String
asm1, Int
countr1) ->
case AST -> Int -> (String, Int)
astToAsm AST
restoDaAst Int
countr1 of
(String
asm2, Int
countr2) ->
(String
asm1 String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
asm2, Int
countr2)
translateCmd :: Cmd -> Int -> (String, Int)
translateCmd :: Cmd -> Int -> (String, Int)
translateCmd Cmd
Incr Int
countr = (String
" inc byte [rbx]\n", Int
countr)
translateCmd Cmd
Decr Int
countr = (String
" dec byte [rbx]\n", Int
countr)
translateCmd Cmd
Next Int
countr = (String
" inc rbx\n", Int
countr)
translateCmd Cmd
Prev Int
countr = (String
" dec rbx\n", Int
countr)
translateCmd Cmd
Print Int
countr =
( [String] -> String
unlines
[ String
" movzx rdi, byte [rbx]"
, String
" call putchar"
]
, Int
countr
)
translateCmd Cmd
Input Int
countr =
( [String] -> String
unlines
[ String
" call getchar"
, String
" mov [rbx], al"
]
, Int
countr
)
translateCmd (Loop AST
innerAst) Int
countr =
case AST -> Int -> (String, Int)
astToAsm AST
innerAst (Int
countr Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) of
(String
asmDoLoop, Int
countrFinal) ->
( [String] -> String
unlines
[ (String
"loop_start_" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
countr) String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
":"
, String
" cmp byte [rbx], 0"
, String
" je " String -> String -> String
forall a. [a] -> [a] -> [a]
++ (String
"loop_end_" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
countr)
, String
asmDoLoop
, String
" jmp " String -> String -> String
forall a. [a] -> [a] -> [a]
++ (String
"loop_start_" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
countr)
, (String
"loop_end_" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
countr) String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
":"
]
, Int
countrFinal
)
generateHeader :: String
=
[String] -> String
unlines
[
String
"section .data"
, String
" memory: times 30000 db 0"
, String
" pointer: dq memory"
, String
""
, String
"section .text"
, String
" global main"
, String
" extern putchar"
, String
" extern getchar"
, String
""
, String
"main:"
, String
" push rbp"
, String
" mov rbp, rsp"
, String
" mov rbx, [pointer]"
]
generateFooter :: String
=
[String] -> String
unlines
[
String
" mov [pointer], rbx"
, String
" mov rax, 0"
, String
" pop rbp"
, String
" ret"
]