22 | Lookup of class list * (vname * int); |
22 | Lookup of class list * (vname * int); |
23 datatype itype = |
23 datatype itype = |
24 `%% of string * itype list |
24 `%% of string * itype list |
25 | `-> of itype * itype |
25 | `-> of itype * itype |
26 | ITyVar of vname; |
26 | ITyVar of vname; |
27 datatype iexpr = |
27 datatype iterm = |
28 IConst of string * (iclasslookup list list * itype) |
28 IConst of string * (iclasslookup list list * itype) |
29 | IVar of vname |
29 | IVar of vname |
30 | `$ of iexpr * iexpr |
30 | `$ of iterm * iterm |
31 | `|-> of (vname * itype) * iexpr |
31 | `|-> of (vname * itype) * iterm |
32 | INum of IntInf.int (*non-negative!*) * iexpr |
32 | INum of IntInf.int (*non-negative!*) * iterm |
33 | IChar of string (*length one!*) * iexpr |
33 | IChar of string (*length one!*) * iterm |
34 | IAbs of ((iexpr * itype) * iexpr) * iexpr |
34 | ICase of ((iterm * itype) * (iterm * iterm) list) * iterm; |
35 (* (((binding expression (ve), binding type (vty)), |
|
36 body expression (be)), native expression (e0)) *) |
|
37 | ICase of ((iexpr * itype) * (iexpr * iexpr) list) * iexpr; |
|
38 (* ((discrimendum expression (de), discrimendum type (dty)), |
35 (* ((discrimendum expression (de), discrimendum type (dty)), |
39 [(selector expression (se), body expression (be))]), |
36 [(selector expression (se), body expression (be))]), |
40 native expression (e0)) *) |
37 native expression (e0)) *) |
41 end; |
38 end; |
42 |
39 |
43 signature CODEGEN_THINGOL = |
40 signature CODEGEN_THINGOL = |
44 sig |
41 sig |
45 include BASIC_CODEGEN_THINGOL; |
42 include BASIC_CODEGEN_THINGOL; |
46 val `--> : itype list * itype -> itype; |
43 val `--> : itype list * itype -> itype; |
47 val `$$ : iexpr * iexpr list -> iexpr; |
44 val `$$ : iterm * iterm list -> iterm; |
48 val `|--> : (vname * itype) list * iexpr -> iexpr; |
45 val `|--> : (vname * itype) list * iterm -> iterm; |
49 val pretty_itype: itype -> Pretty.T; |
46 val pretty_itype: itype -> Pretty.T; |
50 val pretty_iexpr: iexpr -> Pretty.T; |
47 val pretty_iterm: iterm -> Pretty.T; |
51 val unfoldl: ('a -> ('a * 'b) option) -> 'a -> 'a * 'b list; |
48 val unfoldl: ('a -> ('a * 'b) option) -> 'a -> 'a * 'b list; |
52 val unfoldr: ('a -> ('b * 'a) option) -> 'a -> 'b list * 'a; |
49 val unfoldr: ('a -> ('b * 'a) option) -> 'a -> 'b list * 'a; |
53 val unfold_fun: itype -> itype list * itype; |
50 val unfold_fun: itype -> itype list * itype; |
54 val unfold_app: iexpr -> iexpr * iexpr list; |
51 val unfold_app: iterm -> iterm * iterm list; |
55 val unfold_abs: iexpr -> (iexpr * itype) list * iexpr; |
52 val unfold_abs: iterm -> (iterm * itype) list * iterm; |
56 val unfold_let: iexpr -> ((iexpr * itype) * iexpr) list * iexpr; |
53 val unfold_let: iterm -> ((iterm * itype) * iterm) list * iterm; |
57 val unfold_const_app: iexpr -> |
54 val unfold_const_app: iterm -> |
58 ((string * (iclasslookup list list * itype)) * iexpr list) option; |
55 ((string * (iclasslookup list list * itype)) * iterm list) option; |
59 val add_constnames: iexpr -> string list -> string list; |
56 val add_constnames: iterm -> string list -> string list; |
60 val add_varnames: iexpr -> string list -> string list; |
57 val add_varnames: iterm -> string list -> string list; |
61 val is_pat: (string -> bool) -> iexpr -> bool; |
58 val is_pat: (string -> bool) -> iterm -> bool; |
62 val map_pure: (iexpr -> 'a) -> iexpr -> 'a; |
59 val vars_distinct: iterm list -> bool; |
63 val resolve_tycos: (string -> string) -> itype * iexpr list -> itype * iexpr list; |
60 val map_pure: (iterm -> 'a) -> iterm -> 'a; |
64 val resolve_consts: (string -> string) -> iexpr -> iexpr; |
61 val eta_expand: (string * (iclasslookup list list * itype)) * iterm list -> int -> iterm; |
65 val eta_expand: (string * (iclasslookup list list * itype)) * iexpr list -> int -> iexpr; |
62 val proper_name: string -> string; |
66 |
63 val invent_name: string list -> string; |
67 type funn = (iexpr list * iexpr) list * (sortcontext * itype); |
64 val give_names: string list -> 'a list -> (string * 'a) list; |
|
65 val resolve_tycos: (string -> string) -> itype * iterm list -> itype * iterm list; |
|
66 val resolve_consts: (string -> string) -> iterm -> iterm; |
|
67 |
|
68 type funn = (iterm list * iterm) list * (sortcontext * itype); |
68 type datatyp = sortcontext * (string * itype list) list; |
69 type datatyp = sortcontext * (string * itype list) list; |
69 datatype def = |
70 datatype def = |
70 Bot |
71 Bot |
71 | Fun of funn |
72 | Fun of funn |
72 | Typesyn of (vname * sort) list * itype |
73 | Typesyn of (vname * sort) list * itype |
129 case dest x |
130 case dest x |
130 of NONE => ([], x) |
131 of NONE => ([], x) |
131 | SOME (x1, x2) => |
132 | SOME (x1, x2) => |
132 let val (xs', x') = unfoldr dest x2 in (x1::xs', x') end; |
133 let val (xs', x') = unfoldr dest x2 in (x1::xs', x') end; |
133 |
134 |
134 fun map_yield f [] = ([], []) |
135 fun proper_name s = |
135 | map_yield f (x::xs) = |
136 let |
136 let |
137 fun replace_invalid c = |
137 val (y, x') = f x |
138 if (Char.isAlphaNum o the o Char.fromString) c orelse c = "'" |
138 val (ys, xs') = map_yield f xs |
139 andalso not (NameSpace.separator = c) |
139 in (y::ys, x'::xs') end; |
140 then c |
140 |
141 else "_"; |
141 fun get_prefix eq ([], ys) = ([], ([], ys)) |
142 fun contract "_" (acc as "_" :: _) = acc |
142 | get_prefix eq (xs, []) = ([], (xs, [])) |
143 | contract c acc = c :: acc; |
143 | get_prefix eq (xs as x::xs', ys as y::ys') = |
144 fun contract_underscores s = |
144 if eq (x, y) then |
145 implode (fold_rev contract (explode s) []); |
145 let val (ps', xys'') = get_prefix eq (xs', ys') |
146 fun ensure_char s = |
146 in (x::ps', xys'') end |
147 if forall (Char.isDigit o the o Char.fromString) (explode s) |
147 else ([], (xs, ys)); |
148 then prefix "x" s |
|
149 else s |
|
150 in |
|
151 s |
|
152 |> translate_string replace_invalid |
|
153 |> contract_underscores |
|
154 |> ensure_char |
|
155 end; |
148 |
156 |
149 |
157 |
150 (** language core - types, pattern, expressions **) |
158 (** language core - types, pattern, expressions **) |
151 |
159 |
152 (* language representation *) |
160 (* language representation *) |
161 datatype itype = |
169 datatype itype = |
162 `%% of string * itype list |
170 `%% of string * itype list |
163 | `-> of itype * itype |
171 | `-> of itype * itype |
164 | ITyVar of vname; |
172 | ITyVar of vname; |
165 |
173 |
166 datatype iexpr = |
174 datatype iterm = |
167 IConst of string * (iclasslookup list list * itype) |
175 IConst of string * (iclasslookup list list * itype) |
168 | IVar of vname |
176 | IVar of vname |
169 | `$ of iexpr * iexpr |
177 | `$ of iterm * iterm |
170 | `|-> of (vname * itype) * iexpr |
178 | `|-> of (vname * itype) * iterm |
171 | INum of IntInf.int (*non-negative!*) * iexpr |
179 | INum of IntInf.int * iterm |
172 | IChar of string (*length one!*) * iexpr |
180 | IChar of string * iterm |
173 | IAbs of ((iexpr * itype) * iexpr) * iexpr |
181 | ICase of ((iterm * itype) * (iterm * iterm) list) * iterm; |
174 | ICase of ((iexpr * itype) * (iexpr * iexpr) list) * iexpr; |
|
175 (*see also signature*) |
182 (*see also signature*) |
176 |
183 |
177 (* |
184 (* |
178 variable naming conventions |
185 variable naming conventions |
179 |
186 |
211 | pretty_itype (ty1 `-> ty2) = |
218 | pretty_itype (ty1 `-> ty2) = |
212 Pretty.enum "" "(" ")" [pretty_itype ty1, Pretty.str "->", pretty_itype ty2] |
219 Pretty.enum "" "(" ")" [pretty_itype ty1, Pretty.str "->", pretty_itype ty2] |
213 | pretty_itype (ITyVar v) = |
220 | pretty_itype (ITyVar v) = |
214 Pretty.str v; |
221 Pretty.str v; |
215 |
222 |
216 fun pretty_iexpr (IConst (c, _)) = |
223 fun pretty_iterm (IConst (c, _)) = |
217 Pretty.str c |
224 Pretty.str c |
218 | pretty_iexpr (IVar v) = |
225 | pretty_iterm (IVar v) = |
219 Pretty.str ("?" ^ v) |
226 Pretty.str ("?" ^ v) |
220 | pretty_iexpr (e1 `$ e2) = |
227 | pretty_iterm (e1 `$ e2) = |
221 (Pretty.enclose "(" ")" o Pretty.breaks) |
228 (Pretty.enclose "(" ")" o Pretty.breaks) |
222 [pretty_iexpr e1, pretty_iexpr e2] |
229 [pretty_iterm e1, pretty_iterm e2] |
223 | pretty_iexpr ((v, ty) `|-> e) = |
230 | pretty_iterm ((v, ty) `|-> e) = |
224 (Pretty.enclose "(" ")" o Pretty.breaks) |
231 (Pretty.enclose "(" ")" o Pretty.breaks) |
225 [Pretty.str v, Pretty.str "::", pretty_itype ty, Pretty.str "|->", pretty_iexpr e] |
232 [Pretty.str v, Pretty.str "::", pretty_itype ty, Pretty.str "|->", pretty_iterm e] |
226 | pretty_iexpr (INum (n, _)) = |
233 | pretty_iterm (INum (n, _)) = |
227 (Pretty.str o IntInf.toString) n |
234 (Pretty.str o IntInf.toString) n |
228 | pretty_iexpr (IChar (c, _)) = |
235 | pretty_iterm (IChar (c, _)) = |
229 (Pretty.str o quote) c |
236 (Pretty.str o quote) c |
230 | pretty_iexpr (IAbs (((e1, _), e2), _)) = |
237 | pretty_iterm (ICase (((e, _), cs), _)) = |
231 (Pretty.enclose "(" ")" o Pretty.breaks) |
|
232 [pretty_iexpr e1, Pretty.str "|->", pretty_iexpr e2] |
|
233 | pretty_iexpr (ICase (((e, _), cs), _)) = |
|
234 (Pretty.enclose "(" ")" o Pretty.breaks) [ |
238 (Pretty.enclose "(" ")" o Pretty.breaks) [ |
235 Pretty.str "case", |
239 Pretty.str "case", |
236 pretty_iexpr e, |
240 pretty_iterm e, |
237 Pretty.enclose "(" ")" (map (fn (p, e) => |
241 Pretty.enclose "(" ")" (map (fn (p, e) => |
238 (Pretty.block o Pretty.breaks) [ |
242 (Pretty.block o Pretty.breaks) [ |
239 pretty_iexpr p, |
243 pretty_iterm p, |
240 Pretty.str "=>", |
244 Pretty.str "=>", |
241 pretty_iexpr e |
245 pretty_iterm e |
242 ] |
246 ] |
243 ) cs) |
247 ) cs) |
244 ]; |
248 ]; |
245 |
249 |
246 val unfold_fun = unfoldr |
250 val unfold_fun = unfoldr |
250 val unfold_app = unfoldl |
254 val unfold_app = unfoldl |
251 (fn op `$ e => SOME e |
255 (fn op `$ e => SOME e |
252 | _ => NONE); |
256 | _ => NONE); |
253 |
257 |
254 val unfold_abs = unfoldr |
258 val unfold_abs = unfoldr |
255 (fn (v, ty) `|-> e => SOME ((IVar v, ty), e) |
259 (fn (v, ty) `|-> (e as ICase (((IVar w, _), [(se, be)]), _)) => |
256 | IAbs (((e1, ty), e2), _) => SOME ((e1, ty), e2) |
260 if v = w then SOME ((se, ty), be) else SOME ((IVar v, ty), e) |
|
261 | (v, ty) `|-> e => SOME ((IVar v, ty), e) |
257 | _ => NONE) |
262 | _ => NONE) |
258 |
263 |
259 val unfold_let = unfoldr |
264 val unfold_let = unfoldr |
260 (fn ICase (((de, dty), [(se, be)]), _) => SOME (((se, dty), de), be) |
265 (fn ICase (((de, dty), [(se, be)]), _) => SOME (((se, dty), de), be) |
261 | _ => NONE); |
266 | _ => NONE); |
361 insert (op =) v #> add_varnames e |
362 insert (op =) v #> add_varnames e |
362 | add_varnames (INum _) = |
363 | add_varnames (INum _) = |
363 I |
364 I |
364 | add_varnames (IChar _) = |
365 | add_varnames (IChar _) = |
365 I |
366 I |
366 | add_varnames (IAbs (((ve, _), be), _)) = |
|
367 add_varnames ve #> add_varnames be |
|
368 | add_varnames (ICase (((de, _), bses), _)) = |
367 | add_varnames (ICase (((de, _), bses), _)) = |
369 add_varnames de #> fold (fn (be, se) => add_varnames be #> add_varnames se) bses; |
368 add_varnames de #> fold (fn (be, se) => add_varnames be #> add_varnames se) bses; |
370 |
369 |
371 fun invent seed used = |
370 fun vars_distinct es = |
372 let |
371 let |
373 val x = Name.variant used seed |
372 fun distinct _ NONE = |
374 in (x, x :: used) end; |
373 NONE |
|
374 | distinct (IConst _) x = |
|
375 x |
|
376 | distinct (IVar v) (SOME vs) = |
|
377 if member (op =) vs v then NONE else SOME (v::vs) |
|
378 | distinct (e1 `$ e2) x = |
|
379 x |> distinct e1 |> distinct e2 |
|
380 | distinct (_ `|-> e) x = |
|
381 x |> distinct e |
|
382 | distinct (INum _) x = |
|
383 x |
|
384 | distinct (IChar _) x = |
|
385 x |
|
386 | distinct (ICase (((de, _), bses), _)) x = |
|
387 x |> distinct de |> fold (fn (be, se) => distinct be #> distinct se) bses; |
|
388 in is_some (fold distinct es (SOME [])) end; |
|
389 |
|
390 fun invent_name used = hd (Name.invent_list used "a" 1); |
|
391 |
|
392 fun give_names used xs = |
|
393 Name.invent_list used "a" (length xs) ~~ xs; |
375 |
394 |
376 fun eta_expand (c as (_, (_, ty)), es) k = |
395 fun eta_expand (c as (_, (_, ty)), es) k = |
377 let |
396 let |
378 val j = length es; |
397 val j = length es; |
379 val l = k - j; |
398 val l = k - j; |
380 val tys = (curry Library.take l o curry Library.drop j o fst o unfold_fun) ty; |
399 val tys = (curry Library.take l o curry Library.drop j o fst o unfold_fun) ty; |
381 val vs = [] |> fold add_varnames es |> fold_map invent (replicate l "x") |> fst; |
400 val vs_tys = give_names (fold add_varnames es []) tys; |
382 in vs ~~ tys `|--> IConst c `$$ es @ map IVar vs end; |
401 in vs_tys `|--> IConst c `$$ es @ map (fn (v, _) => IVar v) vs_tys end; |
383 |
402 |
384 |
403 |
385 |
404 |
386 (** language module system - definitions, modules, transactions **) |
405 (** language module system - definitions, modules, transactions **) |
387 |
406 |
388 (* type definitions *) |
407 (* type definitions *) |
389 |
408 |
390 type funn = (iexpr list * iexpr) list * (sortcontext * itype); |
409 type funn = (iterm list * iterm) list * (sortcontext * itype); |
391 type datatyp = sortcontext * (string * itype list) list; |
410 type datatyp = sortcontext * (string * itype list) list; |
392 |
411 |
393 datatype def = |
412 datatype def = |
394 Bot |
413 Bot |
395 | Fun of funn |
414 | Fun of funn |
613 if name1 = name2 then modl |
632 if name1 = name2 then modl |
614 else |
633 else |
615 let |
634 let |
616 val m1 = dest_name name1 |> apsnd single |> (op @); |
635 val m1 = dest_name name1 |> apsnd single |> (op @); |
617 val m2 = dest_name name2 |> apsnd single |> (op @); |
636 val m2 = dest_name name2 |> apsnd single |> (op @); |
618 val (ms, (r1, r2)) = get_prefix (op =) (m1, m2); |
637 val (ms, (r1, r2)) = chop_prefix (op =) (m1, m2); |
619 val (ms, (s1::r1, s2::r2)) = get_prefix (op =) (m1, m2); |
638 val (ms, (s1::r1, s2::r2)) = chop_prefix (op =) (m1, m2); |
620 val add_edge = |
639 val add_edge = |
621 if null r1 andalso null r2 |
640 if null r1 andalso null r2 |
622 then Graph.add_edge |
641 then Graph.add_edge |
623 else fn edge => fn gr => (Graph.add_edge_acyclic edge gr |
642 else fn edge => fn gr => (Graph.add_edge_acyclic edge gr |
624 handle Graph.CYCLES _ => |
643 handle Graph.CYCLES _ => |
977 val SOME (N (p', SOME tab')) = Symtab.lookup tab p |
996 val SOME (N (p', SOME tab')) = Symtab.lookup tab p |
978 val (ps', tab'') = get_path_name ps tab' |
997 val (ps', tab'') = get_path_name ps tab' |
979 in (p' :: ps', tab'') end; |
998 in (p' :: ps', tab'') end; |
980 fun deresolv tab prefix name = |
999 fun deresolv tab prefix name = |
981 let |
1000 let |
982 val (common, (_, rem)) = get_prefix (op =) (prefix, NameSpace.unpack name); |
1001 val (common, (_, rem)) = chop_prefix (op =) (prefix, NameSpace.unpack name); |
983 val (_, SOME tab') = get_path_name common tab; |
1002 val (_, SOME tab') = get_path_name common tab; |
984 val (name', _) = get_path_name rem tab'; |
1003 val (name', _) = get_path_name rem tab'; |
985 in NameSpace.pack name' end; |
1004 in NameSpace.pack name' end; |
986 in deresolv (mk module (AList.make (K NameMangler.empty) nsp_conn) Symtab.empty) end; |
1005 in deresolv (mk module (AList.make (K NameMangler.empty) nsp_conn) Symtab.empty) end; |
987 |
1006 |