| author | wenzelm |
| Wed, 11 Oct 2006 22:59:36 +0200 | |
| changeset 20988 | 0887d0dd3210 |
| parent 20976 | e324808e9f1f |
| child 21012 | f08574148b7a |
| 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 |
|
| 20855 | 5 |
Intermediate language ("Thin-gol") representing extracted code.
|
|
18169
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))*) |
|
| 20896 | 37 |
val `--> : itype list * itype -> itype; |
38 |
val `$$ : iterm * iterm list -> iterm; |
|
39 |
val `|--> : (vname * itype) list * iterm -> iterm; |
|
40 |
type typscheme = (vname * sort) list * itype; |
|
| 19136 | 41 |
end; |
42 |
||
43 |
signature CODEGEN_THINGOL = |
|
44 |
sig |
|
45 |
include BASIC_CODEGEN_THINGOL; |
|
| 18216 | 46 |
val unfoldl: ('a -> ('a * 'b) option) -> 'a -> 'a * 'b list;
|
47 |
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
|
48 |
val unfold_fun: itype -> itype list * itype; |
| 20105 | 49 |
val unfold_app: iterm -> iterm * iterm list; |
50 |
val unfold_abs: iterm -> (iterm * itype) list * iterm; |
|
51 |
val unfold_let: iterm -> ((iterm * itype) * iterm) list * iterm; |
|
52 |
val unfold_const_app: iterm -> |
|
| 20456 | 53 |
((string * (inst list list * itype)) * iterm list) option; |
| 20105 | 54 |
val map_pure: (iterm -> 'a) -> iterm -> 'a; |
| 20456 | 55 |
val eta_expand: (string * (inst list list * itype)) * iterm list -> int -> iterm; |
| 20896 | 56 |
val fold_constnames: (string -> 'a -> 'a) -> iterm -> 'a -> 'a; |
57 |
val fold_varnames: (string -> 'a -> 'a) -> iterm -> 'a -> 'a; |
|
58 |
val fold_unbound_varnames: (string -> 'a -> 'a) -> iterm -> 'a -> 'a; |
|
| 18170 | 59 |
|
60 |
datatype def = |
|
|
19816
a8c8ed1c85e0
removed 'primitive definitions' added (non)strict generation, minor fixes
haftmann
parents:
19785
diff
changeset
|
61 |
Bot |
| 20456 | 62 |
| Fun of (iterm list * iterm) list * typscheme |
63 |
| Datatype of (vname * sort) list * (string * itype list) list |
|
|
18380
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
64 |
| Datatypecons of string |
| 20456 | 65 |
| Class of class list * (vname * (string * itype) list) |
|
18380
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
66 |
| Classmember of class |
| 20389 | 67 |
| Classinst of (class * (string * (vname * sort) list)) |
| 20466 | 68 |
* ((class * (string * inst list list)) list |
| 20389 | 69 |
* (string * iterm) list); |
| 20896 | 70 |
type code = def Graph.T; |
| 18170 | 71 |
type transact; |
| 20896 | 72 |
val empty_code: code; |
73 |
val get_def: code -> string -> def; |
|
74 |
val merge_code: code * code -> code; |
|
75 |
val project_code: string list -> code -> code; |
|
76 |
val add_eval_def: string (*shallow name space*) * iterm -> code -> string * code; |
|
77 |
val delete_garbage: string list (*hidden definitions*) -> code -> code; |
|
78 |
||
79 |
val ensure_def: (transact -> def * code) -> bool -> string |
|
| 19884 | 80 |
-> string -> transact -> transact; |
| 20896 | 81 |
val succeed: 'a -> transact -> 'a * code; |
82 |
val fail: string -> transact -> 'a * code; |
|
| 19884 | 83 |
val message: string -> (transact -> 'a) -> transact -> 'a; |
| 20896 | 84 |
val start_transact: string option -> (transact -> 'a * transact) -> code -> 'a * code; |
| 18216 | 85 |
|
| 20835 | 86 |
val trace: bool ref; |
87 |
val tracing: ('a -> string) -> 'a -> 'a;
|
|
| 18231 | 88 |
val soft_exc: bool ref; |
|
18169
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
89 |
end; |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
90 |
|
| 18850 | 91 |
structure CodegenThingol: CODEGEN_THINGOL = |
|
18169
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
92 |
struct |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
93 |
|
| 18170 | 94 |
(** auxiliary **) |
|
18169
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
95 |
|
| 20835 | 96 |
val trace = ref false; |
97 |
fun tracing f x = (if !trace then Output.tracing (f x) else (); x); |
|
| 18231 | 98 |
val soft_exc = ref true; |
|
18169
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
99 |
|
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
100 |
fun unfoldl dest x = |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
101 |
case dest x |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
102 |
of NONE => (x, []) |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
103 |
| SOME (x1, x2) => |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
104 |
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
|
105 |
|
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
106 |
fun unfoldr dest x = |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
107 |
case dest x |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
108 |
of NONE => ([], x) |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
109 |
| SOME (x1, x2) => |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
110 |
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
|
111 |
|
| 18170 | 112 |
|
113 |
||
114 |
(** language core - types, pattern, expressions **) |
|
|
18169
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
115 |
|
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
116 |
(* language representation *) |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
117 |
|
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
118 |
type vname = string; |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
119 |
|
| 20456 | 120 |
datatype inst = |
121 |
Instance of string * inst list list |
|
122 |
| Context of class list * (vname * int); |
|
| 18885 | 123 |
|
|
18169
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
124 |
datatype itype = |
|
19167
f237c0cb3882
refined representation of codegen intermediate language
haftmann
parents:
19150
diff
changeset
|
125 |
`%% of string * itype list |
|
f237c0cb3882
refined representation of codegen intermediate language
haftmann
parents:
19150
diff
changeset
|
126 |
| `-> of itype * itype |
|
f237c0cb3882
refined representation of codegen intermediate language
haftmann
parents:
19150
diff
changeset
|
127 |
| ITyVar of vname; |
|
18169
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
128 |
|
| 20105 | 129 |
datatype iterm = |
| 20456 | 130 |
IConst of string * (inst list list * itype) |
|
19167
f237c0cb3882
refined representation of codegen intermediate language
haftmann
parents:
19150
diff
changeset
|
131 |
| IVar of vname |
| 20105 | 132 |
| `$ of iterm * iterm |
133 |
| `|-> of (vname * itype) * iterm |
|
134 |
| INum of IntInf.int * iterm |
|
135 |
| IChar of string * iterm |
|
136 |
| ICase of ((iterm * itype) * (iterm * iterm) list) * iterm; |
|
|
19167
f237c0cb3882
refined representation of codegen intermediate language
haftmann
parents:
19150
diff
changeset
|
137 |
(*see also signature*) |
|
18169
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
138 |
|
|
18380
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
139 |
(* |
|
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
140 |
variable naming conventions |
|
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
141 |
|
|
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
142 |
bare names: |
|
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
143 |
variable names v |
| 20439 | 144 |
class names class |
|
18380
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
145 |
type constructor names tyco |
|
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
146 |
datatype names dtco |
|
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
147 |
const names (general) c |
|
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
148 |
constructor names co |
| 20439 | 149 |
class operation names clsop (op) |
|
18380
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
150 |
arbitrary name s |
|
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
151 |
|
| 20896 | 152 |
v, c, co, clsop also annotated with types etc. |
| 20439 | 153 |
|
|
18380
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
154 |
constructs: |
|
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
155 |
sort sort |
| 20456 | 156 |
type parameters vs |
|
18380
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
157 |
type ty |
| 20456 | 158 |
type schemes tysm |
| 20439 | 159 |
term t |
160 |
(term as pattern) p |
|
161 |
instance (classs, tyco) inst |
|
|
18380
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
162 |
*) |
|
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
163 |
|
|
19167
f237c0cb3882
refined representation of codegen intermediate language
haftmann
parents:
19150
diff
changeset
|
164 |
val op `--> = Library.foldr (op `->); |
|
f237c0cb3882
refined representation of codegen intermediate language
haftmann
parents:
19150
diff
changeset
|
165 |
val op `$$ = Library.foldl (op `$); |
|
f237c0cb3882
refined representation of codegen intermediate language
haftmann
parents:
19150
diff
changeset
|
166 |
val op `|--> = Library.foldr (op `|->); |
|
18169
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
167 |
|
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
168 |
val unfold_fun = unfoldr |
| 20439 | 169 |
(fn op `-> ty => SOME ty |
|
18169
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
170 |
| _ => NONE); |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
171 |
|
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
172 |
val unfold_app = unfoldl |
| 20439 | 173 |
(fn op `$ t => SOME t |
|
18169
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
174 |
| _ => NONE); |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
175 |
|
| 18282 | 176 |
val unfold_abs = unfoldr |
| 20976 | 177 |
(fn (v, ty) `|-> (t as ICase (((IVar w, _), [(p, t')]), _)) => |
178 |
if v = w then SOME ((p, ty), t') else SOME ((IVar v, ty), t) |
|
| 20439 | 179 |
| (v, ty) `|-> t => SOME ((IVar v, ty), t) |
| 18282 | 180 |
| _ => NONE) |
181 |
||
|
18169
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
182 |
val unfold_let = unfoldr |
| 20439 | 183 |
(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
|
184 |
| _ => NONE); |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
185 |
|
| 20439 | 186 |
fun unfold_const_app t = |
187 |
case unfold_app t |
|
188 |
of (IConst c, ts) => SOME (c, ts) |
|
| 18865 | 189 |
| _ => NONE; |
190 |
||
| 20439 | 191 |
fun map_pure f (t as IConst _) = |
192 |
f t |
|
193 |
| map_pure f (t as IVar _) = |
|
194 |
f t |
|
195 |
| map_pure f (t as _ `$ _) = |
|
196 |
f t |
|
197 |
| map_pure f (t as _ `|-> _) = |
|
198 |
f t |
|
199 |
| map_pure f (INum (_, t0)) = |
|
200 |
f t0 |
|
201 |
| map_pure f (IChar (_, t0)) = |
|
202 |
f t0 |
|
203 |
| map_pure f (ICase (_, t0)) = |
|
204 |
f t0; |
|
| 18912 | 205 |
|
| 20896 | 206 |
fun fold_aiterms f (t as IConst _) = |
207 |
f t |
|
208 |
| fold_aiterms f (t as IVar _) = |
|
209 |
f t |
|
210 |
| fold_aiterms f (t1 `$ t2) = |
|
211 |
fold_aiterms f t1 #> fold_aiterms f t2 |
|
212 |
| fold_aiterms f (t as _ `|-> t') = |
|
213 |
f t #> fold_aiterms f t' |
|
214 |
| fold_aiterms f (INum (_, t0)) = |
|
215 |
fold_aiterms f t0 |
|
216 |
| fold_aiterms f (IChar (_, t0)) = |
|
217 |
fold_aiterms f t0 |
|
218 |
| fold_aiterms f (ICase (_, t0)) = |
|
219 |
fold_aiterms f t0; |
|
| 19202 | 220 |
|
| 20896 | 221 |
fun fold_constnames f = |
222 |
let |
|
223 |
fun add (IConst (c, _)) = f c |
|
224 |
| add _ = I; |
|
225 |
in fold_aiterms add end; |
|
| 18885 | 226 |
|
| 20896 | 227 |
fun fold_varnames f = |
228 |
let |
|
229 |
fun add (IVar v) = f v |
|
230 |
| add ((v, _) `|-> _) = f v |
|
231 |
| add _ = I; |
|
232 |
in fold_aiterms add end; |
|
| 20709 | 233 |
|
| 20896 | 234 |
fun fold_unbound_varnames f = |
| 18885 | 235 |
let |
| 20896 | 236 |
fun add _ (IConst _) = |
237 |
I |
|
238 |
| add vs (IVar v) = |
|
239 |
if not (member (op =) vs v) then f v else I |
|
240 |
| add vs (t1 `$ t2) = |
|
241 |
add vs t1 #> add vs t2 |
|
242 |
| add vs ((v, _) `|-> t) = |
|
243 |
add (insert (op =) v vs) t |
|
244 |
| add vs (INum (_, t)) = |
|
245 |
add vs t |
|
246 |
| add vs (IChar (_, t)) = |
|
247 |
add vs t |
|
248 |
| add vs (ICase (_, t0)) = |
|
249 |
add vs t0 |
|
250 |
in add [] end; |
|
| 20105 | 251 |
|
| 20439 | 252 |
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
|
253 |
let |
| 20439 | 254 |
val j = length ts; |
|
19607
07eeb832f28d
introduced characters for code generator; some improved code lemmas for some list functions
haftmann
parents:
19597
diff
changeset
|
255 |
val l = k - j; |
|
07eeb832f28d
introduced characters for code generator; some improved code lemmas for some list functions
haftmann
parents:
19597
diff
changeset
|
256 |
val tys = (curry Library.take l o curry Library.drop j o fst o unfold_fun) ty; |
| 20896 | 257 |
val ctxt = (fold o fold_varnames) Name.declare ts Name.context; |
258 |
val vs_tys = Name.names ctxt "a" tys; |
|
| 20439 | 259 |
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
|
260 |
|
| 18304 | 261 |
|
| 20896 | 262 |
(** definitions, transactions **) |
| 18170 | 263 |
|
264 |
(* type definitions *) |
|
265 |
||
| 20456 | 266 |
type typscheme = (vname * sort) list * itype; |
| 18170 | 267 |
datatype def = |
|
19816
a8c8ed1c85e0
removed 'primitive definitions' added (non)strict generation, minor fixes
haftmann
parents:
19785
diff
changeset
|
268 |
Bot |
| 20456 | 269 |
| Fun of (iterm list * iterm) list * typscheme |
270 |
| Datatype of (vname * sort) list * (string * itype list) list |
|
|
18380
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
271 |
| Datatypecons of string |
| 20456 | 272 |
| Class of class list * (vname * (string * itype) list) |
|
18380
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
273 |
| Classmember of class |
| 20389 | 274 |
| Classinst of (class * (string * (vname * sort) list)) |
| 20466 | 275 |
* ((class * (string * inst list list)) list |
| 20456 | 276 |
* (string * iterm) list); |
| 19597 | 277 |
val eq_def = (op =) : def * def -> bool; |
| 18170 | 278 |
|
| 20896 | 279 |
type code = def Graph.T; |
280 |
type transact = Graph.key option * code; |
|
281 |
exception FAIL of string list * exn option; |
|
| 18360 | 282 |
|
| 18170 | 283 |
|
| 20896 | 284 |
(* abstract code *) |
| 18170 | 285 |
|
| 20896 | 286 |
val empty_code = Graph.empty : code; (*read: "depends on"*) |
| 18170 | 287 |
|
| 20896 | 288 |
val get_def = Graph.get_node; |
| 18170 | 289 |
|
| 20896 | 290 |
fun ensure_bot name = Graph.default_node (name, Bot); |
|
19816
a8c8ed1c85e0
removed 'primitive definitions' added (non)strict generation, minor fixes
haftmann
parents:
19785
diff
changeset
|
291 |
|
| 20896 | 292 |
fun add_def_incr strict (name, Bot) code = |
293 |
(case the_default Bot (try (get_def code) name) |
|
294 |
of Bot => if strict then error "Attempted to add Bot to code" |
|
295 |
else Graph.map_node name (K Bot) code |
|
296 |
| _ => code) |
|
297 |
| add_def_incr _ (name, def) code = |
|
298 |
(case try (get_def code) name |
|
299 |
of NONE => Graph.new_node (name, def) code |
|
300 |
| SOME Bot => Graph.map_node name (K def) code |
|
|
19816
a8c8ed1c85e0
removed 'primitive definitions' added (non)strict generation, minor fixes
haftmann
parents:
19785
diff
changeset
|
301 |
| SOME def' => if eq_def (def, def') |
| 20896 | 302 |
then code |
| 20389 | 303 |
else error ("Tried to overwrite definition " ^ quote name));
|
|
19816
a8c8ed1c85e0
removed 'primitive definitions' added (non)strict generation, minor fixes
haftmann
parents:
19785
diff
changeset
|
304 |
|
| 20896 | 305 |
fun add_dep (dep as (name1, name2)) = |
306 |
if name1 = name2 then I else Graph.add_edge dep; |
|
| 18170 | 307 |
|
| 20896 | 308 |
val merge_code = Graph.join (fn _ => fn def12 => if eq_def def12 then fst def12 else Bot); |
| 18170 | 309 |
|
| 20896 | 310 |
fun project_code names code = |
311 |
Graph.project (member (op =) (Graph.all_succs code names)) code; |
|
| 20428 | 312 |
|
| 20896 | 313 |
fun delete_garbage hidden code = |
| 20466 | 314 |
let |
| 20896 | 315 |
fun is_bot name = case get_def code name |
316 |
of Bot => true |
|
317 |
| _ => false; |
|
318 |
val names = subtract (op =) hidden (Graph.keys code); |
|
319 |
val names' = subtract (op =) |
|
320 |
(Graph.all_preds code (filter is_bot names)) names; |
|
| 20191 | 321 |
in |
| 20896 | 322 |
Graph.project (member (op =) names') code |
| 20191 | 323 |
end; |
324 |
||
| 18702 | 325 |
fun check_samemodule names = |
326 |
fold (fn name => |
|
327 |
let |
|
| 20896 | 328 |
val module_name = (NameSpace.qualifier o NameSpace.qualifier) name |
| 18702 | 329 |
in |
| 20896 | 330 |
fn NONE => SOME module_name |
331 |
| SOME module_name' => if module_name = module_name' then SOME module_name |
|
| 20386 | 332 |
else error ("Inconsistent name prefix for simultanous names: " ^ commas_quote names)
|
| 18702 | 333 |
end |
334 |
) names NONE; |
|
335 |
||
336 |
fun check_funeqs eqs = |
|
337 |
(fold (fn (pats, _) => |
|
338 |
let |
|
339 |
val l = length pats |
|
340 |
in |
|
341 |
fn NONE => SOME l |
|
| 18850 | 342 |
| SOME l' => if l = l' then SOME l |
| 20389 | 343 |
else error "Function definition with different number of arguments" |
| 18702 | 344 |
end |
345 |
) eqs NONE; eqs); |
|
346 |
||
|
19816
a8c8ed1c85e0
removed 'primitive definitions' added (non)strict generation, minor fixes
haftmann
parents:
19785
diff
changeset
|
347 |
fun check_prep_def modl Bot = |
|
a8c8ed1c85e0
removed 'primitive definitions' added (non)strict generation, minor fixes
haftmann
parents:
19785
diff
changeset
|
348 |
Bot |
| 18702 | 349 |
| check_prep_def modl (Fun (eqs, d)) = |
350 |
Fun (check_funeqs eqs, d) |
|
| 19038 | 351 |
| check_prep_def modl (d as Datatype _) = |
352 |
d |
|
| 18702 | 353 |
| check_prep_def modl (Datatypecons dtco) = |
| 20389 | 354 |
error "Attempted to add bare datatype constructor" |
| 19038 | 355 |
| check_prep_def modl (d as Class _) = |
356 |
d |
|
| 18702 | 357 |
| check_prep_def modl (Classmember _) = |
| 20389 | 358 |
error "Attempted to add bare class member" |
359 |
| check_prep_def modl (d as Classinst ((class, (tyco, arity)), (_, memdefs))) = |
|
| 18170 | 360 |
let |
| 19038 | 361 |
val Class (_, (v, membrs)) = get_def modl class; |
| 18702 | 362 |
val _ = if length memdefs > length memdefs |
| 20389 | 363 |
then error "Too many member definitions given" |
| 18702 | 364 |
else (); |
| 20389 | 365 |
fun check_memdef (m, _) = |
366 |
if AList.defined (op =) memdefs m |
|
367 |
then () else error ("Missing definition for member " ^ quote m);
|
|
368 |
val _ = map check_memdef memdefs; |
|
369 |
in d end |
|
| 19213 | 370 |
| check_prep_def modl Classinstmember = |
| 20389 | 371 |
error "Attempted to add bare class instance member"; |
| 18170 | 372 |
|
| 19038 | 373 |
fun postprocess_def (name, Datatype (_, constrs)) = |
| 18702 | 374 |
(check_samemodule (name :: map fst constrs); |
375 |
fold (fn (co, _) => |
|
|
19816
a8c8ed1c85e0
removed 'primitive definitions' added (non)strict generation, minor fixes
haftmann
parents:
19785
diff
changeset
|
376 |
add_def_incr true (co, Datatypecons name) |
| 18702 | 377 |
#> add_dep (co, name) |
378 |
#> add_dep (name, co) |
|
379 |
) constrs |
|
380 |
) |
|
| 19038 | 381 |
| postprocess_def (name, Class (_, (_, membrs))) = |
| 18702 | 382 |
(check_samemodule (name :: map fst membrs); |
383 |
fold (fn (m, _) => |
|
|
19816
a8c8ed1c85e0
removed 'primitive definitions' added (non)strict generation, minor fixes
haftmann
parents:
19785
diff
changeset
|
384 |
add_def_incr true (m, Classmember name) |
| 18702 | 385 |
#> add_dep (m, name) |
386 |
#> add_dep (name, m) |
|
387 |
) membrs |
|
388 |
) |
|
389 |
| postprocess_def _ = |
|
390 |
I; |
|
|
18380
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
391 |
|
| 19884 | 392 |
|
393 |
(* transaction protocol *) |
|
| 18170 | 394 |
|
|
19816
a8c8ed1c85e0
removed 'primitive definitions' added (non)strict generation, minor fixes
haftmann
parents:
19785
diff
changeset
|
395 |
fun ensure_def defgen strict msg name (dep, modl) = |
| 18170 | 396 |
let |
| 20389 | 397 |
(*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
|
398 |
val msg' = (case dep |
| 18702 | 399 |
of NONE => msg |
| 19884 | 400 |
| SOME dep => msg ^ ", required for " ^ quote dep) |
|
19816
a8c8ed1c85e0
removed 'primitive definitions' added (non)strict generation, minor fixes
haftmann
parents:
19785
diff
changeset
|
401 |
^ (if strict then " (strict)" else " (non-strict)"); |
| 18702 | 402 |
fun add_dp NONE = I |
403 |
| add_dp (SOME dep) = |
|
| 20835 | 404 |
tracing (fn _ => "adding dependency " ^ quote dep ^ " -> " ^ quote name) |
| 18702 | 405 |
#> add_dep (dep, name); |
406 |
fun prep_def def modl = |
|
407 |
(check_prep_def modl def, modl); |
|
|
19816
a8c8ed1c85e0
removed 'primitive definitions' added (non)strict generation, minor fixes
haftmann
parents:
19785
diff
changeset
|
408 |
fun invoke_generator name defgen modl = |
| 20191 | 409 |
if ! soft_exc (*that "!" isn't a "not"...*) |
| 20896 | 410 |
then defgen (SOME name, modl) |
| 19956 | 411 |
handle FAIL (msgs, exc) => |
412 |
if strict then raise FAIL (msg' :: msgs, exc) |
|
413 |
else (Bot, modl) |
|
| 20191 | 414 |
| e => raise |
| 19956 | 415 |
FAIL (["definition generator for " ^ quote name, msg'], SOME e) |
| 20896 | 416 |
else defgen (SOME name, modl) |
| 19956 | 417 |
handle FAIL (msgs, exc) => |
| 19884 | 418 |
if strict then raise FAIL (msg' :: msgs, exc) |
| 19956 | 419 |
else (Bot, modl); |
| 18170 | 420 |
in |
421 |
modl |
|
| 18702 | 422 |
|> (if can (get_def modl) name |
423 |
then |
|
| 20835 | 424 |
tracing (fn _ => "asserting node " ^ quote name) |
| 18702 | 425 |
#> add_dp dep |
426 |
else |
|
| 20835 | 427 |
tracing (fn _ => "allocating node " ^ quote name ^ (if strict then " (strict)" else " (non-strict)")) |
|
19816
a8c8ed1c85e0
removed 'primitive definitions' added (non)strict generation, minor fixes
haftmann
parents:
19785
diff
changeset
|
428 |
#> ensure_bot name |
| 18702 | 429 |
#> add_dp dep |
| 20835 | 430 |
#> tracing (fn _ => "creating node " ^ quote name) |
|
19816
a8c8ed1c85e0
removed 'primitive definitions' added (non)strict generation, minor fixes
haftmann
parents:
19785
diff
changeset
|
431 |
#> invoke_generator name defgen |
| 18702 | 432 |
#-> (fn def => prep_def def) |
433 |
#-> (fn def => |
|
| 20896 | 434 |
tracing (fn _ => "adding") |
|
19816
a8c8ed1c85e0
removed 'primitive definitions' added (non)strict generation, minor fixes
haftmann
parents:
19785
diff
changeset
|
435 |
#> add_def_incr strict (name, def) |
| 20835 | 436 |
#> tracing (fn _ => "postprocessing") |
| 18702 | 437 |
#> postprocess_def (name, def) |
| 20835 | 438 |
#> tracing (fn _ => "adding done") |
| 18702 | 439 |
)) |
440 |
|> pair dep |
|
| 18170 | 441 |
end; |
442 |
||
| 19884 | 443 |
fun succeed some (_, modl) = (some, modl); |
444 |
||
445 |
fun fail msg (_, modl) = raise FAIL ([msg], NONE); |
|
446 |
||
447 |
fun message msg f trns = |
|
448 |
f trns handle FAIL (msgs, exc) => |
|
449 |
raise FAIL (msg :: msgs, exc); |
|
450 |
||
| 18963 | 451 |
fun start_transact init f modl = |
| 18231 | 452 |
let |
| 18963 | 453 |
fun handle_fail f x = |
454 |
(f x |
|
| 18231 | 455 |
handle FAIL (msgs, NONE) => |
| 20389 | 456 |
(error o cat_lines) ("Code generation failed, while:" :: msgs))
|
| 18231 | 457 |
handle FAIL (msgs, SOME e) => |
| 20389 | 458 |
((Output.error_msg o cat_lines) ("Code generation failed, while:" :: msgs); raise e);
|
| 18231 | 459 |
in |
| 19884 | 460 |
modl |
461 |
|> (if is_some init then ensure_bot (the init) else I) |
|
462 |
|> pair init |
|
| 18231 | 463 |
|> handle_fail f |
| 19884 | 464 |
|-> (fn x => fn (_, modl) => (x, modl)) |
| 18231 | 465 |
end; |
| 18172 | 466 |
|
| 20896 | 467 |
fun add_eval_def (shallow, e) code = |
| 20191 | 468 |
let |
| 20216 | 469 |
val name = "VALUE"; |
470 |
val sname = NameSpace.pack [shallow, name]; |
|
| 20191 | 471 |
in |
| 20896 | 472 |
code |
473 |
|> Graph.new_node (sname, Fun ([([], e)], ([("_", [])], ITyVar "_")))
|
|
474 |
|> fold (curry Graph.add_edge sname) (Graph.keys code) (*FIXME*) |
|
| 20191 | 475 |
|> pair name |
476 |
end; |
|
| 18172 | 477 |
|
| 20896 | 478 |
end; (*struct*) |
| 18885 | 479 |
|
| 18216 | 480 |
|
| 19300 | 481 |
structure BasicCodegenThingol: BASIC_CODEGEN_THINGOL = CodegenThingol; |