src/Tools/Code/code_target.ML
changeset 69998 c61f6bc9cf5c
parent 69906 55534affe445
child 69999 76554a0cafe3
equal deleted inserted replaced
69997:9c634887be9e 69998:c61f6bc9cf5c
   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 *)
   465       (fn () => dynamic_compilation_text prepared_serializer width prepared_program syms) ctxt
   462       (fn () => dynamic_compilation_text prepared_serializer width prepared_program syms) ctxt
   466   end;
   463   end;
   467 
   464 
   468 fun compilation_text ctxt target_name program syms =
   465 fun compilation_text ctxt target_name program syms =
   469   fst oo compilation_text' ctxt target_name NONE program syms
   466   fst oo compilation_text' ctxt target_name NONE program syms
   470   
   467 
   471 end; (* local *)
   468 end; (* local *)
   472 
   469 
   473 
   470 
   474 (* code generation *)
   471 (* code generation *)
   475 
   472