Import Debian changes 20180207-1
[hcoop/debian/mlton.git] / mlton / xml / sxml-simplify.fun
CommitLineData
7f918cf1
CE
1(* Copyright (C) 1999-2008 Henry Cejtin, Matthew Fluet, Suresh
2 * Jagannathan, and Stephen Weeks.
3 * Copyright (C) 1997-2000 NEC Research Institute.
4 *
5 * MLton is released under a BSD-style license.
6 * See the file MLton-LICENSE for details.
7 *)
8
9functor SxmlSimplify (S: SXML_SIMPLIFY_STRUCTS): SXML_SIMPLIFY =
10struct
11
12open S
13
14structure ImplementExceptions = ImplementExceptions (open S)
15structure ImplementSuffix = ImplementSuffix (open S)
16structure Polyvariance = Polyvariance (open S)
17(* structure Uncurry = Uncurry (open S) *)
18structure CPSTransform = CPSTransform (open S)
19
20fun polyvariance (hofo, rounds, small, product) p =
21 Ref.fluidLet
22 (Control.polyvariance,
23 SOME {hofo = hofo, rounds = rounds, small = small, product = product},
24 fn () => Polyvariance.transform p)
25
26type pass = {name: string,
27 doit: Program.t -> Program.t,
28 execute: bool}
29
30val sxmlPassesDefault =
31 {name = "sxmlShrink1", doit = S.shrink, execute = true} ::
32 {name = "implementSuffix", doit = ImplementSuffix.transform, execute = true} ::
33 {name = "sxmlShrink2", doit = S.shrink, execute = true} ::
34 {name = "implementExceptions", doit = ImplementExceptions.transform, execute = true} ::
35 {name = "sxmlShrink3", doit = S.shrink, execute = true} ::
36 (* {name = "uncurry", doit = Uncurry.transform, execute = true} :: *)
37 (* {name = "sxmlShrink4", doit = S.shrink, execute = true} :: *)
38 {name = "polyvariance", doit = Polyvariance.transform, execute = true} ::
39 {name = "sxmlShrink4", doit = S.shrink, execute = true} ::
40 nil
41
42val sxmlPassesCpsTransform =
43 sxmlPassesDefault @
44 {name = "cpsTransform", doit = CPSTransform.transform, execute = true} ::
45 {name = "cpsSxmlShrink5", doit = S.shrink, execute = true} ::
46 {name = "cpsPolyvariance", doit = Polyvariance.transform, execute = true} ::
47 {name = "cpsSxmlShrink6", doit = S.shrink, execute = true} ::
48 nil
49
50val sxmlPassesMinimal =
51 {name = "implementSuffix", doit = ImplementSuffix.transform, execute = true} ::
52 {name = "implementExceptions", doit = ImplementExceptions.transform, execute = true} ::
53 nil
54
55val sxmlPasses : pass list ref = ref sxmlPassesDefault
56
57local
58 type passGen = string -> pass option
59
60 fun mkSimplePassGen (name, doit): passGen =
61 let val count = Counter.new 1
62 in fn s => if s = name
63 then SOME {name = name ^ "#" ^
64 (Int.toString (Counter.next count)),
65 doit = doit,
66 execute = true}
67 else NONE
68 end
69
70 val polyvariancePassGen =
71 let
72 val count = Counter.new 1
73 fun nums s =
74 if s = ""
75 then SOME []
76 else if String.sub (s, 0) = #"("
77 andalso String.sub (s, String.size s - 1)= #")"
78 then let
79 val s = String.dropFirst (String.dropLast s)
80 in
81 case List.fold (String.split (s, #","), SOME [],
82 fn (s,SOME nums) => (case Int.fromString s of
83 SOME i => SOME (i::nums)
84 | NONE => NONE)
85 | (_, NONE) => NONE) of
86 SOME (l as _::_) => SOME (List.rev l)
87 | _ => NONE
88 end
89 else NONE
90 in
91 fn s =>
92 if String.hasPrefix (s, {prefix = "polyvariance"})
93 then let
94 fun mk (hofo, rounds, small, product) =
95 SOME {name = concat ["polyvariance(",
96 Bool.toString hofo, ",",
97 Int.toString rounds, ",",
98 Int.toString small, ",",
99 Int.toString product, ")#",
100 Int.toString (Counter.next count)],
101 doit = polyvariance (hofo, rounds, small, product),
102 execute = true}
103 val s = String.dropPrefix (s, String.size "polyvariance")
104 in
105 case nums s of
106 SOME [] => mk (true, 2, 30, 300)
107 | SOME [hofo, rounds, small, product] =>
108 mk (hofo <> 0, rounds, small, product)
109 | _ => NONE
110 end
111 else NONE
112 end
113
114 val passGens =
115 polyvariancePassGen ::
116 (List.map([("sxmlShrink", S.shrink),
117 ("implementExceptions", ImplementExceptions.transform),
118 ("implementSuffix", ImplementSuffix.transform)],
119 mkSimplePassGen))
120in
121 fun sxmlPassesSetCustom s =
122 Exn.withEscape
123 (fn esc =>
124 (let val ss = String.split (s, #":")
125 in
126 sxmlPasses :=
127 List.map(ss, fn s =>
128 case (List.peekMap (passGens, fn gen => gen s)) of
129 NONE => esc (Result.No s)
130 | SOME pass => pass)
131 ; Result.Yes ()
132 end))
133end
134
135val sxmlPassesString = ref "default"
136val sxmlPassesGet = fn () => !sxmlPassesString
137val sxmlPassesSet = fn s =>
138 let
139 val _ = sxmlPassesString := s
140 in
141 case s of
142 "default" => (sxmlPasses := sxmlPassesDefault
143 ; Result.Yes ())
144 | "cpsTransform" => (sxmlPasses := sxmlPassesCpsTransform
145 ; Result.Yes ())
146 | "minimal" => (sxmlPasses := sxmlPassesMinimal
147 ; Result.Yes ())
148 | _ => sxmlPassesSetCustom s
149 end
150val _ = List.push (Control.optimizationPasses,
151 {il = "sxml", get = sxmlPassesGet, set = sxmlPassesSet})
152
153fun pass ({name, doit}, p) =
154 let
155 val _ =
156 let open Control
157 in maybeSaveToFile
158 ({name = name,
159 suffix = "pre.sxml"},
160 Control.No, p, Control.Layouts Program.layouts)
161 end
162 val p =
163 Control.passTypeCheck
164 {display = Control.Layouts Program.layouts,
165 name = name,
166 stats = Program.layoutStats,
167 style = Control.No,
168 suffix = "post.sxml",
169 thunk = fn () => doit p,
170 typeCheck = typeCheck}
171 in
172 p
173 end
174fun maybePass ({name, doit, execute}, p) =
175 if List.foldr (!Control.executePasses, execute, fn ((re, new), old) =>
176 if Regexp.Compiled.matchesAll (re, name)
177 then new
178 else old)
179 then pass ({name = name, doit = doit}, p)
180 else (Control.messageStr (Control.Pass, name ^ " skipped"); p)
181fun simplify p =
182 let
183 fun simplify' p =
184 List.fold
185 (!sxmlPasses, p, fn ({name, doit, execute}, p) =>
186 maybePass ({name = name, doit = doit, execute = execute}, p))
187 val p = simplify' p
188 in
189 p
190 end
191
192val simplify = fn p => let
193 (* Always want to type check the initial and final XML
194 * programs, even if type checking is turned off, just
195 * to catch bugs.
196 *)
197 val _ = typeCheck p
198 val p' = simplify p
199 val _ = typeCheck p'
200 in
201 p'
202 end
203end