blob: af3d072504d8df63c1e2ee29099ba7a2aadba906 (
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
|
implementation module Sil.Util.Printer
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}
incIndent :: PrintState -> PrintState
incIndent ps = {ps & indent=inc ps.indent}
decIndent :: PrintState -> PrintState
decIndent ps = {ps & indent=dec ps.indent}
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 (If bs else) = st <+ printersperse " else " (map oneblock bs) <+ else`
where
st` = incIndent st
oneblock (c,b) = "if (" <+ c <+ ") {\r\n" <+ print st` b <+ "\r\n" <+ st <+ "}"
else` = case else of
Nothing -> ""
Just e -> " else {\r\n" <+ print st` e <+ "\r\n" <+ st <+ "}"
print st stm = st <+ stm
printersperse :: a [b] -> String | toString a & toString b
printersperse _ [] = ""
printersperse _ [x] = toString x
printersperse g [x:xs] = x <+ g <+ printersperse g xs
|