simple inheritance concept
authorhaftmann
Fri, 11 Jul 2008 09:02:33 +0200
changeset 27550 e97d61a67063
parent 27549 0525f5785155
child 27551 9a5543d4cc24
simple inheritance concept
src/Tools/code/code_target.ML
--- a/src/Tools/code/code_target.ML	Fri Jul 11 09:02:32 2008 +0200
+++ b/src/Tools/code/code_target.ML	Fri Jul 11 09:02:33 2008 +0200
@@ -33,6 +33,8 @@
   type serialization;
   type serializer;
   val add_target: string * serializer -> theory -> theory;
+  val extend_target: string * (string * (CodeThingol.program -> CodeThingol.program))
+    -> theory -> theory;
   val assert_target: theory -> string -> string;
   val serialize: theory -> string -> string option -> Args.T list
     -> CodeThingol.program -> string list -> serialization;
@@ -131,6 +133,13 @@
 type term_syntax = int * ((CodeName.var_ctxt -> fixity -> iterm -> Pretty.T)
   -> thm -> bool -> CodeName.var_ctxt -> fixity -> (iterm * itype) list -> Pretty.T);
 
+datatype name_syntax_table = NameSyntaxTable of {
+  class: class_syntax Symtab.table,
+  inst: unit Symtab.table,
+  tyco: typ_syntax Symtab.table,
+  const: term_syntax Symtab.table
+};
+
 
 (** theory data **)
 
@@ -138,13 +147,6 @@
 val target_OCaml = "OCaml";
 val target_Haskell = "Haskell";
 
-datatype name_syntax_table = NameSyntaxTable of {
-  class: class_syntax Symtab.table,
-  inst: unit Symtab.table,
-  tyco: typ_syntax Symtab.table,
-  const: term_syntax Symtab.table
-};
-
 fun mk_name_syntax_table ((class, inst), (tyco, const)) =
   NameSyntaxTable { class = class, inst = inst, tyco = tyco, const = const };
 fun map_name_syntax_table f (NameSyntaxTable { class, inst, tyco, const }) =
@@ -172,9 +174,12 @@
   -> string list                        (*selected statements*)
   -> serialization;
 
+datatype serializer_entry = Serializer of serializer
+  | Extends of string * (CodeThingol.program -> CodeThingol.program);
+
 datatype target = Target of {
   serial: serial,
-  serializer: serializer,
+  serializer: serializer_entry,
   reserved: string list,
   includes: Pretty.T Symtab.table,
   name_syntax_table: name_syntax_table,
@@ -186,13 +191,13 @@
     includes = includes, name_syntax_table = name_syntax_table, module_alias = module_alias };
 fun map_target f ( Target { serial, serializer, reserved, includes, name_syntax_table, module_alias } ) =
   mk_target (f ((serial, serializer), ((reserved, includes), (name_syntax_table, module_alias))));
-fun merge_target target (Target { serial = serial1, serializer = serializer,
+fun merge_target strict target (Target { serial = serial1, serializer = serializer,
   reserved = reserved1, includes = includes1,
   name_syntax_table = name_syntax_table1, module_alias = module_alias1 },
     Target { serial = serial2, serializer = _,
       reserved = reserved2, includes = includes2,
       name_syntax_table = name_syntax_table2, module_alias = module_alias2 }) =
-  if serial1 = serial2 then
+  if serial1 = serial2 orelse not strict then
     mk_target ((serial1, serializer),
       ((merge (op =) (reserved1, reserved2), Symtab.merge (op =) (includes1, includes2)),
         (merge_name_syntax_table (name_syntax_table1, name_syntax_table2),
@@ -208,7 +213,7 @@
   val copy = I;
   val extend = I;
   fun merge _ ((target1, exc1) : T, (target2, exc2)) =
-    (Symtab.join merge_target (target1, target2), Library.merge (op =) (exc1, exc2));
+    (Symtab.join (merge_target true) (target1, target2), Library.merge (op =) (exc1, exc2));
 );
 
 fun the_serializer (Target { serializer, ... }) = serializer;
@@ -224,11 +229,16 @@
    of SOME data => target
     | NONE => error ("Unknown code target language: " ^ quote target);
 
-fun add_target (target, seri) thy =
+fun put_target (target, seri) thy =
   let
-    val _ = case Symtab.lookup (fst (CodeTargetData.get thy)) target
-     of SOME _ => warning ("Overwriting existing serializer " ^ quote target)
-      | NONE => ();
+    val defined_target = is_some o Symtab.lookup (fst (CodeTargetData.get thy));
+    val _ = case seri
+     of Extends (super, _) => if defined_target super then ()
+          else error ("No such target: " ^ quote super)
+      | _ => ();
+    val _ = if defined_target target
+      then warning ("Overwriting existing target " ^ quote target)
+      else ();
   in
     thy
     |> (CodeTargetData.map o apfst oo Symtab.map_default)
@@ -238,6 +248,10 @@
           ((map_target o apfst o apsnd o K) seri)
   end;
 
+fun add_target (target, seri) = put_target (target, Serializer seri);
+fun extend_target (target, (super, modify)) =
+  put_target (target, Extends (super, modify));
+
 fun map_target_data target f thy =
   let
     val _ = assert_target thy target;
@@ -255,14 +269,15 @@
 fun map_module_alias target =
   map_target_data target o apsnd o apsnd o apsnd;
 
-fun invoke_serializer thy abortable serializer reserved includes 
+fun invoke_serializer thy modify abortable serializer reserved includes 
     module_alias class inst tyco const module args program1 cs1 =
   let
+    val program2 = modify program1;
     val hidden = Symtab.keys class @ Symtab.keys inst @ Symtab.keys tyco @ Symtab.keys const;
     val cs2 = subtract (op =) hidden cs1;
-    val program2 = Graph.subgraph (not o member (op =) hidden) program1;
+    val program3 = Graph.subgraph (not o member (op =) hidden) program2;
     val all_cs = Graph.all_succs program2 cs2;
-    val program3 = Graph.subgraph (member (op =) all_cs) program2;
+    val program4 = Graph.subgraph (member (op =) all_cs) program3;
     val empty_funs = filter_out (member (op =) abortable)
       (CodeThingol.empty_funs program3);
     val _ = if null empty_funs then () else error ("No defining equations for "
@@ -271,22 +286,32 @@
     serializer module args (CodeName.labelled_name thy) reserved includes
       (Symtab.lookup module_alias) (Symtab.lookup class)
       (Symtab.lookup tyco) (Symtab.lookup const)
-      program3 cs2
+      program4 cs2
   end;
 
 fun mount_serializer thy alt_serializer target =
   let
     val (targets, abortable) = CodeTargetData.get thy;
-    val data = case Symtab.lookup targets target
-     of SOME data => data
-      | NONE => error ("Unknown code target language: " ^ quote target);
-    val serializer = the_default (the_serializer data) alt_serializer;
+    fun collapse_hierarchy target =
+      let
+        val data = case Symtab.lookup targets target
+         of SOME data => data
+          | NONE => error ("Unknown code target language: " ^ quote target);
+      in case the_serializer data
+       of Serializer _ => (I, data)
+        | Extends (super, modify) => let
+            val (modify', data') = collapse_hierarchy super
+          in (modify' #> modify, merge_target false target (data', data)) end
+      end;
+    val (modify, data) = collapse_hierarchy target;
+    val serializer = the_default (case the_serializer data
+     of Serializer seri => seri) alt_serializer;
     val reserved = the_reserved data;
     val includes = Symtab.dest (the_includes data);
     val module_alias = the_module_alias data;
     val { class, inst, tyco, const } = the_name_syntax data;
   in
-    invoke_serializer thy abortable serializer reserved
+    invoke_serializer thy modify abortable serializer reserved
       includes module_alias class inst tyco const
   end;