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 |