-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathNestEnv.lhs
92 lines (77 loc) · 3.26 KB
/
NestEnv.lhs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
% -*- LaTeX -*-
% $Id: NestEnv.lhs 1848 2006-02-06 09:03:30Z wlux $
%
% Copyright (c) 1999-2005, Wolfgang Lux
% See LICENSE for the full license.
%
\nwfilename{NestEnv.lhs}
\subsection{Nested Environments}
The \texttt{NestEnv} environment type extends top-level environments
(see section~\ref{sec:toplevel-env}) to manage nested scopes. Local
scopes allow only for a single, unambiguous definition.
For convenience, the type \texttt{TopEnv} is exported by the module
\texttt{NestEnv}.
\begin{verbatim}
> module NestEnv(NestEnv, TopEnv, Entity(..),
> globalBindNestEnv, localBindNestEnv, qualBindNestEnv,
> lookupNestEnv, qualLookupNestEnv,
> toplevelEnv, globalEnv, nestEnv) where
> import Env
> import TopEnv
> import Ident
> data NestEnv a = GlobalEnv (TopEnv a) | LocalEnv (NestEnv a) (Env Ident a)
> deriving Show
> instance Functor NestEnv where
> fmap f (GlobalEnv env) = GlobalEnv (fmap f env)
> fmap f (LocalEnv genv env) = LocalEnv (fmap f genv) (fmap f env)
\end{verbatim}
The functions \texttt{globalBindNestEnv} and \texttt{localBindNestEnv}
implement binding of global and local definitions, respectively. The
former introduces bindings for the qualified and unqualified names of
an entity, the latter only for the unqualified name.
\begin{verbatim}
> globalBindNestEnv :: ModuleIdent -> Ident -> a -> NestEnv a -> NestEnv a
> globalBindNestEnv m x y (GlobalEnv env) =
> GlobalEnv (globalBindTopEnv m x y env)
> globalBindNestEnv _ _ _ (LocalEnv _ _) =
> error "internal error: globalBindNestEnv"
> localBindNestEnv :: Ident -> a -> NestEnv a -> NestEnv a
> localBindNestEnv _ _ (GlobalEnv _) =
> error "internal error: localBindNestEnv"
> localBindNestEnv x y (LocalEnv genv env) =
> case lookupEnv x env of
> Just _ -> error "internal error: bindNestEnv"
> Nothing -> LocalEnv genv (bindEnv x y env)
> qualBindNestEnv :: QualIdent -> a -> NestEnv a -> NestEnv a
> qualBindNestEnv x y (GlobalEnv env) = GlobalEnv (qualBindTopEnv x y env)
> qualBindNestEnv x y (LocalEnv genv env)
> | isQualified x = error "internal error: qualBindNestEnv"
> | otherwise =
> case lookupEnv x' env of
> Just _ -> error "internal error: qualBindNestEnv"
> Nothing -> LocalEnv genv (bindEnv x' y env)
> where x' = unqualify x
> lookupNestEnv :: Ident -> NestEnv a -> [a]
> lookupNestEnv x (GlobalEnv env) = lookupTopEnv x env
> lookupNestEnv x (LocalEnv genv env) =
> case lookupEnv x env of
> Just y -> [y]
> Nothing -> lookupNestEnv x genv
> qualLookupNestEnv :: QualIdent -> NestEnv a -> [a]
> qualLookupNestEnv x env
> | isQualified x = qualLookupTopEnv x (toplevelEnv env)
> | otherwise = lookupNestEnv (unqualify x) env
\end{verbatim}
The function \texttt{toplevelEnv} returns the top-level environment of
a nested environment discarding all local scopes. The function
\texttt{globalEnv} transforms a flat top-level environment into a
nested environment and \texttt{nestEnv} opens a new nesting scope.
\begin{verbatim}
> toplevelEnv :: NestEnv a -> TopEnv a
> toplevelEnv (GlobalEnv env) = env
> toplevelEnv (LocalEnv genv _) = toplevelEnv genv
> globalEnv :: TopEnv a -> NestEnv a
> globalEnv = GlobalEnv
> nestEnv :: NestEnv a -> NestEnv a
> nestEnv env = LocalEnv env emptyEnv
\end{verbatim}