Commit | Line | Data |
---|---|---|
7f918cf1 CE |
1 | (* Copyright (C) 1999-2006 Henry Cejtin, Matthew Fluet, Suresh |
2 | * Jagannathan, and Stephen Weeks. | |
3 | * | |
4 | * MLton is released under a BSD-style license. | |
5 | * See the file MLton-LICENSE for details. | |
6 | *) | |
7 | (*-------------------------------------------------------------------*) | |
8 | (* Env *) | |
9 | (*-------------------------------------------------------------------*) | |
10 | ||
11 | functor Env(D: T): ENV = | |
12 | struct | |
13 | ||
14 | structure D = D | |
15 | structure L = List | |
16 | ||
17 | datatype 'a t = T of (D.t * 'a) L.t | |
18 | ||
19 | fun empty() = T(L.empty()) | |
20 | ||
21 | fun isEmpty(T l) = L.isEmpty l | |
22 | ||
23 | fun equal d (d', _) = D.equals(d, d') | |
24 | ||
25 | fun singleton dr = T(L.single dr) | |
26 | ||
27 | fun add(T l, d, r) = T((d, r) :: (L.maybeRemoveFirst(l, equal d))) | |
28 | ||
29 | fun peek(T l, d) = | |
30 | case L.keepFirst(l, equal d) of | |
31 | NONE => NONE | |
32 | | SOME (_, r) => SOME r | |
33 | ||
34 | fun lookup ed = case peek ed of | |
35 | SOME r => r | |
36 | | NONE => Error.error "Env.lookup" | |
37 | ||
38 | fun dom(T l) = L.map(l, #1) | |
39 | ||
40 | fun range(T l) = L.map(l, #2) | |
41 | ||
42 | fun remove(T ps, d) = T(L.removeFirst(ps, equal d)) | |
43 | ||
44 | fun foldl(T l, b, f) = L.foldl(l, b, fn (b, (d, r)) => f(b, d, r)) | |
45 | ||
46 | fun e + e' = foldl(e', e, add) | |
47 | ||
48 | fun foreach(T ps, f) = L.foreach(ps, f) | |
49 | ||
50 | fun multiExtend(env, [], []) = env | |
51 | | multiExtend(env, d :: ds, r :: rs) = multiExtend(extend(env, d, r), ds, rs) | |
52 | | multiExtend _ = Error.error "Env.multiExtend" | |
53 | ||
54 | fun merge(e as T p, e' as T p', f) = | |
55 | let val leftAndBoth = L.map(p, fn (d, r) => | |
56 | case peek(e', d) of | |
57 | NONE => (d, r) | |
58 | | SOME r' => (d, f(r, r'))) | |
59 | val right = L.keepAll(p', | |
60 | fn (d, _) => | |
61 | case peek(e, d) of | |
62 | NONE => true | |
63 | | SOME _ => false) | |
64 | in T(leftAndBoth @ right) | |
65 | end | |
66 | ||
67 | fun output(T ps, outputR, out) = | |
68 | let val print = Out.outputc out | |
69 | fun outputDR((d, r), out) = (D.output(d, out) ; | |
70 | print "->" ; | |
71 | outputR(r, out)) | |
72 | in (print "[" ; | |
73 | L.output(ps, ", ", outputDR, out) ; | |
74 | print "]") | |
75 | end | |
76 | ||
77 | end |