| author | blanchet | 
| Mon, 04 Apr 2016 09:45:04 +0200 | |
| changeset 62842 | db9f95ca2a8f | 
| parent 59103 | 788db6d6b8a5 | 
| child 67521 | 6a27e86cc2e7 | 
| permissions | -rw-r--r-- | 
| 38970 
53d1ee3d98b8
factored out generic part of Scala serializer into code_namespace.ML
 haftmann parents: diff
changeset | 1 | (* Title: Tools/Code/code_namespace.ML | 
| 
53d1ee3d98b8
factored out generic part of Scala serializer into code_namespace.ML
 haftmann parents: diff
changeset | 2 | Author: Florian Haftmann, TU Muenchen | 
| 
53d1ee3d98b8
factored out generic part of Scala serializer into code_namespace.ML
 haftmann parents: diff
changeset | 3 | |
| 
53d1ee3d98b8
factored out generic part of Scala serializer into code_namespace.ML
 haftmann parents: diff
changeset | 4 | Mastering target language namespaces. | 
| 
53d1ee3d98b8
factored out generic part of Scala serializer into code_namespace.ML
 haftmann parents: diff
changeset | 5 | *) | 
| 
53d1ee3d98b8
factored out generic part of Scala serializer into code_namespace.ML
 haftmann parents: diff
changeset | 6 | |
| 
53d1ee3d98b8
factored out generic part of Scala serializer into code_namespace.ML
 haftmann parents: diff
changeset | 7 | signature CODE_NAMESPACE = | 
| 
53d1ee3d98b8
factored out generic part of Scala serializer into code_namespace.ML
 haftmann parents: diff
changeset | 8 | sig | 
| 58520 
a4d1f8041af0
accomplish potentially case-insenstive file systems for Scala
 haftmann parents: 
57428diff
changeset | 9 | val variant_case_insensitive: string -> Name.context -> string * Name.context | 
| 
a4d1f8041af0
accomplish potentially case-insenstive file systems for Scala
 haftmann parents: 
57428diff
changeset | 10 | |
| 55681 | 11 | datatype export = Private | Opaque | Public | 
| 12 | val is_public: export -> bool | |
| 13 | val not_private: export -> bool | |
| 55684 
ee49b4f7edc8
keep only identifiers public which are explicitly requested or demanded by dependencies
 haftmann parents: 
55683diff
changeset | 14 | val join_exports: export list -> export | 
| 55681 | 15 | |
| 39208 | 16 | type flat_program | 
| 55147 
bce3dbc11f95
prefer explicit code symbol type over ad-hoc name mangling
 haftmann parents: 
53414diff
changeset | 17 | val flat_program: Proof.context | 
| 52138 
e21426f244aa
bookkeeping and input syntax for exact specification of names of symbols in generated code
 haftmann parents: 
51930diff
changeset | 18 |     -> { module_prefix: string, module_name: string,
 | 
| 59103 | 19 | reserved: Name.context, identifiers: Code_Printer.identifiers, empty_nsp: 'a, | 
| 39208 | 20 | namify_stmt: Code_Thingol.stmt -> string -> 'a -> string * 'a, | 
| 21 | modify_stmt: Code_Thingol.stmt -> Code_Thingol.stmt option } | |
| 55683 | 22 | -> Code_Symbol.T list -> Code_Thingol.program | 
| 55150 | 23 |       -> { deresolver: string -> Code_Symbol.T -> string,
 | 
| 39208 | 24 | flat_program: flat_program } | 
| 25 | ||
| 39017 
8cd5b6d688fa
generalized hierarchical data structure over statements
 haftmann parents: 
38970diff
changeset | 26 |   datatype ('a, 'b) node =
 | 
| 38970 
53d1ee3d98b8
factored out generic part of Scala serializer into code_namespace.ML
 haftmann parents: diff
changeset | 27 | Dummy | 
| 55681 | 28 | | Stmt of export * 'a | 
| 55147 
bce3dbc11f95
prefer explicit code symbol type over ad-hoc name mangling
 haftmann parents: 
53414diff
changeset | 29 |     | Module of ('b * (string * ('a, 'b) node) Code_Symbol.Graph.T)
 | 
| 39208 | 30 |   type ('a, 'b) hierarchical_program
 | 
| 55147 
bce3dbc11f95
prefer explicit code symbol type over ad-hoc name mangling
 haftmann parents: 
53414diff
changeset | 31 | val hierarchical_program: Proof.context | 
| 52138 
e21426f244aa
bookkeeping and input syntax for exact specification of names of symbols in generated code
 haftmann parents: 
51930diff
changeset | 32 |     -> { module_name: string,
 | 
| 59103 | 33 | reserved: Name.context, identifiers: Code_Printer.identifiers, | 
| 52138 
e21426f244aa
bookkeeping and input syntax for exact specification of names of symbols in generated code
 haftmann parents: 
51930diff
changeset | 34 | empty_nsp: 'c, namify_module: string -> 'c -> string * 'c, | 
| 39022 | 35 | namify_stmt: Code_Thingol.stmt -> string -> 'c -> string * 'c, | 
| 55684 
ee49b4f7edc8
keep only identifiers public which are explicitly requested or demanded by dependencies
 haftmann parents: 
55683diff
changeset | 36 | cyclic_modules: bool, | 
| 
ee49b4f7edc8
keep only identifiers public which are explicitly requested or demanded by dependencies
 haftmann parents: 
55683diff
changeset | 37 | class_transitive: bool, class_relation_public: bool, | 
| 
ee49b4f7edc8
keep only identifiers public which are explicitly requested or demanded by dependencies
 haftmann parents: 
55683diff
changeset | 38 | empty_data: 'b, memorize_data: Code_Symbol.T -> 'b -> 'b, | 
| 
ee49b4f7edc8
keep only identifiers public which are explicitly requested or demanded by dependencies
 haftmann parents: 
55683diff
changeset | 39 | modify_stmts: (Code_Symbol.T * (export * Code_Thingol.stmt)) list -> (export * 'a) option list } | 
| 55683 | 40 | -> Code_Symbol.T list -> Code_Thingol.program | 
| 55150 | 41 |       -> { deresolver: string list -> Code_Symbol.T -> string,
 | 
| 39147 | 42 |            hierarchical_program: ('a, 'b) hierarchical_program }
 | 
| 43 |   val print_hierarchical: { print_module: string list -> string -> 'b -> 'c list -> 'c,
 | |
| 55681 | 44 | print_stmt: string list -> Code_Symbol.T * (export * 'a) -> 'c, | 
| 39147 | 45 | lift_markup: (Pretty.T -> Pretty.T) -> 'c -> 'c } | 
| 46 |       -> ('a, 'b) hierarchical_program -> 'c list
 | |
| 38970 
53d1ee3d98b8
factored out generic part of Scala serializer into code_namespace.ML
 haftmann parents: diff
changeset | 47 | end; | 
| 
53d1ee3d98b8
factored out generic part of Scala serializer into code_namespace.ML
 haftmann parents: diff
changeset | 48 | |
| 
53d1ee3d98b8
factored out generic part of Scala serializer into code_namespace.ML
 haftmann parents: diff
changeset | 49 | structure Code_Namespace : CODE_NAMESPACE = | 
| 
53d1ee3d98b8
factored out generic part of Scala serializer into code_namespace.ML
 haftmann parents: diff
changeset | 50 | struct | 
| 
53d1ee3d98b8
factored out generic part of Scala serializer into code_namespace.ML
 haftmann parents: diff
changeset | 51 | |
| 58520 
a4d1f8041af0
accomplish potentially case-insenstive file systems for Scala
 haftmann parents: 
57428diff
changeset | 52 | (** name handling on case-insensitive file systems **) | 
| 
a4d1f8041af0
accomplish potentially case-insenstive file systems for Scala
 haftmann parents: 
57428diff
changeset | 53 | |
| 
a4d1f8041af0
accomplish potentially case-insenstive file systems for Scala
 haftmann parents: 
57428diff
changeset | 54 | fun restore_for cs = | 
| 
a4d1f8041af0
accomplish potentially case-insenstive file systems for Scala
 haftmann parents: 
57428diff
changeset | 55 | if forall Symbol.is_ascii_upper cs then map Symbol.to_ascii_upper | 
| 
a4d1f8041af0
accomplish potentially case-insenstive file systems for Scala
 haftmann parents: 
57428diff
changeset | 56 | else if Symbol.is_ascii_upper (nth cs 0) then nth_map 0 Symbol.to_ascii_upper | 
| 
a4d1f8041af0
accomplish potentially case-insenstive file systems for Scala
 haftmann parents: 
57428diff
changeset | 57 | else I; | 
| 
a4d1f8041af0
accomplish potentially case-insenstive file systems for Scala
 haftmann parents: 
57428diff
changeset | 58 | |
| 
a4d1f8041af0
accomplish potentially case-insenstive file systems for Scala
 haftmann parents: 
57428diff
changeset | 59 | fun variant_case_insensitive s ctxt = | 
| 
a4d1f8041af0
accomplish potentially case-insenstive file systems for Scala
 haftmann parents: 
57428diff
changeset | 60 | let | 
| 
a4d1f8041af0
accomplish potentially case-insenstive file systems for Scala
 haftmann parents: 
57428diff
changeset | 61 | val cs = Symbol.explode s; | 
| 
a4d1f8041af0
accomplish potentially case-insenstive file systems for Scala
 haftmann parents: 
57428diff
changeset | 62 | val s_lower = implode (map Symbol.to_ascii_lower cs); | 
| 
a4d1f8041af0
accomplish potentially case-insenstive file systems for Scala
 haftmann parents: 
57428diff
changeset | 63 | val restore = implode o restore_for cs o Symbol.explode; | 
| 
a4d1f8041af0
accomplish potentially case-insenstive file systems for Scala
 haftmann parents: 
57428diff
changeset | 64 | in | 
| 
a4d1f8041af0
accomplish potentially case-insenstive file systems for Scala
 haftmann parents: 
57428diff
changeset | 65 | ctxt | 
| 
a4d1f8041af0
accomplish potentially case-insenstive file systems for Scala
 haftmann parents: 
57428diff
changeset | 66 | |> Name.variant s_lower | 
| 
a4d1f8041af0
accomplish potentially case-insenstive file systems for Scala
 haftmann parents: 
57428diff
changeset | 67 | |>> restore | 
| 
a4d1f8041af0
accomplish potentially case-insenstive file systems for Scala
 haftmann parents: 
57428diff
changeset | 68 | end; | 
| 
a4d1f8041af0
accomplish potentially case-insenstive file systems for Scala
 haftmann parents: 
57428diff
changeset | 69 | |
| 
a4d1f8041af0
accomplish potentially case-insenstive file systems for Scala
 haftmann parents: 
57428diff
changeset | 70 | |
| 55681 | 71 | (** export **) | 
| 72 | ||
| 73 | datatype export = Private | Opaque | Public; | |
| 74 | ||
| 75 | fun is_public Public = true | |
| 76 | | is_public _ = false; | |
| 77 | ||
| 78 | fun not_private Public = true | |
| 79 | | not_private Opaque = true | |
| 80 | | not_private _ = false; | |
| 81 | ||
| 55684 
ee49b4f7edc8
keep only identifiers public which are explicitly requested or demanded by dependencies
 haftmann parents: 
55683diff
changeset | 82 | fun mark_export Public _ = Public | 
| 
ee49b4f7edc8
keep only identifiers public which are explicitly requested or demanded by dependencies
 haftmann parents: 
55683diff
changeset | 83 | | mark_export _ Public = Public | 
| 
ee49b4f7edc8
keep only identifiers public which are explicitly requested or demanded by dependencies
 haftmann parents: 
55683diff
changeset | 84 | | mark_export Opaque _ = Opaque | 
| 
ee49b4f7edc8
keep only identifiers public which are explicitly requested or demanded by dependencies
 haftmann parents: 
55683diff
changeset | 85 | | mark_export _ Opaque = Opaque | 
| 
ee49b4f7edc8
keep only identifiers public which are explicitly requested or demanded by dependencies
 haftmann parents: 
55683diff
changeset | 86 | | mark_export _ _ = Private; | 
| 
ee49b4f7edc8
keep only identifiers public which are explicitly requested or demanded by dependencies
 haftmann parents: 
55683diff
changeset | 87 | |
| 
ee49b4f7edc8
keep only identifiers public which are explicitly requested or demanded by dependencies
 haftmann parents: 
55683diff
changeset | 88 | fun join_exports exports = fold mark_export exports Private; | 
| 
ee49b4f7edc8
keep only identifiers public which are explicitly requested or demanded by dependencies
 haftmann parents: 
55683diff
changeset | 89 | |
| 
ee49b4f7edc8
keep only identifiers public which are explicitly requested or demanded by dependencies
 haftmann parents: 
55683diff
changeset | 90 | fun dependent_exports { program = program, class_transitive = class_transitive } =
 | 
| 
ee49b4f7edc8
keep only identifiers public which are explicitly requested or demanded by dependencies
 haftmann parents: 
55683diff
changeset | 91 | let | 
| 
ee49b4f7edc8
keep only identifiers public which are explicitly requested or demanded by dependencies
 haftmann parents: 
55683diff
changeset | 92 | fun is_datatype_or_class (Code_Symbol.Type_Constructor _) = true | 
| 
ee49b4f7edc8
keep only identifiers public which are explicitly requested or demanded by dependencies
 haftmann parents: 
55683diff
changeset | 93 | | is_datatype_or_class (Code_Symbol.Type_Class _) = true | 
| 
ee49b4f7edc8
keep only identifiers public which are explicitly requested or demanded by dependencies
 haftmann parents: 
55683diff
changeset | 94 | | is_datatype_or_class _ = false; | 
| 
ee49b4f7edc8
keep only identifiers public which are explicitly requested or demanded by dependencies
 haftmann parents: 
55683diff
changeset | 95 | fun is_relevant (Code_Symbol.Class_Relation _) = true | 
| 
ee49b4f7edc8
keep only identifiers public which are explicitly requested or demanded by dependencies
 haftmann parents: 
55683diff
changeset | 96 | | is_relevant sym = is_datatype_or_class sym; | 
| 
ee49b4f7edc8
keep only identifiers public which are explicitly requested or demanded by dependencies
 haftmann parents: 
55683diff
changeset | 97 | val proto_gr = Code_Symbol.Graph.restrict is_relevant program; | 
| 
ee49b4f7edc8
keep only identifiers public which are explicitly requested or demanded by dependencies
 haftmann parents: 
55683diff
changeset | 98 | val gr = | 
| 
ee49b4f7edc8
keep only identifiers public which are explicitly requested or demanded by dependencies
 haftmann parents: 
55683diff
changeset | 99 | proto_gr | 
| 
ee49b4f7edc8
keep only identifiers public which are explicitly requested or demanded by dependencies
 haftmann parents: 
55683diff
changeset | 100 | |> Code_Symbol.Graph.fold | 
| 
ee49b4f7edc8
keep only identifiers public which are explicitly requested or demanded by dependencies
 haftmann parents: 
55683diff
changeset | 101 | (fn (sym, (_, (_, deps))) => | 
| 
ee49b4f7edc8
keep only identifiers public which are explicitly requested or demanded by dependencies
 haftmann parents: 
55683diff
changeset | 102 | if is_relevant sym | 
| 
ee49b4f7edc8
keep only identifiers public which are explicitly requested or demanded by dependencies
 haftmann parents: 
55683diff
changeset | 103 | then I | 
| 
ee49b4f7edc8
keep only identifiers public which are explicitly requested or demanded by dependencies
 haftmann parents: 
55683diff
changeset | 104 | else | 
| 
ee49b4f7edc8
keep only identifiers public which are explicitly requested or demanded by dependencies
 haftmann parents: 
55683diff
changeset | 105 | Code_Symbol.Graph.new_node (sym, Code_Thingol.NoStmt) | 
| 
ee49b4f7edc8
keep only identifiers public which are explicitly requested or demanded by dependencies
 haftmann parents: 
55683diff
changeset | 106 | #> Code_Symbol.Graph.Keys.fold | 
| 
ee49b4f7edc8
keep only identifiers public which are explicitly requested or demanded by dependencies
 haftmann parents: 
55683diff
changeset | 107 | (fn sym' => | 
| 
ee49b4f7edc8
keep only identifiers public which are explicitly requested or demanded by dependencies
 haftmann parents: 
55683diff
changeset | 108 | if is_relevant sym' | 
| 
ee49b4f7edc8
keep only identifiers public which are explicitly requested or demanded by dependencies
 haftmann parents: 
55683diff
changeset | 109 | then Code_Symbol.Graph.add_edge (sym, sym') | 
| 
ee49b4f7edc8
keep only identifiers public which are explicitly requested or demanded by dependencies
 haftmann parents: 
55683diff
changeset | 110 | else I) deps) program | 
| 
ee49b4f7edc8
keep only identifiers public which are explicitly requested or demanded by dependencies
 haftmann parents: 
55683diff
changeset | 111 | |> class_transitive ? | 
| 
ee49b4f7edc8
keep only identifiers public which are explicitly requested or demanded by dependencies
 haftmann parents: 
55683diff
changeset | 112 | Code_Symbol.Graph.fold (fn (sym as Code_Symbol.Type_Class _, _) => | 
| 
ee49b4f7edc8
keep only identifiers public which are explicitly requested or demanded by dependencies
 haftmann parents: 
55683diff
changeset | 113 | fold (curry Code_Symbol.Graph.add_edge sym) | 
| 
ee49b4f7edc8
keep only identifiers public which are explicitly requested or demanded by dependencies
 haftmann parents: 
55683diff
changeset | 114 | ((remove (op =) sym o Code_Symbol.Graph.all_succs proto_gr) [sym]) | _ => I) proto_gr | 
| 
ee49b4f7edc8
keep only identifiers public which are explicitly requested or demanded by dependencies
 haftmann parents: 
55683diff
changeset | 115 | fun deps_of sym = | 
| 
ee49b4f7edc8
keep only identifiers public which are explicitly requested or demanded by dependencies
 haftmann parents: 
55683diff
changeset | 116 | let | 
| 
ee49b4f7edc8
keep only identifiers public which are explicitly requested or demanded by dependencies
 haftmann parents: 
55683diff
changeset | 117 | val succs = Code_Symbol.Graph.Keys.dest o Code_Symbol.Graph.imm_succs gr; | 
| 
ee49b4f7edc8
keep only identifiers public which are explicitly requested or demanded by dependencies
 haftmann parents: 
55683diff
changeset | 118 | val deps1 = succs sym; | 
| 55776 
7dd1971b39c1
amended some slips, rolling back currently dysfunctional export minimimalisation for Scala
 haftmann parents: 
55684diff
changeset | 119 | val deps2 = [] |> fold (union (op =)) (map succs deps1) |> subtract (op =) deps1 | 
| 55684 
ee49b4f7edc8
keep only identifiers public which are explicitly requested or demanded by dependencies
 haftmann parents: 
55683diff
changeset | 120 | in (deps1, deps2) end; | 
| 
ee49b4f7edc8
keep only identifiers public which are explicitly requested or demanded by dependencies
 haftmann parents: 
55683diff
changeset | 121 | in | 
| 
ee49b4f7edc8
keep only identifiers public which are explicitly requested or demanded by dependencies
 haftmann parents: 
55683diff
changeset | 122 |     { is_datatype_or_class = is_datatype_or_class,
 | 
| 
ee49b4f7edc8
keep only identifiers public which are explicitly requested or demanded by dependencies
 haftmann parents: 
55683diff
changeset | 123 | deps_of = deps_of } | 
| 
ee49b4f7edc8
keep only identifiers public which are explicitly requested or demanded by dependencies
 haftmann parents: 
55683diff
changeset | 124 | end; | 
| 
ee49b4f7edc8
keep only identifiers public which are explicitly requested or demanded by dependencies
 haftmann parents: 
55683diff
changeset | 125 | |
| 
ee49b4f7edc8
keep only identifiers public which are explicitly requested or demanded by dependencies
 haftmann parents: 
55683diff
changeset | 126 | fun mark_exports_aux { program = program, prefix_of = prefix_of, map_export = map_export,
 | 
| 
ee49b4f7edc8
keep only identifiers public which are explicitly requested or demanded by dependencies
 haftmann parents: 
55683diff
changeset | 127 | is_datatype_or_class = is_datatype_or_class, deps_of = deps_of, | 
| 
ee49b4f7edc8
keep only identifiers public which are explicitly requested or demanded by dependencies
 haftmann parents: 
55683diff
changeset | 128 | class_relation_public = class_relation_public } prefix sym = | 
| 
ee49b4f7edc8
keep only identifiers public which are explicitly requested or demanded by dependencies
 haftmann parents: 
55683diff
changeset | 129 | let | 
| 
ee49b4f7edc8
keep only identifiers public which are explicitly requested or demanded by dependencies
 haftmann parents: 
55683diff
changeset | 130 | val export = (if is_datatype_or_class sym then Opaque else Public); | 
| 
ee49b4f7edc8
keep only identifiers public which are explicitly requested or demanded by dependencies
 haftmann parents: 
55683diff
changeset | 131 | val (dependent_export1, dependent_export2) = | 
| 
ee49b4f7edc8
keep only identifiers public which are explicitly requested or demanded by dependencies
 haftmann parents: 
55683diff
changeset | 132 | case Code_Symbol.Graph.get_node program sym of | 
| 
ee49b4f7edc8
keep only identifiers public which are explicitly requested or demanded by dependencies
 haftmann parents: 
55683diff
changeset | 133 | Code_Thingol.Fun _ => (SOME Opaque, NONE) | 
| 
ee49b4f7edc8
keep only identifiers public which are explicitly requested or demanded by dependencies
 haftmann parents: 
55683diff
changeset | 134 | | Code_Thingol.Classinst _ => (SOME Opaque, NONE) | 
| 
ee49b4f7edc8
keep only identifiers public which are explicitly requested or demanded by dependencies
 haftmann parents: 
55683diff
changeset | 135 | | Code_Thingol.Datatypecons _ => (SOME Public, SOME Opaque) | 
| 
ee49b4f7edc8
keep only identifiers public which are explicitly requested or demanded by dependencies
 haftmann parents: 
55683diff
changeset | 136 | | Code_Thingol.Classparam _ => (SOME Public, SOME Opaque) | 
| 55776 
7dd1971b39c1
amended some slips, rolling back currently dysfunctional export minimimalisation for Scala
 haftmann parents: 
55684diff
changeset | 137 | | Code_Thingol.Class _ => (SOME Opaque, NONE) | 
| 55684 
ee49b4f7edc8
keep only identifiers public which are explicitly requested or demanded by dependencies
 haftmann parents: 
55683diff
changeset | 138 | | Code_Thingol.Classrel _ => | 
| 
ee49b4f7edc8
keep only identifiers public which are explicitly requested or demanded by dependencies
 haftmann parents: 
55683diff
changeset | 139 | (if class_relation_public | 
| 
ee49b4f7edc8
keep only identifiers public which are explicitly requested or demanded by dependencies
 haftmann parents: 
55683diff
changeset | 140 | then (SOME Public, SOME Opaque) | 
| 
ee49b4f7edc8
keep only identifiers public which are explicitly requested or demanded by dependencies
 haftmann parents: 
55683diff
changeset | 141 | else (SOME Opaque, NONE)) | 
| 
ee49b4f7edc8
keep only identifiers public which are explicitly requested or demanded by dependencies
 haftmann parents: 
55683diff
changeset | 142 | | _ => (NONE, NONE); | 
| 
ee49b4f7edc8
keep only identifiers public which are explicitly requested or demanded by dependencies
 haftmann parents: 
55683diff
changeset | 143 | val dependent_exports = | 
| 
ee49b4f7edc8
keep only identifiers public which are explicitly requested or demanded by dependencies
 haftmann parents: 
55683diff
changeset | 144 | case dependent_export1 of | 
| 
ee49b4f7edc8
keep only identifiers public which are explicitly requested or demanded by dependencies
 haftmann parents: 
55683diff
changeset | 145 | SOME export1 => (case dependent_export2 of | 
| 
ee49b4f7edc8
keep only identifiers public which are explicitly requested or demanded by dependencies
 haftmann parents: 
55683diff
changeset | 146 | SOME export2 => | 
| 
ee49b4f7edc8
keep only identifiers public which are explicitly requested or demanded by dependencies
 haftmann parents: 
55683diff
changeset | 147 | let | 
| 
ee49b4f7edc8
keep only identifiers public which are explicitly requested or demanded by dependencies
 haftmann parents: 
55683diff
changeset | 148 | val (deps1, deps2) = deps_of sym | 
| 
ee49b4f7edc8
keep only identifiers public which are explicitly requested or demanded by dependencies
 haftmann parents: 
55683diff
changeset | 149 | in map (rpair export1) deps1 @ map (rpair export2) deps2 end | 
| 
ee49b4f7edc8
keep only identifiers public which are explicitly requested or demanded by dependencies
 haftmann parents: 
55683diff
changeset | 150 | | NONE => map (rpair export1) (fst (deps_of sym))) | 
| 
ee49b4f7edc8
keep only identifiers public which are explicitly requested or demanded by dependencies
 haftmann parents: 
55683diff
changeset | 151 | | NONE => []; | 
| 
ee49b4f7edc8
keep only identifiers public which are explicitly requested or demanded by dependencies
 haftmann parents: 
55683diff
changeset | 152 | in | 
| 
ee49b4f7edc8
keep only identifiers public which are explicitly requested or demanded by dependencies
 haftmann parents: 
55683diff
changeset | 153 | map_export prefix sym (mark_export export) | 
| 
ee49b4f7edc8
keep only identifiers public which are explicitly requested or demanded by dependencies
 haftmann parents: 
55683diff
changeset | 154 | #> fold (fn (sym, export) => map_export (prefix_of sym) sym (mark_export export)) | 
| 
ee49b4f7edc8
keep only identifiers public which are explicitly requested or demanded by dependencies
 haftmann parents: 
55683diff
changeset | 155 | dependent_exports | 
| 
ee49b4f7edc8
keep only identifiers public which are explicitly requested or demanded by dependencies
 haftmann parents: 
55683diff
changeset | 156 | end; | 
| 
ee49b4f7edc8
keep only identifiers public which are explicitly requested or demanded by dependencies
 haftmann parents: 
55683diff
changeset | 157 | |
| 
ee49b4f7edc8
keep only identifiers public which are explicitly requested or demanded by dependencies
 haftmann parents: 
55683diff
changeset | 158 | fun mark_exports { program = program, prefix_of = prefix_of, map_export = map_export,
 | 
| 
ee49b4f7edc8
keep only identifiers public which are explicitly requested or demanded by dependencies
 haftmann parents: 
55683diff
changeset | 159 | class_transitive = class_transitive, class_relation_public = class_relation_public } = | 
| 
ee49b4f7edc8
keep only identifiers public which are explicitly requested or demanded by dependencies
 haftmann parents: 
55683diff
changeset | 160 | let | 
| 
ee49b4f7edc8
keep only identifiers public which are explicitly requested or demanded by dependencies
 haftmann parents: 
55683diff
changeset | 161 |     val { is_datatype_or_class, deps_of } =
 | 
| 
ee49b4f7edc8
keep only identifiers public which are explicitly requested or demanded by dependencies
 haftmann parents: 
55683diff
changeset | 162 |       dependent_exports { program = program, class_transitive = class_transitive };
 | 
| 
ee49b4f7edc8
keep only identifiers public which are explicitly requested or demanded by dependencies
 haftmann parents: 
55683diff
changeset | 163 | in | 
| 
ee49b4f7edc8
keep only identifiers public which are explicitly requested or demanded by dependencies
 haftmann parents: 
55683diff
changeset | 164 |     mark_exports_aux { program = program, prefix_of = prefix_of, map_export = map_export,
 | 
| 
ee49b4f7edc8
keep only identifiers public which are explicitly requested or demanded by dependencies
 haftmann parents: 
55683diff
changeset | 165 | is_datatype_or_class = is_datatype_or_class, deps_of = deps_of, | 
| 
ee49b4f7edc8
keep only identifiers public which are explicitly requested or demanded by dependencies
 haftmann parents: 
55683diff
changeset | 166 | class_relation_public = class_relation_public } | 
| 
ee49b4f7edc8
keep only identifiers public which are explicitly requested or demanded by dependencies
 haftmann parents: 
55683diff
changeset | 167 | end; | 
| 
ee49b4f7edc8
keep only identifiers public which are explicitly requested or demanded by dependencies
 haftmann parents: 
55683diff
changeset | 168 | |
| 55681 | 169 | |
| 52138 
e21426f244aa
bookkeeping and input syntax for exact specification of names of symbols in generated code
 haftmann parents: 
51930diff
changeset | 170 | (** fundamental module name hierarchy **) | 
| 
e21426f244aa
bookkeeping and input syntax for exact specification of names of symbols in generated code
 haftmann parents: 
51930diff
changeset | 171 | |
| 55291 | 172 | fun module_fragments' { identifiers, reserved } name =
 | 
| 173 | case Code_Symbol.lookup_module_data identifiers name of | |
| 174 | SOME (fragments, _) => fragments | |
| 175 | | NONE => map (fn fragment => fst (Name.variant fragment reserved)) (Long_Name.explode name); | |
| 176 | ||
| 177 | fun module_fragments { module_name, identifiers, reserved } =
 | |
| 178 | if module_name = "" | |
| 179 |   then module_fragments' { identifiers = identifiers, reserved = reserved }
 | |
| 180 | else K (Long_Name.explode module_name); | |
| 39055 | 181 | |
| 56826 
ba18bd41e510
enforce case of identifiers only to accomodate strict language requirements (or clear separation of constructors from variables in the case of SML)
 haftmann parents: 
55776diff
changeset | 182 | fun build_module_namespace ctxt enforce_upper { module_prefix, module_name, identifiers, reserved } program =
 | 
| 55291 | 183 | let | 
| 184 | val module_names = Code_Symbol.Graph.fold (insert (op =) o Code_Symbol.default_prefix ctxt o fst) program []; | |
| 185 | val module_fragments' = module_fragments | |
| 186 |       { module_name = module_name, identifiers = identifiers, reserved = reserved };
 | |
| 56826 
ba18bd41e510
enforce case of identifiers only to accomodate strict language requirements (or clear separation of constructors from variables in the case of SML)
 haftmann parents: 
55776diff
changeset | 187 | val adjust_case = if enforce_upper then map (Name.enforce_case true) else I; | 
| 55291 | 188 | in | 
| 56826 
ba18bd41e510
enforce case of identifiers only to accomodate strict language requirements (or clear separation of constructors from variables in the case of SML)
 haftmann parents: 
55776diff
changeset | 189 | fold (fn name => Symtab.update (name, adjust_case (Long_Name.explode module_prefix @ module_fragments' name))) | 
| 55291 | 190 | module_names Symtab.empty | 
| 191 | end; | |
| 192 | ||
| 55292 | 193 | fun prep_symbol ctxt { module_namespace, force_module, identifiers } sym =
 | 
| 55291 | 194 | case Code_Symbol.lookup identifiers sym of | 
| 55292 | 195 | NONE => ((the o Symtab.lookup module_namespace o Code_Symbol.default_prefix ctxt) sym, | 
| 196 | Code_Symbol.default_base sym) | |
| 53414 
dd64696d267a
explicit module names have precedence over identifier declarations
 haftmann parents: 
52138diff
changeset | 197 | | SOME prefix_name => if null force_module then prefix_name | 
| 
dd64696d267a
explicit module names have precedence over identifier declarations
 haftmann parents: 
52138diff
changeset | 198 | else (force_module, snd prefix_name); | 
| 39055 | 199 | |
| 55293 
42cf5802d36a
code generation: explicitly declared identifiers gain predence over implicit ones
 haftmann parents: 
55292diff
changeset | 200 | fun has_priority identifiers = is_some o Code_Symbol.lookup identifiers; | 
| 
42cf5802d36a
code generation: explicitly declared identifiers gain predence over implicit ones
 haftmann parents: 
55292diff
changeset | 201 | |
| 55292 | 202 | fun build_proto_program { empty, add_stmt, add_dep } program =
 | 
| 203 | empty | |
| 204 | |> Code_Symbol.Graph.fold (fn (sym, (stmt, _)) => add_stmt sym stmt) program | |
| 205 | |> Code_Symbol.Graph.fold (fn (sym, (_, (_, syms))) => | |
| 206 | Code_Symbol.Graph.Keys.fold (add_dep sym) syms) program; | |
| 207 | ||
| 55293 
42cf5802d36a
code generation: explicitly declared identifiers gain predence over implicit ones
 haftmann parents: 
55292diff
changeset | 208 | fun prioritize has_priority = uncurry append o List.partition has_priority; | 
| 
42cf5802d36a
code generation: explicitly declared identifiers gain predence over implicit ones
 haftmann parents: 
55292diff
changeset | 209 | |
| 39055 | 210 | |
| 39208 | 211 | (** flat program structure **) | 
| 212 | ||
| 55681 | 213 | type flat_program = ((string * (export * Code_Thingol.stmt) option) Code_Symbol.Graph.T * (string * Code_Symbol.T list) list) Graph.T; | 
| 39208 | 214 | |
| 55147 
bce3dbc11f95
prefer explicit code symbol type over ad-hoc name mangling
 haftmann parents: 
53414diff
changeset | 215 | fun flat_program ctxt { module_prefix, module_name, reserved,
 | 
| 55683 | 216 | identifiers, empty_nsp, namify_stmt, modify_stmt } exports program = | 
| 39208 | 217 | let | 
| 218 | ||
| 219 | (* building module name hierarchy *) | |
| 56826 
ba18bd41e510
enforce case of identifiers only to accomodate strict language requirements (or clear separation of constructors from variables in the case of SML)
 haftmann parents: 
55776diff
changeset | 220 |     val module_namespace = build_module_namespace ctxt true { module_prefix = module_prefix,
 | 
| 55291 | 221 | module_name = module_name, identifiers = identifiers, reserved = reserved } program; | 
| 55292 | 222 |     val prep_sym = prep_symbol ctxt { module_namespace = module_namespace,
 | 
| 223 | force_module = Long_Name.explode module_name, identifiers = identifiers } | |
| 52138 
e21426f244aa
bookkeeping and input syntax for exact specification of names of symbols in generated code
 haftmann parents: 
51930diff
changeset | 224 | #>> Long_Name.implode; | 
| 55293 
42cf5802d36a
code generation: explicitly declared identifiers gain predence over implicit ones
 haftmann parents: 
55292diff
changeset | 225 | val sym_priority = has_priority identifiers; | 
| 39208 | 226 | |
| 227 | (* distribute statements over hierarchy *) | |
| 55684 
ee49b4f7edc8
keep only identifiers public which are explicitly requested or demanded by dependencies
 haftmann parents: 
55683diff
changeset | 228 |     val mark_exports = mark_exports { program = program, prefix_of = fst o prep_sym,
 | 
| 
ee49b4f7edc8
keep only identifiers public which are explicitly requested or demanded by dependencies
 haftmann parents: 
55683diff
changeset | 229 | map_export = fn module_name => fn sym => | 
| 
ee49b4f7edc8
keep only identifiers public which are explicitly requested or demanded by dependencies
 haftmann parents: 
55683diff
changeset | 230 | Graph.map_node module_name o apfst o Code_Symbol.Graph.map_node sym o apsnd o apfst, | 
| 
ee49b4f7edc8
keep only identifiers public which are explicitly requested or demanded by dependencies
 haftmann parents: 
55683diff
changeset | 231 | class_transitive = false, class_relation_public = false }; | 
| 55147 
bce3dbc11f95
prefer explicit code symbol type over ad-hoc name mangling
 haftmann parents: 
53414diff
changeset | 232 | fun add_stmt sym stmt = | 
| 39208 | 233 | let | 
| 55147 
bce3dbc11f95
prefer explicit code symbol type over ad-hoc name mangling
 haftmann parents: 
53414diff
changeset | 234 | val (module_name, base) = prep_sym sym; | 
| 39208 | 235 | in | 
| 55147 
bce3dbc11f95
prefer explicit code symbol type over ad-hoc name mangling
 haftmann parents: 
53414diff
changeset | 236 | Graph.default_node (module_name, (Code_Symbol.Graph.empty, [])) | 
| 55680 | 237 | #> (Graph.map_node module_name o apfst) | 
| 55684 
ee49b4f7edc8
keep only identifiers public which are explicitly requested or demanded by dependencies
 haftmann parents: 
55683diff
changeset | 238 | (Code_Symbol.Graph.new_node (sym, (base, (if null exports then Public else Private, stmt)))) | 
| 39208 | 239 | end; | 
| 55292 | 240 | fun add_dep sym sym' = | 
| 39208 | 241 | let | 
| 55147 
bce3dbc11f95
prefer explicit code symbol type over ad-hoc name mangling
 haftmann parents: 
53414diff
changeset | 242 | val (module_name, _) = prep_sym sym; | 
| 
bce3dbc11f95
prefer explicit code symbol type over ad-hoc name mangling
 haftmann parents: 
53414diff
changeset | 243 | val (module_name', _) = prep_sym sym'; | 
| 39208 | 244 | in if module_name = module_name' | 
| 55147 
bce3dbc11f95
prefer explicit code symbol type over ad-hoc name mangling
 haftmann parents: 
53414diff
changeset | 245 | then (Graph.map_node module_name o apfst) (Code_Symbol.Graph.add_edge (sym, sym')) | 
| 55680 | 246 | else (Graph.map_node module_name o apsnd) | 
| 247 | (AList.map_default (op =) (module_name', []) (insert (op =) sym')) | |
| 55684 
ee49b4f7edc8
keep only identifiers public which are explicitly requested or demanded by dependencies
 haftmann parents: 
55683diff
changeset | 248 | #> mark_exports module_name' sym' | 
| 39208 | 249 | end; | 
| 55292 | 250 | val proto_program = build_proto_program | 
| 55684 
ee49b4f7edc8
keep only identifiers public which are explicitly requested or demanded by dependencies
 haftmann parents: 
55683diff
changeset | 251 |       { empty = Graph.empty, add_stmt = add_stmt, add_dep = add_dep } program
 | 
| 
ee49b4f7edc8
keep only identifiers public which are explicitly requested or demanded by dependencies
 haftmann parents: 
55683diff
changeset | 252 | |> fold (fn sym => mark_exports ((fst o prep_sym) sym) sym) exports; | 
| 39208 | 253 | |
| 254 | (* name declarations and statement modifications *) | |
| 55679 | 255 | fun declare sym (base, (_, stmt)) (gr, nsp) = | 
| 39208 | 256 | let | 
| 257 | val (base', nsp') = namify_stmt stmt base nsp; | |
| 55147 
bce3dbc11f95
prefer explicit code symbol type over ad-hoc name mangling
 haftmann parents: 
53414diff
changeset | 258 | val gr' = (Code_Symbol.Graph.map_node sym o apfst) (K base') gr; | 
| 39208 | 259 | in (gr', nsp') end; | 
| 260 | fun declarations gr = (gr, empty_nsp) | |
| 55293 
42cf5802d36a
code generation: explicitly declared identifiers gain predence over implicit ones
 haftmann parents: 
55292diff
changeset | 261 | |> fold (fn sym => declare sym (Code_Symbol.Graph.get_node gr sym)) | 
| 
42cf5802d36a
code generation: explicitly declared identifiers gain predence over implicit ones
 haftmann parents: 
55292diff
changeset | 262 | (prioritize sym_priority (Code_Symbol.Graph.keys gr)) | 
| 39208 | 263 | |> fst | 
| 55680 | 264 | |> Code_Symbol.Graph.map_strong_conn (fn syms_bases_exports_stmts => | 
| 265 | map snd syms_bases_exports_stmts | |
| 266 | |> (map o apsnd) (fn (export, stmt) => Option.map (pair export) (modify_stmt stmt))); | |
| 39208 | 267 | val flat_program = proto_program | 
| 268 | |> (Graph.map o K o apfst) declarations; | |
| 269 | ||
| 270 | (* qualified and unqualified imports, deresolving *) | |
| 55147 
bce3dbc11f95
prefer explicit code symbol type over ad-hoc name mangling
 haftmann parents: 
53414diff
changeset | 271 | fun base_deresolver sym = fst (Code_Symbol.Graph.get_node | 
| 
bce3dbc11f95
prefer explicit code symbol type over ad-hoc name mangling
 haftmann parents: 
53414diff
changeset | 272 | (fst (Graph.get_node flat_program (fst (prep_sym sym)))) sym); | 
| 39208 | 273 | fun classify_names gr imports = | 
| 274 | let | |
| 275 | val import_tab = maps | |
| 55147 
bce3dbc11f95
prefer explicit code symbol type over ad-hoc name mangling
 haftmann parents: 
53414diff
changeset | 276 | (fn (module_name, syms) => map (rpair module_name) syms) imports; | 
| 
bce3dbc11f95
prefer explicit code symbol type over ad-hoc name mangling
 haftmann parents: 
53414diff
changeset | 277 | val imported_syms = map fst import_tab; | 
| 
bce3dbc11f95
prefer explicit code symbol type over ad-hoc name mangling
 haftmann parents: 
53414diff
changeset | 278 | val here_syms = Code_Symbol.Graph.keys gr; | 
| 39208 | 279 | in | 
| 55147 
bce3dbc11f95
prefer explicit code symbol type over ad-hoc name mangling
 haftmann parents: 
53414diff
changeset | 280 | Code_Symbol.Table.empty | 
| 
bce3dbc11f95
prefer explicit code symbol type over ad-hoc name mangling
 haftmann parents: 
53414diff
changeset | 281 | |> fold (fn sym => Code_Symbol.Table.update (sym, base_deresolver sym)) here_syms | 
| 
bce3dbc11f95
prefer explicit code symbol type over ad-hoc name mangling
 haftmann parents: 
53414diff
changeset | 282 | |> fold (fn sym => Code_Symbol.Table.update (sym, | 
| 
bce3dbc11f95
prefer explicit code symbol type over ad-hoc name mangling
 haftmann parents: 
53414diff
changeset | 283 | Long_Name.append (the (AList.lookup (op =) import_tab sym)) | 
| 
bce3dbc11f95
prefer explicit code symbol type over ad-hoc name mangling
 haftmann parents: 
53414diff
changeset | 284 | (base_deresolver sym))) imported_syms | 
| 39208 | 285 | end; | 
| 40630 | 286 | val deresolver_tab = Symtab.make (AList.make | 
| 287 | (uncurry classify_names o Graph.get_node flat_program) | |
| 288 | (Graph.keys flat_program)); | |
| 55147 
bce3dbc11f95
prefer explicit code symbol type over ad-hoc name mangling
 haftmann parents: 
53414diff
changeset | 289 | fun deresolver "" sym = | 
| 
bce3dbc11f95
prefer explicit code symbol type over ad-hoc name mangling
 haftmann parents: 
53414diff
changeset | 290 | Long_Name.append (fst (prep_sym sym)) (base_deresolver sym) | 
| 
bce3dbc11f95
prefer explicit code symbol type over ad-hoc name mangling
 haftmann parents: 
53414diff
changeset | 291 | | deresolver module_name sym = | 
| 
bce3dbc11f95
prefer explicit code symbol type over ad-hoc name mangling
 haftmann parents: 
53414diff
changeset | 292 | the (Code_Symbol.Table.lookup (the (Symtab.lookup deresolver_tab module_name)) sym) | 
| 52138 
e21426f244aa
bookkeeping and input syntax for exact specification of names of symbols in generated code
 haftmann parents: 
51930diff
changeset | 293 |           handle Option.Option => error ("Unknown statement name: "
 | 
| 55147 
bce3dbc11f95
prefer explicit code symbol type over ad-hoc name mangling
 haftmann parents: 
53414diff
changeset | 294 | ^ Code_Symbol.quote ctxt sym); | 
| 39208 | 295 | |
| 296 |   in { deresolver = deresolver, flat_program = flat_program } end;
 | |
| 297 | ||
| 298 | ||
| 39055 | 299 | (** hierarchical program structure **) | 
| 38970 
53d1ee3d98b8
factored out generic part of Scala serializer into code_namespace.ML
 haftmann parents: diff
changeset | 300 | |
| 39017 
8cd5b6d688fa
generalized hierarchical data structure over statements
 haftmann parents: 
38970diff
changeset | 301 | datatype ('a, 'b) node =
 | 
| 38970 
53d1ee3d98b8
factored out generic part of Scala serializer into code_namespace.ML
 haftmann parents: diff
changeset | 302 | Dummy | 
| 55681 | 303 | | Stmt of export * 'a | 
| 55147 
bce3dbc11f95
prefer explicit code symbol type over ad-hoc name mangling
 haftmann parents: 
53414diff
changeset | 304 |   | Module of ('b * (string * ('a, 'b) node) Code_Symbol.Graph.T);
 | 
| 38970 
53d1ee3d98b8
factored out generic part of Scala serializer into code_namespace.ML
 haftmann parents: diff
changeset | 305 | |
| 55147 
bce3dbc11f95
prefer explicit code symbol type over ad-hoc name mangling
 haftmann parents: 
53414diff
changeset | 306 | type ('a, 'b) hierarchical_program = (string * ('a, 'b) node) Code_Symbol.Graph.T;
 | 
| 39147 | 307 | |
| 55679 | 308 | fun the_stmt (Stmt (export, stmt)) = (export, stmt); | 
| 309 | ||
| 39018 | 310 | fun map_module_content f (Module content) = Module (f content); | 
| 311 | ||
| 312 | fun map_module [] = I | |
| 313 | | map_module (name_fragment :: name_fragments) = | |
| 55147 
bce3dbc11f95
prefer explicit code symbol type over ad-hoc name mangling
 haftmann parents: 
53414diff
changeset | 314 | apsnd o Code_Symbol.Graph.map_node (Code_Symbol.Module name_fragment) o apsnd o map_module_content | 
| 39018 | 315 | o map_module name_fragments; | 
| 316 | ||
| 55680 | 317 | fun map_module_stmts f_module f_stmts sym_base_nodes = | 
| 318 | let | |
| 319 | val some_modules = | |
| 320 | sym_base_nodes | |
| 55684 
ee49b4f7edc8
keep only identifiers public which are explicitly requested or demanded by dependencies
 haftmann parents: 
55683diff
changeset | 321 | |> map (fn (_, (base, Module content)) => SOME (base, content) | _ => NONE) | 
| 55680 | 322 | |> (burrow_options o map o apsnd) f_module; | 
| 323 | val some_export_stmts = | |
| 324 | sym_base_nodes | |
| 325 | |> map (fn (sym, (base, Stmt export_stmt)) => SOME ((sym, export_stmt), base) | _ => NONE) | |
| 326 | |> (burrow_options o burrow_fst) (fn [] => [] | xs => f_stmts xs) | |
| 327 | in | |
| 328 | map2 (fn SOME (base, content) => (K (base, Module content)) | |
| 329 | | NONE => fn SOME (some_export_stmt, base) => | |
| 330 | (base, case some_export_stmt of SOME export_stmt => Stmt export_stmt | NONE => Dummy)) | |
| 331 | some_modules some_export_stmts | |
| 332 | end; | |
| 333 | ||
| 55147 
bce3dbc11f95
prefer explicit code symbol type over ad-hoc name mangling
 haftmann parents: 
53414diff
changeset | 334 | fun hierarchical_program ctxt { module_name, reserved, identifiers, empty_nsp,
 | 
| 55684 
ee49b4f7edc8
keep only identifiers public which are explicitly requested or demanded by dependencies
 haftmann parents: 
55683diff
changeset | 335 | namify_module, namify_stmt, cyclic_modules, | 
| 
ee49b4f7edc8
keep only identifiers public which are explicitly requested or demanded by dependencies
 haftmann parents: 
55683diff
changeset | 336 | class_transitive, class_relation_public, | 
| 
ee49b4f7edc8
keep only identifiers public which are explicitly requested or demanded by dependencies
 haftmann parents: 
55683diff
changeset | 337 | empty_data, memorize_data, modify_stmts } | 
| 55683 | 338 | exports program = | 
| 38970 
53d1ee3d98b8
factored out generic part of Scala serializer into code_namespace.ML
 haftmann parents: diff
changeset | 339 | let | 
| 
53d1ee3d98b8
factored out generic part of Scala serializer into code_namespace.ML
 haftmann parents: diff
changeset | 340 | |
| 
53d1ee3d98b8
factored out generic part of Scala serializer into code_namespace.ML
 haftmann parents: diff
changeset | 341 | (* building module name hierarchy *) | 
| 56826 
ba18bd41e510
enforce case of identifiers only to accomodate strict language requirements (or clear separation of constructors from variables in the case of SML)
 haftmann parents: 
55776diff
changeset | 342 |     val module_namespace = build_module_namespace ctxt false { module_prefix = "",
 | 
| 55291 | 343 | module_name = module_name, identifiers = identifiers, reserved = reserved } program; | 
| 55292 | 344 |     val prep_sym = prep_symbol ctxt { module_namespace = module_namespace,
 | 
| 55293 
42cf5802d36a
code generation: explicitly declared identifiers gain predence over implicit ones
 haftmann parents: 
55292diff
changeset | 345 | force_module = Long_Name.explode module_name, identifiers = identifiers } | 
| 
42cf5802d36a
code generation: explicitly declared identifiers gain predence over implicit ones
 haftmann parents: 
55292diff
changeset | 346 | val sym_priority = has_priority identifiers; | 
| 38970 
53d1ee3d98b8
factored out generic part of Scala serializer into code_namespace.ML
 haftmann parents: diff
changeset | 347 | |
| 
53d1ee3d98b8
factored out generic part of Scala serializer into code_namespace.ML
 haftmann parents: diff
changeset | 348 | (* building empty module hierarchy *) | 
| 55147 
bce3dbc11f95
prefer explicit code symbol type over ad-hoc name mangling
 haftmann parents: 
53414diff
changeset | 349 | val empty_module = (empty_data, Code_Symbol.Graph.empty); | 
| 38970 
53d1ee3d98b8
factored out generic part of Scala serializer into code_namespace.ML
 haftmann parents: diff
changeset | 350 | fun ensure_module name_fragment (data, nodes) = | 
| 55147 
bce3dbc11f95
prefer explicit code symbol type over ad-hoc name mangling
 haftmann parents: 
53414diff
changeset | 351 | if can (Code_Symbol.Graph.get_node nodes) (Code_Symbol.Module name_fragment) then (data, nodes) | 
| 38970 
53d1ee3d98b8
factored out generic part of Scala serializer into code_namespace.ML
 haftmann parents: diff
changeset | 352 | else (data, | 
| 55147 
bce3dbc11f95
prefer explicit code symbol type over ad-hoc name mangling
 haftmann parents: 
53414diff
changeset | 353 | nodes |> Code_Symbol.Graph.new_node (Code_Symbol.Module name_fragment, (name_fragment, Module empty_module))); | 
| 38970 
53d1ee3d98b8
factored out generic part of Scala serializer into code_namespace.ML
 haftmann parents: diff
changeset | 354 | fun allocate_module [] = I | 
| 
53d1ee3d98b8
factored out generic part of Scala serializer into code_namespace.ML
 haftmann parents: diff
changeset | 355 | | allocate_module (name_fragment :: name_fragments) = | 
| 
53d1ee3d98b8
factored out generic part of Scala serializer into code_namespace.ML
 haftmann parents: diff
changeset | 356 | ensure_module name_fragment | 
| 55147 
bce3dbc11f95
prefer explicit code symbol type over ad-hoc name mangling
 haftmann parents: 
53414diff
changeset | 357 | #> (apsnd o Code_Symbol.Graph.map_node (Code_Symbol.Module name_fragment) o apsnd o map_module_content o allocate_module) name_fragments; | 
| 52138 
e21426f244aa
bookkeeping and input syntax for exact specification of names of symbols in generated code
 haftmann parents: 
51930diff
changeset | 358 | val empty_program = | 
| 
e21426f244aa
bookkeeping and input syntax for exact specification of names of symbols in generated code
 haftmann parents: 
51930diff
changeset | 359 | empty_module | 
| 55291 | 360 | |> Symtab.fold (fn (_, fragments) => allocate_module fragments) module_namespace | 
| 55147 
bce3dbc11f95
prefer explicit code symbol type over ad-hoc name mangling
 haftmann parents: 
53414diff
changeset | 361 | |> Code_Symbol.Graph.fold (allocate_module o these o Option.map fst | 
| 55291 | 362 | o Code_Symbol.lookup identifiers o fst) program; | 
| 38970 
53d1ee3d98b8
factored out generic part of Scala serializer into code_namespace.ML
 haftmann parents: diff
changeset | 363 | |
| 
53d1ee3d98b8
factored out generic part of Scala serializer into code_namespace.ML
 haftmann parents: diff
changeset | 364 | (* distribute statements over hierarchy *) | 
| 55684 
ee49b4f7edc8
keep only identifiers public which are explicitly requested or demanded by dependencies
 haftmann parents: 
55683diff
changeset | 365 |     val mark_exports = mark_exports { program = program, prefix_of = fst o prep_sym,
 | 
| 
ee49b4f7edc8
keep only identifiers public which are explicitly requested or demanded by dependencies
 haftmann parents: 
55683diff
changeset | 366 | map_export = fn name_fragments => fn sym => fn f => | 
| 
ee49b4f7edc8
keep only identifiers public which are explicitly requested or demanded by dependencies
 haftmann parents: 
55683diff
changeset | 367 | (map_module name_fragments o apsnd o Code_Symbol.Graph.map_node sym o apsnd) | 
| 
ee49b4f7edc8
keep only identifiers public which are explicitly requested or demanded by dependencies
 haftmann parents: 
55683diff
changeset | 368 | (fn Stmt (export, stmt) => Stmt (f export, stmt)), | 
| 
ee49b4f7edc8
keep only identifiers public which are explicitly requested or demanded by dependencies
 haftmann parents: 
55683diff
changeset | 369 | class_transitive = class_transitive, class_relation_public = class_relation_public }; | 
| 55147 
bce3dbc11f95
prefer explicit code symbol type over ad-hoc name mangling
 haftmann parents: 
53414diff
changeset | 370 | fun add_stmt sym stmt = | 
| 38970 
53d1ee3d98b8
factored out generic part of Scala serializer into code_namespace.ML
 haftmann parents: diff
changeset | 371 | let | 
| 55147 
bce3dbc11f95
prefer explicit code symbol type over ad-hoc name mangling
 haftmann parents: 
53414diff
changeset | 372 | val (name_fragments, base) = prep_sym sym; | 
| 38970 
53d1ee3d98b8
factored out generic part of Scala serializer into code_namespace.ML
 haftmann parents: diff
changeset | 373 | in | 
| 55680 | 374 | (map_module name_fragments o apsnd) | 
| 55684 
ee49b4f7edc8
keep only identifiers public which are explicitly requested or demanded by dependencies
 haftmann parents: 
55683diff
changeset | 375 | (Code_Symbol.Graph.new_node (sym, (base, Stmt (if null exports then Public else Private, stmt)))) | 
| 38970 
53d1ee3d98b8
factored out generic part of Scala serializer into code_namespace.ML
 haftmann parents: diff
changeset | 376 | end; | 
| 55680 | 377 | fun add_edge_acyclic_error error_msg dep gr = | 
| 378 | Code_Symbol.Graph.add_edge_acyclic dep gr | |
| 57428 | 379 | handle Code_Symbol.Graph.CYCLES _ => error (error_msg ()) | 
| 55292 | 380 | fun add_dep sym sym' = | 
| 38970 
53d1ee3d98b8
factored out generic part of Scala serializer into code_namespace.ML
 haftmann parents: diff
changeset | 381 | let | 
| 55147 
bce3dbc11f95
prefer explicit code symbol type over ad-hoc name mangling
 haftmann parents: 
53414diff
changeset | 382 | val (name_fragments, _) = prep_sym sym; | 
| 
bce3dbc11f95
prefer explicit code symbol type over ad-hoc name mangling
 haftmann parents: 
53414diff
changeset | 383 | val (name_fragments', _) = prep_sym sym'; | 
| 38970 
53d1ee3d98b8
factored out generic part of Scala serializer into code_namespace.ML
 haftmann parents: diff
changeset | 384 | val (name_fragments_common, (diff, diff')) = | 
| 
53d1ee3d98b8
factored out generic part of Scala serializer into code_namespace.ML
 haftmann parents: diff
changeset | 385 | chop_prefix (op =) (name_fragments, name_fragments'); | 
| 55680 | 386 | val is_cross_module = not (null diff andalso null diff'); | 
| 59058 
a78612c67ec0
renamed "pairself" to "apply2", in accordance to @{apply 2};
 wenzelm parents: 
58520diff
changeset | 387 | val dep = apply2 hd (map Code_Symbol.Module diff @ [sym], map Code_Symbol.Module diff' @ [sym']); | 
| 55680 | 388 | val add_edge = if is_cross_module andalso not cyclic_modules | 
| 389 | then add_edge_acyclic_error (fn _ => "Dependency " | |
| 390 | ^ Code_Symbol.quote ctxt sym ^ " -> " | |
| 391 | ^ Code_Symbol.quote ctxt sym' | |
| 392 | ^ " would result in module dependency cycle") dep | |
| 393 | else Code_Symbol.Graph.add_edge dep; | |
| 55684 
ee49b4f7edc8
keep only identifiers public which are explicitly requested or demanded by dependencies
 haftmann parents: 
55683diff
changeset | 394 | in | 
| 
ee49b4f7edc8
keep only identifiers public which are explicitly requested or demanded by dependencies
 haftmann parents: 
55683diff
changeset | 395 | (map_module name_fragments_common o apsnd) add_edge | 
| 
ee49b4f7edc8
keep only identifiers public which are explicitly requested or demanded by dependencies
 haftmann parents: 
55683diff
changeset | 396 | #> (if is_cross_module then mark_exports name_fragments' sym' else I) | 
| 
ee49b4f7edc8
keep only identifiers public which are explicitly requested or demanded by dependencies
 haftmann parents: 
55683diff
changeset | 397 | end; | 
| 55292 | 398 | val proto_program = build_proto_program | 
| 55684 
ee49b4f7edc8
keep only identifiers public which are explicitly requested or demanded by dependencies
 haftmann parents: 
55683diff
changeset | 399 |       { empty = empty_program, add_stmt = add_stmt, add_dep = add_dep } program
 | 
| 
ee49b4f7edc8
keep only identifiers public which are explicitly requested or demanded by dependencies
 haftmann parents: 
55683diff
changeset | 400 | |> fold (fn sym => mark_exports ((fst o prep_sym) sym) sym) exports; | 
| 38970 
53d1ee3d98b8
factored out generic part of Scala serializer into code_namespace.ML
 haftmann parents: diff
changeset | 401 | |
| 39022 | 402 | (* name declarations, data and statement modifications *) | 
| 38970 
53d1ee3d98b8
factored out generic part of Scala serializer into code_namespace.ML
 haftmann parents: diff
changeset | 403 | fun make_declarations nsps (data, nodes) = | 
| 
53d1ee3d98b8
factored out generic part of Scala serializer into code_namespace.ML
 haftmann parents: diff
changeset | 404 | let | 
| 55293 
42cf5802d36a
code generation: explicitly declared identifiers gain predence over implicit ones
 haftmann parents: 
55292diff
changeset | 405 | val (module_fragments, stmt_syms) = | 
| 
42cf5802d36a
code generation: explicitly declared identifiers gain predence over implicit ones
 haftmann parents: 
55292diff
changeset | 406 | Code_Symbol.Graph.keys nodes | 
| 
42cf5802d36a
code generation: explicitly declared identifiers gain predence over implicit ones
 haftmann parents: 
55292diff
changeset | 407 | |> List.partition | 
| 
42cf5802d36a
code generation: explicitly declared identifiers gain predence over implicit ones
 haftmann parents: 
55292diff
changeset | 408 | (fn sym => case Code_Symbol.Graph.get_node nodes sym | 
| 
42cf5802d36a
code generation: explicitly declared identifiers gain predence over implicit ones
 haftmann parents: 
55292diff
changeset | 409 | of (_, Module _) => true | _ => false) | 
| 59058 
a78612c67ec0
renamed "pairself" to "apply2", in accordance to @{apply 2};
 wenzelm parents: 
58520diff
changeset | 410 | |> apply2 (prioritize sym_priority) | 
| 55147 
bce3dbc11f95
prefer explicit code symbol type over ad-hoc name mangling
 haftmann parents: 
53414diff
changeset | 411 | fun declare namify sym (nsps, nodes) = | 
| 38970 
53d1ee3d98b8
factored out generic part of Scala serializer into code_namespace.ML
 haftmann parents: diff
changeset | 412 | let | 
| 55147 
bce3dbc11f95
prefer explicit code symbol type over ad-hoc name mangling
 haftmann parents: 
53414diff
changeset | 413 | val (base, node) = Code_Symbol.Graph.get_node nodes sym; | 
| 38970 
53d1ee3d98b8
factored out generic part of Scala serializer into code_namespace.ML
 haftmann parents: diff
changeset | 414 | val (base', nsps') = namify node base nsps; | 
| 55147 
bce3dbc11f95
prefer explicit code symbol type over ad-hoc name mangling
 haftmann parents: 
53414diff
changeset | 415 | val nodes' = Code_Symbol.Graph.map_node sym (K (base', node)) nodes; | 
| 38970 
53d1ee3d98b8
factored out generic part of Scala serializer into code_namespace.ML
 haftmann parents: diff
changeset | 416 | in (nsps', nodes') end; | 
| 
53d1ee3d98b8
factored out generic part of Scala serializer into code_namespace.ML
 haftmann parents: diff
changeset | 417 | val (nsps', nodes') = (nsps, nodes) | 
| 39022 | 418 | |> fold (declare (K namify_module)) module_fragments | 
| 55679 | 419 | |> fold (declare (namify_stmt o snd o the_stmt)) stmt_syms; | 
| 55680 | 420 | fun modify_stmts' syms_stmts = | 
| 55605 | 421 | let | 
| 55680 | 422 | val stmts' = modify_stmts syms_stmts | 
| 423 | in stmts' @ replicate (length syms_stmts - length stmts') NONE end; | |
| 424 | val nodes'' = | |
| 425 | nodes' | |
| 55684 
ee49b4f7edc8
keep only identifiers public which are explicitly requested or demanded by dependencies
 haftmann parents: 
55683diff
changeset | 426 | |> Code_Symbol.Graph.map_strong_conn (map_module_stmts (make_declarations nsps') modify_stmts'); | 
| 55147 
bce3dbc11f95
prefer explicit code symbol type over ad-hoc name mangling
 haftmann parents: 
53414diff
changeset | 427 | val data' = fold memorize_data stmt_syms data; | 
| 39018 | 428 | in (data', nodes'') end; | 
| 38970 
53d1ee3d98b8
factored out generic part of Scala serializer into code_namespace.ML
 haftmann parents: diff
changeset | 429 | val (_, hierarchical_program) = make_declarations empty_nsp proto_program; | 
| 
53d1ee3d98b8
factored out generic part of Scala serializer into code_namespace.ML
 haftmann parents: diff
changeset | 430 | |
| 
53d1ee3d98b8
factored out generic part of Scala serializer into code_namespace.ML
 haftmann parents: diff
changeset | 431 | (* deresolving *) | 
| 55147 
bce3dbc11f95
prefer explicit code symbol type over ad-hoc name mangling
 haftmann parents: 
53414diff
changeset | 432 | fun deresolver prefix_fragments sym = | 
| 38970 
53d1ee3d98b8
factored out generic part of Scala serializer into code_namespace.ML
 haftmann parents: diff
changeset | 433 | let | 
| 55147 
bce3dbc11f95
prefer explicit code symbol type over ad-hoc name mangling
 haftmann parents: 
53414diff
changeset | 434 | val (name_fragments, _) = prep_sym sym; | 
| 38970 
53d1ee3d98b8
factored out generic part of Scala serializer into code_namespace.ML
 haftmann parents: diff
changeset | 435 | val (_, (_, remainder)) = chop_prefix (op =) (prefix_fragments, name_fragments); | 
| 55147 
bce3dbc11f95
prefer explicit code symbol type over ad-hoc name mangling
 haftmann parents: 
53414diff
changeset | 436 | val nodes = fold (fn name_fragment => fn nodes => case Code_Symbol.Graph.get_node nodes (Code_Symbol.Module name_fragment) | 
| 38970 
53d1ee3d98b8
factored out generic part of Scala serializer into code_namespace.ML
 haftmann parents: diff
changeset | 437 | of (_, Module (_, nodes)) => nodes) name_fragments hierarchical_program; | 
| 55147 
bce3dbc11f95
prefer explicit code symbol type over ad-hoc name mangling
 haftmann parents: 
53414diff
changeset | 438 | val (base', _) = Code_Symbol.Graph.get_node nodes sym; | 
| 38970 
53d1ee3d98b8
factored out generic part of Scala serializer into code_namespace.ML
 haftmann parents: diff
changeset | 439 | in Long_Name.implode (remainder @ [base']) end | 
| 55147 
bce3dbc11f95
prefer explicit code symbol type over ad-hoc name mangling
 haftmann parents: 
53414diff
changeset | 440 |         handle Code_Symbol.Graph.UNDEF _ => error ("Unknown statement name: "
 | 
| 
bce3dbc11f95
prefer explicit code symbol type over ad-hoc name mangling
 haftmann parents: 
53414diff
changeset | 441 | ^ Code_Symbol.quote ctxt sym); | 
| 38970 
53d1ee3d98b8
factored out generic part of Scala serializer into code_namespace.ML
 haftmann parents: diff
changeset | 442 | |
| 
53d1ee3d98b8
factored out generic part of Scala serializer into code_namespace.ML
 haftmann parents: diff
changeset | 443 |   in { deresolver = deresolver, hierarchical_program = hierarchical_program } end;
 | 
| 
53d1ee3d98b8
factored out generic part of Scala serializer into code_namespace.ML
 haftmann parents: diff
changeset | 444 | |
| 39147 | 445 | fun print_hierarchical { print_module, print_stmt, lift_markup } =
 | 
| 446 | let | |
| 447 | fun print_node _ (_, Dummy) = | |
| 448 | NONE | |
| 55147 
bce3dbc11f95
prefer explicit code symbol type over ad-hoc name mangling
 haftmann parents: 
53414diff
changeset | 449 | | print_node prefix_fragments (sym, Stmt stmt) = | 
| 
bce3dbc11f95
prefer explicit code symbol type over ad-hoc name mangling
 haftmann parents: 
53414diff
changeset | 450 | SOME (lift_markup (Code_Printer.markup_stmt sym) | 
| 
bce3dbc11f95
prefer explicit code symbol type over ad-hoc name mangling
 haftmann parents: 
53414diff
changeset | 451 | (print_stmt prefix_fragments (sym, stmt))) | 
| 
bce3dbc11f95
prefer explicit code symbol type over ad-hoc name mangling
 haftmann parents: 
53414diff
changeset | 452 | | print_node prefix_fragments (Code_Symbol.Module name_fragment, Module (data, nodes)) = | 
| 39147 | 453 | let | 
| 454 | val prefix_fragments' = prefix_fragments @ [name_fragment] | |
| 455 | in | |
| 456 | Option.map (print_module prefix_fragments' | |
| 457 | name_fragment data) (print_nodes prefix_fragments' nodes) | |
| 458 | end | |
| 459 | and print_nodes prefix_fragments nodes = | |
| 460 | let | |
| 55147 
bce3dbc11f95
prefer explicit code symbol type over ad-hoc name mangling
 haftmann parents: 
53414diff
changeset | 461 | val xs = (map_filter (fn sym => print_node prefix_fragments | 
| 
bce3dbc11f95
prefer explicit code symbol type over ad-hoc name mangling
 haftmann parents: 
53414diff
changeset | 462 | (sym, snd (Code_Symbol.Graph.get_node nodes sym))) o rev o flat o Code_Symbol.Graph.strong_conn) nodes | 
| 39147 | 463 | in if null xs then NONE else SOME xs end; | 
| 464 | in these o print_nodes [] end; | |
| 465 | ||
| 55147 
bce3dbc11f95
prefer explicit code symbol type over ad-hoc name mangling
 haftmann parents: 
53414diff
changeset | 466 | end; |