author | haftmann |
Wed, 21 Dec 2005 15:19:16 +0100 | |
changeset 18454 | 6720b5010a57 |
parent 18441 | 7488d8ea61bc |
child 18515 | 1cad5c2b2a0b |
permissions | -rw-r--r-- |
18380
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
1 |
(* Title: Pure/Tools/codegen_thingol.ML |
18169
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
2 |
ID: $Id$ |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
3 |
Author: Florian Haftmann, TU Muenchen |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
4 |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
5 |
Intermediate language ("Thin-gol") for code extraction. |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
6 |
*) |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
7 |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
8 |
signature CODEGEN_THINGOL = |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
9 |
sig |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
10 |
type vname = string; |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
11 |
datatype itype = |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
12 |
IType of string * itype list |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
13 |
| IFun of itype * itype |
18172 | 14 |
| IVarT of vname * sort |
15 |
| IDictT of (string * itype) list; |
|
18169
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
16 |
datatype ipat = |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
17 |
ICons of (string * ipat list) * itype |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
18 |
| IVarP of vname * itype; |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
19 |
datatype iexpr = |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
20 |
IConst of string * itype |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
21 |
| IVarE of vname * itype |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
22 |
| IApp of iexpr * iexpr |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
23 |
| IInst of iexpr * ClassPackage.sortlookup list list |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
24 |
| IAbs of (vname * itype) * iexpr |
18172 | 25 |
| ICase of iexpr * (ipat * iexpr) list |
26 |
| IDictE of (string * iexpr) list |
|
27 |
| ILookup of (string list * vname); |
|
18169
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
28 |
val mk_funs: itype list * itype -> itype; |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
29 |
val mk_apps: iexpr * iexpr list -> iexpr; |
18247
b17724cae935
code generator: case expressions, improved name resolving
haftmann
parents:
18231
diff
changeset
|
30 |
val mk_abss: (vname * itype) list * iexpr -> iexpr; |
18169
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
31 |
val pretty_itype: itype -> Pretty.T; |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
32 |
val pretty_ipat: ipat -> Pretty.T; |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
33 |
val pretty_iexpr: iexpr -> Pretty.T; |
18216 | 34 |
val unfoldl: ('a -> ('a * 'b) option) -> 'a -> 'a * 'b list; |
35 |
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
|
36 |
val unfold_fun: itype -> itype list * itype; |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
37 |
val unfold_app: iexpr -> iexpr * iexpr list; |
18282 | 38 |
val unfold_abs: iexpr -> (vname * itype) list * iexpr; |
18169
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
39 |
val unfold_let: iexpr -> (ipat * iexpr) list * iexpr; |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
40 |
val itype_of_iexpr: iexpr -> itype; |
18385 | 41 |
val itype_of_ipat: ipat -> itype; |
18169
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
42 |
val ipat_of_iexpr: iexpr -> ipat; |
18282 | 43 |
val eq_itype: itype * itype -> bool; |
18304 | 44 |
val tvars_of_itypes: itype list -> string list; |
45 |
val vars_of_ipats: ipat list -> string list; |
|
46 |
val vars_of_iexprs: iexpr list -> string list; |
|
18170 | 47 |
|
48 |
datatype def = |
|
49 |
Nop |
|
50 |
| Fun of (ipat list * iexpr) list * (ClassPackage.sortcontext * itype) |
|
18172 | 51 |
| Typesyn of (vname * string list) list * itype |
18380
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
52 |
| Datatype of (vname * string list) list * (string * itype list) list * string list |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
53 |
| Datatypecons of string |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
54 |
| Class of class list * vname * (string * (ClassPackage.sortcontext * itype)) list * string list |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
55 |
| Classmember of class |
18304 | 56 |
| Classinst of class * (string * (vname * string list) list) * (string * string) list; |
18170 | 57 |
type module; |
58 |
type transact; |
|
59 |
type 'dst transact_fin; |
|
18304 | 60 |
type ('src, 'dst) gen_exprgen = 'src -> transact -> 'dst transact_fin; |
18170 | 61 |
type gen_defgen = string -> transact -> (def * string list) transact_fin; |
62 |
val pretty_def: def -> Pretty.T; |
|
18282 | 63 |
val pretty_module: module -> Pretty.T; |
18360 | 64 |
val pretty_deps: module -> Pretty.T; |
18170 | 65 |
val empty_module: module; |
66 |
val get_def: module -> string -> def; |
|
67 |
val merge_module: module * module -> module; |
|
68 |
val partof: string list -> module -> module; |
|
69 |
val succeed: 'a -> transact -> 'a transact_fin; |
|
70 |
val fail: string -> transact -> 'a transact_fin; |
|
18304 | 71 |
val gen_invoke: (string * ('src, 'dst) gen_exprgen) list -> string |
18170 | 72 |
-> 'src -> transact -> 'dst * transact; |
73 |
val gen_ensure_def: (string * gen_defgen) list -> string |
|
74 |
-> string -> transact -> transact; |
|
18216 | 75 |
val start_transact: (transact -> 'a * transact) -> module -> 'a * module; |
76 |
||
77 |
val class_eq: string; |
|
78 |
val type_bool: string; |
|
79 |
val type_pair: string; |
|
80 |
val type_list: string; |
|
81 |
val type_integer: string; |
|
82 |
val cons_pair: string; |
|
18335 | 83 |
val fun_eq: string; |
18216 | 84 |
val fun_fst: string; |
85 |
val fun_snd: string; |
|
86 |
val Type_integer: itype; |
|
87 |
val Cons_true: iexpr; |
|
88 |
val Cons_false: iexpr; |
|
89 |
val Cons_pair: iexpr; |
|
90 |
val Cons_nil: iexpr; |
|
91 |
val Cons_cons: iexpr; |
|
92 |
val Fun_eq: iexpr; |
|
93 |
val Fun_not: iexpr; |
|
94 |
val Fun_and: iexpr; |
|
95 |
val Fun_or: iexpr; |
|
96 |
val Fun_if: iexpr; |
|
97 |
val Fun_fst: iexpr; |
|
98 |
val Fun_snd: iexpr; |
|
99 |
val Fun_0: iexpr; |
|
100 |
val Fun_1: iexpr; |
|
101 |
val Fun_add: iexpr; |
|
102 |
val Fun_mult: iexpr; |
|
103 |
val Fun_minus: iexpr; |
|
104 |
val Fun_lt: iexpr; |
|
105 |
val Fun_le: iexpr; |
|
106 |
val Fun_wfrec: iexpr; |
|
18170 | 107 |
|
18172 | 108 |
val prims: string list; |
18385 | 109 |
val invoke_eq: ('a -> transact -> itype * transact) |
110 |
-> (string * (def * (string * sort) list) -> transact -> transact) |
|
111 |
-> 'a -> transact -> bool * transact; |
|
18172 | 112 |
val extract_defs: iexpr -> string list; |
113 |
val eta_expand: (string -> int) -> module -> module; |
|
18216 | 114 |
val eta_expand_poly: module -> module; |
18172 | 115 |
val tupelize_cons: module -> module; |
116 |
val eliminate_classes: module -> module; |
|
117 |
||
18170 | 118 |
val debug_level : int ref; |
119 |
val debug : int -> ('a -> string) -> 'a -> 'a; |
|
18231 | 120 |
val soft_exc: bool ref; |
18216 | 121 |
|
122 |
val serialize: |
|
18380
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
123 |
((string -> string) -> (string * def) list -> Pretty.T option) |
18216 | 124 |
-> (string * Pretty.T list -> Pretty.T) |
125 |
-> (string -> string option) |
|
126 |
-> string list list -> string -> module -> Pretty.T |
|
18454 | 127 |
|
128 |
val get_prefix: ('a * 'a -> bool) -> 'a list * 'a list -> 'a list * ('a list * 'a list) |
|
18169
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
129 |
end; |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
130 |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
131 |
signature CODEGEN_THINGOL_OP = |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
132 |
sig |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
133 |
include CODEGEN_THINGOL; |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
134 |
val `%% : string * itype list -> itype; |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
135 |
val `-> : itype * itype -> itype; |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
136 |
val `--> : itype list * itype -> itype; |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
137 |
val `$ : iexpr * iexpr -> iexpr; |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
138 |
val `$$ : iexpr * iexpr list -> iexpr; |
18247
b17724cae935
code generator: case expressions, improved name resolving
haftmann
parents:
18231
diff
changeset
|
139 |
val `|-> : (vname * itype) * iexpr -> iexpr; |
b17724cae935
code generator: case expressions, improved name resolving
haftmann
parents:
18231
diff
changeset
|
140 |
val `|--> : (vname * itype) list * iexpr -> iexpr; |
18169
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
141 |
end; |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
142 |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
143 |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
144 |
structure CodegenThingolOp: CODEGEN_THINGOL_OP = |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
145 |
struct |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
146 |
|
18170 | 147 |
(** auxiliary **) |
18169
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
148 |
|
18170 | 149 |
val debug_level = ref 0; |
150 |
fun debug d f x = (if d <= !debug_level then Output.debug (f x) else (); x); |
|
18231 | 151 |
val soft_exc = ref true; |
18169
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
152 |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
153 |
fun unfoldl dest x = |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
154 |
case dest x |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
155 |
of NONE => (x, []) |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
156 |
| SOME (x1, x2) => |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
157 |
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
|
158 |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
159 |
fun unfoldr dest x = |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
160 |
case dest x |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
161 |
of NONE => ([], x) |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
162 |
| SOME (x1, x2) => |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
163 |
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
|
164 |
|
18172 | 165 |
fun map_yield f [] = ([], []) |
166 |
| map_yield f (x::xs) = |
|
167 |
let |
|
168 |
val (y, x') = f x |
|
169 |
val (ys, xs') = map_yield f xs |
|
170 |
in (y::ys, x'::xs') end; |
|
171 |
||
18454 | 172 |
fun get_prefix eq ([], ys) = ([], ([], ys)) |
173 |
| get_prefix eq (xs, []) = ([], (xs, [])) |
|
18170 | 174 |
| get_prefix eq (xs as x::xs', ys as y::ys') = |
175 |
if eq (x, y) then |
|
18454 | 176 |
let val (ps', xys'') = get_prefix eq (xs', ys') |
177 |
in (x::ps', xys'') end |
|
178 |
else ([], (xs, ys)); |
|
18170 | 179 |
|
180 |
||
181 |
(** language core - types, pattern, expressions **) |
|
18169
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
182 |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
183 |
(* language representation *) |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
184 |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
185 |
infix 8 `%%; |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
186 |
infixr 6 `->; |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
187 |
infixr 6 `-->; |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
188 |
infix 4 `$; |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
189 |
infix 4 `$$; |
18247
b17724cae935
code generator: case expressions, improved name resolving
haftmann
parents:
18231
diff
changeset
|
190 |
infixr 5 `|->; |
b17724cae935
code generator: case expressions, improved name resolving
haftmann
parents:
18231
diff
changeset
|
191 |
infixr 5 `|-->; |
18169
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
192 |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
193 |
type vname = string; |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
194 |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
195 |
datatype itype = |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
196 |
IType of string * itype list |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
197 |
| IFun of itype * itype |
18172 | 198 |
| IVarT of vname * sort |
199 |
(*ML auxiliary*) |
|
200 |
| IDictT of (string * itype) list; |
|
18169
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
201 |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
202 |
datatype ipat = |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
203 |
ICons of (string * ipat list) * itype |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
204 |
| IVarP of vname * itype; |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
205 |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
206 |
datatype iexpr = |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
207 |
IConst of string * itype |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
208 |
| IVarE of vname * itype |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
209 |
| IApp of iexpr * iexpr |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
210 |
| IInst of iexpr * ClassPackage.sortlookup list list |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
211 |
| IAbs of (vname * itype) * iexpr |
18172 | 212 |
| ICase of iexpr * (ipat * iexpr) list |
213 |
(*ML auxiliary*) |
|
214 |
| IDictE of (string * iexpr) list |
|
215 |
| ILookup of (string list * vname); |
|
18169
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
216 |
|
18380
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
217 |
(* |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
218 |
variable naming conventions |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
219 |
|
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
220 |
bare names: |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
221 |
variable names v |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
222 |
class names cls |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
223 |
type constructor names tyco |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
224 |
datatype names dtco |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
225 |
const names (general) c |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
226 |
constructor names co |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
227 |
class member names m |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
228 |
arbitrary name s |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
229 |
|
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
230 |
constructs: |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
231 |
sort sort |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
232 |
type ty |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
233 |
expression e |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
234 |
pattern p |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
235 |
instance (cls, tyco) inst |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
236 |
variable (v, ty) var |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
237 |
class member (m, ty) membr |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
238 |
constructors (co, tys) constr |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
239 |
*) |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
240 |
|
18169
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
241 |
val mk_funs = Library.foldr IFun; |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
242 |
val mk_apps = Library.foldl IApp; |
18247
b17724cae935
code generator: case expressions, improved name resolving
haftmann
parents:
18231
diff
changeset
|
243 |
val mk_abss = Library.foldr IAbs; |
18169
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
244 |
|
18247
b17724cae935
code generator: case expressions, improved name resolving
haftmann
parents:
18231
diff
changeset
|
245 |
val op `%% = IType; |
18169
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
246 |
val op `-> = IFun; |
18247
b17724cae935
code generator: case expressions, improved name resolving
haftmann
parents:
18231
diff
changeset
|
247 |
val op `$ = IApp; |
b17724cae935
code generator: case expressions, improved name resolving
haftmann
parents:
18231
diff
changeset
|
248 |
val op `|-> = IAbs; |
18169
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
249 |
val op `--> = mk_funs; |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
250 |
val op `$$ = mk_apps; |
18247
b17724cae935
code generator: case expressions, improved name resolving
haftmann
parents:
18231
diff
changeset
|
251 |
val op `|--> = mk_abss; |
18169
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
252 |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
253 |
val unfold_fun = unfoldr |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
254 |
(fn IFun t => SOME t |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
255 |
| _ => NONE); |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
256 |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
257 |
val unfold_app = unfoldl |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
258 |
(fn IApp e => SOME e |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
259 |
| _ => NONE); |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
260 |
|
18282 | 261 |
val unfold_abs = unfoldr |
262 |
(fn IAbs b => SOME b |
|
263 |
| _ => NONE) |
|
264 |
||
18169
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
265 |
val unfold_let = unfoldr |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
266 |
(fn ICase (e, [(p, e')]) => SOME ((p, e), e') |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
267 |
| _ => NONE); |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
268 |
|
18172 | 269 |
fun map_itype f_itype (IType (tyco, tys)) = |
270 |
tyco `%% map f_itype tys |
|
271 |
| map_itype f_itype (IFun (t1, t2)) = |
|
272 |
f_itype t1 `-> f_itype t2 |
|
273 |
| map_itype _ (ty as IVarT _) = |
|
274 |
ty; |
|
275 |
||
276 |
fun map_ipat f_itype f_ipat (ICons ((c, ps), ty)) = |
|
277 |
ICons ((c, map f_ipat ps), f_itype ty) |
|
278 |
| map_ipat _ _ (p as IVarP _) = |
|
279 |
p; |
|
280 |
||
281 |
fun map_iexpr f_itype f_ipat f_iexpr (IApp (e1, e2)) = |
|
282 |
f_iexpr e1 `$ f_iexpr e2 |
|
283 |
| map_iexpr f_itype f_ipat f_iexpr (IInst (e, c)) = |
|
284 |
IInst (f_iexpr e, c) |
|
285 |
| map_iexpr f_itype f_ipat f_iexpr (IAbs (v, e)) = |
|
286 |
IAbs (v, f_iexpr e) |
|
287 |
| map_iexpr f_itype f_ipat f_iexpr (ICase (e, ps)) = |
|
288 |
ICase (f_iexpr e, map (fn (p, e) => (f_ipat p, f_iexpr e)) ps) |
|
289 |
| map_iexpr _ _ _ (e as IConst _) = |
|
290 |
e |
|
291 |
| map_iexpr _ _ _ (e as IVarE _) = |
|
18282 | 292 |
e |
293 |
| map_iexpr f_itype f_ipat f_iexpr (IDictE ms) = |
|
294 |
IDictE (map (apsnd f_iexpr) ms) |
|
18380
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
295 |
| map_iexpr _ _ _ (e as ILookup _) = |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
296 |
e ; |
18172 | 297 |
|
298 |
fun fold_itype f_itype (IFun (t1, t2)) = |
|
299 |
f_itype t1 #> f_itype t2 |
|
300 |
| fold_itype _ (ty as IType _) = |
|
301 |
I |
|
302 |
| fold_itype _ (ty as IVarT _) = |
|
303 |
I; |
|
304 |
||
305 |
fun fold_ipat f_itype f_ipat (ICons ((_, ps), ty)) = |
|
306 |
f_itype ty #> fold f_ipat ps |
|
307 |
| fold_ipat f_itype f_ipat (p as IVarP _) = |
|
308 |
I; |
|
309 |
||
310 |
fun fold_iexpr f_itype f_ipat f_iexpr (IApp (e1, e2)) = |
|
311 |
f_iexpr e1 #> f_iexpr e2 |
|
312 |
| fold_iexpr f_itype f_ipat f_iexpr (IInst (e, c)) = |
|
313 |
f_iexpr e |
|
314 |
| fold_iexpr f_itype f_ipat f_iexpr (IAbs (v, e)) = |
|
315 |
f_iexpr e |
|
316 |
| fold_iexpr f_itype f_ipat f_iexpr (ICase (e, ps)) = |
|
18282 | 317 |
f_iexpr e #> fold (fn (p, e) => f_ipat p #> f_iexpr e) ps |
18172 | 318 |
| fold_iexpr _ _ _ (e as IConst _) = |
319 |
I |
|
320 |
| fold_iexpr _ _ _ (e as IVarE _) = |
|
321 |
I; |
|
322 |
||
18169
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
323 |
|
18282 | 324 |
(* simple type matching *) |
325 |
||
326 |
fun eq_itype (ty1, ty2) = |
|
327 |
let |
|
328 |
exception NO_MATCH; |
|
329 |
fun eq (IVarT (v1, sort1)) (IVarT (v2, sort2)) subs = |
|
330 |
if sort1 <> sort2 |
|
331 |
then raise NO_MATCH |
|
332 |
else |
|
333 |
(case AList.lookup (op =) subs v1 |
|
334 |
of NONE => subs |> AList.update (op =) (v1, v2) |
|
335 |
| (SOME v1') => |
|
336 |
if v1' <> v2 |
|
337 |
then raise NO_MATCH |
|
338 |
else subs) |
|
339 |
| eq (IType (tyco1, tys1)) (IType (tyco2, tys2)) subs = |
|
340 |
if tyco1 <> tyco2 |
|
341 |
then raise NO_MATCH |
|
342 |
else subs |> fold2 eq tys1 tys2 |
|
343 |
| eq (IFun (ty11, ty12)) (IFun (ty21, ty22)) subs = |
|
344 |
subs |> eq ty11 ty21 |> eq ty12 ty22 |
|
345 |
| eq _ _ _ = raise NO_MATCH; |
|
346 |
in |
|
347 |
(eq ty1 ty2 []; true) |
|
348 |
handle NO_MATCH => false |
|
349 |
end; |
|
350 |
||
351 |
||
18169
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
352 |
(* simple diagnosis *) |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
353 |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
354 |
fun pretty_itype (IType (tyco, tys)) = |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
355 |
Pretty.gen_list "" "(" ")" (Pretty.str tyco :: map pretty_itype tys) |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
356 |
| pretty_itype (IFun (ty1, ty2)) = |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
357 |
Pretty.gen_list "" "(" ")" [pretty_itype ty1, Pretty.str "->", pretty_itype ty2] |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
358 |
| pretty_itype (IVarT (v, sort)) = |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
359 |
Pretty.str (v ^ enclose "|" "|" (space_implode "|" sort)) |
18282 | 360 |
| pretty_itype (IDictT _) = |
361 |
Pretty.str "<DictT>"; |
|
18169
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
362 |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
363 |
fun pretty_ipat (ICons ((cons, ps), ty)) = |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
364 |
Pretty.gen_list " " "(" ")" |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
365 |
(Pretty.str cons :: map pretty_ipat ps @ [Pretty.str ":: ", pretty_itype ty]) |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
366 |
| pretty_ipat (IVarP (v, ty)) = |
18282 | 367 |
Pretty.block [Pretty.str ("?" ^ v ^ "::"), pretty_itype ty]; |
18169
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
368 |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
369 |
fun pretty_iexpr (IConst (f, ty)) = |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
370 |
Pretty.block [Pretty.str (f ^ "::"), pretty_itype ty] |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
371 |
| pretty_iexpr (IVarE (v, ty)) = |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
372 |
Pretty.block [Pretty.str ("?" ^ v ^ "::"), pretty_itype ty] |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
373 |
| pretty_iexpr (IApp (e1, e2)) = |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
374 |
Pretty.enclose "(" ")" [pretty_iexpr e1, Pretty.brk 1, pretty_iexpr e2] |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
375 |
| pretty_iexpr (IInst (e, c)) = |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
376 |
pretty_iexpr e |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
377 |
| pretty_iexpr (IAbs ((v, ty), e)) = |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
378 |
Pretty.enclose "(" ")" [Pretty.str ("?" ^ v ^ " |->"), Pretty.brk 1, pretty_iexpr e] |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
379 |
| pretty_iexpr (ICase (e, cs)) = |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
380 |
Pretty.enclose "(" ")" [ |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
381 |
Pretty.str "case ", |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
382 |
pretty_iexpr e, |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
383 |
Pretty.enclose "(" ")" (map (fn (p, e) => |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
384 |
Pretty.block [ |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
385 |
pretty_ipat p, |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
386 |
Pretty.str " => ", |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
387 |
pretty_iexpr e |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
388 |
] |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
389 |
) cs) |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
390 |
] |
18282 | 391 |
| pretty_iexpr (IDictE _) = |
392 |
Pretty.str "<DictE>" |
|
18380
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
393 |
| pretty_iexpr (ILookup (ls, v)) = |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
394 |
Pretty.str ("<Lookup: " ^ commas ls ^ " in " ^ v ^ ">"); |
18169
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
395 |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
396 |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
397 |
(* language auxiliary *) |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
398 |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
399 |
fun itype_of_iexpr (IConst (_, ty)) = ty |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
400 |
| itype_of_iexpr (IVarE (_, ty)) = ty |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
401 |
| itype_of_iexpr (e as IApp (e1, e2)) = (case itype_of_iexpr e1 |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
402 |
of (IFun (ty2, ty')) => |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
403 |
if ty2 = itype_of_iexpr e2 |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
404 |
then ty' |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
405 |
else error ("inconsistent application: in " ^ Pretty.output (pretty_iexpr e) |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
406 |
^ ", " ^ (Pretty.output o pretty_itype) ty2 ^ " vs. " ^ (Pretty.output o pretty_itype o itype_of_iexpr) e2) |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
407 |
| _ => error ("expression is not a function: " ^ Pretty.output (pretty_iexpr e1))) |
18282 | 408 |
| itype_of_iexpr (IInst (e, cs)) = itype_of_iexpr e |
18169
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
409 |
| itype_of_iexpr (IAbs ((_, ty1), e2)) = ty1 `-> itype_of_iexpr e2 |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
410 |
| itype_of_iexpr (ICase ((_, [(_, e)]))) = itype_of_iexpr e; |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
411 |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
412 |
fun itype_of_ipat (ICons (_, ty)) = ty |
18380
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
413 |
| itype_of_ipat (IVarP (_, ty)) = ty; |
18169
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
414 |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
415 |
fun ipat_of_iexpr (IConst (f, ty)) = ICons ((f, []), ty) |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
416 |
| ipat_of_iexpr (IVarE v) = IVarP v |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
417 |
| ipat_of_iexpr (e as IApp _) = |
18380
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
418 |
(case unfold_app e |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
419 |
of (IConst (f, ty), es) => |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
420 |
ICons ((f, map ipat_of_iexpr es), (snd o unfold_fun) ty) |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
421 |
| (IInst (IConst (f, ty), _), es) => |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
422 |
ICons ((f, map ipat_of_iexpr es), (snd o unfold_fun) ty) |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
423 |
| _ => error ("illegal expression for pattern: " ^ (Pretty.output o pretty_iexpr) e)) |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
424 |
| ipat_of_iexpr e = |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
425 |
error ("illegal expression for pattern: " ^ (Pretty.output o pretty_iexpr) e); |
18169
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
426 |
|
18304 | 427 |
fun tvars_of_itypes tys = |
18216 | 428 |
let |
18304 | 429 |
fun vars (IType (_, tys)) = |
430 |
fold vars tys |
|
431 |
| vars (IFun (ty1, ty2)) = |
|
432 |
vars ty1 #> vars ty2 |
|
433 |
| vars (IVarT (v, _)) = |
|
434 |
insert (op =) v |
|
435 |
in fold vars tys [] end; |
|
18216 | 436 |
|
18169
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
437 |
fun vars_of_ipats ps = |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
438 |
let |
18304 | 439 |
fun vars (ICons ((_, ps), _)) = |
440 |
fold vars ps |
|
441 |
| vars (IVarP (v, _)) = |
|
442 |
insert (op =) v |
|
18169
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
443 |
in fold vars ps [] end; |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
444 |
|
18304 | 445 |
fun vars_of_iexprs es = |
446 |
let |
|
447 |
fun vars (IConst (f, _)) = |
|
448 |
I |
|
449 |
| vars (IVarE (v, _)) = |
|
450 |
insert (op =) v |
|
451 |
| vars (IApp (e1, e2)) = |
|
452 |
vars e1 #> vars e2 |
|
453 |
| vars (IAbs ((v, _), e)) = |
|
454 |
insert (op =) v |
|
455 |
#> vars e |
|
456 |
| vars (ICase (e, cs)) = |
|
457 |
vars e |
|
458 |
#> fold (fn (p, e) => fold (insert (op =)) (vars_of_ipats [p]) #> vars e) cs |
|
459 |
| vars (IInst (e, lookup)) = |
|
460 |
vars e |
|
461 |
| vars (IDictE ms) = |
|
462 |
fold (vars o snd) ms |
|
18380
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
463 |
| vars (ILookup (_, v)) = |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
464 |
cons v |
18304 | 465 |
in fold vars es [] end; |
466 |
||
18169
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
467 |
fun instant_itype (v, sty) ty = |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
468 |
let |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
469 |
fun instant (IType (tyco, tys)) = |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
470 |
tyco `%% map instant tys |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
471 |
| instant (IFun (ty1, ty2)) = |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
472 |
instant ty1 `-> instant ty2 |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
473 |
| instant (w as (IVarT (u, _))) = |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
474 |
if v = u then sty else w |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
475 |
in instant ty end; |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
476 |
|
18170 | 477 |
|
18282 | 478 |
|
18170 | 479 |
(** language module system - definitions, modules, transactions **) |
480 |
||
481 |
(* type definitions *) |
|
482 |
||
483 |
datatype def = |
|
484 |
Nop |
|
485 |
| Fun of (ipat list * iexpr) list * (ClassPackage.sortcontext * itype) |
|
18172 | 486 |
| Typesyn of (vname * string list) list * itype |
18380
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
487 |
| Datatype of (vname * string list) list * (string * itype list) list * string list |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
488 |
| Datatypecons of string |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
489 |
| Class of class list * vname * (string * (ClassPackage.sortcontext * itype)) list * string list |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
490 |
| Classmember of class |
18304 | 491 |
| Classinst of class * (string * (vname * string list) list) * (string * string) list; |
18170 | 492 |
|
493 |
datatype node = Def of def | Module of node Graph.T; |
|
494 |
type module = node Graph.T; |
|
495 |
type transact = Graph.key list * module; |
|
18231 | 496 |
datatype 'dst transact_res = Succeed of 'dst | Fail of string list * exn option; |
18170 | 497 |
type 'dst transact_fin = 'dst transact_res * transact; |
18304 | 498 |
type ('src, 'dst) gen_exprgen = 'src -> transact -> 'dst transact_fin; |
18170 | 499 |
type gen_defgen = string -> transact -> (def * string list) transact_fin; |
18231 | 500 |
exception FAIL of string list * exn option; |
18170 | 501 |
|
502 |
val eq_def = (op =); |
|
503 |
||
504 |
(* simple diagnosis *) |
|
505 |
||
506 |
fun pretty_def Nop = |
|
507 |
Pretty.str "<NOP>" |
|
508 |
| pretty_def (Fun (eqs, (_, ty))) = |
|
509 |
Pretty.gen_list " |" "" "" ( |
|
510 |
map (fn (ps, body) => |
|
511 |
Pretty.block [ |
|
512 |
Pretty.gen_list "," "[" "]" (map pretty_ipat ps), |
|
513 |
Pretty.str " |->", |
|
514 |
Pretty.brk 1, |
|
515 |
pretty_iexpr body, |
|
516 |
Pretty.str "::", |
|
517 |
pretty_itype ty |
|
518 |
]) eqs |
|
519 |
) |
|
18172 | 520 |
| pretty_def (Typesyn (vs, ty)) = |
18170 | 521 |
Pretty.block [ |
522 |
Pretty.list "(" ")" (map (pretty_itype o IVarT) vs), |
|
523 |
Pretty.str " |=> ", |
|
524 |
pretty_itype ty |
|
525 |
] |
|
18335 | 526 |
| pretty_def (Datatype (vs, cs, insts)) = |
18170 | 527 |
Pretty.block [ |
528 |
Pretty.list "(" ")" (map (pretty_itype o IVarT) vs), |
|
529 |
Pretty.str " |=> ", |
|
18380
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
530 |
Pretty.gen_list " |" "" "" |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
531 |
(map (fn (c, tys) => (Pretty.block o Pretty.breaks) (Pretty.str c :: map pretty_itype tys)) cs), |
18335 | 532 |
Pretty.str ", instances ", |
533 |
Pretty.gen_list "," "[" "]" (map Pretty.str insts) |
|
18170 | 534 |
] |
18380
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
535 |
| pretty_def (Datatypecons dtname) = |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
536 |
Pretty.str ("cons " ^ dtname) |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
537 |
| pretty_def (Class (supcls, v, mems, insts)) = |
18170 | 538 |
Pretty.block [ |
18380
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
539 |
Pretty.str ("class var " ^ v ^ "extending "), |
18231 | 540 |
Pretty.gen_list "," "[" "]" (map Pretty.str supcls), |
18282 | 541 |
Pretty.str " with ", |
18380
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
542 |
Pretty.gen_list "," "[" "]" |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
543 |
(map (fn (m, (_, ty)) => Pretty.block [Pretty.str (m ^ "::"), pretty_itype ty]) mems), |
18282 | 544 |
Pretty.str " instances ", |
18231 | 545 |
Pretty.gen_list "," "[" "]" (map Pretty.str insts) |
546 |
] |
|
18380
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
547 |
| pretty_def (Classmember clsname) = |
18231 | 548 |
Pretty.block [ |
549 |
Pretty.str "class member belonging to ", |
|
18282 | 550 |
Pretty.str clsname |
18231 | 551 |
] |
18282 | 552 |
| pretty_def (Classinst (clsname, (tyco, arity), mems)) = |
18231 | 553 |
Pretty.block [ |
554 |
Pretty.str "class instance (", |
|
18282 | 555 |
Pretty.str clsname, |
18231 | 556 |
Pretty.str ", (", |
557 |
Pretty.str tyco, |
|
558 |
Pretty.str ", ", |
|
18282 | 559 |
Pretty.gen_list "," "[" "]" (map (Pretty.gen_list "," "{" "}" o map Pretty.str o snd) arity), |
18454 | 560 |
Pretty.str ")) with ", |
561 |
Pretty.gen_list "," "[" "]" (map (fn (m1, m2) => Pretty.str (m1 ^ " => " ^ m2)) mems) |
|
18231 | 562 |
]; |
18170 | 563 |
|
564 |
fun pretty_module modl = |
|
565 |
let |
|
566 |
fun pretty (name, Module modl) = |
|
567 |
Pretty.block ( |
|
568 |
Pretty.str ("module " ^ name ^ " {") |
|
569 |
:: Pretty.brk 1 |
|
570 |
:: Pretty.chunks (map pretty (AList.make (Graph.get_node modl) |
|
571 |
(Graph.strong_conn modl |> List.concat |> rev))) |
|
572 |
:: Pretty.str "}" :: nil |
|
573 |
) |
|
574 |
| pretty (name, Def def) = |
|
575 |
Pretty.block [Pretty.str name, Pretty.str " :=", Pretty.brk 1, pretty_def def] |
|
576 |
in pretty ("//", Module modl) end; |
|
577 |
||
18360 | 578 |
fun pretty_deps modl = |
579 |
let |
|
580 |
fun one_node key = |
|
18380
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
581 |
let |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
582 |
val preds_ = Graph.imm_preds modl key; |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
583 |
val succs_ = Graph.imm_succs modl key; |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
584 |
val mutbs = gen_inter (op =) (preds_, succs_); |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
585 |
val preds = fold (remove (op =)) mutbs preds_; |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
586 |
val succs = fold (remove (op =)) mutbs succs_; |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
587 |
in |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
588 |
(Pretty.block o Pretty.fbreaks) ( |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
589 |
Pretty.str key |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
590 |
:: map (fn s => Pretty.str ("<-> " ^ s)) mutbs |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
591 |
@ map (fn s => Pretty.str ("<-- " ^ s)) preds |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
592 |
@ map (fn s => Pretty.str ("--> " ^ s)) succs |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
593 |
@ (the_list oo Option.mapPartial) ((fn Module modl' => SOME (pretty_deps modl') | _ => NONE) o Graph.get_node modl) (SOME key) |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
594 |
) |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
595 |
end |
18360 | 596 |
in |
597 |
modl |
|
598 |
|> Graph.strong_conn |
|
599 |
|> List.concat |
|
600 |
|> rev |
|
601 |
|> map one_node |
|
602 |
|> Pretty.chunks |
|
603 |
end; |
|
604 |
||
18170 | 605 |
|
606 |
(* name handling *) |
|
607 |
||
608 |
fun dest_name name = |
|
609 |
let |
|
610 |
val name' = NameSpace.unpack name |
|
611 |
val (name'', name_base) = split_last name' |
|
612 |
val (modl, shallow) = split_last name'' |
|
613 |
in (modl, NameSpace.pack [shallow, name_base]) end |
|
614 |
handle Empty => error ("not a qualified name: " ^ quote name); |
|
615 |
||
616 |
fun dest_modl (Module m) = m; |
|
617 |
fun dest_def (Def d) = d; |
|
618 |
||
619 |
||
620 |
(* modules *) |
|
621 |
||
622 |
val empty_module = Graph.empty; (*read: "depends on"*) |
|
623 |
||
624 |
fun get_def modl name = |
|
625 |
case dest_name name |
|
626 |
of (modlname, base) => |
|
627 |
let |
|
628 |
fun get (Module node) [] = |
|
629 |
(dest_def o Graph.get_node node) base |
|
630 |
| get (Module node) (m::ms) = |
|
631 |
get (Graph.get_node node m) ms |
|
632 |
in get (Module modl) modlname end; |
|
633 |
||
634 |
fun add_def (name, def) = |
|
635 |
let |
|
636 |
val (modl, base) = dest_name name; |
|
637 |
fun add [] = |
|
638 |
Graph.new_node (base, Def def) |
|
639 |
| add (m::ms) = |
|
640 |
Graph.default_node (m, Module empty_module) |
|
641 |
#> Graph.map_node m (Module o add ms o dest_modl) |
|
642 |
in add modl end; |
|
643 |
||
644 |
fun map_def name f = |
|
645 |
let |
|
646 |
val (modl, base) = dest_name name; |
|
647 |
fun mapp [] = |
|
648 |
Graph.map_node base (Def o f o dest_def) |
|
649 |
| mapp (m::ms) = |
|
650 |
Graph.map_node m (Module o mapp ms o dest_modl) |
|
651 |
in mapp modl end; |
|
652 |
||
653 |
fun add_dep (name1, name2) modl = |
|
654 |
if name1 = name2 then modl |
|
655 |
else |
|
656 |
let |
|
657 |
val m1 = dest_name name1 |> apsnd single |> (op @); |
|
658 |
val m2 = dest_name name2 |> apsnd single |> (op @); |
|
18454 | 659 |
val (ms, (r1, r2)) = get_prefix (op =) (m1, m2); |
660 |
val (ms, (s1::r1, s2::r2)) = get_prefix (op =) (m1, m2); |
|
18170 | 661 |
val add_edge = |
662 |
if null r1 andalso null r2 |
|
663 |
then Graph.add_edge |
|
664 |
else Graph.add_edge_acyclic |
|
665 |
fun add [] node = |
|
666 |
node |
|
667 |
|> add_edge (s1, s2) |
|
668 |
| add (m::ms) node = |
|
669 |
node |
|
670 |
|> Graph.map_node m (Module o add ms o dest_modl); |
|
671 |
in add ms modl end; |
|
672 |
||
673 |
fun map_defs f = |
|
674 |
let |
|
675 |
fun mapp (Def def) = |
|
676 |
(Def o f) def |
|
677 |
| mapp (Module modl) = |
|
678 |
(Module o Graph.map_nodes mapp) modl |
|
679 |
in dest_modl o mapp o Module end; |
|
680 |
||
681 |
fun fold_defs f = |
|
682 |
let |
|
683 |
fun fol prfix (name, Def def) = |
|
684 |
f (NameSpace.pack (prfix @ [name]), def) |
|
685 |
| fol prfix (name, Module modl) = |
|
686 |
Graph.fold_nodes (fol (prfix @ [name])) modl |
|
687 |
in Graph.fold_nodes (fol []) end; |
|
688 |
||
689 |
fun add_deps f modl = |
|
690 |
modl |
|
691 |
|> fold add_dep ([] |> fold_defs (append o f) modl); |
|
692 |
||
693 |
fun fold_map_defs f = |
|
694 |
let |
|
695 |
fun foldmap prfix (name, Def def) = |
|
696 |
apfst Def o f (NameSpace.pack (prfix @ [name]), def) |
|
697 |
| foldmap prfix (name, Module modl) = |
|
698 |
apfst Module o Graph.fold_map_nodes (foldmap (prfix @ [name])) modl |
|
699 |
in Graph.fold_map_nodes (foldmap []) end; |
|
700 |
||
18172 | 701 |
fun map_def_fun f_ipat f_iexpr (Fun (eqs, cty)) = |
702 |
Fun (map (fn (ps, rhs) => (map f_ipat ps, f_iexpr rhs)) eqs, cty) |
|
703 |
| map_def_fun _ _ def = def; |
|
704 |
||
705 |
fun transform_defs f_def f_ipat f_iexpr s modl = |
|
706 |
let |
|
707 |
val (modl', s') = fold_map_defs f_def modl s |
|
708 |
in |
|
709 |
modl' |
|
710 |
|> map_defs (map_def_fun (f_ipat s') (f_iexpr s')) |
|
711 |
end; |
|
712 |
||
18170 | 713 |
fun merge_module modl12 = |
714 |
let |
|
715 |
fun join_module (Module m1, Module m2) = |
|
716 |
(SOME o Module) (merge_module (m1, m2)) |
|
717 |
| join_module (Def d1, Def d2) = |
|
718 |
if eq_def (d1, d2) then (SOME o Def) d1 else NONE |
|
719 |
| join_module _ = |
|
720 |
NONE |
|
721 |
in Graph.join (K join_module) modl12 end; |
|
722 |
||
723 |
fun partof names modl = |
|
18335 | 724 |
let |
725 |
datatype pathnode = PN of (string list * (string * pathnode) list); |
|
726 |
fun mk_ipath ([], base) (PN (defs, modls)) = |
|
727 |
PN (base :: defs, modls) |
|
728 |
| mk_ipath (n::ns, base) (PN (defs, modls)) = |
|
729 |
modls |
|
730 |
|> AList.default (op =) (n, PN ([], [])) |
|
731 |
|> AList.map_entry (op =) n (mk_ipath (ns, base)) |
|
732 |
|> (pair defs #> PN); |
|
733 |
fun select (PN (defs, modls)) (Module module) = |
|
734 |
module |
|
735 |
|> Graph.subgraph (Graph.all_succs module (defs @ map fst modls)) |
|
736 |
|> fold (fn (name, modls) => Graph.map_node name (select modls)) modls |
|
737 |
|> Module; |
|
738 |
in |
|
739 |
Module modl |
|
740 |
|> select (fold (mk_ipath o dest_name) (filter NameSpace.is_qualified names) (PN ([], []))) |
|
741 |
|> dest_modl |
|
742 |
end; |
|
18170 | 743 |
|
18380
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
744 |
fun (*add_check_transform (name, (Datatypecons dtname)) = |
18231 | 745 |
(debug 7 (fn _ => "transformation for datatype constructor " ^ quote name |
746 |
^ " of datatype " ^ quote dtname) (); |
|
18170 | 747 |
([([dtname], |
18282 | 748 |
fn [Datatype (_, _, [])] => NONE |
749 |
| _ => "attempted to add constructor to already instantiating datatype" |> SOME)], |
|
18170 | 750 |
[(dtname, |
18335 | 751 |
fn Datatype (vs, cs, insts) => Datatype (vs, name::cs, insts) |
18170 | 752 |
| def => "attempted to add datatype constructor to non-datatype: " |
753 |
^ (Pretty.output o pretty_def) def |> error)]) |
|
18231 | 754 |
) |
18170 | 755 |
| add_check_transform (name, Classmember (clsname, v, ty)) = |
756 |
let |
|
18231 | 757 |
val _ = debug 7 (fn _ => "transformation for class member " ^ quote name |
758 |
^ " of class " ^ quote clsname) (); |
|
18170 | 759 |
fun check_var (IType (tyco, tys)) s = |
760 |
fold check_var tys s |
|
761 |
| check_var (IFun (ty1, ty2)) s = |
|
762 |
s |
|
763 |
|> check_var ty1 |
|
764 |
|> check_var ty2 |
|
765 |
| check_var (IVarT (w, sort)) s = |
|
766 |
if v = w |
|
767 |
andalso member (op =) sort clsname |
|
768 |
then "additional class appears at type variable" |> SOME |
|
769 |
else NONE |
|
770 |
in |
|
771 |
([([], fn [] => check_var ty NONE), |
|
772 |
([clsname], |
|
18304 | 773 |
fn [Class (_, _, _, [])] => NONE |
18170 | 774 |
| _ => "attempted to add class member to witnessed class" |> SOME)], |
775 |
[(clsname, |
|
18304 | 776 |
fn Class (supcs, v, mems, insts) => Class (supcs, v, name::mems, insts) |
18170 | 777 |
| def => "attempted to add class member to non-class" |
778 |
^ (Pretty.output o pretty_def) def |> error)]) |
|
779 |
end |
|
18380
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
780 |
| *) add_check_transform (name, Classinst (clsname, (tyco, arity), memdefs)) = |
18170 | 781 |
let |
18231 | 782 |
val _ = debug 7 (fn _ => "transformation for class instance " ^ quote tyco |
18454 | 783 |
^ " of class " ^ quote clsname ^ " with " ^ (commas o map (fn (m1, m2) => m1 ^ " => " ^ m2)) memdefs) (); |
18380
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
784 |
(* fun check [Classmember (_, v, mtyp_c), Fun (_, (_, mtyp_i))] = |
18231 | 785 |
let |
18282 | 786 |
val mtyp_i' = instant_itype (v, tyco `%% map IVarT arity) mtyp_c; |
787 |
in if eq_itype (mtyp_i', mtyp_i) |
|
788 |
then NONE |
|
789 |
else "wrong type signature for class member: " |
|
790 |
^ (Pretty.output o pretty_itype) mtyp_i' ^ " expected, " |
|
791 |
^ (Pretty.output o pretty_itype) mtyp_i ^ " given" |> SOME |
|
792 |
end |
|
18231 | 793 |
| check defs = |
794 |
"non-well-formed definitions encountered for classmembers: " |
|
18380
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
795 |
^ (commas o map (quote o Pretty.output o pretty_def)) defs |> SOME *) |
18170 | 796 |
in |
18380
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
797 |
((* map (fn (memname, memprim) => ([memname, memprim], check)) memdefs*) [], |
18170 | 798 |
[(clsname, |
18304 | 799 |
fn Class (supcs, v, mems, insts) => Class (supcs, v, mems, name::insts) |
18170 | 800 |
| def => "attempted to add class instance to non-class" |
801 |
^ (Pretty.output o pretty_def) def |> error), |
|
802 |
(tyco, |
|
18335 | 803 |
fn Datatype (vs, cs, insts) => Datatype (vs, cs, name::insts) |
18170 | 804 |
| Nop => Nop |
805 |
| def => "attempted to instantiate non-type to class instance" |
|
806 |
^ (Pretty.output o pretty_def) def |> error)]) |
|
807 |
end |
|
808 |
| add_check_transform _ = ([], []); |
|
809 |
||
18380
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
810 |
(* checks to be implemented here lateron: |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
811 |
- well-formedness of function equations |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
812 |
- only possible to add defined constructors and class members |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
813 |
- right type abstraction with class members |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
814 |
- correct typing of instance definitions |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
815 |
*) |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
816 |
|
18231 | 817 |
fun succeed some = pair (Succeed some); |
818 |
fun fail msg = pair (Fail ([msg], NONE)); |
|
18170 | 819 |
|
18231 | 820 |
fun check_fail _ (Succeed dst, trns) = (dst, trns) |
821 |
| check_fail msg (Fail (msgs, e), _) = raise FAIL (msg::msgs, e); |
|
18170 | 822 |
|
18231 | 823 |
fun select_generator _ _ [] modl = |
824 |
([], modl) |> fail ("no code generator available") |
|
825 |
| select_generator mk_msg src gens modl = |
|
826 |
let |
|
827 |
fun handle_fail msgs f = |
|
828 |
let |
|
829 |
in |
|
830 |
if ! soft_exc |
|
831 |
then |
|
18282 | 832 |
([], modl) |> f |
833 |
handle FAIL exc => (Fail exc, ([], modl)) |
|
834 |
| e => (Fail (msgs, SOME e), ([], modl)) |
|
18231 | 835 |
else |
18282 | 836 |
([], modl) |> f |
837 |
handle FAIL exc => (Fail exc, ([], modl)) |
|
18231 | 838 |
end; |
839 |
fun select msgs [(gname, gen)] = |
|
840 |
handle_fail (msgs @ [mk_msg gname]) (gen src) |
|
841 |
fun select msgs ((gname, gen)::gens) = |
|
842 |
let |
|
843 |
val msgs' = msgs @ [mk_msg gname] |
|
844 |
in case handle_fail msgs' (gen src) |
|
845 |
of (Fail (_, NONE), _) => |
|
846 |
select msgs' gens |
|
847 |
| result => |
|
848 |
result |
|
849 |
end; |
|
850 |
in select [] gens end; |
|
18170 | 851 |
|
852 |
fun gen_invoke codegens msg src (deps, modl) = |
|
18231 | 853 |
modl |
854 |
|> select_generator (fn gname => "trying code generator " ^ gname ^ " for source " ^ quote msg) |
|
18170 | 855 |
src codegens |
856 |
|> check_fail msg |
|
857 |
||> (fn (deps', modl') => (append deps' deps, modl')); |
|
858 |
||
859 |
fun gen_ensure_def defgens msg name (deps, modl) = |
|
860 |
let |
|
861 |
fun add (name, def) (deps, modl) = |
|
862 |
let |
|
863 |
val (checks, trans) = add_check_transform (name, def); |
|
864 |
fun check (check_defs, checker) modl = |
|
18231 | 865 |
let |
866 |
fun get_def' s = |
|
867 |
if NameSpace.is_qualified s |
|
868 |
then get_def modl s |
|
869 |
else Nop |
|
870 |
val defs = |
|
871 |
check_defs |
|
872 |
|> map get_def'; |
|
873 |
in |
|
18282 | 874 |
case checker defs |
18231 | 875 |
of NONE => modl |
18282 | 876 |
| SOME msg => raise FAIL ([msg], NONE) |
18231 | 877 |
end; |
18170 | 878 |
fun transform (name, f) modl = |
879 |
modl |
|
18231 | 880 |
|> debug 9 (fn _ => "transforming node " ^ name) |
881 |
|> (if NameSpace.is_qualified name then map_def name f else I); |
|
18170 | 882 |
in |
883 |
modl |
|
18231 | 884 |
|> debug 10 (fn _ => "considering addition of " ^ name |
885 |
^ " := " ^ (Pretty.output o pretty_def) def) |
|
886 |
|> debug 10 (fn _ => "consistency checks") |
|
18170 | 887 |
|> fold check checks |
18231 | 888 |
|> debug 10 (fn _ => "dependencies") |
18170 | 889 |
|> fold (curry add_dep name) deps |
18231 | 890 |
|> debug 10 (fn _ => "adding") |
18170 | 891 |
|> map_def name (fn _ => def) |
18231 | 892 |
|> debug 10 (fn _ => "transforming") |
18170 | 893 |
|> fold transform trans |
18231 | 894 |
|> debug 10 (fn _ => "adding done") |
18170 | 895 |
end; |
896 |
fun ensure_node name modl = |
|
18231 | 897 |
(debug 9 (fn _ => "testing node " ^ quote name) (); |
18170 | 898 |
if can (get_def modl) name |
18231 | 899 |
then |
900 |
modl |
|
901 |
|> debug 9 (fn _ => "asserting node " ^ quote name) |
|
902 |
|> pair [name] |
|
18170 | 903 |
else |
18231 | 904 |
modl |
905 |
|> debug 9 (fn _ => "creating node " ^ quote name) |
|
906 |
|> add_def (name, Nop) |
|
18454 | 907 |
|> debug 9 (fn _ => "checking creation of node " ^ quote name) |
18231 | 908 |
|> select_generator (fn gname => "trying code generator " ^ gname ^ " for definition of " ^ quote name) |
18170 | 909 |
name defgens |
18454 | 910 |
|> debug 9 (fn _ => "checking creation of node " ^ quote name) |
18170 | 911 |
|> check_fail msg |
912 |
|-> (fn (def, names') => |
|
913 |
add (name, def) |
|
914 |
#> fold_map ensure_node names') |
|
915 |
|-> (fn names' => pair (name :: Library.flat names')) |
|
18231 | 916 |
) |
18170 | 917 |
in |
918 |
modl |
|
919 |
|> ensure_node name |
|
920 |
|-> (fn names => pair (names@deps)) |
|
921 |
end; |
|
922 |
||
18231 | 923 |
fun start_transact f modl = |
924 |
let |
|
925 |
fun handle_fail f modl = |
|
926 |
((([], modl) |> f) |
|
927 |
handle FAIL (msgs, NONE) => |
|
928 |
(error o cat_lines) ("code generation failed, while:" :: msgs)) |
|
929 |
handle FAIL (msgs, SOME e) => |
|
930 |
((writeln o cat_lines) ("code generation failed, while:" :: msgs); raise e); |
|
931 |
in |
|
932 |
modl |
|
933 |
|> handle_fail f |
|
934 |
|-> (fn x => fn (_, module) => (x, module)) |
|
935 |
end; |
|
18172 | 936 |
|
937 |
||
938 |
(** primitive language constructs **) |
|
939 |
||
18304 | 940 |
val class_eq = "Eq"; (*defined for all primitve types and extensionally for all datatypes*) |
18172 | 941 |
val type_bool = "Bool"; |
942 |
val type_integer = "Integer"; (*infinite!*) |
|
943 |
val type_float = "Float"; |
|
944 |
val type_pair = "Pair"; |
|
945 |
val type_list = "List"; |
|
946 |
val cons_true = "True"; |
|
947 |
val cons_false = "False"; |
|
948 |
val cons_not = "not"; |
|
949 |
val cons_pair = "Pair"; |
|
950 |
val cons_nil = "Nil"; |
|
951 |
val cons_cons = "Cons"; |
|
952 |
val fun_eq = "eq"; (*to class eq*) |
|
953 |
val fun_not = "not"; |
|
954 |
val fun_and = "and"; |
|
955 |
val fun_or = "or"; |
|
956 |
val fun_if = "if"; |
|
957 |
val fun_fst = "fst"; |
|
958 |
val fun_snd = "snd"; |
|
959 |
val fun_add = "add"; |
|
960 |
val fun_mult = "mult"; |
|
961 |
val fun_minus = "minus"; |
|
962 |
val fun_lt = "lt"; |
|
963 |
val fun_le = "le"; |
|
964 |
val fun_wfrec = "wfrec"; |
|
965 |
||
966 |
local |
|
967 |
||
968 |
val A = IVarT ("a", []); |
|
969 |
val B = IVarT ("b", []); |
|
970 |
val E = IVarT ("e", [class_eq]); |
|
971 |
||
972 |
in |
|
973 |
||
974 |
val Type_bool = type_bool `%% []; |
|
975 |
val Type_integer = type_integer `%% []; |
|
976 |
val Type_float = type_float `%% []; |
|
977 |
fun Type_pair a b = type_pair `%% [a, b]; |
|
978 |
fun Type_list a = type_list `%% [a]; |
|
979 |
val Cons_true = IConst (cons_true, Type_bool); |
|
980 |
val Cons_false = IConst (cons_false, Type_bool); |
|
981 |
val Cons_pair = IConst (cons_pair, A `-> B `-> Type_pair A B); |
|
982 |
val Cons_nil = IConst (cons_nil, Type_list A); |
|
983 |
val Cons_cons = IConst (cons_cons, A `-> Type_list A `-> Type_list A); |
|
984 |
val Fun_eq = IConst (fun_eq, E `-> E `-> Type_bool); |
|
985 |
val Fun_not = IConst (fun_not, Type_bool `-> Type_bool); |
|
986 |
val Fun_and = IConst (fun_and, Type_bool `-> Type_bool `-> Type_bool); |
|
987 |
val Fun_or = IConst (fun_or, Type_bool `-> Type_bool `-> Type_bool); |
|
988 |
val Fun_if = IConst (fun_if, Type_bool `-> A `-> A `-> A); |
|
989 |
val Fun_fst = IConst (fun_fst, Type_pair A B `-> A); |
|
990 |
val Fun_snd = IConst (fun_snd, Type_pair A B `-> B); |
|
991 |
val Fun_0 = IConst ("0", Type_integer); |
|
992 |
val Fun_1 = IConst ("1", Type_integer); |
|
993 |
val Fun_add = IConst (fun_add, Type_integer `-> Type_integer `-> Type_integer); |
|
994 |
val Fun_mult = IConst (fun_mult, Type_integer `-> Type_integer `-> Type_integer); |
|
995 |
val Fun_minus = IConst (fun_minus, Type_integer `-> Type_integer); |
|
996 |
val Fun_lt = IConst (fun_lt, Type_integer `-> Type_integer `-> Type_bool); |
|
997 |
val Fun_le = IConst (fun_le, Type_integer `-> Type_integer `-> Type_bool); |
|
998 |
val Fun_wfrec = IConst (fun_wfrec, ((A `-> B) `-> A `-> B) `-> A `-> B); |
|
999 |
||
18380
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
1000 |
fun foldl1 f (x::xs) = |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
1001 |
Library.foldl f (x, xs); |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
1002 |
val ** = foldl1 (uncurry Type_pair); |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
1003 |
val XXp = foldl1 (fn (a, b) => |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
1004 |
let |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
1005 |
val ty_a = itype_of_ipat a; |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
1006 |
val ty_b = itype_of_ipat b; |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
1007 |
in ICons ((cons_pair, [a, b]), Type_pair ty_a ty_b) end); |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
1008 |
val XXe = foldl1 (fn (a, b) => |
18172 | 1009 |
let |
1010 |
val ty_a = itype_of_iexpr a; |
|
1011 |
val ty_b = itype_of_iexpr b; |
|
18380
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
1012 |
in IConst (cons_pair, ty_a `-> ty_b `-> Type_pair ty_a ty_b) `$ a `$ b end); |
18172 | 1013 |
|
1014 |
end; (* local *) |
|
1015 |
||
1016 |
val prims = [class_eq, type_bool, type_integer, type_float, type_pair, type_list, |
|
18385 | 1017 |
cons_true, cons_false, cons_pair, cons_nil, cons_cons, fun_eq, fun_not, fun_and, |
18172 | 1018 |
fun_or, fun_if, fun_fst, fun_snd, fun_add, fun_mult, fun_minus, fun_lt, fun_le, fun_wfrec]; |
1019 |
||
18335 | 1020 |
|
1021 |
(** equality handling **) |
|
1022 |
||
18385 | 1023 |
fun invoke_eq gen_ty gen_eq x (trns as (_ , modl)) = |
18335 | 1024 |
let |
18385 | 1025 |
fun mk_eqpred dtname = |
1026 |
let |
|
1027 |
val (vs, cons, _) = case get_def modl dtname of Datatype info => info; |
|
1028 |
val arity = map (rpair [class_eq] o fst) vs |
|
1029 |
val ty = IType (dtname, map IVarT arity); |
|
1030 |
fun mk_eq (c, []) = |
|
1031 |
([ICons ((c, []), ty), ICons ((c, []), ty)], Cons_true) |
|
1032 |
| mk_eq (c, tys) = |
|
1033 |
let |
|
1034 |
val vars1 = Term.invent_names [] "a" (length tys); |
|
1035 |
val vars2 = Term.invent_names vars1 "b" (length tys); |
|
1036 |
fun mk_eq_cons ty' (v1, v2) = |
|
1037 |
IConst (fun_eq, ty' `-> ty' `-> Type_bool) `$ IVarE (v1, ty) `$ IVarE (v2, ty) |
|
1038 |
fun mk_conj (e1, e2) = |
|
1039 |
Fun_and `$ e1 `$ e2; |
|
1040 |
in |
|
1041 |
([ICons ((c, map2 (curry IVarP) vars1 tys), ty), |
|
1042 |
ICons ((c, map2 (curry IVarP) vars2 tys), ty)], |
|
1043 |
foldr1 mk_conj (map2 mk_eq_cons tys (vars1 ~~ vars2))) |
|
1044 |
end; |
|
1045 |
val eqs = map mk_eq cons @ [([IVarP ("_", ty), IVarP ("_", ty)], Cons_false)]; |
|
1046 |
in |
|
1047 |
(Fun (eqs, (arity, ty `-> ty `-> Type_bool)), arity) |
|
1048 |
end; |
|
1049 |
fun invoke' (IType (tyco, tys)) trns = |
|
1050 |
trns |
|
1051 |
|> fold_map invoke' tys |
|
1052 |
|-> (fn is_eq => |
|
1053 |
if forall I is_eq |
|
1054 |
then if NameSpace.is_qualified tyco |
|
1055 |
then |
|
1056 |
gen_eq (tyco, mk_eqpred tyco) |
|
1057 |
#> pair true |
|
1058 |
else |
|
1059 |
pair true |
|
1060 |
else |
|
1061 |
pair false) |
|
1062 |
| invoke' (IFun _) trns = |
|
1063 |
trns |
|
1064 |
|> pair false |
|
1065 |
| invoke' (IVarT (_, sort)) trns = |
|
1066 |
trns |
|
1067 |
|> pair (member (op =) sort class_eq) |
|
18335 | 1068 |
in |
18385 | 1069 |
trns |
1070 |
|> gen_ty x |
|
1071 |
|-> (fn ty => invoke' ty) |
|
18335 | 1072 |
end; |
1073 |
||
1074 |
||
1075 |
(** generic transformation **) |
|
18304 | 1076 |
|
18172 | 1077 |
fun extract_defs e = |
1078 |
let |
|
1079 |
fun extr_itype (ty as IType (tyco, _)) = |
|
1080 |
cons tyco #> fold_itype extr_itype ty |
|
1081 |
| extr_itype ty = |
|
1082 |
fold_itype extr_itype ty |
|
1083 |
fun extr_ipat (p as ICons ((c, _), _)) = |
|
1084 |
cons c #> fold_ipat extr_itype extr_ipat p |
|
1085 |
| extr_ipat p = |
|
1086 |
fold_ipat extr_itype extr_ipat p |
|
1087 |
fun extr_iexpr (e as IConst (f, _)) = |
|
1088 |
cons f #> fold_iexpr extr_itype extr_ipat extr_iexpr e |
|
1089 |
| extr_iexpr e = |
|
1090 |
fold_iexpr extr_itype extr_ipat extr_iexpr e |
|
1091 |
in extr_iexpr e [] end; |
|
1092 |
||
1093 |
fun eta_expand query = |
|
1094 |
let |
|
1095 |
fun eta_app ((f, ty), es) = |
|
1096 |
let |
|
1097 |
val delta = query f - length es; |
|
1098 |
val add_n = if delta < 0 then 0 else delta; |
|
18282 | 1099 |
val tys = |
1100 |
(fst o unfold_fun) ty |
|
1101 |
|> curry Library.drop (length es) |
|
1102 |
|> curry Library.take add_n |
|
18172 | 1103 |
val add_vars = |
18304 | 1104 |
Term.invent_names (vars_of_iexprs es) "x" add_n ~~ tys; |
18172 | 1105 |
in |
1106 |
Library.foldr IAbs (add_vars, IConst (f, ty) `$$ es `$$ (map IVarE add_vars)) |
|
1107 |
end; |
|
1108 |
fun eta_iexpr' e = map_iexpr I I eta_iexpr e |
|
1109 |
and eta_iexpr (IConst (f, ty)) = |
|
1110 |
eta_app ((f, ty), []) |
|
1111 |
| eta_iexpr (e as IApp _) = |
|
1112 |
(case (unfold_app e) |
|
1113 |
of (IConst (f, ty), es) => |
|
1114 |
eta_app ((f, ty), map eta_iexpr es) |
|
1115 |
| _ => eta_iexpr' e) |
|
1116 |
| eta_iexpr e = eta_iexpr' e; |
|
1117 |
in map_defs (map_def_fun I eta_iexpr) end; |
|
1118 |
||
18216 | 1119 |
val eta_expand_poly = |
1120 |
let |
|
1121 |
fun map_def_fun (def as Fun ([([], e)], cty as (sortctxt, (ty as IFun (ty1, ty2))))) = |
|
1122 |
if (not o null) sortctxt |
|
18304 | 1123 |
orelse (null o tvars_of_itypes) [ty] |
18216 | 1124 |
then def |
1125 |
else |
|
1126 |
let |
|
18304 | 1127 |
val add_var = (hd (Term.invent_names (vars_of_iexprs [e]) "x" 1), ty1) |
18216 | 1128 |
in (Fun ([([IVarP add_var], IAbs (add_var, e))], cty)) end |
1129 |
| map_def_fun def = def; |
|
1130 |
in map_defs map_def_fun end; |
|
1131 |
||
18172 | 1132 |
fun tupelize_cons module = |
1133 |
let |
|
18380
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
1134 |
fun replace_cons (cons as (_, [])) = |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
1135 |
pair cons |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
1136 |
| replace_cons (cons as (_, [_])) = |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
1137 |
pair cons |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
1138 |
| replace_cons (con, tys) = |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
1139 |
cons con |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
1140 |
#> pair (con, [** tys]) |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
1141 |
fun replace_def (_, (def as Datatype (vs, cs, insts))) = |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
1142 |
fold_map replace_cons cs |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
1143 |
#-> (fn cs => pair (Datatype (vs, cs, insts))) |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
1144 |
| replace_def (_, def) = |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
1145 |
pair def |
18172 | 1146 |
fun replace_app cs ((f, ty), es) = |
1147 |
if member (op =) cs f |
|
1148 |
then |
|
1149 |
let |
|
1150 |
val (tys, ty') = unfold_fun ty |
|
18380
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
1151 |
in IConst (f, ** tys `-> ty') `$ XXe es end |
18172 | 1152 |
else IConst (f, ty) `$$ es; |
1153 |
fun replace_iexpr cs (IConst (f, ty)) = |
|
1154 |
replace_app cs ((f, ty), []) |
|
1155 |
| replace_iexpr cs (e as IApp _) = |
|
1156 |
(case unfold_app e |
|
1157 |
of (IConst fty, es) => replace_app cs (fty, map (replace_iexpr cs) es) |
|
1158 |
| _ => map_iexpr I I (replace_iexpr cs) e) |
|
1159 |
| replace_iexpr cs e = map_iexpr I I (replace_iexpr cs) e; |
|
1160 |
fun replace_ipat cs (p as ICons ((c, ps), ty)) = |
|
1161 |
if member (op =) cs c then |
|
18380
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
1162 |
ICons ((c, [XXp (map (replace_ipat cs) ps)]), ty) |
18172 | 1163 |
else map_ipat I (replace_ipat cs) p |
1164 |
| replace_ipat cs p = map_ipat I (replace_ipat cs) p; |
|
1165 |
in |
|
1166 |
transform_defs replace_def replace_ipat replace_iexpr [cons_cons] module |
|
1167 |
end; |
|
1168 |
||
1169 |
fun eliminate_classes module = |
|
1170 |
let |
|
18380
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
1171 |
fun transform_itype (IVarT (v, s)) = |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
1172 |
IVarT (v, []) |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
1173 |
| transform_itype (ty as IDictT _) = |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
1174 |
ty |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
1175 |
| transform_itype ty = |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
1176 |
map_itype transform_itype ty; |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
1177 |
fun transform_ipat p = |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
1178 |
map_ipat transform_itype transform_ipat p; |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
1179 |
fun transform_iexpr vname_alist (IInst (e, ls)) = |
18172 | 1180 |
let |
18282 | 1181 |
fun transform_lookup (ClassPackage.Instance ((cdict, idict), ls)) = |
18172 | 1182 |
ls |
1183 |
|> transform_lookups |
|
18282 | 1184 |
|-> (fn tys => |
1185 |
curry mk_apps (IConst (idict, cdict `%% tys)) |
|
1186 |
#> pair (cdict `%% tys)) |
|
18172 | 1187 |
| transform_lookup (ClassPackage.Lookup (deriv, (v, i))) = |
1188 |
let |
|
1189 |
val (v', cls) = |
|
1190 |
(nth o the oo AList.lookup (op =)) vname_alist v i; |
|
1191 |
fun mk_parm tyco = tyco `%% [IVarT (v, [])]; |
|
18380
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
1192 |
in (mk_parm cls, ILookup (deriv, v')) end |
18172 | 1193 |
and transform_lookups lss = |
1194 |
map_yield (map_yield transform_lookup |
|
18380
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
1195 |
#> apfst ** |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
1196 |
#> apsnd XXe) lss |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
1197 |
in transform_iexpr vname_alist e `$$ (snd o transform_lookups) ls end |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
1198 |
| transform_iexpr vname_alist e = |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
1199 |
map_iexpr transform_itype transform_ipat (transform_iexpr vname_alist) e; |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
1200 |
fun mk_cls_typ_map v membrs ty_inst = |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
1201 |
map (fn (m, (mctxt, ty)) => |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
1202 |
(m, ty |> instant_itype (v, ty_inst))) membrs; |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
1203 |
fun extract_members (cls, Class (supclss, v, membrs, _)) = |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
1204 |
let |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
1205 |
val ty_cls = cls `%% [IVarT (v, [])]; |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
1206 |
val w = "d"; |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
1207 |
val add_supclss = if null supclss then I else cons (v, supclss); |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
1208 |
fun mk_fun (m, (mctxt, ty)) = (m, Fun ([([IVarP (w, ty_cls)], ILookup ([m], w))], |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
1209 |
(add_supclss mctxt, ty `-> ty_cls))); |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
1210 |
in fold (cons o mk_fun) membrs end |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
1211 |
| extract_members _ = I; |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
1212 |
fun introduce_dicts (Class (supcls, v, membrs, insts)) = |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
1213 |
let |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
1214 |
val varname_cls = Term.invent_names (tvars_of_itypes (map (snd o snd) membrs)) "a" 1 |> hd |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
1215 |
in |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
1216 |
Typesyn ([(varname_cls, supcls)], IDictT (mk_cls_typ_map v membrs (IVarT (varname_cls, [])))) |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
1217 |
end |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
1218 |
| introduce_dicts (Classinst (clsname, (tyco, arity), memdefs)) = |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
1219 |
let |
18385 | 1220 |
val Class (_, v, members, _) = |
1221 |
if clsname = class_eq |
|
1222 |
then |
|
1223 |
Class ([], "a", [(fun_eq, ([], IVarT ("a", []) `-> IVarT ("a", []) `-> Type_bool))], []) |
|
1224 |
else |
|
1225 |
get_def module clsname; |
|
18380
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
1226 |
val ty = tyco `%% map IVarT arity; |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
1227 |
val inst_typ_map = mk_cls_typ_map v members ty; |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
1228 |
val memdefs_ty = map (fn (memname, memprim) => |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
1229 |
(memname, (memprim, (the o AList.lookup (op =) inst_typ_map) memname))) memdefs; |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
1230 |
in |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
1231 |
Fun ([([], IDictE (map (apsnd IConst) memdefs_ty))], |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
1232 |
([], IType (clsname, [ty]))) |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
1233 |
end |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
1234 |
| introduce_dicts d = d; |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
1235 |
fun elim_sorts (Fun (eqs, ([], ty))) = |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
1236 |
Fun (map (fn (ps, rhs) => (map transform_ipat ps, transform_iexpr [] rhs)) eqs, |
18454 | 1237 |
([], transform_itype ty)) |
18380
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
1238 |
| elim_sorts (Fun (eqs, (sortctxt, ty))) = |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
1239 |
let |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
1240 |
val varnames_ctxt = |
18441 | 1241 |
burrow |
18380
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
1242 |
(Term.invent_names ((vars_of_iexprs o map snd) eqs @ |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
1243 |
(vars_of_ipats o Library.flat o map fst) eqs) "d" o length) |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
1244 |
(map snd sortctxt); |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
1245 |
val vname_alist = map2 (fn (vt, sort) => fn vs => (vt, vs ~~ sort)) |
18454 | 1246 |
sortctxt varnames_ctxt; |
18380
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
1247 |
val ty' = map (op ** o (fn (vt, vss) => map (fn (_, cls) => |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
1248 |
cls `%% [IVarT (vt, [])]) vss)) vname_alist |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
1249 |
`--> transform_itype ty; |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
1250 |
val ps_add = map (XXp o (fn (vt, vss) => map (fn (v, cls) => |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
1251 |
IVarP (v, cls `%% [IVarT (vt, [])])) vss)) vname_alist; |
18454 | 1252 |
in Fun (map (fn (ps, rhs) => (ps_add @ map transform_ipat ps, transform_iexpr vname_alist rhs)) eqs, ([], ty')) end |
18380
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
1253 |
| elim_sorts (Datatype (vars, constrs, insts)) = |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
1254 |
Datatype (map (fn (v, _) => (v, [])) vars, map (apsnd (map transform_itype)) constrs, insts) |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
1255 |
| elim_sorts (Typesyn (vars, ty)) = |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
1256 |
Typesyn (map (fn (v, _) => (v, [])) vars, transform_itype ty) |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
1257 |
| elim_sorts d = d; |
18172 | 1258 |
in |
1259 |
module |
|
18380
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
1260 |
|> `(fn module => fold_defs extract_members module []) |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
1261 |
|-> (fn membrs => fold (fn (name, f) => map_def name (K f)) membrs) |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
1262 |
|> map_defs introduce_dicts |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
1263 |
|> map_defs elim_sorts |
18172 | 1264 |
end; |
1265 |
||
18216 | 1266 |
|
1267 |
(** generic serialization **) |
|
1268 |
||
1269 |
(* resolving *) |
|
1270 |
||
1271 |
fun mk_resolvtab nspgrp validate module = |
|
1272 |
let |
|
1273 |
fun ensure_unique prfix prfix' name name' (locals, tab) = |
|
1274 |
let |
|
1275 |
fun uniquify name n = |
|
1276 |
let |
|
1277 |
val name' = if n = 0 then name else name ^ "_" ^ string_of_int n |
|
1278 |
in |
|
1279 |
if member (op =) locals name' |
|
1280 |
then uniquify name (n+1) |
|
1281 |
else case validate name |
|
1282 |
of NONE => name' |
|
1283 |
| SOME name' => uniquify name' n |
|
1284 |
end; |
|
1285 |
val name'' = uniquify name' 0; |
|
1286 |
in |
|
1287 |
(locals, tab) |
|
1288 |
|> apsnd (Symtab.update_new |
|
1289 |
(NameSpace.pack (prfix @ [name]), NameSpace.pack (prfix' @ [name'']))) |
|
1290 |
|> apfst (cons name'') |
|
1291 |
|> pair name'' |
|
1292 |
end; |
|
1293 |
fun fill_in prfix prfix' node tab = |
|
1294 |
let |
|
1295 |
val keys = Graph.keys node; |
|
1296 |
val nodes = AList.make (Graph.get_node node) keys; |
|
1297 |
val (mods, defs) = |
|
1298 |
nodes |
|
1299 |
|> List.partition (fn (_, Module _) => true | _ => false) |
|
1300 |
|> apfst (map (fn (name, Module m) => (name, m))) |
|
1301 |
|> apsnd (map fst) |
|
1302 |
fun modl_validate (name, modl) (locals, tab) = |
|
1303 |
(locals, tab) |
|
1304 |
|> ensure_unique prfix prfix' name name |
|
1305 |
|-> (fn name' => apsnd (fill_in (prfix @ [name]) (prfix @ [name']) modl)) |
|
1306 |
fun ensure_unique_sidf sidf = |
|
1307 |
let |
|
1308 |
val [shallow, name] = NameSpace.unpack sidf; |
|
1309 |
in |
|
1310 |
nspgrp |
|
1311 |
|> get_first |
|
1312 |
(fn grp => if member (op =) grp shallow |
|
1313 |
then grp |> remove (op =) shallow |> SOME else NONE) |
|
1314 |
|> these |
|
1315 |
|> map (fn s => NameSpace.pack [s, name]) |
|
1316 |
|> exists (member (op =) defs) |
|
1317 |
|> (fn b => if b then sidf else name) |
|
1318 |
end; |
|
1319 |
fun def_validate sidf (locals, tab) = |
|
1320 |
(locals, tab) |
|
1321 |
|> ensure_unique prfix prfix' sidf (ensure_unique_sidf sidf) |
|
1322 |
|> snd |
|
1323 |
in |
|
1324 |
([], tab) |
|
1325 |
|> fold modl_validate mods |
|
1326 |
|> fold def_validate defs |
|
1327 |
|> snd |
|
1328 |
end; |
|
1329 |
in |
|
1330 |
Symtab.empty |
|
1331 |
|> fill_in [] [] module |
|
1332 |
end; |
|
1333 |
||
18282 | 1334 |
fun mk_resolv tab = |
18216 | 1335 |
let |
1336 |
fun resolver modl name = |
|
1337 |
if NameSpace.is_qualified name then |
|
1338 |
let |
|
18247
b17724cae935
code generator: case expressions, improved name resolving
haftmann
parents:
18231
diff
changeset
|
1339 |
val _ = debug 12 (fn name' => "resolving " ^ quote name ^ " in " ^ (quote o NameSpace.pack) modl) (); |
18216 | 1340 |
val modl' = if null modl then [] else (NameSpace.unpack o the o Symtab.lookup tab o NameSpace.pack) modl; |
1341 |
val name' = (NameSpace.unpack o the o Symtab.lookup tab) name |
|
1342 |
in |
|
18454 | 1343 |
(NameSpace.pack o snd o snd o get_prefix (op =)) (modl', name') |
18247
b17724cae935
code generator: case expressions, improved name resolving
haftmann
parents:
18231
diff
changeset
|
1344 |
|> debug 12 (fn name' => "resolving " ^ quote name ^ " to " ^ quote name' ^ " in " ^ (quote o NameSpace.pack) modl) |
18216 | 1345 |
end |
1346 |
else name |
|
1347 |
in resolver end; |
|
1348 |
||
1349 |
||
1350 |
(* serialization *) |
|
1351 |
||
1352 |
fun serialize s_def s_module validate nspgrp name_root module = |
|
1353 |
let |
|
1354 |
val resolvtab = mk_resolvtab nspgrp validate module; |
|
1355 |
val resolver = mk_resolv resolvtab; |
|
1356 |
fun seri prfx ([(name, Module module)]) = |
|
18247
b17724cae935
code generator: case expressions, improved name resolving
haftmann
parents:
18231
diff
changeset
|
1357 |
s_module (resolver prfx (prfx @ [name] |> NameSpace.pack), |
18380
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
1358 |
List.mapPartial (seri (prfx @ [name])) |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
1359 |
((map (AList.make (Graph.get_node module)) o rev o Graph.strong_conn) module)) |
18454 | 1360 |
|> SOME |
18216 | 1361 |
| seri prfx ds = |
18380
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
1362 |
s_def (resolver prfx) (map |
18454 | 1363 |
(fn (name, Def def) => (resolver prfx (prfx @ [name] |> NameSpace.pack), def)) ds) |
18216 | 1364 |
in |
18380
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
1365 |
setmp print_mode [] (fn _ => s_module (name_root, (List.mapPartial (seri []) |
18361 | 1366 |
((map (AList.make (Graph.get_node module)) o rev o Graph.strong_conn) module)))) () |
18216 | 1367 |
end; |
1368 |
||
18169
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
1369 |
end; (* struct *) |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
1370 |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
1371 |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
1372 |
structure CodegenThingol : CODEGEN_THINGOL = |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
1373 |
struct |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
1374 |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
1375 |
open CodegenThingolOp; |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
1376 |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
1377 |
end; (* struct *) |