| author | haftmann |
| Fri, 03 Feb 2006 08:48:33 +0100 | |
| changeset 18916 | fda5b8dbbef6 |
| parent 18912 | dd168daf172d |
| child 18918 | 5590770e1b09 |
| permissions | -rw-r--r-- |
|
18380
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
1 |
(* Title: Pure/Tools/codegen_thingol.ML |
|
18169
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
2 |
ID: $Id$ |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
3 |
Author: Florian Haftmann, TU Muenchen |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
4 |
|
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
5 |
Intermediate language ("Thin-gol") for code extraction.
|
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
6 |
*) |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
7 |
|
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
8 |
signature CODEGEN_THINGOL = |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
9 |
sig |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
10 |
type vname = string; |
| 18885 | 11 |
datatype classlookup = Instance of string * classlookup list list |
12 |
| Lookup of class list * (string * int); |
|
|
18169
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
13 |
datatype itype = |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
14 |
IType of string * itype list |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
15 |
| IFun of itype * itype |
| 18885 | 16 |
| IVarT of vname * sort; |
|
18169
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
17 |
datatype iexpr = |
| 18885 | 18 |
IConst of (string * itype) * classlookup list list |
|
18169
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
19 |
| IVarE of vname * itype |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
20 |
| IApp of iexpr * iexpr |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
21 |
| IAbs of (vname * itype) * iexpr |
| 18885 | 22 |
| ICase of iexpr * (iexpr * iexpr) list; |
|
18169
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
23 |
val mk_funs: itype list * itype -> itype; |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
24 |
val mk_apps: iexpr * iexpr list -> iexpr; |
|
18247
b17724cae935
code generator: case expressions, improved name resolving
haftmann
parents:
18231
diff
changeset
|
25 |
val mk_abss: (vname * itype) list * iexpr -> iexpr; |
|
18169
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
26 |
val pretty_itype: itype -> Pretty.T; |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
27 |
val pretty_iexpr: iexpr -> Pretty.T; |
| 18216 | 28 |
val unfoldl: ('a -> ('a * 'b) option) -> 'a -> 'a * 'b list;
|
29 |
val unfoldr: ('a -> ('b * 'a) option) -> 'a -> 'b list * 'a;
|
|
|
18169
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
30 |
val unfold_fun: itype -> itype list * itype; |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
31 |
val unfold_app: iexpr -> iexpr * iexpr list; |
| 18282 | 32 |
val unfold_abs: iexpr -> (vname * itype) list * iexpr; |
| 18865 | 33 |
val unfold_let: iexpr -> (iexpr * iexpr) list * iexpr; |
34 |
val unfold_const_app: iexpr -> |
|
| 18885 | 35 |
(((string * itype) * classlookup list list) * iexpr list) option; |
| 18912 | 36 |
val ensure_pat: iexpr -> iexpr; |
|
18169
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
37 |
val itype_of_iexpr: iexpr -> itype; |
| 18170 | 38 |
|
| 18850 | 39 |
val `%% : string * itype list -> itype; |
40 |
val `-> : itype * itype -> itype; |
|
41 |
val `--> : itype list * itype -> itype; |
|
42 |
val `$ : iexpr * iexpr -> iexpr; |
|
43 |
val `$$ : iexpr * iexpr list -> iexpr; |
|
44 |
val `|-> : (vname * itype) * iexpr -> iexpr; |
|
45 |
val `|--> : (vname * itype) list * iexpr -> iexpr; |
|
46 |
||
| 18865 | 47 |
type funn = (iexpr list * iexpr) list * (ClassPackage.sortcontext * itype); |
| 18850 | 48 |
datatype prim = |
49 |
Pretty of Pretty.T |
|
50 |
| Name of string; |
|
| 18170 | 51 |
datatype def = |
| 18702 | 52 |
Undef |
53 |
| Prim of (string * Pretty.T option) list |
|
54 |
| Fun of funn |
|
| 18172 | 55 |
| Typesyn of (vname * string list) list * itype |
| 18850 | 56 |
| Datatype of ((vname * string list) list * (string * itype list) list) |
57 |
* string list |
|
|
18380
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
58 |
| Datatypecons of string |
| 18850 | 59 |
| Class of (class list * (vname * (string * (ClassPackage.sortcontext * itype)) list)) |
60 |
* string list |
|
|
18380
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
61 |
| Classmember of class |
| 18865 | 62 |
| Classinst of ((class * (string * (vname * sort) list)) |
| 18885 | 63 |
* (class * classlookup list list) list) |
| 18865 | 64 |
* (string * funn) list; |
| 18170 | 65 |
type module; |
66 |
type transact; |
|
67 |
type 'dst transact_fin; |
|
| 18702 | 68 |
type gen_defgen = string -> transact -> def transact_fin; |
| 18170 | 69 |
val pretty_def: def -> Pretty.T; |
| 18282 | 70 |
val pretty_module: module -> Pretty.T; |
| 18360 | 71 |
val pretty_deps: module -> Pretty.T; |
| 18170 | 72 |
val empty_module: module; |
| 18517 | 73 |
val add_prim: string -> string list -> (string * Pretty.T) -> module -> module; |
| 18702 | 74 |
val ensure_prim: string -> string -> module -> module; |
| 18170 | 75 |
val get_def: module -> string -> def; |
76 |
val merge_module: module * module -> module; |
|
77 |
val partof: string list -> module -> module; |
|
| 18516 | 78 |
val has_nsp: string -> string -> bool; |
| 18170 | 79 |
val succeed: 'a -> transact -> 'a transact_fin; |
80 |
val fail: string -> transact -> 'a transact_fin; |
|
81 |
val gen_ensure_def: (string * gen_defgen) list -> string |
|
82 |
-> string -> transact -> transact; |
|
| 18216 | 83 |
val start_transact: (transact -> 'a * transact) -> module -> 'a * module; |
84 |
||
| 18172 | 85 |
val eta_expand: (string -> int) -> module -> module; |
| 18216 | 86 |
val eta_expand_poly: module -> module; |
| 18885 | 87 |
val unclash_vars: module -> module; |
| 18172 | 88 |
|
| 18702 | 89 |
val debug_level: int ref; |
90 |
val debug: int -> ('a -> string) -> 'a -> 'a;
|
|
| 18231 | 91 |
val soft_exc: bool ref; |
| 18216 | 92 |
|
93 |
val serialize: |
|
| 18702 | 94 |
((string -> string) -> (string * def) list -> 'a option) |
| 18850 | 95 |
-> (string list -> (string * string) * 'a list -> 'a option) |
| 18216 | 96 |
-> (string -> string option) |
| 18850 | 97 |
-> string list list -> string -> module -> 'a option; |
|
18169
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
98 |
end; |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
99 |
|
| 18850 | 100 |
structure CodegenThingol: CODEGEN_THINGOL = |
|
18169
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
101 |
struct |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
102 |
|
| 18170 | 103 |
(** auxiliary **) |
|
18169
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
104 |
|
| 18170 | 105 |
val debug_level = ref 0; |
106 |
fun debug d f x = (if d <= !debug_level then Output.debug (f x) else (); x); |
|
| 18231 | 107 |
val soft_exc = ref true; |
|
18169
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
108 |
|
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
109 |
fun unfoldl dest x = |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
110 |
case dest x |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
111 |
of NONE => (x, []) |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
112 |
| SOME (x1, x2) => |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
113 |
let val (x', xs') = unfoldl dest x1 in (x', xs' @ [x2]) end; |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
114 |
|
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
115 |
fun unfoldr dest x = |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
116 |
case dest x |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
117 |
of NONE => ([], x) |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
118 |
| SOME (x1, x2) => |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
119 |
let val (xs', x') = unfoldr dest x2 in (x1::xs', x') end; |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
120 |
|
| 18172 | 121 |
fun map_yield f [] = ([], []) |
122 |
| map_yield f (x::xs) = |
|
123 |
let |
|
124 |
val (y, x') = f x |
|
125 |
val (ys, xs') = map_yield f xs |
|
126 |
in (y::ys, x'::xs') end; |
|
127 |
||
| 18454 | 128 |
fun get_prefix eq ([], ys) = ([], ([], ys)) |
129 |
| get_prefix eq (xs, []) = ([], (xs, [])) |
|
| 18170 | 130 |
| get_prefix eq (xs as x::xs', ys as y::ys') = |
131 |
if eq (x, y) then |
|
| 18454 | 132 |
let val (ps', xys'') = get_prefix eq (xs', ys') |
133 |
in (x::ps', xys'') end |
|
134 |
else ([], (xs, ys)); |
|
| 18170 | 135 |
|
136 |
||
137 |
(** language core - types, pattern, expressions **) |
|
|
18169
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
138 |
|
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
139 |
(* language representation *) |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
140 |
|
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
141 |
infix 8 `%%; |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
142 |
infixr 6 `->; |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
143 |
infixr 6 `-->; |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
144 |
infix 4 `$; |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
145 |
infix 4 `$$; |
| 18885 | 146 |
infixr 3 `|->; |
147 |
infixr 3 `|-->; |
|
|
18169
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
148 |
|
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
149 |
type vname = string; |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
150 |
|
| 18885 | 151 |
datatype classlookup = Instance of string * classlookup list list |
152 |
| Lookup of class list * (string * int); |
|
153 |
||
|
18169
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
154 |
datatype itype = |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
155 |
IType of string * itype list |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
156 |
| IFun of itype * itype |
| 18885 | 157 |
| IVarT of vname * sort; |
|
18169
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
158 |
|
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
159 |
datatype iexpr = |
| 18885 | 160 |
IConst of (string * itype) * classlookup list list |
|
18169
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
161 |
| IVarE of vname * itype |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
162 |
| IApp of iexpr * iexpr |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
163 |
| IAbs of (vname * itype) * iexpr |
| 18885 | 164 |
| ICase of iexpr * (iexpr * iexpr) list; |
|
18169
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
165 |
|
|
18380
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
166 |
(* |
|
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
167 |
variable naming conventions |
|
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
168 |
|
|
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
169 |
bare names: |
|
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
170 |
variable names v |
|
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
171 |
class names cls |
|
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
172 |
type constructor names tyco |
|
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
173 |
datatype names dtco |
|
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
174 |
const names (general) c |
|
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
175 |
constructor names co |
|
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
176 |
class member names m |
|
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
177 |
arbitrary name s |
|
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
178 |
|
|
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
179 |
constructs: |
|
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
180 |
sort sort |
|
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
181 |
type ty |
|
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
182 |
expression e |
| 18702 | 183 |
pattern p, pat |
|
18380
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
184 |
instance (cls, tyco) inst |
|
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
185 |
variable (v, ty) var |
|
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
186 |
class member (m, ty) membr |
|
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
187 |
constructors (co, tys) constr |
|
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
188 |
*) |
|
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
189 |
|
|
18169
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
190 |
val mk_funs = Library.foldr IFun; |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
191 |
val mk_apps = Library.foldl IApp; |
|
18247
b17724cae935
code generator: case expressions, improved name resolving
haftmann
parents:
18231
diff
changeset
|
192 |
val mk_abss = Library.foldr IAbs; |
|
18169
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
193 |
|
|
18247
b17724cae935
code generator: case expressions, improved name resolving
haftmann
parents:
18231
diff
changeset
|
194 |
val op `%% = IType; |
|
18169
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
195 |
val op `-> = IFun; |
|
18247
b17724cae935
code generator: case expressions, improved name resolving
haftmann
parents:
18231
diff
changeset
|
196 |
val op `$ = IApp; |
|
b17724cae935
code generator: case expressions, improved name resolving
haftmann
parents:
18231
diff
changeset
|
197 |
val op `|-> = IAbs; |
|
18169
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
198 |
val op `--> = mk_funs; |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
199 |
val op `$$ = mk_apps; |
|
18247
b17724cae935
code generator: case expressions, improved name resolving
haftmann
parents:
18231
diff
changeset
|
200 |
val op `|--> = mk_abss; |
|
18169
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
201 |
|
| 18885 | 202 |
fun pretty_itype (IType (tyco, tys)) = |
203 |
Pretty.enum "" "(" ")" (Pretty.str tyco :: map pretty_itype tys)
|
|
204 |
| pretty_itype (IFun (ty1, ty2)) = |
|
205 |
Pretty.enum "" "(" ")" [pretty_itype ty1, Pretty.str "->", pretty_itype ty2]
|
|
206 |
| pretty_itype (IVarT (v, sort)) = |
|
207 |
Pretty.str (v ^ enclose "|" "|" (space_implode "|" sort)); |
|
208 |
||
209 |
fun pretty_iexpr (IConst ((c, ty), _)) = |
|
210 |
Pretty.block [Pretty.str (c ^ "::"), pretty_itype ty] |
|
211 |
| pretty_iexpr (IVarE (v, ty)) = |
|
212 |
Pretty.block [Pretty.str ("?" ^ v ^ "::"), pretty_itype ty]
|
|
213 |
| pretty_iexpr (IApp (e1, e2)) = |
|
214 |
Pretty.enclose "(" ")" [pretty_iexpr e1, Pretty.brk 1, pretty_iexpr e2]
|
|
215 |
| pretty_iexpr (IAbs ((v, ty), e)) = |
|
216 |
Pretty.enclose "(" ")" [Pretty.str ("?" ^ v ^ " |->"), Pretty.brk 1, pretty_iexpr e]
|
|
217 |
| pretty_iexpr (ICase (e, cs)) = |
|
218 |
Pretty.enclose "(" ")" [
|
|
219 |
Pretty.str "case ", |
|
220 |
pretty_iexpr e, |
|
221 |
Pretty.enclose "(" ")" (map (fn (p, e) =>
|
|
222 |
Pretty.block [ |
|
223 |
pretty_iexpr p, |
|
224 |
Pretty.str " => ", |
|
225 |
pretty_iexpr e |
|
226 |
] |
|
227 |
) cs) |
|
228 |
]; |
|
229 |
||
|
18169
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
230 |
val unfold_fun = unfoldr |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
231 |
(fn IFun t => SOME t |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
232 |
| _ => NONE); |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
233 |
|
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
234 |
val unfold_app = unfoldl |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
235 |
(fn IApp e => SOME e |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
236 |
| _ => NONE); |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
237 |
|
| 18282 | 238 |
val unfold_abs = unfoldr |
239 |
(fn IAbs b => SOME b |
|
240 |
| _ => NONE) |
|
241 |
||
|
18169
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
242 |
val unfold_let = unfoldr |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
243 |
(fn ICase (e, [(p, e')]) => SOME ((p, e), e') |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
244 |
| _ => NONE); |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
245 |
|
| 18865 | 246 |
fun unfold_const_app e = |
247 |
case unfold_app e |
|
248 |
of (IConst x, es) => SOME (x, es) |
|
249 |
| _ => NONE; |
|
250 |
||
| 18172 | 251 |
fun map_itype f_itype (IType (tyco, tys)) = |
252 |
tyco `%% map f_itype tys |
|
253 |
| map_itype f_itype (IFun (t1, t2)) = |
|
254 |
f_itype t1 `-> f_itype t2 |
|
255 |
| map_itype _ (ty as IVarT _) = |
|
256 |
ty; |
|
257 |
||
| 18885 | 258 |
fun map_iexpr f (IApp (e1, e2)) = |
259 |
f e1 `$ f e2 |
|
260 |
| map_iexpr f (IAbs (v, e)) = |
|
261 |
v `|-> f e |
|
262 |
| map_iexpr f (ICase (e, ps)) = |
|
263 |
ICase (f e, map (fn (p, e) => (f p, f e)) ps) |
|
264 |
| map_iexpr _ (e as IConst _) = |
|
| 18172 | 265 |
e |
| 18885 | 266 |
| map_iexpr _ (e as IVarE _) = |
| 18865 | 267 |
e; |
| 18172 | 268 |
|
| 18885 | 269 |
fun map_atype f (ty as IVarT _) = |
270 |
f ty |
|
271 |
| map_atype f ty = |
|
272 |
map_itype (map_atype f) ty; |
|
273 |
||
274 |
fun map_aexpr f (e as IConst _) = |
|
275 |
f e |
|
276 |
| map_aexpr f (e as IVarE _) = |
|
277 |
f e |
|
278 |
| map_aexpr f e = |
|
279 |
map_iexpr (map_aexpr f) e; |
|
280 |
||
281 |
fun map_iexpr_itype f = |
|
282 |
let |
|
283 |
fun mapp (IConst ((c, ty), ctxt)) = IConst ((c, f ty), ctxt) |
|
284 |
| mapp (IVarE (v, ty)) = IVarE (v, f ty) |
|
285 |
in map_aexpr mapp end; |
|
| 18172 | 286 |
|
| 18885 | 287 |
fun fold_atype f (IFun (ty1, ty2)) = |
288 |
fold_atype f ty1 #> fold_atype f ty2 |
|
289 |
| fold_atype f (ty as IType _) = |
|
290 |
f ty |
|
291 |
| fold_atype f (ty as IVarT _) = |
|
292 |
f ty; |
|
| 18172 | 293 |
|
| 18885 | 294 |
fun fold_aexpr f (IApp (e1, e2)) = |
295 |
fold_aexpr f e1 #> fold_aexpr f e2 |
|
296 |
| fold_aexpr f (IAbs (v, e)) = |
|
297 |
fold_aexpr f e |
|
298 |
| fold_aexpr f (ICase (e, ps)) = |
|
299 |
fold_aexpr f e #> fold (fn (p, e) => fold_aexpr f p #> fold_aexpr f e) ps |
|
300 |
| fold_aexpr f (e as IConst _) = |
|
301 |
f e |
|
302 |
| fold_aexpr f (e as IVarE _) = |
|
303 |
f e; |
|
| 18282 | 304 |
|
305 |
fun eq_itype (ty1, ty2) = |
|
306 |
let |
|
307 |
exception NO_MATCH; |
|
308 |
fun eq (IVarT (v1, sort1)) (IVarT (v2, sort2)) subs = |
|
309 |
if sort1 <> sort2 |
|
310 |
then raise NO_MATCH |
|
311 |
else |
|
312 |
(case AList.lookup (op =) subs v1 |
|
313 |
of NONE => subs |> AList.update (op =) (v1, v2) |
|
314 |
| (SOME v1') => |
|
315 |
if v1' <> v2 |
|
316 |
then raise NO_MATCH |
|
317 |
else subs) |
|
318 |
| eq (IType (tyco1, tys1)) (IType (tyco2, tys2)) subs = |
|
319 |
if tyco1 <> tyco2 |
|
320 |
then raise NO_MATCH |
|
321 |
else subs |> fold2 eq tys1 tys2 |
|
322 |
| eq (IFun (ty11, ty12)) (IFun (ty21, ty22)) subs = |
|
323 |
subs |> eq ty11 ty21 |> eq ty12 ty22 |
|
324 |
| eq _ _ _ = raise NO_MATCH; |
|
325 |
in |
|
326 |
(eq ty1 ty2 []; true) |
|
327 |
handle NO_MATCH => false |
|
328 |
end; |
|
329 |
||
| 18885 | 330 |
fun instant_itype f = |
331 |
let |
|
332 |
fun instant (IVarT x) = f x |
|
333 |
| instant y = map_itype instant y; |
|
334 |
in map_itype instant end; |
|
335 |
||
| 18282 | 336 |
|
|
18169
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
337 |
(* simple diagnosis *) |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
338 |
|
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
339 |
fun pretty_itype (IType (tyco, tys)) = |
| 18812 | 340 |
Pretty.enum "" "(" ")" (Pretty.str tyco :: map pretty_itype tys)
|
|
18169
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
341 |
| pretty_itype (IFun (ty1, ty2)) = |
| 18812 | 342 |
Pretty.enum "" "(" ")" [pretty_itype ty1, Pretty.str "->", pretty_itype ty2]
|
|
18169
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
343 |
| pretty_itype (IVarT (v, sort)) = |
| 18885 | 344 |
Pretty.str (v ^ enclose "|" "|" (space_implode "|" sort)); |
|
18169
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
345 |
|
| 18865 | 346 |
fun pretty_iexpr (IConst ((c, ty), _)) = |
347 |
Pretty.block [Pretty.str (c ^ "::"), pretty_itype ty] |
|
|
18169
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
348 |
| pretty_iexpr (IVarE (v, ty)) = |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
349 |
Pretty.block [Pretty.str ("?" ^ v ^ "::"), pretty_itype ty]
|
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
350 |
| pretty_iexpr (IApp (e1, e2)) = |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
351 |
Pretty.enclose "(" ")" [pretty_iexpr e1, Pretty.brk 1, pretty_iexpr e2]
|
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
352 |
| pretty_iexpr (IAbs ((v, ty), e)) = |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
353 |
Pretty.enclose "(" ")" [Pretty.str ("?" ^ v ^ " |->"), Pretty.brk 1, pretty_iexpr e]
|
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
354 |
| pretty_iexpr (ICase (e, cs)) = |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
355 |
Pretty.enclose "(" ")" [
|
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
356 |
Pretty.str "case ", |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
357 |
pretty_iexpr e, |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
358 |
Pretty.enclose "(" ")" (map (fn (p, e) =>
|
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
359 |
Pretty.block [ |
| 18865 | 360 |
pretty_iexpr p, |
|
18169
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
361 |
Pretty.str " => ", |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
362 |
pretty_iexpr e |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
363 |
] |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
364 |
) cs) |
| 18885 | 365 |
]; |
|
18169
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
366 |
|
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
367 |
|
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
368 |
(* language auxiliary *) |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
369 |
|
| 18865 | 370 |
fun itype_of_iexpr (IConst ((_, ty), s)) = ty |
|
18169
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
371 |
| itype_of_iexpr (IVarE (_, ty)) = ty |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
372 |
| itype_of_iexpr (e as IApp (e1, e2)) = (case itype_of_iexpr e1 |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
373 |
of (IFun (ty2, ty')) => |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
374 |
if ty2 = itype_of_iexpr e2 |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
375 |
then ty' |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
376 |
else error ("inconsistent application: in " ^ Pretty.output (pretty_iexpr e)
|
| 18850 | 377 |
^ ", " ^ (Pretty.output o pretty_itype) ty2 |
378 |
^ " vs. " ^ (Pretty.output o pretty_itype o itype_of_iexpr) e2) |
|
|
18169
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
379 |
| _ => error ("expression is not a function: " ^ Pretty.output (pretty_iexpr e1)))
|
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
380 |
| itype_of_iexpr (IAbs ((_, ty1), e2)) = ty1 `-> itype_of_iexpr e2 |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
381 |
| itype_of_iexpr (ICase ((_, [(_, e)]))) = itype_of_iexpr e; |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
382 |
|
| 18912 | 383 |
fun ensure_pat (e as IConst (_, [])) = e |
384 |
| ensure_pat (e as IVarE _) = e |
|
385 |
| ensure_pat (e as IApp (e1, e2)) = |
|
386 |
(ensure_pat e1 `$ ensure_pat e2; e) |
|
387 |
| ensure_pat e = |
|
388 |
error ("illegal expression for pattern: " ^ (Pretty.output o pretty_iexpr) e);
|
|
389 |
||
| 18885 | 390 |
fun type_vnames ty = |
| 18216 | 391 |
let |
| 18885 | 392 |
fun extr (IVarT (v, _)) = |
393 |
insert (op =) v |
|
394 |
in fold_atype extr ty end; |
|
| 18216 | 395 |
|
| 18885 | 396 |
fun expr_names e = |
|
18169
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
397 |
let |
| 18885 | 398 |
fun extr (IConst ((c, _), _)) = |
| 18865 | 399 |
insert (op =) c |
| 18885 | 400 |
| extr (IVarE (v, _)) = |
| 18304 | 401 |
insert (op =) v |
| 18885 | 402 |
in fold_aexpr extr e end; |
403 |
||
404 |
fun invent seed used = |
|
405 |
let |
|
406 |
val x = Term.variant used seed |
|
407 |
in (x, x :: used) end; |
|
408 |
||
| 18304 | 409 |
|
| 18282 | 410 |
|
| 18170 | 411 |
(** language module system - definitions, modules, transactions **) |
412 |
||
413 |
(* type definitions *) |
|
414 |
||
| 18865 | 415 |
type funn = (iexpr list * iexpr) list * (ClassPackage.sortcontext * itype); |
| 18702 | 416 |
|
| 18850 | 417 |
datatype prim = |
418 |
Pretty of Pretty.T |
|
419 |
| Name of string; |
|
420 |
||
| 18170 | 421 |
datatype def = |
| 18702 | 422 |
Undef |
423 |
| Prim of (string * Pretty.T option) list |
|
424 |
| Fun of funn |
|
| 18172 | 425 |
| Typesyn of (vname * string list) list * itype |
| 18850 | 426 |
| Datatype of ((vname * string list) list * (string * itype list) list) |
427 |
* string list |
|
|
18380
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
428 |
| Datatypecons of string |
| 18850 | 429 |
| Class of (class list * (vname * (string * (ClassPackage.sortcontext * itype)) list)) |
430 |
* string list |
|
|
18380
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
431 |
| Classmember of class |
| 18865 | 432 |
| Classinst of ((class * (string * (vname * sort) list)) |
| 18885 | 433 |
* (class * classlookup list list) list) |
| 18865 | 434 |
* (string * funn) list; |
| 18170 | 435 |
|
436 |
datatype node = Def of def | Module of node Graph.T; |
|
437 |
type module = node Graph.T; |
|
| 18702 | 438 |
type transact = Graph.key option * module; |
| 18231 | 439 |
datatype 'dst transact_res = Succeed of 'dst | Fail of string list * exn option; |
| 18702 | 440 |
type 'dst transact_fin = 'dst transact_res * module; |
441 |
type gen_defgen = string -> transact -> def transact_fin; |
|
| 18231 | 442 |
exception FAIL of string list * exn option; |
| 18170 | 443 |
|
444 |
val eq_def = (op =); |
|
445 |
||
446 |
(* simple diagnosis *) |
|
447 |
||
| 18702 | 448 |
fun pretty_def Undef = |
449 |
Pretty.str "<UNDEF>" |
|
450 |
| pretty_def (Prim prims) = |
|
451 |
Pretty.str ("<PRIM " ^ (commas o map fst) prims ^ ">")
|
|
| 18170 | 452 |
| pretty_def (Fun (eqs, (_, ty))) = |
| 18812 | 453 |
Pretty.enum " |" "" "" ( |
| 18170 | 454 |
map (fn (ps, body) => |
455 |
Pretty.block [ |
|
| 18865 | 456 |
Pretty.enum "," "[" "]" (map pretty_iexpr ps), |
| 18170 | 457 |
Pretty.str " |->", |
458 |
Pretty.brk 1, |
|
459 |
pretty_iexpr body, |
|
460 |
Pretty.str "::", |
|
461 |
pretty_itype ty |
|
462 |
]) eqs |
|
463 |
) |
|
| 18172 | 464 |
| pretty_def (Typesyn (vs, ty)) = |
| 18170 | 465 |
Pretty.block [ |
466 |
Pretty.list "(" ")" (map (pretty_itype o IVarT) vs),
|
|
467 |
Pretty.str " |=> ", |
|
468 |
pretty_itype ty |
|
469 |
] |
|
| 18702 | 470 |
| pretty_def (Datatype ((vs, cs), insts)) = |
| 18170 | 471 |
Pretty.block [ |
472 |
Pretty.list "(" ")" (map (pretty_itype o IVarT) vs),
|
|
473 |
Pretty.str " |=> ", |
|
| 18852 | 474 |
Pretty.enum " |" "" "" |
| 18850 | 475 |
(map (fn (c, tys) => (Pretty.block o Pretty.breaks) |
476 |
(Pretty.str c :: map pretty_itype tys)) cs), |
|
| 18335 | 477 |
Pretty.str ", instances ", |
| 18812 | 478 |
Pretty.enum "," "[" "]" (map Pretty.str insts) |
| 18170 | 479 |
] |
|
18380
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
480 |
| pretty_def (Datatypecons dtname) = |
|
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
481 |
Pretty.str ("cons " ^ dtname)
|
| 18702 | 482 |
| pretty_def (Class ((supcls, (v, mems)), insts)) = |
| 18170 | 483 |
Pretty.block [ |
|
18380
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
484 |
Pretty.str ("class var " ^ v ^ "extending "),
|
| 18812 | 485 |
Pretty.enum "," "[" "]" (map Pretty.str supcls), |
| 18282 | 486 |
Pretty.str " with ", |
| 18852 | 487 |
Pretty.enum "," "[" "]" |
| 18850 | 488 |
(map (fn (m, (_, ty)) => Pretty.block |
489 |
[Pretty.str (m ^ "::"), pretty_itype ty]) mems), |
|
| 18282 | 490 |
Pretty.str " instances ", |
| 18812 | 491 |
Pretty.enum "," "[" "]" (map Pretty.str insts) |
| 18231 | 492 |
] |
|
18380
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
493 |
| pretty_def (Classmember clsname) = |
| 18231 | 494 |
Pretty.block [ |
495 |
Pretty.str "class member belonging to ", |
|
| 18282 | 496 |
Pretty.str clsname |
| 18231 | 497 |
] |
| 18865 | 498 |
| pretty_def (Classinst (((clsname, (tyco, arity)), _), _)) = |
| 18231 | 499 |
Pretty.block [ |
500 |
Pretty.str "class instance (",
|
|
| 18282 | 501 |
Pretty.str clsname, |
| 18231 | 502 |
Pretty.str ", (",
|
503 |
Pretty.str tyco, |
|
504 |
Pretty.str ", ", |
|
| 18852 | 505 |
Pretty.enum "," "[" "]" (map (Pretty.enum "," "{" "}" o
|
| 18850 | 506 |
map Pretty.str o snd) arity), |
| 18515 | 507 |
Pretty.str "))" |
| 18231 | 508 |
]; |
| 18170 | 509 |
|
510 |
fun pretty_module modl = |
|
511 |
let |
|
512 |
fun pretty (name, Module modl) = |
|
513 |
Pretty.block ( |
|
514 |
Pretty.str ("module " ^ name ^ " {")
|
|
515 |
:: Pretty.brk 1 |
|
516 |
:: Pretty.chunks (map pretty (AList.make (Graph.get_node modl) |
|
517 |
(Graph.strong_conn modl |> List.concat |> rev))) |
|
518 |
:: Pretty.str "}" :: nil |
|
519 |
) |
|
520 |
| pretty (name, Def def) = |
|
521 |
Pretty.block [Pretty.str name, Pretty.str " :=", Pretty.brk 1, pretty_def def] |
|
522 |
in pretty ("//", Module modl) end;
|
|
523 |
||
| 18360 | 524 |
fun pretty_deps modl = |
525 |
let |
|
526 |
fun one_node key = |
|
|
18380
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
527 |
let |
|
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
528 |
val preds_ = Graph.imm_preds modl key; |
|
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
529 |
val succs_ = Graph.imm_succs modl key; |
|
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
530 |
val mutbs = gen_inter (op =) (preds_, succs_); |
|
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
531 |
val preds = fold (remove (op =)) mutbs preds_; |
|
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
532 |
val succs = fold (remove (op =)) mutbs succs_; |
|
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
533 |
in |
|
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
534 |
(Pretty.block o Pretty.fbreaks) ( |
|
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
535 |
Pretty.str key |
|
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
536 |
:: map (fn s => Pretty.str ("<-> " ^ s)) mutbs
|
|
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
537 |
@ map (fn s => Pretty.str ("<-- " ^ s)) preds
|
|
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
538 |
@ map (fn s => Pretty.str ("--> " ^ s)) succs
|
| 18850 | 539 |
@ (the_list oo Option.mapPartial) |
540 |
((fn Module modl' => SOME (pretty_deps modl') |
|
541 |
| _ => NONE) o Graph.get_node modl) (SOME key) |
|
|
18380
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
542 |
) |
|
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
543 |
end |
| 18360 | 544 |
in |
545 |
modl |
|
546 |
|> Graph.strong_conn |
|
547 |
|> List.concat |
|
548 |
|> rev |
|
549 |
|> map one_node |
|
550 |
|> Pretty.chunks |
|
551 |
end; |
|
552 |
||
| 18170 | 553 |
|
554 |
(* name handling *) |
|
555 |
||
556 |
fun dest_name name = |
|
557 |
let |
|
558 |
val name' = NameSpace.unpack name |
|
559 |
val (name'', name_base) = split_last name' |
|
560 |
val (modl, shallow) = split_last name'' |
|
561 |
in (modl, NameSpace.pack [shallow, name_base]) end |
|
562 |
handle Empty => error ("not a qualified name: " ^ quote name);
|
|
563 |
||
| 18516 | 564 |
fun has_nsp name shallow = |
565 |
NameSpace.is_qualified name |
|
566 |
andalso let |
|
567 |
val name' = NameSpace.unpack name |
|
568 |
val (name'', _) = split_last name' |
|
569 |
val (_, shallow') = split_last name'' |
|
570 |
in shallow' = shallow end; |
|
571 |
||
| 18170 | 572 |
fun dest_modl (Module m) = m; |
573 |
fun dest_def (Def d) = d; |
|
574 |
||
575 |
||
576 |
(* modules *) |
|
577 |
||
578 |
val empty_module = Graph.empty; (*read: "depends on"*) |
|
579 |
||
580 |
fun get_def modl name = |
|
581 |
case dest_name name |
|
582 |
of (modlname, base) => |
|
583 |
let |
|
584 |
fun get (Module node) [] = |
|
585 |
(dest_def o Graph.get_node node) base |
|
586 |
| get (Module node) (m::ms) = |
|
587 |
get (Graph.get_node node m) ms |
|
588 |
in get (Module modl) modlname end; |
|
589 |
||
590 |
fun add_def (name, def) = |
|
591 |
let |
|
592 |
val (modl, base) = dest_name name; |
|
593 |
fun add [] = |
|
594 |
Graph.new_node (base, Def def) |
|
595 |
| add (m::ms) = |
|
596 |
Graph.default_node (m, Module empty_module) |
|
597 |
#> Graph.map_node m (Module o add ms o dest_modl) |
|
598 |
in add modl end; |
|
599 |
||
600 |
fun add_dep (name1, name2) modl = |
|
601 |
if name1 = name2 then modl |
|
602 |
else |
|
603 |
let |
|
604 |
val m1 = dest_name name1 |> apsnd single |> (op @); |
|
605 |
val m2 = dest_name name2 |> apsnd single |> (op @); |
|
| 18454 | 606 |
val (ms, (r1, r2)) = get_prefix (op =) (m1, m2); |
607 |
val (ms, (s1::r1, s2::r2)) = get_prefix (op =) (m1, m2); |
|
| 18170 | 608 |
val add_edge = |
609 |
if null r1 andalso null r2 |
|
610 |
then Graph.add_edge |
|
611 |
else Graph.add_edge_acyclic |
|
612 |
fun add [] node = |
|
613 |
node |
|
614 |
|> add_edge (s1, s2) |
|
615 |
| add (m::ms) node = |
|
616 |
node |
|
617 |
|> Graph.map_node m (Module o add ms o dest_modl); |
|
618 |
in add ms modl end; |
|
619 |
||
| 18885 | 620 |
fun map_def name f = |
621 |
let |
|
622 |
val (modl, base) = dest_name name; |
|
623 |
fun mapp [] = |
|
624 |
Graph.map_node base (Def o f o dest_def) |
|
625 |
| mapp (m::ms) = |
|
626 |
Graph.map_node m (Module o mapp ms o dest_modl) |
|
627 |
in mapp modl end; |
|
628 |
||
629 |
fun map_defs f = |
|
630 |
let |
|
631 |
fun mapp (Def def) = |
|
632 |
(Def o f) def |
|
633 |
| mapp (Module modl) = |
|
634 |
(Module o Graph.map_nodes mapp) modl |
|
635 |
in dest_modl o mapp o Module end; |
|
636 |
||
637 |
fun fold_defs f = |
|
638 |
let |
|
639 |
fun fol prfix (name, Def def) = |
|
640 |
f (NameSpace.pack (prfix @ [name]), def) |
|
641 |
| fol prfix (name, Module modl) = |
|
642 |
Graph.fold_nodes (fol (prfix @ [name])) modl |
|
643 |
in Graph.fold_nodes (fol []) end; |
|
644 |
||
645 |
fun add_deps f modl = |
|
646 |
modl |
|
647 |
|> fold add_dep ([] |> fold_defs (append o f) modl); |
|
648 |
||
649 |
fun ensure_def (name, Undef) module = |
|
650 |
(case try (get_def module) name |
|
651 |
of NONE => (error "attempted to add Undef to module") |
|
652 |
| SOME Undef => (error "attempted to add Undef to module") |
|
653 |
| SOME def' => map_def name (K def') module) |
|
654 |
| ensure_def (name, def) module = |
|
655 |
(case try (get_def module) name |
|
656 |
of NONE => add_def (name, def) module |
|
657 |
| SOME Undef => map_def name (K def) module |
|
658 |
| SOME def' => if eq_def (def, def') |
|
659 |
then module |
|
660 |
else error ("tried to overwrite definition " ^ name));
|
|
661 |
||
| 18517 | 662 |
fun add_prim name deps (target, primdef) = |
| 18516 | 663 |
let |
664 |
val (modl, base) = dest_name name; |
|
665 |
fun add [] module = |
|
666 |
(case try (Graph.get_node module) base |
|
667 |
of NONE => |
|
668 |
module |
|
| 18702 | 669 |
|> Graph.new_node (base, (Def o Prim) [(target, SOME primdef)]) |
| 18516 | 670 |
| SOME (Def (Prim prim)) => |
| 18702 | 671 |
if AList.defined (op =) prim target |
| 18850 | 672 |
then error ("already primitive definition (" ^ target
|
673 |
^ ") present for " ^ name) |
|
| 18516 | 674 |
else |
675 |
module |
|
| 18850 | 676 |
|> Graph.map_node base ((K o Def o Prim) (AList.update (op =) |
677 |
(target, SOME primdef) prim)) |
|
| 18516 | 678 |
| _ => error ("already non-primitive definition present for " ^ name))
|
679 |
| add (m::ms) module = |
|
680 |
module |
|
681 |
|> Graph.default_node (m, Module empty_module) |
|
682 |
|> Graph.map_node m (Module o add ms o dest_modl) |
|
683 |
in |
|
684 |
add modl |
|
685 |
#> fold (curry add_dep name) deps |
|
686 |
end; |
|
687 |
||
| 18702 | 688 |
fun ensure_prim name target = |
| 18516 | 689 |
let |
690 |
val (modl, base) = dest_name name; |
|
691 |
fun ensure [] module = |
|
692 |
(case try (Graph.get_node module) base |
|
693 |
of NONE => |
|
694 |
module |
|
| 18702 | 695 |
|> Graph.new_node (base, (Def o Prim) [(target, NONE)]) |
696 |
| SOME (Def (Prim prim)) => |
|
| 18516 | 697 |
module |
| 18850 | 698 |
|> Graph.map_node base ((K o Def o Prim) (AList.default (op =) |
699 |
(target, NONE) prim)) |
|
700 |
| _ => module) |
|
| 18516 | 701 |
| ensure (m::ms) module = |
702 |
module |
|
703 |
|> Graph.default_node (m, Module empty_module) |
|
704 |
|> Graph.map_node m (Module o ensure ms o dest_modl) |
|
705 |
in ensure modl end; |
|
706 |
||
| 18170 | 707 |
fun merge_module modl12 = |
708 |
let |
|
709 |
fun join_module (Module m1, Module m2) = |
|
710 |
(SOME o Module) (merge_module (m1, m2)) |
|
711 |
| join_module (Def d1, Def d2) = |
|
712 |
if eq_def (d1, d2) then (SOME o Def) d1 else NONE |
|
713 |
| join_module _ = |
|
714 |
NONE |
|
715 |
in Graph.join (K join_module) modl12 end; |
|
716 |
||
717 |
fun partof names modl = |
|
| 18335 | 718 |
let |
719 |
datatype pathnode = PN of (string list * (string * pathnode) list); |
|
720 |
fun mk_ipath ([], base) (PN (defs, modls)) = |
|
721 |
PN (base :: defs, modls) |
|
722 |
| mk_ipath (n::ns, base) (PN (defs, modls)) = |
|
723 |
modls |
|
724 |
|> AList.default (op =) (n, PN ([], [])) |
|
725 |
|> AList.map_entry (op =) n (mk_ipath (ns, base)) |
|
726 |
|> (pair defs #> PN); |
|
727 |
fun select (PN (defs, modls)) (Module module) = |
|
728 |
module |
|
729 |
|> Graph.subgraph (Graph.all_succs module (defs @ map fst modls)) |
|
730 |
|> fold (fn (name, modls) => Graph.map_node name (select modls)) modls |
|
731 |
|> Module; |
|
732 |
in |
|
733 |
Module modl |
|
| 18850 | 734 |
|> select (fold (mk_ipath o dest_name) |
735 |
(filter NameSpace.is_qualified names) (PN ([], []))) |
|
| 18335 | 736 |
|> dest_modl |
737 |
end; |
|
| 18170 | 738 |
|
| 18850 | 739 |
fun imports_of modl name = |
| 18702 | 740 |
let |
741 |
fun imports prfx [] modl = |
|
742 |
[] |
|
743 |
| imports prfx (m::ms) modl = |
|
744 |
map (cons m) (imports (prfx @ [m]) ms ((dest_modl oo Graph.get_node) modl m)) |
|
| 18850 | 745 |
@ map single (Graph.imm_succs modl m); |
| 18702 | 746 |
in |
| 18850 | 747 |
modl |
748 |
|> imports [] name |
|
| 18702 | 749 |
|> map NameSpace.pack |
750 |
end; |
|
751 |
||
752 |
fun check_samemodule names = |
|
753 |
fold (fn name => |
|
754 |
let |
|
755 |
val modn = (fst o dest_name) name |
|
756 |
in |
|
757 |
fn NONE => SOME modn |
|
| 18850 | 758 |
| SOME mod' => if modn = mod' then SOME modn |
759 |
else error "inconsistent name prefix for simultanous names" |
|
| 18702 | 760 |
end |
761 |
) names NONE; |
|
762 |
||
763 |
fun check_funeqs eqs = |
|
764 |
(fold (fn (pats, _) => |
|
765 |
let |
|
766 |
val l = length pats |
|
767 |
in |
|
768 |
fn NONE => SOME l |
|
| 18850 | 769 |
| SOME l' => if l = l' then SOME l |
770 |
else error "function definition with different number of arguments" |
|
| 18702 | 771 |
end |
772 |
) eqs NONE; eqs); |
|
773 |
||
774 |
fun check_prep_def modl Undef = |
|
775 |
Undef |
|
776 |
| check_prep_def modl (d as Prim _) = |
|
777 |
d |
|
778 |
| check_prep_def modl (Fun (eqs, d)) = |
|
779 |
Fun (check_funeqs eqs, d) |
|
780 |
| check_prep_def modl (d as Typesyn _) = |
|
781 |
d |
|
782 |
| check_prep_def modl (d as Datatype (_, insts)) = |
|
783 |
if null insts |
|
784 |
then d |
|
785 |
else error "attempted to add datatype with bare instances" |
|
786 |
| check_prep_def modl (Datatypecons dtco) = |
|
787 |
error "attempted to add bare datatype constructor" |
|
788 |
| check_prep_def modl (d as Class ((_, (v, membrs)), insts)) = |
|
789 |
if null insts |
|
790 |
then |
|
791 |
if member (op =) (map fst (Library.flat (map (fst o snd) membrs))) v |
|
792 |
then error "incorrectly abstracted class type variable" |
|
793 |
else d |
|
794 |
else error "attempted to add class with bare instances" |
|
795 |
| check_prep_def modl (Classmember _) = |
|
796 |
error "attempted to add bare class member" |
|
| 18865 | 797 |
| check_prep_def modl (Classinst ((d as ((class, (tyco, arity)), _), memdefs))) = |
| 18170 | 798 |
let |
| 18702 | 799 |
val Class ((_, (v, membrs)), _) = get_def modl class; |
800 |
val _ = if length memdefs > length memdefs |
|
801 |
then error "too many member definitions given" |
|
802 |
else (); |
|
| 18885 | 803 |
fun instant (w, ty) (var as (v, _)) = |
804 |
if v = w then ty else IVarT var; |
|
| 18702 | 805 |
fun mk_memdef (m, (ctxt, ty)) = |
806 |
case AList.lookup (op =) memdefs m |
|
807 |
of NONE => error ("missing definition for member " ^ quote m)
|
|
808 |
| SOME (eqs, (ctxt', ty')) => |
|
| 18885 | 809 |
if eq_itype (instant_itype (instant (v, tyco `%% map IVarT arity)) ty, ty') |
| 18702 | 810 |
then (m, (check_funeqs eqs, (ctxt', ty'))) |
811 |
else error ("inconsistent type for member definition " ^ quote m)
|
|
812 |
in Classinst (d, map mk_memdef membrs) end; |
|
| 18170 | 813 |
|
| 18702 | 814 |
fun postprocess_def (name, Datatype ((_, constrs), _)) = |
815 |
(check_samemodule (name :: map fst constrs); |
|
816 |
fold (fn (co, _) => |
|
817 |
ensure_def (co, Datatypecons name) |
|
818 |
#> add_dep (co, name) |
|
819 |
#> add_dep (name, co) |
|
820 |
) constrs |
|
821 |
) |
|
822 |
| postprocess_def (name, Class ((_, (_, membrs)), _)) = |
|
823 |
(check_samemodule (name :: map fst membrs); |
|
824 |
fold (fn (m, _) => |
|
825 |
ensure_def (m, Classmember name) |
|
826 |
#> add_dep (m, name) |
|
827 |
#> add_dep (name, m) |
|
828 |
) membrs |
|
829 |
) |
|
| 18865 | 830 |
| postprocess_def (name, Classinst (((class, (tyco, _)), _), _)) = |
| 18702 | 831 |
map_def class (fn Datatype (d, insts) => Datatype (d, name::insts) |
832 |
| d => d) |
|
833 |
#> map_def class (fn Class (d, insts) => Class (d, name::insts)) |
|
834 |
| postprocess_def _ = |
|
835 |
I; |
|
|
18380
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
836 |
|
| 18702 | 837 |
fun succeed some (_, modl) = (Succeed some, modl); |
838 |
fun fail msg (_, modl) = (Fail ([msg], NONE), modl); |
|
| 18170 | 839 |
|
| 18231 | 840 |
fun check_fail _ (Succeed dst, trns) = (dst, trns) |
841 |
| check_fail msg (Fail (msgs, e), _) = raise FAIL (msg::msgs, e); |
|
| 18170 | 842 |
|
| 18702 | 843 |
fun select_generator _ src [] modl = |
844 |
(SOME src, modl) |> fail ("no code generator available")
|
|
| 18231 | 845 |
| select_generator mk_msg src gens modl = |
846 |
let |
|
847 |
fun handle_fail msgs f = |
|
848 |
let |
|
849 |
in |
|
850 |
if ! soft_exc |
|
851 |
then |
|
| 18702 | 852 |
(SOME src, modl) |> f |
853 |
handle FAIL exc => (Fail exc, modl) |
|
854 |
| e => (Fail (msgs, SOME e), modl) |
|
| 18231 | 855 |
else |
| 18702 | 856 |
(SOME src, modl) |> f |
857 |
handle FAIL exc => (Fail exc, modl) |
|
| 18231 | 858 |
end; |
859 |
fun select msgs [(gname, gen)] = |
|
| 18702 | 860 |
handle_fail (msgs @ [mk_msg gname]) (gen src) |
861 |
| select msgs ((gname, gen)::gens) = |
|
862 |
let |
|
863 |
val msgs' = msgs @ [mk_msg gname] |
|
864 |
in case handle_fail msgs' (gen src) |
|
865 |
of (Fail (_, NONE), _) => |
|
866 |
select msgs' gens |
|
867 |
| result => result |
|
| 18231 | 868 |
end; |
869 |
in select [] gens end; |
|
| 18170 | 870 |
|
| 18702 | 871 |
fun gen_ensure_def defgens msg name (dep, modl) = |
| 18170 | 872 |
let |
| 18702 | 873 |
val msg' = case dep |
874 |
of NONE => msg |
|
875 |
| SOME dep => msg ^ ", with dependency " ^ quote dep; |
|
876 |
fun add_dp NONE = I |
|
877 |
| add_dp (SOME dep) = |
|
878 |
debug 9 (fn _ => "adding dependency " ^ quote dep ^ " -> " ^ quote name) |
|
879 |
#> add_dep (dep, name); |
|
880 |
fun prep_def def modl = |
|
881 |
(check_prep_def modl def, modl); |
|
| 18170 | 882 |
in |
883 |
modl |
|
| 18702 | 884 |
|> (if can (get_def modl) name |
885 |
then |
|
886 |
debug 9 (fn _ => "asserting node " ^ quote name) |
|
887 |
#> add_dp dep |
|
888 |
else |
|
889 |
debug 9 (fn _ => "allocating node " ^ quote name) |
|
890 |
#> add_def (name, Undef) |
|
891 |
#> add_dp dep |
|
892 |
#> debug 9 (fn _ => "creating node " ^ quote name) |
|
| 18850 | 893 |
#> select_generator (fn gname => "trying code generator " |
894 |
^ gname ^ " for definition of " ^ quote name) name defgens |
|
| 18702 | 895 |
#> debug 9 (fn _ => "checking creation of node " ^ quote name) |
896 |
#> check_fail msg' |
|
897 |
#-> (fn def => prep_def def) |
|
898 |
#-> (fn def => |
|
899 |
debug 10 (fn _ => "addition of " ^ name |
|
900 |
^ " := " ^ (Pretty.output o pretty_def) def) |
|
901 |
#> debug 10 (fn _ => "adding") |
|
902 |
#> ensure_def (name, def) |
|
903 |
#> debug 10 (fn _ => "postprocessing") |
|
904 |
#> postprocess_def (name, def) |
|
905 |
#> debug 10 (fn _ => "adding done") |
|
906 |
)) |
|
907 |
|> pair dep |
|
| 18170 | 908 |
end; |
909 |
||
| 18231 | 910 |
fun start_transact f modl = |
911 |
let |
|
912 |
fun handle_fail f modl = |
|
| 18702 | 913 |
(((NONE, modl) |> f) |
| 18231 | 914 |
handle FAIL (msgs, NONE) => |
915 |
(error o cat_lines) ("code generation failed, while:" :: msgs))
|
|
916 |
handle FAIL (msgs, SOME e) => |
|
917 |
((writeln o cat_lines) ("code generation failed, while:" :: msgs); raise e);
|
|
918 |
in |
|
919 |
modl |
|
920 |
|> handle_fail f |
|
921 |
|-> (fn x => fn (_, module) => (x, module)) |
|
922 |
end; |
|
| 18172 | 923 |
|
924 |
||
| 18335 | 925 |
|
926 |
(** generic transformation **) |
|
| 18304 | 927 |
|
| 18885 | 928 |
fun map_def_fun f (Fun funn) = |
929 |
Fun (f funn) |
|
930 |
| map_def_fun _ def = def; |
|
931 |
||
932 |
fun map_def_fun_expr f (eqs, cty) = |
|
933 |
(map (fn (ps, rhs) => (map f ps, f rhs)) eqs, cty); |
|
934 |
||
| 18172 | 935 |
fun eta_expand query = |
936 |
let |
|
| 18885 | 937 |
fun eta e = |
| 18865 | 938 |
case unfold_const_app e |
| 18885 | 939 |
of SOME (((f, ty), ls), es) => |
940 |
let |
|
941 |
val delta = query f - length es; |
|
942 |
val add_n = if delta < 0 then 0 else delta; |
|
943 |
val tys = |
|
944 |
(fst o unfold_fun) ty |
|
945 |
|> curry Library.drop (length es) |
|
946 |
|> curry Library.take add_n |
|
947 |
val add_vars = |
|
948 |
Term.invent_names (fold expr_names es []) "x" add_n ~~ tys; |
|
949 |
in |
|
950 |
add_vars `|--> IConst ((f, ty), ls) `$$ es `$$ map IVarE add_vars |
|
951 |
end |
|
952 |
| NONE => map_iexpr eta e; |
|
953 |
in (map_defs o map_def_fun o map_def_fun_expr) eta end; |
|
| 18172 | 954 |
|
| 18216 | 955 |
val eta_expand_poly = |
956 |
let |
|
| 18885 | 957 |
fun eta (funn as ([([], e)], cty as (sortctxt, (ty as IFun (ty1, ty2))))) = |
| 18216 | 958 |
if (not o null) sortctxt |
| 18885 | 959 |
orelse null (type_vnames ty []) |
960 |
then funn |
|
| 18216 | 961 |
else |
962 |
let |
|
| 18885 | 963 |
val add_var = (hd (Term.invent_names (expr_names e []) "x" 1), ty1) |
964 |
in (([([IVarE add_var], add_var `|-> e)], cty)) end |
|
965 |
| eta funn = funn; |
|
966 |
in (map_defs o map_def_fun) eta end; |
|
967 |
||
968 |
val unclash_vars = |
|
969 |
let |
|
970 |
fun unclash (eqs, (sortctxt, ty)) = |
|
971 |
let |
|
972 |
val used_expr = |
|
973 |
fold (fn (pats, rhs) => fold expr_names pats #> expr_names rhs) eqs []; |
|
974 |
val used_type = map fst sortctxt; |
|
975 |
val clash = gen_union (op =) (used_expr, used_type); |
|
976 |
val rename_map = fold_map (fn c => invent c #-> (fn c' => pair (c, c'))) clash [] |> fst; |
|
977 |
fun rename (v, sort) = |
|
978 |
(perhaps (AList.lookup (op =) rename_map) v, sort); |
|
979 |
val rename_typ = instant_itype (IVarT o rename); |
|
980 |
val rename_expr = map_iexpr_itype rename_typ; |
|
981 |
fun rename_eq (args, rhs) = (map rename_expr args, rename_expr rhs) |
|
982 |
in |
|
983 |
(map rename_eq eqs, (map rename sortctxt, rename_typ ty)) |
|
984 |
end; |
|
985 |
in (map_defs o map_def_fun) unclash end; |
|
| 18216 | 986 |
|
| 18172 | 987 |
|
| 18216 | 988 |
|
989 |
(** generic serialization **) |
|
990 |
||
991 |
(* resolving *) |
|
992 |
||
| 18885 | 993 |
structure NameMangler = NameManglerFun ( |
994 |
type ctxt = (string * string -> string) * (string -> string option); |
|
| 18516 | 995 |
type src = string * string; |
996 |
val ord = prod_ord string_ord string_ord; |
|
| 18885 | 997 |
fun mk (preprocess, validate) ((shallow, name), 0) = |
998 |
(case validate (preprocess (shallow, name)) |
|
| 18516 | 999 |
of NONE => name |
| 18885 | 1000 |
| _ => mk (preprocess, validate) ((shallow, name), 1)) |
1001 |
| mk (preprocess, validate) (("", name), i) =
|
|
1002 |
preprocess ("", name ^ "_" ^ string_of_int (i+1))
|
|
1003 |
|> perhaps validate |
|
1004 |
| mk (preprocess, validate) ((shallow, name), i) = |
|
1005 |
preprocess (shallow, shallow ^ "_" ^ name ^ "_" ^ string_of_int (i+1)) |
|
| 18516 | 1006 |
|> perhaps validate; |
1007 |
fun is_valid _ _ = true; |
|
1008 |
fun maybe_unique _ _ = NONE; |
|
1009 |
fun re_mangle _ dst = error ("no such definition name: " ^ quote dst);
|
|
1010 |
); |
|
1011 |
||
| 18885 | 1012 |
fun mk_deresolver module nsp_conn preprocess validate = |
1013 |
let |
|
1014 |
datatype tabnode = N of string * tabnode Symtab.table option; |
|
1015 |
fun mk module manglers tab = |
|
1016 |
let |
|
1017 |
fun mk_name name = |
|
1018 |
case NameSpace.unpack name |
|
1019 |
of [n] => ("", n)
|
|
1020 |
| [s, n] => (s, n); |
|
1021 |
fun in_conn (shallow, conn) = |
|
1022 |
member (op = : string * string -> bool) conn shallow; |
|
1023 |
fun add_name name = |
|
1024 |
let |
|
1025 |
val n as (shallow, _) = mk_name name; |
|
1026 |
fun diag (nm as (name, n')) = (writeln ("resolving " ^ quote name ^ " to " ^ quote n'); nm);
|
|
1027 |
in |
|
1028 |
AList.map_entry_yield in_conn shallow ( |
|
1029 |
NameMangler.declare (preprocess, validate) n |
|
1030 |
#-> (fn n' => pair (name, n')) |
|
1031 |
) #> apfst the #> apfst diag |
|
1032 |
end; |
|
1033 |
val (renamings, manglers') = |
|
1034 |
fold_map add_name (Graph.keys module) manglers; |
|
1035 |
fun extend_tab (n, n') = |
|
1036 |
if (length o NameSpace.unpack) n = 1 |
|
1037 |
then |
|
1038 |
Symtab.update_new |
|
1039 |
(n, N (n', SOME (mk ((dest_modl o Graph.get_node module) n) manglers' Symtab.empty))) |
|
1040 |
else |
|
1041 |
Symtab.update_new (n, N (n', NONE)); |
|
1042 |
in fold extend_tab renamings tab end; |
|
1043 |
fun get_path_name [] tab = |
|
1044 |
([], SOME tab) |
|
1045 |
| get_path_name [p] tab = |
|
1046 |
let |
|
1047 |
val _ = writeln ("(1) " ^ p);
|
|
1048 |
val SOME (N (p', tab')) = Symtab.lookup tab p |
|
1049 |
in ([p'], tab') end |
|
1050 |
| get_path_name [p1, p2] tab = |
|
1051 |
let |
|
1052 |
val _ = (writeln o prefix "(2) " o NameSpace.pack) [p1, p2]; |
|
1053 |
in case Symtab.lookup tab p1 |
|
1054 |
of SOME (N (p', SOME tab')) => |
|
1055 |
let |
|
1056 |
val _ = writeln ("(2) 'twas a module");
|
|
1057 |
val (ps', tab'') = get_path_name [p2] tab' |
|
1058 |
in (p' :: ps', tab'') end |
|
1059 |
| NONE => |
|
1060 |
let |
|
1061 |
val _ = writeln ("(2) 'twas a definition");
|
|
1062 |
val SOME (N (p', NONE)) = Symtab.lookup tab (NameSpace.pack [p1, p2]) |
|
1063 |
in ([p'], NONE) end |
|
1064 |
end |
|
1065 |
| get_path_name (p::ps) tab = |
|
1066 |
let |
|
1067 |
val _ = (writeln o prefix "(3) " o commas) (p::ps); |
|
1068 |
val SOME (N (p', SOME tab')) = Symtab.lookup tab p |
|
1069 |
val (ps', tab'') = get_path_name ps tab' |
|
1070 |
in (p' :: ps', tab'') end; |
|
1071 |
fun deresolv tab prefix name = |
|
1072 |
if (is_some o Int.fromString) name |
|
1073 |
then name |
|
1074 |
else let |
|
1075 |
val _ = writeln ("(0) prefix: " ^ commas prefix);
|
|
1076 |
val _ = writeln ("(0) name: " ^ name)
|
|
1077 |
val (common, (_, rem)) = get_prefix (op =) (prefix, NameSpace.unpack name); |
|
1078 |
val _ = writeln ("(0) common: " ^ commas common);
|
|
1079 |
val _ = writeln ("(0) rem: " ^ commas rem);
|
|
1080 |
val (_, SOME tab') = get_path_name common tab; |
|
1081 |
val (name', _) = get_path_name rem tab'; |
|
1082 |
in NameSpace.pack name' end; |
|
1083 |
in deresolv (mk module (AList.make (K NameMangler.empty) nsp_conn) Symtab.empty) end; |
|
1084 |
||
1085 |
val _ : module -> string list list -> (string * string -> string) -> (string -> string option) -> string list -> string -> string = mk_deresolver; |
|
1086 |
||
1087 |
fun mk_resolvtab' nsp_conn validate module = |
|
| 18216 | 1088 |
let |
| 18702 | 1089 |
fun validate' n = perhaps validate n; |
| 18216 | 1090 |
fun ensure_unique prfix prfix' name name' (locals, tab) = |
1091 |
let |
|
1092 |
fun uniquify name n = |
|
1093 |
let |
|
1094 |
val name' = if n = 0 then name else name ^ "_" ^ string_of_int n |
|
1095 |
in |
|
1096 |
if member (op =) locals name' |
|
1097 |
then uniquify name (n+1) |
|
1098 |
else case validate name |
|
1099 |
of NONE => name' |
|
1100 |
| SOME name' => uniquify name' n |
|
1101 |
end; |
|
1102 |
val name'' = uniquify name' 0; |
|
1103 |
in |
|
1104 |
(locals, tab) |
|
1105 |
|> apsnd (Symtab.update_new |
|
1106 |
(NameSpace.pack (prfix @ [name]), NameSpace.pack (prfix' @ [name'']))) |
|
1107 |
|> apfst (cons name'') |
|
1108 |
|> pair name'' |
|
1109 |
end; |
|
1110 |
fun fill_in prfix prfix' node tab = |
|
1111 |
let |
|
1112 |
val keys = Graph.keys node; |
|
1113 |
val nodes = AList.make (Graph.get_node node) keys; |
|
1114 |
val (mods, defs) = |
|
1115 |
nodes |
|
1116 |
|> List.partition (fn (_, Module _) => true | _ => false) |
|
1117 |
|> apfst (map (fn (name, Module m) => (name, m))) |
|
1118 |
|> apsnd (map fst) |
|
1119 |
fun modl_validate (name, modl) (locals, tab) = |
|
1120 |
(locals, tab) |
|
1121 |
|> ensure_unique prfix prfix' name name |
|
1122 |
|-> (fn name' => apsnd (fill_in (prfix @ [name]) (prfix @ [name']) modl)) |
|
1123 |
fun ensure_unique_sidf sidf = |
|
1124 |
let |
|
1125 |
val [shallow, name] = NameSpace.unpack sidf; |
|
1126 |
in |
|
| 18516 | 1127 |
nsp_conn |
| 18216 | 1128 |
|> get_first |
1129 |
(fn grp => if member (op =) grp shallow |
|
1130 |
then grp |> remove (op =) shallow |> SOME else NONE) |
|
1131 |
|> these |
|
1132 |
|> map (fn s => NameSpace.pack [s, name]) |
|
1133 |
|> exists (member (op =) defs) |
|
1134 |
|> (fn b => if b then sidf else name) |
|
1135 |
end; |
|
1136 |
fun def_validate sidf (locals, tab) = |
|
1137 |
(locals, tab) |
|
1138 |
|> ensure_unique prfix prfix' sidf (ensure_unique_sidf sidf) |
|
1139 |
|> snd |
|
1140 |
in |
|
1141 |
([], tab) |
|
1142 |
|> fold modl_validate mods |
|
1143 |
|> fold def_validate defs |
|
1144 |
|> snd |
|
1145 |
end; |
|
1146 |
in |
|
1147 |
Symtab.empty |
|
1148 |
|> fill_in [] [] module |
|
1149 |
end; |
|
1150 |
||
| 18282 | 1151 |
fun mk_resolv tab = |
| 18216 | 1152 |
let |
1153 |
fun resolver modl name = |
|
1154 |
if NameSpace.is_qualified name then |
|
1155 |
let |
|
| 18850 | 1156 |
val _ = debug 12 (fn name' => "resolving " ^ quote name ^ " in " |
1157 |
^ (quote o NameSpace.pack) modl) (); |
|
1158 |
val modl' = if null modl then [] else |
|
1159 |
(NameSpace.unpack o the o Symtab.lookup tab o NameSpace.pack) modl; |
|
| 18216 | 1160 |
val name' = (NameSpace.unpack o the o Symtab.lookup tab) name |
1161 |
in |
|
| 18454 | 1162 |
(NameSpace.pack o snd o snd o get_prefix (op =)) (modl', name') |
| 18850 | 1163 |
|> debug 12 (fn name' => "resolving " ^ quote name ^ " to " |
1164 |
^ quote name' ^ " in " ^ (quote o NameSpace.pack) modl) |
|
| 18216 | 1165 |
end |
1166 |
else name |
|
1167 |
in resolver end; |
|
1168 |
||
1169 |
||
1170 |
(* serialization *) |
|
1171 |
||
| 18756 | 1172 |
fun serialize seri_defs seri_module validate nsp_conn name_root module = |
| 18216 | 1173 |
let |
| 18912 | 1174 |
val resolver = mk_deresolver module nsp_conn snd validate; |
1175 |
(* val resolver = mk_resolv (mk_resolvtab' nsp_conn validate module); *) |
|
| 18702 | 1176 |
fun mk_name prfx name = |
| 18850 | 1177 |
let |
1178 |
val name_qual = NameSpace.pack (prfx @ [name]) |
|
1179 |
in (name_qual, resolver prfx name_qual) end; |
|
| 18756 | 1180 |
fun mk_contents prfx module = |
| 18850 | 1181 |
List.mapPartial (seri prfx) |
1182 |
((map (AList.make (Graph.get_node module)) o rev o Graph.strong_conn) module) |
|
| 18756 | 1183 |
and seri prfx ([(name, Module modl)]) = |
| 18850 | 1184 |
seri_module (map (resolver []) (imports_of module (prfx @ [name]))) |
1185 |
(mk_name prfx name, mk_contents (prfx @ [name]) modl) |
|
| 18756 | 1186 |
| seri prfx ds = |
| 18850 | 1187 |
seri_defs (resolver prfx) |
| 18912 | 1188 |
(map (fn (name, Def def) => (fst (mk_name prfx name), def)) ds) |
| 18216 | 1189 |
in |
| 18850 | 1190 |
seri_module (map (resolver []) (Graph.strong_conn module |> List.concat |> rev)) |
1191 |
(("", name_root), (mk_contents [] module))
|
|
| 18216 | 1192 |
end; |
1193 |
||
|
18169
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
1194 |
end; (* struct *) |