File: Pretty.hs

package info (click to toggle)
haskell-language-glsl 0.3.0-5
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 144 kB
  • sloc: haskell: 1,593; makefile: 3
file content (346 lines) | stat: -rw-r--r-- 13,397 bytes parent folder | download | duplicates (3)
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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
{-# OPTIONS_GHC -fno-warn-orphans #-}
module Language.GLSL.Pretty where

import Text.PrettyPrint.HughesPJClass
import Text.Printf

import Language.GLSL.Syntax
import Prelude hiding ((<>))

----------------------------------------------------------------------
-- helpers (TODO clean)
----------------------------------------------------------------------

type Assoc = (Rational -> Rational, Rational -> Rational)

assocLeft, assocRight, assocNone :: Assoc
assocLeft  = (id,bump)
assocRight = (bump,id)
assocNone  = (bump,bump)

bump :: Rational -> Rational
bump = (+ 0.5)

prettyBinary :: Pretty a =>
  PrettyLevel -> Rational -> Rational -> Assoc -> String -> a -> a -> Doc
prettyBinary l p op (lf,rf) o e1 e2 = prettyParen (p > op) $
  pPrintPrec l (lf op) e1 <+> text o <+> pPrintPrec l (rf op) e2

option :: Pretty a => Maybe a -> Doc
option Nothing = empty
option (Just x) = pPrint x

indexing :: Pretty a => Maybe (Maybe a) -> Doc
indexing Nothing = empty
indexing (Just Nothing) = brackets empty
indexing (Just (Just e)) = brackets $ pPrint e

indexing' :: Pretty a => Maybe (String, Maybe a) -> Doc
indexing' Nothing = empty
indexing' (Just (i, Nothing)) = text i
indexing' (Just (i, Just e)) = text i <> brackets (pPrint e)

initialize :: Pretty a => Maybe a -> Doc
initialize Nothing = empty
initialize (Just e) = char ' ' <> equals <+> pPrint e

ident :: Pretty a => Maybe (String, Maybe (Maybe a)) -> Doc
ident Nothing = empty
ident (Just (i, Nothing)) = text i
ident (Just (i, Just Nothing)) = text i <> brackets empty
ident (Just (i, Just (Just e))) = text i <> brackets (pPrint e)

initialize' :: Pretty a => Maybe (String, Maybe a) -> Doc
initialize' Nothing = empty
initialize' (Just (i, Nothing)) = text i
initialize' (Just (i, Just e)) = text i <+> char '=' <+> pPrint e

----------------------------------------------------------------------
-- Pretty instances
----------------------------------------------------------------------

instance Pretty TranslationUnit where
  pPrint (TranslationUnit ds) = vcat $ map pPrint ds
--  pPrint (Alternative p e) = text "(" <> nest 2 (vcat [pPrint p, pPrint e]) <> text ")"

instance Pretty ExternalDeclaration where
  pPrint (FunctionDeclaration p) = pPrint p <> semi
  pPrint (FunctionDefinition p s) = vcat [pPrint p, pPrint s]
  pPrint (Declaration d) = pPrint d

instance Pretty Declaration where
  pPrint (InitDeclaration it ds) = pPrint it <+> hsep (punctuate comma (map pPrint ds)) <> semi
  pPrint (Precision pq t) = text "precision" <+> pPrint pq <+> pPrint t <> semi
  pPrint (Block tq i ds n) = vcat [pPrint tq <+> text i, lbrace, nest 2 (vcat $ map pPrint ds), rbrace <+> ident n <> semi]
  pPrint (TQ tq) = pPrint tq <> semi

instance Pretty InitDeclarator where
  pPrint (InitDecl i a b) = text i <> indexing a <> initialize b

instance Pretty InvariantOrType where
  pPrint InvariantDeclarator = text "invariant"
  pPrint (TypeDeclarator ft) = pPrint ft

instance Pretty FullType where
  pPrint (FullType tq ts) = option tq <+> pPrint ts

instance Pretty TypeQualifier where
  pPrint (TypeQualSto sq) = pPrint sq
  pPrint (TypeQualLay lq sq) = pPrint lq <+> option sq
  pPrint (TypeQualInt iq sq) = pPrint iq <+> option sq
  pPrint (TypeQualInv iq sq) = pPrint iq <+> option sq
  pPrint (TypeQualInv3 iq iq' sq) = pPrint iq <+> pPrint iq' <+> pPrint sq

instance Pretty StorageQualifier where
  pPrint q = case q of
    Const -> text "const"
    Attribute -> text "attribute"
    Varying -> text "varying"
    CentroidVarying -> text "centroid varying"
    In -> text "in"
    Out -> text "out"
    CentroidIn -> text "centroid in"
    CentroidOut -> text "centroid out"
    Uniform -> text "uniform"

instance Pretty LayoutQualifier where
  pPrint (Layout is) = text "layout" <+> char '(' <>
    (hsep $ punctuate comma $ map pPrint is) <> char ')'

instance Pretty LayoutQualifierId where
  pPrint (LayoutQualId i Nothing) = text i
  pPrint (LayoutQualId i (Just e)) = text i <+> char '=' <+> pPrint e

instance Pretty InterpolationQualifier where
  pPrint q = case q of
    Smooth -> text "smooth"
    Flat -> text "flat"
    NoPerspective -> text "noperspective"

instance Pretty InvariantQualifier where
  pPrint Invariant = text "invariant"

instance Pretty TypeSpecifier where
  pPrint (TypeSpec (Just pq) t) = pPrint pq <+> pPrint t
  pPrint (TypeSpec Nothing t) = pPrint t

instance Pretty PrecisionQualifier where
  pPrint HighP = text "highp"
  pPrint MediumP = text "mediump"
  pPrint LowP = text "lowp"

instance Pretty TypeSpecifierNoPrecision where
  pPrint (TypeSpecNoPrecision t a) = pPrint t <+> indexing a

instance Pretty TypeSpecifierNonArray where
  pPrint t = case t of
    Void -> text "void"
    Float -> text "float"
    Int -> text "int"
    UInt -> text "uint"
    Bool -> text "bool"
    Vec2 -> text "vec2"
    Vec3 -> text "vec3"
    Vec4 -> text "vec4"
    BVec2 -> text "bvec2"
    BVec3 -> text "bvec3"
    BVec4 -> text "bvec4"
    IVec2 -> text "ivec2"
    IVec3 -> text "ivec3"
    IVec4 -> text "ivec4"
    UVec2 -> text "uvec2"
    UVec3 -> text "uvec3"
    UVec4 -> text "uvec4"
    Mat2 -> text "mat2"
    Mat3 -> text "mat3"
    Mat4 -> text "mat4"
    Mat2x2 -> text "mat2x2"
    Mat2x3 -> text "mat2x3"
    Mat2x4 -> text "mat2x4"
    Mat3x2 -> text "mat3x2"
    Mat3x3 -> text "mat3x3"
    Mat3x4 -> text "mat3x4"
    Mat4x2 -> text "mat4x2"
    Mat4x3 -> text "mat4x3"
    Mat4x4 -> text "mat4x4"
    Sampler1D -> text "sampler1D"
    Sampler2D -> text "sampler2D"
    Sampler3D -> text "sampler3D"
    SamplerCube -> text "samplerCube"
    Sampler1DShadow -> text "sampler1DShadow"
    Sampler2DShadow -> text "sampler2DShadow"
    SamplerCubeShadow -> text "samplerCubeShadow"
    Sampler1DArray -> text "sampler1DArray"
    Sampler2DArray -> text "sampler2DArray"
    Sampler1DArrayShadow -> text "sampler1DArrayShadow"
    Sampler2DArrayShadow -> text "sampler2DArrayShadow"
    ISampler1D -> text "isampler1D"
    ISampler2D -> text "isampler2D"
    ISampler3D -> text "isampler3D"
    ISamplerCube -> text "isamplerCube"
    ISampler1DArray -> text "isampler1DArray"
    ISampler2DArray -> text "isampler2DArray"
    USampler1D -> text "usampler1D"
    USampler2D -> text "usampler2D"
    USampler3D -> text "usampler3D"
    USamplerCube -> text "usamplerCube"
    USampler1DArray -> text "usampler1DArray"
    USampler2DArray -> text "usampler2DArray"
    Sampler2DRect -> text "sampler2DRect"
    Sampler2DRectShadow -> text "sampler2DRectShadow"
    ISampler2DRect -> text "isampler2DRect"
    USampler2DRect -> text "usampler2DRect"
    SamplerBuffer -> text "samplerBuffer"
    ISamplerBuffer -> text "isamplerBuffer"
    USamplerBuffer -> text "usamplerBuffer"
    Sampler2DMS -> text "sampler2DMS"
    ISampler2DMS -> text "isampler2DMS"
    USampler2DMS -> text "usampler2DMS"
    Sampler2DMSArray -> text "sampler2DMSArray"
    ISampler2DMSArray -> text "isampler2DMSArray"
    USampler2DMSArray -> text "usampler2DMSArray"
    StructSpecifier i ds ->
      vcat [text "struct" <+> i', lbrace, nest 2 (vcat $ map pPrint ds), rbrace]
      where i' = case i of { Nothing -> empty ; Just n -> text n }
    TypeName i -> text i

instance Pretty Field where
  pPrint (Field tq s ds) =
    option tq <+> pPrint s <+> hsep (punctuate comma $ map pPrint ds) <> semi

instance Pretty StructDeclarator where
  pPrint (StructDeclarator i e) = ident (Just (i, e))

instance Pretty Expr where
  pPrintPrec l p e = case e of
  -- primaryExpression
    Variable v -> text v
    IntConstant Decimal i -> text (show i)
    IntConstant Hexadecimal i -> text (printf "0x%x" i)
    IntConstant Octal i -> text (printf "0%o" i)
    FloatConstant f -> text (show f)
    BoolConstant True -> text "true"
    BoolConstant False -> text "false"
  -- postfixExpression
    Bracket e1 e2 -> prettyParen (p > 16) $
      pPrintPrec l 16 e1 <> brackets (pPrint e2)
    FieldSelection e1 f -> prettyParen (p > 16) $
      pPrintPrec l 16 e1 <> char '.' <> text f
    MethodCall e1 i ps -> prettyParen (p > 16) $
      pPrintPrec l 16 e1 <> char '.' <> pPrint i <+> parens (pPrint ps)
    FunctionCall i ps -> prettyParen (p > 16) $
      pPrint i <+> parens (pPrint ps)
    PostInc e1 -> prettyParen (p > 15) $
      pPrintPrec l 15 e1 <+> text "++"
    PostDec e1 -> prettyParen (p > 15) $
      pPrintPrec l 15 e1 <+> text "--"
    PreInc e1 -> prettyParen (p > 15) $
      text "++" <+> pPrintPrec l 15 e1
    PreDec e1 -> prettyParen (p > 15) $
      text "--" <+> pPrintPrec l 15 e1
  -- unary expression
    UnaryPlus e1 -> prettyParen (p > 15) $
      text "+" <> pPrintPrec l 15 e1
    UnaryNegate e1 -> prettyParen (p > 15) $
      text "-" <> pPrintPrec l 15 e1
    UnaryNot e1 -> prettyParen (p > 15) $
      text "!" <> pPrintPrec l 15 e1
    UnaryOneComplement e1 -> prettyParen (p > 15) $
      text "~" <> pPrintPrec l 15 e1
  -- binary expression
    Mul        e1 e2 -> prettyBinary l p 14 assocLeft "*" e1 e2
    Div        e1 e2 -> prettyBinary l p 14 assocLeft "/" e1 e2
    Mod        e1 e2 -> prettyBinary l p 14 assocLeft "%" e1 e2
    Add        e1 e2 -> prettyBinary l p 13 assocLeft "+" e1 e2
    Sub        e1 e2 -> prettyBinary l p 13 assocLeft "-" e1 e2
    LeftShift  e1 e2 -> prettyBinary l p 12 assocLeft "<<" e1 e2
    RightShift e1 e2 -> prettyBinary l p 12 assocLeft ">>" e1 e2
    Lt         e1 e2 -> prettyBinary l p 11 assocLeft "<" e1 e2
    Gt         e1 e2 -> prettyBinary l p 11 assocLeft ">" e1 e2
    Lte        e1 e2 -> prettyBinary l p 11 assocLeft "<=" e1 e2
    Gte        e1 e2 -> prettyBinary l p 11 assocLeft ">=" e1 e2
    Equ        e1 e2 -> prettyBinary l p 10 assocLeft "==" e1 e2
    Neq        e1 e2 -> prettyBinary l p 10 assocLeft "!=" e1 e2
    BitAnd     e1 e2 -> prettyBinary l p 9 assocLeft "&" e1 e2
    BitXor     e1 e2 -> prettyBinary l p 8 assocLeft "^" e1 e2
    BitOr      e1 e2 -> prettyBinary l p 7 assocLeft "|" e1 e2
    And        e1 e2 -> prettyBinary l p 6 assocLeft "&&" e1 e2
-- TODO Xor 5 "^^"
    Or         e1 e2 -> prettyBinary l p 4 assocLeft "||" e1 e2
    Selection e1 e2 e3 -> prettyParen (p > 3) $
      pPrintPrec l 3 e1 <+> char '?' <+> pPrintPrec l 3 e2
      <+> char ':' <+> pPrintPrec l 3 e3
  -- assignment, the left Expr should be unary expression
    Equal       e1 e2 -> prettyBinary l p 2 assocRight "=" e1 e2
    MulAssign   e1 e2 -> prettyBinary l p 2 assocRight "*=" e1 e2
    DivAssign   e1 e2 -> prettyBinary l p 2 assocRight "/=" e1 e2
    ModAssign   e1 e2 -> prettyBinary l p 2 assocRight "%=" e1 e2
    AddAssign   e1 e2 -> prettyBinary l p 2 assocRight "+=" e1 e2
    SubAssign   e1 e2 -> prettyBinary l p 2 assocRight "-=" e1 e2
    LeftAssign  e1 e2 -> prettyBinary l p 2 assocRight "<<=" e1 e2
    RightAssign e1 e2 -> prettyBinary l p 2 assocRight ">>=" e1 e2
    AndAssign   e1 e2 -> prettyBinary l p 2 assocRight "&=" e1 e2
    XorAssign   e1 e2 -> prettyBinary l p 2 assocRight "^=" e1 e2
    OrAssign    e1 e2 -> prettyBinary l p 2 assocRight "|=" e1 e2
  -- sequence
    Sequence e1 e2 -> prettyParen (p > 1) $
      pPrintPrec l 1 e1 <> char ',' <+> pPrintPrec l 1 e2

instance Pretty FunctionIdentifier where
  pPrint (FuncIdTypeSpec t) = pPrint t
  pPrint (FuncId i) = text i

instance Pretty Parameters where
  pPrint ParamVoid = empty
  pPrint (Params es) = hsep $ punctuate comma $ map pPrint es

instance Pretty FunctionPrototype where
  pPrint (FuncProt t i ps) = pPrint t <+> text i <+> char '(' <> hsep (punctuate comma $ map pPrint ps) <> text ")"

instance Pretty ParameterDeclaration where
  pPrint (ParameterDeclaration tq q s i) =
    option tq <+> option q <+> pPrint s <+> indexing' i

instance Pretty ParameterTypeQualifier  where
  pPrint ConstParameter = text "const"

instance Pretty ParameterQualifier where
  pPrint InParameter = text "in"
  pPrint OutParameter = text "out"
  pPrint InOutParameter = text "inout"

instance Pretty Statement where
  pPrint s = case s of
  -- declaration statement
    DeclarationStatement d -> pPrint d
  -- jump statement
    Continue -> text "continue" <> semi
    Break -> text "break" <> semi
    Return e -> text "return" <+> option e <> semi
    Discard -> text "discard" <> semi
  -- compound statement
    CompoundStatement c -> pPrint c
  -- expression statement
    ExpressionStatement e -> option e <> semi
  -- selection statement
    SelectionStatement e s1 s2 -> vcat [text "if" <+> parens (pPrint e), nest 2 $ pPrint s1, option s2]
  -- switch statement
    SwitchStatement e s1 -> vcat [text "switch" <+> parens (pPrint e), lbrace, nest 2 $ vcat $ map pPrint s1, rbrace]
    CaseLabel l -> pPrint l
  -- iteration statement
    While c s1 -> vcat [text "while" <+> parens (pPrint c), pPrint s1]
    DoWhile s1 e -> vcat [text "do", pPrint s1, text "while" <+> parens (pPrint e)]
    For (Left e1) c e2 s1 -> vcat [text "for", parens (option e1 <+> semi <+> option c <+> semi <+> option e2), pPrint s1]
    For (Right d) c e2 s1 -> vcat [text "for", parens (pPrint d <+> semi <+> option c <+> semi <+> option e2), pPrint s1]

instance Pretty Compound where
  pPrint (Compound s) = vcat [lbrace, nest 2 $ vcat $ map pPrint s, rbrace]

instance Pretty Condition where
  pPrint (Condition e) = pPrint e
  pPrint (InitializedCondition t i e) = pPrint t <+> pPrint i <+> pPrint e

instance Pretty CaseLabel where
  pPrint  (Case e) = text "case" <+> pPrint e <> colon
  pPrint Default = text "default:"