X-Git-Url: https://ruin.nu/git/?p=proglang.git;a=blobdiff_plain;f=Compile.hs;h=f2de7ecdac8228f805218815320e1e2fb5a3ab2f;hp=c3e93f94850a720839196f010a8b6fe6294b60ce;hb=HEAD;hpb=98e238b8dd8c07705ab9681ff07c85e10eda9397 diff --git a/Compile.hs b/Compile.hs index c3e93f9..f2de7ec 100644 --- a/Compile.hs +++ b/Compile.hs @@ -1,15 +1,23 @@ -module Compile (compileExp, compileStm) where +module Compile (compile,compileExp, compileStm) where import Abssyntax import Prelude hiding (lookup) +cHeader = "#include \nint read(){\nint n;\nscanf(\"%d\",&n);\nreturn n;\n}\n" + +cMiddle = "\nint main(void){\n" + +cFooter = "return 0;}\n" + +compile :: [Func] -> [Stm] -> String +compile f s = cHeader++concat (map compileFuncDecl f)++concat (map compileFunc f)++cMiddle++concat (map compileStm s)++cFooter + compileExp :: Exp -> String compileExp (EBool True) = "1"; compileExp (EBool False) = "0"; compileExp (EInt n) = show n compileExp (EVar (Ident i)) = i compileExp (EAss (Ident i) e) = i++"="++compileExp e -compileExp EDefault = error "EDefault called from an illegal place" compileExp (BiOpExp e o e') = "("++compileExp e++")"++op o++"("++compileExp e'++")" compileExp (ENeg e) = "-("++compileExp e++")" compileExp (ENot e) ="!("++compileExp e++")" @@ -17,6 +25,7 @@ compileExp (EPost (Ident i) Plus) = i++"++" compileExp (EPost (Ident i) Minus) = i++"--" compileExp EReadI = "read()" compileExp EReadB = "read()" +compileExp (EFunc (Ident i) as) = i++"("++(foldl1 (\a b -> a++","++b) (map compileExp as))++")" op :: Op -> String op Eq = "==" @@ -37,5 +46,15 @@ compileStm (SIf b s s') = "if("++compileExp b++")"++compileStm s++" \nelse "++co compileStm (SPrint e) = "printf(\"%d\\n\","++compileExp e++");\n" compileStm (SBlock ss) = "{\n"++concat (map (("\t"++).compileStm) ss)++"\n}\n" compileStm (SWhile e s) = "while("++compileExp e++")"++compileStm s -compileStm (SDecl t (Ident i) EDefault) = "int "++i++"=0;\n" +compileStm (SDeclD t i) = compileStm (SDecl t i $ case t of + TInt -> EInt 0 + TBool -> EBool False + ) compileStm (SDecl t (Ident i) e) = "int "++i++"="++compileExp e++";\n" +compileStm (SReturn e) = "return "++compileExp e++";" + +compileFunc :: Func -> String +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" + +compileFuncDecl :: Func -> String +compileFuncDecl (Func _ (Ident i) d ss) = "\nint "++i++"("++(foldl1 (\a b -> a++","++b) (map (\(Decl _ (Ident i)) -> "int "++i) d))++");\n"