| author | mengj |
| Sat, 30 Sep 2006 14:31:41 +0200 | |
| changeset 20790 | a9595fdc02b1 |
| parent 20709 | 645236e80885 |
| child 20835 | 27d049062b56 |
| 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 |
|
|
19167
f237c0cb3882
refined representation of codegen intermediate language
haftmann
parents:
19150
diff
changeset
|
8 |
infix 8 `%%; |
|
f237c0cb3882
refined representation of codegen intermediate language
haftmann
parents:
19150
diff
changeset
|
9 |
infixr 6 `->; |
|
f237c0cb3882
refined representation of codegen intermediate language
haftmann
parents:
19150
diff
changeset
|
10 |
infixr 6 `-->; |
|
f237c0cb3882
refined representation of codegen intermediate language
haftmann
parents:
19150
diff
changeset
|
11 |
infix 4 `$; |
|
f237c0cb3882
refined representation of codegen intermediate language
haftmann
parents:
19150
diff
changeset
|
12 |
infix 4 `$$; |
|
f237c0cb3882
refined representation of codegen intermediate language
haftmann
parents:
19150
diff
changeset
|
13 |
infixr 3 `|->; |
|
f237c0cb3882
refined representation of codegen intermediate language
haftmann
parents:
19150
diff
changeset
|
14 |
infixr 3 `|-->; |
|
f237c0cb3882
refined representation of codegen intermediate language
haftmann
parents:
19150
diff
changeset
|
15 |
|
| 19136 | 16 |
signature BASIC_CODEGEN_THINGOL = |
|
18169
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
17 |
sig |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
18 |
type vname = string; |
| 20456 | 19 |
datatype inst = |
20 |
Instance of string * inst list list |
|
21 |
| Context of class list * (vname * int); |
|
|
18169
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
22 |
datatype itype = |
|
19167
f237c0cb3882
refined representation of codegen intermediate language
haftmann
parents:
19150
diff
changeset
|
23 |
`%% of string * itype list |
|
f237c0cb3882
refined representation of codegen intermediate language
haftmann
parents:
19150
diff
changeset
|
24 |
| `-> of itype * itype |
|
f237c0cb3882
refined representation of codegen intermediate language
haftmann
parents:
19150
diff
changeset
|
25 |
| ITyVar of vname; |
| 20105 | 26 |
datatype iterm = |
| 20456 | 27 |
IConst of string * (inst list list * itype) |
|
19167
f237c0cb3882
refined representation of codegen intermediate language
haftmann
parents:
19150
diff
changeset
|
28 |
| IVar of vname |
| 20105 | 29 |
| `$ of iterm * iterm |
30 |
| `|-> of (vname * itype) * iterm |
|
| 20600 | 31 |
| INum of IntInf.int * iterm |
| 20105 | 32 |
| IChar of string (*length one!*) * iterm |
33 |
| ICase of ((iterm * itype) * (iterm * iterm) list) * iterm; |
|
| 20439 | 34 |
(*((discriminendum term (td), discriminendum type (ty)), |
35 |
[(selector pattern (p), body term (t))] (bs)), |
|
36 |
pure term (t0))*) |
|
| 19136 | 37 |
end; |
38 |
||
39 |
signature CODEGEN_THINGOL = |
|
40 |
sig |
|
41 |
include BASIC_CODEGEN_THINGOL; |
|
|
19167
f237c0cb3882
refined representation of codegen intermediate language
haftmann
parents:
19150
diff
changeset
|
42 |
val `--> : itype list * itype -> itype; |
| 20105 | 43 |
val `$$ : iterm * iterm list -> iterm; |
44 |
val `|--> : (vname * itype) list * iterm -> iterm; |
|
|
18169
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
45 |
val pretty_itype: itype -> Pretty.T; |
| 20105 | 46 |
val pretty_iterm: iterm -> Pretty.T; |
| 18216 | 47 |
val unfoldl: ('a -> ('a * 'b) option) -> 'a -> 'a * 'b list;
|
48 |
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
|
49 |
val unfold_fun: itype -> itype list * itype; |
| 20105 | 50 |
val unfold_app: iterm -> iterm * iterm list; |
51 |
val unfold_abs: iterm -> (iterm * itype) list * iterm; |
|
52 |
val unfold_let: iterm -> ((iterm * itype) * iterm) list * iterm; |
|
53 |
val unfold_const_app: iterm -> |
|
| 20456 | 54 |
((string * (inst list list * itype)) * iterm list) option; |
| 20105 | 55 |
val add_constnames: iterm -> string list -> string list; |
56 |
val add_varnames: iterm -> string list -> string list; |
|
| 20709 | 57 |
val add_unbound_varnames: iterm -> string list -> string list; |
| 20105 | 58 |
val is_pat: (string -> bool) -> iterm -> bool; |
59 |
val vars_distinct: iterm list -> bool; |
|
60 |
val map_pure: (iterm -> 'a) -> iterm -> 'a; |
|
| 20456 | 61 |
val eta_expand: (string * (inst list list * itype)) * iterm list -> int -> iterm; |
| 18170 | 62 |
|
| 20456 | 63 |
type typscheme = (vname * sort) list * itype; |
| 18170 | 64 |
datatype def = |
|
19816
a8c8ed1c85e0
removed 'primitive definitions' added (non)strict generation, minor fixes
haftmann
parents:
19785
diff
changeset
|
65 |
Bot |
| 20456 | 66 |
| Fun of (iterm list * iterm) list * typscheme |
67 |
| Typesyn of typscheme |
|
68 |
| Datatype of (vname * sort) list * (string * itype list) list |
|
|
18380
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
69 |
| Datatypecons of string |
| 20456 | 70 |
| Class of class list * (vname * (string * itype) list) |
|
18380
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
71 |
| Classmember of class |
| 20389 | 72 |
| Classinst of (class * (string * (vname * sort) list)) |
| 20466 | 73 |
* ((class * (string * inst list list)) list |
| 20389 | 74 |
* (string * iterm) list); |
| 18170 | 75 |
type module; |
76 |
type transact; |
|
77 |
type 'dst transact_fin; |
|
78 |
val pretty_def: def -> Pretty.T; |
|
| 20191 | 79 |
val pretty_module: module -> Pretty.T; |
| 18360 | 80 |
val pretty_deps: module -> Pretty.T; |
| 18170 | 81 |
val empty_module: module; |
|
19341
3414c04fbc39
added definitional code generator module: codegen_theorems.ML
haftmann
parents:
19300
diff
changeset
|
82 |
val get_def: module -> string -> def; |
| 18170 | 83 |
val merge_module: module * module -> module; |
|
19042
630b8dd0b31a
exported some interfaces useful for other code generator approaches
haftmann
parents:
19038
diff
changeset
|
84 |
val diff_module: module * module -> (string * def) list; |
|
19341
3414c04fbc39
added definitional code generator module: codegen_theorems.ML
haftmann
parents:
19300
diff
changeset
|
85 |
val project_module: string list -> module -> module; |
|
3414c04fbc39
added definitional code generator module: codegen_theorems.ML
haftmann
parents:
19300
diff
changeset
|
86 |
val purge_module: string list -> module -> module; |
| 20428 | 87 |
(* val flat_funs_datatypes: module -> (string * def) list; *) |
| 20216 | 88 |
val add_eval_def: string (*shallow name space*) * iterm -> module -> string * module; |
| 20191 | 89 |
val delete_garbage: string list (*hidden definitions*) -> module -> module; |
| 19884 | 90 |
val ensure_def: (string -> transact -> def transact_fin) -> bool -> string |
91 |
-> string -> transact -> transact; |
|
| 18170 | 92 |
val succeed: 'a -> transact -> 'a transact_fin; |
93 |
val fail: string -> transact -> 'a transact_fin; |
|
| 19884 | 94 |
val message: string -> (transact -> 'a) -> transact -> 'a; |
| 18963 | 95 |
val start_transact: string option -> (transact -> 'a * transact) -> module -> 'a * module; |
| 20456 | 96 |
val elim_classes: module -> (iterm list * iterm) list * typscheme -> (iterm list * iterm) list * itype; |
| 18216 | 97 |
|
|
19341
3414c04fbc39
added definitional code generator module: codegen_theorems.ML
haftmann
parents:
19300
diff
changeset
|
98 |
val debug: bool ref; |
|
3414c04fbc39
added definitional code generator module: codegen_theorems.ML
haftmann
parents:
19300
diff
changeset
|
99 |
val debug_msg: ('a -> string) -> 'a -> 'a;
|
| 18231 | 100 |
val soft_exc: bool ref; |
| 18216 | 101 |
|
102 |
val serialize: |
|
| 19038 | 103 |
((string -> string -> string) -> string -> (string * def) list -> 'a option) |
|
19341
3414c04fbc39
added definitional code generator module: codegen_theorems.ML
haftmann
parents:
19300
diff
changeset
|
104 |
-> ((string -> string) -> string list -> (string * string) * 'a list -> 'a option) |
| 18216 | 105 |
-> (string -> string option) |
| 18919 | 106 |
-> (string * string -> string) |
| 18850 | 107 |
-> string list list -> string -> module -> 'a option; |
|
18169
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
108 |
end; |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
109 |
|
| 18850 | 110 |
structure CodegenThingol: CODEGEN_THINGOL = |
|
18169
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
111 |
struct |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
112 |
|
| 18170 | 113 |
(** auxiliary **) |
|
18169
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
114 |
|
|
19341
3414c04fbc39
added definitional code generator module: codegen_theorems.ML
haftmann
parents:
19300
diff
changeset
|
115 |
val debug = ref false; |
| 20405 | 116 |
fun debug_msg f x = (if !debug then Output.tracing (f x) else (); x); |
| 18231 | 117 |
val soft_exc = ref true; |
|
18169
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
118 |
|
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
119 |
fun unfoldl dest x = |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
120 |
case dest x |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
121 |
of NONE => (x, []) |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
122 |
| SOME (x1, x2) => |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
123 |
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
|
124 |
|
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
125 |
fun unfoldr dest x = |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
126 |
case dest x |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
127 |
of NONE => ([], x) |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
128 |
| SOME (x1, x2) => |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
129 |
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
|
130 |
|
| 18170 | 131 |
|
132 |
||
133 |
(** language core - types, pattern, expressions **) |
|
|
18169
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
134 |
|
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
135 |
(* language representation *) |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
136 |
|
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
137 |
type vname = string; |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
138 |
|
| 20456 | 139 |
datatype inst = |
140 |
Instance of string * inst list list |
|
141 |
| Context of class list * (vname * int); |
|
| 18885 | 142 |
|
|
18169
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
143 |
datatype itype = |
|
19167
f237c0cb3882
refined representation of codegen intermediate language
haftmann
parents:
19150
diff
changeset
|
144 |
`%% of string * itype list |
|
f237c0cb3882
refined representation of codegen intermediate language
haftmann
parents:
19150
diff
changeset
|
145 |
| `-> of itype * itype |
|
f237c0cb3882
refined representation of codegen intermediate language
haftmann
parents:
19150
diff
changeset
|
146 |
| ITyVar of vname; |
|
18169
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
147 |
|
| 20105 | 148 |
datatype iterm = |
| 20456 | 149 |
IConst of string * (inst list list * itype) |
|
19167
f237c0cb3882
refined representation of codegen intermediate language
haftmann
parents:
19150
diff
changeset
|
150 |
| IVar of vname |
| 20105 | 151 |
| `$ of iterm * iterm |
152 |
| `|-> of (vname * itype) * iterm |
|
153 |
| INum of IntInf.int * iterm |
|
154 |
| IChar of string * iterm |
|
155 |
| ICase of ((iterm * itype) * (iterm * iterm) list) * iterm; |
|
|
19167
f237c0cb3882
refined representation of codegen intermediate language
haftmann
parents:
19150
diff
changeset
|
156 |
(*see also signature*) |
|
18169
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
157 |
|
|
18380
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
158 |
(* |
|
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
159 |
variable naming conventions |
|
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
160 |
|
|
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
161 |
bare names: |
|
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
162 |
variable names v |
| 20439 | 163 |
class names class |
|
18380
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
164 |
type constructor names tyco |
|
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
165 |
datatype names dtco |
|
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
166 |
const names (general) c |
|
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
167 |
constructor names co |
| 20439 | 168 |
class operation names clsop (op) |
|
18380
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
169 |
arbitrary name s |
|
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
170 |
|
| 20439 | 171 |
v, c, co, clsop also annotated with types usw. |
172 |
||
|
18380
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
173 |
constructs: |
|
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
174 |
sort sort |
| 20456 | 175 |
type parameters vs |
|
18380
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
176 |
type ty |
| 20456 | 177 |
type schemes tysm |
| 20439 | 178 |
term t |
179 |
(term as pattern) p |
|
180 |
instance (classs, tyco) inst |
|
|
18380
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
181 |
*) |
|
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
182 |
|
|
19167
f237c0cb3882
refined representation of codegen intermediate language
haftmann
parents:
19150
diff
changeset
|
183 |
val op `--> = Library.foldr (op `->); |
|
f237c0cb3882
refined representation of codegen intermediate language
haftmann
parents:
19150
diff
changeset
|
184 |
val op `$$ = Library.foldl (op `$); |
|
f237c0cb3882
refined representation of codegen intermediate language
haftmann
parents:
19150
diff
changeset
|
185 |
val op `|--> = Library.foldr (op `|->); |
|
18169
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
186 |
|
| 20456 | 187 |
val pretty_typparms = |
|
19341
3414c04fbc39
added definitional code generator module: codegen_theorems.ML
haftmann
parents:
19300
diff
changeset
|
188 |
Pretty.list "(" ")" o Pretty.commas o map (fn (v, sort) => (Pretty.block o Pretty.breaks)
|
| 19150 | 189 |
[Pretty.str v, Pretty.str "::", Pretty.enum "&" "" "" (map Pretty.str sort)]); |
190 |
||
|
19167
f237c0cb3882
refined representation of codegen intermediate language
haftmann
parents:
19150
diff
changeset
|
191 |
fun pretty_itype (tyco `%% tys) = |
|
19341
3414c04fbc39
added definitional code generator module: codegen_theorems.ML
haftmann
parents:
19300
diff
changeset
|
192 |
Pretty.enum "" "(" ")" (Pretty.str tyco :: map pretty_itype tys)
|
|
19167
f237c0cb3882
refined representation of codegen intermediate language
haftmann
parents:
19150
diff
changeset
|
193 |
| pretty_itype (ty1 `-> ty2) = |
| 18885 | 194 |
Pretty.enum "" "(" ")" [pretty_itype ty1, Pretty.str "->", pretty_itype ty2]
|
|
19167
f237c0cb3882
refined representation of codegen intermediate language
haftmann
parents:
19150
diff
changeset
|
195 |
| pretty_itype (ITyVar v) = |
| 19150 | 196 |
Pretty.str v; |
| 18885 | 197 |
|
| 20105 | 198 |
fun pretty_iterm (IConst (c, _)) = |
|
19167
f237c0cb3882
refined representation of codegen intermediate language
haftmann
parents:
19150
diff
changeset
|
199 |
Pretty.str c |
| 20105 | 200 |
| pretty_iterm (IVar v) = |
|
19167
f237c0cb3882
refined representation of codegen intermediate language
haftmann
parents:
19150
diff
changeset
|
201 |
Pretty.str ("?" ^ v)
|
| 20439 | 202 |
| pretty_iterm (t1 `$ t2) = |
|
19167
f237c0cb3882
refined representation of codegen intermediate language
haftmann
parents:
19150
diff
changeset
|
203 |
(Pretty.enclose "(" ")" o Pretty.breaks)
|
| 20439 | 204 |
[pretty_iterm t1, pretty_iterm t2] |
205 |
| pretty_iterm ((v, ty) `|-> t) = |
|
| 20105 | 206 |
(Pretty.enclose "(" ")" o Pretty.breaks)
|
| 20439 | 207 |
[Pretty.str v, Pretty.str "::", pretty_itype ty, Pretty.str "|->", pretty_iterm t] |
| 20105 | 208 |
| pretty_iterm (INum (n, _)) = |
| 19202 | 209 |
(Pretty.str o IntInf.toString) n |
| 20439 | 210 |
| pretty_iterm (IChar (h, _)) = |
211 |
(Pretty.str o quote) h |
|
212 |
| pretty_iterm (ICase (((t, _), bs), _)) = |
|
|
19167
f237c0cb3882
refined representation of codegen intermediate language
haftmann
parents:
19150
diff
changeset
|
213 |
(Pretty.enclose "(" ")" o Pretty.breaks) [
|
|
f237c0cb3882
refined representation of codegen intermediate language
haftmann
parents:
19150
diff
changeset
|
214 |
Pretty.str "case", |
| 20439 | 215 |
pretty_iterm t, |
216 |
Pretty.enclose "(" ")" (map (fn (p, t) =>
|
|
|
19167
f237c0cb3882
refined representation of codegen intermediate language
haftmann
parents:
19150
diff
changeset
|
217 |
(Pretty.block o Pretty.breaks) [ |
| 20105 | 218 |
pretty_iterm p, |
|
19167
f237c0cb3882
refined representation of codegen intermediate language
haftmann
parents:
19150
diff
changeset
|
219 |
Pretty.str "=>", |
| 20439 | 220 |
pretty_iterm t |
| 18885 | 221 |
] |
| 20439 | 222 |
) bs) |
| 18885 | 223 |
]; |
224 |
||
|
18169
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
225 |
val unfold_fun = unfoldr |
| 20439 | 226 |
(fn op `-> ty => SOME ty |
|
18169
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
227 |
| _ => NONE); |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
228 |
|
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
229 |
val unfold_app = unfoldl |
| 20439 | 230 |
(fn op `$ t => SOME t |
|
18169
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
231 |
| _ => NONE); |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
232 |
|
| 18282 | 233 |
val unfold_abs = unfoldr |
| 20439 | 234 |
(fn (v, ty) `|-> (e as ICase (((IVar w, _), [(p, t)]), _)) => |
235 |
if v = w then SOME ((p, ty), t) else SOME ((IVar v, ty), t) |
|
236 |
| (v, ty) `|-> t => SOME ((IVar v, ty), t) |
|
| 18282 | 237 |
| _ => NONE) |
238 |
||
|
18169
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
239 |
val unfold_let = unfoldr |
| 20439 | 240 |
(fn ICase (((td, ty), [(p, t)]), _) => SOME (((p, ty), td), t) |
|
18169
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
241 |
| _ => NONE); |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
242 |
|
| 20439 | 243 |
fun unfold_const_app t = |
244 |
case unfold_app t |
|
245 |
of (IConst c, ts) => SOME (c, ts) |
|
| 18865 | 246 |
| _ => NONE; |
247 |
||
|
19167
f237c0cb3882
refined representation of codegen intermediate language
haftmann
parents:
19150
diff
changeset
|
248 |
fun map_itype _ (ty as ITyVar _) = |
|
f237c0cb3882
refined representation of codegen intermediate language
haftmann
parents:
19150
diff
changeset
|
249 |
ty |
|
f237c0cb3882
refined representation of codegen intermediate language
haftmann
parents:
19150
diff
changeset
|
250 |
| map_itype f (tyco `%% tys) = |
|
f237c0cb3882
refined representation of codegen intermediate language
haftmann
parents:
19150
diff
changeset
|
251 |
tyco `%% map f tys |
| 20439 | 252 |
| map_itype f (ty1 `-> ty2) = |
253 |
f ty1 `-> f ty2; |
|
| 18172 | 254 |
|
| 20456 | 255 |
fun eq_ityp ((vs1, ty1), (vs2, ty2)) = |
| 18282 | 256 |
let |
257 |
exception NO_MATCH; |
|
| 20456 | 258 |
fun eq_typparms subs vs1 vs2 = |
| 19597 | 259 |
map (fn (v : string, sort : string list) => case AList.lookup (op =) subs v |
| 19150 | 260 |
of NONE => raise NO_MATCH |
| 20456 | 261 |
| SOME (v' : string) => case AList.lookup (op =) vs2 v' |
| 19150 | 262 |
of NONE => raise NO_MATCH |
| 20456 | 263 |
| SOME sort' => if sort <> sort' then raise NO_MATCH else ()) vs1 |
|
19167
f237c0cb3882
refined representation of codegen intermediate language
haftmann
parents:
19150
diff
changeset
|
264 |
fun eq (ITyVar v1) (ITyVar v2) subs = |
| 19150 | 265 |
(case AList.lookup (op =) subs v1 |
266 |
of NONE => subs |> AList.update (op =) (v1, v2) |
|
267 |
| SOME v1' => |
|
268 |
if v1' <> v2 |
|
269 |
then raise NO_MATCH |
|
270 |
else subs) |
|
|
19167
f237c0cb3882
refined representation of codegen intermediate language
haftmann
parents:
19150
diff
changeset
|
271 |
| eq (tyco1 `%% tys1) (tyco2 `%% tys2) subs = |
| 18282 | 272 |
if tyco1 <> tyco2 |
273 |
then raise NO_MATCH |
|
274 |
else subs |> fold2 eq tys1 tys2 |
|
|
19167
f237c0cb3882
refined representation of codegen intermediate language
haftmann
parents:
19150
diff
changeset
|
275 |
| eq (ty11 `-> ty12) (ty21 `-> ty22) subs = |
| 18282 | 276 |
subs |> eq ty11 ty21 |> eq ty12 ty22 |
277 |
| eq _ _ _ = raise NO_MATCH; |
|
278 |
in |
|
| 20456 | 279 |
(eq_typparms vs1 vs2; eq ty1 ty2 []; true) |
| 18282 | 280 |
handle NO_MATCH => false |
281 |
end; |
|
282 |
||
| 18885 | 283 |
fun instant_itype f = |
284 |
let |
|
| 20439 | 285 |
fun instant (ITyVar v) = f v |
286 |
| instant ty = map_itype instant ty; |
|
| 19215 | 287 |
in instant end; |
| 18885 | 288 |
|
| 20456 | 289 |
fun is_pat is_cons (IConst (c, _)) = is_cons c |
| 20439 | 290 |
| is_pat _ (IVar _) = true |
291 |
| is_pat is_cons (t1 `$ t2) = |
|
292 |
is_pat is_cons t1 andalso is_pat is_cons t2 |
|
293 |
| is_pat _ (INum _) = true |
|
294 |
| is_pat _ (IChar _) = true |
|
|
19953
2f54a51f1801
class package refinements, slight code generation refinements
haftmann
parents:
19937
diff
changeset
|
295 |
| is_pat _ _ = false; |
| 19202 | 296 |
|
| 20439 | 297 |
fun map_pure f (t as IConst _) = |
298 |
f t |
|
299 |
| map_pure f (t as IVar _) = |
|
300 |
f t |
|
301 |
| map_pure f (t as _ `$ _) = |
|
302 |
f t |
|
303 |
| map_pure f (t as _ `|-> _) = |
|
304 |
f t |
|
305 |
| map_pure f (INum (_, t0)) = |
|
306 |
f t0 |
|
307 |
| map_pure f (IChar (_, t0)) = |
|
308 |
f t0 |
|
309 |
| map_pure f (ICase (_, t0)) = |
|
310 |
f t0; |
|
| 18912 | 311 |
|
| 19202 | 312 |
fun add_constnames (IConst (c, _)) = |
313 |
insert (op =) c |
|
314 |
| add_constnames (IVar _) = |
|
|
19167
f237c0cb3882
refined representation of codegen intermediate language
haftmann
parents:
19150
diff
changeset
|
315 |
I |
| 20439 | 316 |
| add_constnames (t1 `$ t2) = |
317 |
add_constnames t1 #> add_constnames t2 |
|
318 |
| add_constnames (_ `|-> t) = |
|
319 |
add_constnames t |
|
320 |
| add_constnames (INum (_, t0)) = |
|
321 |
add_constnames t0 |
|
322 |
| add_constnames (IChar (_, t0)) = |
|
323 |
add_constnames t0 |
|
324 |
| add_constnames (ICase (_, t0)) = |
|
325 |
add_constnames t0; |
|
| 19202 | 326 |
|
327 |
fun add_varnames (IConst _) = |
|
328 |
I |
|
329 |
| add_varnames (IVar v) = |
|
|
19167
f237c0cb3882
refined representation of codegen intermediate language
haftmann
parents:
19150
diff
changeset
|
330 |
insert (op =) v |
| 20439 | 331 |
| add_varnames (t1 `$ t2) = |
332 |
add_varnames t1 #> add_varnames t2 |
|
333 |
| add_varnames ((v, _) `|-> t) = |
|
334 |
insert (op =) v #> add_varnames t |
|
335 |
| add_varnames (INum (_, t)) = |
|
336 |
add_varnames t |
|
337 |
| add_varnames (IChar (_, t)) = |
|
338 |
add_varnames t |
|
339 |
| add_varnames (ICase (((td, _), bs), _)) = |
|
340 |
add_varnames td #> fold (fn (p, t) => add_varnames p #> add_varnames t) bs; |
|
| 18885 | 341 |
|
| 20709 | 342 |
fun add_unbound_varnames (IConst _) = |
343 |
I |
|
344 |
| add_unbound_varnames (IVar v) = |
|
345 |
insert (op =) v |
|
346 |
| add_unbound_varnames (t1 `$ t2) = |
|
347 |
add_unbound_varnames t1 #> add_unbound_varnames t2 |
|
348 |
| add_unbound_varnames ((v, _) `|-> t) = |
|
349 |
I |
|
350 |
| add_unbound_varnames (INum (_, t)) = |
|
351 |
add_unbound_varnames t |
|
352 |
| add_unbound_varnames (IChar (_, t)) = |
|
353 |
add_unbound_varnames t |
|
354 |
| add_unbound_varnames (ICase (((td, _), bs), _)) = |
|
355 |
add_unbound_varnames td #> fold (fn (p, t) => add_unbound_varnames p #> add_unbound_varnames t) bs; |
|
356 |
||
| 20439 | 357 |
fun vars_distinct ts = |
| 18885 | 358 |
let |
| 20105 | 359 |
fun distinct _ NONE = |
360 |
NONE |
|
361 |
| distinct (IConst _) x = |
|
362 |
x |
|
363 |
| distinct (IVar v) (SOME vs) = |
|
364 |
if member (op =) vs v then NONE else SOME (v::vs) |
|
| 20439 | 365 |
| distinct (t1 `$ t2) x = |
366 |
x |> distinct t1 |> distinct t2 |
|
367 |
| distinct (_ `|-> t) x = |
|
368 |
x |> distinct t |
|
| 20105 | 369 |
| distinct (INum _) x = |
370 |
x |
|
371 |
| distinct (IChar _) x = |
|
372 |
x |
|
| 20439 | 373 |
| distinct (ICase (((td, _), bs), _)) x = |
374 |
x |> distinct td |> fold (fn (p, t) => distinct p #> distinct t) bs; |
|
375 |
in is_some (fold distinct ts (SOME [])) end; |
|
| 20105 | 376 |
|
| 20439 | 377 |
fun eta_expand (c as (_, (_, ty)), ts) k = |
|
19607
07eeb832f28d
introduced characters for code generator; some improved code lemmas for some list functions
haftmann
parents:
19597
diff
changeset
|
378 |
let |
| 20439 | 379 |
val j = length ts; |
|
19607
07eeb832f28d
introduced characters for code generator; some improved code lemmas for some list functions
haftmann
parents:
19597
diff
changeset
|
380 |
val l = k - j; |
|
07eeb832f28d
introduced characters for code generator; some improved code lemmas for some list functions
haftmann
parents:
19597
diff
changeset
|
381 |
val tys = (curry Library.take l o curry Library.drop j o fst o unfold_fun) ty; |
| 20439 | 382 |
val vs_tys = Name.names (fold Name.declare (fold add_varnames ts []) Name.context) "a" tys; |
383 |
in vs_tys `|--> IConst c `$$ ts @ map (fn (v, _) => IVar v) vs_tys end; |
|
|
19607
07eeb832f28d
introduced characters for code generator; some improved code lemmas for some list functions
haftmann
parents:
19597
diff
changeset
|
384 |
|
| 18304 | 385 |
|
| 18282 | 386 |
|
| 18170 | 387 |
(** language module system - definitions, modules, transactions **) |
388 |
||
389 |
(* type definitions *) |
|
390 |
||
| 20456 | 391 |
type typscheme = (vname * sort) list * itype; |
| 18170 | 392 |
datatype def = |
|
19816
a8c8ed1c85e0
removed 'primitive definitions' added (non)strict generation, minor fixes
haftmann
parents:
19785
diff
changeset
|
393 |
Bot |
| 20456 | 394 |
| Fun of (iterm list * iterm) list * typscheme |
395 |
| Typesyn of typscheme |
|
396 |
| Datatype of (vname * sort) list * (string * itype list) list |
|
|
18380
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
397 |
| Datatypecons of string |
| 20456 | 398 |
| Class of class list * (vname * (string * itype) list) |
|
18380
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
399 |
| Classmember of class |
| 20389 | 400 |
| Classinst of (class * (string * (vname * sort) list)) |
| 20466 | 401 |
* ((class * (string * inst list list)) list |
| 20456 | 402 |
* (string * iterm) list); |
| 18170 | 403 |
|
404 |
datatype node = Def of def | Module of node Graph.T; |
|
405 |
type module = node Graph.T; |
|
| 18702 | 406 |
type transact = Graph.key option * module; |
|
19816
a8c8ed1c85e0
removed 'primitive definitions' added (non)strict generation, minor fixes
haftmann
parents:
19785
diff
changeset
|
407 |
type 'dst transact_fin = 'dst * module; |
| 18231 | 408 |
exception FAIL of string list * exn option; |
| 18170 | 409 |
|
| 19597 | 410 |
val eq_def = (op =) : def * def -> bool; |
| 18170 | 411 |
|
412 |
(* simple diagnosis *) |
|
413 |
||
|
19816
a8c8ed1c85e0
removed 'primitive definitions' added (non)strict generation, minor fixes
haftmann
parents:
19785
diff
changeset
|
414 |
fun pretty_def Bot = |
|
a8c8ed1c85e0
removed 'primitive definitions' added (non)strict generation, minor fixes
haftmann
parents:
19785
diff
changeset
|
415 |
Pretty.str "<Bot>" |
| 20456 | 416 |
| pretty_def (Fun (eqs, (vs, ty))) = |
| 18812 | 417 |
Pretty.enum " |" "" "" ( |
| 18170 | 418 |
map (fn (ps, body) => |
419 |
Pretty.block [ |
|
| 20105 | 420 |
Pretty.enum "," "[" "]" (map pretty_iterm ps), |
| 18170 | 421 |
Pretty.str " |->", |
422 |
Pretty.brk 1, |
|
| 20105 | 423 |
pretty_iterm body, |
| 18170 | 424 |
Pretty.str "::", |
| 20456 | 425 |
pretty_typparms vs, |
|
19341
3414c04fbc39
added definitional code generator module: codegen_theorems.ML
haftmann
parents:
19300
diff
changeset
|
426 |
Pretty.str "/", |
| 18170 | 427 |
pretty_itype ty |
428 |
]) eqs |
|
429 |
) |
|
| 18172 | 430 |
| pretty_def (Typesyn (vs, ty)) = |
| 18170 | 431 |
Pretty.block [ |
| 20456 | 432 |
pretty_typparms vs, |
| 18170 | 433 |
Pretty.str " |=> ", |
434 |
pretty_itype ty |
|
435 |
] |
|
| 19038 | 436 |
| pretty_def (Datatype (vs, cs)) = |
| 18170 | 437 |
Pretty.block [ |
| 20456 | 438 |
pretty_typparms vs, |
| 18170 | 439 |
Pretty.str " |=> ", |
| 18852 | 440 |
Pretty.enum " |" "" "" |
| 18850 | 441 |
(map (fn (c, tys) => (Pretty.block o Pretty.breaks) |
| 19038 | 442 |
(Pretty.str c :: map pretty_itype tys)) cs) |
| 18170 | 443 |
] |
|
18380
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
444 |
| pretty_def (Datatypecons dtname) = |
|
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
445 |
Pretty.str ("cons " ^ dtname)
|
| 19038 | 446 |
| pretty_def (Class (supcls, (v, mems))) = |
| 18170 | 447 |
Pretty.block [ |
| 20386 | 448 |
Pretty.str ("class var " ^ v ^ " extending "),
|
| 18812 | 449 |
Pretty.enum "," "[" "]" (map Pretty.str supcls), |
| 18282 | 450 |
Pretty.str " with ", |
| 18852 | 451 |
Pretty.enum "," "[" "]" |
| 20456 | 452 |
(map (fn (m, ty) => Pretty.block |
| 19038 | 453 |
[Pretty.str (m ^ "::"), pretty_itype ty]) mems) |
| 18231 | 454 |
] |
|
18380
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
455 |
| pretty_def (Classmember clsname) = |
| 18231 | 456 |
Pretty.block [ |
457 |
Pretty.str "class member belonging to ", |
|
| 18282 | 458 |
Pretty.str clsname |
| 18231 | 459 |
] |
| 20389 | 460 |
| pretty_def (Classinst ((clsname, (tyco, arity)), _)) = |
| 18231 | 461 |
Pretty.block [ |
462 |
Pretty.str "class instance (",
|
|
| 18282 | 463 |
Pretty.str clsname, |
| 18231 | 464 |
Pretty.str ", (",
|
465 |
Pretty.str tyco, |
|
466 |
Pretty.str ", ", |
|
| 18852 | 467 |
Pretty.enum "," "[" "]" (map (Pretty.enum "," "{" "}" o
|
| 18850 | 468 |
map Pretty.str o snd) arity), |
| 18515 | 469 |
Pretty.str "))" |
| 20389 | 470 |
]; |
| 18170 | 471 |
|
472 |
fun pretty_module modl = |
|
473 |
let |
|
474 |
fun pretty (name, Module modl) = |
|
475 |
Pretty.block ( |
|
476 |
Pretty.str ("module " ^ name ^ " {")
|
|
477 |
:: Pretty.brk 1 |
|
478 |
:: Pretty.chunks (map pretty (AList.make (Graph.get_node modl) |
|
|
19482
9f11af8f7ef9
tuned basic list operators (flat, maps, map_filter);
wenzelm
parents:
19466
diff
changeset
|
479 |
(Graph.strong_conn modl |> flat |> rev))) |
| 18170 | 480 |
:: Pretty.str "}" :: nil |
481 |
) |
|
482 |
| pretty (name, Def def) = |
|
483 |
Pretty.block [Pretty.str name, Pretty.str " :=", Pretty.brk 1, pretty_def def] |
|
484 |
in pretty ("//", Module modl) end;
|
|
485 |
||
| 18360 | 486 |
fun pretty_deps modl = |
487 |
let |
|
488 |
fun one_node key = |
|
|
18380
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
489 |
let |
|
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
490 |
val preds_ = Graph.imm_preds modl key; |
|
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
491 |
val succs_ = Graph.imm_succs modl key; |
|
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
492 |
val mutbs = gen_inter (op =) (preds_, succs_); |
| 19300 | 493 |
val preds = subtract (op =) mutbs preds_; |
494 |
val succs = subtract (op =) mutbs succs_; |
|
|
18380
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
495 |
in |
|
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
496 |
(Pretty.block o Pretty.fbreaks) ( |
|
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
497 |
Pretty.str key |
|
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
498 |
:: map (fn s => Pretty.str ("<-> " ^ s)) mutbs
|
|
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
499 |
@ map (fn s => Pretty.str ("<-- " ^ s)) preds
|
|
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
500 |
@ map (fn s => Pretty.str ("--> " ^ s)) succs
|
| 18850 | 501 |
@ (the_list oo Option.mapPartial) |
502 |
((fn Module modl' => SOME (pretty_deps modl') |
|
503 |
| _ => NONE) o Graph.get_node modl) (SOME key) |
|
|
18380
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
504 |
) |
|
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
505 |
end |
| 18360 | 506 |
in |
507 |
modl |
|
508 |
|> Graph.strong_conn |
|
|
19482
9f11af8f7ef9
tuned basic list operators (flat, maps, map_filter);
wenzelm
parents:
19466
diff
changeset
|
509 |
|> flat |
| 18360 | 510 |
|> rev |
511 |
|> map one_node |
|
512 |
|> Pretty.chunks |
|
513 |
end; |
|
514 |
||
| 18170 | 515 |
|
516 |
(* name handling *) |
|
517 |
||
518 |
fun dest_name name = |
|
519 |
let |
|
520 |
val name' = NameSpace.unpack name |
|
521 |
val (name'', name_base) = split_last name' |
|
522 |
val (modl, shallow) = split_last name'' |
|
523 |
in (modl, NameSpace.pack [shallow, name_base]) end |
|
| 20389 | 524 |
handle Empty => error ("Not a qualified name: " ^ quote name);
|
| 18170 | 525 |
|
526 |
fun dest_modl (Module m) = m; |
|
527 |
fun dest_def (Def d) = d; |
|
528 |
||
529 |
||
530 |
(* modules *) |
|
531 |
||
532 |
val empty_module = Graph.empty; (*read: "depends on"*) |
|
533 |
||
534 |
fun get_def modl name = |
|
535 |
case dest_name name |
|
536 |
of (modlname, base) => |
|
537 |
let |
|
538 |
fun get (Module node) [] = |
|
539 |
(dest_def o Graph.get_node node) base |
|
540 |
| get (Module node) (m::ms) = |
|
541 |
get (Graph.get_node node m) ms |
|
542 |
in get (Module modl) modlname end; |
|
543 |
||
|
19816
a8c8ed1c85e0
removed 'primitive definitions' added (non)strict generation, minor fixes
haftmann
parents:
19785
diff
changeset
|
544 |
fun is_def modl name = |
|
a8c8ed1c85e0
removed 'primitive definitions' added (non)strict generation, minor fixes
haftmann
parents:
19785
diff
changeset
|
545 |
case try (get_def modl) name |
|
a8c8ed1c85e0
removed 'primitive definitions' added (non)strict generation, minor fixes
haftmann
parents:
19785
diff
changeset
|
546 |
of NONE => false |
|
a8c8ed1c85e0
removed 'primitive definitions' added (non)strict generation, minor fixes
haftmann
parents:
19785
diff
changeset
|
547 |
| SOME Bot => false |
|
a8c8ed1c85e0
removed 'primitive definitions' added (non)strict generation, minor fixes
haftmann
parents:
19785
diff
changeset
|
548 |
| _ => true; |
|
a8c8ed1c85e0
removed 'primitive definitions' added (non)strict generation, minor fixes
haftmann
parents:
19785
diff
changeset
|
549 |
|
| 18170 | 550 |
fun add_def (name, def) = |
551 |
let |
|
552 |
val (modl, base) = dest_name name; |
|
553 |
fun add [] = |
|
554 |
Graph.new_node (base, Def def) |
|
555 |
| add (m::ms) = |
|
556 |
Graph.default_node (m, Module empty_module) |
|
557 |
#> Graph.map_node m (Module o add ms o dest_modl) |
|
558 |
in add modl end; |
|
559 |
||
|
19816
a8c8ed1c85e0
removed 'primitive definitions' added (non)strict generation, minor fixes
haftmann
parents:
19785
diff
changeset
|
560 |
fun map_def name f = |
|
a8c8ed1c85e0
removed 'primitive definitions' added (non)strict generation, minor fixes
haftmann
parents:
19785
diff
changeset
|
561 |
let |
|
a8c8ed1c85e0
removed 'primitive definitions' added (non)strict generation, minor fixes
haftmann
parents:
19785
diff
changeset
|
562 |
val (modl, base) = dest_name name; |
|
a8c8ed1c85e0
removed 'primitive definitions' added (non)strict generation, minor fixes
haftmann
parents:
19785
diff
changeset
|
563 |
fun mapp [] = |
|
a8c8ed1c85e0
removed 'primitive definitions' added (non)strict generation, minor fixes
haftmann
parents:
19785
diff
changeset
|
564 |
Graph.map_node base (Def o f o dest_def) |
|
a8c8ed1c85e0
removed 'primitive definitions' added (non)strict generation, minor fixes
haftmann
parents:
19785
diff
changeset
|
565 |
| mapp (m::ms) = |
|
a8c8ed1c85e0
removed 'primitive definitions' added (non)strict generation, minor fixes
haftmann
parents:
19785
diff
changeset
|
566 |
Graph.map_node m (Module o mapp ms o dest_modl) |
|
a8c8ed1c85e0
removed 'primitive definitions' added (non)strict generation, minor fixes
haftmann
parents:
19785
diff
changeset
|
567 |
in mapp modl end; |
|
a8c8ed1c85e0
removed 'primitive definitions' added (non)strict generation, minor fixes
haftmann
parents:
19785
diff
changeset
|
568 |
|
|
a8c8ed1c85e0
removed 'primitive definitions' added (non)strict generation, minor fixes
haftmann
parents:
19785
diff
changeset
|
569 |
fun ensure_bot name = |
|
a8c8ed1c85e0
removed 'primitive definitions' added (non)strict generation, minor fixes
haftmann
parents:
19785
diff
changeset
|
570 |
let |
|
a8c8ed1c85e0
removed 'primitive definitions' added (non)strict generation, minor fixes
haftmann
parents:
19785
diff
changeset
|
571 |
val (modl, base) = dest_name name; |
|
a8c8ed1c85e0
removed 'primitive definitions' added (non)strict generation, minor fixes
haftmann
parents:
19785
diff
changeset
|
572 |
fun ensure [] module = |
|
a8c8ed1c85e0
removed 'primitive definitions' added (non)strict generation, minor fixes
haftmann
parents:
19785
diff
changeset
|
573 |
(case try (Graph.get_node module) base |
|
a8c8ed1c85e0
removed 'primitive definitions' added (non)strict generation, minor fixes
haftmann
parents:
19785
diff
changeset
|
574 |
of NONE => |
|
a8c8ed1c85e0
removed 'primitive definitions' added (non)strict generation, minor fixes
haftmann
parents:
19785
diff
changeset
|
575 |
module |
|
a8c8ed1c85e0
removed 'primitive definitions' added (non)strict generation, minor fixes
haftmann
parents:
19785
diff
changeset
|
576 |
|> Graph.new_node (base, Def Bot) |
| 20389 | 577 |
| SOME (Module _) => error ("Module already present: " ^ quote name)
|
|
19816
a8c8ed1c85e0
removed 'primitive definitions' added (non)strict generation, minor fixes
haftmann
parents:
19785
diff
changeset
|
578 |
| _ => module) |
|
a8c8ed1c85e0
removed 'primitive definitions' added (non)strict generation, minor fixes
haftmann
parents:
19785
diff
changeset
|
579 |
| ensure (m::ms) module = |
|
a8c8ed1c85e0
removed 'primitive definitions' added (non)strict generation, minor fixes
haftmann
parents:
19785
diff
changeset
|
580 |
module |
|
a8c8ed1c85e0
removed 'primitive definitions' added (non)strict generation, minor fixes
haftmann
parents:
19785
diff
changeset
|
581 |
|> Graph.default_node (m, Module empty_module) |
|
a8c8ed1c85e0
removed 'primitive definitions' added (non)strict generation, minor fixes
haftmann
parents:
19785
diff
changeset
|
582 |
|> Graph.map_node m (Module o ensure ms o dest_modl) |
|
a8c8ed1c85e0
removed 'primitive definitions' added (non)strict generation, minor fixes
haftmann
parents:
19785
diff
changeset
|
583 |
in ensure modl end; |
|
a8c8ed1c85e0
removed 'primitive definitions' added (non)strict generation, minor fixes
haftmann
parents:
19785
diff
changeset
|
584 |
|
|
a8c8ed1c85e0
removed 'primitive definitions' added (non)strict generation, minor fixes
haftmann
parents:
19785
diff
changeset
|
585 |
fun add_def_incr strict (name, Bot) module = |
|
a8c8ed1c85e0
removed 'primitive definitions' added (non)strict generation, minor fixes
haftmann
parents:
19785
diff
changeset
|
586 |
(case try (get_def module) name |
| 20389 | 587 |
of NONE => if strict then error "Attempted to add Bot to module" |
|
19816
a8c8ed1c85e0
removed 'primitive definitions' added (non)strict generation, minor fixes
haftmann
parents:
19785
diff
changeset
|
588 |
else map_def name (K Bot) module |
| 20389 | 589 |
| SOME Bot => if strict then error "Attempted to add Bot to module" |
|
19816
a8c8ed1c85e0
removed 'primitive definitions' added (non)strict generation, minor fixes
haftmann
parents:
19785
diff
changeset
|
590 |
else map_def name (K Bot) module |
|
a8c8ed1c85e0
removed 'primitive definitions' added (non)strict generation, minor fixes
haftmann
parents:
19785
diff
changeset
|
591 |
| SOME _ => module) |
|
a8c8ed1c85e0
removed 'primitive definitions' added (non)strict generation, minor fixes
haftmann
parents:
19785
diff
changeset
|
592 |
| add_def_incr _ (name, def) module = |
|
a8c8ed1c85e0
removed 'primitive definitions' added (non)strict generation, minor fixes
haftmann
parents:
19785
diff
changeset
|
593 |
(case try (get_def module) name |
|
a8c8ed1c85e0
removed 'primitive definitions' added (non)strict generation, minor fixes
haftmann
parents:
19785
diff
changeset
|
594 |
of NONE => add_def (name, def) module |
|
a8c8ed1c85e0
removed 'primitive definitions' added (non)strict generation, minor fixes
haftmann
parents:
19785
diff
changeset
|
595 |
| SOME Bot => map_def name (K def) module |
|
a8c8ed1c85e0
removed 'primitive definitions' added (non)strict generation, minor fixes
haftmann
parents:
19785
diff
changeset
|
596 |
| SOME def' => if eq_def (def, def') |
|
a8c8ed1c85e0
removed 'primitive definitions' added (non)strict generation, minor fixes
haftmann
parents:
19785
diff
changeset
|
597 |
then module |
| 20389 | 598 |
else error ("Tried to overwrite definition " ^ quote name));
|
|
19816
a8c8ed1c85e0
removed 'primitive definitions' added (non)strict generation, minor fixes
haftmann
parents:
19785
diff
changeset
|
599 |
|
| 18170 | 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 @); |
|
| 20105 | 606 |
val (ms, (r1, r2)) = chop_prefix (op =) (m1, m2); |
607 |
val (ms, (s1::r1, s2::r2)) = chop_prefix (op =) (m1, m2); |
|
| 18170 | 608 |
val add_edge = |
609 |
if null r1 andalso null r2 |
|
610 |
then Graph.add_edge |
|
| 19785 | 611 |
else fn edge => fn gr => (Graph.add_edge_acyclic edge gr |
| 19884 | 612 |
handle Graph.CYCLES _ => |
| 20389 | 613 |
error ("Adding dependency "
|
| 19884 | 614 |
^ quote name1 ^ " -> " ^ quote name2 ^ " would result in module dependency cycle")) |
| 18170 | 615 |
fun add [] node = |
616 |
node |
|
617 |
|> add_edge (s1, s2) |
|
618 |
| add (m::ms) node = |
|
619 |
node |
|
620 |
|> Graph.map_node m (Module o add ms o dest_modl); |
|
621 |
in add ms modl end; |
|
622 |
||
623 |
fun merge_module modl12 = |
|
624 |
let |
|
| 19025 | 625 |
fun join_module _ (Module m1, Module m2) = |
626 |
Module (merge_module (m1, m2)) |
|
627 |
| join_module name (Def d1, Def d2) = |
|
| 19884 | 628 |
if eq_def (d1, d2) then Def d1 else Def Bot |
| 19025 | 629 |
| join_module name _ = raise Graph.DUP name |
630 |
in Graph.join join_module modl12 end; |
|
| 18170 | 631 |
|
|
19042
630b8dd0b31a
exported some interfaces useful for other code generator approaches
haftmann
parents:
19038
diff
changeset
|
632 |
fun diff_module modl12 = |
|
630b8dd0b31a
exported some interfaces useful for other code generator approaches
haftmann
parents:
19038
diff
changeset
|
633 |
let |
| 20191 | 634 |
fun diff_entry prefix modl2 (name, Def def1) = |
|
19042
630b8dd0b31a
exported some interfaces useful for other code generator approaches
haftmann
parents:
19038
diff
changeset
|
635 |
let |
|
630b8dd0b31a
exported some interfaces useful for other code generator approaches
haftmann
parents:
19038
diff
changeset
|
636 |
val e2 = try (Graph.get_node modl2) name |
|
630b8dd0b31a
exported some interfaces useful for other code generator approaches
haftmann
parents:
19038
diff
changeset
|
637 |
in if is_some e2 andalso eq_def (def1, (dest_def o the) e2) |
|
630b8dd0b31a
exported some interfaces useful for other code generator approaches
haftmann
parents:
19038
diff
changeset
|
638 |
then I |
|
630b8dd0b31a
exported some interfaces useful for other code generator approaches
haftmann
parents:
19038
diff
changeset
|
639 |
else cons (NameSpace.pack (prefix @ [name]), def1) |
|
630b8dd0b31a
exported some interfaces useful for other code generator approaches
haftmann
parents:
19038
diff
changeset
|
640 |
end |
|
630b8dd0b31a
exported some interfaces useful for other code generator approaches
haftmann
parents:
19038
diff
changeset
|
641 |
| diff_entry prefix modl2 (name, Module modl1) = |
|
630b8dd0b31a
exported some interfaces useful for other code generator approaches
haftmann
parents:
19038
diff
changeset
|
642 |
diff_modl (prefix @ [name]) (modl1, |
|
630b8dd0b31a
exported some interfaces useful for other code generator approaches
haftmann
parents:
19038
diff
changeset
|
643 |
(the_default empty_module o Option.map dest_modl o try (Graph.get_node modl2)) name) |
|
630b8dd0b31a
exported some interfaces useful for other code generator approaches
haftmann
parents:
19038
diff
changeset
|
644 |
and diff_modl prefix (modl1, modl2) = |
|
630b8dd0b31a
exported some interfaces useful for other code generator approaches
haftmann
parents:
19038
diff
changeset
|
645 |
fold (diff_entry prefix modl2) |
| 19466 | 646 |
((AList.make (Graph.get_node modl1) o flat o Graph.strong_conn) modl1) |
|
19042
630b8dd0b31a
exported some interfaces useful for other code generator approaches
haftmann
parents:
19038
diff
changeset
|
647 |
in diff_modl [] modl12 [] end; |
|
630b8dd0b31a
exported some interfaces useful for other code generator approaches
haftmann
parents:
19038
diff
changeset
|
648 |
|
| 19884 | 649 |
fun project_module names modl = |
| 18335 | 650 |
let |
651 |
datatype pathnode = PN of (string list * (string * pathnode) list); |
|
652 |
fun mk_ipath ([], base) (PN (defs, modls)) = |
|
653 |
PN (base :: defs, modls) |
|
654 |
| mk_ipath (n::ns, base) (PN (defs, modls)) = |
|
655 |
modls |
|
656 |
|> AList.default (op =) (n, PN ([], [])) |
|
657 |
|> AList.map_entry (op =) n (mk_ipath (ns, base)) |
|
658 |
|> (pair defs #> PN); |
|
659 |
fun select (PN (defs, modls)) (Module module) = |
|
660 |
module |
|
| 20191 | 661 |
|> Graph.project (member (op =) ((*!*) Graph.all_succs module (defs @ map fst modls))) |
| 18335 | 662 |
|> fold (fn (name, modls) => Graph.map_node name (select modls)) modls |
663 |
|> Module; |
|
664 |
in |
|
665 |
Module modl |
|
| 18850 | 666 |
|> select (fold (mk_ipath o dest_name) |
667 |
(filter NameSpace.is_qualified names) (PN ([], []))) |
|
| 18335 | 668 |
|> dest_modl |
669 |
end; |
|
| 18170 | 670 |
|
| 19884 | 671 |
fun purge_module names modl = |
| 18702 | 672 |
let |
| 19884 | 673 |
fun split_names names = |
674 |
fold |
|
675 |
(fn ([], name) => apfst (cons name) |
|
676 |
| (m::ms, name) => apsnd (AList.default (op =) (m : string, []) |
|
677 |
#> AList.map_entry (op =) m (cons (ms, name)))) |
|
678 |
names ([], []); |
|
679 |
fun purge names (Module modl) = |
|
680 |
let |
|
681 |
val (ndefs, nmodls) = split_names names; |
|
682 |
in |
|
| 20191 | 683 |
modl |
| 19884 | 684 |
|> Graph.del_nodes (Graph.all_preds modl ndefs) |
| 20191 | 685 |
|> Graph.del_nodes ndefs |
686 |
|> Graph.del_nodes (Graph.all_preds modl (map fst nmodls)) |
|
| 19884 | 687 |
|> fold (fn (nmodl, names') => Graph.map_node nmodl (purge names')) nmodls |
688 |
|> Module |
|
689 |
end; |
|
| 18702 | 690 |
in |
| 19884 | 691 |
Module modl |
692 |
|> purge (map dest_name names) |
|
693 |
|> dest_modl |
|
| 18702 | 694 |
end; |
695 |
||
| 20428 | 696 |
fun flat_module modl = |
697 |
maps ( |
|
698 |
fn (name, Module modl) => map (apfst (NameSpace.append name)) (flat_module modl) |
|
699 |
| (name, Def def) => [(name, def)] |
|
700 |
) ((AList.make (Graph.get_node modl) o flat o Graph.strong_conn) modl) |
|
701 |
||
702 |
(* |
|
| 20466 | 703 |
(*FIXME: graph-based approach is better. |
704 |
* build graph |
|
705 |
* implement flat_classops on sort level, not class level |
|
706 |
* flat_instances bleibt wie es ist |
|
707 |
*) |
|
708 |
fun flat_classops modl = |
|
709 |
let |
|
710 |
fun add_ancestry class anc = |
|
711 |
let |
|
712 |
val SOME (Class (super_classes, (v, ops))) = AList.lookup (op =) modl class |
|
713 |
val super_classees' = filter (not o member (fn (c', (c, _)) => c = c') anc) super_classes; |
|
714 |
in |
|
715 |
[(class, ops)] @ anc |
|
716 |
|> fold add_ancestry super_classees' |
|
717 |
end; |
|
718 |
in |
|
719 |
Symtab.empty |
|
720 |
|> fold ( |
|
721 |
fn (class, Class _) => |
|
722 |
Symtab.update_new (class, maps snd (add_ancestry class [])) |
|
723 |
| _ => I |
|
724 |
) modl |
|
725 |
|> the oo Symtab.lookup |
|
726 |
end; |
|
727 |
||
728 |
fun flat_instances modl = |
|
729 |
let |
|
730 |
fun add_ancestry instance instsss anc = |
|
731 |
let |
|
732 |
val SOME (Classinst (_, (super_instances, ops))) = AList.lookup (op =) modl instance; |
|
733 |
val super_instances' = filter (not o member (eq_fst (op =)) anc) super_instances; |
|
734 |
val ops' = map (apsnd (rpair instsss)) ops; |
|
735 |
(*FIXME: build types*) |
|
736 |
in |
|
737 |
[(instance, ops')] @ anc |
|
738 |
|> fold (fn (_, (instance, instss)) => add_ancestry instance (instss :: instsss)) super_instances' |
|
739 |
end; |
|
740 |
in |
|
741 |
Symtab.empty |
|
742 |
|> fold ( |
|
743 |
fn (instance, Classinst _) => |
|
744 |
Symtab.update_new (instance, maps snd (add_ancestry instance [] [])) |
|
745 |
| _ => I |
|
746 |
) modl |
|
747 |
|> the oo Symtab.lookup |
|
748 |
end; |
|
749 |
||
750 |
fun flat_fundef classops instdefs is_classop (eqs, (vs, ty)) = |
|
751 |
let |
|
752 |
fun fold_map_snd' f (x, ys) = fold_map (f x) ys; |
|
753 |
fun fold_map_snd f (x, ys) = fold_map f ys #-> (fn zs => pair (x, zs)); |
|
754 |
val names = |
|
755 |
Name.context |
|
756 |
|> fold Name.declare |
|
757 |
(fold (fn (rhs, lhs) => fold add_varnames rhs #> add_varnames lhs) eqs []); |
|
758 |
val opmap = [] : (string * (string * (string * itype) list) list) list; |
|
759 |
val (params, tys) = (split_list o maps snd o maps snd) opmap; |
|
760 |
(*fun name_ops v' class = |
|
761 |
(fold_map o fold_map_snd') |
|
762 |
(fn (class, v) => fn (c, ty) => Name.variants [c] #-> (fn [p] => |
|
763 |
pair (class, v') (c, (ty, p)))) |
|
764 |
(classops class); |
|
765 |
val (opsmap, _) = (fold_map o fold_map_snd') name_ops vs names; |
|
766 |
(* --> (iterm * itype) list *)*) |
|
767 |
fun flat_inst (Instance (instance, instss)) = |
|
768 |
let |
|
769 |
val xs : (string * (iterm * (itype * inst list list list))) list = instdefs instance |
|
770 |
fun mk_t (t, (ty, instsss)) = |
|
771 |
(Library.foldl (fn (t, instss) => t `$$ map (fst o snd) ((maps o maps) flat_inst instss)) |
|
772 |
(t, instss :: instsss), ty) |
|
773 |
in |
|
774 |
map (apsnd mk_t) xs |
|
775 |
end |
|
776 |
| flat_inst (Context (classes, (v, k))) = |
|
777 |
let |
|
778 |
val _ : 'a = classops (hd classes); |
|
779 |
in |
|
780 |
[] |
|
781 |
end |
|
782 |
(* |
|
783 |
val parm_map = nth ((the o AList.lookup (op =) octxt) v) |
|
784 |
(if k = ~1 then 0 else k); |
|
785 |
in map (apfst IVar o swap o snd) (case classes |
|
786 |
of class::_ => (the o AList.lookup (op =) parm_map) class |
|
787 |
| _ => (snd o hd) parm_map)*) |
|
788 |
and flat_iterm (e as IConst (c, (lss, ty))) = |
|
789 |
if is_classop c then let |
|
790 |
val tab = (maps o maps) flat_inst lss; |
|
791 |
val SOME (t, _) = AList.lookup (op =) tab c; |
|
792 |
in t end else let |
|
793 |
val (es, tys) = (split_list o map snd) ((maps o maps) flat_inst lss) |
|
794 |
in IConst (c, (replicate (length lss) [], tys `--> ty)) `$$ es end |
|
795 |
| flat_iterm (e as IVar _) = |
|
796 |
e |
|
797 |
| flat_iterm (e1 `$ e2) = |
|
798 |
flat_iterm e1 `$ flat_iterm e2 |
|
799 |
| flat_iterm (v_ty `|-> e) = |
|
800 |
v_ty `|-> flat_iterm e |
|
801 |
| flat_iterm (INum (k, e)) = |
|
802 |
INum (k, flat_iterm e) |
|
803 |
| flat_iterm (IChar (s, e)) = |
|
804 |
IChar (s, flat_iterm e) |
|
805 |
| flat_iterm (ICase (((de, dty), es), e)) = |
|
806 |
ICase (((flat_iterm de, dty), map (pairself flat_iterm) es), flat_iterm e); |
|
807 |
fun flat_eq (lhs, rhs) = (map IVar params @ lhs, flat_iterm rhs); |
|
808 |
in (map flat_eq eqs, (map (apsnd (K [])) vs, tys `--> ty)) end; |
|
809 |
||
| 20428 | 810 |
fun flat_funs_datatypes modl = |
| 20466 | 811 |
let |
812 |
val modl = flat_module modl; |
|
813 |
val classops = flat_classops modl; |
|
814 |
val instdefs = flat_instances modl; |
|
815 |
val is_classop = is_some o AList.lookup (op =) modl; |
|
816 |
in map_filter ( |
|
817 |
fn def as (_, Datatype _) => SOME def |
|
818 |
| (name, Fun funn) => SOME (name, (Fun (flat_fundef classops instdefs is_classop funn))) |
|
819 |
| _ => NONE |
|
820 |
) end; |
|
| 20428 | 821 |
*) |
822 |
||
| 20456 | 823 |
val add_deps_of_typparms = |
| 20191 | 824 |
fold (fn (v : vname, sort : sort) => fold (insert (op =)) sort); |
825 |
||
| 20600 | 826 |
fun add_deps_of_classlookup (Instance (inst, lss)) = |
827 |
insert (op =) inst |
|
| 20191 | 828 |
#> (fold o fold) add_deps_of_classlookup lss |
| 20456 | 829 |
| add_deps_of_classlookup (Context (clss, _)) = |
| 20191 | 830 |
fold (insert (op =)) clss; |
831 |
||
832 |
fun add_deps_of_type (tyco `%% tys) = |
|
833 |
insert (op =) tyco |
|
834 |
#> fold add_deps_of_type tys |
|
835 |
| add_deps_of_type (ty1 `-> ty2) = |
|
836 |
add_deps_of_type ty1 |
|
837 |
#> add_deps_of_type ty2 |
|
838 |
| add_deps_of_type (ITyVar v) = |
|
839 |
I; |
|
840 |
||
841 |
fun add_deps_of_term (IConst (c, (lss, ty))) = |
|
842 |
insert (op =) c |
|
843 |
#> add_deps_of_type ty |
|
844 |
#> (fold o fold) add_deps_of_classlookup lss |
|
845 |
| add_deps_of_term (IVar _) = |
|
846 |
I |
|
847 |
| add_deps_of_term (e1 `$ e2) = |
|
848 |
add_deps_of_term e1 #> add_deps_of_term e2 |
|
849 |
| add_deps_of_term ((_, ty) `|-> e) = |
|
850 |
add_deps_of_type ty |
|
851 |
#> add_deps_of_term e |
|
852 |
| add_deps_of_term (INum _) = |
|
853 |
I |
|
854 |
| add_deps_of_term (IChar (_, e)) = |
|
855 |
add_deps_of_term e |
|
856 |
| add_deps_of_term (ICase (_, e)) = |
|
857 |
add_deps_of_term e; |
|
858 |
||
859 |
fun deps_of Bot = |
|
860 |
[] |
|
| 20456 | 861 |
| deps_of (Fun (eqs, (vs, ty))) = |
| 20191 | 862 |
[] |
| 20456 | 863 |
|> add_deps_of_typparms vs |
| 20191 | 864 |
|> add_deps_of_type ty |
865 |
|> fold (fn (lhs, rhs) => fold add_deps_of_term lhs #> add_deps_of_term rhs) eqs |
|
| 20456 | 866 |
| deps_of (Typesyn (vs, ty)) = |
| 20191 | 867 |
[] |
| 20456 | 868 |
|> add_deps_of_typparms vs |
| 20191 | 869 |
|> add_deps_of_type ty |
| 20456 | 870 |
| deps_of (Datatype (vs, cos)) = |
| 20191 | 871 |
[] |
| 20456 | 872 |
|> add_deps_of_typparms vs |
| 20191 | 873 |
|> fold (fn (c, tys) => insert (op =) c #> fold add_deps_of_type tys) cos |
874 |
| deps_of (Datatypecons dtco) = |
|
875 |
[dtco] |
|
876 |
| deps_of (Class (supclss, (_, memdecls))) = |
|
877 |
[] |
|
878 |
|> fold (insert (op =)) supclss |
|
| 20456 | 879 |
|> fold (fn (name, ty) => |
| 20191 | 880 |
insert (op =) name |
881 |
#> add_deps_of_type ty |
|
882 |
) memdecls |
|
883 |
| deps_of (Classmember class) = |
|
884 |
[class] |
|
| 20456 | 885 |
| deps_of (Classinst ((class, (tyco, vs)), (suparities, memdefs))) = |
| 20191 | 886 |
[] |
887 |
|> insert (op =) class |
|
888 |
|> insert (op =) tyco |
|
| 20456 | 889 |
|> add_deps_of_typparms vs |
| 20466 | 890 |
|> fold (fn (supclass, (supinst, lss)) => |
| 20191 | 891 |
insert (op =) supclass |
| 20466 | 892 |
#> insert (op =) supinst |
893 |
#> (fold o fold) add_deps_of_classlookup lss |
|
| 20191 | 894 |
) suparities |
| 20389 | 895 |
|> fold (fn (name, e) => |
| 20191 | 896 |
insert (op =) name |
| 20389 | 897 |
#> add_deps_of_term e |
898 |
) memdefs; |
|
| 20191 | 899 |
|
900 |
fun delete_garbage hidden modl = |
|
901 |
let |
|
902 |
fun allnames modl = |
|
903 |
let |
|
904 |
val entries = AList.make (Graph.get_node modl) (Graph.keys modl) |
|
905 |
fun is_def (name, Module _) = NONE |
|
906 |
| is_def (name, _) = SOME name; |
|
907 |
fun is_modl (name, Module modl) = SOME (name, modl) |
|
908 |
| is_modl (name, _) = NONE; |
|
909 |
val defs = map_filter is_def entries; |
|
910 |
val modls = map_filter is_modl entries; |
|
911 |
in |
|
912 |
defs |
|
913 |
@ maps (fn (name, modl) => map (NameSpace.append name) (allnames modl)) modls |
|
914 |
end; |
|
915 |
fun alldeps modl = |
|
916 |
let |
|
917 |
val entries = AList.make (Graph.get_node modl) (Graph.keys modl) |
|
918 |
fun is_def (name, Module _) = NONE |
|
919 |
| is_def (name, _) = SOME name; |
|
920 |
fun is_modl (name, Module modl) = SOME (name, modl) |
|
921 |
| is_modl (name, _) = NONE; |
|
922 |
val defs = map_filter is_def entries; |
|
923 |
val modls = map_filter is_modl entries; |
|
924 |
in |
|
925 |
maps (fn name => map (pair (name)) (Graph.imm_succs modl name)) defs |
|
926 |
@ maps (fn (name, modl) => (map o pairself) (NameSpace.append name) (alldeps modl)) modls |
|
927 |
end; |
|
928 |
val names = subtract (op =) hidden (allnames modl); |
|
| 20353 | 929 |
(* val _ = writeln "HIDDEN"; *) |
930 |
(* val _ = (writeln o commas) hidden; *) |
|
931 |
(* val _ = writeln "NAMES"; *) |
|
932 |
(* val _ = (writeln o commas) names; *) |
|
| 20191 | 933 |
fun is_bot name = |
934 |
case get_def modl name of Bot => true | _ => false; |
|
935 |
val bots = filter is_bot names; |
|
936 |
val defs = filter (not o is_bot) names; |
|
937 |
val expldeps = |
|
938 |
Graph.empty |
|
939 |
|> fold (fn name => Graph.new_node (name, ())) names |
|
940 |
|> fold (fn name => fold (curry Graph.add_edge name) |
|
941 |
(deps_of (get_def modl name) |> subtract (op =) hidden)) names |
|
942 |
val bots' = fold (insert op =) bots (Graph.all_preds expldeps bots); |
|
943 |
val selected = subtract (op =) bots' names; |
|
944 |
(* val deps = filter (fn (x, y) => member (op =) selected x andalso member (op =) selected y) *) |
|
945 |
val adddeps = maps (fn (n, ns) => map (pair n) ns) (expldeps |> Graph.del_nodes bots' |> Graph.dest); |
|
| 20353 | 946 |
(* val _ = writeln "SELECTED"; |
| 20191 | 947 |
val _ = (writeln o commas) selected; |
948 |
val _ = writeln "DEPS"; |
|
| 20353 | 949 |
val _ = (writeln o cat_lines o map (fn (x, y) => x ^ " -> " ^ y)) adddeps; *) |
| 20191 | 950 |
in |
951 |
empty_module |
|
952 |
|> fold (fn name => add_def (name, get_def modl name)) selected |
|
953 |
(* |> fold ensure_bot (hidden @ bots') *) |
|
| 20216 | 954 |
|> fold (fn (x, y) => ((*writeln ("adding " ^ x ^ " -> " ^ y);*) add_dep (x, y))) adddeps
|
| 20191 | 955 |
end; |
956 |
||
| 19884 | 957 |
fun allimports_of modl = |
958 |
let |
|
959 |
fun imps_of prfx (Module modl) imps tab = |
|
960 |
let |
|
961 |
val this = NameSpace.pack prfx; |
|
962 |
val name_con = (rev o Graph.strong_conn) modl; |
|
963 |
in |
|
964 |
tab |
|
965 |
|> pair [] |
|
966 |
|> fold (fn names => fn (imps', tab) => |
|
967 |
tab |
|
| 20191 | 968 |
|> fold_map (fn name => |
| 19884 | 969 |
imps_of (prfx @ [name]) (Graph.get_node modl name) (imps' @ imps)) names |
970 |
|-> (fn imps'' => pair (flat imps'' @ imps'))) name_con |
|
| 20191 | 971 |
|-> (fn imps' => |
| 19884 | 972 |
Symtab.update_new (this, imps' @ imps) |
973 |
#> pair (this :: imps')) |
|
974 |
end |
|
975 |
| imps_of prfx (Def _) imps tab = |
|
976 |
([], tab); |
|
977 |
in snd (imps_of [] (Module modl) [] Symtab.empty) end; |
|
978 |
||
| 18702 | 979 |
fun check_samemodule names = |
980 |
fold (fn name => |
|
981 |
let |
|
982 |
val modn = (fst o dest_name) name |
|
983 |
in |
|
984 |
fn NONE => SOME modn |
|
| 18850 | 985 |
| SOME mod' => if modn = mod' then SOME modn |
| 20386 | 986 |
else error ("Inconsistent name prefix for simultanous names: " ^ commas_quote names)
|
| 18702 | 987 |
end |
988 |
) names NONE; |
|
989 |
||
990 |
fun check_funeqs eqs = |
|
991 |
(fold (fn (pats, _) => |
|
992 |
let |
|
993 |
val l = length pats |
|
994 |
in |
|
995 |
fn NONE => SOME l |
|
| 18850 | 996 |
| SOME l' => if l = l' then SOME l |
| 20389 | 997 |
else error "Function definition with different number of arguments" |
| 18702 | 998 |
end |
999 |
) eqs NONE; eqs); |
|
1000 |
||
|
19816
a8c8ed1c85e0
removed 'primitive definitions' added (non)strict generation, minor fixes
haftmann
parents:
19785
diff
changeset
|
1001 |
fun check_prep_def modl Bot = |
|
a8c8ed1c85e0
removed 'primitive definitions' added (non)strict generation, minor fixes
haftmann
parents:
19785
diff
changeset
|
1002 |
Bot |
| 18702 | 1003 |
| check_prep_def modl (Fun (eqs, d)) = |
1004 |
Fun (check_funeqs eqs, d) |
|
1005 |
| check_prep_def modl (d as Typesyn _) = |
|
1006 |
d |
|
| 19038 | 1007 |
| check_prep_def modl (d as Datatype _) = |
1008 |
d |
|
| 18702 | 1009 |
| check_prep_def modl (Datatypecons dtco) = |
| 20389 | 1010 |
error "Attempted to add bare datatype constructor" |
| 19038 | 1011 |
| check_prep_def modl (d as Class _) = |
1012 |
d |
|
| 18702 | 1013 |
| check_prep_def modl (Classmember _) = |
| 20389 | 1014 |
error "Attempted to add bare class member" |
1015 |
| check_prep_def modl (d as Classinst ((class, (tyco, arity)), (_, memdefs))) = |
|
| 18170 | 1016 |
let |
| 19038 | 1017 |
val Class (_, (v, membrs)) = get_def modl class; |
| 18702 | 1018 |
val _ = if length memdefs > length memdefs |
| 20389 | 1019 |
then error "Too many member definitions given" |
| 18702 | 1020 |
else (); |
| 20389 | 1021 |
fun check_memdef (m, _) = |
1022 |
if AList.defined (op =) memdefs m |
|
1023 |
then () else error ("Missing definition for member " ^ quote m);
|
|
1024 |
val _ = map check_memdef memdefs; |
|
1025 |
in d end |
|
| 19213 | 1026 |
| check_prep_def modl Classinstmember = |
| 20389 | 1027 |
error "Attempted to add bare class instance member"; |
| 18170 | 1028 |
|
| 19038 | 1029 |
fun postprocess_def (name, Datatype (_, constrs)) = |
| 18702 | 1030 |
(check_samemodule (name :: map fst constrs); |
1031 |
fold (fn (co, _) => |
|
|
19816
a8c8ed1c85e0
removed 'primitive definitions' added (non)strict generation, minor fixes
haftmann
parents:
19785
diff
changeset
|
1032 |
add_def_incr true (co, Datatypecons name) |
| 18702 | 1033 |
#> add_dep (co, name) |
1034 |
#> add_dep (name, co) |
|
1035 |
) constrs |
|
1036 |
) |
|
| 19038 | 1037 |
| postprocess_def (name, Class (_, (_, membrs))) = |
| 18702 | 1038 |
(check_samemodule (name :: map fst membrs); |
1039 |
fold (fn (m, _) => |
|
|
19816
a8c8ed1c85e0
removed 'primitive definitions' added (non)strict generation, minor fixes
haftmann
parents:
19785
diff
changeset
|
1040 |
add_def_incr true (m, Classmember name) |
| 18702 | 1041 |
#> add_dep (m, name) |
1042 |
#> add_dep (name, m) |
|
1043 |
) membrs |
|
1044 |
) |
|
1045 |
| postprocess_def _ = |
|
1046 |
I; |
|
|
18380
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
1047 |
|
| 19884 | 1048 |
|
1049 |
(* transaction protocol *) |
|
| 18170 | 1050 |
|
|
19816
a8c8ed1c85e0
removed 'primitive definitions' added (non)strict generation, minor fixes
haftmann
parents:
19785
diff
changeset
|
1051 |
fun ensure_def defgen strict msg name (dep, modl) = |
| 18170 | 1052 |
let |
| 20389 | 1053 |
(*FIXME represent dependencies as tuple (name, name -> string), for better error msgs*) |
|
19816
a8c8ed1c85e0
removed 'primitive definitions' added (non)strict generation, minor fixes
haftmann
parents:
19785
diff
changeset
|
1054 |
val msg' = (case dep |
| 18702 | 1055 |
of NONE => msg |
| 19884 | 1056 |
| SOME dep => msg ^ ", required for " ^ quote dep) |
|
19816
a8c8ed1c85e0
removed 'primitive definitions' added (non)strict generation, minor fixes
haftmann
parents:
19785
diff
changeset
|
1057 |
^ (if strict then " (strict)" else " (non-strict)"); |
| 18702 | 1058 |
fun add_dp NONE = I |
1059 |
| add_dp (SOME dep) = |
|
|
19341
3414c04fbc39
added definitional code generator module: codegen_theorems.ML
haftmann
parents:
19300
diff
changeset
|
1060 |
debug_msg (fn _ => "adding dependency " ^ quote dep ^ " -> " ^ quote name) |
| 18702 | 1061 |
#> add_dep (dep, name); |
1062 |
fun prep_def def modl = |
|
1063 |
(check_prep_def modl def, modl); |
|
|
19816
a8c8ed1c85e0
removed 'primitive definitions' added (non)strict generation, minor fixes
haftmann
parents:
19785
diff
changeset
|
1064 |
fun invoke_generator name defgen modl = |
| 20191 | 1065 |
if ! soft_exc (*that "!" isn't a "not"...*) |
| 19956 | 1066 |
then defgen name (SOME name, modl) |
1067 |
handle FAIL (msgs, exc) => |
|
1068 |
if strict then raise FAIL (msg' :: msgs, exc) |
|
1069 |
else (Bot, modl) |
|
| 20191 | 1070 |
| e => raise |
| 19956 | 1071 |
FAIL (["definition generator for " ^ quote name, msg'], SOME e) |
1072 |
else defgen name (SOME name, modl) |
|
1073 |
handle FAIL (msgs, exc) => |
|
| 19884 | 1074 |
if strict then raise FAIL (msg' :: msgs, exc) |
| 19956 | 1075 |
else (Bot, modl); |
| 18170 | 1076 |
in |
1077 |
modl |
|
| 18702 | 1078 |
|> (if can (get_def modl) name |
1079 |
then |
|
|
19341
3414c04fbc39
added definitional code generator module: codegen_theorems.ML
haftmann
parents:
19300
diff
changeset
|
1080 |
debug_msg (fn _ => "asserting node " ^ quote name) |
| 18702 | 1081 |
#> add_dp dep |
1082 |
else |
|
|
19816
a8c8ed1c85e0
removed 'primitive definitions' added (non)strict generation, minor fixes
haftmann
parents:
19785
diff
changeset
|
1083 |
debug_msg (fn _ => "allocating node " ^ quote name ^ (if strict then " (strict)" else " (non-strict)")) |
|
a8c8ed1c85e0
removed 'primitive definitions' added (non)strict generation, minor fixes
haftmann
parents:
19785
diff
changeset
|
1084 |
#> ensure_bot name |
| 18702 | 1085 |
#> add_dp dep |
|
19341
3414c04fbc39
added definitional code generator module: codegen_theorems.ML
haftmann
parents:
19300
diff
changeset
|
1086 |
#> debug_msg (fn _ => "creating node " ^ quote name) |
|
19816
a8c8ed1c85e0
removed 'primitive definitions' added (non)strict generation, minor fixes
haftmann
parents:
19785
diff
changeset
|
1087 |
#> invoke_generator name defgen |
| 18702 | 1088 |
#-> (fn def => prep_def def) |
1089 |
#-> (fn def => |
|
|
19341
3414c04fbc39
added definitional code generator module: codegen_theorems.ML
haftmann
parents:
19300
diff
changeset
|
1090 |
debug_msg (fn _ => "addition of " ^ name ^ " := " ^ (Pretty.output o pretty_def) def) |
|
3414c04fbc39
added definitional code generator module: codegen_theorems.ML
haftmann
parents:
19300
diff
changeset
|
1091 |
#> debug_msg (fn _ => "adding") |
|
19816
a8c8ed1c85e0
removed 'primitive definitions' added (non)strict generation, minor fixes
haftmann
parents:
19785
diff
changeset
|
1092 |
#> add_def_incr strict (name, def) |
|
19341
3414c04fbc39
added definitional code generator module: codegen_theorems.ML
haftmann
parents:
19300
diff
changeset
|
1093 |
#> debug_msg (fn _ => "postprocessing") |
| 18702 | 1094 |
#> postprocess_def (name, def) |
|
19341
3414c04fbc39
added definitional code generator module: codegen_theorems.ML
haftmann
parents:
19300
diff
changeset
|
1095 |
#> debug_msg (fn _ => "adding done") |
| 18702 | 1096 |
)) |
1097 |
|> pair dep |
|
| 18170 | 1098 |
end; |
1099 |
||
| 19884 | 1100 |
fun succeed some (_, modl) = (some, modl); |
1101 |
||
1102 |
fun fail msg (_, modl) = raise FAIL ([msg], NONE); |
|
1103 |
||
1104 |
fun message msg f trns = |
|
1105 |
f trns handle FAIL (msgs, exc) => |
|
1106 |
raise FAIL (msg :: msgs, exc); |
|
1107 |
||
| 18963 | 1108 |
fun start_transact init f modl = |
| 18231 | 1109 |
let |
| 18963 | 1110 |
fun handle_fail f x = |
1111 |
(f x |
|
| 18231 | 1112 |
handle FAIL (msgs, NONE) => |
| 20389 | 1113 |
(error o cat_lines) ("Code generation failed, while:" :: msgs))
|
| 18231 | 1114 |
handle FAIL (msgs, SOME e) => |
| 20389 | 1115 |
((Output.error_msg o cat_lines) ("Code generation failed, while:" :: msgs); raise e);
|
| 18231 | 1116 |
in |
| 19884 | 1117 |
modl |
1118 |
|> (if is_some init then ensure_bot (the init) else I) |
|
1119 |
|> pair init |
|
| 18231 | 1120 |
|> handle_fail f |
| 19884 | 1121 |
|-> (fn x => fn (_, modl) => (x, modl)) |
| 18231 | 1122 |
end; |
| 18172 | 1123 |
|
| 20216 | 1124 |
fun add_eval_def (shallow, e) modl = |
| 20191 | 1125 |
let |
| 20216 | 1126 |
val name = "VALUE"; |
1127 |
val sname = NameSpace.pack [shallow, name]; |
|
| 20191 | 1128 |
in |
1129 |
modl |
|
| 20456 | 1130 |
|> add_def (sname, Fun ([([], e)], ([("_", [])], ITyVar "_")))
|
| 20216 | 1131 |
|> fold (curry add_dep sname) (add_deps_of_term e []) |
| 20191 | 1132 |
|> pair name |
1133 |
end; |
|
| 18172 | 1134 |
|
| 18335 | 1135 |
|
| 20389 | 1136 |
(** eliminating classes in definitions **) |
1137 |
||
| 20456 | 1138 |
fun elim_classes modl (eqs, (vs, ty)) = |
| 20389 | 1139 |
let |
1140 |
fun elim_expr _ = (); |
|
1141 |
in (error ""; (eqs, ty)) end; |
|
1142 |
||
| 18216 | 1143 |
(** generic serialization **) |
1144 |
||
1145 |
(* resolving *) |
|
1146 |
||
| 18885 | 1147 |
structure NameMangler = NameManglerFun ( |
1148 |
type ctxt = (string * string -> string) * (string -> string option); |
|
| 18516 | 1149 |
type src = string * string; |
1150 |
val ord = prod_ord string_ord string_ord; |
|
| 18963 | 1151 |
fun mk (postprocess, validate) ((shallow, name), 0) = |
1152 |
let |
|
1153 |
val name' = postprocess (shallow, name); |
|
1154 |
in case validate name' |
|
1155 |
of NONE => name' |
|
1156 |
| _ => mk (postprocess, validate) ((shallow, name), 1) |
|
1157 |
end |
|
1158 |
| mk (postprocess, validate) (("", name), i) =
|
|
| 19150 | 1159 |
postprocess ("", name ^ replicate_string i "'")
|
1160 |
|> perhaps validate |
|
1161 |
| mk (postprocess, validate) ((shallow, name), 1) = |
|
1162 |
postprocess (shallow, shallow ^ "_" ^ name) |
|
| 18885 | 1163 |
|> perhaps validate |
| 18963 | 1164 |
| mk (postprocess, validate) ((shallow, name), i) = |
| 19150 | 1165 |
postprocess (shallow, name ^ replicate_string i "'") |
| 18516 | 1166 |
|> perhaps validate; |
1167 |
fun is_valid _ _ = true; |
|
1168 |
fun maybe_unique _ _ = NONE; |
|
| 20389 | 1169 |
fun re_mangle _ dst = error ("No such definition name: " ^ quote dst);
|
| 18516 | 1170 |
); |
1171 |
||
| 18963 | 1172 |
fun mk_deresolver module nsp_conn postprocess validate = |
| 18885 | 1173 |
let |
1174 |
datatype tabnode = N of string * tabnode Symtab.table option; |
|
1175 |
fun mk module manglers tab = |
|
1176 |
let |
|
1177 |
fun mk_name name = |
|
1178 |
case NameSpace.unpack name |
|
1179 |
of [n] => ("", n)
|
|
1180 |
| [s, n] => (s, n); |
|
1181 |
fun in_conn (shallow, conn) = |
|
1182 |
member (op = : string * string -> bool) conn shallow; |
|
1183 |
fun add_name name = |
|
1184 |
let |
|
1185 |
val n as (shallow, _) = mk_name name; |
|
1186 |
in |
|
1187 |
AList.map_entry_yield in_conn shallow ( |
|
| 18963 | 1188 |
NameMangler.declare (postprocess, validate) n |
| 18885 | 1189 |
#-> (fn n' => pair (name, n')) |
| 18963 | 1190 |
) #> apfst the |
| 18885 | 1191 |
end; |
1192 |
val (renamings, manglers') = |
|
1193 |
fold_map add_name (Graph.keys module) manglers; |
|
1194 |
fun extend_tab (n, n') = |
|
1195 |
if (length o NameSpace.unpack) n = 1 |
|
1196 |
then |
|
1197 |
Symtab.update_new |
|
1198 |
(n, N (n', SOME (mk ((dest_modl o Graph.get_node module) n) manglers' Symtab.empty))) |
|
1199 |
else |
|
1200 |
Symtab.update_new (n, N (n', NONE)); |
|
1201 |
in fold extend_tab renamings tab end; |
|
1202 |
fun get_path_name [] tab = |
|
1203 |
([], SOME tab) |
|
1204 |
| get_path_name [p] tab = |
|
1205 |
let |
|
1206 |
val SOME (N (p', tab')) = Symtab.lookup tab p |
|
1207 |
in ([p'], tab') end |
|
1208 |
| get_path_name [p1, p2] tab = |
|
| 18919 | 1209 |
(case Symtab.lookup tab p1 |
| 20191 | 1210 |
of SOME (N (p', SOME tab')) => |
| 18885 | 1211 |
let |
1212 |
val (ps', tab'') = get_path_name [p2] tab' |
|
1213 |
in (p' :: ps', tab'') end |
|
1214 |
| NONE => |
|
1215 |
let |
|
1216 |
val SOME (N (p', NONE)) = Symtab.lookup tab (NameSpace.pack [p1, p2]) |
|
| 18919 | 1217 |
in ([p'], NONE) end) |
| 18885 | 1218 |
| get_path_name (p::ps) tab = |
1219 |
let |
|
1220 |
val SOME (N (p', SOME tab')) = Symtab.lookup tab p |
|
1221 |
val (ps', tab'') = get_path_name ps tab' |
|
1222 |
in (p' :: ps', tab'') end; |
|
1223 |
fun deresolv tab prefix name = |
|
|
19341
3414c04fbc39
added definitional code generator module: codegen_theorems.ML
haftmann
parents:
19300
diff
changeset
|
1224 |
let |
| 20105 | 1225 |
val (common, (_, rem)) = chop_prefix (op =) (prefix, NameSpace.unpack name); |
| 18885 | 1226 |
val (_, SOME tab') = get_path_name common tab; |
1227 |
val (name', _) = get_path_name rem tab'; |
|
| 20428 | 1228 |
in NameSpace.pack name' end handle BIND => (error ("Missing name: " ^ quote name ^ ", in " ^ quote (NameSpace.pack prefix)));
|
| 18885 | 1229 |
in deresolv (mk module (AList.make (K NameMangler.empty) nsp_conn) Symtab.empty) end; |
1230 |
||
| 18216 | 1231 |
|
1232 |
(* serialization *) |
|
1233 |
||
| 18963 | 1234 |
fun serialize seri_defs seri_module validate postprocess nsp_conn name_root module = |
| 18216 | 1235 |
let |
| 19884 | 1236 |
val imptab = allimports_of module; |
| 18963 | 1237 |
val resolver = mk_deresolver module nsp_conn postprocess validate; |
| 19038 | 1238 |
fun sresolver s = (resolver o NameSpace.unpack) s |
| 18702 | 1239 |
fun mk_name prfx name = |
| 18850 | 1240 |
let |
1241 |
val name_qual = NameSpace.pack (prfx @ [name]) |
|
1242 |
in (name_qual, resolver prfx name_qual) end; |
|
| 20191 | 1243 |
fun is_bot (_, (Def Bot)) = true |
1244 |
| is_bot _ = false; |
|
| 18756 | 1245 |
fun mk_contents prfx module = |
|
19482
9f11af8f7ef9
tuned basic list operators (flat, maps, map_filter);
wenzelm
parents:
19466
diff
changeset
|
1246 |
map_filter (seri prfx) |
| 18850 | 1247 |
((map (AList.make (Graph.get_node module)) o rev o Graph.strong_conn) module) |
|
19816
a8c8ed1c85e0
removed 'primitive definitions' added (non)strict generation, minor fixes
haftmann
parents:
19785
diff
changeset
|
1248 |
and seri prfx [(name, Module modl)] = |
| 19884 | 1249 |
seri_module (resolver []) (map (resolver []) ((the o Symtab.lookup imptab) (NameSpace.pack (prfx @ [name])))) |
| 18850 | 1250 |
(mk_name prfx name, mk_contents (prfx @ [name]) modl) |
| 18756 | 1251 |
| seri prfx ds = |
| 20191 | 1252 |
case filter_out is_bot ds |
1253 |
of [] => NONE |
|
1254 |
| ds' => seri_defs sresolver (NameSpace.pack prfx) |
|
1255 |
(map (fn (name, Def def) => (fst (mk_name prfx name), def (*|> tap (Pretty.writeln o pretty_def)*))) ds') |
|
| 18216 | 1256 |
in |
| 19937 | 1257 |
seri_module (resolver []) (map (resolver []) ((the o Symtab.lookup imptab) "")) |
| 18850 | 1258 |
(("", name_root), (mk_contents [] module))
|
| 18216 | 1259 |
end; |
1260 |
||
|
18169
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
1261 |
end; (* struct *) |
| 19136 | 1262 |
|
| 19300 | 1263 |
structure BasicCodegenThingol: BASIC_CODEGEN_THINGOL = CodegenThingol; |