Mercurial > urweb
comparison src/elab_env.sml @ 157:adc4e42e3adc
Basic datatype importing works
author | Adam Chlipala <adamc@hcoop.net> |
---|---|
date | Thu, 24 Jul 2008 15:49:30 -0400 |
parents | 34ccd7d2bea8 |
children | b4b70de488e9 |
comparison
equal
deleted
inserted
replaced
156:34ccd7d2bea8 | 157:adc4e42e3adc |
---|---|
71 datatype 'a var = | 71 datatype 'a var = |
72 NotBound | 72 NotBound |
73 | Rel of int * 'a | 73 | Rel of int * 'a |
74 | Named of int * 'a | 74 | Named of int * 'a |
75 | 75 |
76 type datatyp = (string * con option) IM.map | |
77 | |
76 type env = { | 78 type env = { |
77 renameC : kind var' SM.map, | 79 renameC : kind var' SM.map, |
78 relC : (string * kind) list, | 80 relC : (string * kind) list, |
79 namedC : (string * kind * con option) IM.map, | 81 namedC : (string * kind * con option) IM.map, |
80 | 82 |
83 datatypes : datatyp IM.map, | |
84 | |
81 renameE : con var' SM.map, | 85 renameE : con var' SM.map, |
82 relE : (string * con) list, | 86 relE : (string * con) list, |
83 namedE : (string * con) IM.map, | 87 namedE : (string * con) IM.map, |
84 | 88 |
85 renameSgn : (int * sgn) SM.map, | 89 renameSgn : (int * sgn) SM.map, |
102 val empty = { | 106 val empty = { |
103 renameC = SM.empty, | 107 renameC = SM.empty, |
104 relC = [], | 108 relC = [], |
105 namedC = IM.empty, | 109 namedC = IM.empty, |
106 | 110 |
111 datatypes = IM.empty, | |
112 | |
107 renameE = SM.empty, | 113 renameE = SM.empty, |
108 relE = [], | 114 relE = [], |
109 namedE = IM.empty, | 115 namedE = IM.empty, |
110 | 116 |
111 renameSgn = SM.empty, | 117 renameSgn = SM.empty, |
121 | x => x) (#renameC env) | 127 | x => x) (#renameC env) |
122 in | 128 in |
123 {renameC = SM.insert (renameC, x, Rel' (0, k)), | 129 {renameC = SM.insert (renameC, x, Rel' (0, k)), |
124 relC = (x, k) :: #relC env, | 130 relC = (x, k) :: #relC env, |
125 namedC = IM.map (fn (x, k, co) => (x, k, Option.map lift co)) (#namedC env), | 131 namedC = IM.map (fn (x, k, co) => (x, k, Option.map lift co)) (#namedC env), |
132 | |
133 datatypes = #datatypes env, | |
126 | 134 |
127 renameE = #renameE env, | 135 renameE = #renameE env, |
128 relE = map (fn (x, c) => (x, lift c)) (#relE env), | 136 relE = map (fn (x, c) => (x, lift c)) (#relE env), |
129 namedE = IM.map (fn (x, c) => (x, lift c)) (#namedE env), | 137 namedE = IM.map (fn (x, c) => (x, lift c)) (#namedE env), |
130 | 138 |
142 | 150 |
143 fun pushCNamedAs (env : env) x n k co = | 151 fun pushCNamedAs (env : env) x n k co = |
144 {renameC = SM.insert (#renameC env, x, Named' (n, k)), | 152 {renameC = SM.insert (#renameC env, x, Named' (n, k)), |
145 relC = #relC env, | 153 relC = #relC env, |
146 namedC = IM.insert (#namedC env, n, (x, k, co)), | 154 namedC = IM.insert (#namedC env, n, (x, k, co)), |
155 | |
156 datatypes = #datatypes env, | |
147 | 157 |
148 renameE = #renameE env, | 158 renameE = #renameE env, |
149 relE = #relE env, | 159 relE = #relE env, |
150 namedE = #namedE env, | 160 namedE = #namedE env, |
151 | 161 |
172 case SM.find (#renameC env, x) of | 182 case SM.find (#renameC env, x) of |
173 NONE => NotBound | 183 NONE => NotBound |
174 | SOME (Rel' x) => Rel x | 184 | SOME (Rel' x) => Rel x |
175 | SOME (Named' x) => Named x | 185 | SOME (Named' x) => Named x |
176 | 186 |
187 fun pushDatatype (env : env) n xncs = | |
188 {renameC = #renameC env, | |
189 relC = #relC env, | |
190 namedC = #namedC env, | |
191 | |
192 datatypes = IM.insert (#datatypes env, n, | |
193 foldl (fn ((x, n, to), cons) => | |
194 IM.insert (cons, n, (x, to))) IM.empty xncs), | |
195 | |
196 renameE = #renameE env, | |
197 relE = #relE env, | |
198 namedE = #namedE env, | |
199 | |
200 renameSgn = #renameSgn env, | |
201 sgn = #sgn env, | |
202 | |
203 renameStr = #renameStr env, | |
204 str = #str env} | |
205 | |
206 fun lookupDatatype (env : env) n = | |
207 case IM.find (#datatypes env, n) of | |
208 NONE => raise UnboundNamed n | |
209 | SOME x => x | |
210 | |
211 fun lookupConstructor dt n = | |
212 case IM.find (dt, n) of | |
213 NONE => raise UnboundNamed n | |
214 | SOME x => x | |
215 | |
216 fun constructors dt = IM.foldri (fn (n, (x, to), ls) => (x, n, to) :: ls) [] dt | |
217 | |
177 fun pushERel (env : env) x t = | 218 fun pushERel (env : env) x t = |
178 let | 219 let |
179 val renameE = SM.map (fn Rel' (n, t) => Rel' (n+1, t) | 220 val renameE = SM.map (fn Rel' (n, t) => Rel' (n+1, t) |
180 | x => x) (#renameE env) | 221 | x => x) (#renameE env) |
181 in | 222 in |
182 {renameC = #renameC env, | 223 {renameC = #renameC env, |
183 relC = #relC env, | 224 relC = #relC env, |
184 namedC = #namedC env, | 225 namedC = #namedC env, |
226 | |
227 datatypes = #datatypes env, | |
185 | 228 |
186 renameE = SM.insert (renameE, x, Rel' (0, t)), | 229 renameE = SM.insert (renameE, x, Rel' (0, t)), |
187 relE = (x, t) :: #relE env, | 230 relE = (x, t) :: #relE env, |
188 namedE = #namedE env, | 231 namedE = #namedE env, |
189 | 232 |
200 | 243 |
201 fun pushENamedAs (env : env) x n t = | 244 fun pushENamedAs (env : env) x n t = |
202 {renameC = #renameC env, | 245 {renameC = #renameC env, |
203 relC = #relC env, | 246 relC = #relC env, |
204 namedC = #namedC env, | 247 namedC = #namedC env, |
248 | |
249 datatypes = #datatypes env, | |
205 | 250 |
206 renameE = SM.insert (#renameE env, x, Named' (n, t)), | 251 renameE = SM.insert (#renameE env, x, Named' (n, t)), |
207 relE = #relE env, | 252 relE = #relE env, |
208 namedE = IM.insert (#namedE env, n, (x, t)), | 253 namedE = IM.insert (#namedE env, n, (x, t)), |
209 | 254 |
235 fun pushSgnNamedAs (env : env) x n sgis = | 280 fun pushSgnNamedAs (env : env) x n sgis = |
236 {renameC = #renameC env, | 281 {renameC = #renameC env, |
237 relC = #relC env, | 282 relC = #relC env, |
238 namedC = #namedC env, | 283 namedC = #namedC env, |
239 | 284 |
285 datatypes = #datatypes env, | |
286 | |
240 renameE = #renameE env, | 287 renameE = #renameE env, |
241 relE = #relE env, | 288 relE = #relE env, |
242 namedE = #namedE env, | 289 namedE = #namedE env, |
243 | 290 |
244 renameSgn = SM.insert (#renameSgn env, x, (n, sgis)), | 291 renameSgn = SM.insert (#renameSgn env, x, (n, sgis)), |
265 fun pushStrNamedAs (env : env) x n sgis = | 312 fun pushStrNamedAs (env : env) x n sgis = |
266 {renameC = #renameC env, | 313 {renameC = #renameC env, |
267 relC = #relC env, | 314 relC = #relC env, |
268 namedC = #namedC env, | 315 namedC = #namedC env, |
269 | 316 |
317 datatypes = #datatypes env, | |
318 | |
270 renameE = #renameE env, | 319 renameE = #renameE env, |
271 relE = #relE env, | 320 relE = #relE env, |
272 namedE = #namedE env, | 321 namedE = #namedE env, |
273 | 322 |
274 renameSgn = #renameSgn env, | 323 renameSgn = #renameSgn env, |
289 case IM.find (#str env, n) of | 338 case IM.find (#str env, n) of |
290 NONE => raise UnboundNamed n | 339 NONE => raise UnboundNamed n |
291 | SOME x => x | 340 | SOME x => x |
292 | 341 |
293 fun lookupStr (env : env) x = SM.find (#renameStr env, x) | 342 fun lookupStr (env : env) x = SM.find (#renameStr env, x) |
294 | |
295 fun declBinds env (d, loc) = | |
296 case d of | |
297 DCon (x, n, k, c) => pushCNamedAs env x n k (SOME c) | |
298 | DDatatype (x, n, xncs) => | |
299 let | |
300 val env = pushCNamedAs env x n (KType, loc) NONE | |
301 in | |
302 foldl (fn ((x', n', NONE), env) => pushENamedAs env x' n' (CNamed n, loc) | |
303 | ((x', n', SOME t), env) => pushENamedAs env x' n' (TFun (t, (CNamed n, loc)), loc)) | |
304 env xncs | |
305 end | |
306 | DDatatypeImp (x, n, m, ms, x') => pushCNamedAs env x n (KType, loc) (SOME (CModProj (m, ms, x'), loc)) | |
307 | DVal (x, n, t, _) => pushENamedAs env x n t | |
308 | DValRec vis => foldl (fn ((x, n, t, _), env) => pushENamedAs env x n t) env vis | |
309 | DSgn (x, n, sgn) => pushSgnNamedAs env x n sgn | |
310 | DStr (x, n, sgn, _) => pushStrNamedAs env x n sgn | |
311 | DFfiStr (x, n, sgn) => pushStrNamedAs env x n sgn | |
312 | DConstraint _ => env | |
313 | DExport _ => env | |
314 | 343 |
315 fun sgiBinds env (sgi, loc) = | 344 fun sgiBinds env (sgi, loc) = |
316 case sgi of | 345 case sgi of |
317 SgiConAbs (x, n, k) => pushCNamedAs env x n k NONE | 346 SgiConAbs (x, n, k) => pushCNamedAs env x n k NONE |
318 | SgiCon (x, n, k, c) => pushCNamedAs env x n k (SOME c) | 347 | SgiCon (x, n, k, c) => pushCNamedAs env x n k (SOME c) |
477 fun projectCon env {sgn, str, field} = | 506 fun projectCon env {sgn, str, field} = |
478 case #1 (hnormSgn env sgn) of | 507 case #1 (hnormSgn env sgn) of |
479 SgnConst sgis => | 508 SgnConst sgis => |
480 (case sgnSeek (fn SgiConAbs (x, _, k) => if x = field then SOME (k, NONE) else NONE | 509 (case sgnSeek (fn SgiConAbs (x, _, k) => if x = field then SOME (k, NONE) else NONE |
481 | SgiCon (x, _, k, c) => if x = field then SOME (k, SOME c) else NONE | 510 | SgiCon (x, _, k, c) => if x = field then SOME (k, SOME c) else NONE |
511 | SgiDatatype (x, _, _) => if x = field then SOME ((KType, #2 sgn), NONE) else NONE | |
482 | _ => NONE) sgis of | 512 | _ => NONE) sgis of |
483 NONE => NONE | 513 NONE => NONE |
484 | SOME ((k, co), subs) => SOME (k, Option.map (sgnSubCon (str, subs)) co)) | 514 | SOME ((k, co), subs) => SOME (k, Option.map (sgnSubCon (str, subs)) co)) |
485 | SgnError => SOME ((KError, ErrorMsg.dummySpan), SOME (CError, ErrorMsg.dummySpan)) | 515 | SgnError => SOME ((KError, ErrorMsg.dummySpan), SOME (CError, ErrorMsg.dummySpan)) |
516 | _ => NONE | |
517 | |
518 fun projectDatatype env {sgn, str, field} = | |
519 case #1 (hnormSgn env sgn) of | |
520 SgnConst sgis => | |
521 (case sgnSeek (fn SgiDatatype (x, _, xncs) => if x = field then SOME xncs else NONE | |
522 | _ => NONE) sgis of | |
523 NONE => NONE | |
524 | SOME (xncs, subs) => SOME (map (fn (x, n, to) => (x, n, Option.map (sgnSubCon (str, subs)) to)) xncs)) | |
486 | _ => NONE | 525 | _ => NONE |
487 | 526 |
488 fun projectVal env {sgn, str, field} = | 527 fun projectVal env {sgn, str, field} = |
489 case #1 (hnormSgn env sgn) of | 528 case #1 (hnormSgn env sgn) of |
490 SgnConst sgis => | 529 SgnConst sgis => |
522 case #1 (hnormSgn env sgn) of | 561 case #1 (hnormSgn env sgn) of |
523 SgnConst sgis => SOME (sgnSeekConstraints (str, sgis)) | 562 SgnConst sgis => SOME (sgnSeekConstraints (str, sgis)) |
524 | SgnError => SOME [] | 563 | SgnError => SOME [] |
525 | _ => NONE | 564 | _ => NONE |
526 | 565 |
566 fun declBinds env (d, loc) = | |
567 case d of | |
568 DCon (x, n, k, c) => pushCNamedAs env x n k (SOME c) | |
569 | DDatatype (x, n, xncs) => | |
570 let | |
571 val env = pushCNamedAs env x n (KType, loc) NONE | |
572 in | |
573 foldl (fn ((x', n', NONE), env) => pushENamedAs env x' n' (CNamed n, loc) | |
574 | ((x', n', SOME t), env) => pushENamedAs env x' n' (TFun (t, (CNamed n, loc)), loc)) | |
575 env xncs | |
576 end | |
577 | DDatatypeImp (x, n, m, ms, x') => | |
578 let | |
579 val t = (CModProj (m, ms, x'), loc) | |
580 val env = pushCNamedAs env x n (KType, loc) (SOME t) | |
581 val (_, sgn) = lookupStrNamed env m | |
582 val (str, sgn) = foldl (fn (m, (str, sgn)) => | |
583 case projectStr env {sgn = sgn, str = str, field = m} of | |
584 NONE => raise Fail "ElabEnv.declBinds: Couldn't projectStr" | |
585 | SOME sgn => ((StrProj (str, m), loc), sgn)) | |
586 ((StrVar m, loc), sgn) ms | |
587 val xncs = case projectDatatype env {sgn = sgn, str = str, field = x'} of | |
588 NONE => raise Fail "ElabEnv.declBinds: Couldn't projectDatatype" | |
589 | SOME xncs => xncs | |
590 | |
591 val t = (CNamed n, loc) | |
592 in | |
593 foldl (fn ((x', n', NONE), env) => pushENamedAs env x' n' t | |
594 | ((x', n', SOME t'), env) => pushENamedAs env x' n' (TFun (t', t), loc)) | |
595 env xncs | |
596 end | |
597 | DVal (x, n, t, _) => pushENamedAs env x n t | |
598 | DValRec vis => foldl (fn ((x, n, t, _), env) => pushENamedAs env x n t) env vis | |
599 | DSgn (x, n, sgn) => pushSgnNamedAs env x n sgn | |
600 | DStr (x, n, sgn, _) => pushStrNamedAs env x n sgn | |
601 | DFfiStr (x, n, sgn) => pushStrNamedAs env x n sgn | |
602 | DConstraint _ => env | |
603 | DExport _ => env | |
604 | |
527 end | 605 end |