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