comparison src/elaborate.sml @ 10:dde5c52e5e5e

Start of elaborating expressions
author Adam Chlipala <adamc@hcoop.net>
date Fri, 28 Mar 2008 13:59:03 -0400
parents 14b533dbe6cc
children e97c6d335869
comparison
equal deleted inserted replaced
9:14b533dbe6cc 10:dde5c52e5e5e
137 val ktype = (L'.KType, dummy) 137 val ktype = (L'.KType, dummy)
138 val kname = (L'.KName, dummy) 138 val kname = (L'.KName, dummy)
139 139
140 val cerror = (L'.CError, dummy) 140 val cerror = (L'.CError, dummy)
141 val kerror = (L'.KError, dummy) 141 val kerror = (L'.KError, dummy)
142 val eerror = (L'.EError, dummy)
142 143
143 local 144 local
144 val count = ref 0 145 val count = ref 0
145 in 146 in
146 147
158 (L'.KUnif (s, ref NONE), dummy) 159 (L'.KUnif (s, ref NONE), dummy)
159 end 160 end
160 161
161 end 162 end
162 163
164 local
165 val count = ref 0
166 in
167
168 fun resetCunif () = count := 0
169
170 fun cunif k =
171 let
172 val n = !count
173 val s = if n <= 26 then
174 str (chr (ord #"A" + n))
175 else
176 "U" ^ Int.toString (n - 26)
177 in
178 count := n + 1;
179 (L'.CUnif (k, s, ref NONE), dummy)
180 end
181
182 end
183
163 fun elabCon env (c, loc) = 184 fun elabCon env (c, loc) =
164 case c of 185 case c of
165 L.CAnnot (c, k) => 186 L.CAnnot (c, k) =>
166 let 187 let
167 val k' = elabKind k 188 val k' = elabKind k
262 283
263 fun kunifsRemain k = 284 fun kunifsRemain k =
264 case k of 285 case k of
265 L'.KUnif (_, ref NONE) => true 286 L'.KUnif (_, ref NONE) => true
266 | _ => false 287 | _ => false
288 fun cunifsRemain c =
289 case c of
290 L'.CUnif (_, _, ref NONE) => true
291 | _ => false
267 292
268 val kunifsInKind = U.Kind.exists kunifsRemain 293 val kunifsInKind = U.Kind.exists kunifsRemain
269 val kunifsInCon = U.Con.exists {kind = kunifsRemain, 294 val kunifsInCon = U.Con.exists {kind = kunifsRemain,
270 con = fn _ => false} 295 con = fn _ => false}
296 val kunifsInExp = U.Exp.exists {kind = kunifsRemain,
297 con = fn _ => false,
298 exp = fn _ => false}
299
300 val cunifsInCon = U.Con.exists {kind = fn _ => false,
301 con = cunifsRemain}
302 val cunifsInExp = U.Exp.exists {kind = fn _ => false,
303 con = cunifsRemain,
304 exp = fn _ => false}
305
306 fun occursCon r =
307 U.Con.exists {kind = fn _ => false,
308 con = fn L'.CUnif (_, _, r') => r = r'
309 | _ => false}
310
311 datatype cunify_error =
312 CKind of L'.kind * L'.kind * kunify_error
313 | COccursCheckFailed of L'.con * L'.con
314 | CIncompatible of L'.con * L'.con
315 | CExplicitness of L'.con * L'.con
316
317 exception CUnify' of cunify_error
318
319 fun cunifyError env err =
320 case err of
321 CKind (k1, k2, kerr) =>
322 (eprefaces "Kind unification failure"
323 [("Kind 1", p_kind k1),
324 ("Kind 2", p_kind k2)];
325 kunifyError kerr)
326 | COccursCheckFailed (c1, c2) =>
327 eprefaces "Constructor occurs check failed"
328 [("Con 1", p_con env c1),
329 ("Con 2", p_con env c2)]
330 | CIncompatible (c1, c2) =>
331 eprefaces "Incompatible constructors"
332 [("Con 1", p_con env c1),
333 ("Con 2", p_con env c2)]
334 | CExplicitness (c1, c2) =>
335 eprefaces "Differing constructor function explicitness"
336 [("Con 1", p_con env c1),
337 ("Con 2", p_con env c2)]
338
339 fun unifyCons' env (c1All as (c1, _)) (c2All as (c2, _)) =
340 let
341 fun err f = raise CUnify' (f (c1All, c2All))
342 in
343 case (c1, c2) of
344 (L'.TFun (d1, r1), L'.TFun (d2, r2)) =>
345 (unifyCons' env d1 d2;
346 unifyCons' env r1 r2)
347 | (L'.TCFun (expl1, x1, d1, r1), L'.TCFun (expl2, _, d2, r2)) =>
348 if expl1 <> expl2 then
349 err CExplicitness
350 else
351 (unifyKinds d1 d2;
352 unifyCons' (E.pushCRel env x1 d1) r1 r2)
353 | (L'.TRecord r1, L'.TRecord r2) => unifyCons' env r1 r2
354
355 | (L'.CRel n1, L'.CRel n2) =>
356 if n1 = n2 then
357 ()
358 else
359 err CIncompatible
360 | (L'.CNamed n1, L'.CNamed n2) =>
361 if n1 = n2 then
362 ()
363 else
364 err CIncompatible
365
366 | (L'.CApp (d1, r1), L'.CApp (d2, r2)) =>
367 (unifyCons' env d1 d2;
368 unifyCons' env r1 r2)
369 | (L'.CAbs (x1, k1, c1), L'.CAbs (_, k2, c2)) =>
370 (unifyKinds k1 k2;
371 unifyCons' (E.pushCRel env x1 k1) c1 c2)
372
373 | (L'.CName n1, L'.CName n2) =>
374 if n1 = n2 then
375 ()
376 else
377 err CIncompatible
378
379 | (L'.CRecord (k1, rs1), L'.CRecord (k2, rs2)) =>
380 (unifyKinds k1 k2;
381 ((ListPair.appEq (fn ((n1, v1), (n2, v2)) =>
382 (unifyCons' env n1 n2;
383 unifyCons' env v1 v2)) (rs1, rs2))
384 handle ListPair.UnequalLengths => err CIncompatible))
385 | (L'.CConcat (d1, r1), L'.CConcat (d2, r2)) =>
386 (unifyCons' env d1 d2;
387 unifyCons' env r1 r2)
388
389
390 | (L'.CError, _) => ()
391 | (_, L'.CError) => ()
392
393 | (L'.CUnif (_, _, ref (SOME c1All)), _) => unifyCons' env c1All c2All
394 | (_, L'.CUnif (_, _, ref (SOME c2All))) => unifyCons' env c1All c2All
395
396 | (L'.CUnif (k1, _, r1), L'.CUnif (k2, _, r2)) =>
397 if r1 = r2 then
398 ()
399 else
400 (unifyKinds k1 k2;
401 r1 := SOME c2All)
402
403 | (L'.CUnif (_, _, r), _) =>
404 if occursCon r c2All then
405 err COccursCheckFailed
406 else
407 r := SOME c2All
408 | (_, L'.CUnif (_, _, r)) =>
409 if occursCon r c1All then
410 err COccursCheckFailed
411 else
412 r := SOME c1All
413
414 | _ => err CIncompatible
415 end
416
417 exception CUnify of L'.con * L'.con * cunify_error
418
419 fun unifyCons env c1 c2 =
420 unifyCons' env c1 c2
421 handle CUnify' err => raise CUnify (c1, c2, err)
422 | KUnify args => raise CUnify (c1, c2, CKind args)
423
424 datatype exp_error =
425 UnboundExp of ErrorMsg.span * string
426 | Unify of L'.exp * L'.con * L'.con * cunify_error
427
428 fun expError env err =
429 case err of
430 UnboundExp (loc, s) =>
431 ErrorMsg.errorAt loc ("Unbound expression variable " ^ s)
432 | Unify (e, c1, c2, uerr) =>
433 (ErrorMsg.errorAt (#2 e) "Unification failure";
434 eprefaces' [("Expression", p_exp env e),
435 ("Have con", p_con env c1),
436 ("Need con", p_con env c2)];
437 cunifyError env uerr)
438
439 fun checkCon env e c1 c2 =
440 unifyCons env c1 c2
441 handle CUnify (c1, c2, err) =>
442 expError env (Unify (e, c1, c2, err))
443
444 fun elabExp env (e, loc) =
445 case e of
446 L.EAnnot (e, t) =>
447 let
448 val (e', et) = elabExp env e
449 val (t', _) = elabCon env t
450 in
451 checkCon env e' et t';
452 (e', t')
453 end
454
455 | L.EVar s =>
456 (case E.lookupE env s of
457 E.NotBound =>
458 (expError env (UnboundExp (loc, s));
459 (eerror, cerror))
460 | E.Rel (n, t) => ((L'.ERel n, loc), t)
461 | E.Named (n, t) => ((L'.ENamed n, loc), t))
462 | L.EApp (e1, e2) =>
463 let
464 val (e1', t1) = elabExp env e1
465 val (e2', t2) = elabExp env e2
466
467 val dom = cunif ktype
468 val ran = cunif ktype
469 val t = (L'.TFun (dom, ran), dummy)
470 in
471 checkCon env e1' t1 t;
472 checkCon env e2' t2 dom;
473 ((L'.EApp (e1', e2'), loc), ran)
474 end
475 | L.EAbs (x, to, e) =>
476 let
477 val t' = case to of
478 NONE => cunif ktype
479 | SOME t =>
480 let
481 val (t', tk) = elabCon env t
482 in
483 checkKind env t' tk ktype;
484 t'
485 end
486 val (e', et) = elabExp (E.pushERel env x t') e
487 in
488 ((L'.EAbs (x, t', e'), loc),
489 (L'.TFun (t', et), loc))
490 end
491 | L.ECApp (e, c) =>
492 let
493 val (e', et) = elabExp env e
494 val (c', ck) = elabCon env c
495 in
496 raise Fail "ECApp"
497 end
498 | L.ECAbs _ => raise Fail "ECAbs"
271 499
272 datatype decl_error = 500 datatype decl_error =
273 KunifsRemainKind of ErrorMsg.span * L'.kind 501 KunifsRemainKind of ErrorMsg.span * L'.kind
274 | KunifsRemainCon of ErrorMsg.span * L'.con 502 | KunifsRemainCon of ErrorMsg.span * L'.con
503 | KunifsRemainExp of ErrorMsg.span * L'.exp
504 | CunifsRemainCon of ErrorMsg.span * L'.con
505 | CunifsRemainExp of ErrorMsg.span * L'.exp
275 506
276 fun declError env err = 507 fun declError env err =
277 case err of 508 case err of
278 KunifsRemainKind (loc, k) => 509 KunifsRemainKind (loc, k) =>
279 (ErrorMsg.errorAt loc "Some kind unification variables are undetermined in kind"; 510 (ErrorMsg.errorAt loc "Some kind unification variables are undetermined in kind";
280 eprefaces' [("Kind", p_kind k)]) 511 eprefaces' [("Kind", p_kind k)])
281 | KunifsRemainCon (loc, c) => 512 | KunifsRemainCon (loc, c) =>
282 (ErrorMsg.errorAt loc "Some kind unification variables are undetermined in constructor"; 513 (ErrorMsg.errorAt loc "Some kind unification variables are undetermined in constructor";
283 eprefaces' [("Constructor", p_con env c)]) 514 eprefaces' [("Constructor", p_con env c)])
515 | KunifsRemainExp (loc, e) =>
516 (ErrorMsg.errorAt loc "Some kind unification variables are undetermined in expression";
517 eprefaces' [("Expression", p_exp env e)])
518 | CunifsRemainCon (loc, c) =>
519 (ErrorMsg.errorAt loc "Some constructor unification variables are undetermined in constructor";
520 eprefaces' [("Constructor", p_con env c)])
521 | CunifsRemainExp (loc, e) =>
522 (ErrorMsg.errorAt loc "Some constructor unification variables are undetermined in expression";
523 eprefaces' [("Expression", p_exp env e)])
284 524
285 fun elabDecl env (d, loc) = 525 fun elabDecl env (d, loc) =
286 (resetKunif (); 526 (resetKunif ();
287 case d of 527 case d of
288 L.DCon (x, ko, c) => 528 L.DCon (x, ko, c) =>
306 else 546 else
307 (); 547 ();
308 548
309 (env', 549 (env',
310 (L'.DCon (x, n, k', c'), loc)) 550 (L'.DCon (x, n, k', c'), loc))
551 end
552 | L.DVal (x, co, e) =>
553 let
554 val (c', ck) = case co of
555 NONE => (cunif ktype, ktype)
556 | SOME c => elabCon env c
557
558 val (e', et) = elabExp env e
559 val (env', n) = E.pushENamed env x c'
560 in
561 checkCon env e' et c';
562
563 if kunifsInCon c' then
564 declError env (KunifsRemainCon (loc, c'))
565 else
566 ();
567
568 if cunifsInCon c' then
569 declError env (CunifsRemainCon (loc, c'))
570 else
571 ();
572
573 if kunifsInExp e' then
574 declError env (KunifsRemainExp (loc, e'))
575 else
576 ();
577
578 if cunifsInExp e' then
579 declError env (CunifsRemainExp (loc, e'))
580 else
581 ();
582
583 (env',
584 (L'.DVal (x, n, c', e'), loc))
311 end) 585 end)
312 586
313 fun elabFile env ds = 587 fun elabFile env ds =
314 ListUtil.mapfoldl (fn (d, env) => elabDecl env d) env ds 588 ListUtil.mapfoldl (fn (d, env) => elabDecl env d) env ds
315 589