src/Tools/code/code_target.ML
changeset 27550 e97d61a67063
parent 27437 727297fcf7c8
child 27710 29702aa892a5
equal deleted inserted replaced
27549:0525f5785155 27550:e97d61a67063
    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