This repository has been archived by the owner on Jul 6, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Generator.hs
66 lines (56 loc) · 2.66 KB
/
Generator.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
module Generator(generateBlock,genearateDecs) where
import AST
import qualified TypeChecking as T
import qualified Data.Map as Map
generateBlock dec indent l = foldr (\s p -> p ++ indent ++ s++ "\n") "" $ map (generateStmt dec indent ) l
generateTerm litType (TTimes e f) = (generateTerm litType e ) ++" * " ++(generateFac litType f)
generateTerm litType (TDiv e f) = (generateTerm litType e ) ++" / " ++(generateFac litType f)
generateTerm litType (TFac t) = generateFac litType t
generateExp litType (EPlus e t) = case litType of
TypeString->" add_s("++(generateExp litType e ) ++" , " ++(generateTerm litType t)++") "
_->(generateExp litType e ) ++" + " ++(generateTerm litType t)
generateExp litType (EMinus e t) = generateExp litType $ EPlus e $ TFac $ FNeg $ FPar $ ETerm t
generateExp litType (ETerm t) = generateTerm litType t
generateFac litType (FPar e) = " ("++ generateExp litType e ++") "
generateFac litType (FNeg e) = case litType of
TypeString->" neg_s("++(generateFac litType e ) ++") "
_->"-" ++(generateFac litType e)
generateFac litType (FFLit (p,f)) = show f
generateFac litType (FILit (p,i)) = show i
generateFac litType (FSLit (p,i)) = i
generateFac litType (FId (p,i)) = i
generateStmt dec indent (SAssign (p,i) e) = i ++ " = " ++ (generateExp (T.getVarType dec i p) e)++";"
generateStmt dec indent (SElse e s1 s2) = let
i1 = "if ("++(generateExp TypeInt e)++") {\n"
i2 = (generateBlock dec (indent++" ") s1)++indent ++"} else {\n"
i3 = (generateBlock dec (indent++" ") s2)++indent ++ "}"
in i1 ++ i2 ++ i3
generateStmt dec indent (SIf e s1) = let
i1 = "if ("++(generateExp TypeInt e)++") {\n"
i2 = (generateBlock dec (indent++" ") s1)++indent ++"}"
in i1++i2
generateStmt dec indent (SWhile e s1) = let
i1 = "while ("++(generateExp TypeInt e)++") {\n"
i2 = (generateBlock dec (indent++" ") s1)++indent ++"}"
in i1++i2
generateStmt dec indent (SPrint e) = let
t = T.checkExp e dec
s = generateExp t e
p = getPrintFunction t
in p++s++" );"
generateStmt dec indent (SRead (p,i) ) = let
t = (T.getVarType dec i p)
f = getReadFunction indent t
in case t of
TypeString -> i ++ f ++ i ++");"
_ -> f ++ i ++ ");"
getPrintFunction TypeInt = "printf( \"%d\\n\","
getPrintFunction TypeString = "printf( \"%s\\n\","
getPrintFunction TypeFloat = "printf( \"%f\\n\","
getReadFunction i TypeInt = "scanf( \"%d\",&"
getReadFunction i TypeString = "=malloc(1024);\n" ++ i ++ "scanf( \"%s\","
getReadFunction i TypeFloat = "scanf( \"%f\",&"
genearateDecs d = Map.foldrWithKey (\s t p -> p++" "++ (getCType t) ++ s ++ ";\n" ) "" d
getCType TypeInt = "int "
getCType TypeFloat = "float "
getCType TypeString = "char* "