211 |
211 |
212 (** theory data **) |
212 (** theory data **) |
213 |
213 |
214 type language = {serializer: serializer, literals: literals, |
214 type language = {serializer: serializer, literals: literals, |
215 check: {env_var: string, make_destination: Path.T -> Path.T, make_command: string -> string}, |
215 check: {env_var: string, make_destination: Path.T -> Path.T, make_command: string -> string}, |
216 evaluation_args: Token.T list}; |
216 evaluation_args: Token.T list}; |
217 |
217 |
218 type ancestry = (string * (Code_Thingol.program -> Code_Thingol.program)) list; |
218 type ancestry = (string * (Code_Thingol.program -> Code_Thingol.program)) list; |
219 |
219 |
220 val merge_ancestry : ancestry * ancestry -> ancestry = AList.join (op =) (K snd); |
220 val merge_ancestry : ancestry * ancestry -> ancestry = AList.join (op =) (K snd); |
221 |
221 |
230 Symtab.join (fn target_name => fn ((target1, data1), (target2, data2)) => |
230 Symtab.join (fn target_name => fn ((target1, data1), (target2, data2)) => |
231 if #serial target1 = #serial target2 then |
231 if #serial target1 = #serial target2 then |
232 ({serial = #serial target1, language = #language target1, |
232 ({serial = #serial target1, language = #language target1, |
233 ancestry = merge_ancestry (#ancestry target1, #ancestry target2)}, |
233 ancestry = merge_ancestry (#ancestry target1, #ancestry target2)}, |
234 Code_Printer.merge_data (data1, data2)) |
234 Code_Printer.merge_data (data1, data2)) |
235 else error ("Incompatible targets: " ^ quote target_name) |
235 else error ("Incompatible targets: " ^ quote target_name) |
236 ) (targets1, targets2) |
236 ) (targets1, targets2) |
237 ); |
237 ); |
238 |
238 |
239 fun exists_target thy = Symtab.defined (Targets.get thy); |
239 fun exists_target thy = Symtab.defined (Targets.get thy); |
240 fun lookup_target_data thy = Symtab.lookup (Targets.get thy); |
240 fun lookup_target_data thy = Symtab.lookup (Targets.get thy); |
245 |
245 |
246 fun fold1 f xs = fold f (tl xs) (hd xs); |
246 fun fold1 f xs = fold f (tl xs) (hd xs); |
247 |
247 |
248 fun join_ancestry thy target_name = |
248 fun join_ancestry thy target_name = |
249 let |
249 let |
250 val _ = assert_target thy target_name; |
250 val _ = assert_target thy target_name; |
251 val the_target_data = the o lookup_target_data thy; |
251 val the_target_data = the o lookup_target_data thy; |
252 val (target, this_data) = the_target_data target_name; |
252 val (target, this_data) = the_target_data target_name; |
253 val ancestry = #ancestry target; |
253 val ancestry = #ancestry target; |
254 val modifies = rev (map snd ancestry); |
254 val modifies = rev (map snd ancestry); |
255 val modify = fold (curry (op o)) modifies I; |
255 val modify = fold (curry (op o)) modifies I; |
262 val _ = if exists_target thy target_name |
262 val _ = if exists_target thy target_name |
263 then error ("Attempt to overwrite existing target " ^ quote target_name) |
263 then error ("Attempt to overwrite existing target " ^ quote target_name) |
264 else (); |
264 else (); |
265 in |
265 in |
266 thy |
266 thy |
267 |> (Targets.map o Symtab.update) (target_name, (target, Code_Printer.empty_data)) |
267 |> (Targets.map o Symtab.update) (target_name, (target, Code_Printer.empty_data)) |
268 end; |
268 end; |
269 |
269 |
270 fun add_language (target_name, language) = |
270 fun add_language (target_name, language) = |
271 allocate_target target_name {serial = serial (), language = language, |
271 allocate_target target_name {serial = serial (), language = language, |
272 ancestry = []}; |
272 ancestry = []}; |
285 val ancestries = map #ancestry targets @ [initial_ancestry]; |
285 val ancestries = map #ancestry targets @ [initial_ancestry]; |
286 val ancestry = fold1 (fn ancestry' => fn ancestry => |
286 val ancestry = fold1 (fn ancestry' => fn ancestry => |
287 merge_ancestry (ancestry, ancestry')) ancestries; |
287 merge_ancestry (ancestry, ancestry')) ancestries; |
288 in |
288 in |
289 allocate_target target_name {serial = #serial supremum, language = #language supremum, |
289 allocate_target target_name {serial = #serial supremum, language = #language supremum, |
290 ancestry = ancestry} thy |
290 ancestry = ancestry} thy |
291 end; |
291 end; |
292 |
292 |
293 fun map_data target_name f thy = |
293 fun map_data target_name f thy = |
294 let |
294 let |
295 val _ = assert_target thy target_name; |
295 val _ = assert_target thy target_name; |
296 in |
296 in |
297 thy |
297 thy |
298 |> (Targets.map o Symtab.map_entry target_name o apsnd o Code_Printer.map_data) f |
298 |> (Targets.map o Symtab.map_entry target_name o apsnd o Code_Printer.map_data) f |
299 end; |
299 end; |
300 |
300 |
301 fun map_reserved target_name = |
301 fun map_reserved target_name = map_data target_name o @{apply 3(1)}; |
302 map_data target_name o @{apply 3 (1)}; |
302 fun map_identifiers target_name = map_data target_name o @{apply 3(2)}; |
303 fun map_identifiers target_name = |
303 fun map_printings target_name = map_data target_name o @{apply 3(3)}; |
304 map_data target_name o @{apply 3 (2)}; |
|
305 fun map_printings target_name = |
|
306 map_data target_name o @{apply 3 (3)}; |
|
307 |
304 |
308 |
305 |
309 (** serializer usage **) |
306 (** serializer usage **) |
310 |
307 |
311 (* technical aside: pretty printing width *) |
308 (* technical aside: pretty printing width *) |