Commit | Line | Data |
---|---|---|
7f918cf1 CE |
1 | (* Copyright (C) 2009-2010,2015,2017 Matthew Fluet. |
2 | * Copyright (C) 1999-2007 Henry Cejtin, Matthew Fluet, Suresh | |
3 | * Jagannathan, and Stephen Weeks. | |
4 | * Copyright (C) 1997-2000 NEC Research Institute. | |
5 | * | |
6 | * MLton is released under a BSD-style license. | |
7 | * See the file MLton-LICENSE for details. | |
8 | *) | |
9 | ||
10 | functor ElaborateEnv (S: ELABORATE_ENV_STRUCTS): ELABORATE_ENV = | |
11 | struct | |
12 | ||
13 | open S | |
14 | ||
15 | local | |
16 | open Control.Elaborate | |
17 | in | |
18 | val warnUnused = fn () => current warnUnused | |
19 | end | |
20 | ||
21 | local | |
22 | open Layout | |
23 | in | |
24 | val align = align | |
25 | val alignPrefix = alignPrefix | |
26 | (* val empty = empty *) | |
27 | val mayAlign = mayAlign | |
28 | val seq = seq | |
29 | val str = str | |
30 | val bracket = fn l => | |
31 | seq [str "[", l, str "]"] | |
32 | end | |
33 | ||
34 | local | |
35 | open Ast | |
36 | in | |
37 | structure Basid = Basid | |
38 | structure Fctid = Fctid | |
39 | structure Strid = Strid | |
40 | structure Longtycon = Longtycon | |
41 | structure Priority = Priority | |
42 | structure Sigid = Sigid | |
43 | structure Strid = Strid | |
44 | structure Symbol = Symbol | |
45 | end | |
46 | ||
47 | fun layoutLong (ids: Layout.t list) = | |
48 | let | |
49 | open Layout | |
50 | in | |
51 | seq (separate (ids, ".")) | |
52 | end | |
53 | ||
54 | fun layoutStrids (ss: Strid.t list): Layout.t = | |
55 | layoutLong (List.map (ss, Strid.layout)) | |
56 | ||
57 | fun layoutLongRev (ss: Strid.t list, id: Layout.t) = | |
58 | (seq o List.fold) | |
59 | (ss, [id], fn (s, ls) => | |
60 | Strid.layout s :: str "." :: ls) | |
61 | fun toStringLongRev (ss: Strid.t list, id: Layout.t) = | |
62 | Layout.toString (layoutLongRev (ss, id)) | |
63 | ||
64 | local | |
65 | open CoreML | |
66 | in | |
67 | structure Con = Con | |
68 | structure Dec = Dec | |
69 | structure Exp = Exp | |
70 | structure Pat = Pat | |
71 | structure Tycon = Tycon | |
72 | structure Tyvar = Tyvar | |
73 | structure Var = Var | |
74 | end | |
75 | ||
76 | local | |
77 | open Tycon | |
78 | in | |
79 | structure AdmitsEquality = AdmitsEquality | |
80 | structure Kind = Kind | |
81 | structure Symbol = Symbol | |
82 | end | |
83 | ||
84 | local | |
85 | open TypeEnv | |
86 | in | |
87 | structure Scheme = Scheme | |
88 | structure Type = Type | |
89 | end | |
90 | ||
91 | structure Decs = Decs (structure CoreML = CoreML) | |
92 | ||
93 | structure Tycon = | |
94 | struct | |
95 | open Tycon | |
96 | open TypeEnv.TyconExt | |
97 | end | |
98 | ||
99 | structure Tyvar = | |
100 | struct | |
101 | open Tyvar | |
102 | open TypeEnv.TyvarExt | |
103 | fun fromAst a = | |
104 | makeString (Ast.Tyvar.toString a, | |
105 | {equality = Ast.Tyvar.isEquality a}) | |
106 | end | |
107 | ||
108 | structure TyvarEnv = | |
109 | struct | |
110 | datatype t = T of {cur: (Ast.Tyvar.t * Tyvar.t) list ref, | |
111 | get: Ast.Tyvar.t -> Tyvar.t list ref} | |
112 | fun new () = | |
113 | let | |
114 | val {get: Ast.Tyvar.t -> Tyvar.t list ref, ...} = | |
115 | Property.get | |
116 | (Symbol.plist o Ast.Tyvar.toSymbol, | |
117 | Property.initFun (fn _ => ref [])) | |
118 | val cur = ref [] | |
119 | in | |
120 | T {get = get, cur = cur} | |
121 | end | |
122 | fun peekTyvar (T {get, ...}, a) = | |
123 | case !(get a) of | |
124 | [] => NONE | |
125 | | a'::_ => SOME a' | |
126 | fun lookupTyvar (env, a) = | |
127 | case peekTyvar (env, a) of | |
128 | NONE => | |
129 | let | |
130 | val _ = | |
131 | Control.error | |
132 | (Ast.Tyvar.region a, | |
133 | seq [str "undefined type variable: ", | |
134 | Ast.Tyvar.layout a], | |
135 | Layout.empty) | |
136 | in | |
137 | NONE | |
138 | end | |
139 | | SOME tv => SOME tv | |
140 | fun scope (T {cur, get, ...}, bs, th) = | |
141 | let | |
142 | val bs' = Vector.map (bs, Tyvar.fromAst) | |
143 | val () = | |
144 | Vector.foreach2 | |
145 | (bs, bs', fn (b, b') => | |
146 | (List.push (cur, (b, b')) | |
147 | ; List.push (get b, b'))) | |
148 | val res = th bs' | |
149 | val () = | |
150 | Vector.foreach | |
151 | (bs, fn b => | |
152 | (ignore (List.pop cur) | |
153 | ; ignore (List.pop (get b)))) | |
154 | in | |
155 | res | |
156 | end | |
157 | ||
158 | val E = new () | |
159 | val lookupTyvar = fn a => | |
160 | lookupTyvar (E, a) | |
161 | val scope = fn (bs, th) => | |
162 | scope (E, bs, th) | |
163 | (* | |
164 | val makeLayoutPretty = fn () => | |
165 | let | |
166 | val {destroy, get = layoutPretty, set = setLayoutPretty, ...} = | |
167 | Property.destGetSet | |
168 | (Tyvar.plist, Property.initFun Tyvar.layout) | |
169 | val T {cur, ...} = E | |
170 | val pre = fn () => | |
171 | List.foreach | |
172 | (!cur, fn (a, a') => | |
173 | setLayoutPretty (a', Ast.Tyvar.layout a)) | |
174 | val pre = ClearablePromise.delay pre | |
175 | val destroy = fn () => | |
176 | (ClearablePromise.clear pre | |
177 | ; destroy ()) | |
178 | val layoutPretty = fn a' => | |
179 | (ClearablePromise.force pre | |
180 | ; layoutPretty a') | |
181 | in | |
182 | {destroy = destroy, | |
183 | layoutPretty = layoutPretty} | |
184 | end | |
185 | *) | |
186 | val makeLayoutPretty = fn () => | |
187 | let | |
188 | fun layoutPretty a' = | |
189 | let | |
190 | val T {cur, ...} = E | |
191 | in | |
192 | case List.peek (!cur, fn (_, b') => Tyvar.equals (a', b')) of | |
193 | NONE => Tyvar.layout a' | |
194 | | SOME (a, _) => Ast.Tyvar.layout a | |
195 | end | |
196 | in | |
197 | {destroy = fn () => (), | |
198 | layoutPretty = layoutPretty} | |
199 | end | |
200 | end | |
201 | ||
202 | val insideFunctor = ref false | |
203 | ||
204 | fun amInsideFunctor () = !insideFunctor | |
205 | ||
206 | structure Scope = | |
207 | struct | |
208 | structure Unique = UniqueId () | |
209 | datatype t = T of {unique: Unique.t} | |
210 | ||
211 | local | |
212 | fun make f (T r) = f r | |
213 | in | |
214 | val unique = make #unique | |
215 | end | |
216 | ||
217 | fun new (): t = | |
218 | T {unique = Unique.new ()} | |
219 | ||
220 | fun equals (s, s') = Unique.equals (unique s, unique s') | |
221 | end | |
222 | ||
223 | structure Uses: | |
224 | sig | |
225 | type 'a t | |
226 | ||
227 | structure Extend: | |
228 | sig | |
229 | val new: {rebind: {domain: 'a, uses: 'a t} option} -> 'a t option | |
230 | val old: 'a t -> {rebind: {domain: 'a, uses: 'a t} option} -> 'a t option | |
231 | val fromIsRebind: {isRebind: bool} -> {rebind: {domain: 'a, uses: 'a t} option} -> 'a t option | |
232 | end | |
233 | ||
234 | val add: 'a t * 'a -> unit | |
235 | val all: 'a t -> 'a list | |
236 | val clear: 'a t -> unit | |
237 | val forceUsed: 'a t -> unit | |
238 | val hasUse: 'a t -> bool | |
239 | val isUsed: 'a t -> bool | |
240 | val new: unit -> 'a t | |
241 | end = | |
242 | struct | |
243 | datatype 'a t = T of {direct: 'a list ref, | |
244 | forceUsed: bool ref} | |
245 | ||
246 | fun new () = T {direct = ref [], | |
247 | forceUsed = ref false} | |
248 | ||
249 | fun add (T {direct, ...}, a) = List.push (direct, a) | |
250 | ||
251 | fun forceUsed (T {forceUsed = r, ...}) = r := true | |
252 | ||
253 | fun clear (T {direct, ...}) = direct := [] | |
254 | ||
255 | fun all (T {direct, ...}) = !direct | |
256 | ||
257 | fun hasUse (T {direct, ...}): bool = | |
258 | not (List.isEmpty (!direct)) | |
259 | ||
260 | fun isUsed (u as T {forceUsed, ...}): bool = | |
261 | !forceUsed orelse hasUse u | |
262 | ||
263 | structure Extend = | |
264 | struct | |
265 | fun new _ = NONE | |
266 | fun old uses _ = SOME uses | |
267 | fun fromIsRebind {isRebind} = | |
268 | if isRebind | |
269 | then (fn {rebind} => | |
270 | case rebind of | |
271 | NONE => | |
272 | Error.bug "ElaborateEnv.Uses.Extend.fromIsRebind" | |
273 | | SOME {domain = _, uses} => | |
274 | SOME uses) | |
275 | else new | |
276 | end | |
277 | end | |
278 | ||
279 | structure Class = | |
280 | struct | |
281 | datatype t = Bas | Con | Exn | Fix | Fct | Sig | Str | Typ | Var | |
282 | ||
283 | val toString = | |
284 | fn Bas => "basis" | |
285 | | Con => "constructor" | |
286 | | Exn => "exception" | |
287 | | Fix => "fixity" | |
288 | | Fct => "functor" | |
289 | | Sig => "signature" | |
290 | | Str => "structure" | |
291 | | Typ => "type" | |
292 | | Var => "variable" | |
293 | end | |
294 | ||
295 | structure Vid = | |
296 | struct | |
297 | datatype t = | |
298 | Con of Con.t | |
299 | | Exn of Con.t | |
300 | | Overload of Priority.t * (Var.t * Scheme.t) vector | |
301 | | Var of Var.t | |
302 | ||
303 | val statusPretty = | |
304 | fn Con _ => "constructor" | |
305 | | Exn _ => "exception" | |
306 | | Overload _ => "overload" | |
307 | | Var _ => "variable" | |
308 | ||
309 | fun layout vid = | |
310 | let | |
311 | open Layout | |
312 | val (name, l) = | |
313 | case vid of | |
314 | Con c => ("Con", Con.layout c) | |
315 | | Exn c => ("Exn", Con.layout c) | |
316 | | Overload (p,xts) => | |
317 | (concat ["Overload (", | |
318 | Layout.toString (Priority.layout p), | |
319 | ")"], | |
320 | Vector.layout (tuple2 (Var.layout, Scheme.layout)) | |
321 | xts) | |
322 | | Var v => ("Var", Var.layout v) | |
323 | in | |
324 | paren (seq [str name, str " ", l]) | |
325 | end | |
326 | ||
327 | val deVar = | |
328 | fn Var v => SOME v | |
329 | | _ => NONE | |
330 | ||
331 | val deCon = | |
332 | fn Con c => SOME c | |
333 | | Exn c => SOME c | |
334 | | _ => NONE | |
335 | ||
336 | val deExn = | |
337 | fn Exn c => SOME c | |
338 | | _ => NONE | |
339 | ||
340 | val class = | |
341 | fn Con _ => Class.Con | |
342 | | Exn _ => Class.Exn | |
343 | | Overload _ => Class.Var | |
344 | | Var _ => Class.Var | |
345 | end | |
346 | ||
347 | structure TypeStr = | |
348 | struct | |
349 | structure Cons : | |
350 | sig | |
351 | type t | |
352 | val dest: t -> {con: Con.t, | |
353 | name: Ast.Con.t, | |
354 | scheme: Scheme.t, | |
355 | uses: Ast.Vid.t Uses.t} vector | |
356 | val fromSortedVector: {con: Con.t, | |
357 | name: Ast.Con.t, | |
358 | scheme: Scheme.t, | |
359 | uses: Ast.Vid.t Uses.t} vector -> t | |
360 | val fromVector: {con: Con.t, | |
361 | name: Ast.Con.t, | |
362 | scheme: Scheme.t, | |
363 | uses: Ast.Vid.t Uses.t} vector -> t | |
364 | val layout: t -> Layout.t | |
365 | val map: t * ({con: Con.t, | |
366 | name: Ast.Con.t, | |
367 | scheme: Scheme.t, | |
368 | uses: Ast.Vid.t Uses.t} | |
369 | -> {con: Con.t, | |
370 | scheme: Scheme.t, | |
371 | uses: Ast.Vid.t Uses.t}) -> t | |
372 | end = | |
373 | struct | |
374 | datatype t = T of {con: Con.t, | |
375 | name: Ast.Con.t, | |
376 | scheme: Scheme.t, | |
377 | uses: Ast.Vid.t Uses.t} vector | |
378 | ||
379 | fun dest (T v) = v | |
380 | ||
381 | val fromSortedVector = T | |
382 | ||
383 | fun fromVector v = | |
384 | (fromSortedVector o QuickSort.sortVector) | |
385 | (v, fn ({name = name1, ...}, {name = name2, ...}) => | |
386 | case Ast.Con.compare (name1, name2) of | |
387 | LESS => true | |
388 | | EQUAL => true | |
389 | | GREATER => false) | |
390 | ||
391 | fun map (T v, f) = | |
392 | (T o Vector.map) | |
393 | (v, fn elt as {name, ...} => | |
394 | let | |
395 | val {con, scheme, uses} = | |
396 | f elt | |
397 | in | |
398 | {con = con, | |
399 | name = name, | |
400 | scheme = scheme, | |
401 | uses = uses} | |
402 | end) | |
403 | ||
404 | fun layout (T v) = | |
405 | Vector.layout (fn {name, scheme, ...} => | |
406 | seq [Ast.Con.layout name, | |
407 | str ": ", Scheme.layout scheme]) | |
408 | v | |
409 | end | |
410 | ||
411 | datatype node = | |
412 | Datatype of {cons: Cons.t, | |
413 | tycon: Tycon.t} | |
414 | | Scheme of Scheme.t | |
415 | | Tycon of Tycon.t | |
416 | type t = node | |
417 | ||
418 | val node = fn s => s | |
419 | ||
420 | fun kind s = | |
421 | case node s of | |
422 | Datatype {tycon, ...} => Tycon.kind tycon | |
423 | | Scheme s => Scheme.kind s | |
424 | | Tycon c => Tycon.kind c | |
425 | ||
426 | fun layout t = | |
427 | let | |
428 | open Layout | |
429 | in | |
430 | case node t of | |
431 | Datatype {tycon, cons} => | |
432 | seq [str "Datatype ", | |
433 | record [("tycon", Tycon.layout tycon), | |
434 | ("cons", Cons.layout cons)]] | |
435 | | Scheme s => seq [str "Scheme ", Scheme.layout s] | |
436 | | Tycon c => seq [str "Tycon ", Tycon.layout c] | |
437 | end | |
438 | ||
439 | fun admitsEquality (s: t): AdmitsEquality.t = | |
440 | case node s of | |
441 | Datatype {tycon = c, ...} => Tycon.admitsEquality c | |
442 | | Scheme s => if Scheme.admitsEquality s | |
443 | then AdmitsEquality.Sometimes | |
444 | else AdmitsEquality.Never | |
445 | | Tycon c => Tycon.admitsEquality c | |
446 | ||
447 | fun explainDoesNotAdmitEquality (s: t, {layoutPrettyTycon}): Layout.t = | |
448 | let | |
449 | fun doitScheme s = | |
450 | case Scheme.checkEquality (s, {layoutPrettyTycon = layoutPrettyTycon}) of | |
451 | SOME l => l | |
452 | | NONE => Error.bug "ElaborateEnv.TypeStr.explainDoesNotAdmitEquality.doitScheme: NONE" | |
453 | in | |
454 | case node s of | |
455 | Datatype {cons, ...} => | |
456 | let | |
457 | val extra = ref false | |
458 | val cons = | |
459 | Vector.toList | |
460 | (Vector.keepAllMap | |
461 | (Cons.dest cons, fn {name, scheme, ...} => | |
462 | let | |
463 | val (tyvars, ty) = Scheme.dest scheme | |
464 | in | |
465 | case Type.deArrowOpt ty of | |
466 | NONE => (extra := true; NONE) | |
467 | | SOME (arg, _) => | |
468 | let | |
469 | val argScheme = | |
470 | Scheme.make {canGeneralize = true, | |
471 | ty = arg, | |
472 | tyvars = tyvars} | |
473 | in | |
474 | case Scheme.checkEquality (argScheme, {layoutPrettyTycon = layoutPrettyTycon}) of | |
475 | NONE => (extra := true; NONE) | |
476 | | SOME l => SOME (seq [Ast.Con.layout name, str " of ", l]) | |
477 | end | |
478 | end)) | |
479 | val cons = | |
480 | if !extra | |
481 | then List.snoc (cons, str "...") | |
482 | else cons | |
483 | val cons = alignPrefix (cons, "| ") | |
484 | in | |
485 | cons | |
486 | end | |
487 | | Scheme s => doitScheme s | |
488 | | Tycon c => doitScheme (Scheme.fromTycon c) | |
489 | end | |
490 | ||
491 | fun apply (t: t, tys: Type.t vector): Type.t = | |
492 | case node t of | |
493 | Datatype {tycon, ...} => Type.con (tycon, tys) | |
494 | | Scheme s => Scheme.apply (s, tys) | |
495 | | Tycon c => Type.con (c, tys) | |
496 | ||
497 | fun toTyconOpt s = | |
498 | case node s of | |
499 | Datatype {tycon, ...} => SOME tycon | |
500 | | Scheme s => | |
501 | let | |
502 | val (tyvars, ty) = Scheme.dest s | |
503 | in | |
504 | case Type.deEta (ty, tyvars) of | |
505 | NONE => NONE | |
506 | | SOME c => | |
507 | if Tycon.equals (c, Tycon.arrow) | |
508 | orelse Tycon.equals (c, Tycon.tuple) | |
509 | then NONE | |
510 | else SOME c | |
511 | end | |
512 | | Tycon c => SOME c | |
513 | ||
514 | fun data (tycon, cons) = | |
515 | Datatype {tycon = tycon, cons = cons} | |
516 | ||
517 | val def = Scheme | |
518 | ||
519 | val tycon = Tycon | |
520 | ||
521 | fun abs t = | |
522 | case node t of | |
523 | Datatype {tycon = c, ...} => tycon c | |
524 | | _ => t | |
525 | end | |
526 | ||
527 | local | |
528 | open TypeStr | |
529 | in | |
530 | structure Cons = Cons | |
531 | end | |
532 | ||
533 | structure Interface = Interface (structure Ast = Ast | |
534 | structure AdmitsEquality = AdmitsEquality | |
535 | structure Kind = Kind | |
536 | structure EnvTycon = Tycon | |
537 | structure EnvTypeStr = TypeStr | |
538 | structure Tyvar = Tyvar) | |
539 | ||
540 | structure Interface = | |
541 | struct | |
542 | structure Econs = Cons | |
543 | structure Escheme = Scheme | |
544 | structure Etycon = Tycon | |
545 | structure Etype = Type | |
546 | structure EtypeStr = TypeStr | |
547 | structure Etyvar = Tyvar | |
548 | open Interface | |
549 | ||
550 | fun flexibleTyconToEnv (fc: FlexibleTycon.t): EtypeStr.t = | |
551 | let | |
552 | datatype z = datatype FlexibleTycon.realization | |
553 | in | |
554 | case FlexibleTycon.realization fc of | |
555 | SOME (ETypeStr s) => s | |
556 | | SOME (TypeStr s) => typeStrToEnv s | |
557 | | NONE => | |
558 | let | |
559 | (* A shadowed flexible tycon was not reported as | |
560 | * a flexible tycon and was not realized. *) | |
561 | val () = | |
562 | Assert.assert | |
563 | ("ElaborateEnv.Interface.flexibleTyconToEnv", | |
564 | fn () => !Control.numErrors > 0) | |
565 | val {admitsEquality = ae, kind = k, | |
566 | prettyDefault = pd, ...} = | |
567 | FlexibleTycon.dest fc | |
568 | val pd = "??." ^ pd | |
569 | val c = | |
570 | Etycon.make {admitsEquality = ae, | |
571 | kind = k, | |
572 | name = "<bogus>", | |
573 | prettyDefault = pd, | |
574 | region = Region.bogus} | |
575 | val tyStr = EtypeStr.tycon c | |
576 | val () = FlexibleTycon.realize (fc, tyStr) | |
577 | in | |
578 | tyStr | |
579 | end | |
580 | end | |
581 | and tyconToEnv (t: Tycon.t): EtypeStr.t = | |
582 | let | |
583 | open Tycon | |
584 | in | |
585 | case t of | |
586 | Flexible c => flexibleTyconToEnv c | |
587 | | Rigid c => EtypeStr.tycon c | |
588 | end | |
589 | and typeToEnv (t: Type.t): Etype.t = | |
590 | Type.hom (t, {con = fn (c, ts) => EtypeStr.apply (tyconToEnv c, ts), | |
591 | record = Etype.record, | |
592 | var = Etype.var}) | |
593 | and schemeToEnv (Scheme.T {ty, tyvars}): Escheme.t = | |
594 | Escheme.make {canGeneralize = true, | |
595 | ty = typeToEnv ty, | |
596 | tyvars = tyvars} | |
597 | and consToEnv cons: Econs.t = | |
598 | (Econs.fromSortedVector o Vector.map) | |
599 | (Cons.dest cons, fn {name, scheme} => | |
600 | {con = Con.newNoname (), | |
601 | name = name, | |
602 | scheme = schemeToEnv scheme, | |
603 | uses = Uses.new ()}) | |
604 | and typeStrToEnv (s: TypeStr.t): EtypeStr.t = | |
605 | let | |
606 | datatype z = datatype TypeStr.node | |
607 | in | |
608 | case TypeStr.node s of | |
609 | Datatype {cons, tycon, ...} => | |
610 | let | |
611 | fun data c = | |
612 | EtypeStr.data (c, consToEnv cons) | |
613 | in | |
614 | case tycon of | |
615 | Tycon.Flexible c => | |
616 | let | |
617 | val typeStr = flexibleTyconToEnv c | |
618 | in | |
619 | case EtypeStr.toTyconOpt typeStr of | |
620 | SOME c => data c | |
621 | | _ => Error.bug | |
622 | (Layout.toString | |
623 | (seq [str "ElaborateEnv.Interface.typeStrToEnv ", | |
624 | str "datatype ", | |
625 | TypeStr.layout s, | |
626 | str " realized with type structure ", | |
627 | EtypeStr.layout typeStr])) | |
628 | end | |
629 | | Tycon.Rigid c => data c | |
630 | end | |
631 | | Scheme s => | |
632 | EtypeStr.def (schemeToEnv s) | |
633 | | Tycon {tycon, ...} => | |
634 | EtypeStr.abs (tyconToEnv tycon) | |
635 | end | |
636 | ||
637 | structure FlexibleTycon = | |
638 | struct | |
639 | open FlexibleTycon | |
640 | ||
641 | val toEnv = flexibleTyconToEnv | |
642 | ||
643 | fun dummyTycon (fc, name, strids, {prefix}) = | |
644 | let | |
645 | val {admitsEquality = ae, kind = k, ...} = | |
646 | FlexibleTycon.dest fc | |
647 | val r = Ast.Tycon.region name | |
648 | val n = Ast.Tycon.toString name | |
649 | val pd = | |
650 | prefix ^ toStringLongRev (strids, Ast.Tycon.layout name) | |
651 | val c = | |
652 | Etycon.make {admitsEquality = ae, | |
653 | kind = k, | |
654 | name = n, | |
655 | prettyDefault = pd, | |
656 | region = r} | |
657 | in | |
658 | c | |
659 | end | |
660 | end | |
661 | ||
662 | structure Tycon = | |
663 | struct | |
664 | open Tycon | |
665 | ||
666 | val fromEnv = Rigid | |
667 | end | |
668 | ||
669 | structure Type = | |
670 | struct | |
671 | open Type | |
672 | ||
673 | fun fromEnv (t: Etype.t): t = | |
674 | let | |
675 | fun con (c, ts) = | |
676 | Type.con (Tycon.fromEnv c, ts) | |
677 | in | |
678 | Etype.hom (t, {con = con, | |
679 | expandOpaque = false, | |
680 | record = record, | |
681 | replaceSynonyms = false, | |
682 | var = var}) | |
683 | end | |
684 | end | |
685 | ||
686 | structure Scheme = | |
687 | struct | |
688 | open Scheme | |
689 | ||
690 | val toEnv = schemeToEnv | |
691 | ||
692 | fun fromEnv (s: Escheme.t): t = | |
693 | let | |
694 | val (tyvars, ty) = Escheme.dest s | |
695 | in | |
696 | Scheme.T {ty = Type.fromEnv ty, | |
697 | tyvars = tyvars} | |
698 | end | |
699 | end | |
700 | ||
701 | structure Cons = | |
702 | struct | |
703 | open Cons | |
704 | ||
705 | fun fromEnv (cons): t = | |
706 | (fromSortedVector o Vector.map) | |
707 | (Econs.dest cons, fn {name, scheme, ...} => | |
708 | {name = name, | |
709 | scheme = Scheme.fromEnv scheme}) | |
710 | end | |
711 | ||
712 | structure TypeStr = | |
713 | struct | |
714 | open TypeStr | |
715 | ||
716 | val toEnv = typeStrToEnv | |
717 | ||
718 | fun fromEnv (s: EtypeStr.t) = | |
719 | case EtypeStr.node s of | |
720 | EtypeStr.Datatype {cons, tycon} => | |
721 | data (Tycon.fromEnv tycon, | |
722 | Cons.fromEnv cons, | |
723 | true) | |
724 | | EtypeStr.Scheme s => def (Scheme.fromEnv s) | |
725 | | EtypeStr.Tycon c => def (Scheme.fromTycon (Tycon.fromEnv c)) | |
726 | ||
727 | structure Sort = | |
728 | struct | |
729 | datatype t = | |
730 | Datatype of {tycon: Etycon.t, cons: Econs.t, repl: bool} | |
731 | | Scheme of Escheme.t | |
732 | | Type of {admitsEquality: bool} | |
733 | end | |
734 | ||
735 | fun sort (sigStr, rlzStr, representative) = | |
736 | case (representative, node sigStr, EtypeStr.node rlzStr) of | |
737 | (false, Datatype _, EtypeStr.Datatype {tycon = rlzTycon, cons = rlzCons}) => | |
738 | Sort.Datatype {tycon = rlzTycon, cons = rlzCons, repl = true} | |
739 | | (false, Datatype _, EtypeStr.Scheme _) => | |
740 | Error.bug "ElaborateEnv.Interface.TypeStr.sort: {repr = false, sigStr = Datatype _, rlzStr = Scheme _}" | |
741 | | (false, Datatype _, EtypeStr.Tycon _) => | |
742 | Error.bug "ElaborateEnv.Interface.TypeStr.sort: {repr = false, sigStr = Datatype _, rlzStr = Tycon _}" | |
743 | | (false, _, rlzStr) => | |
744 | Sort.Scheme (case rlzStr of | |
745 | EtypeStr.Datatype {tycon, ...} => | |
746 | Escheme.fromTycon tycon | |
747 | | EtypeStr.Scheme s => s | |
748 | | EtypeStr.Tycon c => | |
749 | Escheme.fromTycon c) | |
750 | | (true, Datatype {repl = false, ...}, EtypeStr.Datatype {tycon = rlzTycon, cons = rlzCons}) => | |
751 | Sort.Datatype {tycon = rlzTycon, cons = rlzCons, repl = false} | |
752 | | (true, Datatype {repl = false, ...}, EtypeStr.Scheme _) => | |
753 | Error.bug "ElaborateEnv.Interface.TypeStr.sort: {repr = true, sigStr = Datatype {repl = false, ...}, rlzStr = Scheme _}" | |
754 | | (true, Datatype {repl = false, ...}, EtypeStr.Tycon _) => | |
755 | Error.bug "ElaborateEnv.Interface.TypeStr.sort: {repr = true, sigStr = Datatype {repl = false, ...}, rlzStr = Tycon _}" | |
756 | | (true, Datatype {repl = true, ...}, _) => | |
757 | Error.bug "ElaborateEnv.Interface.TypeStr.sort: {repr = true, sigStr = Datatype {repl = true, ...}}" | |
758 | | (true, Scheme _, _) => | |
759 | Error.bug "ElaborateEnv.Interface.TypeStr.sort: {repr = true, sigStr = Scheme _}" | |
760 | | (true, Tycon _, _) => | |
761 | (case admitsEquality sigStr of | |
762 | AdmitsEquality.Always => Sort.Type {admitsEquality = true} | |
763 | | AdmitsEquality.Never => Sort.Type {admitsEquality = false} | |
764 | | AdmitsEquality.Sometimes => Sort.Type {admitsEquality = true}) | |
765 | ||
766 | val sort = fn (name, sigStr, rlzStr, | |
767 | flexTyconMap: FlexibleTycon.t TyconMap.t) => | |
768 | sort (sigStr, rlzStr, | |
769 | Option.isSome (TyconMap.peekTycon (flexTyconMap, name))) | |
770 | end | |
771 | ||
772 | fun layouts {interfaceSigid, layoutPrettyTycon, setLayoutPrettyTycon} = | |
773 | let | |
774 | val empty = Layout.empty | |
775 | val indent = fn l => Layout.indent (l, 3) | |
776 | val isEmpty = Layout.isEmpty | |
777 | val tuple = Layout.tuple | |
778 | ||
779 | val {destroy = destroyLayoutPrettyTyvar, | |
780 | layoutPretty = layoutPrettyTyvar, | |
781 | localInit = localInitLayoutPrettyTyvar} = | |
782 | Etyvar.makeLayoutPretty () | |
783 | val {destroy = destroyLayoutPrettyType, | |
784 | layoutPretty = layoutPrettyType} = | |
785 | Etype.makeLayoutPretty | |
786 | {expandOpaque = false, | |
787 | layoutPrettyTycon = layoutPrettyTycon, | |
788 | layoutPrettyTyvar = layoutPrettyTyvar} | |
789 | fun layoutPrettyScheme s = | |
790 | let | |
791 | val (bs, t) = Escheme.dest s | |
792 | val () = localInitLayoutPrettyTyvar bs | |
793 | in | |
794 | #1 (layoutPrettyType t) | |
795 | end | |
796 | ||
797 | fun layoutValSpec (strids, name, (sigStatus, sigScheme), {compact, con, def}) = | |
798 | let | |
799 | val rlzScheme = Scheme.toEnv sigScheme | |
800 | fun doit kw = | |
801 | let | |
802 | val lay = | |
803 | mayAlign | |
804 | [seq [str kw, str " ", | |
805 | layoutLongRev (strids, Ast.Vid.layout name), | |
806 | str (if Ast.Vid.isSymbolic name then " : " else ": "), | |
807 | layoutPrettyScheme rlzScheme], | |
808 | indent (if def | |
809 | then seq [str "(* @ ", | |
810 | Region.layout (Ast.Vid.region name), | |
811 | str " *)"] | |
812 | else empty)] | |
813 | val lay = | |
814 | if compact | |
815 | then Layout.compact lay | |
816 | else lay | |
817 | in | |
818 | SOME lay | |
819 | end | |
820 | in | |
821 | case sigStatus of | |
822 | Status.Con => | |
823 | if con | |
824 | then doit "con" | |
825 | else NONE | |
826 | | Status.Exn => | |
827 | if con | |
828 | then doit "exn" | |
829 | else let | |
830 | val lay = | |
831 | mayAlign | |
832 | [seq [str "exception ", | |
833 | layoutLongRev (strids, Ast.Vid.layout name), | |
834 | case Etype.deArrowOpt (Escheme.ty rlzScheme) of | |
835 | NONE => empty | |
836 | | SOME (ty, _) => seq [str " of ", | |
837 | #1 (layoutPrettyType ty)]], | |
838 | indent (if def | |
839 | then seq [str "(* @ ", | |
840 | Region.layout (Ast.Vid.region name), | |
841 | str " *)"] | |
842 | else empty)] | |
843 | val lay = | |
844 | if compact | |
845 | then Layout.compact lay | |
846 | else lay | |
847 | in | |
848 | SOME lay | |
849 | end | |
850 | | Status.Var => | |
851 | doit "val" | |
852 | end | |
853 | fun layoutTypeSpec (strids, name, sigStr, | |
854 | {compact, def, flexTyconMap}) = | |
855 | let | |
856 | val lay = #1 o layoutPrettyType | |
857 | val rlzStr = TypeStr.toEnv sigStr | |
858 | val sort = TypeStr.sort (name, sigStr, rlzStr, flexTyconMap) | |
859 | val arity = | |
860 | case Interface.TypeStr.kind sigStr of | |
861 | Kind.Arity sigArity => sigArity | |
862 | | _ => Error.bug "ElaborateEnv.transparentCut.layouts.layoutTypeSpec: sigArity" | |
863 | val tyvars = | |
864 | Vector.tabulate | |
865 | (arity, fn _ => | |
866 | Etyvar.makeNoname {equality = false}) | |
867 | val () = localInitLayoutPrettyTyvar tyvars | |
868 | val tyargs = Vector.map (tyvars, Etype.var) | |
869 | val tyvars = Vector.map (tyvars, layoutPrettyTyvar) | |
870 | val tyvars = | |
871 | case Vector.length tyvars of | |
872 | 0 => empty | |
873 | | 1 => Vector.first tyvars | |
874 | | _ => tuple (Vector.toList tyvars) | |
875 | datatype sort = datatype TypeStr.Sort.t | |
876 | val (kw, rest) = | |
877 | case sort of | |
878 | Datatype {repl, cons, ...} => | |
879 | let | |
880 | val cons = | |
881 | Vector.toListMap | |
882 | (Econs.dest cons, fn {name, scheme, ...} => | |
883 | let | |
884 | val ty = Escheme.apply (scheme, tyargs) | |
885 | in | |
886 | seq [Ast.Con.layout name, | |
887 | case Etype.deArrowOpt ty of | |
888 | NONE => empty | |
889 | | SOME (ty, _) => seq [str " of ", lay ty]] | |
890 | end) | |
891 | val cons = | |
892 | List.mapi | |
893 | (cons, fn (i, l) => | |
894 | if i = 0 | |
895 | then l | |
896 | else Layout.indent (seq [str "| ", l], ~2)) | |
897 | val rest = | |
898 | if repl | |
899 | then let | |
900 | val repl = | |
901 | seq [str "(* = datatype ", | |
902 | lay (EtypeStr.apply (rlzStr, tyargs)), | |
903 | str " *)"] | |
904 | in | |
905 | List.snoc (cons, Layout.indent (repl, ~2)) | |
906 | end | |
907 | else cons | |
908 | in | |
909 | ("datatype", | |
910 | SOME (mayAlign rest)) | |
911 | end | |
912 | | Scheme scheme => | |
913 | ("type", | |
914 | SOME (lay (Escheme.apply (scheme, tyargs)))) | |
915 | | Type {admitsEquality} => | |
916 | (if admitsEquality then "eqtype" else "type", | |
917 | NONE) | |
918 | val lay = | |
919 | mayAlign | |
920 | [seq [str kw, str " ", | |
921 | tyvars, | |
922 | if isEmpty tyvars then empty else str " ", | |
923 | layoutLongRev (strids, Ast.Tycon.layout name), | |
924 | case rest of | |
925 | NONE => empty | |
926 | | SOME rest => seq [str " = ", rest]], | |
927 | indent (if def | |
928 | then seq [str "(* @ ", | |
929 | Region.layout (Ast.Tycon.region name), | |
930 | str " *)"] | |
931 | else empty)] | |
932 | val lay = | |
933 | if compact | |
934 | then Layout.compact lay | |
935 | else lay | |
936 | in | |
937 | lay | |
938 | end | |
939 | fun layoutStrSpec (strids, name, I, | |
940 | {compact, def, elide, flexTyconMap}) = | |
941 | let | |
942 | val bind = seq [str "structure ", | |
943 | layoutLongRev (strids, Ast.Strid.layout name), | |
944 | str ":"] | |
945 | val flexTyconMap = | |
946 | Option.fold | |
947 | (TyconMap.peekStrid (flexTyconMap, name), | |
948 | TyconMap.empty (), | |
949 | fn (flexTyconMap, _) => flexTyconMap) | |
950 | val {abbrev, full} = | |
951 | layoutSigRlz (I, | |
952 | {compact = compact, | |
953 | elide = elide, | |
954 | flexTyconMap = flexTyconMap}) | |
955 | val def = | |
956 | if def | |
957 | then seq [str "(* @ ", | |
958 | Region.layout (Ast.Strid.region name), | |
959 | str " *)"] | |
960 | else empty | |
961 | val full = fn () => | |
962 | align [bind, indent (full ()), indent def] | |
963 | in | |
964 | case abbrev () of | |
965 | NONE => full () | |
966 | | SOME sigg => | |
967 | let | |
968 | val lay = | |
969 | mayAlign | |
970 | [seq [bind, str " ", sigg], | |
971 | indent def] | |
972 | val lay = | |
973 | if compact | |
974 | then Layout.compact lay | |
975 | else lay | |
976 | in | |
977 | lay | |
978 | end | |
979 | end | |
980 | and layoutSigFlex (I, | |
981 | {compact, elide}) = | |
982 | let | |
983 | fun realize (TyconMap.T {strs, types}, strids) = | |
984 | let | |
985 | val () = | |
986 | Array.foreach | |
987 | (strs, fn (name, tm) => | |
988 | realize (tm, name :: strids)) | |
989 | val () = | |
990 | Array.foreach | |
991 | (types, fn (name, fc) => | |
992 | let | |
993 | val c = | |
994 | FlexibleTycon.dummyTycon | |
995 | (fc, name, strids, {prefix = "_sig."}) | |
996 | val () = | |
997 | setLayoutPrettyTycon | |
998 | (c, Etycon.layoutPrettyDefault c) | |
999 | val () = | |
1000 | FlexibleTycon.realize | |
1001 | (fc, EtypeStr.tycon c) | |
1002 | in | |
1003 | () | |
1004 | end) | |
1005 | in | |
1006 | () | |
1007 | end | |
1008 | val rlzI = copy I | |
1009 | val flexTyconMap = flexibleTycons rlzI | |
1010 | val () = realize (flexTyconMap, []) | |
1011 | in | |
1012 | layoutSigRlz (rlzI, | |
1013 | {compact = compact, | |
1014 | elide = elide, | |
1015 | flexTyconMap = flexTyconMap}) | |
1016 | end | |
1017 | and layoutSigRlz (I, | |
1018 | {compact, elide, flexTyconMap}) = | |
1019 | let | |
1020 | fun abbrev () = | |
1021 | case interfaceSigid (Interface.original I) of | |
1022 | NONE => NONE | |
1023 | | SOME (s, I') => | |
1024 | SOME (layoutSigRlzAbbrev (s, I', I, | |
1025 | {compact = compact, | |
1026 | flexTyconMap = flexTyconMap})) | |
1027 | fun full () = | |
1028 | layoutSigRlzFull (I, | |
1029 | {compact = compact, | |
1030 | elide = elide, | |
1031 | flexTyconMap = flexTyconMap}) | |
1032 | in | |
1033 | {abbrev = abbrev, | |
1034 | full = full} | |
1035 | end | |
1036 | and layoutSigRlzFull (I, | |
1037 | {compact, | |
1038 | elide: {strs: (int * int) option, | |
1039 | types: (int * int) option, | |
1040 | vals: (int * int) option}, | |
1041 | flexTyconMap}) = | |
1042 | let | |
1043 | val {strs, types, vals} = Interface.dest I | |
1044 | fun doit (a, layout, elide) = | |
1045 | let | |
1046 | val specs = | |
1047 | Array.foldr | |
1048 | (a, [], fn ((name, range), ls) => | |
1049 | case layout (name, range) of | |
1050 | NONE => ls | |
1051 | | SOME l => l :: ls) | |
1052 | in | |
1053 | case elide of | |
1054 | NONE => align specs | |
1055 | | SOME (n, m) => | |
1056 | let | |
1057 | val l = List.length specs | |
1058 | in | |
1059 | if n + m + 1 < l | |
1060 | then align [align (List.dropSuffix (specs, l - n)), | |
1061 | str "...", | |
1062 | align (List.dropPrefix (specs, l - m))] | |
1063 | else align specs | |
1064 | end | |
1065 | end | |
1066 | val layoutTypeSpec = | |
1067 | fn (name, sigStr) => | |
1068 | layoutTypeSpec | |
1069 | ([], name, sigStr, | |
1070 | {compact = compact, | |
1071 | def = false, | |
1072 | flexTyconMap = flexTyconMap}) | |
1073 | val layoutValSpec = | |
1074 | fn (name, (sigStatus, sigScheme)) => | |
1075 | layoutValSpec | |
1076 | ([], name, (sigStatus, sigScheme), | |
1077 | {compact = compact, | |
1078 | con = false, | |
1079 | def = false}) | |
1080 | val layoutStrSpec = | |
1081 | fn (name, I) => | |
1082 | layoutStrSpec | |
1083 | ([], name, I, | |
1084 | {compact = compact, | |
1085 | def = false, | |
1086 | elide = elide, | |
1087 | flexTyconMap = flexTyconMap}) | |
1088 | in | |
1089 | align [str "sig", | |
1090 | indent (align [doit (types, SOME o layoutTypeSpec, #types elide), | |
1091 | doit (vals, layoutValSpec, #vals elide), | |
1092 | doit (strs, SOME o layoutStrSpec, #strs elide)]), | |
1093 | str "end"] | |
1094 | end | |
1095 | and layoutSigRlzAbbrev (s, I', I, {compact, flexTyconMap}) = | |
1096 | let | |
1097 | val flexTyconMap' = | |
1098 | Interface.flexibleTycons I' | |
1099 | val wheres = ref [] | |
1100 | fun loop (strids, flexTyconMap', I, flexTyconMap) = | |
1101 | let | |
1102 | val TyconMap.T {strs = strs', types = types'} = | |
1103 | flexTyconMap' | |
1104 | val _ = | |
1105 | Array.foreach | |
1106 | (strs', fn (name, flexTyconMap') => | |
1107 | let | |
1108 | val I = | |
1109 | valOf (Interface.peekStrid (I, name)) | |
1110 | val flexTyconMap = | |
1111 | Option.fold | |
1112 | (TyconMap.peekStrid (flexTyconMap, name), | |
1113 | TyconMap.empty (), | |
1114 | fn (flexTyconMap, _) => flexTyconMap) | |
1115 | in | |
1116 | loop (name::strids, flexTyconMap', I, flexTyconMap) | |
1117 | end) | |
1118 | val _ = | |
1119 | Array.foreach | |
1120 | (types', fn (name, _) => | |
1121 | let | |
1122 | val (_, sigStr) = valOf (Interface.peekTycon (I, name)) | |
1123 | val flexTycon = TyconMap.peekTycon (flexTyconMap, name) | |
1124 | in | |
1125 | case flexTycon of | |
1126 | NONE => | |
1127 | List.push | |
1128 | (wheres, | |
1129 | seq [str "where ", | |
1130 | layoutTypeSpec (strids, | |
1131 | name, | |
1132 | Interface.TypeStr.abs sigStr, | |
1133 | {compact = compact, | |
1134 | def = false, | |
1135 | flexTyconMap = flexTyconMap})]) | |
1136 | | SOME _ => () | |
1137 | end) | |
1138 | in | |
1139 | () | |
1140 | end | |
1141 | val () = loop ([], flexTyconMap', I, flexTyconMap) | |
1142 | val wheres = rev (!wheres) | |
1143 | val lay = | |
1144 | align (Ast.Sigid.layout s :: wheres) | |
1145 | in | |
1146 | lay | |
1147 | end | |
1148 | fun layoutSigDefn (name, I, {compact, def}) = | |
1149 | let | |
1150 | val bind = seq [str "signature ", Ast.Sigid.layout name, str " ="] | |
1151 | val {abbrev, full} = layoutSigFlex (I, | |
1152 | {compact = compact, | |
1153 | elide = {strs = NONE, | |
1154 | types = NONE, | |
1155 | vals = NONE}}) | |
1156 | val origI = Interface.original I | |
1157 | val def = | |
1158 | if def | |
1159 | then seq [str "(* @ ", | |
1160 | Region.layout (Ast.Sigid.region name), | |
1161 | str " *)"] | |
1162 | else empty | |
1163 | val full = fn () => | |
1164 | align [bind, indent (full ()), indent def] | |
1165 | in | |
1166 | if Interface.equals (I, origI) | |
1167 | then full () | |
1168 | else (case abbrev () of | |
1169 | NONE => full () | |
1170 | | SOME sigg => | |
1171 | let | |
1172 | val lay = | |
1173 | mayAlign | |
1174 | [seq [bind, str " ", sigg], | |
1175 | indent def] | |
1176 | val lay = | |
1177 | if compact | |
1178 | then Layout.compact lay | |
1179 | else lay | |
1180 | in | |
1181 | lay | |
1182 | end) | |
1183 | end | |
1184 | in | |
1185 | {destroy = fn () => (destroyLayoutPrettyType () | |
1186 | ; destroyLayoutPrettyTyvar ()), | |
1187 | destroyLayoutPrettyType = destroyLayoutPrettyType, | |
1188 | destroyLayoutPrettyTyvar = destroyLayoutPrettyTyvar, | |
1189 | localInitLayoutPrettyTyvar = localInitLayoutPrettyTyvar, | |
1190 | layoutPrettyScheme = layoutPrettyScheme, | |
1191 | layoutPrettyType = layoutPrettyType, | |
1192 | layoutPrettyTyvar = layoutPrettyTyvar, | |
1193 | layoutSigDefn = layoutSigDefn, | |
1194 | layoutSigFlex = layoutSigFlex, | |
1195 | layoutSigRlz = layoutSigRlz, | |
1196 | layoutStrSpec = layoutStrSpec, | |
1197 | layoutTypeSpec = layoutTypeSpec, | |
1198 | layoutValSpec = layoutValSpec} | |
1199 | end | |
1200 | ||
1201 | fun layoutPretty I = | |
1202 | let | |
1203 | val {destroy, layoutSigFlex, ...} = | |
1204 | layouts {interfaceSigid = fn _ => NONE, | |
1205 | layoutPrettyTycon = Etycon.layoutPrettyDefault, | |
1206 | setLayoutPrettyTycon = fn _ => ()} | |
1207 | val {full, ...} = | |
1208 | layoutSigFlex | |
1209 | (I, | |
1210 | {compact = false, | |
1211 | elide = {strs = NONE, | |
1212 | types = NONE, | |
1213 | vals = NONE}}) | |
1214 | val res = full () | |
1215 | val () = destroy () | |
1216 | in | |
1217 | res | |
1218 | end | |
1219 | end | |
1220 | ||
1221 | local | |
1222 | open Interface | |
1223 | in | |
1224 | structure FlexibleTycon = FlexibleTycon | |
1225 | structure Status = Status | |
1226 | structure TyconMap = TyconMap | |
1227 | end | |
1228 | structure Status = | |
1229 | struct | |
1230 | open Status | |
1231 | ||
1232 | val class = | |
1233 | fn Con => Class.Con | |
1234 | | Exn => Class.Exn | |
1235 | | Var => Class.Var | |
1236 | ||
1237 | fun fromVid vid = | |
1238 | case vid of | |
1239 | Vid.Con _ => Con | |
1240 | | Vid.Exn _ => Exn | |
1241 | | Vid.Overload _ => Var | |
1242 | | Vid.Var _ => Var | |
1243 | ||
1244 | val kw: t -> string = | |
1245 | fn Con => "con" | |
1246 | | Exn => "exn" | |
1247 | | Var => "val" | |
1248 | ||
1249 | val pretty: t -> string = | |
1250 | fn Con => "constructor" | |
1251 | | Exn => "exception" | |
1252 | | Var => "variable" | |
1253 | end | |
1254 | ||
1255 | structure Time:> | |
1256 | sig | |
1257 | type t | |
1258 | ||
1259 | val >= : t * t -> bool | |
1260 | val next: unit -> t | |
1261 | end = | |
1262 | struct | |
1263 | type t = int | |
1264 | ||
1265 | val layout = Int.layout | |
1266 | ||
1267 | val op >= : t * t -> bool = op >= | |
1268 | ||
1269 | val c = Counter.new 0 | |
1270 | ||
1271 | fun next () = Counter.next c | |
1272 | ||
1273 | val next = | |
1274 | Trace.trace | |
1275 | ("ElaborateEnv.Time.next", Unit.layout, layout) | |
1276 | next | |
1277 | end | |
1278 | ||
1279 | structure Info = | |
1280 | struct | |
1281 | (* The array is sorted by domain element. *) | |
1282 | datatype ('a, 'b) t = T of {domain: 'a, | |
1283 | range: 'b, | |
1284 | time: Time.t, | |
1285 | uses: 'a Uses.t} array | |
1286 | ||
1287 | fun layout (layoutDomain, layoutRange) (T a) = | |
1288 | Array.layout (fn {domain, range, ...} => | |
1289 | Layout.tuple [layoutDomain domain, layoutRange range]) | |
1290 | a | |
1291 | ||
1292 | fun isEmpty (T a) = Array.isEmpty a | |
1293 | ||
1294 | fun foreach (T a, f) = | |
1295 | Array.foreach (a, fn {domain, range, ...} => f (domain, range)) | |
1296 | ||
1297 | fun foreachByTime (T a, f) = | |
1298 | let | |
1299 | val a = Array.copy a | |
1300 | val _ = | |
1301 | QuickSort.sortArray | |
1302 | (a, fn ({time = t, ...}, {time = t', ...}) => | |
1303 | Time.>= (t, t')) | |
1304 | in | |
1305 | foreach (T a, f) | |
1306 | end | |
1307 | ||
1308 | fun peek (T a, domain: 'a, toSymbol: 'a -> Symbol.t) = | |
1309 | Option.map | |
1310 | (BinarySearch.search (a, fn {domain = d, ...} => | |
1311 | Symbol.compare (toSymbol domain, toSymbol d)), | |
1312 | fn i => Array.sub (a, i)) | |
1313 | ||
1314 | fun keepAll (T a, f) = T (Array.keepAll (a, f)) | |
1315 | ||
1316 | val map: ('a, 'b) t * ('b -> 'b) -> ('a, 'b) t = | |
1317 | fn (T a, f) => | |
1318 | T (Array.map (a, fn {domain, range, time, uses} => | |
1319 | {domain = domain, | |
1320 | range = f range, | |
1321 | time = time, | |
1322 | uses = uses})) | |
1323 | ||
1324 | val map2: ('a, 'b) t * ('a, 'b) t * ('b * 'b -> 'b) -> ('a, 'b) t = | |
1325 | fn (T a, T a', f) => | |
1326 | T (Array.map2 | |
1327 | (a, a', fn ({domain, range = r, time, uses}, {range = r', ...}) => | |
1328 | {domain = domain, | |
1329 | range = f (r, r'), | |
1330 | time = time, | |
1331 | uses = uses})) | |
1332 | end | |
1333 | ||
1334 | fun foreach2Sorted (abs: ('a * 'b) array, | |
1335 | info: ('a, 'c) Info.t, | |
1336 | equals: ('a * 'a -> bool), | |
1337 | f: ('a * 'b * (int * 'c) option -> unit)): unit = | |
1338 | let | |
1339 | val Info.T acs = info | |
1340 | val _ = | |
1341 | Array.fold | |
1342 | (abs, 0, fn ((a, b), i) => | |
1343 | let | |
1344 | fun find j = | |
1345 | if j = Array.length acs | |
1346 | then (i, NONE) | |
1347 | else | |
1348 | let | |
1349 | val {domain = a', range = c, ...} = Array.sub (acs, j) | |
1350 | in | |
1351 | if equals (a, a') | |
1352 | then (j + 1, SOME (j, c)) | |
1353 | else find (j + 1) | |
1354 | end | |
1355 | val (i, co) = find i | |
1356 | val () = f (a, b, co) | |
1357 | in | |
1358 | i | |
1359 | end) | |
1360 | in | |
1361 | () | |
1362 | end | |
1363 | ||
1364 | (* ------------------------------------------------- *) | |
1365 | (* Structure *) | |
1366 | (* ------------------------------------------------- *) | |
1367 | ||
1368 | structure Structure = | |
1369 | struct | |
1370 | datatype t = T of {interface: Interface.t option, | |
1371 | plist: PropertyList.t, | |
1372 | strs: (Ast.Strid.t, t) Info.t, | |
1373 | types: (Ast.Tycon.t, TypeStr.t) Info.t, | |
1374 | vals: (Ast.Vid.t, Vid.t * Scheme.t) Info.t} | |
1375 | ||
1376 | val ffi: t option ref = ref NONE | |
1377 | ||
1378 | local | |
1379 | fun make f (T r) = f r | |
1380 | in | |
1381 | val interface = make #interface | |
1382 | val plist = make #plist | |
1383 | end | |
1384 | ||
1385 | fun layout (T {interface, strs, vals, types, ...}) = | |
1386 | Layout.record | |
1387 | [("interface", Option.layout Interface.layout interface), | |
1388 | ("types", Info.layout (Ast.Tycon.layout, TypeStr.layout) types), | |
1389 | ("vals", (Info.layout (Ast.Vid.layout, | |
1390 | Layout.tuple2 (Vid.layout, Scheme.layout)) | |
1391 | vals)), | |
1392 | ("strs", Info.layout (Strid.layout, layout) strs)] | |
1393 | ||
1394 | fun eq (s: t, s': t): bool = PropertyList.equals (plist s, plist s') | |
1395 | ||
1396 | (* ------------------------------------------------- *) | |
1397 | (* peek *) | |
1398 | (* ------------------------------------------------- *) | |
1399 | ||
1400 | local | |
1401 | fun make (field, toSymbol) (T fields, domain) = | |
1402 | Option.map | |
1403 | (Info.peek (field fields, domain, toSymbol), | |
1404 | fn v as {uses, ...} => | |
1405 | (Uses.add (uses, domain); v)) | |
1406 | in | |
1407 | val peekStrid' = make (#strs, Ast.Strid.toSymbol) | |
1408 | val peekVid' = make (#vals, Ast.Vid.toSymbol) | |
1409 | val peekTycon' = make (#types, Ast.Tycon.toSymbol) | |
1410 | end | |
1411 | ||
1412 | fun peekStrid z = Option.map (peekStrid' z, #range) | |
1413 | fun peekTycon z = Option.map (peekTycon' z, #range) | |
1414 | fun peekVid z = Option.map (peekVid' z, #range) | |
1415 | ||
1416 | local | |
1417 | fun make (from, de) (S, x) = | |
1418 | case peekVid (S, from x) of | |
1419 | NONE => NONE | |
1420 | | SOME (vid, s) => Option.map (de vid, fn z => (z, s)) | |
1421 | in | |
1422 | val peekCon = make (Ast.Vid.fromCon, Vid.deCon) | |
1423 | val peekExn = make (Ast.Vid.fromCon, Vid.deExn) | |
1424 | val peekVar = make (Ast.Vid.fromVar, Vid.deVar) | |
1425 | end | |
1426 | ||
1427 | structure PeekResult = | |
1428 | struct | |
1429 | datatype 'a t = | |
1430 | Found of 'a | |
1431 | | UndefinedStructure of Strid.t list | |
1432 | end | |
1433 | ||
1434 | fun peekStrids (S, strids) = | |
1435 | let | |
1436 | fun loop (S, strids, ac) = | |
1437 | case strids of | |
1438 | [] => PeekResult.Found S | |
1439 | | strid :: strids => | |
1440 | case peekStrid (S, strid) of | |
1441 | NONE => PeekResult.UndefinedStructure (rev (strid :: ac)) | |
1442 | | SOME S => loop (S, strids, strid :: ac) | |
1443 | in | |
1444 | loop (S, strids, []) | |
1445 | end | |
1446 | ||
1447 | (* ------------------------------------------------- *) | |
1448 | (* layoutPretty *) | |
1449 | (* ------------------------------------------------- *) | |
1450 | ||
1451 | fun layouts {interfaceSigid, layoutPrettyTycon, setLayoutPrettyTycon} = | |
1452 | let | |
1453 | val elide = {strs = NONE, types = NONE, vals = NONE} | |
1454 | val flexTyconMap = TyconMap.empty () | |
1455 | ||
1456 | val {destroy, destroyLayoutPrettyType, destroyLayoutPrettyTyvar, | |
1457 | layoutPrettyScheme, | |
1458 | layoutPrettyType, layoutPrettyTyvar, | |
1459 | layoutSigDefn, layoutSigFlex, layoutSigRlz, | |
1460 | layoutStrSpec, layoutTypeSpec, layoutValSpec, ...} = | |
1461 | Interface.layouts {interfaceSigid = interfaceSigid, | |
1462 | layoutPrettyTycon = layoutPrettyTycon, | |
1463 | setLayoutPrettyTycon = setLayoutPrettyTycon} | |
1464 | ||
1465 | fun layoutTypeDefn (strids, name, strStr, {compact, def}) = | |
1466 | layoutTypeSpec | |
1467 | (strids, name, | |
1468 | Interface.TypeStr.fromEnv strStr, | |
1469 | {compact = compact, | |
1470 | def = def, | |
1471 | flexTyconMap = flexTyconMap}) | |
1472 | fun layoutValDefn (strids, name, (strVid, strScheme), {compact, con, def}) = | |
1473 | layoutValSpec | |
1474 | (strids, name, | |
1475 | (Status.fromVid strVid, Interface.Scheme.fromEnv strScheme), | |
1476 | {compact = compact, con = con, def = def}) | |
1477 | local | |
1478 | fun toInterface (T {interface, strs, types, vals, ...}) = | |
1479 | case interface of | |
1480 | NONE => | |
1481 | let | |
1482 | fun doit (Info.T a, f) = | |
1483 | Array.map (a, f) | |
1484 | val types = | |
1485 | doit | |
1486 | (types, fn {domain = name, range = strStr, ...} => | |
1487 | (name, Interface.TypeStr.fromEnv strStr)) | |
1488 | val vals = | |
1489 | doit | |
1490 | (vals, fn {domain = name, range = (strVid, strScheme), ...} => | |
1491 | (name, (Status.fromVid strVid, Interface.Scheme.fromEnv strScheme))) | |
1492 | val strs = | |
1493 | doit | |
1494 | (strs, fn {domain = name, range = S, ...} => | |
1495 | (name, toInterface S)) | |
1496 | in | |
1497 | Interface.new | |
1498 | {isClosed = true, | |
1499 | original = NONE, | |
1500 | strs = strs, | |
1501 | types = types, | |
1502 | vals = vals} | |
1503 | end | |
1504 | | SOME I => I | |
1505 | in | |
1506 | fun layoutStrDefn (strids, name, S, {compact, def}) = | |
1507 | layoutStrSpec | |
1508 | (strids, name, toInterface S, | |
1509 | {compact = compact, | |
1510 | def = def, | |
1511 | elide = elide, | |
1512 | flexTyconMap = flexTyconMap}) | |
1513 | fun layoutStr (S, {compact}) = | |
1514 | layoutSigRlz | |
1515 | (toInterface S, | |
1516 | {compact = compact, | |
1517 | elide = elide, | |
1518 | flexTyconMap = flexTyconMap}) | |
1519 | end | |
1520 | in | |
1521 | {destroy = destroy, | |
1522 | destroyLayoutPrettyType = destroyLayoutPrettyType, | |
1523 | destroyLayoutPrettyTyvar = destroyLayoutPrettyTyvar, | |
1524 | layoutPrettyScheme = layoutPrettyScheme, | |
1525 | layoutPrettyType = layoutPrettyType, | |
1526 | layoutPrettyTyvar = layoutPrettyTyvar, | |
1527 | layoutSigDefn = layoutSigDefn, | |
1528 | layoutSigFlex = layoutSigFlex, | |
1529 | layoutSigRlz = layoutSigRlz, | |
1530 | layoutStr = layoutStr, | |
1531 | layoutStrDefn = layoutStrDefn, | |
1532 | layoutStrSpec = layoutStrSpec, | |
1533 | layoutTypeDefn = layoutTypeDefn, | |
1534 | layoutTypeSpec = layoutTypeSpec, | |
1535 | layoutValDefn = layoutValDefn, | |
1536 | layoutValSpec = layoutValSpec} | |
1537 | end | |
1538 | ||
1539 | fun layoutPretty S = | |
1540 | let | |
1541 | val {destroy, layoutStr, ...} = | |
1542 | layouts {interfaceSigid = fn _ => NONE, | |
1543 | layoutPrettyTycon = Tycon.layoutPrettyDefault, | |
1544 | setLayoutPrettyTycon = fn _ => ()} | |
1545 | val res = #full (layoutStr (S, {compact = false})) () | |
1546 | val () = destroy () | |
1547 | in | |
1548 | res | |
1549 | end | |
1550 | ||
1551 | (* ------------------------------------------------- *) | |
1552 | (* forceUsed *) | |
1553 | (* ------------------------------------------------- *) | |
1554 | ||
1555 | local | |
1556 | datatype handleUses = Clear | Force | |
1557 | fun make handleUses = | |
1558 | let | |
1559 | fun loop (T f) = | |
1560 | let | |
1561 | fun doit (sel, forceRange) = | |
1562 | let | |
1563 | val Info.T a = sel f | |
1564 | in | |
1565 | Array.foreach | |
1566 | (a, fn {range, uses, ...} => | |
1567 | let | |
1568 | val _ = | |
1569 | case handleUses of | |
1570 | Clear => Uses.clear uses | |
1571 | | Force => Uses.forceUsed uses | |
1572 | val _ = forceRange range | |
1573 | in | |
1574 | () | |
1575 | end) | |
1576 | end | |
1577 | val _ = doit (#strs, loop) | |
1578 | val _ = doit (#types, ignore) | |
1579 | val _ = doit (#vals, ignore) | |
1580 | in | |
1581 | () | |
1582 | end | |
1583 | in | |
1584 | loop | |
1585 | end | |
1586 | in | |
1587 | val forceUsed = make Force | |
1588 | end | |
1589 | ||
1590 | (* ------------------------------------------------- *) | |
1591 | (* realize *) | |
1592 | (* ------------------------------------------------- *) | |
1593 | ||
1594 | fun realize (S: t, tm: 'a TyconMap.t, | |
1595 | f: (Ast.Tycon.t | |
1596 | * 'a | |
1597 | * TypeStr.t option | |
1598 | * {nest: Strid.t list}) -> unit): unit = | |
1599 | let | |
1600 | fun allNone (TyconMap.T {strs, types}, nest) = | |
1601 | (Array.foreach (strs, fn (name, tm) => allNone (tm, name :: nest)) | |
1602 | ; Array.foreach (types, fn (name, flex) => | |
1603 | f (name, flex, NONE, {nest = nest}))) | |
1604 | fun loop (TyconMap.T {strs, types}, | |
1605 | T {strs = strs', types = types', ...}, | |
1606 | nest: Strid.t list) = | |
1607 | let | |
1608 | val () = | |
1609 | foreach2Sorted | |
1610 | (strs, strs', Ast.Strid.equals, | |
1611 | fn (name, tm, S) => | |
1612 | case S of | |
1613 | NONE => allNone (tm, name :: nest) | |
1614 | | SOME (_, S) => loop (tm, S, name :: nest)) | |
1615 | val () = | |
1616 | foreach2Sorted | |
1617 | (types, types', Ast.Tycon.equals, | |
1618 | fn (name, flex, opt) => | |
1619 | f (name, flex, Option.map (opt, #2), {nest = nest})) | |
1620 | in | |
1621 | () | |
1622 | end | |
1623 | in | |
1624 | loop (tm, S, []) | |
1625 | end | |
1626 | ||
1627 | (* ------------------------------------------------- *) | |
1628 | (* dummy *) | |
1629 | (* ------------------------------------------------- *) | |
1630 | ||
1631 | fun dummy (I: Interface.t, {prefix: string}) | |
1632 | : t * (t * (Tycon.t * TypeStr.t -> unit) -> unit) = | |
1633 | let | |
1634 | val time = Time.next () | |
1635 | val I = Interface.copy I | |
1636 | fun realizeLoop (TyconMap.T {strs, types}, strids) = | |
1637 | let | |
1638 | val strs = | |
1639 | Array.map | |
1640 | (strs, fn (name, tm) => | |
1641 | (name, realizeLoop (tm, name :: strids))) | |
1642 | val types = | |
1643 | Array.map | |
1644 | (types, fn (name, flex) => | |
1645 | let | |
1646 | val c = | |
1647 | FlexibleTycon.dummyTycon | |
1648 | (flex, name, strids, | |
1649 | {prefix = prefix}) | |
1650 | val () = | |
1651 | FlexibleTycon.realize | |
1652 | (flex, TypeStr.tycon c) | |
1653 | in | |
1654 | (name, c) | |
1655 | end) | |
1656 | in | |
1657 | TyconMap.T {strs = strs, types = types} | |
1658 | end | |
1659 | val flexible = realizeLoop (Interface.flexibleTycons I, []) | |
1660 | val {get, ...} = | |
1661 | Property.get | |
1662 | (Interface.plist, | |
1663 | Property.initRec | |
1664 | (fn (I, get) => | |
1665 | let | |
1666 | val {strs, types, vals} = Interface.dest I | |
1667 | val strs = | |
1668 | Array.map (strs, fn (name, I) => | |
1669 | {domain = name, | |
1670 | range = get I, | |
1671 | time = time, | |
1672 | uses = Uses.new ()}) | |
1673 | val types = | |
1674 | Array.map (types, fn (name, s) => | |
1675 | {domain = name, | |
1676 | range = Interface.TypeStr.toEnv s, | |
1677 | time = time, | |
1678 | uses = Uses.new ()}) | |
1679 | val vals = | |
1680 | Array.map | |
1681 | (vals, fn (name, (status, scheme)) => | |
1682 | let | |
1683 | val con = CoreML.Con.newString o Ast.Vid.toString | |
1684 | val var = CoreML.Var.newString o Ast.Vid.toString | |
1685 | val vid = | |
1686 | case status of | |
1687 | Status.Con => Vid.Con (con name) | |
1688 | | Status.Exn => Vid.Exn (con name) | |
1689 | | Status.Var => Vid.Var (var name) | |
1690 | in | |
1691 | {domain = name, | |
1692 | range = (vid, Interface.Scheme.toEnv scheme), | |
1693 | time = time, | |
1694 | uses = Uses.new ()} | |
1695 | end) | |
1696 | in | |
1697 | T {interface = SOME I, | |
1698 | plist = PropertyList.new (), | |
1699 | strs = Info.T strs, | |
1700 | types = Info.T types, | |
1701 | vals = Info.T vals} | |
1702 | end)) | |
1703 | val S = get I | |
1704 | fun instantiate (S, f) = | |
1705 | realize (S, flexible, fn (_, c, so, _) => | |
1706 | case so of | |
1707 | NONE => Error.bug "ElaborateEnv.Structure.dummy.instantiate" | |
1708 | | SOME s => f (c, s)) | |
1709 | in | |
1710 | (S, instantiate) | |
1711 | end | |
1712 | ||
1713 | val dummy = | |
1714 | Trace.trace ("ElaborateEnv.Structure.dummy", | |
1715 | Interface.layoutPretty o #1, | |
1716 | layoutPretty o #1) | |
1717 | dummy | |
1718 | ||
1719 | end | |
1720 | ||
1721 | (* ------------------------------------------------- *) | |
1722 | (* FunctorClosure *) | |
1723 | (* ------------------------------------------------- *) | |
1724 | ||
1725 | structure FunctorClosure = | |
1726 | struct | |
1727 | datatype t = | |
1728 | T of {apply: Structure.t * string list -> Decs.t * Structure.t option, | |
1729 | argInterface: Interface.t, | |
1730 | resultStructure: Structure.t option, | |
1731 | summary: Structure.t -> Structure.t option} | |
1732 | ||
1733 | local | |
1734 | fun make f (T r) = f r | |
1735 | in | |
1736 | val argInterface = make #argInterface | |
1737 | end | |
1738 | ||
1739 | fun layout _ = Layout.str "<functor closure>" | |
1740 | ||
1741 | fun apply (T {apply, ...}, S, nest) = apply (S, nest) | |
1742 | ||
1743 | val apply = | |
1744 | Trace.trace3 ("ElaborateEnv.FunctorClosure.apply", | |
1745 | layout, | |
1746 | Structure.layout, | |
1747 | List.layout String.layout, | |
1748 | (Option.layout Structure.layout) o #2) | |
1749 | apply | |
1750 | ||
1751 | fun forceUsed (T {resultStructure, ...}) = | |
1752 | Option.app (resultStructure, Structure.forceUsed) | |
1753 | end | |
1754 | ||
1755 | (* ------------------------------------------------- *) | |
1756 | (* Basis *) | |
1757 | (* ------------------------------------------------- *) | |
1758 | ||
1759 | structure Basis = | |
1760 | struct | |
1761 | datatype t = T of {plist: PropertyList.t, | |
1762 | bass: (Ast.Basid.t, t) Info.t, | |
1763 | fcts: (Ast.Fctid.t, FunctorClosure.t) Info.t, | |
1764 | fixs: (Ast.Vid.t, Ast.Fixity.t) Info.t, | |
1765 | sigs: (Ast.Sigid.t, Interface.t) Info.t, | |
1766 | strs: (Ast.Strid.t, Structure.t) Info.t, | |
1767 | types: (Ast.Tycon.t, TypeStr.t) Info.t, | |
1768 | vals: (Ast.Vid.t, Vid.t * Scheme.t) Info.t} | |
1769 | ||
1770 | fun layout (T {bass, fcts, sigs, strs, types, vals, ...}) = | |
1771 | Layout.record | |
1772 | [("bass", Info.layout (Ast.Basid.layout, layout) bass), | |
1773 | ("fcts", Info.layout (Ast.Fctid.layout, FunctorClosure.layout) fcts), | |
1774 | ("sigs", Info.layout (Ast.Sigid.layout, Interface.layout) sigs), | |
1775 | ("strs", Info.layout (Ast.Strid.layout, Structure.layout) strs), | |
1776 | ("types", Info.layout (Ast.Tycon.layout, TypeStr.layout) types), | |
1777 | ("vals", (Info.layout (Ast.Vid.layout, Layout.tuple2 (Vid.layout, Scheme.layout)) vals))] | |
1778 | end | |
1779 | ||
1780 | (* ------------------------------------------------- *) | |
1781 | (* NameSpace *) | |
1782 | (* ------------------------------------------------- *) | |
1783 | ||
1784 | structure Values = | |
1785 | struct | |
1786 | type ('a, 'b) value = {domain: 'a, | |
1787 | range: 'b, | |
1788 | scope: Scope.t, | |
1789 | time: Time.t, | |
1790 | uses: 'a Uses.t} | |
1791 | (* The domains of all elements in a values list have the same symbol. *) | |
1792 | datatype ('a, 'b) t = T of ('a, 'b) value list ref | |
1793 | ||
1794 | fun new (): ('a, 'b) t = T (ref []) | |
1795 | ||
1796 | fun ! (T r) = Ref.! r | |
1797 | ||
1798 | fun pop (T r) = List.pop r | |
1799 | end | |
1800 | ||
1801 | structure NameSpace = | |
1802 | struct | |
1803 | datatype ('a, 'b) t = | |
1804 | T of {class: 'b -> Class.t, | |
1805 | current: ('a, 'b) Values.t list ref, | |
1806 | defUses: {class: Class.t, | |
1807 | def: 'a, | |
1808 | range: 'b option, | |
1809 | uses: 'a Uses.t} list ref option, | |
1810 | lookup: 'a -> ('a, 'b) Values.t, | |
1811 | region: 'a -> Region.t, | |
1812 | toSymbol: 'a -> Symbol.t} | |
1813 | ||
1814 | fun values (T {lookup, ...}, a) = lookup a | |
1815 | ||
1816 | (* ------------------------------------------------- *) | |
1817 | (* empty *) | |
1818 | (* ------------------------------------------------- *) | |
1819 | ||
1820 | fun empty {class, defUses, lookup, region, toSymbol} = | |
1821 | T {class = class, | |
1822 | current = ref [], | |
1823 | defUses = if defUses then SOME (ref []) else NONE, | |
1824 | lookup = lookup, | |
1825 | region = region, | |
1826 | toSymbol = toSymbol} | |
1827 | ||
1828 | (* ------------------------------------------------- *) | |
1829 | (* newUses *) | |
1830 | (* ------------------------------------------------- *) | |
1831 | ||
1832 | fun newUses (T {class, defUses, ...}, {def, forceUsed, range}) = | |
1833 | let | |
1834 | val u = Uses.new () | |
1835 | val _ = | |
1836 | if not (warnUnused ()) orelse forceUsed | |
1837 | then Uses.forceUsed u | |
1838 | else () | |
1839 | val _ = | |
1840 | case defUses of | |
1841 | NONE => () | |
1842 | | SOME defUses => | |
1843 | let | |
1844 | val class = class range | |
1845 | val range = | |
1846 | if isSome (!Control.showDefUse) | |
1847 | andalso | |
1848 | (class = Class.Var | |
1849 | orelse | |
1850 | class = Class.Exn | |
1851 | orelse | |
1852 | class = Class.Con) | |
1853 | then SOME range | |
1854 | else NONE | |
1855 | in | |
1856 | List.push (defUses, {class = class, | |
1857 | def = def, | |
1858 | range = range, | |
1859 | uses = u}) | |
1860 | end | |
1861 | in | |
1862 | u | |
1863 | end | |
1864 | ||
1865 | (* ------------------------------------------------- *) | |
1866 | (* peek *) | |
1867 | (* ------------------------------------------------- *) | |
1868 | ||
1869 | fun ('a, 'b) peek (ns, a: 'a, {markUse: 'b -> bool}) | |
1870 | : 'b option = | |
1871 | case Values.! (values (ns, a)) of | |
1872 | [] => NONE | |
1873 | | {range, uses, ...} :: _ => | |
1874 | (if markUse range then Uses.add (uses, a) else () | |
1875 | ; SOME range) | |
1876 | ||
1877 | (* ------------------------------------------------- *) | |
1878 | (* extend *) | |
1879 | (* ------------------------------------------------- *) | |
1880 | ||
1881 | fun extend (ns as T {current, lookup, ...}, | |
1882 | {domain, forceUsed, range, scope, time, uses}) = | |
1883 | let | |
1884 | val newUses = fn () => | |
1885 | newUses | |
1886 | (ns, | |
1887 | {def = domain, | |
1888 | range = range, | |
1889 | forceUsed = forceUsed}) | |
1890 | val values as Values.T r = lookup domain | |
1891 | fun make uses = | |
1892 | {domain = domain, | |
1893 | range = range, | |
1894 | scope = scope, | |
1895 | time = time, | |
1896 | uses = uses} | |
1897 | fun new () = | |
1898 | let | |
1899 | val _ = List.push (current, values) | |
1900 | val uses = | |
1901 | case uses {rebind = NONE} of | |
1902 | NONE => newUses () | |
1903 | | SOME u => u | |
1904 | in | |
1905 | make uses | |
1906 | end | |
1907 | in | |
1908 | case !r of | |
1909 | [] => r := [new ()] | |
1910 | | all as ({domain = domain', scope = scope', uses = uses', ...} :: rest) => | |
1911 | if Scope.equals (scope, scope') | |
1912 | then let | |
1913 | val rebind = SOME {domain = domain', uses = uses'} | |
1914 | val uses = | |
1915 | case uses {rebind = rebind} of | |
1916 | NONE => newUses () | |
1917 | | SOME u => u | |
1918 | in | |
1919 | r := (make uses) :: rest | |
1920 | end | |
1921 | else r := new () :: all | |
1922 | end | |
1923 | ||
1924 | (* ------------------------------------------------- *) | |
1925 | (* scope *) | |
1926 | (* ------------------------------------------------- *) | |
1927 | ||
1928 | fun scope (T {current, ...}: ('a, 'b) t) | |
1929 | : unit -> unit = | |
1930 | let | |
1931 | val old = !current | |
1932 | val _ = current := [] | |
1933 | in | |
1934 | fn () => | |
1935 | let | |
1936 | val c = !current | |
1937 | val _ = List.foreach (c, ignore o Values.pop) | |
1938 | val _ = current := old | |
1939 | in | |
1940 | () | |
1941 | end | |
1942 | end | |
1943 | ||
1944 | (* ------------------------------------------------- *) | |
1945 | (* local *) | |
1946 | (* ------------------------------------------------- *) | |
1947 | ||
1948 | fun locall (T {current, ...}: ('a, 'b) t) = | |
1949 | let | |
1950 | val old = !current | |
1951 | val _ = current := [] | |
1952 | in | |
1953 | fn () => | |
1954 | let | |
1955 | val c1 = !current | |
1956 | val _ = current := [] | |
1957 | in | |
1958 | fn () => | |
1959 | let | |
1960 | val c2 = !current | |
1961 | val elts = List.revMap (c2, fn values => | |
1962 | let | |
1963 | val {domain, range, time, uses, ...} = | |
1964 | Values.pop values | |
1965 | in | |
1966 | {domain = domain, | |
1967 | range = range, | |
1968 | time = time, | |
1969 | uses = uses} | |
1970 | end) | |
1971 | val _ = List.foreach (c1, ignore o Values.pop) | |
1972 | val _ = current := old | |
1973 | in | |
1974 | elts | |
1975 | end | |
1976 | end | |
1977 | end | |
1978 | ||
1979 | (* ------------------------------------------------- *) | |
1980 | (* collect *) | |
1981 | (* ------------------------------------------------- *) | |
1982 | ||
1983 | fun collect (T {current, toSymbol, ...}: ('a, 'b) t) | |
1984 | : unit -> ('a, 'b) Info.t = | |
1985 | let | |
1986 | val old = !current | |
1987 | val _ = current := [] | |
1988 | in | |
1989 | fn () => | |
1990 | let | |
1991 | val elts = | |
1992 | List.revMap (!current, fn values => | |
1993 | let | |
1994 | val {domain, range, time, uses, ...} = | |
1995 | Values.pop values | |
1996 | in | |
1997 | {domain = domain, | |
1998 | range = range, | |
1999 | time = time, | |
2000 | uses = uses} | |
2001 | end) | |
2002 | val _ = current := old | |
2003 | val a = Array.fromList elts | |
2004 | val () = | |
2005 | QuickSort.sortArray | |
2006 | (a, fn ({domain = d, ...}, {domain = d', ...}) => | |
2007 | Symbol.<= (toSymbol d, toSymbol d')) | |
2008 | in | |
2009 | Info.T a | |
2010 | end | |
2011 | end | |
2012 | end | |
2013 | ||
2014 | (* ------------------------------------------------- *) | |
2015 | (* Main Env Datatype *) | |
2016 | (* ------------------------------------------------- *) | |
2017 | ||
2018 | structure All = | |
2019 | struct | |
2020 | datatype t = | |
2021 | Bas of (Basid.t, Basis.t) Values.t | |
2022 | | Fct of (Fctid.t, FunctorClosure.t) Values.t | |
2023 | | Fix of (Ast.Vid.t, Ast.Fixity.t) Values.t | |
2024 | | IfcStr of (Strid.t, Interface.t) Values.t | |
2025 | | IfcTyc of (Ast.Tycon.t, Interface.TypeStr.t) Values.t | |
2026 | | IfcVal of (Ast.Vid.t, Interface.Status.t * Interface.Scheme.t) Values.t | |
2027 | | Sig of (Sigid.t, Interface.t) Values.t | |
2028 | | Str of (Strid.t, Structure.t) Values.t | |
2029 | | Tyc of (Ast.Tycon.t, TypeStr.t) Values.t | |
2030 | | Val of (Ast.Vid.t, Vid.t * Scheme.t) Values.t | |
2031 | ||
2032 | val basOpt = fn Bas z => SOME z | _ => NONE | |
2033 | val fctOpt = fn Fct z => SOME z | _ => NONE | |
2034 | val fixOpt = fn Fix z => SOME z | _ => NONE | |
2035 | val ifcStrOpt = fn IfcStr z => SOME z | _ => NONE | |
2036 | val ifcTycOpt = fn IfcTyc z => SOME z | _ => NONE | |
2037 | val ifcValOpt = fn IfcVal z => SOME z | _ => NONE | |
2038 | val sigOpt = fn Sig z => SOME z | _ => NONE | |
2039 | val strOpt = fn Str z => SOME z | _ => NONE | |
2040 | val tycOpt = fn Tyc z => SOME z | _ => NONE | |
2041 | val valOpt = fn Val z => SOME z | _ => NONE | |
2042 | end | |
2043 | ||
2044 | datatype t = | |
2045 | T of {currentScope: Scope.t ref, | |
2046 | bass: (Ast.Basid.t, Basis.t) NameSpace.t, | |
2047 | fcts: (Ast.Fctid.t, FunctorClosure.t) NameSpace.t, | |
2048 | fixs: (Ast.Vid.t, Ast.Fixity.t) NameSpace.t, | |
2049 | interface: {strs: (Ast.Strid.t, Interface.t) NameSpace.t, | |
2050 | types: (Ast.Tycon.t, Interface.TypeStr.t) NameSpace.t, | |
2051 | vals: (Ast.Vid.t, Interface.Status.t * Interface.Scheme.t) NameSpace.t}, | |
2052 | lookup: Symbol.t -> All.t list ref, | |
2053 | sigs: (Ast.Sigid.t, Interface.t) NameSpace.t, | |
2054 | strs: (Ast.Strid.t, Structure.t) NameSpace.t, | |
2055 | types: (Ast.Tycon.t, TypeStr.t) NameSpace.t, | |
2056 | vals: (Ast.Vid.t, Vid.t * Scheme.t) NameSpace.t} | |
2057 | ||
2058 | fun sizeMessage (E: t): Layout.t = | |
2059 | let | |
2060 | val size = MLton.size | |
2061 | open Layout | |
2062 | in | |
2063 | record [("total", Int.layout (size E))] | |
2064 | end | |
2065 | (* quell unused warning *) | |
2066 | val _ = sizeMessage | |
2067 | ||
2068 | (* ------------------------------------------------- *) | |
2069 | (* empty *) | |
2070 | (* ------------------------------------------------- *) | |
2071 | ||
2072 | fun empty () = | |
2073 | let | |
2074 | val {get = lookupAll: Symbol.t -> All.t list ref, ...} = | |
2075 | Property.get (Symbol.plist, Property.initFun (fn _ => ref [])) | |
2076 | fun ('a, 'b) make (class: 'b -> Class.t, | |
2077 | region: 'a -> Region.t, | |
2078 | toSymbol: 'a -> Symbol.t, | |
2079 | defUses: bool, | |
2080 | extract: All.t -> ('a, 'b) Values.t option, | |
2081 | make: ('a, 'b) Values.t -> All.t) | |
2082 | : ('a, 'b) NameSpace.t = | |
2083 | let | |
2084 | fun lookup (a: 'a): ('a, 'b) Values.t = | |
2085 | let | |
2086 | val r = lookupAll (toSymbol a) | |
2087 | in | |
2088 | case List.peekMap (!r, extract) of | |
2089 | NONE => | |
2090 | let | |
2091 | val v = Values.new () | |
2092 | val _ = List.push (r, make v) | |
2093 | in | |
2094 | v | |
2095 | end | |
2096 | | SOME v => v | |
2097 | end | |
2098 | in | |
2099 | NameSpace.empty {class = class, | |
2100 | defUses = defUses, | |
2101 | lookup = lookup, | |
2102 | region = region, | |
2103 | toSymbol = toSymbol} | |
2104 | end | |
2105 | val bass = make (fn _ => Class.Bas, Basid.region, Basid.toSymbol, | |
2106 | false, All.basOpt, All.Bas) | |
2107 | val fcts = make (fn _ => Class.Fct, Fctid.region, Fctid.toSymbol, | |
2108 | !Control.keepDefUse, All.fctOpt, All.Fct) | |
2109 | val fixs = make (fn _ => Class.Fix, Ast.Vid.region, Ast.Vid.toSymbol, | |
2110 | false, All.fixOpt, All.Fix) | |
2111 | val sigs = make (fn _ => Class.Sig, Sigid.region, Sigid.toSymbol, | |
2112 | !Control.keepDefUse, All.sigOpt, All.Sig) | |
2113 | val strs = make (fn _ => Class.Str, Strid.region, Strid.toSymbol, | |
2114 | !Control.keepDefUse, All.strOpt, All.Str) | |
2115 | val types = make (fn _ => Class.Typ, Ast.Tycon.region, Ast.Tycon.toSymbol, | |
2116 | !Control.keepDefUse, All.tycOpt, All.Tyc) | |
2117 | val vals = make (Vid.class o #1, Ast.Vid.region, Ast.Vid.toSymbol, | |
2118 | !Control.keepDefUse, All.valOpt, All.Val) | |
2119 | ||
2120 | local | |
2121 | val strs = make (fn _ => Class.Str, Strid.region, Strid.toSymbol, | |
2122 | false, All.ifcStrOpt, All.IfcStr) | |
2123 | val types = make (fn _ => Class.Typ, Ast.Tycon.region, Ast.Tycon.toSymbol, | |
2124 | false, All.ifcTycOpt, All.IfcTyc) | |
2125 | val vals = make (Status.class o #1, Ast.Vid.region, Ast.Vid.toSymbol, | |
2126 | false, All.ifcValOpt, All.IfcVal) | |
2127 | in | |
2128 | val interface = {strs = strs, types = types, vals = vals} | |
2129 | end | |
2130 | in | |
2131 | T {currentScope = ref (Scope.new ()), | |
2132 | bass = bass, | |
2133 | fcts = fcts, | |
2134 | fixs = fixs, | |
2135 | interface = interface, | |
2136 | lookup = lookupAll, | |
2137 | sigs = sigs, | |
2138 | strs = strs, | |
2139 | types = types, | |
2140 | vals = vals} | |
2141 | end | |
2142 | ||
2143 | (* ------------------------------------------------- *) | |
2144 | (* foreach *) | |
2145 | (* ------------------------------------------------- *) | |
2146 | ||
2147 | local | |
2148 | fun foreach (T {lookup, ...}, s, | |
2149 | {bass, fcts, fixs, | |
2150 | interface = {strs = ifcStrs, types = ifcTypes, vals = ifcVals}, | |
2151 | sigs, strs, types, vals}) = | |
2152 | List.foreach | |
2153 | (! (lookup s), fn a => | |
2154 | let | |
2155 | datatype z = datatype All.t | |
2156 | in | |
2157 | case a of | |
2158 | Bas vs => bass vs | |
2159 | | Fct vs => fcts vs | |
2160 | | Fix vs => fixs vs | |
2161 | | IfcStr vs => ifcStrs vs | |
2162 | | IfcTyc vs => ifcTypes vs | |
2163 | | IfcVal vs => ifcVals vs | |
2164 | | Sig vs => sigs vs | |
2165 | | Str vs => strs vs | |
2166 | | Tyc vs => types vs | |
2167 | | Val vs => vals vs | |
2168 | end) | |
2169 | in | |
2170 | fun foreachDefinedSymbol (E, z) = | |
2171 | Symbol.foreach (fn s => foreach (E, s, z)) | |
2172 | end | |
2173 | ||
2174 | (* ------------------------------------------------- *) | |
2175 | (* current *) | |
2176 | (* ------------------------------------------------- *) | |
2177 | ||
2178 | fun current (E, keep: {hasUse: bool, scope: Scope.t} -> bool) = | |
2179 | let | |
2180 | val bass = ref [] | |
2181 | val fcts = ref [] | |
2182 | val ifcStrs = ref [] | |
2183 | val ifcTypes = ref [] | |
2184 | val ifcVals = ref [] | |
2185 | val sigs = ref [] | |
2186 | val strs = ref [] | |
2187 | val types = ref [] | |
2188 | val vals = ref [] | |
2189 | fun doit ac vs = | |
2190 | case Values.! vs of | |
2191 | [] => () | |
2192 | | (z as {scope, uses, ...}) :: _ => | |
2193 | if keep {hasUse = Uses.hasUse uses, scope = scope} | |
2194 | then List.push (ac, z) | |
2195 | else () | |
2196 | val _ = | |
2197 | foreachDefinedSymbol (E, {bass = doit bass, | |
2198 | fcts = doit fcts, | |
2199 | fixs = fn _ => (), | |
2200 | interface = {strs = doit ifcStrs, | |
2201 | types = doit ifcTypes, | |
2202 | vals = doit ifcVals}, | |
2203 | sigs = doit sigs, | |
2204 | strs = doit strs, | |
2205 | types = doit types, | |
2206 | vals = doit vals}) | |
2207 | fun ('a, 'b) finish (r: ('a, 'b) Values.value list ref, toSymbol: 'a -> Symbol.t) () = | |
2208 | let | |
2209 | val a = | |
2210 | Array.fromListMap | |
2211 | (!r, fn {domain, range, time, uses, ...} => | |
2212 | {domain = domain, range = range, | |
2213 | time = time, uses = uses}) | |
2214 | val () = | |
2215 | QuickSort.sortArray | |
2216 | (a, fn ({domain = d, ...}, {domain = d', ...}) => | |
2217 | Symbol.<= (toSymbol d, toSymbol d')) | |
2218 | in | |
2219 | Info.T a | |
2220 | end | |
2221 | in | |
2222 | {bass = finish (bass, Basid.toSymbol), | |
2223 | fcts = finish (fcts, Fctid.toSymbol), | |
2224 | interface = {strs = finish (ifcStrs, Strid.toSymbol), | |
2225 | types = finish (ifcTypes, Ast.Tycon.toSymbol), | |
2226 | vals = finish (ifcVals, Ast.Vid.toSymbol)}, | |
2227 | sigs = finish (sigs, Sigid.toSymbol), | |
2228 | strs = finish (strs, Strid.toSymbol), | |
2229 | types = finish (types, Ast.Tycon.toSymbol), | |
2230 | vals = finish (vals, Ast.Vid.toSymbol)} | |
2231 | end | |
2232 | ||
2233 | (* ------------------------------------------------- *) | |
2234 | (* snapshot *) | |
2235 | (* ------------------------------------------------- *) | |
2236 | ||
2237 | fun snapshot (E as T {currentScope, bass, fcts, fixs, sigs, strs, types, vals, ...}) | |
2238 | : (unit -> 'a) -> 'a = | |
2239 | let | |
2240 | val add: (Scope.t -> unit) list ref = ref [] | |
2241 | (* Push onto add everything currently in scope. *) | |
2242 | fun doit (NameSpace.T {current, ...}) (v as Values.T vs) = | |
2243 | case ! vs of | |
2244 | [] => () | |
2245 | | {domain, range, uses, ...} :: _ => | |
2246 | List.push | |
2247 | (add, fn s0 => | |
2248 | (List.push (vs, {domain = domain, | |
2249 | range = range, | |
2250 | scope = s0, | |
2251 | time = Time.next (), | |
2252 | uses = uses}) | |
2253 | ; List.push (current, v))) | |
2254 | val _ = | |
2255 | foreachDefinedSymbol (E, {bass = doit bass, | |
2256 | fcts = doit fcts, | |
2257 | fixs = doit fixs, | |
2258 | interface = {strs = ignore, | |
2259 | types = ignore, | |
2260 | vals = ignore}, | |
2261 | sigs = doit sigs, | |
2262 | strs = doit strs, | |
2263 | types = doit types, | |
2264 | vals = doit vals}) | |
2265 | in | |
2266 | fn th => | |
2267 | let | |
2268 | val s0 = Scope.new () | |
2269 | val restore: (unit -> unit) list ref = ref [] | |
2270 | fun doit (NameSpace.T {current, ...}) = | |
2271 | let | |
2272 | val current0 = !current | |
2273 | val _ = current := [] | |
2274 | in | |
2275 | List.push (restore, fn () => | |
2276 | (List.foreach (!current, fn v => ignore (Values.pop v)) | |
2277 | ; current := current0)) | |
2278 | end | |
2279 | val _ = (doit bass; doit fcts; doit fixs; doit sigs | |
2280 | ; doit strs; doit types; doit vals) | |
2281 | val _ = List.foreach (!add, fn f => f s0) | |
2282 | (* Clear out any symbols that weren't available in the old scope. *) | |
2283 | fun doit (Values.T vs) = | |
2284 | let | |
2285 | val cur = !vs | |
2286 | in | |
2287 | case cur of | |
2288 | [] => () | |
2289 | | {scope, ...} :: _ => | |
2290 | if Scope.equals (s0, scope) | |
2291 | then () | |
2292 | else (vs := [] | |
2293 | ; List.push (restore, fn () => vs := cur)) | |
2294 | end | |
2295 | val _ = | |
2296 | (* Can't use foreachToplevelSymbol here, because a constructor C may | |
2297 | * have been defined in a local scope but may not have been defined | |
2298 | * at the snapshot point. This will make the identifier C, which | |
2299 | * originally would have elaborated as a variable instead elaborate | |
2300 | * as a constructor. | |
2301 | *) | |
2302 | foreachDefinedSymbol (E, {bass = doit, | |
2303 | fcts = doit, | |
2304 | fixs = doit, | |
2305 | interface = {strs = ignore, | |
2306 | types = ignore, | |
2307 | vals = ignore}, | |
2308 | sigs = doit, | |
2309 | strs = doit, | |
2310 | types = doit, | |
2311 | vals = doit}) | |
2312 | val s1 = !currentScope | |
2313 | val _ = currentScope := s0 | |
2314 | val res = th () | |
2315 | val _ = currentScope := s1 | |
2316 | val _ = List.foreach (!restore, fn f => f ()) | |
2317 | in | |
2318 | res | |
2319 | end | |
2320 | end | |
2321 | ||
2322 | (* ------------------------------------------------- *) | |
2323 | (* peek *) | |
2324 | (* ------------------------------------------------- *) | |
2325 | ||
2326 | local | |
2327 | fun make sel (T r, a) = NameSpace.peek (sel r, a, {markUse = fn _ => true}) | |
2328 | in | |
2329 | val peekBasid = make #bass | |
2330 | val peekFctid = make #fcts | |
2331 | val peekFix = make #fixs | |
2332 | val peekIfcStrid = make (#strs o #interface) | |
2333 | val peekIfcTycon= make (#types o #interface) | |
2334 | val peekSigid = make #sigs | |
2335 | val peekStrid = make #strs | |
2336 | val peekTycon = make #types | |
2337 | val peekVid = make #vals | |
2338 | fun peekVar (E, x) = | |
2339 | case peekVid (E, Ast.Vid.fromVar x) of | |
2340 | NONE => NONE | |
2341 | | SOME (vid, s) => Option.map (Vid.deVar vid, fn x => (x, s)) | |
2342 | end | |
2343 | ||
2344 | fun peekCon (T {vals, ...}, c: Ast.Con.t): (Con.t * Scheme.t) option = | |
2345 | case NameSpace.peek (vals, Ast.Vid.fromCon c, | |
2346 | {markUse = fn (vid, _) => isSome (Vid.deCon vid)}) of | |
2347 | NONE => NONE | |
2348 | | SOME (vid, s) => Option.map (Vid.deCon vid, fn c => (c, s)) | |
2349 | ||
2350 | fun peekExn (T {vals, ...}, c: Ast.Con.t): (Con.t * Scheme.t) option = | |
2351 | case NameSpace.peek (vals, Ast.Vid.fromCon c, | |
2352 | {markUse = fn (vid, _) => isSome (Vid.deExn vid)}) of | |
2353 | NONE => NONE | |
2354 | | SOME (vid, s) => Option.map (Vid.deExn vid, fn c => (c, s)) | |
2355 | ||
2356 | structure PeekResult = | |
2357 | struct | |
2358 | datatype 'a t = | |
2359 | Found of 'a | |
2360 | | UndefinedStructure of Strid.t list | |
2361 | | Undefined | |
2362 | ||
2363 | val toOption: 'a t -> 'a option = | |
2364 | fn Found z => SOME z | |
2365 | | _ => NONE | |
2366 | end | |
2367 | ||
2368 | local | |
2369 | fun make (split: 'a -> Strid.t list * 'b, | |
2370 | peek: t * 'b -> 'c option, | |
2371 | strPeek: Structure.t * 'b -> 'c option) (E, x) = | |
2372 | let | |
2373 | val (strids, x) = split x | |
2374 | in | |
2375 | case strids of | |
2376 | [] => (case peek (E, x) of | |
2377 | NONE => PeekResult.Undefined | |
2378 | | SOME z => PeekResult.Found z) | |
2379 | | strid :: strids => | |
2380 | case peekStrid (E, strid) of | |
2381 | NONE => PeekResult.UndefinedStructure [strid] | |
2382 | | SOME S => | |
2383 | case Structure.peekStrids (S, strids) of | |
2384 | Structure.PeekResult.Found S => | |
2385 | (case strPeek (S, x) of | |
2386 | NONE => PeekResult.Undefined | |
2387 | | SOME z => PeekResult.Found z) | |
2388 | | Structure.PeekResult.UndefinedStructure ss => | |
2389 | PeekResult.UndefinedStructure (strid :: ss) | |
2390 | end | |
2391 | in | |
2392 | val peekLongstrid = | |
2393 | make (Ast.Longstrid.split, peekStrid, Structure.peekStrid) | |
2394 | val peekLongtycon = | |
2395 | make (Longtycon.split, peekTycon, Structure.peekTycon) | |
2396 | val peekLongvar = make (Ast.Longvar.split, peekVar, Structure.peekVar) | |
2397 | val peekLongvid = make (Ast.Longvid.split, peekVid, Structure.peekVid) | |
2398 | val peekLongcon = make (Ast.Longcon.split, peekCon, Structure.peekCon) | |
2399 | val peekLongexn = make (Ast.Longcon.split, peekExn, Structure.peekExn) | |
2400 | end | |
2401 | ||
2402 | (* ------------------------------------------------- *) | |
2403 | (* lookup *) | |
2404 | (* ------------------------------------------------- *) | |
2405 | ||
2406 | fun unbound (r: Region.t, className, x: Layout.t): unit = | |
2407 | Control.error | |
2408 | (r, | |
2409 | seq [str "undefined ", str className, str ": ", x], | |
2410 | Layout.empty) | |
2411 | ||
2412 | fun lookupBasid (E, x) = | |
2413 | case peekBasid (E, x) of | |
2414 | NONE => (unbound (Ast.Basid.region x, "basis", Ast.Basid.layout x) | |
2415 | ; NONE) | |
2416 | | SOME f => SOME f | |
2417 | ||
2418 | fun lookupFctid (E, x) = | |
2419 | case peekFctid (E, x) of | |
2420 | NONE => (unbound (Ast.Fctid.region x, "functor", Ast.Fctid.layout x) | |
2421 | ; NONE) | |
2422 | | SOME f => SOME f | |
2423 | ||
2424 | fun lookupSigid (E, x) = | |
2425 | case peekSigid (E, x) of | |
2426 | NONE => (unbound (Ast.Sigid.region x, "signature", Ast.Sigid.layout x) | |
2427 | ; NONE) | |
2428 | | SOME I => SOME I | |
2429 | ||
2430 | fun lookupStrid (E, x) = | |
2431 | case peekStrid (E, x) of | |
2432 | NONE => (unbound (Ast.Strid.region x, "structure", Ast.Strid.layout x) | |
2433 | ; NONE) | |
2434 | | SOME S => SOME S | |
2435 | ||
2436 | local | |
2437 | fun make (peek: t * 'a -> 'b PeekResult.t, | |
2438 | className: string, | |
2439 | region: 'a -> Region.t, | |
2440 | layout: 'a -> Layout.t) | |
2441 | (E: t, x: 'a): 'b option = | |
2442 | let | |
2443 | datatype z = datatype PeekResult.t | |
2444 | in | |
2445 | case peek (E, x) of | |
2446 | Found z => SOME z | |
2447 | | UndefinedStructure ss => | |
2448 | (unbound (region x, "structure", layoutStrids ss); NONE) | |
2449 | | Undefined => | |
2450 | (unbound (region x, className, layout x); NONE) | |
2451 | end | |
2452 | in | |
2453 | val lookupLongcon = | |
2454 | make (peekLongcon, | |
2455 | "constructor", | |
2456 | Ast.Longcon.region, | |
2457 | Ast.Longcon.layout) | |
2458 | val lookupLongexn = | |
2459 | make (peekLongexn, | |
2460 | "exception", | |
2461 | Ast.Longcon.region, | |
2462 | Ast.Longcon.layout) | |
2463 | val lookupLongstrid = | |
2464 | make (peekLongstrid, | |
2465 | "structure", | |
2466 | Ast.Longstrid.region, | |
2467 | Ast.Longstrid.layout) | |
2468 | val lookupLongtycon = | |
2469 | make (peekLongtycon, | |
2470 | "type", | |
2471 | Ast.Longtycon.region, | |
2472 | Ast.Longtycon.layout) | |
2473 | val lookupLongvid = | |
2474 | make (peekLongvid, | |
2475 | "variable", | |
2476 | Ast.Longvid.region, | |
2477 | Ast.Longvid.layout) | |
2478 | val lookupLongvar = | |
2479 | make (peekLongvar, | |
2480 | "variable", | |
2481 | Ast.Longvar.region, | |
2482 | Ast.Longvar.layout) | |
2483 | end | |
2484 | ||
2485 | val peekLongcon = PeekResult.toOption o peekLongcon | |
2486 | ||
2487 | (* ------------------------------------------------- *) | |
2488 | (* extend *) | |
2489 | (* ------------------------------------------------- *) | |
2490 | ||
2491 | local | |
2492 | fun extend (T (r as {currentScope, ...}), sel, | |
2493 | domain: 'a, range: 'b, forceUsed: bool, uses) = | |
2494 | NameSpace.extend | |
2495 | (sel r, | |
2496 | {domain = domain, | |
2497 | forceUsed = forceUsed, | |
2498 | range = range, | |
2499 | scope = !currentScope, | |
2500 | time = Time.next (), | |
2501 | uses = uses}) | |
2502 | in | |
2503 | fun extendBasid (E, d, r) = extend (E, #bass, d, r, false, Uses.Extend.new) | |
2504 | fun extendFctid (E, d, r) = extend (E, #fcts, d, r, false, Uses.Extend.new) | |
2505 | fun extendFix (E, d, r) = extend (E, #fixs, d, r, false, Uses.Extend.new) | |
2506 | fun extendSigid (E, d, r) = extend (E, #sigs, d, r, false, Uses.Extend.new) | |
2507 | fun extendStrid (E, d, r) = extend (E, #strs, d, r, false, Uses.Extend.new) | |
2508 | fun extendVals (E, d, r, eu) = extend (E, #vals, d, r, false, eu) | |
2509 | fun extendTycon (E, d, s, {forceUsed, isRebind}) = | |
2510 | let | |
2511 | val () = | |
2512 | let | |
2513 | datatype z = datatype TypeStr.node | |
2514 | in | |
2515 | case TypeStr.node s of | |
2516 | Datatype {cons, ...} => | |
2517 | Vector.foreach | |
2518 | (Cons.dest cons, fn {con, name, scheme, uses} => | |
2519 | extendVals (E, Ast.Vid.fromCon name, | |
2520 | (Vid.Con con, scheme), | |
2521 | Uses.Extend.old uses)) | |
2522 | | _ => () | |
2523 | end | |
2524 | val _ = | |
2525 | extend (E, #types, d, s, forceUsed, | |
2526 | Uses.Extend.fromIsRebind {isRebind = isRebind}) | |
2527 | in | |
2528 | () | |
2529 | end | |
2530 | end | |
2531 | ||
2532 | fun extendExn (E, c, c', s) = | |
2533 | extendVals (E, Ast.Vid.fromCon c, (Vid.Exn c', s), Uses.Extend.new) | |
2534 | ||
2535 | fun extendVar (E, x, x', s, ir) = | |
2536 | extendVals (E, Ast.Vid.fromVar x, (Vid.Var x', s), | |
2537 | Uses.Extend.fromIsRebind ir) | |
2538 | ||
2539 | val extendVar = | |
2540 | Trace.trace | |
2541 | ("ElaborateEnv.extendVar", | |
2542 | fn (_, x, x', s, _) => | |
2543 | Layout.tuple [Ast.Var.layout x, Var.layout x', Scheme.layout s], | |
2544 | Unit.layout) | |
2545 | extendVar | |
2546 | ||
2547 | fun extendOverload (E, p, x, yts, s) = | |
2548 | extendVals (E, Ast.Vid.fromVar x, (Vid.Overload (p, yts), s), | |
2549 | Uses.Extend.new) | |
2550 | ||
2551 | (* ------------------------------------------------- *) | |
2552 | (* scope *) | |
2553 | (* ------------------------------------------------- *) | |
2554 | ||
2555 | fun scopeAll (T {currentScope, bass, fcts, fixs, sigs, strs, types, vals, ...}, th) = | |
2556 | let | |
2557 | val b = NameSpace.scope bass | |
2558 | val fc = NameSpace.scope fcts | |
2559 | val f = NameSpace.scope fixs | |
2560 | val si = NameSpace.scope sigs | |
2561 | val s = NameSpace.scope strs | |
2562 | val t = NameSpace.scope types | |
2563 | val v = NameSpace.scope vals | |
2564 | val s0 = !currentScope | |
2565 | val _ = currentScope := Scope.new () | |
2566 | val res = th () | |
2567 | val _ = (b (); fc (); f (); si (); s (); t (); v ()) | |
2568 | val _ = currentScope := s0 | |
2569 | in | |
2570 | res | |
2571 | end | |
2572 | ||
2573 | fun scope (T {currentScope, fixs, strs, types, vals, ...}, th) = | |
2574 | let | |
2575 | val f = NameSpace.scope fixs | |
2576 | val s = NameSpace.scope strs | |
2577 | val t = NameSpace.scope types | |
2578 | val v = NameSpace.scope vals | |
2579 | val s0 = !currentScope | |
2580 | val _ = currentScope := Scope.new () | |
2581 | val res = th () | |
2582 | val _ = (f (); s (); t (); v ()) | |
2583 | val _ = currentScope := s0 | |
2584 | in | |
2585 | res | |
2586 | end | |
2587 | ||
2588 | (* ------------------------------------------------- *) | |
2589 | (* local *) | |
2590 | (* ------------------------------------------------- *) | |
2591 | ||
2592 | local | |
2593 | fun locall (ns, s0) = | |
2594 | let | |
2595 | val f = NameSpace.locall ns | |
2596 | in | |
2597 | fn () => | |
2598 | let | |
2599 | val f = f () | |
2600 | in | |
2601 | fn () => | |
2602 | let | |
2603 | val elts = f () | |
2604 | val _ = | |
2605 | List.foreach (elts, fn {domain, range, time, uses} => | |
2606 | NameSpace.extend | |
2607 | (ns, {domain = domain, | |
2608 | forceUsed = false, | |
2609 | range = range, | |
2610 | scope = s0, | |
2611 | time = time, | |
2612 | uses = Uses.Extend.old uses})) | |
2613 | in | |
2614 | () | |
2615 | end | |
2616 | end | |
2617 | end | |
2618 | in | |
2619 | fun localAll (T {currentScope, bass, fcts, fixs, sigs, strs, types, vals, ...}, | |
2620 | f1, f2) = | |
2621 | let | |
2622 | val s0 = !currentScope | |
2623 | val bass = locall (bass, s0) | |
2624 | val fcts = locall (fcts, s0) | |
2625 | val fixs = locall (fixs, s0) | |
2626 | val sigs = locall (sigs, s0) | |
2627 | val strs = locall (strs, s0) | |
2628 | val types = locall (types, s0) | |
2629 | val vals = locall (vals, s0) | |
2630 | val _ = currentScope := Scope.new () | |
2631 | val a1 = f1 () | |
2632 | val bass = bass () | |
2633 | val fcts = fcts () | |
2634 | val fixs = fixs () | |
2635 | val sigs = sigs () | |
2636 | val strs = strs () | |
2637 | val types = types () | |
2638 | val vals = vals () | |
2639 | val _ = currentScope := Scope.new () | |
2640 | val a2 = f2 a1 | |
2641 | val _ = (bass (); fcts (); fixs (); sigs (); strs (); types (); vals ()) | |
2642 | val _ = currentScope := s0 | |
2643 | in | |
2644 | a2 | |
2645 | end | |
2646 | ||
2647 | fun localModule (T {currentScope, fixs, strs, types, vals, ...}, | |
2648 | f1, f2) = | |
2649 | let | |
2650 | val s0 = !currentScope | |
2651 | val fixs = locall (fixs, s0) | |
2652 | val strs = locall (strs, s0) | |
2653 | val types = locall (types, s0) | |
2654 | val vals = locall (vals, s0) | |
2655 | val _ = currentScope := Scope.new () | |
2656 | val a1 = f1 () | |
2657 | val fixs = fixs () | |
2658 | val strs = strs () | |
2659 | val types = types () | |
2660 | val vals = vals () | |
2661 | val _ = currentScope := Scope.new () | |
2662 | val a2 = f2 a1 | |
2663 | val _ = (fixs (); strs (); types (); vals ()) | |
2664 | val _ = currentScope := s0 | |
2665 | in | |
2666 | a2 | |
2667 | end | |
2668 | ||
2669 | (* Can't eliminate the use of strs in localCore, because openn still modifies | |
2670 | * module level constructs. | |
2671 | *) | |
2672 | val localCore = localModule | |
2673 | end | |
2674 | ||
2675 | (* ------------------------------------------------- *) | |
2676 | (* makeBasis / makeStructure *) | |
2677 | (* ------------------------------------------------- *) | |
2678 | ||
2679 | fun makeBasis (T {currentScope, bass, fcts, fixs, sigs, strs, types, vals, ...}, make) = | |
2680 | let | |
2681 | val bass = NameSpace.collect bass | |
2682 | val fcts = NameSpace.collect fcts | |
2683 | val fixs = NameSpace.collect fixs | |
2684 | val sigs = NameSpace.collect sigs | |
2685 | val strs = NameSpace.collect strs | |
2686 | val types = NameSpace.collect types | |
2687 | val vals = NameSpace.collect vals | |
2688 | val s0 = !currentScope | |
2689 | val _ = currentScope := Scope.new () | |
2690 | val res = make () | |
2691 | val B = Basis.T {plist = PropertyList.new (), | |
2692 | bass = bass (), | |
2693 | fcts = fcts (), | |
2694 | fixs = fixs (), | |
2695 | sigs = sigs (), | |
2696 | strs = strs (), | |
2697 | types = types (), | |
2698 | vals = vals ()} | |
2699 | val _ = currentScope := s0 | |
2700 | in | |
2701 | (res, B) | |
2702 | end | |
2703 | ||
2704 | fun makeStructure (T {currentScope, fixs, strs, types, vals, ...}, make) = | |
2705 | let | |
2706 | val f = NameSpace.collect fixs | |
2707 | val s = NameSpace.collect strs | |
2708 | val t = NameSpace.collect types | |
2709 | val v = NameSpace.collect vals | |
2710 | val s0 = !currentScope | |
2711 | val _ = currentScope := Scope.new () | |
2712 | val res = make () | |
2713 | val _ = f () | |
2714 | val S = Structure.T {interface = NONE, | |
2715 | plist = PropertyList.new (), | |
2716 | strs = s (), | |
2717 | types = t (), | |
2718 | vals = v ()} | |
2719 | val _ = currentScope := s0 | |
2720 | in | |
2721 | (res, S) | |
2722 | end | |
2723 | ||
2724 | (* ------------------------------------------------- *) | |
2725 | (* open *) | |
2726 | (* ------------------------------------------------- *) | |
2727 | ||
2728 | local | |
2729 | fun openn (ns, Info.T a, s) = | |
2730 | Array.foreach (a, fn {domain, range, time, uses} => | |
2731 | NameSpace.extend (ns, {domain = domain, | |
2732 | forceUsed = false, | |
2733 | range = range, | |
2734 | scope = s, | |
2735 | time = time, | |
2736 | uses = Uses.Extend.old uses})) | |
2737 | in | |
2738 | fun openBasis (T {currentScope, bass, fcts, fixs, sigs, strs, vals, types, ...}, | |
2739 | Basis.T {bass = bass', | |
2740 | fcts = fcts', | |
2741 | fixs = fixs', | |
2742 | sigs = sigs', | |
2743 | strs = strs', | |
2744 | vals = vals', | |
2745 | types = types', ...}): unit = | |
2746 | let | |
2747 | val s0 = !currentScope | |
2748 | val _ = openn (bass, bass', s0) | |
2749 | val _ = openn (fcts, fcts', s0) | |
2750 | val _ = openn (fixs, fixs', s0) | |
2751 | val _ = openn (sigs, sigs', s0) | |
2752 | val _ = openn (strs, strs', s0) | |
2753 | val _ = openn (vals, vals', s0) | |
2754 | val _ = openn (types, types', s0) | |
2755 | in | |
2756 | () | |
2757 | end | |
2758 | ||
2759 | fun openStructure (T {currentScope, strs, vals, types, ...}, | |
2760 | Structure.T {strs = strs', | |
2761 | vals = vals', | |
2762 | types = types', ...}): unit = | |
2763 | let | |
2764 | val s0 = !currentScope | |
2765 | val _ = openn (strs, strs', s0) | |
2766 | val _ = openn (vals, vals', s0) | |
2767 | val _ = openn (types, types', s0) | |
2768 | in | |
2769 | () | |
2770 | end | |
2771 | end | |
2772 | ||
2773 | (* ------------------------------------------------- *) | |
2774 | (* forceUsed *) | |
2775 | (* ------------------------------------------------- *) | |
2776 | ||
2777 | (* Force everything that is currently in scope to be marked as used. *) | |
2778 | fun forceUsed E = | |
2779 | let | |
2780 | fun doit forceRange (Values.T r) = | |
2781 | case !r of | |
2782 | [] => () | |
2783 | | {uses, range, ...} :: _ => | |
2784 | (Uses.forceUsed uses | |
2785 | ; forceRange range) | |
2786 | val _ = | |
2787 | foreachDefinedSymbol | |
2788 | (E, {bass = doit ignore, | |
2789 | fcts = doit FunctorClosure.forceUsed, | |
2790 | fixs = doit ignore, | |
2791 | interface = {strs = doit ignore, | |
2792 | types = doit ignore, | |
2793 | vals = doit ignore}, | |
2794 | sigs = doit ignore, | |
2795 | strs = doit Structure.forceUsed, | |
2796 | types = doit ignore, | |
2797 | vals = doit ignore}) | |
2798 | in | |
2799 | () | |
2800 | end | |
2801 | ||
2802 | fun forceUsedLocal (T {currentScope, bass, fcts, fixs, sigs, strs, types, vals, ...}, | |
2803 | th) = | |
2804 | let | |
2805 | fun doit (forceRange: 'b -> unit, ns as NameSpace.T {current, ...}, s0) = | |
2806 | let | |
2807 | val old = !current | |
2808 | val _ = current := [] | |
2809 | in | |
2810 | fn () => | |
2811 | let | |
2812 | val c = !current | |
2813 | val lift = List.revMap (c, Values.pop) | |
2814 | val _ = current := old | |
2815 | val _ = | |
2816 | List.foreach | |
2817 | (lift, fn {domain, range, time, uses, ...} => | |
2818 | (Uses.forceUsed uses | |
2819 | ; forceRange range | |
2820 | ; NameSpace.extend (ns, {domain = domain, | |
2821 | forceUsed = false, | |
2822 | range = range, | |
2823 | scope = s0, | |
2824 | time = time, | |
2825 | uses = Uses.Extend.old uses}))) | |
2826 | in | |
2827 | () | |
2828 | end | |
2829 | end | |
2830 | val s0 = !currentScope | |
2831 | val bass = doit (ignore, bass, s0) | |
2832 | val fcts = doit (FunctorClosure.forceUsed, fcts, s0) | |
2833 | val fixs = doit (ignore, fixs, s0) | |
2834 | val sigs = doit (ignore, sigs, s0) | |
2835 | val strs = doit (Structure.forceUsed, strs, s0) | |
2836 | val types = doit (ignore, types, s0) | |
2837 | val vals = doit (ignore, vals, s0) | |
2838 | val _ = currentScope := Scope.new () | |
2839 | val res = th () | |
2840 | val _ = (bass(); fcts (); fixs (); sigs (); strs (); types (); vals ()) | |
2841 | val _ = currentScope := s0 | |
2842 | in | |
2843 | res | |
2844 | end | |
2845 | ||
2846 | (* ------------------------------------------------- *) | |
2847 | (* InterfaceEnv *) | |
2848 | (* ------------------------------------------------- *) | |
2849 | ||
2850 | structure InterfaceEnv = | |
2851 | struct | |
2852 | structure Env = | |
2853 | struct | |
2854 | val lookupLongtycon = lookupLongtycon | |
2855 | val peekIfcStrid = peekIfcStrid | |
2856 | val peekIfcTycon = peekIfcTycon | |
2857 | val lookupSigid = lookupSigid | |
2858 | end | |
2859 | ||
2860 | local | |
2861 | open Interface | |
2862 | in | |
2863 | structure FlexibleTycon = FlexibleTycon | |
2864 | structure Scheme = Scheme | |
2865 | structure Status = Status | |
2866 | structure TypeStr = TypeStr | |
2867 | end | |
2868 | ||
2869 | type t = t | |
2870 | ||
2871 | (* ------------------------------------------------- *) | |
2872 | (* peek *) | |
2873 | (* ------------------------------------------------- *) | |
2874 | ||
2875 | val peekStrid = Env.peekIfcStrid | |
2876 | val peekTycon = Env.peekIfcTycon | |
2877 | ||
2878 | (* ------------------------------------------------- *) | |
2879 | (* lookup *) | |
2880 | (* ------------------------------------------------- *) | |
2881 | ||
2882 | val lookupSigid = Env.lookupSigid | |
2883 | ||
2884 | fun lookupLongtycon (E: t, long: Longtycon.t): TypeStr.t option = | |
2885 | let | |
2886 | fun lookupEnv () = | |
2887 | Option.map (Env.lookupLongtycon (E, long), TypeStr.fromEnv) | |
2888 | val (strids, c) = Longtycon.split long | |
2889 | in | |
2890 | case strids of | |
2891 | [] => | |
2892 | (case peekTycon (E, c) of | |
2893 | NONE => lookupEnv () | |
2894 | | SOME s => SOME s) | |
2895 | | s :: ss => | |
2896 | case peekStrid (E, s) of | |
2897 | NONE => lookupEnv () | |
2898 | | SOME I => | |
2899 | ((fn opt => Option.map (opt, #2)) o Interface.lookupLongtycon) | |
2900 | (I, Longtycon.long (ss, c), Longtycon.region long, | |
2901 | {prefix = [s]}) | |
2902 | end | |
2903 | ||
2904 | (* ------------------------------------------------- *) | |
2905 | (* extend *) | |
2906 | (* ------------------------------------------------- *) | |
2907 | ||
2908 | datatype z = MustExtend of Region.t | MustRebind | |
2909 | ||
2910 | fun extend (T {currentScope, interface, ...}, sel, | |
2911 | domain, range, kind, must) = | |
2912 | NameSpace.extend | |
2913 | (sel interface, | |
2914 | {domain = domain, | |
2915 | forceUsed = true, | |
2916 | range = range, | |
2917 | scope = !currentScope, | |
2918 | time = Time.next (), | |
2919 | uses = (case must of | |
2920 | MustExtend extendRegion => | |
2921 | (fn {rebind} => | |
2922 | let | |
2923 | val NameSpace.T {region, toSymbol, ...} = sel interface | |
2924 | val () = | |
2925 | case rebind of | |
2926 | SOME {domain = domain', ...} => | |
2927 | let | |
2928 | open Layout | |
2929 | in | |
2930 | Control.error | |
2931 | (extendRegion, | |
2932 | seq [str "duplicate ", | |
2933 | str kind, | |
2934 | str " specification: ", | |
2935 | Symbol.layout (toSymbol domain)], | |
2936 | (align o List.map) | |
2937 | (if Region.equals (extendRegion, | |
2938 | region domain) | |
2939 | then [domain'] | |
2940 | else [domain', domain], | |
2941 | fn d => seq [str "spec at: ", | |
2942 | Region.layout (region d)])) | |
2943 | end | |
2944 | | _ => () | |
2945 | in | |
2946 | NONE | |
2947 | end) | |
2948 | | MustRebind => | |
2949 | (fn {rebind} => | |
2950 | case rebind of | |
2951 | NONE => | |
2952 | Error.bug "ElaborateEnv.InterfaceEnv.extend: MustRebind" | |
2953 | | SOME {uses, ...} => | |
2954 | SOME uses))}) | |
2955 | ||
2956 | fun extendStrid (E, s, I, r) = | |
2957 | extend (E, #strs, s, I, "structure", MustExtend r) | |
2958 | ||
2959 | fun extendTycon (E, c, s, r) = | |
2960 | extend (E, #types, c, s, "type", MustExtend r) | |
2961 | ||
2962 | fun extendVid (E, v, st, s, r) = | |
2963 | extend (E, #vals, v, (st, s), "value", MustExtend r) | |
2964 | ||
2965 | fun rebindTycon (E, c, s) = | |
2966 | extend (E, #types, c, s, "type", MustRebind) | |
2967 | ||
2968 | (* ------------------------------------------------- *) | |
2969 | (* makeInterface *) | |
2970 | (* ------------------------------------------------- *) | |
2971 | ||
2972 | fun makeInterface (T {currentScope, interface = {strs, types, vals}, ...}, | |
2973 | {isTop}, make) = | |
2974 | let | |
2975 | val s = NameSpace.collect strs | |
2976 | val t = NameSpace.collect types | |
2977 | val v = NameSpace.collect vals | |
2978 | val s0 = !currentScope | |
2979 | val _ = currentScope := Scope.new () | |
2980 | val res = make () | |
2981 | val Info.T s = s () | |
2982 | val s = Array.map (s, fn {domain, range, ...} => (domain, range)) | |
2983 | val Info.T t = t () | |
2984 | val t = Array.map (t, fn {domain, range, ...} => (domain, range)) | |
2985 | val Info.T v = v () | |
2986 | val v = Array.map (v, fn {domain, range = (status, scheme), ...} => | |
2987 | (domain, (status, scheme))) | |
2988 | val I = Interface.new {isClosed = isTop, | |
2989 | original = NONE, | |
2990 | strs = s, types = t, vals = v} | |
2991 | val _ = currentScope := s0 | |
2992 | in | |
2993 | (I, res) | |
2994 | end | |
2995 | ||
2996 | (* ------------------------------------------------- *) | |
2997 | (* openInterface *) | |
2998 | (* ------------------------------------------------- *) | |
2999 | ||
3000 | fun openInterface (E, I, r: Region.t) = | |
3001 | let | |
3002 | val {strs, vals, types} = Interface.dest I | |
3003 | val _ = Array.foreach (strs, fn (s, I) => extendStrid (E, s, I, r)) | |
3004 | val _ = Array.foreach (types, fn (c, s) => extendTycon (E, c, s, r)) | |
3005 | val _ = Array.foreach (vals, fn (x, (s, sc)) => | |
3006 | extendVid (E, x, s, sc, r)) | |
3007 | in | |
3008 | () | |
3009 | end | |
3010 | ||
3011 | (* ------------------------------------------------- *) | |
3012 | (* extend *) | |
3013 | (* ------------------------------------------------- *) | |
3014 | ||
3015 | val extendStrid = fn (E, s, I) => extendStrid (E, s, I, Strid.region s) | |
3016 | ||
3017 | val extendTycon = fn (E, c, s) => extendTycon (E, c, s, Ast.Tycon.region c) | |
3018 | ||
3019 | val extendVid = fn (E, v, st, s) => extendVid (E, v, st, s, Ast.Vid.region v) | |
3020 | ||
3021 | fun extendCon (E, c, s) = | |
3022 | extendVid (E, Ast.Vid.fromCon c, Status.Con, s) | |
3023 | ||
3024 | fun extendExn (E, c, s) = | |
3025 | extendVid (E, Ast.Vid.fromCon c, Status.Exn, s) | |
3026 | ||
3027 | (* ------------------------------------------------- *) | |
3028 | (* makeLayoutPrettyFlexTycon *) | |
3029 | (* ------------------------------------------------- *) | |
3030 | ||
3031 | fun genLayoutPrettyFlexTycon {prefixUnset} = | |
3032 | let | |
3033 | val {destroy = destroyLayoutPrettyFlexTycon: unit -> unit, | |
3034 | get = layoutPrettyFlexTycon: FlexibleTycon.t -> Layout.t, | |
3035 | set = setLayoutPrettyFlexTycon: FlexibleTycon.t * Layout.t -> unit} = | |
3036 | Property.destGetSet | |
3037 | (FlexibleTycon.plist, | |
3038 | Property.initFun | |
3039 | (fn f => | |
3040 | let val l = FlexibleTycon.layoutPrettyDefault f | |
3041 | in if prefixUnset then seq [str "??.", l] else l | |
3042 | end)) | |
3043 | fun doFlexTycon (flex, name, strids: Strid.t list) = | |
3044 | let | |
3045 | val name = layoutLongRev (strids, Ast.Tycon.layout name) | |
3046 | in | |
3047 | setLayoutPrettyFlexTycon (flex, name) | |
3048 | end | |
3049 | fun loopFlexTyconMap (TyconMap.T {strs, types}, strids) = | |
3050 | let | |
3051 | val () = | |
3052 | Array.foreach | |
3053 | (types, fn (name, flex) => | |
3054 | doFlexTycon (flex, name, strids)) | |
3055 | val () = | |
3056 | Array.foreach | |
3057 | (strs, fn (name, flexTyconMap) => | |
3058 | loopFlexTyconMap (flexTyconMap, name::strids)) | |
3059 | in | |
3060 | () | |
3061 | end | |
3062 | in | |
3063 | {destroy = destroyLayoutPrettyFlexTycon, | |
3064 | layoutPrettyFlexTycon = layoutPrettyFlexTycon, | |
3065 | loopFlexTyconMap = loopFlexTyconMap} | |
3066 | end | |
3067 | ||
3068 | end | |
3069 | ||
3070 | val makeInterfaceEnv = fn E => E | |
3071 | ||
3072 | (* ------------------------------------------------- *) | |
3073 | (* makeLayoutPrettyTycon *) | |
3074 | (* ------------------------------------------------- *) | |
3075 | ||
3076 | fun genLayoutPrettyTycon {prefixUnset} = | |
3077 | let | |
3078 | val {destroy = destroyLayoutPrettyTycon: unit -> unit, | |
3079 | get = layoutPrettyTycon: Tycon.t -> Layout.t, | |
3080 | set = setLayoutPrettyTycon: Tycon.t * Layout.t -> unit} = | |
3081 | Property.destGetSet | |
3082 | (Tycon.plist, | |
3083 | Property.initFun | |
3084 | (fn c => | |
3085 | let val l = Tycon.layoutPrettyDefault c | |
3086 | in if prefixUnset then seq [str "?.", l] else l | |
3087 | end)) | |
3088 | val {destroy = destroyTyconShortest, | |
3089 | get = tyconShortest: Tycon.t -> (int * int) option ref, ...} = | |
3090 | Property.destGet (Tycon.plist, Property.initFun (fn _ => ref NONE)) | |
3091 | fun doType (typeStr: TypeStr.t, | |
3092 | name: Ast.Tycon.t, | |
3093 | priority: int, | |
3094 | length: int, | |
3095 | strids: Strid.t list): unit = | |
3096 | case TypeStr.toTyconOpt typeStr of | |
3097 | NONE => () | |
3098 | | SOME c => | |
3099 | let | |
3100 | val r = tyconShortest c | |
3101 | fun doit () = | |
3102 | let | |
3103 | val _ = r := SOME (priority, length) | |
3104 | val name = layoutLongRev (strids, Ast.Tycon.layout name) | |
3105 | in | |
3106 | setLayoutPrettyTycon (c, name) | |
3107 | end | |
3108 | in | |
3109 | case !r of | |
3110 | NONE => doit () | |
3111 | | SOME (priority', length') => | |
3112 | (case Int.compare (priority, priority') of | |
3113 | LESS => doit () | |
3114 | | EQUAL => if length >= length' | |
3115 | then () | |
3116 | else doit () | |
3117 | | GREATER => ()) | |
3118 | end | |
3119 | val {destroy = destroyStrShortest, | |
3120 | get = strShortest: Structure.t -> (int * int) option ref, ...} = | |
3121 | Property.destGet (Structure.plist, Property.initFun (fn _ => ref NONE)) | |
3122 | fun loopStr (s as Structure.T {strs, types, ...}, | |
3123 | priority: int, | |
3124 | length: int, | |
3125 | strids: Strid.t list): unit = | |
3126 | let | |
3127 | val r = strShortest s | |
3128 | fun doit () = | |
3129 | let | |
3130 | val _ = r := SOME (priority, length) | |
3131 | (* Process the declarations in decreasing order of | |
3132 | * definition time so that later declarations will be | |
3133 | * processed first, and hence will take precedence. | |
3134 | *) | |
3135 | val _ = | |
3136 | Info.foreachByTime | |
3137 | (types, fn (name, typeStr) => | |
3138 | doType (typeStr, name, priority, length, strids)) | |
3139 | val _ = | |
3140 | Info.foreachByTime | |
3141 | (strs, fn (strid, str) => | |
3142 | loopStr (str, priority, 1 + length, strid::strids)) | |
3143 | in | |
3144 | () | |
3145 | end | |
3146 | in | |
3147 | case !r of | |
3148 | NONE => doit () | |
3149 | | SOME (priority', length') => | |
3150 | (case Int.compare (priority, priority') of | |
3151 | LESS => doit () | |
3152 | | EQUAL => if length >= length' | |
3153 | then () | |
3154 | else doit () | |
3155 | | GREATER => ()) | |
3156 | end | |
3157 | fun loopFlexTyconMap (tm: FlexibleTycon.t TyconMap.t, priority, length: int, strids: Strid.t list): unit = | |
3158 | let | |
3159 | val TyconMap.T {strs, types} = tm | |
3160 | val _ = | |
3161 | Array.foreach | |
3162 | (types, fn (name, flex) => | |
3163 | doType (FlexibleTycon.toEnv flex, name, priority, length, strids)) | |
3164 | val _ = | |
3165 | Array.foreach | |
3166 | (strs, fn (strid, tm) => | |
3167 | loopFlexTyconMap (tm, priority, 1 + length, strid::strids)) | |
3168 | in | |
3169 | () | |
3170 | end | |
3171 | fun mk loop (z, priority, strids) = | |
3172 | loop (z, priority, length strids, strids) | |
3173 | in | |
3174 | {destroy = fn () => (destroyStrShortest () | |
3175 | ; destroyTyconShortest () | |
3176 | ; destroyLayoutPrettyTycon ()), | |
3177 | layoutPrettyTycon = layoutPrettyTycon, | |
3178 | setLayoutPrettyTycon = setLayoutPrettyTycon, | |
3179 | loopStr = mk loopStr, | |
3180 | loopFlexTyconMap = mk loopFlexTyconMap} | |
3181 | end | |
3182 | ||
3183 | fun makeLayoutPrettyTycon (E, {prefixUnset}) = | |
3184 | let | |
3185 | val {destroy = destroyLayoutPrettyTycon, | |
3186 | layoutPrettyTycon, setLayoutPrettyTycon, | |
3187 | loopStr, ...} = | |
3188 | genLayoutPrettyTycon {prefixUnset = prefixUnset} | |
3189 | fun pre () = | |
3190 | let | |
3191 | val {strs, types, ...} = current (E, fn _ => true) | |
3192 | in | |
3193 | loopStr (Structure.T {interface = NONE, | |
3194 | plist = PropertyList.new (), | |
3195 | strs = strs (), | |
3196 | types = types (), | |
3197 | vals = Info.T (Array.new0 ())}, | |
3198 | 0, []) | |
3199 | end | |
3200 | val pre = ClearablePromise.delay pre | |
3201 | in | |
3202 | {destroy = fn () => (ClearablePromise.clear pre | |
3203 | ; destroyLayoutPrettyTycon ()), | |
3204 | layoutPrettyTycon = fn c => (ClearablePromise.force pre | |
3205 | ; layoutPrettyTycon c), | |
3206 | setLayoutPrettyTycon = setLayoutPrettyTycon, | |
3207 | loopStr = loopStr} | |
3208 | end | |
3209 | ||
3210 | fun makeLayoutPrettyTyconAndFlexTycon (E, _, Io, {prefixUnset}) = | |
3211 | let | |
3212 | val {destroy = destroyLayoutPrettyFlexTycon, | |
3213 | layoutPrettyFlexTycon, loopFlexTyconMap, ...} = | |
3214 | InterfaceEnv.genLayoutPrettyFlexTycon {prefixUnset = prefixUnset} | |
3215 | val {destroy = destroyLayoutPrettyTycon, | |
3216 | layoutPrettyTycon, setLayoutPrettyTycon, | |
3217 | loopStr, ...} = | |
3218 | genLayoutPrettyTycon {prefixUnset = prefixUnset} | |
3219 | fun pre () = | |
3220 | let | |
3221 | val {strs, types, interface = {strs = ifcStrs, types = ifcTypes, ...}, ...} = | |
3222 | current (E, fn _ => true) | |
3223 | val strs = strs () | |
3224 | val types = types () | |
3225 | val ifcStrs = ifcStrs () | |
3226 | val ifcTypes = ifcTypes () | |
3227 | local | |
3228 | fun doit (env, ifc, toSymbol) = | |
3229 | if Info.isEmpty ifc | |
3230 | then env | |
3231 | else Info.keepAll | |
3232 | (env, fn {domain, ...} => | |
3233 | case Info.peek (ifc, domain, toSymbol) of | |
3234 | NONE => true | |
3235 | | SOME _ => false) | |
3236 | in | |
3237 | val () = loopStr (Structure.T {interface = NONE, | |
3238 | plist = PropertyList.new (), | |
3239 | strs = doit (strs, ifcStrs, Ast.Strid.toSymbol), | |
3240 | types = doit (types, ifcTypes, Ast.Tycon.toSymbol), | |
3241 | vals = Info.T (Array.new0 ())}, | |
3242 | 0, []) | |
3243 | end | |
3244 | local | |
3245 | fun doit ifc = | |
3246 | let val Info.T a = ifc | |
3247 | in Array.map (a, fn {domain, range, ...} => (domain, range)) | |
3248 | end | |
3249 | val I = Interface.new {isClosed = true, | |
3250 | original = NONE, | |
3251 | strs = doit ifcStrs, | |
3252 | types = doit ifcTypes, | |
3253 | vals = Array.new0 ()} | |
3254 | in | |
3255 | val () = loopFlexTyconMap (Interface.flexibleTycons I, []) | |
3256 | end | |
3257 | val () = Option.foreach | |
3258 | (Io, fn I => | |
3259 | loopFlexTyconMap (Interface.flexibleTycons I, | |
3260 | [Ast.Strid.uSig])) | |
3261 | in | |
3262 | () | |
3263 | end | |
3264 | val pre = ClearablePromise.delay pre | |
3265 | in | |
3266 | {destroy = fn () => (ClearablePromise.clear pre | |
3267 | ; destroyLayoutPrettyFlexTycon () | |
3268 | ; destroyLayoutPrettyTycon ()), | |
3269 | layoutPrettyTycon = fn c => (ClearablePromise.force pre | |
3270 | ; layoutPrettyTycon c), | |
3271 | layoutPrettyFlexTycon = fn f => (ClearablePromise.force pre | |
3272 | ; layoutPrettyFlexTycon f), | |
3273 | setLayoutPrettyTycon = setLayoutPrettyTycon} | |
3274 | end | |
3275 | ||
3276 | fun output (E: t, out, {compact, def, flat, onlyCurrent, prefixUnset}): unit = | |
3277 | let | |
3278 | val keep = | |
3279 | if onlyCurrent | |
3280 | then let | |
3281 | val T {currentScope, ...} = E | |
3282 | val currentScope = !currentScope | |
3283 | in | |
3284 | fn {scope, ...} => | |
3285 | Scope.equals (scope, currentScope) | |
3286 | end | |
3287 | else fn _ => true | |
3288 | val {bass, fcts, sigs, strs, types, vals, ...} = current (E, keep) | |
3289 | val bass = bass () | |
3290 | val fcts = fcts () | |
3291 | val sigs = sigs () | |
3292 | val strs = strs () | |
3293 | val types = types () | |
3294 | val vals = vals () | |
3295 | ||
3296 | val {get = interfaceSigid: Interface.t -> (Sigid.t * Interface.t) option, | |
3297 | set = setInterfaceSigid, ...} = | |
3298 | Property.getSet (Interface.plist, Property.initConst NONE) | |
3299 | val _ = Array.foreach (let val Info.T sigs = sigs in sigs end, | |
3300 | fn {domain = s, range = I, ...} => | |
3301 | setInterfaceSigid (I, SOME (s, I))) | |
3302 | val {destroy = destroyLayoutPrettyTycon, | |
3303 | layoutPrettyTycon, setLayoutPrettyTycon, | |
3304 | loopStr, ...} = | |
3305 | makeLayoutPrettyTycon (E, {prefixUnset = prefixUnset}) | |
3306 | ||
3307 | val empty = Layout.empty | |
3308 | val indent = fn l => Layout.indent (l, 3) | |
3309 | val paren = Layout.paren | |
3310 | ||
3311 | val {destroy, layoutSigDefn, layoutSigFlex, | |
3312 | layoutStr, layoutStrDefn, | |
3313 | layoutTypeDefn, layoutValDefn, ...} = | |
3314 | Structure.layouts {interfaceSigid = interfaceSigid, | |
3315 | layoutPrettyTycon = layoutPrettyTycon, | |
3316 | setLayoutPrettyTycon = setLayoutPrettyTycon} | |
3317 | val destroy = fn () => | |
3318 | (destroy (); destroyLayoutPrettyTycon ()) | |
3319 | ||
3320 | fun layoutFctDefn (name, FunctorClosure.T {argInterface, summary, ...}, | |
3321 | {compact, def}) = | |
3322 | let | |
3323 | val bind = | |
3324 | seq [str "functor ", Fctid.layout name] | |
3325 | val argId = Strid.uArg (Fctid.toString name) | |
3326 | val {abbrev = argAbbrev, full = argFull} = | |
3327 | let | |
3328 | val bind = | |
3329 | seq [Strid.layout argId, str ":"] | |
3330 | val {abbrev, full} = | |
3331 | layoutSigFlex (argInterface, | |
3332 | {compact = compact, | |
3333 | elide = {strs = NONE, types = NONE, vals = NONE}}) | |
3334 | val abbrev = | |
3335 | case abbrev () of | |
3336 | NONE => NONE | |
3337 | | SOME sigg => SOME (seq [bind, str " ", sigg]) | |
3338 | val full = fn () => | |
3339 | align [bind, indent (full ())] | |
3340 | in | |
3341 | {abbrev = abbrev, full = full} | |
3342 | end | |
3343 | val arg = #1 (Structure.dummy (argInterface, {prefix = Strid.toString argId ^ "."})) | |
3344 | val () = loopStr (arg, 1, [argId]) | |
3345 | val {abbrev = resAbbrev, full = resFull} = | |
3346 | case summary arg of | |
3347 | NONE => {abbrev = SOME (str "???"), full = fn () => str "???"} | |
3348 | | SOME res => let | |
3349 | val resId = Strid.uRes (Fctid.toString name) | |
3350 | val () = loopStr (res, 2, [resId]) | |
3351 | val {abbrev, full} = layoutStr (res, {compact = compact}) | |
3352 | val abbrev = | |
3353 | case abbrev () of | |
3354 | NONE => NONE | |
3355 | | SOME sigg => | |
3356 | SOME (if compact | |
3357 | then Layout.compact sigg | |
3358 | else sigg) | |
3359 | in | |
3360 | {abbrev = abbrev, full = full} | |
3361 | end | |
3362 | val def = | |
3363 | if def | |
3364 | then seq [str "(* @ ", | |
3365 | Region.layout (Fctid.region name), | |
3366 | str " *)"] | |
3367 | else empty | |
3368 | val full = fn (arg, res) => | |
3369 | align | |
3370 | [bind, | |
3371 | indent (seq [paren arg, str ":"]), | |
3372 | indent res, | |
3373 | indent def] | |
3374 | in | |
3375 | case (argAbbrev, resAbbrev) of | |
3376 | (NONE, NONE) => full (argFull (), resFull ()) | |
3377 | | (NONE, SOME resAbbrev) => full (argFull (), resAbbrev) | |
3378 | | (SOME argAbbrev, NONE) => full (argAbbrev, resFull ()) | |
3379 | | (SOME argAbbrev, SOME resAbbrev) => | |
3380 | let | |
3381 | val lay = | |
3382 | mayAlign | |
3383 | [seq [bind, str " ", | |
3384 | paren argAbbrev, str ": ", | |
3385 | resAbbrev], | |
3386 | indent def] | |
3387 | val lay = | |
3388 | if compact | |
3389 | then Layout.compact lay | |
3390 | else lay | |
3391 | in | |
3392 | lay | |
3393 | end | |
3394 | end | |
3395 | fun layoutBasDefn (name, _, {compact, def}) = | |
3396 | let | |
3397 | val lay = | |
3398 | mayAlign | |
3399 | [seq [str "basis ", Basid.layout name], | |
3400 | indent (if def | |
3401 | then seq [str "(* @ ", | |
3402 | Region.layout (Basid.region name), | |
3403 | str " *)"] | |
3404 | else empty)] | |
3405 | val lay = | |
3406 | if compact | |
3407 | then Layout.compact lay | |
3408 | else lay | |
3409 | in | |
3410 | lay | |
3411 | end | |
3412 | ||
3413 | val outputl = fn l => Layout.outputl (l, out) | |
3414 | val maybeOutputl = fn lo => | |
3415 | case lo of | |
3416 | NONE => () | |
3417 | | SOME l => outputl l | |
3418 | val outputTypeDefn = | |
3419 | fn (strids, name, tyStr) => | |
3420 | (outputl o layoutTypeDefn) | |
3421 | (strids, name, tyStr, | |
3422 | {compact = compact, def = def}) | |
3423 | val outputValDefn = | |
3424 | fn (strids, name, (vid, scheme)) => | |
3425 | (maybeOutputl o layoutValDefn) | |
3426 | (strids, name, (vid, scheme), | |
3427 | {compact = compact, con = flat, def = def}) | |
3428 | val outputSigDefn = | |
3429 | fn (name, I) => | |
3430 | (outputl o layoutSigDefn) | |
3431 | (name, I, | |
3432 | {compact = compact, def = def}) | |
3433 | val outputStrDefn = | |
3434 | fn (strids, name, S) => | |
3435 | (outputl o layoutStrDefn) | |
3436 | (strids, name, S, | |
3437 | {compact = compact, def = def}) | |
3438 | fun outputStrDefnFlat (strids, name, S) = | |
3439 | let | |
3440 | val () = outputStrDefn (strids, name, S) | |
3441 | val strids = name::strids | |
3442 | val Structure.T {strs, types, vals, ...} = S | |
3443 | fun doit (Info.T a, output) = | |
3444 | Array.foreach | |
3445 | (a, fn {domain, range, ...} => | |
3446 | output (strids, domain, range)) | |
3447 | val () = doit (types, outputTypeDefn) | |
3448 | val () = doit (vals, outputValDefn) | |
3449 | val () = doit (strs, outputStrDefnFlat) | |
3450 | in | |
3451 | () | |
3452 | end | |
3453 | val outputFctDefn = | |
3454 | fn (name, fctCls) => | |
3455 | (outputl o layoutFctDefn) | |
3456 | (name, fctCls, | |
3457 | {compact = compact, def = def}) | |
3458 | val outputBasDefn = | |
3459 | fn (name, B) => | |
3460 | (outputl o layoutBasDefn) | |
3461 | (name, B, | |
3462 | {compact = compact, def = def}) | |
3463 | ||
3464 | fun doit (Info.T a, output) = | |
3465 | Array.foreach | |
3466 | (a, fn {domain, range, ...} => | |
3467 | output (domain, range)) | |
3468 | val () = doit (types, fn (name, tyStr) => | |
3469 | outputTypeDefn ([], name, tyStr)) | |
3470 | val () = doit (vals, fn (name, (vid, scheme)) => | |
3471 | outputValDefn ([], name, (vid, scheme))) | |
3472 | val () = doit (sigs, outputSigDefn) | |
3473 | val () = doit (strs, fn (name, S) => | |
3474 | if flat | |
3475 | then outputStrDefnFlat ([], name, S) | |
3476 | else outputStrDefn ([], name, S)) | |
3477 | val () = doit (fcts, outputFctDefn) | |
3478 | val () = doit (bass, outputBasDefn) | |
3479 | val () = destroy () | |
3480 | in | |
3481 | () | |
3482 | end | |
3483 | ||
3484 | (* ------------------------------------------------- *) | |
3485 | (* processDefUse *) | |
3486 | (* ------------------------------------------------- *) | |
3487 | ||
3488 | fun processDefUse (E as T f) = | |
3489 | let | |
3490 | val {destroy = destroyLayoutPrettyTycon, | |
3491 | layoutPrettyTycon, ...} = | |
3492 | makeLayoutPrettyTycon (E, {prefixUnset = false}) | |
3493 | val {destroy = destroyLayoutPrettyTyvar, | |
3494 | layoutPretty = layoutPrettyTyvar, | |
3495 | reset = resetLayoutPrettyTyvar} = | |
3496 | Tyvar.makeLayoutPrettyLocal () | |
3497 | fun layoutPrettyScheme s = | |
3498 | let | |
3499 | val () = resetLayoutPrettyTyvar () | |
3500 | in | |
3501 | (#1 o Type.layoutPretty) | |
3502 | (Scheme.ty s, | |
3503 | {expandOpaque = false, | |
3504 | layoutPrettyTycon = layoutPrettyTycon, | |
3505 | layoutPrettyTyvar = layoutPrettyTyvar}) | |
3506 | end | |
3507 | val destroy = fn () => | |
3508 | (destroyLayoutPrettyTyvar () | |
3509 | ; destroyLayoutPrettyTycon ()) | |
3510 | ||
3511 | val _ = forceUsed E | |
3512 | val all: {class: Class.t, | |
3513 | def: Layout.t, | |
3514 | extra: Layout.t list, | |
3515 | isUsed: bool, | |
3516 | region: Region.t, | |
3517 | uses: Region.t list} list ref = ref [] | |
3518 | fun doit (sel, mkExtra) = | |
3519 | let | |
3520 | val NameSpace.T {defUses, region, toSymbol, ...} = sel f | |
3521 | in | |
3522 | List.foreach | |
3523 | (Option.fold (defUses, [], ! o #1), | |
3524 | fn {class, def, uses, range, ...} => | |
3525 | List.push | |
3526 | (all, {class = class, | |
3527 | def = Symbol.layout (toSymbol def), | |
3528 | extra = mkExtra range, | |
3529 | isUsed = Uses.isUsed uses, | |
3530 | region = region def, | |
3531 | uses = List.fold (Uses.all uses, [], fn (u, ac) => | |
3532 | region u :: ac)})) | |
3533 | end | |
3534 | val _ = doit (#fcts, fn _ => []) | |
3535 | val _ = doit (#sigs, fn _ => []) | |
3536 | val _ = doit (#strs, fn _ => []) | |
3537 | val _ = doit (#types, fn _ => []) | |
3538 | local | |
3539 | fun mkExtraFromScheme so = | |
3540 | case so of | |
3541 | NONE => [] | |
3542 | | SOME (_, s) => [layoutPrettyScheme s] | |
3543 | in | |
3544 | val _ = doit (#vals, mkExtraFromScheme) | |
3545 | end | |
3546 | val a = Array.fromList (!all) | |
3547 | val _ = | |
3548 | QuickSort.sortArray (a, fn ({region = r, ...}, {region = r', ...}) => | |
3549 | Region.<= (r, r')) | |
3550 | val l = | |
3551 | Array.foldr | |
3552 | (a, [], fn (z as {class, def, extra, isUsed, region, uses}, ac) => | |
3553 | case ac of | |
3554 | [] => [z] | |
3555 | | {extra = e', isUsed = i', region = r', uses = u', ...} :: ac' => | |
3556 | if Region.equals (region, r') | |
3557 | then {class = class, | |
3558 | def = def, | |
3559 | extra = extra @ e', | |
3560 | isUsed = isUsed orelse i', | |
3561 | region = region, | |
3562 | uses = uses @ u'} :: ac' | |
3563 | else z :: ac) | |
3564 | val _ = | |
3565 | List.foreach | |
3566 | (l, fn {class, def, isUsed, region, ...} => | |
3567 | if isUsed orelse Option.isNone (Region.left region) | |
3568 | then () | |
3569 | else | |
3570 | Control.warning | |
3571 | (region, | |
3572 | seq [str (concat ["unused ", Class.toString class, ": "]), def], | |
3573 | Layout.empty)) | |
3574 | val _ = | |
3575 | case !Control.showDefUse of | |
3576 | NONE => () | |
3577 | | SOME f => | |
3578 | File.withOut | |
3579 | (f, fn out => | |
3580 | List.foreach | |
3581 | (l, fn {class, def, extra, region, uses, ...} => | |
3582 | case Region.left region of | |
3583 | NONE => () | |
3584 | | SOME p => | |
3585 | let | |
3586 | val uses = Array.fromList uses | |
3587 | val _ = QuickSort.sortArray (uses, Region.<=) | |
3588 | val uses = | |
3589 | Array.foldr | |
3590 | (uses, [], fn (r, ac) => | |
3591 | case ac of | |
3592 | [] => [r] | |
3593 | | r' :: _ => | |
3594 | if Region.equals (r, r') | |
3595 | then ac | |
3596 | else r :: ac) | |
3597 | open Layout | |
3598 | in | |
3599 | outputl | |
3600 | (align [seq [str (Class.toString class), | |
3601 | str " ", | |
3602 | def, | |
3603 | str " ", | |
3604 | str (SourcePos.toString p), | |
3605 | case extra of | |
3606 | [] => empty | |
3607 | | ss => let | |
3608 | val ts = | |
3609 | List.map (ss, | |
3610 | toString) | |
3611 | val uts = | |
3612 | List.map (List.equivalence | |
3613 | (ts, String.equals), | |
3614 | hd) | |
3615 | val sts = | |
3616 | List.insertionSort | |
3617 | (uts, | |
3618 | fn (l, r) => | |
3619 | size l < size r | |
3620 | orelse size l = size r | |
3621 | andalso l < r) | |
3622 | in | |
3623 | str (concat | |
3624 | (" \"" :: | |
3625 | List.separate | |
3626 | (sts, " andalso ") @ ["\""])) | |
3627 | end], | |
3628 | indent | |
3629 | (align | |
3630 | (List.map | |
3631 | (uses, fn r => | |
3632 | str (case Region.left r of | |
3633 | NONE => "NONE" | |
3634 | | SOME p => | |
3635 | SourcePos.toString p))), | |
3636 | 4)], | |
3637 | out) | |
3638 | end)) | |
3639 | val () = destroy () | |
3640 | in | |
3641 | () | |
3642 | end | |
3643 | ||
3644 | (* ------------------------------------------------- *) | |
3645 | (* newCons *) | |
3646 | (* ------------------------------------------------- *) | |
3647 | ||
3648 | fun newCons (T {vals, ...}, v) = | |
3649 | let | |
3650 | val forceUsed = 1 = Vector.length v | |
3651 | in | |
3652 | (Cons.fromVector o Vector.map) | |
3653 | (v, fn {con, name, scheme} => | |
3654 | let | |
3655 | val uses = | |
3656 | NameSpace.newUses | |
3657 | (vals, | |
3658 | {def = Ast.Vid.fromCon name, | |
3659 | range = (Vid.Con con, scheme), | |
3660 | forceUsed = forceUsed}) | |
3661 | in | |
3662 | {con = con, | |
3663 | name = name, | |
3664 | scheme = scheme, | |
3665 | uses = uses} | |
3666 | end) | |
3667 | end | |
3668 | ||
3669 | (* ------------------------------------------------- *) | |
3670 | (* cut *) | |
3671 | (* ------------------------------------------------- *) | |
3672 | ||
3673 | local | |
3674 | ||
3675 | fun makeOpaque (S: Structure.t, I: Interface.t, {prefix: string}) = | |
3676 | let | |
3677 | fun fixCons (cs, cs') = | |
3678 | Cons.map | |
3679 | (cs', fn {name, scheme, ...} => | |
3680 | let | |
3681 | val (con, uses) = | |
3682 | case Vector.peek (Cons.dest cs, fn {name = n, ...} => | |
3683 | Ast.Con.equals (n, name)) of | |
3684 | NONE => (Con.bogus, Uses.new ()) | |
3685 | | SOME {con, uses, ...} => (con, uses) | |
3686 | in | |
3687 | {con = con, scheme = scheme, uses = uses} | |
3688 | end) | |
3689 | val (S', instantiate) = Structure.dummy (I, {prefix = prefix}) | |
3690 | val _ = instantiate (S, fn (c, s) => | |
3691 | Tycon.setOpaqueExpansion | |
3692 | (c, fn ts => TypeStr.apply (s, ts))) | |
3693 | val {destroy, | |
3694 | get : Structure.t -> {formal: Structure.t, new: Structure.t} list ref, | |
3695 | ...} = | |
3696 | Property.destGet (Structure.plist, Property.initFun (fn _ => ref [])) | |
3697 | (* | |
3698 | fun replace (S, S'): Structure.t = | |
3699 | reallyReplace (S, S') | |
3700 | *) | |
3701 | fun replace (S, S'): Structure.t = | |
3702 | let | |
3703 | val seen = get S | |
3704 | in | |
3705 | case List.peek (!seen, fn {formal, ...} => | |
3706 | Structure.eq (S', formal)) of | |
3707 | NONE => let | |
3708 | val new = reallyReplace (S, S') | |
3709 | val _ = List.push (seen, {formal = S', new = new}) | |
3710 | in | |
3711 | new | |
3712 | end | |
3713 | | SOME {new, ...} => new | |
3714 | end | |
3715 | and reallyReplace (S, S'): Structure.t = | |
3716 | let | |
3717 | val Structure.T {strs, | |
3718 | types, | |
3719 | vals, ...} = S | |
3720 | val Structure.T {strs = strs', | |
3721 | types = types', | |
3722 | vals = vals', ...} = S' | |
3723 | val strs = Info.map2 (strs, strs', replace) | |
3724 | val types = | |
3725 | Info.map2 | |
3726 | (types, types', fn (s, s') => | |
3727 | let | |
3728 | datatype z = datatype TypeStr.node | |
3729 | in | |
3730 | case TypeStr.node s' of | |
3731 | Datatype {cons = cs', tycon} => | |
3732 | (case TypeStr.node s of | |
3733 | Datatype {cons = cs, ...} => | |
3734 | TypeStr.data | |
3735 | (tycon, fixCons (cs, cs')) | |
3736 | | _ => s') | |
3737 | | Scheme _ => s' | |
3738 | | Tycon _ => s' | |
3739 | end) | |
3740 | val vals = | |
3741 | Info.map2 | |
3742 | (vals, vals', fn ((v, _), (_, s')) => | |
3743 | (v, s')) | |
3744 | in | |
3745 | Structure.T {interface = Structure.interface S', | |
3746 | plist = PropertyList.new (), | |
3747 | strs = strs, | |
3748 | types = types, | |
3749 | vals = vals} | |
3750 | end | |
3751 | val S'' = replace (S, S') | |
3752 | val _ = destroy () | |
3753 | in | |
3754 | S'' | |
3755 | end | |
3756 | ||
3757 | fun transparentCut (E: t, S: Structure.t, I: Interface.t, | |
3758 | {isFunctor: bool, prefix: string}, | |
3759 | region: Region.t): Structure.t * Decs.t = | |
3760 | let | |
3761 | val I = Interface.copy I | |
3762 | val flexTyconMap = Interface.flexibleTycons I | |
3763 | val () = | |
3764 | Structure.realize | |
3765 | (S, flexTyconMap, | |
3766 | fn (name, flex, typeStr, {nest = strids}) => | |
3767 | let | |
3768 | val {admitsEquality = a, hasCons, kind = k, ...} = | |
3769 | FlexibleTycon.dest flex | |
3770 | fun dummy () = | |
3771 | TypeStr.tycon | |
3772 | (FlexibleTycon.dummyTycon | |
3773 | (flex, name, strids, {prefix = prefix})) | |
3774 | val typeStr = | |
3775 | case typeStr of | |
3776 | NONE => dummy () | |
3777 | | SOME typeStr => | |
3778 | (* Only realize a plausible candidate for typeStr. *) | |
3779 | if Kind.equals (k, TypeStr.kind typeStr) | |
3780 | andalso AdmitsEquality.<= (a, TypeStr.admitsEquality typeStr) | |
3781 | andalso (not hasCons orelse Option.isSome (TypeStr.toTyconOpt typeStr)) | |
3782 | then typeStr | |
3783 | else dummy () | |
3784 | val () = FlexibleTycon.realize (flex, typeStr) | |
3785 | in | |
3786 | () | |
3787 | end) | |
3788 | (* This tick is so that the type schemes for any values that need to be | |
3789 | * instantiated and then re-generalized will be at a new time, so we can | |
3790 | * check if something should not be generalized. | |
3791 | *) | |
3792 | val () = TypeEnv.Time.tick {region = region} | |
3793 | val sign = | |
3794 | if isFunctor | |
3795 | then "argument signature" | |
3796 | else "signature" | |
3797 | ||
3798 | val {destroy = destroyInterfaceSigid, | |
3799 | get = interfaceSigid: Interface.t -> (Sigid.t * Interface.t) option, | |
3800 | set = setInterfaceSigid, ...} = | |
3801 | Property.destGetSet (Interface.plist, Property.initConst NONE) | |
3802 | val {destroy = destroyLayoutPrettyTycon, | |
3803 | layoutPrettyTycon, setLayoutPrettyTycon, | |
3804 | loopStr, loopFlexTyconMap, ...} = | |
3805 | genLayoutPrettyTycon {prefixUnset = true} | |
3806 | val pre = | |
3807 | Promise.delay | |
3808 | (fn () => | |
3809 | let | |
3810 | val {sigs, strs, types, ...} = current (E, fn _ => true) | |
3811 | val _ = | |
3812 | Info.foreachByTime | |
3813 | (sigs (), fn (s, I) => | |
3814 | setInterfaceSigid (I, SOME (s, I))) | |
3815 | val _ = loopFlexTyconMap (flexTyconMap, 2, [Strid.uSig]) | |
3816 | val _ = loopStr (S, 1, [Strid.uStr]) | |
3817 | val _ = | |
3818 | loopStr (Structure.T {interface = NONE, | |
3819 | plist = PropertyList.new (), | |
3820 | strs = strs (), | |
3821 | types = types (), | |
3822 | vals = Info.T (Array.new0 ())}, | |
3823 | 0, []) | |
3824 | in | |
3825 | () | |
3826 | end) | |
3827 | val interfaceSigid = fn I => | |
3828 | (Promise.force pre; interfaceSigid I) | |
3829 | val layoutPrettyTycon = fn c => | |
3830 | (Promise.force pre; layoutPrettyTycon c) | |
3831 | val {destroy = destroyLayouts, | |
3832 | layoutPrettyType, layoutPrettyTyvar, | |
3833 | layoutStrSpec, layoutTypeSpec, layoutValSpec, | |
3834 | localInitLayoutPrettyTyvar, ...} = | |
3835 | Interface.layouts {interfaceSigid = interfaceSigid, | |
3836 | layoutPrettyTycon = layoutPrettyTycon, | |
3837 | setLayoutPrettyTycon = setLayoutPrettyTycon} | |
3838 | ||
3839 | datatype sort = datatype Interface.TypeStr.Sort.t | |
3840 | val sort = Interface.TypeStr.sort | |
3841 | ||
3842 | val decs = ref [] | |
3843 | fun map {strInfo: ('name, 'strRange) Info.t, | |
3844 | ifcArray: ('name * 'ifcRange) array, | |
3845 | strids: Strid.t list, | |
3846 | nameEquals: 'name * 'name -> bool, | |
3847 | nameLayout: 'name -> Layout.t, | |
3848 | specs: 'name * 'ifcRange -> Region.t list, | |
3849 | notFound: 'name * 'ifcRange -> {diag: {spec: Layout.t option, | |
3850 | thing: string} option, | |
3851 | range: 'range}, | |
3852 | doit: 'name * 'strRange * 'name * 'ifcRange -> 'range}: ('name, 'range) Info.t = | |
3853 | let | |
3854 | val Info.T strArray = strInfo | |
3855 | val n = Array.length strArray | |
3856 | val r = ref 0 | |
3857 | val array = | |
3858 | Array.map | |
3859 | (ifcArray, fn (ifcName, ifcRange) => | |
3860 | let | |
3861 | fun find i = | |
3862 | if i = n | |
3863 | then | |
3864 | let | |
3865 | val {diag, range} = notFound (ifcName, ifcRange) | |
3866 | val _ = | |
3867 | Option.app | |
3868 | (diag, fn {thing, spec} => | |
3869 | Control.error | |
3870 | (region, | |
3871 | seq [str thing, | |
3872 | str " in ", | |
3873 | str sign, | |
3874 | str " but not in structure: ", | |
3875 | layoutLongRev (strids, nameLayout ifcName)], | |
3876 | align ((case spec of | |
3877 | NONE => Layout.empty | |
3878 | | SOME spec => seq [str "signature: ", spec]):: | |
3879 | (List.map | |
3880 | (specs (ifcName, ifcRange), fn r => | |
3881 | seq [str "spec at: ", Region.layout r]))))) | |
3882 | in | |
3883 | {domain = ifcName, | |
3884 | range = range, | |
3885 | time = Time.next (), | |
3886 | uses = Uses.new ()} | |
3887 | end | |
3888 | else | |
3889 | let | |
3890 | val {domain = strName, range = strRange, time, uses} = | |
3891 | Array.sub (strArray, i) | |
3892 | in | |
3893 | if nameEquals (strName, ifcName) | |
3894 | then (r := i + 1 | |
3895 | ; {domain = strName, | |
3896 | range = doit (strName, strRange, ifcName, ifcRange), | |
3897 | time = time, | |
3898 | uses = uses}) | |
3899 | else find (i + 1) | |
3900 | end | |
3901 | in | |
3902 | find (!r) | |
3903 | end) | |
3904 | in | |
3905 | Info.T array | |
3906 | end | |
3907 | val {destroy, get: Structure.t -> (Interface.t * Structure.t) list ref, | |
3908 | ...} = | |
3909 | Property.destGet (Structure.plist, Property.initFun (fn _ => ref [])) | |
3910 | (* | |
3911 | fun cut (S, I, strids): Structure.t = | |
3912 | reallyCut (S, I, strids) | |
3913 | *) | |
3914 | fun cut (S, I, flexTyconMap, strids): Structure.t = | |
3915 | let | |
3916 | val seen = get S | |
3917 | in | |
3918 | case List.peek (!seen, fn (I', _) => Interface.equals (I, I')) of | |
3919 | NONE => | |
3920 | let | |
3921 | fun really () = reallyCut (S, I, flexTyconMap, strids) | |
3922 | val S = | |
3923 | case Structure.interface S of | |
3924 | NONE => really () | |
3925 | | SOME I' => | |
3926 | if Interface.equals (I, I') | |
3927 | then S | |
3928 | else really () | |
3929 | val _ = List.push (seen, (I, S)) | |
3930 | in | |
3931 | S | |
3932 | end | |
3933 | | SOME (_, S) => S | |
3934 | end | |
3935 | and reallyCut (S, I, flexTyconMap, strids) = | |
3936 | let | |
3937 | val Structure.T {strs = strStrs, types = strTypes, vals = strVals, ...} = S | |
3938 | val {strs = sigStrs, types = sigTypes, vals = sigVals} = Interface.dest I | |
3939 | val types = | |
3940 | map {strInfo = strTypes, | |
3941 | ifcArray = sigTypes, | |
3942 | strids = strids, | |
3943 | nameEquals = Ast.Tycon.equals, | |
3944 | nameLayout = Ast.Tycon.layout, | |
3945 | specs = fn (name, sigStr) => | |
3946 | Interface.TypeStr.specs (sigStr, Ast.Tycon.region name), | |
3947 | notFound = fn (name, sigStr) => | |
3948 | let | |
3949 | val spec = | |
3950 | layoutTypeSpec | |
3951 | (strids, name, sigStr, | |
3952 | {compact = false, | |
3953 | def = false, | |
3954 | flexTyconMap = flexTyconMap}) | |
3955 | val thing = "type" | |
3956 | ||
3957 | val rlzStr = Interface.TypeStr.toEnv sigStr | |
3958 | in | |
3959 | {diag = SOME {spec = SOME spec, | |
3960 | thing = thing}, | |
3961 | range = rlzStr} | |
3962 | end, | |
3963 | doit = fn (strName, strStr, sigName, sigStr) => | |
3964 | let | |
3965 | val rlzStr = Interface.TypeStr.toEnv sigStr | |
3966 | val error: (Layout.t list * Layout.t * Layout.t) option ref = ref NONE | |
3967 | fun reportError () = | |
3968 | case !error of | |
3969 | NONE => () | |
3970 | | SOME (msgs, strError, sigError) => | |
3971 | Control.error | |
3972 | (region, | |
3973 | seq [str "type in structure disagrees with signature (", | |
3974 | (seq o List.separate) (List.rev msgs, str ", "), | |
3975 | str "): ", | |
3976 | layoutLongRev (strids, Ast.Tycon.layout sigName)], | |
3977 | align ((seq [str "structure: ", strError]) :: | |
3978 | (seq [str "defn at: ", | |
3979 | Region.layout (Ast.Tycon.region strName)]) :: | |
3980 | (seq [str "signature: ", sigError]) :: | |
3981 | (List.map | |
3982 | (Interface.TypeStr.specs | |
3983 | (sigStr, Ast.Tycon.region sigName), | |
3984 | fn r => seq [str "spec at: ", Region.layout r])))) | |
3985 | val error = fn (msg, strError, sigError) => | |
3986 | let | |
3987 | val msgs = | |
3988 | case !error of | |
3989 | NONE => [str msg] | |
3990 | | SOME (msgs, _, _) => (str msg)::msgs | |
3991 | in | |
3992 | error := SOME (msgs, strError, sigError) | |
3993 | end | |
3994 | ||
3995 | val strKind = TypeStr.kind strStr | |
3996 | val strArity = | |
3997 | case strKind of | |
3998 | Kind.Arity strArity => strArity | |
3999 | | _ => Error.bug "ElaborateEnv.transparentCut.reallyCut.<anon>: strArity" | |
4000 | val sigKind = Interface.TypeStr.kind sigStr | |
4001 | val sigArity = | |
4002 | case sigKind of | |
4003 | Kind.Arity sigArity => sigArity | |
4004 | | _ => Error.bug "ElaborateEnv.transparentCut.reallyCut.<anon>: sigArity" | |
4005 | local | |
4006 | val tyvars = | |
4007 | Vector.tabulate | |
4008 | (Int.max (strArity, sigArity), fn _ => | |
4009 | Tyvar.makeNoname {equality = false}) | |
4010 | val () = localInitLayoutPrettyTyvar tyvars | |
4011 | in | |
4012 | val strTyvars = Vector.prefix (tyvars, strArity) | |
4013 | val strTyargs = Vector.map (strTyvars, Type.var) | |
4014 | val sigTyvars = Vector.prefix (tyvars, sigArity) | |
4015 | val sigTyargs = Vector.map (sigTyvars, Type.var) | |
4016 | end | |
4017 | fun layoutTyvars tyvars = | |
4018 | let | |
4019 | open Layout | |
4020 | val tyvars = | |
4021 | case Vector.length tyvars of | |
4022 | 0 => empty | |
4023 | | 1 => layoutPrettyTyvar (Vector.first tyvars) | |
4024 | | _ => tuple (Vector.toListMap (tyvars, layoutPrettyTyvar)) | |
4025 | val tyvars = | |
4026 | if strArity = sigArity | |
4027 | then tyvars | |
4028 | else bracket tyvars | |
4029 | in | |
4030 | if isEmpty tyvars | |
4031 | then str " " | |
4032 | else seq [str " ", tyvars, str " "] | |
4033 | end | |
4034 | ||
4035 | val sort = sort (sigName, sigStr, rlzStr, flexTyconMap) | |
4036 | ||
4037 | fun sigMsg (b, rest) = | |
4038 | let | |
4039 | val empty = Layout.empty | |
4040 | val indent = fn l => Layout.indent (l, 3) | |
4041 | val rest = | |
4042 | case rest of | |
4043 | NONE => SOME (str "...") | |
4044 | | SOME _ => rest | |
4045 | val (kw, rest) = | |
4046 | case sort of | |
4047 | Datatype _ => ("datatype", rest) | |
4048 | | Scheme _ => ("type", rest) | |
4049 | | Type {admitsEquality} => | |
4050 | (if admitsEquality then "eqtype" else "type", | |
4051 | NONE) | |
4052 | in | |
4053 | mayAlign [seq [if b then bracket (str kw) else str kw, | |
4054 | layoutTyvars sigTyvars, | |
4055 | layoutLongRev (strids, Ast.Tycon.layout sigName), | |
4056 | if Option.isSome rest then str " =" else empty], | |
4057 | indent (case rest of | |
4058 | NONE => empty | |
4059 | | SOME rest => rest)] | |
4060 | end | |
4061 | fun strMsg (b, rest) = | |
4062 | let | |
4063 | val empty = Layout.empty | |
4064 | val indent = fn l => Layout.indent (l, 3) | |
4065 | val rest = | |
4066 | case rest of | |
4067 | NONE => SOME (str "...") | |
4068 | | SOME _ => rest | |
4069 | val kw = | |
4070 | case TypeStr.node strStr of | |
4071 | TypeStr.Datatype _ => "datatype" | |
4072 | | TypeStr.Scheme _ => "type" | |
4073 | | TypeStr.Tycon _ => "type" | |
4074 | in | |
4075 | mayAlign [seq [if b then bracket (str kw) else str kw, | |
4076 | layoutTyvars strTyvars, | |
4077 | layoutLongRev (strids, Ast.Tycon.layout strName), | |
4078 | if Option.isSome rest then str " =" else empty], | |
4079 | indent (case rest of | |
4080 | NONE => empty | |
4081 | | SOME rest => rest)] | |
4082 | end | |
4083 | ||
4084 | val lay = #1 o layoutPrettyType | |
4085 | ||
4086 | fun unify (t, t', error) = | |
4087 | let | |
4088 | val error = fn (l, l', _) => | |
4089 | error (l, l') | |
4090 | in | |
4091 | Type.unify | |
4092 | (t, t', {error = error, | |
4093 | layoutPretty = layoutPrettyType, | |
4094 | layoutPrettyTycon = layoutPrettyTycon, | |
4095 | layoutPrettyTyvar = layoutPrettyTyvar}) | |
4096 | end | |
4097 | ||
4098 | val () = | |
4099 | if Kind.equals (strKind, sigKind) | |
4100 | then () | |
4101 | else error ("arity", | |
4102 | strMsg (false, NONE), | |
4103 | sigMsg (false, NONE)) | |
4104 | val resStr = | |
4105 | case sort of | |
4106 | Type _ => | |
4107 | let | |
4108 | val sigEq = Interface.TypeStr.admitsEquality sigStr | |
4109 | val strEq = TypeStr.admitsEquality strStr | |
4110 | val _ = | |
4111 | if AdmitsEquality.<= (sigEq, strEq) | |
4112 | then () | |
4113 | else error ("admits equality", | |
4114 | strMsg (false, SOME (TypeStr.explainDoesNotAdmitEquality | |
4115 | (strStr, | |
4116 | {layoutPrettyTycon = layoutPrettyTycon}))), | |
4117 | sigMsg (true, NONE)) | |
4118 | in | |
4119 | rlzStr | |
4120 | end | |
4121 | | Scheme sigScheme => | |
4122 | let | |
4123 | fun chkScheme strScheme = | |
4124 | unify | |
4125 | (Scheme.apply (strScheme, strTyargs), | |
4126 | Scheme.apply (sigScheme, sigTyargs), | |
4127 | fn (l, l') => error ("type definition", | |
4128 | strMsg (false, SOME l), | |
4129 | sigMsg (false, SOME l'))) | |
4130 | val _ = | |
4131 | case TypeStr.node strStr of | |
4132 | TypeStr.Datatype {tycon = strTycon, ...} => | |
4133 | let | |
4134 | val strScheme = Scheme.fromTycon strTycon | |
4135 | in | |
4136 | unify | |
4137 | (Scheme.apply (strScheme, strTyargs), | |
4138 | Scheme.apply (sigScheme, sigTyargs), | |
4139 | fn _ => | |
4140 | error ("type structure", | |
4141 | strMsg (true, NONE), | |
4142 | sigMsg (false, SOME (bracket (lay (Scheme.apply (sigScheme, sigTyargs))))))) | |
4143 | end | |
4144 | | TypeStr.Scheme s => | |
4145 | chkScheme s | |
4146 | | TypeStr.Tycon c => | |
4147 | chkScheme (Scheme.fromTycon c) | |
4148 | in | |
4149 | rlzStr | |
4150 | end | |
4151 | | Datatype {repl = true, tycon = sigTycon, ...} => | |
4152 | let | |
4153 | val sigScheme = Scheme.fromTycon sigTycon | |
4154 | fun nonDatatype strScheme = | |
4155 | (error ("type structure", | |
4156 | strMsg (false, SOME (bracket (lay (Scheme.apply (strScheme, strTyargs))))), | |
4157 | sigMsg (false, SOME (bracket (seq [str "datatype ", | |
4158 | lay (Scheme.apply (sigScheme, sigTyargs))])))) | |
4159 | ; rlzStr) | |
4160 | in | |
4161 | case TypeStr.node strStr of | |
4162 | TypeStr.Datatype {tycon = strTycon, ...} => | |
4163 | let | |
4164 | val strScheme = Scheme.fromTycon strTycon | |
4165 | in | |
4166 | Exn.withEscape | |
4167 | (fn escape => | |
4168 | (unify | |
4169 | (Scheme.apply (strScheme, strTyargs), | |
4170 | Scheme.apply (sigScheme, sigTyargs), | |
4171 | fn _ => | |
4172 | (error ("type structure", | |
4173 | strMsg (true, NONE), | |
4174 | sigMsg (false, SOME (bracket (seq [str "datatype ", | |
4175 | lay (Scheme.apply (sigScheme, sigTyargs))])))) | |
4176 | ; escape rlzStr)) | |
4177 | ; strStr)) | |
4178 | end | |
4179 | | TypeStr.Scheme strScheme => | |
4180 | nonDatatype strScheme | |
4181 | | TypeStr.Tycon strTycon => | |
4182 | nonDatatype (Scheme.fromTycon strTycon) | |
4183 | end | |
4184 | | Datatype {repl = false, cons = sigCons, ...} => | |
4185 | let | |
4186 | fun nonDatatype strScheme = | |
4187 | (error ("type structure", | |
4188 | strMsg (false, SOME (bracket (lay (Scheme.apply (strScheme, strTyargs))))), | |
4189 | sigMsg (true, NONE)) | |
4190 | ; rlzStr) | |
4191 | in | |
4192 | case TypeStr.node strStr of | |
4193 | TypeStr.Datatype {cons = strCons, ...} => | |
4194 | let | |
4195 | val extra: bool ref = ref false | |
4196 | fun conScheme (scheme, tyvars) = | |
4197 | case Type.deArrowOpt (Scheme.apply (scheme, tyvars)) of | |
4198 | NONE => NONE | |
4199 | | SOME (ty, _) => SOME ty | |
4200 | fun layCon (name, scheme, tyvars) = | |
4201 | (bracket o seq) | |
4202 | [Ast.Con.layout name, | |
4203 | case conScheme (scheme, tyvars) of | |
4204 | NONE => Layout.empty | |
4205 | | SOME _ => str " of _"] | |
4206 | fun loop (sigCons, strCons, sigConsAcc, strConsAcc) = | |
4207 | case (sigCons, strCons) of | |
4208 | ([], []) => (List.rev sigConsAcc, List.rev strConsAcc) | |
4209 | | ({name, scheme = sigScheme}::sigCons, []) => | |
4210 | loop (sigCons, | |
4211 | [], | |
4212 | (layCon (name, sigScheme, sigTyargs))::sigConsAcc, | |
4213 | strConsAcc) | |
4214 | | ([], {name, scheme = strScheme}::strCons) => | |
4215 | loop ([], | |
4216 | strCons, | |
4217 | sigConsAcc, | |
4218 | (layCon (name, strScheme, strTyargs))::strConsAcc) | |
4219 | | (sigCons as {name = sigName, scheme = sigScheme}::sigCons', | |
4220 | strCons as {name = strName, scheme = strScheme}::strCons') => | |
4221 | (case Ast.Con.compare (sigName, strName) of | |
4222 | LESS => | |
4223 | loop (sigCons', | |
4224 | strCons, | |
4225 | (layCon (sigName, sigScheme, sigTyargs))::sigConsAcc, | |
4226 | strConsAcc) | |
4227 | | EQUAL => | |
4228 | (case (conScheme (sigScheme, sigTyargs), conScheme (strScheme, strTyargs)) of | |
4229 | (NONE, NONE) => (extra := true | |
4230 | ; loop (sigCons', strCons', | |
4231 | sigConsAcc, strConsAcc)) | |
4232 | | (NONE, SOME _) => | |
4233 | loop (sigCons', strCons', | |
4234 | (Ast.Con.layout sigName)::sigConsAcc, | |
4235 | (seq [Ast.Con.layout strName, str " [of _]"])::strConsAcc) | |
4236 | | (SOME _, NONE) => | |
4237 | loop (sigCons', strCons', | |
4238 | (seq [Ast.Con.layout sigName, str " [of _]"])::sigConsAcc, | |
4239 | (Ast.Con.layout strName)::strConsAcc) | |
4240 | | (SOME sigTy, SOME strTy) => | |
4241 | Exn.withEscape | |
4242 | (fn escape => | |
4243 | (unify | |
4244 | (sigTy, strTy, | |
4245 | fn (sigLay, strLay) => | |
4246 | (escape o loop) | |
4247 | (sigCons', strCons', | |
4248 | (seq [Ast.Con.layout sigName, str " of ", sigLay])::sigConsAcc, | |
4249 | (seq [Ast.Con.layout strName, str " of ", strLay])::strConsAcc)) | |
4250 | ; extra := true | |
4251 | ; loop (sigCons', strCons', | |
4252 | sigConsAcc, strConsAcc)))) | |
4253 | | GREATER => | |
4254 | loop (sigCons, | |
4255 | strCons', | |
4256 | sigConsAcc, | |
4257 | (layCon (strName, strScheme, strTyargs))::strConsAcc)) | |
4258 | val (sigCons, strCons) = | |
4259 | loop (Vector.toListMap | |
4260 | (Cons.dest sigCons, fn {name, scheme, ...} => | |
4261 | {name = name, scheme = scheme}), | |
4262 | Vector.toListMap | |
4263 | (Cons.dest strCons, fn {name, scheme, ...} => | |
4264 | {name = name, scheme = scheme}), | |
4265 | [], | |
4266 | []) | |
4267 | val resStr = | |
4268 | if List.isEmpty sigCons | |
4269 | andalso List.isEmpty strCons | |
4270 | then strStr | |
4271 | else let | |
4272 | fun layCons cons = | |
4273 | let | |
4274 | val cons = | |
4275 | if !extra | |
4276 | then List.snoc (cons, str "...") | |
4277 | else cons | |
4278 | val cons = alignPrefix (cons, "| ") | |
4279 | in | |
4280 | SOME cons | |
4281 | end | |
4282 | in | |
4283 | error ("constructors", | |
4284 | strMsg (false, layCons strCons), | |
4285 | sigMsg (false, layCons sigCons)) | |
4286 | ; rlzStr | |
4287 | end | |
4288 | in | |
4289 | resStr | |
4290 | end | |
4291 | | TypeStr.Scheme strScheme => | |
4292 | nonDatatype strScheme | |
4293 | | TypeStr.Tycon strTycon => | |
4294 | nonDatatype (Scheme.fromTycon strTycon) | |
4295 | end | |
4296 | val () = reportError () | |
4297 | in | |
4298 | resStr | |
4299 | end} | |
4300 | val vals = | |
4301 | map | |
4302 | {strInfo = strVals, | |
4303 | ifcArray = sigVals, | |
4304 | strids = strids, | |
4305 | nameEquals = Ast.Vid.equals, | |
4306 | nameLayout = Ast.Vid.layout, | |
4307 | specs = fn (name, _) => [Ast.Vid.region name], | |
4308 | notFound = fn (name, (sigStatus, sigScheme)) => | |
4309 | let | |
4310 | val spec = | |
4311 | layoutValSpec | |
4312 | (strids, name, (sigStatus, sigScheme), | |
4313 | {compact = false, con = false, def = false}) | |
4314 | val thing = Status.pretty sigStatus | |
4315 | ||
4316 | val con = Con.newString o Ast.Vid.toString | |
4317 | val var = Var.newString o Ast.Vid.toString | |
4318 | val vid = | |
4319 | case sigStatus of | |
4320 | Status.Con => Vid.Con (con name) | |
4321 | | Status.Exn => Vid.Exn (con name) | |
4322 | | Status.Var => Vid.Var (var name) | |
4323 | val rlzScheme = Interface.Scheme.toEnv sigScheme | |
4324 | in | |
4325 | {diag = Option.map (spec, fn spec => | |
4326 | {spec = SOME spec, | |
4327 | thing = thing}), | |
4328 | range = (vid, rlzScheme)} | |
4329 | end, | |
4330 | doit = fn (strName, (strVid, strScheme), sigName, (sigStatus, sigScheme)) => | |
4331 | let | |
4332 | val rlzScheme = Interface.Scheme.toEnv sigScheme | |
4333 | val unifyError = ref NONE | |
4334 | val statusError = ref false | |
4335 | val (rlzTyvars, rlzType) = Scheme.fresh rlzScheme | |
4336 | val () = localInitLayoutPrettyTyvar rlzTyvars | |
4337 | val {args = strTyargs, instance = strType} = | |
4338 | Scheme.instantiate strScheme | |
4339 | val _ = | |
4340 | Type.unify | |
4341 | (strType, rlzType, | |
4342 | {error = fn (l, l', {notes, ...}) => | |
4343 | unifyError := SOME (l, l', notes), | |
4344 | layoutPretty = layoutPrettyType, | |
4345 | layoutPrettyTycon = layoutPrettyTycon, | |
4346 | layoutPrettyTyvar = layoutPrettyTyvar}) | |
4347 | val strTyargs = strTyargs () | |
4348 | fun addDec (name: string, n: Exp.node): Vid.t = | |
4349 | let | |
4350 | val x = Var.newString name | |
4351 | val e = Exp.make (n, strType) | |
4352 | val _ = | |
4353 | List.push | |
4354 | (decs, | |
4355 | Dec.Val {matchDiags = {nonexhaustiveExn = Control.Elaborate.DiagDI.Default, | |
4356 | nonexhaustive = Control.Elaborate.DiagEIW.Ignore, | |
4357 | redundant = Control.Elaborate.DiagEIW.Ignore}, | |
4358 | rvbs = Vector.new0 (), | |
4359 | tyvars = fn () => rlzTyvars, | |
4360 | vbs = (Vector.new1 | |
4361 | {ctxt = fn _ => Layout.empty, | |
4362 | exp = e, | |
4363 | layPat = fn _ => Layout.empty, | |
4364 | nest = [], | |
4365 | pat = Pat.var (x, strType), | |
4366 | regionPat = Region.bogus})}) | |
4367 | in | |
4368 | Vid.Var x | |
4369 | end | |
4370 | fun con (c: Con.t): Vid.t = | |
4371 | addDec (Con.originalName c, Exp.Con (c, strTyargs)) | |
4372 | val strStatus = Status.fromVid strVid | |
4373 | val vid = | |
4374 | case (strVid, sigStatus) of | |
4375 | (Vid.Con c, Status.Var) => con c | |
4376 | | (Vid.Exn c, Status.Var) => con c | |
4377 | | (Vid.Var x, Status.Var) => | |
4378 | if 0 < Vector.length rlzTyvars | |
4379 | orelse 0 < Vector.length strTyargs | |
4380 | then addDec (Var.originalName x, | |
4381 | Exp.Var (fn () => x, fn () => strTyargs)) | |
4382 | else strVid | |
4383 | | (Vid.Con _, Status.Con) => strVid | |
4384 | | (Vid.Exn _, Status.Exn) => strVid | |
4385 | | _ => (statusError := true; strVid) | |
4386 | val () = | |
4387 | if Option.isNone (!unifyError) andalso not (!statusError) | |
4388 | then () | |
4389 | else let | |
4390 | val errors = [] | |
4391 | val errors = | |
4392 | if Option.isSome (!unifyError) | |
4393 | then str "type" :: errors | |
4394 | else errors | |
4395 | val errors = | |
4396 | if !statusError | |
4397 | then str "status" :: errors | |
4398 | else errors | |
4399 | val name = | |
4400 | layoutLongRev (strids, Ast.Vid.layout sigName) | |
4401 | val (strTy, sigTy, notes) = | |
4402 | case !unifyError of | |
4403 | NONE => | |
4404 | let | |
4405 | val lay = #1 (layoutPrettyType rlzType) | |
4406 | in | |
4407 | (lay, lay, Layout.empty) | |
4408 | end | |
4409 | | SOME (strLay, sigLay, notes) => | |
4410 | (strLay, sigLay, notes ()) | |
4411 | fun doit (space, status, ty, kind, vid) = | |
4412 | let | |
4413 | val indent = fn l => Layout.indent (l, 3) | |
4414 | val kw = str (Status.kw status) | |
4415 | val kw = | |
4416 | if !statusError then bracket kw else kw | |
4417 | in | |
4418 | align [seq [str space, str ": ", | |
4419 | mayAlign | |
4420 | [seq [kw, str " ", | |
4421 | name, | |
4422 | str (if Ast.Vid.isSymbolic sigName | |
4423 | then " :" | |
4424 | else ":")], | |
4425 | indent ty]], | |
4426 | seq [str kind, str " at: ", | |
4427 | Region.layout (Ast.Vid.region vid)]] | |
4428 | end | |
4429 | in | |
4430 | Control.error | |
4431 | (region, | |
4432 | seq [if !statusError | |
4433 | then str "value identifier" | |
4434 | else str (Vid.statusPretty strVid), | |
4435 | str " in structure disagrees with ", | |
4436 | str sign, | |
4437 | str " (", | |
4438 | (seq o List.separate) | |
4439 | (errors, str ", "), | |
4440 | str "): ", | |
4441 | name], | |
4442 | align [doit ("structure", strStatus, strTy, | |
4443 | "defn", strName), | |
4444 | doit ("signature", sigStatus, sigTy, | |
4445 | "spec", sigName), | |
4446 | notes]) | |
4447 | end | |
4448 | in | |
4449 | (vid, rlzScheme) | |
4450 | end} | |
4451 | val strs = | |
4452 | map {strInfo = strStrs, | |
4453 | ifcArray = sigStrs, | |
4454 | strids = strids, | |
4455 | nameEquals = Strid.equals, | |
4456 | nameLayout = Strid.layout, | |
4457 | specs = fn (name, _) => [Strid.region name], | |
4458 | notFound = fn (name, I) => | |
4459 | let | |
4460 | val spec = | |
4461 | layoutStrSpec | |
4462 | (strids, name, I, | |
4463 | {compact = false, | |
4464 | def = false, | |
4465 | elide = {strs = SOME (2, 0), | |
4466 | types = NONE, | |
4467 | vals = SOME (3, 2)}, | |
4468 | flexTyconMap = flexTyconMap}) | |
4469 | val thing = "structure" | |
4470 | ||
4471 | val (S, _) = Structure.dummy (I, {prefix = ""}) | |
4472 | in | |
4473 | {diag = SOME {spec = SOME spec, | |
4474 | thing = thing}, | |
4475 | range = S} | |
4476 | end, | |
4477 | doit = fn (_, S, name, I) => | |
4478 | let | |
4479 | val flexTyconMap = | |
4480 | Option.fold | |
4481 | (TyconMap.peekStrid (flexTyconMap, name), | |
4482 | TyconMap.empty (), | |
4483 | fn (flexTyconMap, _) => flexTyconMap) | |
4484 | in | |
4485 | cut (S, I, flexTyconMap, name :: strids) | |
4486 | end} | |
4487 | in | |
4488 | Structure.T {interface = SOME I, | |
4489 | plist = PropertyList.new (), | |
4490 | strs = strs, | |
4491 | types = types, | |
4492 | vals = vals} | |
4493 | end | |
4494 | val S = cut (S, I, flexTyconMap, []) | |
4495 | val () = destroy () | |
4496 | val () = destroyLayouts () | |
4497 | val () = destroyLayoutPrettyTycon () | |
4498 | val () = destroyInterfaceSigid () | |
4499 | in | |
4500 | (S, Decs.fromList (!decs)) | |
4501 | end | |
4502 | ||
4503 | in | |
4504 | ||
4505 | (* section 5.3, 5.5, 5.6 and rules 52, 53 *) | |
4506 | fun cut (E: t, S: Structure.t, I: Interface.t, | |
4507 | {isFunctor: bool, opaque: bool, prefix: string}, region) | |
4508 | : Structure.t * Decs.t = | |
4509 | let | |
4510 | val (S, decs) = transparentCut (E, S, I, {isFunctor = isFunctor, prefix = prefix}, region) | |
4511 | val S = | |
4512 | if opaque | |
4513 | then makeOpaque (S, I, {prefix = prefix}) | |
4514 | else S | |
4515 | in | |
4516 | (S, decs) | |
4517 | end | |
4518 | ||
4519 | val cut = | |
4520 | Trace.trace ("ElaborateEnv.cut", | |
4521 | fn (_, S, I, _, _) => | |
4522 | Layout.tuple [Structure.layout S, | |
4523 | Interface.layout I], | |
4524 | Structure.layout o #1) | |
4525 | cut | |
4526 | ||
4527 | end | |
4528 | ||
4529 | (* ------------------------------------------------- *) | |
4530 | (* functorClosure *) | |
4531 | (* ------------------------------------------------- *) | |
4532 | ||
4533 | fun functorClosure | |
4534 | (E: t, | |
4535 | name: Fctid.t, | |
4536 | argInterface: Interface.t, | |
4537 | makeBody: Structure.t * string list -> Decs.t * Structure.t option) = | |
4538 | let | |
4539 | val argId = Strid.uArg (Fctid.toString name) | |
4540 | val resId = Strid.uRes (Fctid.toString name) | |
4541 | val _ = insideFunctor := true | |
4542 | (* Need to tick here so that any tycons created in the dummy structure | |
4543 | * for the functor formal have a new time, and will therefore report an | |
4544 | * error if they occur before the functor declaration. | |
4545 | *) | |
4546 | val _ = TypeEnv.Time.tick {region = Fctid.region name} | |
4547 | val (formal, instantiate) = | |
4548 | Structure.dummy (argInterface, {prefix = Strid.toString argId ^ "."}) | |
4549 | (* Keep track of all tycons created during the instantiation of the | |
4550 | * functor. These will later become the generative tycons that will need | |
4551 | * to be recreated for each functor application. | |
4552 | *) | |
4553 | val (resultStructure, generativeTycons) = | |
4554 | Tycon.scopeNew | |
4555 | (fn () => | |
4556 | let | |
4557 | val nest = [Strid.toString resId] | |
4558 | val (_, resultStructure) = makeBody (formal, nest) | |
4559 | val _ = Option.app (resultStructure, Structure.forceUsed) | |
4560 | in | |
4561 | resultStructure | |
4562 | end) | |
4563 | val _ = insideFunctor := false | |
4564 | val restore = | |
4565 | if !Control.elaborateOnly | |
4566 | then fn f => f () | |
4567 | else let | |
4568 | val withSaved = Control.Elaborate.snapshot () | |
4569 | val snapshot = snapshot E | |
4570 | in | |
4571 | fn f => snapshot (fn () => withSaved f) | |
4572 | end | |
4573 | fun summary actual = | |
4574 | let | |
4575 | val _ = Structure.forceUsed actual | |
4576 | val {destroy = destroy1, | |
4577 | get = tyconTypeStr: Tycon.t -> TypeStr.t option, | |
4578 | set = setTyconTypeStr, ...} = | |
4579 | Property.destGetSet (Tycon.plist, Property.initConst NONE) | |
4580 | (* Match the actual against the formal, to set the tycons. | |
4581 | * Then duplicate the result, replacing tycons. Want to generate | |
4582 | * new tycons just like the functor body did. | |
4583 | *) | |
4584 | val _ = | |
4585 | instantiate (actual, fn (c, s) => setTyconTypeStr (c, SOME s)) | |
4586 | val _ = | |
4587 | List.foreach | |
4588 | (generativeTycons, fn c => | |
4589 | setTyconTypeStr | |
4590 | (c, SOME (TypeStr.tycon (Tycon.makeLike c)))) | |
4591 | fun replaceType (t: Type.t): Type.t = | |
4592 | let | |
4593 | fun con (c, ts) = | |
4594 | case tyconTypeStr c of | |
4595 | NONE => Type.con (c, ts) | |
4596 | | SOME s => TypeStr.apply (s, ts) | |
4597 | in | |
4598 | Type.hom (t, {con = con, | |
4599 | expandOpaque = false, | |
4600 | record = Type.record, | |
4601 | replaceSynonyms = false, | |
4602 | var = Type.var}) | |
4603 | end | |
4604 | fun replaceScheme (s: Scheme.t): Scheme.t = | |
4605 | let | |
4606 | val (tyvars, ty) = Scheme.dest s | |
4607 | in | |
4608 | Scheme.make {canGeneralize = true, | |
4609 | ty = replaceType ty, | |
4610 | tyvars = tyvars} | |
4611 | end | |
4612 | fun replaceCons cons: Cons.t = | |
4613 | Cons.map | |
4614 | (cons, fn {con, scheme, uses, ...} => | |
4615 | {con = con, | |
4616 | scheme = replaceScheme scheme, | |
4617 | uses = uses}) | |
4618 | fun replaceTypeStr (s: TypeStr.t): TypeStr.t = | |
4619 | let | |
4620 | datatype z = datatype TypeStr.node | |
4621 | in | |
4622 | case TypeStr.node s of | |
4623 | Datatype {cons, tycon} => | |
4624 | let | |
4625 | val tycon = | |
4626 | case tyconTypeStr tycon of | |
4627 | NONE => tycon | |
4628 | | SOME s => | |
4629 | (case TypeStr.toTyconOpt s of | |
4630 | NONE => Error.bug "ElaborateEnv.functorClosure.apply: bad datatype" | |
4631 | | SOME c => c) | |
4632 | in | |
4633 | TypeStr.data (tycon, replaceCons cons) | |
4634 | end | |
4635 | | Scheme s => TypeStr.def (replaceScheme s) | |
4636 | | Tycon c => (case tyconTypeStr c of | |
4637 | NONE => s | |
4638 | | SOME s => s) | |
4639 | end | |
4640 | val {destroy = destroy2, | |
4641 | get = replaceInterface: Interface.t -> Interface.t, ...} = | |
4642 | Property.destGet | |
4643 | (Interface.plist, | |
4644 | Property.initRec | |
4645 | (fn (I, replaceInterface) => | |
4646 | let | |
4647 | val {strs, types, vals} = Interface.dest I | |
4648 | val replaceIScheme = | |
4649 | Interface.Scheme.fromEnv | |
4650 | o replaceScheme | |
4651 | o Interface.Scheme.toEnv | |
4652 | val replaceITypeStr = | |
4653 | Interface.TypeStr.fromEnv | |
4654 | o replaceTypeStr | |
4655 | o Interface.TypeStr.toEnv | |
4656 | in | |
4657 | Interface.new | |
4658 | {isClosed = true, | |
4659 | original = SOME (Interface.original I), | |
4660 | strs = Array.map (strs, fn (strid, I) => | |
4661 | (strid, replaceInterface I)), | |
4662 | types = Array.map (types, fn (tycon, s) => | |
4663 | (tycon, replaceITypeStr s)), | |
4664 | vals = Array.map (vals, fn (vid, (status, scheme)) => | |
4665 | (vid, (status, replaceIScheme scheme)))} | |
4666 | end)) | |
4667 | val {destroy = destroy3, | |
4668 | get = replaceStructure: Structure.t -> Structure.t, ...} = | |
4669 | Property.destGet | |
4670 | (Structure.plist, | |
4671 | Property.initRec | |
4672 | (fn (Structure.T {interface, strs, types, vals, ... }, | |
4673 | replaceStructure) => | |
4674 | Structure.T | |
4675 | {interface = Option.map (interface, replaceInterface), | |
4676 | plist = PropertyList.new (), | |
4677 | strs = Info.map (strs, replaceStructure), | |
4678 | types = Info.map (types, replaceTypeStr), | |
4679 | vals = Info.map (vals, fn (status, s) => | |
4680 | (status, replaceScheme s))})) | |
4681 | val resultStructure = Option.map (resultStructure, replaceStructure) | |
4682 | val _ = destroy1 () | |
4683 | val _ = destroy2 () | |
4684 | val _ = destroy3 () | |
4685 | in | |
4686 | resultStructure | |
4687 | end | |
4688 | val summary = | |
4689 | Trace.trace | |
4690 | ("ElaborateEnv.functorClosure.summary", | |
4691 | fn actual => | |
4692 | Layout.record [("argInterface", Interface.layout argInterface), | |
4693 | ("formal", Structure.layout formal), | |
4694 | ("resultStructure", Option.layout Structure.layout resultStructure), | |
4695 | ("actual", Structure.layout actual)], | |
4696 | Option.layout Structure.layout) | |
4697 | summary | |
4698 | fun apply (actual, nest) = | |
4699 | if not (!insideFunctor) | |
4700 | andalso not (!Control.elaborateOnly) | |
4701 | andalso !Control.numErrors = 0 | |
4702 | then restore (fn () => makeBody (actual, nest)) | |
4703 | else (Decs.empty, summary actual) | |
4704 | in | |
4705 | FunctorClosure.T {apply = apply, | |
4706 | argInterface = argInterface, | |
4707 | resultStructure = resultStructure, | |
4708 | summary = summary} | |
4709 | end | |
4710 | ||
4711 | end |