blob: ad7cfacf4c700e604a56654de8b787d3188403ed (
plain) (
blame)
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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
|
implementation module Sil.Util
import _SystemArray
import StdEnum
from StdFunc import id
import StdInt
import StdList
import StdOverloaded
import StdString
from Data.Func import $
import Data.List
import Data.Maybe
import Text
import Sil.Parse
import Sil.Syntax
:: PrintState =
{ indent :: Int
}
instance zero PrintState where zero = {indent=0}
instance toString PrintState where toString st = {'\t' \\ _ <- [1..st.indent]}
instance PrettyPrinter [Token]
where
print st [] = ""
print st [t] = toString t
print st [t:ts=:[t`:_]] = toString t +++ spaceBetween t t` +++ print st` ts
where
st` = {st & indent=indent`}
indent` = newIndent t t` st.indent
spaceBetween :: Token Token -> String
spaceBetween _ TBraceClose = newline
spaceBetween TParenOpen _ = ""
spaceBetween TParenClose TBraceOpen = space
spaceBetween TParenClose _ = ""
spaceBetween TBraceOpen _ = newline
spaceBetween TBraceClose _ = newline
spaceBetween TComma _ = space
spaceBetween TSemicolon _ = newline
spaceBetween TAssign _ = space
spaceBetween (TLit _) _ = space
spaceBetween TIf _ = space
spaceBetween TWhile _ = space
spaceBetween TReturn _ = space
spaceBetween (TName _) TParenClose = ""
spaceBetween (TName _) TSemicolon = ""
spaceBetween (TName _) _ = space
newline = "\r\n" +++ {'\t' \\ _ <- [1..indent`]}
space = " "
newIndent :: Token Token -> Int -> Int
newIndent TBraceOpen _ = inc
newIndent _ TBraceClose = dec
newIndent _ _ = id
instance PrettyPrinter Program
where
print st prog = p st prog.p_funs
where
p :: PrintState [Function] -> String
p _ [] = ""
p st [f] = print st f
p st [f:fs] = print st f <+ "\r\n\r\n" <+ p st fs
instance PrettyPrinter Function
where
print st f = st <+ f.f_type <+ " " <+ f.f_name
<+ "(" <+ printersperse ", " f.f_args <+ ") {\r\n"
<+ print {st & indent=st.indent+1} f.f_code <+ "\r\n" <+ st <+ "}"
instance PrettyPrinter CodeBlock
where
print st cb = concat $ intersperse "\r\n" $
[print st x \\ x <- cb.cb_init] ++ [print st x \\ x <- cb.cb_content]
instance PrettyPrinter Initialisation
where
print st init = st <+ init.init_type <+ " " <+ init.init_name <+ ";"
instance PrettyPrinter Statement where print st stm = st <+ stm <+ ";"
instance toString Statement
where
toString (Declaration n a) = n <+ " " <+ TAssign <+ " " <+ a
toString (Application app) = toString app
toString (Return Nothing) = "return"
toString (Return (Just a)) = "return " <+ a <+ ""
toString _ = "<<unimplemented Statement>>"
instance toString Type
where
toString TBool = "Bool"
toString TInt = "Int"
toString TVoid = "Void"
instance toString Arg where toString arg = arg.arg_type <+ " " <+ arg.arg_name
instance toString Application
where
toString (Name n) = n
toString (Literal lit) = toString lit
toString (App n args) = n <+ "(" <+ printersperse ", " args <+ ")"
instance toString Literal
where
toString (BLit b) = toString b
toString (ILit i) = toString i
printersperse :: a [b] -> String | toString a & toString b
printersperse _ [] = ""
printersperse _ [x] = toString x
printersperse g [x:xs] = x <+ g <+ printersperse g xs
|