]> ruin.nu Git - proglang.git/blob - Compile.hs
compiler seems to be working
[proglang.git] / Compile.hs
1 module Compile (compile,compileExp, compileStm) where
2
3 import Abssyntax
4 import Prelude hiding (lookup)
5
6 cHeader = "#include <stdio.h>\nint read(){\nint n;\nscanf(\"%d\",&n);\nreturn n;\n}\n"
7
8 cMiddle = "\nint main(void){\n"
9
10 cFooter = "return 0;}\n"
11
12 compile :: [Func] -> [Stm] -> String
13 compile f s = cHeader++concat (map compileFuncDecl f)++concat (map compileFunc f)++cMiddle++concat (map compileStm s)++cFooter
14
15 compileExp :: Exp -> String
16 compileExp (EBool True) = "1";
17 compileExp (EBool False) = "0";
18 compileExp (EInt n) = show n
19 compileExp (EVar (Ident i)) = i
20 compileExp (EAss (Ident i) e) = i++"="++compileExp e
21 compileExp (BiOpExp e o e') = "("++compileExp e++")"++op o++"("++compileExp e'++")"
22 compileExp (ENeg e) = "-("++compileExp e++")"
23 compileExp (ENot e) ="!("++compileExp e++")" 
24 compileExp (EPost (Ident i) Plus) = i++"++"
25 compileExp (EPost (Ident i) Minus) = i++"--"
26 compileExp EReadI = "read()"
27 compileExp EReadB = "read()"
28 compileExp (EFunc (Ident i) as) = i++"("++(foldl1 (\a b -> a++","++b) (map compileExp as))++")"
29
30 op :: Op -> String
31 op Eq = "=="
32 op NEq = "!="
33 op Plus = "+"
34 op Minus = "-"
35 op Times = "*" 
36 op Div = "/" 
37 op Lt = "<"
38 op ELt = "<="
39 op Gt = ">"
40 op EGt = ">="
41
42 compileStm :: Stm -> String
43 compileStm (SNoop) = ";\n"
44 compileStm (SExp e) = compileExp e++";\n"
45 compileStm (SIf b s s') = "if("++compileExp b++")"++compileStm s++" \nelse "++compileStm s'
46 compileStm (SPrint e) = "printf(\"%d\\n\","++compileExp e++");\n"
47 compileStm (SBlock ss) = "{\n"++concat (map (("\t"++).compileStm) ss)++"\n}\n"
48 compileStm (SWhile e s) = "while("++compileExp e++")"++compileStm s
49 compileStm (SDeclD t i) = compileStm (SDecl t i $ case t of
50         TInt -> EInt 0
51         TBool -> EBool False
52         )
53 compileStm (SDecl t (Ident i) e) = "int "++i++"="++compileExp e++";\n"
54 compileStm (SReturn e) = "return "++compileExp e++";"
55
56 compileFunc :: Func -> String
57 compileFunc (Func _ (Ident i) d ss) = "\nint "++i++"("++(foldl1 (\a b -> a++","++b) (map (\(Decl _ (Ident i)) -> "int "++i) d))++"){\n"++concat (map compileStm ss)++"\n}\n"
58
59 compileFuncDecl :: Func -> String
60 compileFuncDecl (Func _ (Ident i) d ss) = "\nint "++i++"("++(foldl1 (\a b -> a++","++b) (map (\(Decl _ (Ident i)) -> "int "++i) d))++");\n"