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