Commit | Line | Data |
---|---|---|
7f918cf1 CE |
1 | (* Copyright (C) 2010,2012,2015,2017 Matthew Fluet. |
2 | * Copyright (C) 1999-2006 Henry Cejtin, Matthew Fluet, Suresh | |
3 | * Jagannathan, and Stephen Weeks. | |
4 | * Copyright (C) 1997-2000 NEC Research Institute. | |
5 | * | |
6 | * MLton is released under a BSD-style license. | |
7 | * See the file MLton-LICENSE for details. | |
8 | *) | |
9 | ||
10 | functor ElaborateSigexp (S: ELABORATE_SIGEXP_STRUCTS): ELABORATE_SIGEXP = | |
11 | struct | |
12 | ||
13 | open S | |
14 | ||
15 | local | |
16 | open Ast | |
17 | in | |
18 | structure Atype = Type | |
19 | structure DatBind = DatBind | |
20 | structure DatatypeRhs = DatatypeRhs | |
21 | structure SharingEquation = SharingEquation | |
22 | structure Longstrid = Longstrid | |
23 | structure Longtycon = Longtycon | |
24 | structure Record = Record | |
25 | structure Sigexp = Sigexp | |
26 | structure Sigid = Sigid | |
27 | structure SortedRecord = SortedRecord | |
28 | structure Spec = Spec | |
29 | structure TypBind = TypBind | |
30 | structure Atyvar = Tyvar | |
31 | structure WhereEquation = WhereEquation | |
32 | end | |
33 | ||
34 | local | |
35 | open Env | |
36 | in | |
37 | structure Interface = Interface | |
38 | structure StructureTycon = | |
39 | struct | |
40 | open Tycon | |
41 | open TypeEnv.TyconExt | |
42 | end | |
43 | structure TyvarEnv = TyvarEnv | |
44 | end | |
45 | structure StructureEnv = Env | |
46 | structure Env = StructureEnv.InterfaceEnv | |
47 | ||
48 | local | |
49 | open Interface | |
50 | in | |
51 | structure AdmitsEquality = AdmitsEquality | |
52 | structure Cons = Cons | |
53 | structure Kind = Kind | |
54 | structure FlexibleTycon = FlexibleTycon | |
55 | structure Scheme = Scheme | |
56 | structure Status = Status | |
57 | structure Tycon = Tycon | |
58 | structure Type = Type | |
59 | structure TypeStr = TypeStr | |
60 | structure Tyvar = Tyvar | |
61 | end | |
62 | ||
63 | local | |
64 | open Control.Elaborate | |
65 | in | |
66 | fun check (c: (bool,bool) t, keyword: string, region) = | |
67 | if current c | |
68 | then () | |
69 | else | |
70 | let | |
71 | open Layout | |
72 | in | |
73 | Control.error | |
74 | (region, | |
75 | str (concat (if expert c | |
76 | then [keyword, " disallowed"] | |
77 | else [keyword, " disallowed, compile with -default-ann '", | |
78 | name c, " true'"])), | |
79 | empty) | |
80 | end | |
81 | end | |
82 | ||
83 | fun elaborateType (ty: Atype.t, E: Env.t): Type.t = | |
84 | let | |
85 | fun makeBogus (mc, ts) = | |
86 | let | |
87 | val arity = Vector.length ts | |
88 | val (name, region) = | |
89 | Option.fold | |
90 | (mc, ("t", NONE), fn (c, _) => | |
91 | (Longtycon.toString c, | |
92 | SOME (Longtycon.region c))) | |
93 | val c = | |
94 | StructureTycon.makeBogus | |
95 | {name = name, | |
96 | kind = Kind.Arity arity, | |
97 | region = region} | |
98 | in | |
99 | Type.con (Tycon.Rigid c, ts) | |
100 | end | |
101 | fun loop (ty: Atype.t): Type.t = | |
102 | case Atype.node ty of | |
103 | Atype.Var a => (* rule 44 *) | |
104 | (case TyvarEnv.lookupTyvar a of | |
105 | NONE => makeBogus (NONE, Vector.new0 ()) | |
106 | | SOME a => Type.var a) | |
107 | | Atype.Con (c, ts) => (* rules 46, 47 *) | |
108 | let | |
109 | val ts = Vector.map (ts, loop) | |
110 | fun normal () = | |
111 | case Env.lookupLongtycon (E, c) of | |
112 | NONE => makeBogus (SOME c, ts) | |
113 | | SOME s => | |
114 | let | |
115 | val kind = TypeStr.kind s | |
116 | val numArgs = Vector.length ts | |
117 | val ts = | |
118 | case kind of | |
119 | Kind.Arity n => | |
120 | let | |
121 | fun error () = | |
122 | let | |
123 | open Layout | |
124 | fun doit n = | |
125 | seq [str "[", | |
126 | case n of | |
127 | 0 => empty | |
128 | | 1 => str "_" | |
129 | | _ => seq [str "(", | |
130 | (seq o separate) | |
131 | (List.tabulate (n, fn _ => str "_"), | |
132 | ", "), | |
133 | str ")"], | |
134 | str "] ", | |
135 | Ast.Longtycon.layout c] | |
136 | in | |
137 | Control.error | |
138 | (Atype.region ty, | |
139 | seq [str "type constructor applied to incorrect number of type arguments: ", | |
140 | Ast.Longtycon.layout c], | |
141 | align [seq [str "expects: ", doit n], | |
142 | seq [str "but got: ", doit numArgs], | |
143 | seq [str "in: ", Atype.layout ty]]) | |
144 | end | |
145 | in | |
146 | case Int.compare (n, numArgs) of | |
147 | LESS => | |
148 | (error (); Vector.prefix (ts, n)) | |
149 | | EQUAL => ts | |
150 | | GREATER => | |
151 | (error () | |
152 | ; Vector.concat | |
153 | [ts, | |
154 | Vector.tabulate | |
155 | (n - numArgs, fn _ => | |
156 | makeBogus | |
157 | (NONE, | |
158 | Vector.new0 ()))]) | |
159 | end | |
160 | | Kind.Nary => ts | |
161 | in | |
162 | TypeStr.apply (s, ts) | |
163 | end | |
164 | in | |
165 | case (Ast.Longtycon.split c, Vector.length ts) of | |
166 | (([], c), 2) => | |
167 | if Ast.Tycon.equals (c, Ast.Tycon.arrow) | |
168 | then Type.arrow (Vector.sub (ts, 0), | |
169 | Vector.sub (ts, 1)) | |
170 | else normal () | |
171 | | _ => normal () | |
172 | end | |
173 | | Atype.Paren t => loop t | |
174 | | Atype.Record r => (* rules 45, 49 *) | |
175 | Type.record | |
176 | (SortedRecord.fromVector | |
177 | (Vector.map | |
178 | (Record.toVector r, | |
179 | fn (f, (_, t)) => (f, loop t)))) | |
180 | val ty = loop ty | |
181 | in | |
182 | ty | |
183 | end | |
184 | ||
185 | val elaborateType = | |
186 | Trace.trace ("ElaborateSigexp.elaborateType", Atype.layout o #1, Type.layout) | |
187 | elaborateType | |
188 | ||
189 | fun elaborateScheme (tyvars: Tyvar.t vector, ty: Atype.t, E): Scheme.t = | |
190 | let | |
191 | val ty = elaborateType (ty, E) | |
192 | in | |
193 | Scheme.make (tyvars, ty) | |
194 | end | |
195 | ||
196 | fun elaborateTypedescs (typedescs: {tycon: Ast.Tycon.t, | |
197 | tyvars: Ast.Tyvar.t vector} vector, | |
198 | {equality: bool}, | |
199 | E, | |
200 | nest): unit = | |
201 | Vector.foreach | |
202 | (typedescs, fn {tycon = name, tyvars} => | |
203 | let | |
204 | val admitsEquality = | |
205 | if equality | |
206 | then AdmitsEquality.Sometimes | |
207 | else AdmitsEquality.Never | |
208 | val kind = Kind.Arity (Vector.length tyvars) | |
209 | val prettyDefault = | |
210 | concat (List.separate (rev (Ast.Tycon.toString name :: nest), ".")) | |
211 | val flex = FlexibleTycon.new {admitsEquality = admitsEquality, | |
212 | hasCons = false, | |
213 | kind = kind, | |
214 | prettyDefault = prettyDefault, | |
215 | region = Ast.Tycon.region name} | |
216 | val tycon = Tycon.Flexible flex | |
217 | in | |
218 | Env.extendTycon (E, name, TypeStr.tycon (tycon, equality)) | |
219 | end) | |
220 | ||
221 | fun elabTypBind (typBind: TypBind.t, E, {sequential}) = | |
222 | let | |
223 | fun mkDef {def, tycon = _, tyvars} = | |
224 | TyvarEnv.scope | |
225 | (tyvars, fn tyvars => | |
226 | let | |
227 | val realization = | |
228 | TypeStr.def (elaborateScheme (tyvars, def, E)) | |
229 | val _ = | |
230 | TypeStr.pushSpec (realization, Ast.Type.region def) | |
231 | in | |
232 | realization | |
233 | end) | |
234 | val TypBind.T bs = TypBind.node typBind | |
235 | in | |
236 | if sequential | |
237 | then Vector.foreach | |
238 | (bs, fn b as {tycon, ...} => | |
239 | Env.extendTycon (E, tycon, mkDef b)) | |
240 | else Vector.foreach2 | |
241 | (bs, Vector.map (bs, mkDef), fn ({tycon, ...}, str) => | |
242 | Env.extendTycon (E, tycon, str)) | |
243 | end | |
244 | ||
245 | fun elaborateDatBind (datBind: DatBind.t, E, nest): unit = | |
246 | let | |
247 | val DatBind.T {datatypes, withtypes} = DatBind.node datBind | |
248 | (* Build enough of an interface so that that the constructor argument | |
249 | * types can be elaborated. | |
250 | *) | |
251 | val datatypes = | |
252 | Vector.map | |
253 | (datatypes, fn {cons, tycon = name, tyvars} => | |
254 | let | |
255 | val arity = Vector.length tyvars | |
256 | val kind = Kind.Arity arity | |
257 | val prettyDefault = | |
258 | concat (List.separate (rev (Ast.Tycon.toString name :: nest), ".")) | |
259 | val flex = FlexibleTycon.new {admitsEquality = AdmitsEquality.Sometimes, | |
260 | hasCons = true, | |
261 | kind = kind, | |
262 | prettyDefault = prettyDefault, | |
263 | region = Ast.Tycon.region name} | |
264 | val tycon = Tycon.Flexible flex | |
265 | val _ = Env.extendTycon (E, name, TypeStr.tycon (tycon, false)) | |
266 | in | |
267 | {cons = cons, | |
268 | flex = flex, | |
269 | name = name, | |
270 | tycon = tycon, | |
271 | tyvars = tyvars} | |
272 | end) | |
273 | val _ = if TypBind.isEmpty withtypes | |
274 | then () | |
275 | else check (Control.Elaborate.allowSigWithtype, | |
276 | "withtype in signatures", | |
277 | TypBind.region withtypes) | |
278 | (* To match semantics of withtype in Core, | |
279 | * type binds are elaborated simultaneously. | |
280 | *) | |
281 | val _ = elabTypBind (withtypes, E, {sequential = false}) | |
282 | val datatypes = | |
283 | Vector.map | |
284 | (datatypes, fn {cons, flex, name, tycon, tyvars} => | |
285 | let | |
286 | val cons = | |
287 | Vector.map | |
288 | (cons, fn (name, arg) => | |
289 | TyvarEnv.scope | |
290 | (tyvars, fn tyvars => | |
291 | {arg = Option.map (arg, fn t => elaborateType (t, E)), | |
292 | name = name, | |
293 | tyvars = tyvars})) | |
294 | in | |
295 | {cons = cons, | |
296 | flex = flex, | |
297 | name = name, | |
298 | tycon = tycon} | |
299 | end) | |
300 | (* Maximize equality *) | |
301 | val change = ref false | |
302 | fun loop () = | |
303 | let | |
304 | val _ = | |
305 | Vector.foreach | |
306 | (datatypes, fn {cons, flex, ...} => | |
307 | let | |
308 | val isEquality = ref true | |
309 | val () = | |
310 | Vector.foreach | |
311 | (cons, fn {arg, tyvars, ...} => | |
312 | Option.foreach | |
313 | (arg, fn arg => | |
314 | let | |
315 | val argScheme = | |
316 | Scheme.make (tyvars, arg) | |
317 | in | |
318 | if Scheme.admitsEquality argScheme | |
319 | then () | |
320 | else isEquality := false | |
321 | end)) | |
322 | datatype z = datatype AdmitsEquality.t | |
323 | in | |
324 | case FlexibleTycon.admitsEquality flex of | |
325 | Always => Error.bug "ElaborateSigexp.elaborateDatBind: Always" | |
326 | | Never => () | |
327 | | Sometimes => | |
328 | if !isEquality | |
329 | then () | |
330 | else (FlexibleTycon.setAdmitsEquality (flex, Never) | |
331 | ; change := true) | |
332 | end) | |
333 | in | |
334 | if !change | |
335 | then (change := false; loop ()) | |
336 | else () | |
337 | end | |
338 | val () = loop () | |
339 | val () = | |
340 | Vector.foreach | |
341 | (datatypes, fn {cons, name, tycon, ...} => | |
342 | let | |
343 | val cons = | |
344 | Vector.map | |
345 | (cons, fn {arg, name, tyvars} => | |
346 | let | |
347 | val res = | |
348 | Type.con (tycon, Vector.map (tyvars, Type.var)) | |
349 | val ty = | |
350 | case arg of | |
351 | NONE => res | |
352 | | SOME arg => Type.arrow (arg, res) | |
353 | val scheme = | |
354 | Scheme.make (tyvars, ty) | |
355 | val () = | |
356 | Env.extendCon (E, name, scheme) | |
357 | in | |
358 | {name = name, | |
359 | scheme = scheme} | |
360 | end) | |
361 | val () = | |
362 | Env.rebindTycon | |
363 | (E, name, TypeStr.data (tycon, Cons.fromVector cons, false)) | |
364 | in | |
365 | () | |
366 | end) | |
367 | in | |
368 | () | |
369 | end | |
370 | ||
371 | val traceElaborateSigexp = | |
372 | Trace.trace2 ("ElaborateSigexp.elaborateSigexp", | |
373 | Sigexp.layout, | |
374 | fn {isTop, nest} => Layout.record [("isTop", Bool.layout isTop), | |
375 | ("nest", List.layout Layout.str nest)], | |
376 | Option.layout Interface.layout) | |
377 | val traceElaborateSpec = | |
378 | Trace.trace2 ("ElaborateSigexp.elaborateSpec", | |
379 | Spec.layout, | |
380 | fn {nest} => Layout.record [("nest", List.layout Layout.str nest)], | |
381 | Unit.layout) | |
382 | ||
383 | (* rule 65 *) | |
384 | fun elaborateSigexp (sigexp: Sigexp.t, {env = E: StructureEnv.t, nest: string list}): Interface.t option = | |
385 | let | |
386 | val strE = E | |
387 | val E = StructureEnv.makeInterfaceEnv E | |
388 | fun elaborateSigexp arg : Interface.t option = | |
389 | traceElaborateSigexp | |
390 | (fn (sigexp: Sigexp.t, {isTop, nest}) => | |
391 | case Sigexp.node sigexp of | |
392 | Sigexp.Spec spec => | |
393 | (* rule 62 *) | |
394 | SOME (#1 (Env.makeInterface (E, {isTop = isTop}, | |
395 | fn () => elaborateSpec (spec, {nest = nest})))) | |
396 | | Sigexp.Var x => | |
397 | (* rule 63 *) | |
398 | Option.map (Env.lookupSigid (E, x), Interface.copy) | |
399 | | Sigexp.Where {sigexp, equations} => | |
400 | (* rule 64 *) | |
401 | let | |
402 | val time = Interface.Time.tick () | |
403 | in | |
404 | Option.map | |
405 | (elaborateSigexp (sigexp, {isTop = false, nest = nest}), fn I => | |
406 | let | |
407 | val {layoutPrettyTycon = layoutPrettyEnvTycon, | |
408 | layoutPrettyFlexTycon, ...} = | |
409 | StructureEnv.makeLayoutPrettyTyconAndFlexTycon | |
410 | (strE, E, SOME I, {prefixUnset = true}) | |
411 | val _ = | |
412 | Vector.foreach | |
413 | (equations, fn eqn => | |
414 | case WhereEquation.node eqn of | |
415 | WhereEquation.Type {longtycon, ty, tyvars} => | |
416 | Option.app | |
417 | (Interface.lookupLongtycon | |
418 | (I, longtycon, Longtycon.region longtycon, | |
419 | {prefix = []}), | |
420 | fn (name, s) => | |
421 | let | |
422 | val realization = | |
423 | TyvarEnv.scope | |
424 | (tyvars, fn tyvars => | |
425 | TypeStr.def (elaborateScheme (tyvars, ty, E))) | |
426 | in | |
427 | TypeStr.wheree | |
428 | {layoutPrettyEnvTycon = layoutPrettyEnvTycon, | |
429 | layoutPrettyFlexTycon = layoutPrettyFlexTycon, | |
430 | realization = realization, | |
431 | region = WhereEquation.region eqn, | |
432 | time = time, | |
433 | ty = {name = fn () => Longtycon.layout longtycon, | |
434 | region = Longtycon.region longtycon, | |
435 | spec = Ast.Tycon.region name, | |
436 | tyStr = s}} | |
437 | end)) | |
438 | in | |
439 | I | |
440 | end) | |
441 | end) arg | |
442 | and elaborateSpec arg : unit = | |
443 | traceElaborateSpec | |
444 | (fn (spec: Spec.t, {nest}) => | |
445 | case Spec.node spec of | |
446 | Spec.Datatype rhs => | |
447 | (* rules 71, 72 *) | |
448 | (case DatatypeRhs.node rhs of | |
449 | DatatypeRhs.DatBind b => elaborateDatBind (b, E, nest) | |
450 | | DatatypeRhs.Repl {lhs, rhs} => | |
451 | Option.app | |
452 | (Env.lookupLongtycon (E, rhs), fn s => | |
453 | let | |
454 | val _ = TypeStr.pushSpec (s, Longtycon.region rhs) | |
455 | val _ = Env.extendTycon (E, lhs, TypeStr.repl s) | |
456 | val _ = | |
457 | Vector.foreach | |
458 | (Cons.dest (TypeStr.cons s), fn {name, scheme} => | |
459 | Env.extendCon (E, name, scheme)) | |
460 | in | |
461 | () | |
462 | end)) | |
463 | | Spec.Empty => | |
464 | (* rule 76 *) | |
465 | () | |
466 | | Spec.Eqtype typedescs => | |
467 | (* rule 70 *) | |
468 | elaborateTypedescs (typedescs, {equality = true}, E, nest) | |
469 | | Spec.Exception cons => | |
470 | (* rule 73 *) | |
471 | Vector.foreach | |
472 | (cons, fn (name: Ast.Con.t, arg: Ast.Type.t option) => | |
473 | let | |
474 | val ty = | |
475 | case arg of | |
476 | NONE => Type.exn | |
477 | | SOME t => | |
478 | let | |
479 | val t = elaborateType (t, E) | |
480 | in | |
481 | Type.arrow (t, Type.exn) | |
482 | end | |
483 | val scheme = Scheme.make (Vector.new0 (), ty) | |
484 | val _ = Env.extendExn (E, name, scheme) | |
485 | in | |
486 | () | |
487 | end) | |
488 | | Spec.IncludeSigexp sigexp => | |
489 | (* rule 75 *) | |
490 | Option.app (elaborateSigexp (sigexp, {isTop = false, nest = nest}), fn I => | |
491 | Env.openInterface (E, I, Sigexp.region sigexp)) | |
492 | | Spec.IncludeSigids sigids => | |
493 | (* Appendix A, p.59 *) | |
494 | Vector.foreach (sigids, fn x => | |
495 | Option.app | |
496 | (Env.lookupSigid (E, x), fn I => | |
497 | Env.openInterface | |
498 | (E, Interface.copy I, Sigid.region x))) | |
499 | | Spec.Seq (s, s') => | |
500 | (* rule 77 *) | |
501 | (elaborateSpec (s, {nest = nest}) | |
502 | ; elaborateSpec (s', {nest = nest})) | |
503 | | Spec.Sharing {equation, spec} => | |
504 | (* rule 78 and section G.3.3 *) | |
505 | let | |
506 | val time = Interface.Time.tick () | |
507 | (* Reifying the interface of spec is expensive, | |
508 | * so collect all `sharing` equations that | |
509 | * constrain the same spec. | |
510 | *) | |
511 | val (spec, equations) = | |
512 | let | |
513 | fun loop (spec, equations) = | |
514 | case Spec.node spec of | |
515 | Spec.Sharing {equation, spec} => | |
516 | loop (spec, equation::equations) | |
517 | | _ => (spec, equations) | |
518 | in | |
519 | loop (spec, [equation]) | |
520 | end | |
521 | val (I, _) = | |
522 | Env.makeInterface | |
523 | (E, {isTop = false}, | |
524 | fn () => elaborateSpec (spec, {nest = nest})) | |
525 | val () = Env.openInterface (E, I, Spec.region spec) | |
526 | val {layoutPrettyTycon = layoutPrettyEnvTycon, | |
527 | layoutPrettyFlexTycon, ...} = | |
528 | StructureEnv.makeLayoutPrettyTyconAndFlexTycon | |
529 | (strE, E, NONE, {prefixUnset = true}) | |
530 | val () = | |
531 | List.foreach | |
532 | (equations, fn eqn => | |
533 | case SharingEquation.node eqn of | |
534 | SharingEquation.Structure ss => | |
535 | let | |
536 | (* The following implements the "all | |
537 | * pairs" sharing as specified in | |
538 | * Appendix A (and described in | |
539 | * Appendix G.3.3). | |
540 | *) | |
541 | fun loop Is = | |
542 | case Is of | |
543 | [] => () | |
544 | | (long1, I1) :: Is => | |
545 | (List.foreach | |
546 | (Is, fn (long2, I2) => | |
547 | Interface.share | |
548 | {layoutPrettyEnvTycon = layoutPrettyEnvTycon, | |
549 | layoutPrettyFlexTycon = layoutPrettyFlexTycon, | |
550 | I1 = I1, long1 = long1, | |
551 | I2 = I2, long2 = long2, | |
552 | region = SharingEquation.region eqn, | |
553 | time = time}) | |
554 | ; loop Is) | |
555 | val Is = | |
556 | List.keepAllMap | |
557 | (ss, fn s => | |
558 | Option.map | |
559 | (Interface.lookupLongstrid | |
560 | (I, s, Longstrid.region s, {prefix = []}), | |
561 | fn I => (s, I))) | |
562 | in | |
563 | loop Is | |
564 | end | |
565 | | SharingEquation.Type cs => | |
566 | ignore | |
567 | (List.fold | |
568 | (cs, NONE, fn (c', so) => | |
569 | case (so, Interface.lookupLongtycon (I, c', Longtycon.region c', {prefix = []})) of | |
570 | (NONE, NONE) => NONE | |
571 | | (SOME _, NONE) => so | |
572 | | (NONE, SOME (n', s')) => SOME (c', n', s') | |
573 | | (SOME (c, n, s), SOME (n', s')) => | |
574 | let | |
575 | fun mkTy (c, n, s) = | |
576 | {name = fn () => Longtycon.layout c, | |
577 | region = Longtycon.region c, | |
578 | spec = Ast.Tycon.region n, | |
579 | tyStr = s} | |
580 | val _ = | |
581 | TypeStr.share | |
582 | {layoutPrettyEnvTycon = layoutPrettyEnvTycon, | |
583 | layoutPrettyFlexTycon = layoutPrettyFlexTycon, | |
584 | region = SharingEquation.region eqn, | |
585 | time = time, | |
586 | ty1 = mkTy (c, n, s), | |
587 | ty2 = mkTy (c', n', s')} | |
588 | in | |
589 | SOME (c', n', s') | |
590 | end))) | |
591 | in | |
592 | () | |
593 | end | |
594 | | Spec.Structure ss => | |
595 | (* rules 74, 84 *) | |
596 | let | |
597 | val ss = | |
598 | Vector.map | |
599 | (ss, fn (strid, sigexp) => | |
600 | (strid, | |
601 | case elaborateSigexp | |
602 | (sigexp, | |
603 | {isTop = false, | |
604 | nest = (Ast.Strid.toString strid)::nest}) of | |
605 | NONE => Interface.empty | |
606 | | SOME I => I)) | |
607 | in | |
608 | Vector.foreach | |
609 | (ss, fn (strid, I) => | |
610 | Env.extendStrid | |
611 | (E, strid, I)) | |
612 | end | |
613 | | Spec.Type typedescs => | |
614 | (* rule 69 *) | |
615 | elaborateTypedescs (typedescs, {equality = false}, E, nest) | |
616 | | Spec.TypeDefs typBind => | |
617 | (* Abbreviation on page 59 combined with rules 77 and 80. *) | |
618 | elabTypBind (typBind, E, {sequential = true}) | |
619 | | Spec.Val xts => | |
620 | (* rules 68, 79 *) | |
621 | Vector.foreach | |
622 | (xts, fn (x, t) => | |
623 | Env.extendVid | |
624 | (E, Ast.Vid.fromVar x, Status.Var, | |
625 | let | |
626 | val tyvars = | |
627 | let | |
628 | val tyvars = ref [] | |
629 | fun loop t = | |
630 | case Ast.Type.node t of | |
631 | Atype.Var a => | |
632 | if List.contains (!tyvars, a, Atyvar.equals) | |
633 | then () | |
634 | else List.push (tyvars, a) | |
635 | | Atype.Con (_, ts) => | |
636 | Vector.foreach (ts, loop) | |
637 | | Atype.Paren t => loop t | |
638 | | Atype.Record r => Record.foreach (r, loop o #2) | |
639 | val () = loop t | |
640 | in | |
641 | Vector.fromListRev (!tyvars) | |
642 | end | |
643 | in | |
644 | TyvarEnv.scope | |
645 | (tyvars, fn tyvars => | |
646 | elaborateScheme (tyvars, t, E)) | |
647 | end))) arg | |
648 | in | |
649 | elaborateSigexp (sigexp, {isTop = true, nest = nest}) | |
650 | end | |
651 | ||
652 | val elaborateSigexp = | |
653 | fn (sigexp, {env = E, nest}) => | |
654 | case Sigexp.node sigexp of | |
655 | Sigexp.Var x => StructureEnv.lookupSigid (E, x) | |
656 | | _ => elaborateSigexp (sigexp, {env = E, nest = nest}) | |
657 | ||
658 | val elaborateSigexp = | |
659 | Trace.trace2 ("ElaborateSigexp.elaborateSigexp", | |
660 | Sigexp.layout, | |
661 | Layout.ignore, | |
662 | Layout.ignore) | |
663 | elaborateSigexp | |
664 | ||
665 | structure Env = StructureEnv | |
666 | ||
667 | end |