src/Tools/Code/code_scala.ML
changeset 38970 53d1ee3d98b8
parent 38966 68853347ba37
child 38971 5d49165a192e
equal deleted inserted replaced
38967:b912278b719f 38970:53d1ee3d98b8
   279               str "=", str "new", print_dicttyp tyvars classtyp, str "{"], str "}")
   279               str "=", str "new", print_dicttyp tyvars classtyp, str "{"], str "}")
   280                 (map print_classparam_instance (classparam_instances @ further_classparam_instances))
   280                 (map print_classparam_instance (classparam_instances @ further_classparam_instances))
   281           end;
   281           end;
   282   in print_stmt end;
   282   in print_stmt end;
   283 
   283 
   284 local
       
   285 
       
   286 (* hierarchical module name space *)
       
   287 
       
   288 datatype node =
       
   289     Dummy
       
   290   | Stmt of Code_Thingol.stmt
       
   291   | Module of (string list * (string * node) Graph.T);
       
   292 
       
   293 in
       
   294 
       
   295 fun scala_program_of_program labelled_name reserved module_alias program =
   284 fun scala_program_of_program labelled_name reserved module_alias program =
   296   let
   285   let
   297 
       
   298     (* building module name hierarchy *)
       
   299     fun alias_fragments name = case module_alias name
       
   300      of SOME name' => Long_Name.explode name'
       
   301       | NONE => map (fn name => fst (yield_singleton Name.variants name reserved))
       
   302           (Long_Name.explode name);
       
   303     val module_names = Graph.fold (insert (op =) o fst o dest_name o fst) program [];
       
   304     val fragments_tab = fold (fn name => Symtab.update
       
   305       (name, alias_fragments name)) module_names Symtab.empty;
       
   306     val dest_name = Code_Printer.dest_name #>> (the o Symtab.lookup fragments_tab);
       
   307 
       
   308     (* building empty module hierarchy *)
       
   309     val empty_module = ([], Graph.empty);
       
   310     fun map_module f (Module content) = Module (f content);
       
   311     fun change_module [] = I
       
   312       | change_module (name_fragment :: name_fragments) =
       
   313           apsnd o Graph.map_node name_fragment o apsnd o map_module
       
   314             o change_module name_fragments;
       
   315     fun ensure_module name_fragment (implicits, nodes) =
       
   316       if can (Graph.get_node nodes) name_fragment then (implicits, nodes)
       
   317       else (implicits,
       
   318         nodes |> Graph.new_node (name_fragment, (name_fragment, Module empty_module)));
       
   319     fun allocate_module [] = I
       
   320       | allocate_module (name_fragment :: name_fragments) =
       
   321           ensure_module name_fragment
       
   322           #> (apsnd o Graph.map_node name_fragment o apsnd o map_module o allocate_module) name_fragments;
       
   323     val empty_program = Symtab.fold (fn (_, fragments) => allocate_module fragments)
       
   324       fragments_tab empty_module;
       
   325 
       
   326     (* distribute statements over hierarchy *)
       
   327     fun add_stmt name stmt =
       
   328       let
       
   329         val (name_fragments, base) = dest_name name;
       
   330         fun is_classinst stmt = case stmt
       
   331          of Code_Thingol.Classinst _ => true
       
   332           | _ => false;
       
   333         val implicit_deps = filter (is_classinst o Graph.get_node program)
       
   334           (Graph.imm_succs program name);
       
   335       in
       
   336         change_module name_fragments (fn (implicits, nodes) =>
       
   337           (union (op =) implicit_deps implicits, Graph.new_node (name, (base, Stmt stmt)) nodes))
       
   338       end;
       
   339     fun add_dependency name name' =
       
   340       let
       
   341         val (name_fragments, base) = dest_name name;
       
   342         val (name_fragments', base') = dest_name name';
       
   343         val (name_fragments_common, (diff, diff')) =
       
   344           chop_prefix (op =) (name_fragments, name_fragments');
       
   345         val dep = if null diff then (name, name') else (hd diff, hd diff')
       
   346       in (change_module name_fragments_common o apsnd) (Graph.add_edge dep) end;
       
   347     val proto_program = empty_program
       
   348       |> Graph.fold (fn (name, (stmt, _)) => add_stmt name stmt) program
       
   349       |> Graph.fold (fn (name, (_, (_, names))) => fold (add_dependency name) names) program;
       
   350 
       
   351     (* name declarations *)
       
   352     fun namify_module name_fragment ((nsp_class, nsp_object), nsp_common) =
   286     fun namify_module name_fragment ((nsp_class, nsp_object), nsp_common) =
   353       let
   287       let
   354         val declare = Name.declare name_fragment;
   288         val declare = Name.declare name_fragment;
   355       in (name_fragment, ((declare nsp_class, declare nsp_object), declare nsp_common)) end;
   289       in (name_fragment, ((declare nsp_class, declare nsp_object), declare nsp_common)) end;
   356     fun namify_class base ((nsp_class, nsp_object), nsp_common) =
   290     fun namify_class base ((nsp_class, nsp_object), nsp_common) =
   374       | namify_stmt (Code_Thingol.Datatypecons _) = namify_common true
   308       | namify_stmt (Code_Thingol.Datatypecons _) = namify_common true
   375       | namify_stmt (Code_Thingol.Class _) = namify_class
   309       | namify_stmt (Code_Thingol.Class _) = namify_class
   376       | namify_stmt (Code_Thingol.Classrel _) = namify_object
   310       | namify_stmt (Code_Thingol.Classrel _) = namify_object
   377       | namify_stmt (Code_Thingol.Classparam _) = namify_object
   311       | namify_stmt (Code_Thingol.Classparam _) = namify_object
   378       | namify_stmt (Code_Thingol.Classinst _) = namify_common false;
   312       | namify_stmt (Code_Thingol.Classinst _) = namify_common false;
   379     fun make_declarations nsps (implicits, nodes) =
   313     fun memorize_implicits name =
   380       let
   314       let
   381         val (module_fragments, stmt_names) = List.partition
   315         fun is_classinst stmt = case stmt
   382           (fn name_fragment => case Graph.get_node nodes name_fragment
   316          of Code_Thingol.Classinst _ => true
   383             of (_, Module _) => true | _ => false) (Graph.keys nodes);
   317           | _ => false;
   384         fun modify_stmt (Stmt (Code_Thingol.Datatypecons _)) = Dummy
   318         val implicits = filter (is_classinst o Graph.get_node program)
   385           | modify_stmt (Stmt (Code_Thingol.Classrel _)) = Dummy
   319           (Graph.imm_succs program name);
   386           | modify_stmt (Stmt (Code_Thingol.Classparam _)) = Dummy
   320       in union (op =) implicits end;
   387           | modify_stmt stmt = stmt;
   321   in
   388         fun declare namify modify name (nsps, nodes) =
   322     Code_Namespace.hierarchical_program labelled_name { module_alias = module_alias, reserved = reserved,
   389           let
   323       empty_nsp = ((reserved, reserved), reserved), namify_module = namify_module, namify_stmt = namify_stmt,
   390             val (base, node) = Graph.get_node nodes name;
   324       cyclic_modules = true, empty_data = [], memorize_data = memorize_implicits } program
   391             val (base', nsps') = namify node base nsps;
   325   end;
   392             val nodes' = Graph.map_node name (K (base', modify node)) nodes;
       
   393           in (nsps', nodes') end;
       
   394         val (nsps', nodes') = (nsps, nodes)
       
   395           |> fold (declare (K namify_module) I) module_fragments
       
   396           |> fold (declare (namify_stmt o (fn Stmt stmt => stmt)) modify_stmt) stmt_names;
       
   397         val nodes'' = nodes'
       
   398           |> fold (fn name_fragment => (Graph.map_node name_fragment
       
   399               o apsnd o map_module) (make_declarations nsps')) module_fragments;
       
   400       in (implicits, nodes'') end;
       
   401     val (_, sca_program) = make_declarations ((reserved, reserved), reserved) proto_program;
       
   402 
       
   403     (* deresolving *)
       
   404     fun deresolver prefix_fragments name =
       
   405       let
       
   406         val (name_fragments, _) = dest_name name;
       
   407         val (_, (_, remainder)) = chop_prefix (op =) (prefix_fragments, name_fragments);
       
   408         val nodes = fold (fn name_fragment => fn nodes => case Graph.get_node nodes name_fragment
       
   409          of (_, Module (_, nodes)) => nodes) name_fragments sca_program;
       
   410         val (base', _) = Graph.get_node nodes name;
       
   411       in Long_Name.implode (remainder @ [base']) end
       
   412         handle Graph.UNDEF _ => error ("Unknown statement name: " ^ labelled_name name);
       
   413 
       
   414   in (deresolver, sca_program) end;
       
   415 
   326 
   416 fun serialize_scala { labelled_name, reserved_syms, includes,
   327 fun serialize_scala { labelled_name, reserved_syms, includes,
   417     module_alias, class_syntax, tyco_syntax, const_syntax, program,
   328     module_alias, class_syntax, tyco_syntax, const_syntax, program,
   418     names, presentation_names } =
   329     names, presentation_names } =
   419   let
   330   let
   420 
   331 
   421     (* build program *)
   332     (* build program *)
   422     val reserved = fold (insert (op =) o fst) includes reserved_syms;
   333     val reserved = fold (insert (op =) o fst) includes reserved_syms;
   423     val (deresolver, sca_program) = scala_program_of_program labelled_name
   334     val { deresolver, hierarchical_program = sca_program } =
   424       (Name.make_context reserved) module_alias program;
   335       scala_program_of_program labelled_name (Name.make_context reserved) module_alias program;
   425 
   336 
   426     (* print statements *)
   337     (* print statements *)
   427     fun lookup_constr tyco constr = case Graph.get_node program tyco
   338     fun lookup_constr tyco constr = case Graph.get_node program tyco
   428      of Code_Thingol.Datatype (_, (_, constrs)) =>
   339      of Code_Thingol.Datatype (_, (_, constrs)) =>
   429           the (AList.lookup (op = o apsnd fst) constrs constr);
   340           the (AList.lookup (op = o apsnd fst) constrs constr);
   452     fun print_implicit prefix_fragments implicit =
   363     fun print_implicit prefix_fragments implicit =
   453       let
   364       let
   454         val s = deresolver prefix_fragments implicit;
   365         val s = deresolver prefix_fragments implicit;
   455       in if length (Long_Name.explode s) = 1 then NONE else SOME (str s) end;
   366       in if length (Long_Name.explode s) = 1 then NONE else SOME (str s) end;
   456     fun print_node _ (_, Dummy) = NONE
   367     fun print_node _ (_, Dummy) = NONE
   457       | print_node prefix_fragments (name, Stmt stmt) =
   368       | print_node prefix_fragments (name, Code_Namespace.Stmt stmt) =
   458           if null presentation_names
   369           if null presentation_names
   459           orelse member (op =) presentation_names name
   370           orelse member (op =) presentation_names name
   460           then SOME (print_stmt (deresolver prefix_fragments, deresolver []) (name, stmt))
   371           then SOME (print_stmt (deresolver prefix_fragments, deresolver []) (name, stmt))
   461           else NONE
   372           else NONE
   462       | print_node prefix_fragments (name_fragment, Module (implicits, nodes)) =
   373       | print_node prefix_fragments (name_fragment, Code_Namespace.Module (implicits, nodes)) =
   463           if null presentation_names
   374           if null presentation_names
   464           then
   375           then
   465             let
   376             let
   466               val prefix_fragments' = prefix_fragments @ [name_fragment];
   377               val prefix_fragments' = prefix_fragments @ [name_fragment];
   467             in
   378             in
   483     fun write width NONE = writeln_pretty width
   394     fun write width NONE = writeln_pretty width
   484       | write width (SOME p) = File.write p o string_of_pretty width;
   395       | write width (SOME p) = File.write p o string_of_pretty width;
   485   in
   396   in
   486     Code_Target.serialization write (rpair [] oo string_of_pretty) p
   397     Code_Target.serialization write (rpair [] oo string_of_pretty) p
   487   end;
   398   end;
   488 
       
   489 end; (*local*)
       
   490 
   399 
   491 val serializer : Code_Target.serializer =
   400 val serializer : Code_Target.serializer =
   492   Code_Target.parse_args (Scan.succeed ()) #> K serialize_scala;
   401   Code_Target.parse_args (Scan.succeed ()) #> K serialize_scala;
   493 
   402 
   494 val literals = let
   403 val literals = let