Home My Page Projects Code Snippets Project Openings diderot
Summary Activity Tracker Tasks SCM

SCM Repository

[diderot] Annotation of /branches/vis15/src/compiler/typechecker/env.sml
ViewVC logotype

Annotation of /branches/vis15/src/compiler/typechecker/env.sml

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3431 - (view) (download)

1 : jhr 3396 (* env.sml
2 :     *
3 :     * Environments and contexts to support typechecking.
4 :     *
5 :     * This code is part of the Diderot Project (http://diderot-language.cs.uchicago.edu)
6 :     *
7 :     * COPYRIGHT (c) 2015 The University of Chicago
8 :     * All rights reserved.
9 :     *)
10 :    
11 :     structure Env : sig
12 :    
13 : jhr 3407 type t
14 :    
15 : jhr 3410 (* create a new environment at global scope that includes the basis environment *)
16 :     val new : unit -> t
17 :    
18 : jhr 3407 type context = Error.err_stream * Error.span
19 :    
20 : jhr 3396 datatype scope
21 :     = GlobalScope (* global declarations *)
22 : jhr 3401 | FunctionScope of Types.ty * Atom.atom (* inside a function definition *)
23 : jhr 3396 | StrandScope (* inside a strand definition *)
24 :     | MethodScope of StrandUtil.method_name (* inside a strand method definition *)
25 :     | InitScope (* inside global initialization *)
26 :     | CreateScope (* inside initial strand creation *)
27 :     | UpdateScope (* inside global update *)
28 :    
29 : jhr 3431 (* string representation of scope *)
30 : jhr 3396 val scopeToString : scope -> string
31 :    
32 : jhr 3431 (* return the current scope *)
33 : jhr 3407 val currentScope : t -> scope
34 : jhr 3396
35 : jhr 3431 (* are we currently in a strand method scope? *)
36 : jhr 3407 val inMethod : t -> bool
37 : jhr 3396
38 : jhr 3431 (* are we currently in a strand scope? *)
39 : jhr 3407 val inStrand : t -> bool
40 :    
41 : jhr 3431 (* are we currently in a global update block? *)
42 :     val inGlobalUpdate : t -> bool
43 :    
44 : jhr 3408 (* start a new function scope *)
45 :     val functionScope : t * Types.ty * Atom.atom -> t
46 :     (* start a new strand scope *)
47 :     val strandScope : t -> t
48 :     (* start a new strand scope *)
49 :     val methodScope : t * StrandUtil.method_name -> t
50 :     (* start a new global initialization scope *)
51 :     val initScope : t -> t
52 :     (* start a new initial-strand creation scope *)
53 :     val createScope : t -> t
54 :     (* start a new global update scope *)
55 :     val updateScope : t -> t
56 :     (* start a new block scope *)
57 :     val blockScope : t -> t
58 :    
59 : jhr 3405 (* functions are either user-defined or pre-defined *)
60 :     datatype fun_def
61 :     = PrimFun of AST.var list (* possibly overloaded builtin function *)
62 :     | UserFun of AST.var (* user-defined function *)
63 :    
64 : jhr 3409 (* insert a global variable into the environment (includes constants and inputs) *)
65 :     val insertGlobal : t * context * Atom.atom * AST.var -> t
66 :    
67 :     (* insert a user function into the environment *)
68 :     val insertFunc : t * context * Atom.atom * AST.var -> t
69 :    
70 : jhr 3410 (* insert a strand into the environment *)
71 : jhr 3428 val insertStrand : t * context * StrandEnv.t -> t
72 : jhr 3410
73 : jhr 3408 (* insert a local variable into the environment *)
74 :     val insertLocal : t * context * Atom.atom * AST.var -> t
75 :    
76 : jhr 3407 val findStrand : t * Atom.atom -> StrandEnv.t option
77 :     val findFunc : t * Atom.atom -> fun_def
78 :     val findVar : t * Atom.atom -> AST.var option
79 : jhr 3405
80 : jhr 3431 (* find the strand-set function with the given name *)
81 :     val findSetFn : t * Atom.atom -> AST.var option
82 :    
83 : jhr 3396 (* unwrap a parse-tree location marker and update the context with the span *)
84 :     val withContext : context * 'a Error.mark -> (context * 'a)
85 :    
86 :     (* same as `withContext`, but includes the environment too *)
87 : jhr 3407 val withEnvAndContext : t * context * 'a Error.mark -> (t * context * 'a)
88 : jhr 3396
89 : jhr 3408 (* check for redefinition of an identifier in the same scope *)
90 :     val checkForRedef : t * context * Atom.atom -> unit
91 :    
92 :     (* tracking program features *)
93 : jhr 3431 val recordProp : t * Properties.t -> unit
94 :     val properties : t -> Properties.t list
95 : jhr 3408
96 : jhr 3396 end = struct
97 :    
98 :     structure GE = GlobalEnv
99 : jhr 3401 structure Ty = Types
100 :     structure AMap = AtomMap
101 : jhr 3396
102 : jhr 3405 datatype fun_def = datatype GE.fun_def
103 :    
104 : jhr 3396 datatype scope
105 :     = GlobalScope (* global declarations *)
106 :     | FunctionScope of Ty.ty * Atom.atom (* inside a function definition *)
107 :     | StrandScope (* inside a strand definition *)
108 :     | MethodScope of StrandUtil.method_name (* inside a strand method definition *)
109 :     | InitScope (* inside global initialization *)
110 :     | CreateScope (* inside initial strand creation *)
111 :     | UpdateScope (* inside global update *)
112 :    
113 :     fun scopeToString GlobalScope = "global scope"
114 :     | scopeToString (FunctionScope(_, f)) = "function " ^ Atom.toString f
115 :     | scopeToString StrandScope = "strand initialization"
116 :     | scopeToString (MethodScope m) = "method " ^ StrandUtil.nameToString m
117 :     | scopeToString InitScope = "initialization"
118 :     | scopeToString CreateScope = "strand creation"
119 :     | scopeToString UpdateScope = "global update"
120 :    
121 : jhr 3407 datatype t = E of {
122 : jhr 3396 scope : scope, (* current scope *)
123 :     (* NOTE: since we added location info to variables, we probably don't need this anymore! *)
124 : jhr 3401 bindings : Error.location AMap.map, (* map from atoms to innermost binding location *)
125 :     gEnv : GE.t, (* global environment *)
126 : jhr 3396 vEnv : AST.var AMap.map (* variables defined in inner scopes *)
127 :     }
128 :    
129 :     type context = Error.err_stream * Error.span
130 :    
131 : jhr 3410 (* create a fresh environment with global scope from a global environment *)
132 :     fun new () = E{
133 :     scope = GlobalScope,
134 :     bindings = AMap.empty,
135 :     gEnv = Basis.env(),
136 :     vEnv = AMap.empty
137 :     }
138 :    
139 : jhr 3396 (* start a new scope *)
140 : jhr 3405 fun functionScope (E{scope, bindings, gEnv, vEnv}, ty, f) =
141 :     E{scope=FunctionScope(ty, f), bindings=AtomMap.empty, gEnv=gEnv, vEnv=vEnv}
142 :     fun strandScope (E{scope, bindings, gEnv, vEnv}) =
143 :     E{scope=StrandScope, bindings=AtomMap.empty, gEnv=gEnv, vEnv=vEnv}
144 :     fun methodScope (E{scope, bindings, gEnv, vEnv}, name) =
145 :     E{scope=MethodScope name, bindings=AtomMap.empty, gEnv=gEnv, vEnv=vEnv}
146 :     fun initScope (E{scope, bindings, gEnv, vEnv}) =
147 :     E{scope=InitScope, bindings=AtomMap.empty, gEnv=gEnv, vEnv=vEnv}
148 : jhr 3408 fun createScope (E{scope, bindings, gEnv, vEnv}) =
149 :     E{scope=CreateScope, bindings=AtomMap.empty, gEnv=gEnv, vEnv=vEnv}
150 :     fun updateScope (E{scope, bindings, gEnv, vEnv}) =
151 :     E{scope=UpdateScope, bindings=AtomMap.empty, gEnv=gEnv, vEnv=vEnv}
152 : jhr 3405 fun blockScope (E{scope, bindings, gEnv, vEnv}) =
153 :     E{scope=scope, bindings=AtomMap.empty, gEnv=gEnv, vEnv=vEnv}
154 : jhr 3396
155 : jhr 3407 fun currentScope (E{scope, ...}) = scope
156 :    
157 : jhr 3405 fun inMethod (E{scope=MethodScope _, ...}) = true
158 : jhr 3396 | inMethod _ = false
159 :    
160 : jhr 3405 fun inStrand (E{scope=StrandScope, ...}) = true
161 :     | inStrand (E{scope=MethodScope _, ...}) = true
162 : jhr 3396 | inStrand _ = false
163 :    
164 : jhr 3431 fun inGlobalUpdate (E{scope=UpdateScope, ...}) = true
165 :     | inGlobalUpdate _ = false
166 :    
167 : jhr 3405 fun findStrand (E{gEnv, ...}, s) = GE.findStrand(gEnv, s)
168 :     fun findFunc (E{gEnv, ...}, f) = GE.findFunc(gEnv, f)
169 :     fun findVar (E{gEnv, vEnv, ...}, x) = (case AMap.find(vEnv, x)
170 :     of NONE => GE.findVar (gEnv, x)
171 :     | someVar => someVar
172 :     (* end case *))
173 :    
174 : jhr 3431 (* find the strand-set function with the given name; we do this by brute force
175 :     * for now.
176 :     *)
177 :     fun findSetFn (_, name) =
178 :     if Atom.same(name, BasisNames.set_active) then SOME BasisVars.set_active
179 :     else if Atom.same(name, BasisNames.set_all) then SOME BasisVars.set_all
180 :     else if Atom.same(name, BasisNames.set_stable) then SOME BasisVars.set_stable
181 :     else NONE
182 :    
183 : jhr 3409 fun insertGlobal (E{scope, bindings, gEnv, vEnv}, cxt, x, x') = let
184 :     val loc = Error.location cxt
185 :     in
186 :     (* setLoc(x', loc);*)
187 :     GE.insertVar (gEnv, x, x');
188 :     E{
189 :     scope = scope,
190 :     bindings = AtomMap.insert(bindings, x, loc),
191 :     gEnv = gEnv,
192 : jhr 3405 vEnv = vEnv
193 : jhr 3409 }
194 :     end
195 :    
196 : jhr 3405 fun insertFunc (E{scope, bindings, gEnv, vEnv}, cxt, f, f') = let
197 : jhr 3396 val loc = Error.location cxt
198 :     in
199 : jhr 3402 (* setLoc(f', loc);*)
200 : jhr 3405 GE.insertFunc(gEnv, f, GE.UserFun f');
201 :     E{
202 : jhr 3396 scope = scope,
203 :     bindings = AtomMap.insert(bindings, f, loc),
204 : jhr 3405 gEnv = gEnv,
205 : jhr 3401 vEnv = vEnv
206 : jhr 3396 }
207 :     end
208 : jhr 3409
209 : jhr 3428 fun insertStrand (E{scope, bindings, gEnv, vEnv}, cxt, sEnv) = let
210 :     val () = GE.insertStrand(gEnv, sEnv)
211 : jhr 3410 val env = E{
212 :     scope=scope,
213 : jhr 3428 bindings = AtomMap.insert(bindings, StrandEnv.strandName sEnv, Error.location cxt),
214 : jhr 3410 gEnv = gEnv,
215 :     vEnv = vEnv
216 :     }
217 :     in
218 : jhr 3428 env
219 : jhr 3410 end
220 : jhr 3409
221 : jhr 3405 fun insertLocal (E{scope, bindings, gEnv, vEnv}, cxt, x, x') = let
222 : jhr 3396 val loc = Error.location cxt
223 :     in
224 : jhr 3402 (* setLoc(x', loc);*)
225 : jhr 3405 E{
226 : jhr 3396 scope = scope,
227 :     bindings = AtomMap.insert(bindings, x, loc),
228 : jhr 3401 gEnv = gEnv,
229 :     vEnv = AMap.insert(vEnv, x, x')
230 : jhr 3396 }
231 :     end
232 :    
233 :     fun withContext ((errStrm, _), {span, tree}) =
234 :     ((errStrm, span), tree)
235 :     fun withEnvAndContext (env, (errStrm, _), {span, tree}) =
236 :     (env, (errStrm, span), tree)
237 :    
238 :     (* check for redefinition of an identifier in the same scope *)
239 :     (* TODO: check for shadowing too? *)
240 : jhr 3405 fun checkForRedef (E{bindings, ...}, cxt : context, x) = (case AtomMap.find(bindings, x)
241 : jhr 3401 of SOME loc => TypeError.error (cxt, [
242 :     TypeError.S "redefinition of ", TypeError.A x,
243 :     TypeError.S(Error.fmt (", previous definition at line %l", "") loc)
244 : jhr 3396 ])
245 :     | NONE => ()
246 :     (* end case *))
247 :    
248 : jhr 3408 (* tracking program features *)
249 :     fun recordProp (E{gEnv, ...}, p) = GE.recordProp (gEnv, p)
250 :     fun properties (E{gEnv, ...}) = GE.properties gEnv
251 :    
252 : jhr 3396 end

root@smlnj-gforge.cs.uchicago.edu
ViewVC Help
Powered by ViewVC 1.0.0