31 val allow_abort: string -> theory -> theory; |
31 val allow_abort: string -> theory -> theory; |
32 |
32 |
33 type serialization; |
33 type serialization; |
34 type serializer; |
34 type serializer; |
35 val add_target: string * serializer -> theory -> theory; |
35 val add_target: string * serializer -> theory -> theory; |
|
36 val extend_target: string * (string * (CodeThingol.program -> CodeThingol.program)) |
|
37 -> theory -> theory; |
36 val assert_target: theory -> string -> string; |
38 val assert_target: theory -> string -> string; |
37 val serialize: theory -> string -> string option -> Args.T list |
39 val serialize: theory -> string -> string option -> Args.T list |
38 -> CodeThingol.program -> string list -> serialization; |
40 -> CodeThingol.program -> string list -> serialization; |
39 val compile: serialization -> unit; |
41 val compile: serialization -> unit; |
40 val export: serialization -> unit; |
42 val export: serialization -> unit; |
129 type typ_syntax = int * ((fixity -> itype -> Pretty.T) |
131 type typ_syntax = int * ((fixity -> itype -> Pretty.T) |
130 -> fixity -> itype list -> Pretty.T); |
132 -> fixity -> itype list -> Pretty.T); |
131 type term_syntax = int * ((CodeName.var_ctxt -> fixity -> iterm -> Pretty.T) |
133 type term_syntax = int * ((CodeName.var_ctxt -> fixity -> iterm -> Pretty.T) |
132 -> thm -> bool -> CodeName.var_ctxt -> fixity -> (iterm * itype) list -> Pretty.T); |
134 -> thm -> bool -> CodeName.var_ctxt -> fixity -> (iterm * itype) list -> Pretty.T); |
133 |
135 |
134 |
|
135 (** theory data **) |
|
136 |
|
137 val target_SML = "SML"; |
|
138 val target_OCaml = "OCaml"; |
|
139 val target_Haskell = "Haskell"; |
|
140 |
|
141 datatype name_syntax_table = NameSyntaxTable of { |
136 datatype name_syntax_table = NameSyntaxTable of { |
142 class: class_syntax Symtab.table, |
137 class: class_syntax Symtab.table, |
143 inst: unit Symtab.table, |
138 inst: unit Symtab.table, |
144 tyco: typ_syntax Symtab.table, |
139 tyco: typ_syntax Symtab.table, |
145 const: term_syntax Symtab.table |
140 const: term_syntax Symtab.table |
146 }; |
141 }; |
|
142 |
|
143 |
|
144 (** theory data **) |
|
145 |
|
146 val target_SML = "SML"; |
|
147 val target_OCaml = "OCaml"; |
|
148 val target_Haskell = "Haskell"; |
147 |
149 |
148 fun mk_name_syntax_table ((class, inst), (tyco, const)) = |
150 fun mk_name_syntax_table ((class, inst), (tyco, const)) = |
149 NameSyntaxTable { class = class, inst = inst, tyco = tyco, const = const }; |
151 NameSyntaxTable { class = class, inst = inst, tyco = tyco, const = const }; |
150 fun map_name_syntax_table f (NameSyntaxTable { class, inst, tyco, const }) = |
152 fun map_name_syntax_table f (NameSyntaxTable { class, inst, tyco, const }) = |
151 mk_name_syntax_table (f ((class, inst), (tyco, const))); |
153 mk_name_syntax_table (f ((class, inst), (tyco, const))); |
170 -> (string -> term_syntax option) |
172 -> (string -> term_syntax option) |
171 -> CodeThingol.program |
173 -> CodeThingol.program |
172 -> string list (*selected statements*) |
174 -> string list (*selected statements*) |
173 -> serialization; |
175 -> serialization; |
174 |
176 |
|
177 datatype serializer_entry = Serializer of serializer |
|
178 | Extends of string * (CodeThingol.program -> CodeThingol.program); |
|
179 |
175 datatype target = Target of { |
180 datatype target = Target of { |
176 serial: serial, |
181 serial: serial, |
177 serializer: serializer, |
182 serializer: serializer_entry, |
178 reserved: string list, |
183 reserved: string list, |
179 includes: Pretty.T Symtab.table, |
184 includes: Pretty.T Symtab.table, |
180 name_syntax_table: name_syntax_table, |
185 name_syntax_table: name_syntax_table, |
181 module_alias: string Symtab.table |
186 module_alias: string Symtab.table |
182 }; |
187 }; |
184 fun mk_target ((serial, serializer), ((reserved, includes), (name_syntax_table, module_alias))) = |
189 fun mk_target ((serial, serializer), ((reserved, includes), (name_syntax_table, module_alias))) = |
185 Target { serial = serial, serializer = serializer, reserved = reserved, |
190 Target { serial = serial, serializer = serializer, reserved = reserved, |
186 includes = includes, name_syntax_table = name_syntax_table, module_alias = module_alias }; |
191 includes = includes, name_syntax_table = name_syntax_table, module_alias = module_alias }; |
187 fun map_target f ( Target { serial, serializer, reserved, includes, name_syntax_table, module_alias } ) = |
192 fun map_target f ( Target { serial, serializer, reserved, includes, name_syntax_table, module_alias } ) = |
188 mk_target (f ((serial, serializer), ((reserved, includes), (name_syntax_table, module_alias)))); |
193 mk_target (f ((serial, serializer), ((reserved, includes), (name_syntax_table, module_alias)))); |
189 fun merge_target target (Target { serial = serial1, serializer = serializer, |
194 fun merge_target strict target (Target { serial = serial1, serializer = serializer, |
190 reserved = reserved1, includes = includes1, |
195 reserved = reserved1, includes = includes1, |
191 name_syntax_table = name_syntax_table1, module_alias = module_alias1 }, |
196 name_syntax_table = name_syntax_table1, module_alias = module_alias1 }, |
192 Target { serial = serial2, serializer = _, |
197 Target { serial = serial2, serializer = _, |
193 reserved = reserved2, includes = includes2, |
198 reserved = reserved2, includes = includes2, |
194 name_syntax_table = name_syntax_table2, module_alias = module_alias2 }) = |
199 name_syntax_table = name_syntax_table2, module_alias = module_alias2 }) = |
195 if serial1 = serial2 then |
200 if serial1 = serial2 orelse not strict then |
196 mk_target ((serial1, serializer), |
201 mk_target ((serial1, serializer), |
197 ((merge (op =) (reserved1, reserved2), Symtab.merge (op =) (includes1, includes2)), |
202 ((merge (op =) (reserved1, reserved2), Symtab.merge (op =) (includes1, includes2)), |
198 (merge_name_syntax_table (name_syntax_table1, name_syntax_table2), |
203 (merge_name_syntax_table (name_syntax_table1, name_syntax_table2), |
199 Symtab.join (K snd) (module_alias1, module_alias2)) |
204 Symtab.join (K snd) (module_alias1, module_alias2)) |
200 )) |
205 )) |
206 type T = target Symtab.table * string list; |
211 type T = target Symtab.table * string list; |
207 val empty = (Symtab.empty, []); |
212 val empty = (Symtab.empty, []); |
208 val copy = I; |
213 val copy = I; |
209 val extend = I; |
214 val extend = I; |
210 fun merge _ ((target1, exc1) : T, (target2, exc2)) = |
215 fun merge _ ((target1, exc1) : T, (target2, exc2)) = |
211 (Symtab.join merge_target (target1, target2), Library.merge (op =) (exc1, exc2)); |
216 (Symtab.join (merge_target true) (target1, target2), Library.merge (op =) (exc1, exc2)); |
212 ); |
217 ); |
213 |
218 |
214 fun the_serializer (Target { serializer, ... }) = serializer; |
219 fun the_serializer (Target { serializer, ... }) = serializer; |
215 fun the_reserved (Target { reserved, ... }) = reserved; |
220 fun the_reserved (Target { reserved, ... }) = reserved; |
216 fun the_includes (Target { includes, ... }) = includes; |
221 fun the_includes (Target { includes, ... }) = includes; |
222 fun assert_target thy target = |
227 fun assert_target thy target = |
223 case Symtab.lookup (fst (CodeTargetData.get thy)) target |
228 case Symtab.lookup (fst (CodeTargetData.get thy)) target |
224 of SOME data => target |
229 of SOME data => target |
225 | NONE => error ("Unknown code target language: " ^ quote target); |
230 | NONE => error ("Unknown code target language: " ^ quote target); |
226 |
231 |
227 fun add_target (target, seri) thy = |
232 fun put_target (target, seri) thy = |
228 let |
233 let |
229 val _ = case Symtab.lookup (fst (CodeTargetData.get thy)) target |
234 val defined_target = is_some o Symtab.lookup (fst (CodeTargetData.get thy)); |
230 of SOME _ => warning ("Overwriting existing serializer " ^ quote target) |
235 val _ = case seri |
231 | NONE => (); |
236 of Extends (super, _) => if defined_target super then () |
|
237 else error ("No such target: " ^ quote super) |
|
238 | _ => (); |
|
239 val _ = if defined_target target |
|
240 then warning ("Overwriting existing target " ^ quote target) |
|
241 else (); |
232 in |
242 in |
233 thy |
243 thy |
234 |> (CodeTargetData.map o apfst oo Symtab.map_default) |
244 |> (CodeTargetData.map o apfst oo Symtab.map_default) |
235 (target, mk_target ((serial (), seri), (([], Symtab.empty), |
245 (target, mk_target ((serial (), seri), (([], Symtab.empty), |
236 (mk_name_syntax_table ((Symtab.empty, Symtab.empty), (Symtab.empty, Symtab.empty)), |
246 (mk_name_syntax_table ((Symtab.empty, Symtab.empty), (Symtab.empty, Symtab.empty)), |
237 Symtab.empty)))) |
247 Symtab.empty)))) |
238 ((map_target o apfst o apsnd o K) seri) |
248 ((map_target o apfst o apsnd o K) seri) |
239 end; |
249 end; |
240 |
250 |
|
251 fun add_target (target, seri) = put_target (target, Serializer seri); |
|
252 fun extend_target (target, (super, modify)) = |
|
253 put_target (target, Extends (super, modify)); |
|
254 |
241 fun map_target_data target f thy = |
255 fun map_target_data target f thy = |
242 let |
256 let |
243 val _ = assert_target thy target; |
257 val _ = assert_target thy target; |
244 in |
258 in |
245 thy |
259 thy |
253 fun map_name_syntax target = |
267 fun map_name_syntax target = |
254 map_target_data target o apsnd o apsnd o apfst o map_name_syntax_table; |
268 map_target_data target o apsnd o apsnd o apfst o map_name_syntax_table; |
255 fun map_module_alias target = |
269 fun map_module_alias target = |
256 map_target_data target o apsnd o apsnd o apsnd; |
270 map_target_data target o apsnd o apsnd o apsnd; |
257 |
271 |
258 fun invoke_serializer thy abortable serializer reserved includes |
272 fun invoke_serializer thy modify abortable serializer reserved includes |
259 module_alias class inst tyco const module args program1 cs1 = |
273 module_alias class inst tyco const module args program1 cs1 = |
260 let |
274 let |
|
275 val program2 = modify program1; |
261 val hidden = Symtab.keys class @ Symtab.keys inst @ Symtab.keys tyco @ Symtab.keys const; |
276 val hidden = Symtab.keys class @ Symtab.keys inst @ Symtab.keys tyco @ Symtab.keys const; |
262 val cs2 = subtract (op =) hidden cs1; |
277 val cs2 = subtract (op =) hidden cs1; |
263 val program2 = Graph.subgraph (not o member (op =) hidden) program1; |
278 val program3 = Graph.subgraph (not o member (op =) hidden) program2; |
264 val all_cs = Graph.all_succs program2 cs2; |
279 val all_cs = Graph.all_succs program2 cs2; |
265 val program3 = Graph.subgraph (member (op =) all_cs) program2; |
280 val program4 = Graph.subgraph (member (op =) all_cs) program3; |
266 val empty_funs = filter_out (member (op =) abortable) |
281 val empty_funs = filter_out (member (op =) abortable) |
267 (CodeThingol.empty_funs program3); |
282 (CodeThingol.empty_funs program3); |
268 val _ = if null empty_funs then () else error ("No defining equations for " |
283 val _ = if null empty_funs then () else error ("No defining equations for " |
269 ^ commas (map (CodeName.labelled_name thy) empty_funs)); |
284 ^ commas (map (CodeName.labelled_name thy) empty_funs)); |
270 in |
285 in |
271 serializer module args (CodeName.labelled_name thy) reserved includes |
286 serializer module args (CodeName.labelled_name thy) reserved includes |
272 (Symtab.lookup module_alias) (Symtab.lookup class) |
287 (Symtab.lookup module_alias) (Symtab.lookup class) |
273 (Symtab.lookup tyco) (Symtab.lookup const) |
288 (Symtab.lookup tyco) (Symtab.lookup const) |
274 program3 cs2 |
289 program4 cs2 |
275 end; |
290 end; |
276 |
291 |
277 fun mount_serializer thy alt_serializer target = |
292 fun mount_serializer thy alt_serializer target = |
278 let |
293 let |
279 val (targets, abortable) = CodeTargetData.get thy; |
294 val (targets, abortable) = CodeTargetData.get thy; |
280 val data = case Symtab.lookup targets target |
295 fun collapse_hierarchy target = |
281 of SOME data => data |
296 let |
282 | NONE => error ("Unknown code target language: " ^ quote target); |
297 val data = case Symtab.lookup targets target |
283 val serializer = the_default (the_serializer data) alt_serializer; |
298 of SOME data => data |
|
299 | NONE => error ("Unknown code target language: " ^ quote target); |
|
300 in case the_serializer data |
|
301 of Serializer _ => (I, data) |
|
302 | Extends (super, modify) => let |
|
303 val (modify', data') = collapse_hierarchy super |
|
304 in (modify' #> modify, merge_target false target (data', data)) end |
|
305 end; |
|
306 val (modify, data) = collapse_hierarchy target; |
|
307 val serializer = the_default (case the_serializer data |
|
308 of Serializer seri => seri) alt_serializer; |
284 val reserved = the_reserved data; |
309 val reserved = the_reserved data; |
285 val includes = Symtab.dest (the_includes data); |
310 val includes = Symtab.dest (the_includes data); |
286 val module_alias = the_module_alias data; |
311 val module_alias = the_module_alias data; |
287 val { class, inst, tyco, const } = the_name_syntax data; |
312 val { class, inst, tyco, const } = the_name_syntax data; |
288 in |
313 in |
289 invoke_serializer thy abortable serializer reserved |
314 invoke_serializer thy modify abortable serializer reserved |
290 includes module_alias class inst tyco const |
315 includes module_alias class inst tyco const |
291 end; |
316 end; |
292 |
317 |
293 fun serialize thy = mount_serializer thy NONE; |
318 fun serialize thy = mount_serializer thy NONE; |
294 |
319 |