src/Tools/Code/code_namespace.ML
changeset 55680 bc5edc5dbf18
parent 55679 59244fc1a7ca
child 55681 7714287dc044
equal deleted inserted replaced
55679:59244fc1a7ca 55680:bc5edc5dbf18
   100     fun add_stmt sym stmt =
   100     fun add_stmt sym stmt =
   101       let
   101       let
   102         val (module_name, base) = prep_sym sym;
   102         val (module_name, base) = prep_sym sym;
   103       in
   103       in
   104         Graph.default_node (module_name, (Code_Symbol.Graph.empty, []))
   104         Graph.default_node (module_name, (Code_Symbol.Graph.empty, []))
   105         #> (Graph.map_node module_name o apfst) (Code_Symbol.Graph.new_node (sym, (base, (true, stmt))))
   105         #> (Graph.map_node module_name o apfst)
       
   106           (Code_Symbol.Graph.new_node (sym, (base, (true, stmt))))
   106       end;
   107       end;
   107     fun add_dep sym sym' =
   108     fun add_dep sym sym' =
   108       let
   109       let
   109         val (module_name, _) = prep_sym sym;
   110         val (module_name, _) = prep_sym sym;
   110         val (module_name', _) = prep_sym sym';
   111         val (module_name', _) = prep_sym sym';
   111       in if module_name = module_name'
   112       in if module_name = module_name'
   112         then (Graph.map_node module_name o apfst) (Code_Symbol.Graph.add_edge (sym, sym'))
   113         then (Graph.map_node module_name o apfst) (Code_Symbol.Graph.add_edge (sym, sym'))
   113         else (Graph.map_node module_name o apsnd) (AList.map_default (op =) (module_name', []) (insert (op =) sym'))
   114         else (Graph.map_node module_name o apsnd)
       
   115           (AList.map_default (op =) (module_name', []) (insert (op =) sym'))
   114       end;
   116       end;
   115     val proto_program = build_proto_program
   117     val proto_program = build_proto_program
   116       { empty = Graph.empty, add_stmt = add_stmt, add_dep = add_dep } program;
   118       { empty = Graph.empty, add_stmt = add_stmt, add_dep = add_dep } program;
   117 
   119 
   118     (* name declarations and statement modifications *)
   120     (* name declarations and statement modifications *)
   123       in (gr', nsp') end;
   125       in (gr', nsp') end;
   124     fun declarations gr = (gr, empty_nsp)
   126     fun declarations gr = (gr, empty_nsp)
   125       |> fold (fn sym => declare sym (Code_Symbol.Graph.get_node gr sym))
   127       |> fold (fn sym => declare sym (Code_Symbol.Graph.get_node gr sym))
   126           (prioritize sym_priority (Code_Symbol.Graph.keys gr))
   128           (prioritize sym_priority (Code_Symbol.Graph.keys gr))
   127       |> fst
   129       |> fst
   128       |> (Code_Symbol.Graph.map o K o apsnd)
   130       |> Code_Symbol.Graph.map_strong_conn (fn syms_bases_exports_stmts =>
   129         (fn (export, stmt) => Option.map (pair export) (modify_stmt stmt));
   131         map snd syms_bases_exports_stmts
       
   132         |> (map o apsnd) (fn (export, stmt) => Option.map (pair export) (modify_stmt stmt)));
   130     val flat_program = proto_program
   133     val flat_program = proto_program
   131       |> (Graph.map o K o apfst) declarations;
   134       |> (Graph.map o K o apfst) declarations;
   132 
   135 
   133     (* qualified and unqualified imports, deresolving *)
   136     (* qualified and unqualified imports, deresolving *)
   134     fun base_deresolver sym = fst (Code_Symbol.Graph.get_node
   137     fun base_deresolver sym = fst (Code_Symbol.Graph.get_node
   175 fun map_module [] = I
   178 fun map_module [] = I
   176   | map_module (name_fragment :: name_fragments) =
   179   | map_module (name_fragment :: name_fragments) =
   177       apsnd o Code_Symbol.Graph.map_node (Code_Symbol.Module name_fragment) o apsnd o map_module_content
   180       apsnd o Code_Symbol.Graph.map_node (Code_Symbol.Module name_fragment) o apsnd o map_module_content
   178         o map_module name_fragments;
   181         o map_module name_fragments;
   179 
   182 
       
   183 fun map_module_stmts f_module f_stmts sym_base_nodes =
       
   184   let
       
   185     val some_modules =
       
   186       sym_base_nodes
       
   187       |> map (fn (sym, (base, Module content)) => SOME (base, content) | _ => NONE)
       
   188       |> (burrow_options o map o apsnd) f_module;
       
   189     val some_export_stmts =
       
   190       sym_base_nodes
       
   191       |> map (fn (sym, (base, Stmt export_stmt)) => SOME ((sym, export_stmt), base) | _ => NONE)
       
   192       |> (burrow_options o burrow_fst) (fn [] => [] | xs => f_stmts xs)
       
   193   in
       
   194     map2 (fn SOME (base, content) => (K (base, Module content))
       
   195       | NONE => fn SOME (some_export_stmt, base) =>
       
   196           (base, case some_export_stmt of SOME export_stmt => Stmt export_stmt | NONE => Dummy))
       
   197       some_modules some_export_stmts
       
   198   end;
       
   199 
   180 fun hierarchical_program ctxt { module_name, reserved, identifiers, empty_nsp,
   200 fun hierarchical_program ctxt { module_name, reserved, identifiers, empty_nsp,
   181       namify_module, namify_stmt, cyclic_modules, empty_data, memorize_data, modify_stmts } program =
   201       namify_module, namify_stmt, cyclic_modules, empty_data, memorize_data, modify_stmts } program =
   182   let
   202   let
   183 
   203 
   184     (* building module name hierarchy *)
   204     (* building module name hierarchy *)
   207     (* distribute statements over hierarchy *)
   227     (* distribute statements over hierarchy *)
   208     fun add_stmt sym stmt =
   228     fun add_stmt sym stmt =
   209       let
   229       let
   210         val (name_fragments, base) = prep_sym sym;
   230         val (name_fragments, base) = prep_sym sym;
   211       in
   231       in
   212         (map_module name_fragments o apsnd) (Code_Symbol.Graph.new_node (sym, (base, Stmt (true, stmt))))
   232         (map_module name_fragments o apsnd)
       
   233           (Code_Symbol.Graph.new_node (sym, (base, Stmt (true, stmt))))
   213       end;
   234       end;
       
   235     fun add_edge_acyclic_error error_msg dep gr =
       
   236       Code_Symbol.Graph.add_edge_acyclic dep gr
       
   237         handle Graph.CYCLES _ => error (error_msg ())
   214     fun add_dep sym sym' =
   238     fun add_dep sym sym' =
   215       let
   239       let
   216         val (name_fragments, _) = prep_sym sym;
   240         val (name_fragments, _) = prep_sym sym;
   217         val (name_fragments', _) = prep_sym sym';
   241         val (name_fragments', _) = prep_sym sym';
   218         val (name_fragments_common, (diff, diff')) =
   242         val (name_fragments_common, (diff, diff')) =
   219           chop_prefix (op =) (name_fragments, name_fragments');
   243           chop_prefix (op =) (name_fragments, name_fragments');
   220         val is_module = not (null diff andalso null diff');
   244         val is_cross_module = not (null diff andalso null diff');
   221         val dep = pairself hd (map Code_Symbol.Module diff @ [sym], map Code_Symbol.Module diff' @ [sym']);
   245         val dep = pairself hd (map Code_Symbol.Module diff @ [sym], map Code_Symbol.Module diff' @ [sym']);
   222         val add_edge = if is_module andalso not cyclic_modules
   246         val add_edge = if is_cross_module andalso not cyclic_modules
   223           then (fn node => Code_Symbol.Graph.add_edge_acyclic dep node
   247           then add_edge_acyclic_error (fn _ => "Dependency "
   224             handle Graph.CYCLES _ => error ("Dependency "
   248             ^ Code_Symbol.quote ctxt sym ^ " -> "
   225               ^ Code_Symbol.quote ctxt sym ^ " -> "
   249             ^ Code_Symbol.quote ctxt sym'
   226               ^ Code_Symbol.quote ctxt sym'
   250             ^ " would result in module dependency cycle") dep
   227               ^ " would result in module dependency cycle"))
   251           else Code_Symbol.Graph.add_edge dep;
   228           else Code_Symbol.Graph.add_edge dep
       
   229       in (map_module name_fragments_common o apsnd) add_edge end;
   252       in (map_module name_fragments_common o apsnd) add_edge end;
   230     val proto_program = build_proto_program
   253     val proto_program = build_proto_program
   231       { empty = empty_program, add_stmt = add_stmt, add_dep = add_dep } program;
   254       { empty = empty_program, add_stmt = add_stmt, add_dep = add_dep } program;
   232 
   255 
   233     (* name declarations, data and statement modifications *)
   256     (* name declarations, data and statement modifications *)
   246             val nodes' = Code_Symbol.Graph.map_node sym (K (base', node)) nodes;
   269             val nodes' = Code_Symbol.Graph.map_node sym (K (base', node)) nodes;
   247           in (nsps', nodes') end;
   270           in (nsps', nodes') end;
   248         val (nsps', nodes') = (nsps, nodes)
   271         val (nsps', nodes') = (nsps, nodes)
   249           |> fold (declare (K namify_module)) module_fragments
   272           |> fold (declare (K namify_module)) module_fragments
   250           |> fold (declare (namify_stmt o snd o the_stmt)) stmt_syms;
   273           |> fold (declare (namify_stmt o snd o the_stmt)) stmt_syms;
   251         fun select_syms syms = case filter (member (op =) stmt_syms) syms
   274         fun modify_stmts' syms_stmts =
   252          of [] => NONE
       
   253           | syms => SOME syms;
       
   254         fun select_stmt (sym, (export, SOME stmt)) = SOME (sym, (export, stmt))
       
   255           | select_stmt _ = NONE;
       
   256         fun modify_stmts' syms =
       
   257           let
   275           let
   258             val (exports, stmts) = map_split (the_stmt o snd o Code_Symbol.Graph.get_node nodes) syms;
   276             val stmts' = modify_stmts syms_stmts
   259             val stmts' = modify_stmts (syms ~~ stmts);
   277           in stmts' @ replicate (length syms_stmts - length stmts') NONE end;
   260             val stmts'' = stmts' @ replicate (length syms - length stmts') NONE;
   278         fun modify_stmts'' syms_exports_stmts =
   261           in map_filter select_stmt (syms ~~ (exports ~~ stmts'')) end;
   279           syms_exports_stmts
   262         val stmtss' = (maps modify_stmts' o map_filter select_syms o Code_Symbol.Graph.strong_conn) nodes;
   280           |> map (fn (sym, (export, stmt)) => ((sym, stmt), export))
   263         val nodes'' = Code_Symbol.Graph.map (fn sym => apsnd (fn Module content => Module (make_declarations nsps' content)
   281           |> burrow_fst modify_stmts'
   264             | _ => case AList.lookup (op =) stmtss' sym of SOME stmt => Stmt stmt | _ => Dummy)) nodes';
   282           |> map (fn (SOME stmt, export) => SOME (export, stmt) | _ => NONE);
       
   283         val nodes'' =
       
   284           nodes'
       
   285           |> Code_Symbol.Graph.map_strong_conn (map_module_stmts (make_declarations nsps') modify_stmts'');
   265         val data' = fold memorize_data stmt_syms data;
   286         val data' = fold memorize_data stmt_syms data;
   266       in (data', nodes'') end;
   287       in (data', nodes'') end;
   267     val (_, hierarchical_program) = make_declarations empty_nsp proto_program;
   288     val (_, hierarchical_program) = make_declarations empty_nsp proto_program;
   268 
   289 
   269     (* deresolving *)
   290     (* deresolving *)