File: PrintOcamlCode.ag

package info (click to toggle)
uuagc 0.9.56-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, trixie
  • size: 5,764 kB
  • sloc: haskell: 84,340; makefile: 11
file content (222 lines) | stat: -rw-r--r-- 7,825 bytes parent folder | download | duplicates (2)
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
PRAGMA strictdata
PRAGMA optimize
PRAGMA bangpats
PRAGMA strictwrap

INCLUDE "Code.ag"
INCLUDE "Patterns.ag"

imports
{
import Pretty
import Code
import Patterns
import Options
import CommonTypes hiding (List,Type,Map,Maybe,IntMap,Either)
import Data.List(intersperse,intercalate)
import Data.Char(toLower)
}


{
type PP_Docs = [PP_Doc]

ppMultiSeqH :: [PP_Doc] -> PP_Doc -> PP_Doc
ppMultiSeqH = ppMultiSeq' (>#<)

ppMultiSeqV :: [PP_Doc] -> PP_Doc -> PP_Doc
ppMultiSeqV = ppMultiSeq' (>-<)

ppMultiSeq' :: (PP_Doc -> PP_Doc -> PP_Doc) -> [PP_Doc] -> PP_Doc -> PP_Doc
ppMultiSeq' next strictArgs expr
  = foldr (\v r -> (v >#< "`seq`") `next` pp_parens r) expr strictArgs

ppTuple :: Bool -> [PP_Doc] -> PP_Doc
ppTuple True  pps = "(" >|< pp_block " " (replicate (length pps `max` 1) ')') ",(" pps
ppTuple False pps = "(" >|< pp_block " " ")" "," pps
}


--
-- Pass options down
--

ATTR Program Expr Exprs Decl Decls Chunk Chunks CaseAlts CaseAlt Lhs Pattern Patterns [ options:{Options} | | ]

ATTR Program Chunks Chunk [ textBlockMap : {Map BlockInfo PP_Doc} | | ]


--
-- Collect outputs
--

ATTR Program                                                              [ | | output:{PP_Docs} ]
ATTR Expr Decl DataAlt CaseAlt Type NamedType Lhs Pattern                 [ | | pp:{PP_Doc} ]
ATTR Exprs DataAlts CaseAlts Types NamedTypes Decls Chunk Chunks Patterns [ | | pps : {PP_Docs} ]

SEM Program
  | Program    lhs.output  = @chunks.pps

SEM Exprs
  | Cons lhs.pps = @hd.pp : @tl.pps
  | Nil  lhs.pps = []

SEM CaseAlts
  | Cons lhs.pps = @hd.pp : @tl.pps
  | Nil  lhs.pps = []

SEM DataAlts
  | Cons lhs.pps = @hd.pp : @tl.pps
  | Nil  lhs.pps = []

SEM Types
  | Cons lhs.pps = @hd.pp : @tl.pps
  | Nil  lhs.pps = []

SEM NamedTypes
  | Cons lhs.pps = @hd.pp : @tl.pps
  | Nil  lhs.pps = []

SEM Decls
  | Cons lhs.pps = @hd.pp : @tl.pps
  | Nil  lhs.pps = []

SEM Chunks
  | Cons lhs.pps = @hd.pps ++ @tl.pps
  | Nil  lhs.pps = []

SEM Patterns
  | Cons lhs.pps = @hd.pp : @tl.pps
  | Nil  lhs.pps = []

--
-- Individual cases
--

SEM Chunk
  | Chunk      lhs.pps     =  @comment.pp
                              :  @info.pps
                              ++ @dataDef.pps
                              ++ @semDom.pps
                              ++ @semFunctions.pps
                              ++ @semWrapper.pps
                              ++ @cataFun.pps
                              ++ [Map.findWithDefault empty (BlockOther, Just $ identifier @name) @lhs.textBlockMap]

SEM Decl
  | Decl       lhs.pp      = if @lhs.isToplevel
                             then "let" >#< @left.pp >#< "="
                                  >-< indent 4 @rhs.pp >#< ";;"
                             else "let" >#< @left.pp >#< "="
                                  >-< indent 4 @rhs.pp >#< "in"
  | Bind       lhs.pp      = error "pp of Decl.Bind not supported"
  | BindLet    lhs.pp      = error "pp of Decl.BindLet not supported"
  | Data       lhs.pp      = "type" >#< hv_sp (map (\p -> "'" >|< p) @params ++ [text $ toOcamlTC @name])
                             >#<  ( case @alts.pps of
                                          [] -> empty
                                          (x:xs) ->              "=" >#<  x
                                                 >-< vlist (map ("|" >#<) xs)
                                  )
                             >#< ";;"
  | NewType    lhs.pp      = error "pp of Decl.NewType not supported"
  | Type       lhs.pp      = "type" >#< hv_sp (map (\p -> "'" >|< p) @params ++ [text $ toOcamlTC @name]) >#< "=" >#<  @tp.pp >#< ";;"
  | TSig       lhs.pp      = "(*" >#< @name >#< ":" >#< @tp.pp >#< "*)"
  | Comment    lhs.pp      = if '\n' `elem` @txt
                               then "(* " >-< vlist (lines @txt) >-< "*)"
                               else "(*" >#< @txt >#< "*)"
  | PragmaDecl lhs.pp      = error "pp of Decl.PragmaDecl not supported"


  SEM Expr
    | Let        lhs.pp      = pp_parens $ vlist (@decls.pps ++ [@body.pp])
    | Case       lhs.pp      = pp_parens ( "match" >#< @expr.pp >#< "with"
                                         >-< indent 2 ( case @alts.pps of
                                                          [] -> empty
                                                          (x:xs) -> " " >#<  x
                                                                    >-< vlist (map ("|" >#<) xs)
                                                      )
                                         )
    | Do         lhs.pp      = error "pp of Expr.Do not supported"
    | Lambda     lhs.pp      = pp_parens ( pp "fun" >#< hv_sp @args.pps >#< "->"
                                         >-< indent 2 @body.pp )
    | TupleExpr  lhs.pp      = ppTuple False @exprs.pps
    | UnboxedTupleExpr  lhs.pp = error "pp of Expr.UnboxedTupleExpr not supported"
    | App        lhs.pp      = pp_parens $ @name >#< hv_sp @args.pps
    | SimpleExpr lhs.pp      = text @txt
    | TextExpr   lhs.pp      = vlist (map text @lns)
    | Trace      lhs.pp      = @expr.pp
    | PragmaExpr lhs.pp      = @expr.pp
    | LineExpr   lhs.pp      = @expr.pp
    | TypedExpr  lhs.pp      = @expr.pp

SEM Lhs
  | Pattern3   lhs.pp      = @pat3.pp
  | Pattern3SM lhs.pp      = error "pp of Lhs.Pattern3SM not supported"
  | TupleLhs   lhs.pp      = ppTuple False (map text @comps)
  | UnboxedTupleLhs   lhs.pp      = error "pp of Lhs.UnboxedTupleLhs not supported"
  | Fun        lhs.pp      = @name >#< hv_sp @args.pps
  | Unwrap     lhs.pp      = pp_parens (@name >#< @sub.pp)

SEM Type
  | Arr        lhs.pp = pp_parens (@left.pp >#< "->" >#< @right.pp)
  | CtxApp     lhs.pp = error "pp of Type.CtxApp not supported"
  | TypeApp    lhs.pp = pp_parens (hv_sp (@args.pps ++ [@func.pp]))
  | TupleType  lhs.pp = pp_block "(" ")" "," @tps.pps
  | UnboxedTupleType
               lhs.pp = error "pp of Type.UnboxedTupleType is not supported"
  | List       lhs.pp = @tp.pp >#< "list"
  | SimpleType lhs.pp = text @txt
  | NontermType lhs.pp = pp_block "(" ")" " " (map text @params ++ [text $ toOcamlTC @name])
  | TMaybe     lhs.pp = @tp.pp >#< "opt"
  | TEither    lhs.pp = error "pp of Type.TEither is not supported"
  | TMap       lhs.pp = error "pp of Type.TMap is not supported"
  | TIntMap    lhs.pp = error "pp of Type.TIntMap is not supported"
  | TSet       lhs.pp = error "pp of Type.TSet is not supported"
  | TIntSet    lhs.pp = error "pp of Type.TIntSet is not supported"

{
toOcamlTC :: String -> String
toOcamlTC (c:cs) = toLower c : cs
toOcamlTC xs = xs
}

SEM CaseAlt
  | CaseAlt    lhs.pp      = @left.pp >#< "->" >#< @expr.pp

SEM DataAlt
  | DataAlt    lhs.pp      = @name >#< "of" >#< pp_block "" "" " * " (map pp_parens @args.pps)
  | Record     lhs.pp      = pp_block "{" "}" ";" @args.pps

SEM NamedType
  | Named      lhs.pp      = @name >#< ":" >#< @tp.pp

SEM Pattern
  | Constr  lhs.pp     = pp_parens $ @name >#< hv_sp @pats.pps
  | Product lhs.pp     = pp_block "(" ")" "," @pats.pps
  | Alias   -- assuming here that there is only an underscore under an alias
            lhs.pp     = if @pat.isUnderscore
                          then pp (attrname @lhs.options False @field @attr)
                          else error "pp of Pattern.Alias is only supported in the form (x@_)"
  | Irrefutable lhs.pp = error "pp of Pattern.Irrefutable not supported"
  | Underscore lhs.pp  = text "_"

SEM Pattern [ | | isUnderscore:{Bool}]
 | Constr      lhs.isUnderscore = False
 | Product     lhs.isUnderscore = False
 | Alias       lhs.isUnderscore = False
 | Underscore  lhs.isUnderscore = True

--
-- Determine if a declaration is toplevel
--

ATTR Chunks Chunk Decls Decl [ isToplevel : Bool | | ]
SEM Program
  | Program
      chunks.isToplevel = True

SEM Expr
  | Let
      decls.isToplevel = False
  | Do
      stmts.isToplevel = False