author | haftmann |
Tue, 15 Nov 2005 10:11:52 +0100 | |
changeset 18172 | 8ff5bcfae27a |
parent 18170 | 73ce773f12de |
child 18216 | db7d43b25c99 |
permissions | -rw-r--r-- |
18169
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
1 |
(* Title: Pure/Tools/codegen_thingol.ML |
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 eq_itype: itype * itype -> bool |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
29 |
val eq_ipat: ipat * ipat -> bool |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
30 |
val eq_iexpr: iexpr * iexpr -> bool |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
31 |
val mk_funs: itype list * itype -> itype; |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
32 |
val mk_apps: iexpr * iexpr list -> iexpr; |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
33 |
val pretty_itype: itype -> Pretty.T; |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
34 |
val pretty_ipat: ipat -> Pretty.T; |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
35 |
val pretty_iexpr: iexpr -> Pretty.T; |
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; |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
38 |
val unfold_let: iexpr -> (ipat * iexpr) list * iexpr; |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
39 |
val itype_of_iexpr: iexpr -> itype; |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
40 |
val itype_of_ipat: ipat -> itype; |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
41 |
val ipat_of_iexpr: iexpr -> ipat; |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
42 |
val vars_of_ipats: ipat list -> vname list; |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
43 |
val instant_itype: vname * itype -> itype -> itype; |
18172 | 44 |
val invent_var_t_names: itype list -> int -> vname list -> vname -> vname list; |
45 |
val invent_var_e_names: iexpr list -> int -> vname list -> vname -> vname list; |
|
18170 | 46 |
|
47 |
datatype def = |
|
48 |
Nop |
|
49 |
| Fun of (ipat list * iexpr) list * (ClassPackage.sortcontext * itype) |
|
18172 | 50 |
| Typesyn of (vname * string list) list * itype |
51 |
| Datatype of (vname * string list) list * string list * string list |
|
52 |
| Datatypecons of string * itype list |
|
18170 | 53 |
| Class of string list * string list * string list |
54 |
| Classmember of string * vname * itype |
|
55 |
| Classinst of string * (string * string list list) * (string * string) list; |
|
56 |
type module; |
|
57 |
type transact; |
|
58 |
type 'dst transact_fin; |
|
59 |
type ('src, 'dst) gen_codegen = 'src -> transact -> 'dst transact_fin; |
|
60 |
type gen_defgen = string -> transact -> (def * string list) transact_fin; |
|
61 |
val eq_def: def * def -> bool; |
|
62 |
val pretty_def: def -> Pretty.T; |
|
63 |
val pretty_module: module -> Pretty.T; |
|
64 |
val empty_module: module; |
|
65 |
val get_def: module -> string -> def; |
|
66 |
val merge_module: module * module -> module; |
|
67 |
val partof: string list -> module -> module; |
|
68 |
val succeed: 'a -> transact -> 'a transact_fin; |
|
69 |
val fail: string -> transact -> 'a transact_fin; |
|
70 |
val gen_invoke: (string * ('src, 'dst) gen_codegen) list -> string |
|
71 |
-> 'src -> transact -> 'dst * transact; |
|
72 |
val gen_ensure_def: (string * gen_defgen) list -> string |
|
73 |
-> string -> transact -> transact; |
|
74 |
||
18172 | 75 |
val prims: string list; |
76 |
val extract_defs: iexpr -> string list; |
|
77 |
val eta_expand: (string -> int) -> module -> module; |
|
78 |
val connect_datatypes_clsdecls: module -> module; |
|
79 |
val tupelize_cons: module -> module; |
|
80 |
val eliminate_dtconstr: module -> module; |
|
81 |
val eliminate_classes: module -> module; |
|
82 |
||
18170 | 83 |
val debug_level : int ref; |
84 |
val debug : int -> ('a -> string) -> 'a -> 'a; |
|
18169
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
85 |
end; |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
86 |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
87 |
signature CODEGEN_THINGOL_OP = |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
88 |
sig |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
89 |
include CODEGEN_THINGOL; |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
90 |
val `%% : string * itype list -> itype; |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
91 |
val `-> : itype * itype -> itype; |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
92 |
val `--> : itype list * itype -> itype; |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
93 |
val `$ : iexpr * iexpr -> iexpr; |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
94 |
val `$$ : iexpr * iexpr list -> iexpr; |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
95 |
end; |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
96 |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
97 |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
98 |
structure CodegenThingolOp: CODEGEN_THINGOL_OP = |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
99 |
struct |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
100 |
|
18170 | 101 |
(** auxiliary **) |
18169
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
102 |
|
18170 | 103 |
val debug_level = ref 0; |
104 |
fun debug d f x = (if d <= !debug_level then Output.debug (f x) else (); x); |
|
18169
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
105 |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
106 |
fun foldl' f (l, []) = the l |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
107 |
| foldl' f (_, (r::rs)) = |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
108 |
let |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
109 |
fun itl (l, []) = l |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
110 |
| itl (l, r::rs) = itl (f (l, r), rs) |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
111 |
in itl (r, rs) end; |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
112 |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
113 |
fun foldr' f ([], r) = the r |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
114 |
| foldr' f (ls, _) = |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
115 |
let |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
116 |
fun itr [l] = l |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
117 |
| itr (l::ls) = f (l, itr ls) |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
118 |
in itr ls end; |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
119 |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
120 |
fun unfoldl dest x = |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
121 |
case dest x |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
122 |
of NONE => (x, []) |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
123 |
| SOME (x1, x2) => |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
124 |
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
|
125 |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
126 |
fun unfoldr dest x = |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
127 |
case dest x |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
128 |
of NONE => ([], x) |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
129 |
| SOME (x1, x2) => |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
130 |
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
|
131 |
|
18172 | 132 |
fun map_yield f [] = ([], []) |
133 |
| map_yield f (x::xs) = |
|
134 |
let |
|
135 |
val (y, x') = f x |
|
136 |
val (ys, xs') = map_yield f xs |
|
137 |
in (y::ys, x'::xs') end; |
|
138 |
||
18170 | 139 |
fun get_prefix eq ([], ys) = ([], [], ys) |
140 |
| get_prefix eq (xs, []) = ([], xs, []) |
|
141 |
| get_prefix eq (xs as x::xs', ys as y::ys') = |
|
142 |
if eq (x, y) then |
|
143 |
let val (ps', xs'', ys'') = get_prefix eq (xs', ys') |
|
144 |
in (x::ps', xs'', ys'') end |
|
145 |
else ([], xs, ys); |
|
146 |
||
147 |
||
148 |
(** language core - types, pattern, expressions **) |
|
18169
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
149 |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
150 |
(* language representation *) |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
151 |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
152 |
infix 8 `%%; |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
153 |
infixr 6 `->; |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
154 |
infixr 6 `-->; |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
155 |
infix 4 `$; |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
156 |
infix 4 `$$; |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
157 |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
158 |
type vname = string; |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
159 |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
160 |
datatype itype = |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
161 |
IType of string * itype list |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
162 |
| IFun of itype * itype |
18172 | 163 |
| IVarT of vname * sort |
164 |
(*ML auxiliary*) |
|
165 |
| IDictT of (string * itype) list; |
|
18169
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
166 |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
167 |
datatype ipat = |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
168 |
ICons of (string * ipat list) * itype |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
169 |
| IVarP of vname * itype; |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
170 |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
171 |
datatype iexpr = |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
172 |
IConst of string * itype |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
173 |
| IVarE of vname * itype |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
174 |
| IApp of iexpr * iexpr |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
175 |
| IInst of iexpr * ClassPackage.sortlookup list list |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
176 |
| IAbs of (vname * itype) * iexpr |
18172 | 177 |
| ICase of iexpr * (ipat * iexpr) list |
178 |
(*ML auxiliary*) |
|
179 |
| IDictE of (string * iexpr) list |
|
180 |
| ILookup of (string list * vname); |
|
18169
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
181 |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
182 |
val eq_itype = (op =); |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
183 |
val eq_ipat = (op =); |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
184 |
val eq_iexpr = (op =); |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
185 |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
186 |
val mk_funs = Library.foldr IFun; |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
187 |
val mk_apps = Library.foldl IApp; |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
188 |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
189 |
fun tyco `%% tys = IType (tyco, tys); |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
190 |
val op `-> = IFun; |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
191 |
fun f `$ x = IApp (f, x); |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
192 |
val op `--> = mk_funs; |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
193 |
val op `$$ = mk_apps; |
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 |
val unfold_fun = unfoldr |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
196 |
(fn IFun t => SOME t |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
197 |
| _ => NONE); |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
198 |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
199 |
val unfold_app = unfoldl |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
200 |
(fn IApp e => SOME e |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
201 |
| _ => NONE); |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
202 |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
203 |
val unfold_let = unfoldr |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
204 |
(fn ICase (e, [(p, e')]) => SOME ((p, e), e') |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
205 |
| _ => NONE); |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
206 |
|
18172 | 207 |
fun map_itype f_itype (IType (tyco, tys)) = |
208 |
tyco `%% map f_itype tys |
|
209 |
| map_itype f_itype (IFun (t1, t2)) = |
|
210 |
f_itype t1 `-> f_itype t2 |
|
211 |
| map_itype _ (ty as IVarT _) = |
|
212 |
ty; |
|
213 |
||
214 |
fun map_ipat f_itype f_ipat (ICons ((c, ps), ty)) = |
|
215 |
ICons ((c, map f_ipat ps), f_itype ty) |
|
216 |
| map_ipat _ _ (p as IVarP _) = |
|
217 |
p; |
|
218 |
||
219 |
fun map_iexpr f_itype f_ipat f_iexpr (IApp (e1, e2)) = |
|
220 |
f_iexpr e1 `$ f_iexpr e2 |
|
221 |
| map_iexpr f_itype f_ipat f_iexpr (IInst (e, c)) = |
|
222 |
IInst (f_iexpr e, c) |
|
223 |
| map_iexpr f_itype f_ipat f_iexpr (IAbs (v, e)) = |
|
224 |
IAbs (v, f_iexpr e) |
|
225 |
| map_iexpr f_itype f_ipat f_iexpr (ICase (e, ps)) = |
|
226 |
ICase (f_iexpr e, map (fn (p, e) => (f_ipat p, f_iexpr e)) ps) |
|
227 |
| map_iexpr _ _ _ (e as IConst _) = |
|
228 |
e |
|
229 |
| map_iexpr _ _ _ (e as IVarE _) = |
|
230 |
e; |
|
231 |
||
232 |
fun fold_itype f_itype (IFun (t1, t2)) = |
|
233 |
f_itype t1 #> f_itype t2 |
|
234 |
| fold_itype _ (ty as IType _) = |
|
235 |
I |
|
236 |
| fold_itype _ (ty as IVarT _) = |
|
237 |
I; |
|
238 |
||
239 |
fun fold_ipat f_itype f_ipat (ICons ((_, ps), ty)) = |
|
240 |
f_itype ty #> fold f_ipat ps |
|
241 |
| fold_ipat f_itype f_ipat (p as IVarP _) = |
|
242 |
I; |
|
243 |
||
244 |
fun fold_iexpr f_itype f_ipat f_iexpr (IApp (e1, e2)) = |
|
245 |
f_iexpr e1 #> f_iexpr e2 |
|
246 |
| fold_iexpr f_itype f_ipat f_iexpr (IInst (e, c)) = |
|
247 |
f_iexpr e |
|
248 |
| fold_iexpr f_itype f_ipat f_iexpr (IAbs (v, e)) = |
|
249 |
f_iexpr e |
|
250 |
| fold_iexpr f_itype f_ipat f_iexpr (ICase (e, ps)) = |
|
251 |
f_iexpr e #> fold (fn (p, e) => f_ipat p #> f_iexpr e) ps |
|
252 |
| fold_iexpr _ _ _ (e as IConst _) = |
|
253 |
I |
|
254 |
| fold_iexpr _ _ _ (e as IVarE _) = |
|
255 |
I; |
|
256 |
||
18169
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
257 |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
258 |
(* simple diagnosis *) |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
259 |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
260 |
fun pretty_itype (IType (tyco, tys)) = |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
261 |
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
|
262 |
| pretty_itype (IFun (ty1, ty2)) = |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
263 |
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
|
264 |
| pretty_itype (IVarT (v, sort)) = |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
265 |
Pretty.str (v ^ enclose "|" "|" (space_implode "|" sort)) |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
266 |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
267 |
fun pretty_ipat (ICons ((cons, ps), ty)) = |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
268 |
Pretty.gen_list " " "(" ")" |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
269 |
(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
|
270 |
| pretty_ipat (IVarP (v, ty)) = |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
271 |
Pretty.block [Pretty.str ("?" ^ v ^ "::"), pretty_itype ty] |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
272 |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
273 |
fun pretty_iexpr (IConst (f, ty)) = |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
274 |
Pretty.block [Pretty.str (f ^ "::"), pretty_itype ty] |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
275 |
| pretty_iexpr (IVarE (v, ty)) = |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
276 |
Pretty.block [Pretty.str ("?" ^ v ^ "::"), pretty_itype ty] |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
277 |
| pretty_iexpr (IApp (e1, e2)) = |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
278 |
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
|
279 |
| pretty_iexpr (IInst (e, c)) = |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
280 |
pretty_iexpr e |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
281 |
| pretty_iexpr (IAbs ((v, ty), e)) = |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
282 |
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
|
283 |
| pretty_iexpr (ICase (e, cs)) = |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
284 |
Pretty.enclose "(" ")" [ |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
285 |
Pretty.str "case ", |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
286 |
pretty_iexpr e, |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
287 |
Pretty.enclose "(" ")" (map (fn (p, e) => |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
288 |
Pretty.block [ |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
289 |
pretty_ipat p, |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
290 |
Pretty.str " => ", |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
291 |
pretty_iexpr e |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
292 |
] |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
293 |
) cs) |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
294 |
] |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
295 |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
296 |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
297 |
(* language auxiliary *) |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
298 |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
299 |
fun itype_of_iexpr (IConst (_, ty)) = ty |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
300 |
| itype_of_iexpr (IVarE (_, ty)) = ty |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
301 |
| 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
|
302 |
of (IFun (ty2, ty')) => |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
303 |
if ty2 = itype_of_iexpr e2 |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
304 |
then ty' |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
305 |
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
|
306 |
^ ", " ^ (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
|
307 |
| _ => error ("expression is not a function: " ^ Pretty.output (pretty_iexpr e1))) |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
308 |
| itype_of_iexpr (IInst (e, cs)) = error "" |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
309 |
| 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
|
310 |
| itype_of_iexpr (ICase ((_, [(_, e)]))) = itype_of_iexpr e; |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
311 |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
312 |
fun itype_of_ipat (ICons (_, ty)) = ty |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
313 |
| itype_of_ipat (IVarP (_, ty)) = ty |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
314 |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
315 |
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
|
316 |
| ipat_of_iexpr (IVarE v) = IVarP v |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
317 |
| ipat_of_iexpr (e as IApp _) = |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
318 |
case unfold_app e of (IConst (f, ty), es) => |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
319 |
ICons ((f, map ipat_of_iexpr es), (snd o unfold_fun) ty); |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
320 |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
321 |
fun vars_of_ipats ps = |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
322 |
let |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
323 |
fun vars (ICons ((_, ps), _)) = fold vars ps |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
324 |
| vars (IVarP (v, _)) = cons v |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
325 |
in fold vars ps [] end; |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
326 |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
327 |
fun instant_itype (v, sty) ty = |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
328 |
let |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
329 |
fun instant (IType (tyco, tys)) = |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
330 |
tyco `%% map instant tys |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
331 |
| instant (IFun (ty1, ty2)) = |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
332 |
instant ty1 `-> instant ty2 |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
333 |
| instant (w as (IVarT (u, _))) = |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
334 |
if v = u then sty else w |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
335 |
in instant ty end; |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
336 |
|
18172 | 337 |
fun invent_var_t_names tys n used a = |
18169
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
338 |
let |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
339 |
fun invent (IType (_, tys)) = |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
340 |
fold invent tys |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
341 |
| invent (IFun (ty1, ty2)) = |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
342 |
invent ty1 #> invent ty2 |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
343 |
| invent (IVarT (v, _)) = |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
344 |
cons v |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
345 |
in Term.invent_names (fold invent tys used) a n end; |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
346 |
|
18172 | 347 |
fun invent_var_e_names es n used a = |
18169
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
348 |
let |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
349 |
fun invent (IConst (f, _)) = |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
350 |
I |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
351 |
| invent (IVarE (v, _)) = |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
352 |
cons v |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
353 |
| invent (IApp (e1, e2)) = |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
354 |
invent e1 #> invent e2 |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
355 |
| invent (IAbs ((v, _), e)) = |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
356 |
cons v #> invent e |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
357 |
| invent (ICase (e, cs)) = |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
358 |
invent e |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
359 |
#> |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
360 |
fold (fn (p, e) => append (vars_of_ipats [p]) #> invent e) cs |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
361 |
in Term.invent_names (fold invent es used) a n end; |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
362 |
|
18170 | 363 |
|
364 |
(** language module system - definitions, modules, transactions **) |
|
365 |
||
366 |
||
367 |
||
368 |
(* type definitions *) |
|
369 |
||
370 |
datatype def = |
|
371 |
Nop |
|
372 |
| Fun of (ipat list * iexpr) list * (ClassPackage.sortcontext * itype) |
|
18172 | 373 |
| Typesyn of (vname * string list) list * itype |
374 |
| Datatype of (vname * string list) list * string list * string list |
|
375 |
| Datatypecons of string * itype list |
|
18170 | 376 |
| Class of string list * string list * string list |
377 |
| Classmember of string * string * itype |
|
378 |
| Classinst of string * (string * string list list) * (string * string) list; |
|
379 |
||
380 |
datatype node = Def of def | Module of node Graph.T; |
|
381 |
type module = node Graph.T; |
|
382 |
type transact = Graph.key list * module; |
|
383 |
datatype 'dst transact_res = Succeed of 'dst | Fail of string; |
|
384 |
type 'dst transact_fin = 'dst transact_res * transact; |
|
385 |
type ('src, 'dst) gen_codegen = 'src -> transact -> 'dst transact_fin; |
|
386 |
type gen_defgen = string -> transact -> (def * string list) transact_fin; |
|
387 |
exception FAIL of string; |
|
388 |
||
389 |
val eq_def = (op =); |
|
390 |
||
391 |
(* simple diagnosis *) |
|
392 |
||
393 |
fun pretty_def Nop = |
|
394 |
Pretty.str "<NOP>" |
|
395 |
| pretty_def (Fun (eqs, (_, ty))) = |
|
396 |
Pretty.gen_list " |" "" "" ( |
|
397 |
map (fn (ps, body) => |
|
398 |
Pretty.block [ |
|
399 |
Pretty.gen_list "," "[" "]" (map pretty_ipat ps), |
|
400 |
Pretty.str " |->", |
|
401 |
Pretty.brk 1, |
|
402 |
pretty_iexpr body, |
|
403 |
Pretty.str "::", |
|
404 |
pretty_itype ty |
|
405 |
]) eqs |
|
406 |
) |
|
18172 | 407 |
| pretty_def (Typesyn (vs, ty)) = |
18170 | 408 |
Pretty.block [ |
409 |
Pretty.list "(" ")" (map (pretty_itype o IVarT) vs), |
|
410 |
Pretty.str " |=> ", |
|
411 |
pretty_itype ty |
|
412 |
] |
|
18172 | 413 |
| pretty_def (Datatype (vs, cs, clss)) = |
18170 | 414 |
Pretty.block [ |
415 |
Pretty.list "(" ")" (map (pretty_itype o IVarT) vs), |
|
416 |
Pretty.str " |=> ", |
|
417 |
Pretty.gen_list " |" "" "" (map Pretty.str cs), |
|
418 |
Pretty.str ", instance of ", |
|
419 |
Pretty.gen_list "," "[" "]" (map Pretty.str clss) |
|
420 |
] |
|
18172 | 421 |
| pretty_def (Datatypecons (dtname, tys)) = |
18170 | 422 |
Pretty.block [ |
423 |
Pretty.str "cons ", |
|
424 |
Pretty.gen_list " ->" "" "" (map pretty_itype tys @ [Pretty.str dtname]) |
|
425 |
] |
|
426 |
| pretty_def (Class (supcls, mems, insts)) = |
|
427 |
Pretty.str "Class ..." |
|
428 |
| pretty_def (Classmember (cls, v, ty)) = |
|
429 |
Pretty.str "Classmember ..." |
|
430 |
| pretty_def (Classinst (cls, insts, mems)) = |
|
431 |
Pretty.str "Classinst ..." |
|
432 |
||
433 |
fun pretty_module modl = |
|
434 |
let |
|
435 |
fun pretty (name, Module modl) = |
|
436 |
Pretty.block ( |
|
437 |
Pretty.str ("module " ^ name ^ " {") |
|
438 |
:: Pretty.brk 1 |
|
439 |
:: Pretty.chunks (map pretty (AList.make (Graph.get_node modl) |
|
440 |
(Graph.strong_conn modl |> List.concat |> rev))) |
|
441 |
:: Pretty.str "}" :: nil |
|
442 |
) |
|
443 |
| pretty (name, Def def) = |
|
444 |
Pretty.block [Pretty.str name, Pretty.str " :=", Pretty.brk 1, pretty_def def] |
|
445 |
in pretty ("//", Module modl) end; |
|
446 |
||
447 |
||
448 |
(* name handling *) |
|
449 |
||
450 |
fun dest_name name = |
|
451 |
let |
|
452 |
val name' = NameSpace.unpack name |
|
453 |
val (name'', name_base) = split_last name' |
|
454 |
val (modl, shallow) = split_last name'' |
|
455 |
in (modl, NameSpace.pack [shallow, name_base]) end |
|
456 |
handle Empty => error ("not a qualified name: " ^ quote name); |
|
457 |
||
458 |
fun dest_modl (Module m) = m; |
|
459 |
fun dest_def (Def d) = d; |
|
460 |
||
461 |
||
462 |
(* modules *) |
|
463 |
||
464 |
val empty_module = Graph.empty; (*read: "depends on"*) |
|
465 |
||
466 |
fun get_def modl name = |
|
467 |
case dest_name name |
|
468 |
of (modlname, base) => |
|
469 |
let |
|
470 |
fun get (Module node) [] = |
|
471 |
(dest_def o Graph.get_node node) base |
|
472 |
| get (Module node) (m::ms) = |
|
473 |
get (Graph.get_node node m) ms |
|
474 |
in get (Module modl) modlname end; |
|
475 |
||
476 |
fun add_def (name, def) = |
|
477 |
let |
|
478 |
val (modl, base) = dest_name name; |
|
479 |
fun add [] = |
|
480 |
Graph.new_node (base, Def def) |
|
481 |
| add (m::ms) = |
|
482 |
Graph.default_node (m, Module empty_module) |
|
483 |
#> Graph.map_node m (Module o add ms o dest_modl) |
|
484 |
in add modl end; |
|
485 |
||
486 |
fun map_def name f = |
|
487 |
let |
|
488 |
val (modl, base) = dest_name name; |
|
489 |
fun mapp [] = |
|
490 |
Graph.map_node base (Def o f o dest_def) |
|
491 |
| mapp (m::ms) = |
|
492 |
Graph.map_node m (Module o mapp ms o dest_modl) |
|
493 |
in mapp modl end; |
|
494 |
||
495 |
fun add_dep (name1, name2) modl = |
|
496 |
if name1 = name2 then modl |
|
497 |
else |
|
498 |
let |
|
499 |
val m1 = dest_name name1 |> apsnd single |> (op @); |
|
500 |
val m2 = dest_name name2 |> apsnd single |> (op @); |
|
501 |
val (ms, r1, r2) = get_prefix (op =) (m1, m2); |
|
502 |
val (ms, s1::r1, s2::r2) = get_prefix (op =) (m1, m2); |
|
503 |
val add_edge = |
|
504 |
if null r1 andalso null r2 |
|
505 |
then Graph.add_edge |
|
506 |
else Graph.add_edge_acyclic |
|
507 |
fun add [] node = |
|
508 |
node |
|
509 |
|> add_edge (s1, s2) |
|
510 |
| add (m::ms) node = |
|
511 |
node |
|
512 |
|> Graph.map_node m (Module o add ms o dest_modl); |
|
513 |
in add ms modl end; |
|
514 |
||
515 |
fun map_defs f = |
|
516 |
let |
|
517 |
fun mapp (Def def) = |
|
518 |
(Def o f) def |
|
519 |
| mapp (Module modl) = |
|
520 |
(Module o Graph.map_nodes mapp) modl |
|
521 |
in dest_modl o mapp o Module end; |
|
522 |
||
523 |
fun fold_defs f = |
|
524 |
let |
|
525 |
fun fol prfix (name, Def def) = |
|
526 |
f (NameSpace.pack (prfix @ [name]), def) |
|
527 |
| fol prfix (name, Module modl) = |
|
528 |
Graph.fold_nodes (fol (prfix @ [name])) modl |
|
529 |
in Graph.fold_nodes (fol []) end; |
|
530 |
||
531 |
fun add_deps f modl = |
|
532 |
modl |
|
533 |
|> fold add_dep ([] |> fold_defs (append o f) modl); |
|
534 |
||
535 |
fun fold_map_defs f = |
|
536 |
let |
|
537 |
fun foldmap prfix (name, Def def) = |
|
538 |
apfst Def o f (NameSpace.pack (prfix @ [name]), def) |
|
539 |
| foldmap prfix (name, Module modl) = |
|
540 |
apfst Module o Graph.fold_map_nodes (foldmap (prfix @ [name])) modl |
|
541 |
in Graph.fold_map_nodes (foldmap []) end; |
|
542 |
||
18172 | 543 |
fun map_def_fun f_ipat f_iexpr (Fun (eqs, cty)) = |
544 |
Fun (map (fn (ps, rhs) => (map f_ipat ps, f_iexpr rhs)) eqs, cty) |
|
545 |
| map_def_fun _ _ def = def; |
|
546 |
||
547 |
fun transform_defs f_def f_ipat f_iexpr s modl = |
|
548 |
let |
|
549 |
val (modl', s') = fold_map_defs f_def modl s |
|
550 |
in |
|
551 |
modl' |
|
552 |
|> map_defs (map_def_fun (f_ipat s') (f_iexpr s')) |
|
553 |
end; |
|
554 |
||
18170 | 555 |
fun merge_module modl12 = |
556 |
let |
|
557 |
fun join_module (Module m1, Module m2) = |
|
558 |
(SOME o Module) (merge_module (m1, m2)) |
|
559 |
| join_module (Def d1, Def d2) = |
|
560 |
if eq_def (d1, d2) then (SOME o Def) d1 else NONE |
|
561 |
| join_module _ = |
|
562 |
NONE |
|
563 |
in Graph.join (K join_module) modl12 end; |
|
564 |
||
565 |
fun partof names modl = |
|
566 |
let |
|
567 |
datatype pathnode = PN of (string list * (string * pathnode) list); |
|
18172 | 568 |
fun mk_ipath ([], base) (PN (defs, modls)) = |
18170 | 569 |
PN (base :: defs, modls) |
18172 | 570 |
| mk_ipath (n::ns, base) (PN (defs, modls)) = |
18170 | 571 |
modls |
572 |
|> AList.default (op =) (n, PN ([], [])) |
|
18172 | 573 |
|> AList.map_entry (op =) n (mk_ipath (ns, base)) |
18170 | 574 |
|> (pair defs #> PN); |
575 |
fun select (PN (defs, modls)) (Module module) = |
|
576 |
module |
|
577 |
|> Graph.subgraph (Graph.all_succs module (defs @ map fst modls)) |
|
578 |
|> fold (fn (name, modls) => Graph.map_node name (select modls)) modls |
|
579 |
|> Module; |
|
580 |
in |
|
581 |
Module modl |
|
18172 | 582 |
|> select (fold (mk_ipath o dest_name) (filter NameSpace.is_qualified names) (PN ([], []))) |
18170 | 583 |
|> dest_modl |
584 |
end; |
|
585 |
||
18172 | 586 |
fun add_check_transform (name, (Datatypecons (dtname, _))) = |
18170 | 587 |
([([dtname], |
18172 | 588 |
fn [Datatype (_, _, [])] => NONE | _ => "attempted to add constructor to already instantiating datatype" |> SOME)], |
18170 | 589 |
[(dtname, |
18172 | 590 |
fn Datatype (vs, cs, clss) => Datatype (vs, name::cs, clss) |
18170 | 591 |
| def => "attempted to add datatype constructor to non-datatype: " |
592 |
^ (Pretty.output o pretty_def) def |> error)]) |
|
593 |
| add_check_transform (name, Classmember (clsname, v, ty)) = |
|
594 |
let |
|
595 |
fun check_var (IType (tyco, tys)) s = |
|
596 |
fold check_var tys s |
|
597 |
| check_var (IFun (ty1, ty2)) s = |
|
598 |
s |
|
599 |
|> check_var ty1 |
|
600 |
|> check_var ty2 |
|
601 |
| check_var (IVarT (w, sort)) s = |
|
602 |
if v = w |
|
603 |
andalso member (op =) sort clsname |
|
604 |
then "additional class appears at type variable" |> SOME |
|
605 |
else NONE |
|
606 |
in |
|
607 |
([([], fn [] => check_var ty NONE), |
|
608 |
([clsname], |
|
609 |
fn [Class (_, _, [])] => NONE |
|
610 |
| _ => "attempted to add class member to witnessed class" |> SOME)], |
|
611 |
[(clsname, |
|
612 |
fn Class (supcs, mems, insts) => Class (supcs, name::mems, insts) |
|
613 |
| def => "attempted to add class member to non-class" |
|
614 |
^ (Pretty.output o pretty_def) def |> error)]) |
|
615 |
end |
|
616 |
| add_check_transform (name, Classinst (clsname, (tyco, arity), memdefs)) = |
|
617 |
let |
|
618 |
fun check [Classmember (_, v, mtyp_c), Fun (_, (_, mtyp_i))] = |
|
619 |
let |
|
620 |
val mtyp_i' = instant_itype (v, tyco `%% |
|
18172 | 621 |
map2 IVarT ((invent_var_t_names [mtyp_c] (length arity) [] "a"), arity)) mtyp_c; |
18170 | 622 |
in if eq_itype (mtyp_i', mtyp_i) (*! PERHAPS TOO STRICT !*) |
623 |
then NONE |
|
624 |
else "wrong type signature for class member: " |
|
625 |
^ (Pretty.output o pretty_itype) mtyp_i' ^ " expected," |
|
626 |
^ (Pretty.output o pretty_itype) mtyp_i ^ " given" |> SOME end |
|
627 |
in |
|
628 |
(map (fn (memname, memprim) => ((writeln memname; writeln memprim; [memname, memprim]), check)) memdefs, |
|
629 |
[(clsname, |
|
630 |
fn Class (supcs, mems, insts) => Class (supcs, mems, name::insts) |
|
631 |
| def => "attempted to add class instance to non-class" |
|
632 |
^ (Pretty.output o pretty_def) def |> error), |
|
633 |
(tyco, |
|
18172 | 634 |
fn Datatype (vs, cs, clss) => Datatype (vs, cs, clsname::clss) |
18170 | 635 |
| Nop => Nop |
636 |
| def => "attempted to instantiate non-type to class instance" |
|
637 |
^ (Pretty.output o pretty_def) def |> error)]) |
|
638 |
end |
|
639 |
| add_check_transform _ = ([], []); |
|
640 |
||
641 |
fun succeed some = (pair o Succeed) some; |
|
642 |
fun fail msg = (pair o Fail) msg; |
|
643 |
||
644 |
fun check_fail msg' (Succeed dst, trns) = (dst, trns) |
|
645 |
| check_fail msg' (Fail errmsg, _) = (tracing ("ROLLBACK CHECK: " ^ errmsg ^ "\n" ^ msg'); raise FAIL errmsg); |
|
646 |
||
647 |
fun handle_fail msg f modl = |
|
648 |
f modl handle FAIL msg' => ([], modl) |> fail (msg ^ "\n" ^ msg'); |
|
649 |
||
650 |
fun select_generator print_msg src [] trns = |
|
651 |
fail ("no code generator available") trns |
|
652 |
| select_generator print_msg src [(gname, cgen)] trns = |
|
653 |
(print_msg gname; cgen src trns) |
|
654 |
| select_generator print_msg src ((gname, cgen)::cgens) trns = |
|
655 |
case cgen src trns |
|
656 |
of result as (Succeed _, _) => |
|
657 |
(print_msg gname; result) |
|
658 |
| _ => select_generator print_msg src cgens trns |
|
659 |
||
660 |
fun gen_invoke codegens msg src (deps, modl) = |
|
661 |
([], modl) |
|
662 |
|> select_generator (fn gname => "choosing code generator " ^ gname ^ " for source " ^ quote msg) |
|
663 |
src codegens |
|
664 |
|> check_fail msg |
|
665 |
||> (fn (deps', modl') => (append deps' deps, modl')); |
|
666 |
||
667 |
fun gen_ensure_def defgens msg name (deps, modl) = |
|
668 |
let |
|
669 |
fun add (name, def) (deps, modl) = |
|
670 |
let |
|
671 |
val (checks, trans) = add_check_transform (name, def); |
|
672 |
fun check (check_defs, checker) modl = |
|
673 |
case checker (check_defs |> filter NameSpace.is_qualified |> map (get_def modl)) |
|
674 |
of NONE => modl |
|
675 |
| SOME e => raise FAIL e; |
|
676 |
fun transform (name, f) modl = |
|
677 |
modl |
|
678 |
|> K (NameSpace.is_qualified name) ? map_def name f; |
|
679 |
in |
|
680 |
modl |
|
681 |
|> fold check checks |
|
682 |
|> fold (curry add_dep name) deps |
|
683 |
|> map_def name (fn _ => def) |
|
684 |
|> fold transform trans |
|
685 |
end; |
|
686 |
fun ensure_node name modl = |
|
687 |
if can (get_def modl) name |
|
688 |
then ([name], modl) |
|
689 |
else |
|
690 |
([], modl |> add_def (name, Nop)) |
|
691 |
|> select_generator (fn gname => "choosing code generator " ^ gname ^ " for definition of " ^ quote name) |
|
692 |
name defgens |
|
693 |
|> check_fail msg |
|
694 |
|-> (fn (def, names') => |
|
695 |
add (name, def) |
|
696 |
#> fold_map ensure_node names') |
|
697 |
|-> (fn names' => pair (name :: Library.flat names')) |
|
698 |
in |
|
699 |
modl |
|
700 |
|> ensure_node name |
|
701 |
|-> (fn names => pair (names@deps)) |
|
702 |
end; |
|
703 |
||
18172 | 704 |
|
705 |
||
706 |
(** primitive language constructs **) |
|
707 |
||
708 |
val class_eq = "Eqtype"; (*defined for all primitve types and extensionally for all datatypes*) |
|
709 |
val type_bool = "Bool"; |
|
710 |
val type_integer = "Integer"; (*infinite!*) |
|
711 |
val type_float = "Float"; |
|
712 |
val type_pair = "Pair"; |
|
713 |
val type_list = "List"; |
|
714 |
val cons_true = "True"; |
|
715 |
val cons_false = "False"; |
|
716 |
val cons_not = "not"; |
|
717 |
val cons_pair = "Pair"; |
|
718 |
val cons_nil = "Nil"; |
|
719 |
val cons_cons = "Cons"; |
|
720 |
val fun_primeq = "primeq"; (*defined for all primitive types*) |
|
721 |
val fun_eq = "eq"; (*to class eq*) |
|
722 |
val fun_not = "not"; |
|
723 |
val fun_and = "and"; |
|
724 |
val fun_or = "or"; |
|
725 |
val fun_if = "if"; |
|
726 |
val fun_fst = "fst"; |
|
727 |
val fun_snd = "snd"; |
|
728 |
val fun_add = "add"; |
|
729 |
val fun_mult = "mult"; |
|
730 |
val fun_minus = "minus"; |
|
731 |
val fun_lt = "lt"; |
|
732 |
val fun_le = "le"; |
|
733 |
val fun_wfrec = "wfrec"; |
|
734 |
||
735 |
local |
|
736 |
||
737 |
val A = IVarT ("a", []); |
|
738 |
val B = IVarT ("b", []); |
|
739 |
val E = IVarT ("e", [class_eq]); |
|
740 |
||
741 |
in |
|
742 |
||
743 |
val Type_bool = type_bool `%% []; |
|
744 |
val Type_integer = type_integer `%% []; |
|
745 |
val Type_float = type_float `%% []; |
|
746 |
fun Type_pair a b = type_pair `%% [a, b]; |
|
747 |
fun Type_list a = type_list `%% [a]; |
|
748 |
val Cons_true = IConst (cons_true, Type_bool); |
|
749 |
val Cons_false = IConst (cons_false, Type_bool); |
|
750 |
val Cons_pair = IConst (cons_pair, A `-> B `-> Type_pair A B); |
|
751 |
val Cons_nil = IConst (cons_nil, Type_list A); |
|
752 |
val Cons_cons = IConst (cons_cons, A `-> Type_list A `-> Type_list A); |
|
753 |
val Fun_eq = IConst (fun_eq, E `-> E `-> Type_bool); |
|
754 |
val Fun_not = IConst (fun_not, Type_bool `-> Type_bool); |
|
755 |
val Fun_and = IConst (fun_and, Type_bool `-> Type_bool `-> Type_bool); |
|
756 |
val Fun_or = IConst (fun_or, Type_bool `-> Type_bool `-> Type_bool); |
|
757 |
val Fun_if = IConst (fun_if, Type_bool `-> A `-> A `-> A); |
|
758 |
val Fun_fst = IConst (fun_fst, Type_pair A B `-> A); |
|
759 |
val Fun_snd = IConst (fun_snd, Type_pair A B `-> B); |
|
760 |
val Fun_0 = IConst ("0", Type_integer); |
|
761 |
val Fun_1 = IConst ("1", Type_integer); |
|
762 |
val Fun_add = IConst (fun_add, Type_integer `-> Type_integer `-> Type_integer); |
|
763 |
val Fun_mult = IConst (fun_mult, Type_integer `-> Type_integer `-> Type_integer); |
|
764 |
val Fun_minus = IConst (fun_minus, Type_integer `-> Type_integer); |
|
765 |
val Fun_lt = IConst (fun_lt, Type_integer `-> Type_integer `-> Type_bool); |
|
766 |
val Fun_le = IConst (fun_le, Type_integer `-> Type_integer `-> Type_bool); |
|
767 |
val Fun_wfrec = IConst (fun_wfrec, ((A `-> B) `-> A `-> B) `-> A `-> B); |
|
768 |
||
769 |
infix 7 xx; |
|
770 |
infix 5 **; |
|
771 |
infix 5 &&; |
|
772 |
||
773 |
fun a xx b = Type_pair a b; |
|
774 |
fun a ** b = |
|
775 |
let |
|
776 |
val ty_a = itype_of_iexpr a; |
|
777 |
val ty_b = itype_of_iexpr b; |
|
778 |
in IConst (cons_pair, ty_a `-> ty_b `-> ty_a xx ty_b) `$ a `$ b end; |
|
779 |
fun a && b = |
|
780 |
let |
|
781 |
val ty_a = itype_of_ipat a; |
|
782 |
val ty_b = itype_of_ipat b; |
|
783 |
in ICons ((cons_pair, [a, b]), ty_a xx ty_b) end; |
|
784 |
||
785 |
end; (* local *) |
|
786 |
||
787 |
val prims = [class_eq, type_bool, type_integer, type_float, type_pair, type_list, |
|
788 |
cons_true, cons_false, cons_pair, cons_nil, cons_cons, fun_primeq, fun_eq, fun_not, fun_and, |
|
789 |
fun_or, fun_if, fun_fst, fun_snd, fun_add, fun_mult, fun_minus, fun_lt, fun_le, fun_wfrec]; |
|
790 |
||
791 |
fun extract_defs e = |
|
792 |
let |
|
793 |
fun extr_itype (ty as IType (tyco, _)) = |
|
794 |
cons tyco #> fold_itype extr_itype ty |
|
795 |
| extr_itype ty = |
|
796 |
fold_itype extr_itype ty |
|
797 |
fun extr_ipat (p as ICons ((c, _), _)) = |
|
798 |
cons c #> fold_ipat extr_itype extr_ipat p |
|
799 |
| extr_ipat p = |
|
800 |
fold_ipat extr_itype extr_ipat p |
|
801 |
fun extr_iexpr (e as IConst (f, _)) = |
|
802 |
cons f #> fold_iexpr extr_itype extr_ipat extr_iexpr e |
|
803 |
| extr_iexpr e = |
|
804 |
fold_iexpr extr_itype extr_ipat extr_iexpr e |
|
805 |
in extr_iexpr e [] end; |
|
806 |
||
807 |
||
808 |
||
809 |
(** generic transformation **) |
|
810 |
||
811 |
fun eta_expand query = |
|
812 |
let |
|
813 |
fun eta_app ((f, ty), es) = |
|
814 |
let |
|
815 |
val delta = query f - length es; |
|
816 |
val add_n = if delta < 0 then 0 else delta; |
|
817 |
val add_vars = |
|
818 |
invent_var_e_names es add_n [] "x" ~~ Library.drop (length es, (fst o unfold_fun) ty); |
|
819 |
in |
|
820 |
Library.foldr IAbs (add_vars, IConst (f, ty) `$$ es `$$ (map IVarE add_vars)) |
|
821 |
end; |
|
822 |
fun eta_iexpr' e = map_iexpr I I eta_iexpr e |
|
823 |
and eta_iexpr (IConst (f, ty)) = |
|
824 |
eta_app ((f, ty), []) |
|
825 |
| eta_iexpr (e as IApp _) = |
|
826 |
(case (unfold_app e) |
|
827 |
of (IConst (f, ty), es) => |
|
828 |
eta_app ((f, ty), map eta_iexpr es) |
|
829 |
| _ => eta_iexpr' e) |
|
830 |
| eta_iexpr e = eta_iexpr' e; |
|
831 |
in map_defs (map_def_fun I eta_iexpr) end; |
|
832 |
||
833 |
fun connect_datatypes_clsdecls module = |
|
834 |
let |
|
835 |
fun extract_dep (name, Datatypecons (dtname, _)) = |
|
836 |
[(dtname, name)] |
|
837 |
| extract_dep (name, Classmember (cls, _, _)) = |
|
838 |
[(cls, name)] |
|
839 |
| extract_dep (name, def) = [] |
|
840 |
in add_deps extract_dep module end; |
|
841 |
||
842 |
fun tupelize_cons module = |
|
843 |
let |
|
844 |
fun replace_def (_, (def as Datatypecons (_, []))) acc = |
|
845 |
(def, acc) |
|
846 |
| replace_def (_, (def as Datatypecons (_, [_]))) acc = |
|
847 |
(def, acc) |
|
848 |
| replace_def (name, (Datatypecons (tyco, tys))) acc = |
|
849 |
(Datatypecons (tyco, |
|
850 |
[foldl' (op xx) (NONE, tys)]), name::acc) |
|
851 |
| replace_def (_, def) acc = (def, acc); |
|
852 |
fun replace_app cs ((f, ty), es) = |
|
853 |
if member (op =) cs f |
|
854 |
then |
|
855 |
let |
|
856 |
val (tys, ty') = unfold_fun ty |
|
857 |
in IConst (f, foldr' (op xx) (tys, NONE) `-> ty') `$ foldl' (op **) (NONE, es) end |
|
858 |
else IConst (f, ty) `$$ es; |
|
859 |
fun replace_iexpr cs (IConst (f, ty)) = |
|
860 |
replace_app cs ((f, ty), []) |
|
861 |
| replace_iexpr cs (e as IApp _) = |
|
862 |
(case unfold_app e |
|
863 |
of (IConst fty, es) => replace_app cs (fty, map (replace_iexpr cs) es) |
|
864 |
| _ => map_iexpr I I (replace_iexpr cs) e) |
|
865 |
| replace_iexpr cs e = map_iexpr I I (replace_iexpr cs) e; |
|
866 |
fun replace_ipat cs (p as ICons ((c, ps), ty)) = |
|
867 |
if member (op =) cs c then |
|
868 |
ICons ((c, [(foldl' (op &&) (NONE, map (replace_ipat cs) ps))]), ty) |
|
869 |
else map_ipat I (replace_ipat cs) p |
|
870 |
| replace_ipat cs p = map_ipat I (replace_ipat cs) p; |
|
871 |
in |
|
872 |
transform_defs replace_def replace_ipat replace_iexpr [cons_cons] module |
|
873 |
end; |
|
874 |
||
875 |
fun eliminate_dtconstr module = |
|
876 |
let |
|
877 |
fun replace_def (name, (Datatype (vs, cs, is))) acc = |
|
878 |
(Datatype (map (fn (v, _) => (v, [])) vs, cs, is), (name, vs)::acc) |
|
879 |
| replace_def (_, def) acc = (def, acc); |
|
880 |
fun constrain (ty as IType _, _) = |
|
881 |
ty |
|
882 |
| constrain (IVarT (v, sort1), (_, sort2)) = |
|
883 |
IVarT (v, gen_union (op =) (sort1, sort2)); |
|
884 |
fun replace_ty tycos (ty as (IType (tyco, tys))) = |
|
885 |
(case AList.lookup (op =) tycos tyco |
|
886 |
of NONE => ty |
|
887 |
| SOME vs => IType (tyco, map2 constrain (tys, vs))) |
|
888 |
| replace_ty tycos ty = |
|
889 |
map_itype (replace_ty tycos) ty; |
|
890 |
in |
|
891 |
transform_defs replace_def |
|
892 |
(*! HIER FEHLT NOCH: ÄNDERN VON TYP UND SORTCTXT BEI FUNS !*) |
|
893 |
(fn tycos => map_ipat (replace_ty tycos) I) |
|
894 |
(fn tycos => map_iexpr (replace_ty tycos) (map_ipat (replace_ty tycos) I) I) [] module |
|
895 |
end; |
|
896 |
||
897 |
fun eliminate_classes module = |
|
898 |
let |
|
899 |
fun mk_cls_typ_map memberdecls ty_inst = |
|
900 |
map (fn (memname, (v, ty)) => |
|
901 |
(memname, ty |> instant_itype (v, ty_inst))) memberdecls; |
|
902 |
fun transform_dicts (Class (supcls, members, insts)) = |
|
903 |
let |
|
904 |
val memberdecls = AList.make |
|
905 |
((fn Classmember (_, v, ty) => (v, ty)) o get_def module) members; |
|
906 |
val varname_cls = invent_var_t_names (map (snd o snd) memberdecls) 1 [] "a" |> hd; |
|
907 |
in |
|
908 |
Typesyn ([(varname_cls, [])], IDictT (mk_cls_typ_map memberdecls (IVarT (varname_cls, [])))) |
|
909 |
end |
|
910 |
| transform_dicts (Classinst (tyco, (cls, arity), memdefs)) = |
|
911 |
let |
|
912 |
val Class (_, members, _) = get_def module cls; |
|
913 |
val memberdecls = AList.make |
|
914 |
((fn Classmember (_, v, ty) => (v, ty)) o get_def module) members; |
|
915 |
val ty_arity = tyco `%% map IVarT (invent_var_t_names (map (snd o snd) memberdecls) |
|
916 |
(length arity) [] "a" ~~ arity); |
|
917 |
val inst_typ_map = mk_cls_typ_map memberdecls ty_arity; |
|
918 |
val memdefs_ty = map (fn (memname, memprim) => |
|
919 |
(memname, (memprim, (the o AList.lookup (op =) inst_typ_map) memname))) memdefs; |
|
920 |
in |
|
921 |
Fun ([([], IDictE (map (apsnd IConst) memdefs_ty))], |
|
922 |
([], IDictT inst_typ_map)) |
|
923 |
end |
|
924 |
| transform_dicts d = d |
|
925 |
fun transform_defs (Fun (ds, (sortctxt, ty))) = |
|
926 |
let |
|
927 |
fun reduce f xs = foldl' f (NONE, xs); |
|
928 |
val varnames_ctxt = |
|
929 |
sortctxt |
|
930 |
|> length o Library.flat o map snd |
|
931 |
|> (fn used => invent_var_e_names (map snd ds) used ((vars_of_ipats o fst o hd) ds) "d") |
|
932 |
|> unflat (map snd sortctxt); |
|
933 |
val vname_alist = map2 (fn ((vt, sort), vs) => (vt, vs ~~ sort)) (sortctxt, varnames_ctxt); |
|
934 |
fun add_typarms ty = |
|
935 |
map (reduce (op xx) o (fn (vt, vss) => map (fn (_, cls) => cls `%% [IVarT (vt, [])]) vss)) vname_alist |
|
936 |
`--> ty; |
|
937 |
fun add_parms ps = |
|
938 |
map (reduce (op &&) o (fn (vt, vss) => map (fn (v, cls) => IVarP (v, cls `%% [IVarT (vt, [])])) vss)) vname_alist |
|
939 |
@ ps; |
|
940 |
fun transform_itype (IVarT (v, s)) = |
|
941 |
IVarT (v, []) |
|
942 |
| transform_itype ty = |
|
943 |
map_itype transform_itype ty; |
|
944 |
fun transform_ipat p = |
|
945 |
map_ipat transform_itype transform_ipat p; |
|
946 |
fun transform_lookup (ClassPackage.Instance ((cdict, idict), ls)) = |
|
947 |
ls |
|
948 |
|> transform_lookups |
|
949 |
|-> (fn ty => |
|
950 |
curry mk_apps (IConst (idict, cdict `%% ty)) |
|
951 |
#> pair (cdict `%% ty)) |
|
952 |
| transform_lookup (ClassPackage.Lookup (deriv, (v, i))) = |
|
953 |
let |
|
954 |
val (v', cls) = |
|
955 |
(nth o the oo AList.lookup (op =)) vname_alist v i; |
|
956 |
fun mk_parm tyco = tyco `%% [IVarT (v, [])]; |
|
957 |
in (mk_parm (hd (deriv)), ILookup (rev deriv, v')) end |
|
958 |
and transform_lookups lss = |
|
959 |
map_yield (map_yield transform_lookup |
|
960 |
#> apfst (reduce (op xx)) |
|
961 |
#> apsnd (reduce (op **))) lss; |
|
962 |
fun transform_iexpr (IInst (e, ls)) = |
|
963 |
transform_iexpr e `$$ (snd o transform_lookups) ls |
|
964 |
| transform_iexpr e = |
|
965 |
map_iexpr transform_itype transform_ipat transform_iexpr e; |
|
966 |
fun transform_rhs (ps, rhs) = (add_parms ps, transform_iexpr rhs) |
|
967 |
in Fun (map transform_rhs ds, ([], add_typarms ty)) end |
|
968 |
| transform_defs d = d |
|
969 |
in |
|
970 |
module |
|
971 |
|> map_defs transform_dicts |
|
972 |
|> map_defs transform_defs |
|
973 |
end; |
|
974 |
||
18169
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
975 |
end; (* struct *) |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
976 |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
977 |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
978 |
structure CodegenThingol : CODEGEN_THINGOL = |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
979 |
struct |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
980 |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
981 |
open CodegenThingolOp; |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
982 |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
983 |
end; (* struct *) |