Import Debian changes 20180207-1
[hcoop/debian/mlton.git] / mlton / elaborate / elaborate-env.fun
CommitLineData
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
10functor ElaborateEnv (S: ELABORATE_ENV_STRUCTS): ELABORATE_ENV =
11struct
12
13open S
14
15local
16 open Control.Elaborate
17in
18 val warnUnused = fn () => current warnUnused
19end
20
21local
22 open Layout
23in
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 "]"]
32end
33
34local
35 open Ast
36in
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
45end
46
47fun layoutLong (ids: Layout.t list) =
48 let
49 open Layout
50 in
51 seq (separate (ids, "."))
52 end
53
54fun layoutStrids (ss: Strid.t list): Layout.t =
55 layoutLong (List.map (ss, Strid.layout))
56
57fun 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)
61fun toStringLongRev (ss: Strid.t list, id: Layout.t) =
62 Layout.toString (layoutLongRev (ss, id))
63
64local
65 open CoreML
66in
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
74end
75
76local
77 open Tycon
78in
79 structure AdmitsEquality = AdmitsEquality
80 structure Kind = Kind
81 structure Symbol = Symbol
82end
83
84local
85 open TypeEnv
86in
87 structure Scheme = Scheme
88 structure Type = Type
89end
90
91structure Decs = Decs (structure CoreML = CoreML)
92
93structure Tycon =
94 struct
95 open Tycon
96 open TypeEnv.TyconExt
97 end
98
99structure 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
108structure 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
202val insideFunctor = ref false
203
204fun amInsideFunctor () = !insideFunctor
205
206structure 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
223structure 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
279structure 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
295structure 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
347structure 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
527local
528 open TypeStr
529in
530 structure Cons = Cons
531end
532
533structure 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
540structure 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
1221local
1222 open Interface
1223in
1224 structure FlexibleTycon = FlexibleTycon
1225 structure Status = Status
1226 structure TyconMap = TyconMap
1227end
1228structure 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
1255structure 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
1279structure 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
1334fun 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
1368structure 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
1725structure 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
1759structure 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
1784structure 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
1801structure 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
2018structure 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
2044datatype 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
2058fun 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 *)
2066val _ = sizeMessage
2067
2068(* ------------------------------------------------- *)
2069(* empty *)
2070(* ------------------------------------------------- *)
2071
2072fun 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
2147local
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)
2169in
2170 fun foreachDefinedSymbol (E, z) =
2171 Symbol.foreach (fn s => foreach (E, s, z))
2172end
2173
2174(* ------------------------------------------------- *)
2175(* current *)
2176(* ------------------------------------------------- *)
2177
2178fun 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
2237fun 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
2326local
2327 fun make sel (T r, a) = NameSpace.peek (sel r, a, {markUse = fn _ => true})
2328in
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))
2342end
2343
2344fun 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
2350fun 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
2356structure 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
2368local
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
2391in
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)
2400end
2401
2402(* ------------------------------------------------- *)
2403(* lookup *)
2404(* ------------------------------------------------- *)
2405
2406fun 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
2412fun 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
2418fun 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
2424fun 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
2430fun 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
2436local
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
2452in
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)
2483end
2484
2485val peekLongcon = PeekResult.toOption o peekLongcon
2486
2487(* ------------------------------------------------- *)
2488(* extend *)
2489(* ------------------------------------------------- *)
2490
2491local
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})
2502in
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
2530end
2531
2532fun extendExn (E, c, c', s) =
2533 extendVals (E, Ast.Vid.fromCon c, (Vid.Exn c', s), Uses.Extend.new)
2534
2535fun extendVar (E, x, x', s, ir) =
2536 extendVals (E, Ast.Vid.fromVar x, (Vid.Var x', s),
2537 Uses.Extend.fromIsRebind ir)
2538
2539val 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
2547fun 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
2555fun 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
2573fun 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
2592local
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
2618in
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
2673end
2674
2675(* ------------------------------------------------- *)
2676(* makeBasis / makeStructure *)
2677(* ------------------------------------------------- *)
2678
2679fun 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
2704fun 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
2728local
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}))
2737in
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
2771end
2772
2773(* ------------------------------------------------- *)
2774(* forceUsed *)
2775(* ------------------------------------------------- *)
2776
2777(* Force everything that is currently in scope to be marked as used. *)
2778fun 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
2802fun 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
2850structure 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
3068end
3069
3070val makeInterfaceEnv = fn E => E
3071
3072(* ------------------------------------------------- *)
3073(* makeLayoutPrettyTycon *)
3074(* ------------------------------------------------- *)
3075
3076fun 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
3183fun 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
3210fun 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
3276fun 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
3488fun 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
3648fun 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
3673local
3674
3675fun 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
3757fun 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
4503in
4504
4505(* section 5.3, 5.5, 5.6 and rules 52, 53 *)
4506fun 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
4519val 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
4527end
4528
4529(* ------------------------------------------------- *)
4530(* functorClosure *)
4531(* ------------------------------------------------- *)
4532
4533fun 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
4711end