home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 7 / Apprentice-Release7.iso / Source Code / C / Applications / Moscow ML 1.42 / src / compiler / Elab.sml < prev    next >
Encoding:
Text File  |  1997-08-18  |  32.8 KB  |  1,085 lines  |  [TEXT/R*ch]

  1.  
  2. open List;
  3. open Fnlib Config Mixture Const Smlexc;
  4. open Globals Location Units Asynt Asyntfn Types;
  5.  
  6. type UEnv = (string * Type) list;   (* Syntax TyVars to TypeVars *)
  7.  
  8. (* --- Warning printing --- *)
  9.  
  10. fun isFunType tau =
  11.   case normType tau of
  12.       ARROWt _ => true
  13.     |        _ => false
  14. ;
  15.  
  16. fun unitResultExpected exp tau =
  17.   if isFunType tau then
  18.     (msgIBlock 0;
  19.      errLocation (xLR exp);
  20.      errPrompt "Warning: function-type result is being discarded.";
  21.      msgEOL(); msgEOL();
  22.      msgEBlock())
  23.   else ()
  24. ;
  25. (* --- Error printing --- *)
  26.  
  27. fun typeClash tau1 tau2 reason =
  28.     let fun isEqVar tau = case normType tau of 
  29.                            VARt var => #tvEqu (!var)
  30.                  | _        => false
  31.     fun isExVar tau = case normType tau of 
  32.                            VARt var => isExplicit var
  33.                  | _        => false
  34.     fun msgTy tau = 
  35.         if reason = UnifyEquality andalso isEqVar tau then 
  36.         (msgString "equality type "; printNextType tau)
  37.         else if reason = UnifyExplicit andalso isExVar tau then 
  38.         (msgString "explicit type "; printNextType tau)
  39.         else 
  40.         (msgString "type"; msgEOL();
  41.          errPrompt "  "; printNextType tau)
  42.      in
  43.     resetTypePrinter();
  44.     collectExplicitVars tau1;
  45.     collectExplicitVars tau2;
  46.     msgString " of "; msgTy tau1; msgEOL();
  47.     errPrompt "cannot have "; msgTy tau2; msgEOL();
  48.     (case reason of
  49.          UnifyCircular => 
  50.          (errPrompt "because of circularity"; msgEOL())
  51.        | UnifyEquality => ()
  52.        | UnifyExplicit => ()
  53.        | UnifyTup      => 
  54.          (errPrompt "because the tuple has the\
  55.                      \ wrong number of components"; 
  56.           msgEOL())
  57.        | UnifyRec lab  => 
  58.          (errPrompt "because record label  "; 
  59.           printLab lab; msgString "  is missing"; msgEOL())
  60.        | UnifyOther    => ());
  61.        resetTypePrinter()
  62.     end;
  63.  
  64. fun typeClashId (ii : IdInfo) tau1 tau2 reason =
  65.   let val {qualid, info} = ii in
  66.     msgIBlock 0;
  67.     errLocation (#idLoc info);
  68.     errPrompt "Type clash: identifier "; msgString (showQualId qualid);
  69.     typeClash tau1 tau2 reason;
  70.     msgEBlock();
  71.     raise Toplevel
  72.   end
  73. ;
  74.  
  75. fun unifyId ii tau1 tau2 =
  76.   unify tau1 tau2
  77.   handle Unify reason => typeClashId ii tau1 tau2 reason
  78. ;
  79.  
  80. fun typeClashPat pat tau1 tau2 reason =
  81. (
  82.   msgIBlock 0;
  83.   errLocation (xLR pat);
  84.   errPrompt "Type clash: pattern";
  85.   typeClash tau1 tau2 reason;
  86.   msgEBlock();
  87.   raise Toplevel
  88. );
  89.  
  90. fun unifyPat pat tau1 tau2 =
  91.   unify tau1 tau2
  92.   handle Unify reason => typeClashPat pat tau1 tau2 reason
  93. ;
  94.  
  95. fun typeClashExp exp tau1 tau2 reason =
  96. (
  97.   msgIBlock 0;
  98.   errLocation (xLR exp);
  99.   errPrompt "Type clash: expression";
  100.   typeClash tau1 tau2 reason;
  101.   msgEBlock();
  102.   raise Toplevel
  103. );
  104.  
  105. fun unifyExp exp tau1 tau2 =
  106.   unify tau1 tau2
  107.   handle Unify reason => typeClashExp exp tau1 tau2 reason
  108. ;
  109.  
  110. fun unifyMatch mrules tau1 tau2 =
  111.   unify tau1 tau2
  112.   handle Unify reason =>
  113.   let val MRule(pats, exp) = hd mrules in
  114.     msgIBlock 0;
  115.     errLocation (xxLR (hd pats) exp);
  116.     errPrompt "Type clash: match rule";
  117.     typeClash tau1 tau2 reason;
  118.     msgEBlock();
  119.     raise Toplevel
  120.   end
  121. ;
  122.  
  123. fun looksLikeInfixId (ii : IdInfo) =
  124.   case ii of
  125.       {qualid={qual="", ...}, info={withOp=false, ...}} => true
  126.     | _ => false
  127. ;
  128.  
  129. fun isPairPat (_, pat') =
  130.   case pat' of
  131.       RECpat(ref (RECrp(fs, NONE))) => isPairRow fs
  132.     | _ => false
  133. ;
  134.  
  135. fun looksLikeInfixExp (_, exp') =
  136.   case exp' of
  137.     VARexp(ref(RESve{qualid={qual="",...}, info={withOp=false,...}}))
  138.       => true
  139.   | VARexp(ref(OVLve({qualid={qual="",...}, info={withOp=false,...}}, _, _)))
  140.       => true
  141.   | _ => false
  142. ;
  143.  
  144. fun isPairExp (_, exp') =
  145.   case exp' of
  146.     RECexp(ref (RECre fs)) => isPairRow fs
  147.   | _ => false
  148. ;
  149.  
  150. fun newUnknownPair() = type_pair (newUnknown()) (newUnknown());
  151.  
  152. infix 6 U;
  153.  
  154. fun list_union [] ys = ys
  155.   | list_union (x :: xs) ys =
  156.       if member x ys then (list_union xs ys) else (x :: list_union xs ys)
  157.  
  158. fun list_subtract xs [] = xs
  159.   | list_subtract xs ys =
  160.       let fun h [] = []
  161.             | h (x :: xs) = if member x ys then (h xs) else (x :: h xs)
  162.       in h xs end
  163. ;
  164.  
  165. fun xs U ys = list_union xs ys;
  166. fun U_map f = foldR_map list_union f [];
  167.  
  168. fun unguardedExp (_, exp') =
  169.   case exp' of
  170.     SCONexp _ => []
  171.   | VARexp _ => []
  172.   | RECexp(ref (RECre fields)) =>
  173.       U_map (fn(_, e) => unguardedExp e) fields
  174.   | RECexp(ref (TUPLEre _)) => fatalError "unguardedExp"
  175.   | VECexp es =>
  176.       U_map unguardedExp es
  177.   | LETexp(dec, exp) =>
  178.       unguardedDec dec U unguardedExp exp
  179.   | PARexp exp => unguardedExp exp
  180.   | APPexp(exp1, exp2) =>
  181.       unguardedExp exp1 U unguardedExp exp2
  182.   | INFIXexp _ =>  fatalError "unguardedExp"
  183.   | TYPEDexp(exp, ty) =>
  184.       unguardedExp exp U unguardedTy ty
  185.   | ANDALSOexp(exp1, exp2) =>
  186.       unguardedExp exp1 U unguardedExp exp2
  187.   | ORELSEexp(exp1, exp2) =>
  188.       unguardedExp exp1 U unguardedExp exp2
  189.   | HANDLEexp(exp, mrules) =>
  190.       unguardedExp exp U U_map unguardedMRule mrules
  191.   | RAISEexp exp =>
  192.       unguardedExp exp
  193.   | IFexp(e0, e1, e2) =>
  194.       unguardedExp e0 U unguardedExp e1 U unguardedExp e2
  195.   | FNexp mrules =>
  196.       U_map unguardedMRule mrules
  197.   | WHILEexp(exp1, exp2) =>
  198.       unguardedExp exp1 U unguardedExp exp2
  199.   | SEQexp(exp1, exp2) =>
  200.       unguardedExp exp1 U unguardedExp exp2
  201.  
  202. and unguardedMRule (MRule(pats, exp)) =
  203.   U_map unguardedPat pats U unguardedExp exp
  204.  
  205. and unguardedPat (_, pat') =
  206.   case pat' of
  207.     SCONpat _ => []
  208.   | VARpat _ => []
  209.   | WILDCARDpat => []
  210.   | NILpat _ => []
  211.   | CONSpat(_, p) => unguardedPat p
  212.   | EXNILpat _ => []
  213.   | EXCONSpat(_,p) => unguardedPat p
  214.   | EXNAMEpat _ => fatalError "unguardedPat"
  215.   | REFpat p => unguardedPat p
  216.   | RECpat(ref (RECrp(fs, _))) =>
  217.       U_map (fn(_, p) => unguardedPat p) fs
  218.   | RECpat(ref (TUPLErp _)) => fatalError "unguardedPat"
  219.   | VECpat ps =>
  220.       U_map unguardedPat ps
  221.   | INFIXpat _ => fatalError "unguardedPat"
  222.   | PARpat pat => unguardedPat pat
  223.   | TYPEDpat(pat, ty) =>
  224.       unguardedPat pat U unguardedTy ty
  225.   | LAYEREDpat(pat1, pat2) =>
  226.       unguardedPat pat1 U unguardedPat pat2
  227.  
  228. and unguardedDec (_, dec') =
  229.   case dec' of
  230.     VALdec _ => []
  231.   | PRIM_VALdec _ => []
  232.   | FUNdec _ => fatalError "unguardedDec"
  233.   | TYPEdec tbs => []
  234.   | PRIM_TYPEdec _ => []
  235.   | DATATYPEdec _ => []
  236.   | ABSTYPEdec(_, _, dec2) =>
  237.       unguardedDec dec2
  238.   | EXCEPTIONdec ebs =>
  239.       U_map unguardedExBind ebs
  240.   | LOCALdec (dec1, dec2) =>
  241.       unguardedDec dec1 U unguardedDec dec2
  242.   | OPENdec _ => []
  243.   | EMPTYdec => []
  244.   | SEQdec (dec1, dec2) =>
  245.       unguardedDec dec1 U unguardedDec dec2
  246.   | FIXITYdec _ => []
  247.  
  248. and unguardedExBind (EXDECexbind(_, SOME ty)) = unguardedTy ty
  249.   | unguardedExBind (EXDECexbind(_, NONE)) = []
  250.   | unguardedExBind (EXEQUALexbind(_,_)) = []
  251.  
  252. and unguardedValBind (ValBind(pat, exp)) =
  253.   unguardedPat pat U unguardedExp exp
  254.  
  255. and unguardedValDec (pvbs, rvbs) =
  256.   (U_map unguardedValBind pvbs) U
  257.   (U_map unguardedValBind rvbs)
  258.  
  259. and unguardedTy (_, ty') =
  260.   case ty' of
  261.     TYVARty ii => [#id(#qualid ii)]
  262.   | RECty fs =>
  263.       U_map (fn(_, ty) => unguardedTy ty) fs
  264.   | CONty(tys, _) =>
  265.       U_map unguardedTy tys
  266.   | FNty(ty1, ty2) =>
  267.       unguardedTy ty1 U unguardedTy ty2
  268. ;
  269.  
  270. fun scopedTyVars UE pars unguardedTyVars =
  271.   list_subtract (pars U unguardedTyVars) (map fst UE)
  272. ;
  273.  
  274. fun incrUE tyvars =
  275.   map (fn tv => (tv, TypeOfTypeVar(newExplicitTypeVar tv))) tyvars
  276. ;
  277.  
  278. (* Modified to allow more forms of non-expansive expressions: *)
  279.  
  280. fun isExpansiveExp (_, exp') =
  281.   case exp' of
  282.     SCONexp _       => false
  283.   | VARexp _        => false
  284.   | PARexp exp      => isExpansiveExp exp
  285.   | TYPEDexp(exp,_) => isExpansiveExp exp
  286.   | FNexp _         => false
  287.   | RECexp (ref (RECre exprow))    => 
  288.     exists (fn (_, e) => isExpansiveExp e) exprow
  289.   | RECexp (ref (TUPLEre explist)) =>
  290.     exists isExpansiveExp explist
  291.   | APPexp((_, VARexp varexpinfo), exp) =>
  292.     isExpansiveExp exp orelse
  293.     let val {info = {idKind, ...}, ...} =
  294.             case !varexpinfo of
  295.             RESve ii         => ii
  296.           | OVLve (ii, _, _) => ii
  297.     in case !idKind of
  298.         {info = CONik _, qualid = {id, qual}} => id = "ref"
  299.       | {info = EXCONik _, ...}               => false
  300.       | _                                     => true
  301.     end
  302.   | _ => true
  303. ;
  304.  
  305. fun expansiveIdsInValBind (ValBind(pat, exp)) acc =
  306.   if (isExpansiveExp exp) then (domPatAcc pat acc) else acc
  307. ;
  308.  
  309. fun closeValBindVE onTop loc (pvbs: ValBind list) VE =
  310.   let val exIds = foldR expansiveIdsInValBind [] pvbs in
  311.     mapEnv (fn id => fn t => generalization onTop loc (member id exIds) t) VE
  312.   end
  313. ;
  314.  
  315. fun lookup_TE (TE : TyEnv) (tycon : IdInfo) =
  316.   let val {qualid, info} = tycon
  317.       val {idLoc, ...} = info
  318.   in
  319.     findInfo tyEnvOfSig TE idLoc qualid
  320.     handle Subscript =>
  321.       errorMsg idLoc ("Unbound type identifier: " ^ showQualId qualid)
  322.   end;
  323.  
  324. fun lookup_VE (VE : VarEnv) (ii : IdInfo) =
  325.   let val {qualid, info} = ii
  326.       val {idLoc, ...} = info
  327.   in
  328.     specialization(findInfo varEnvOfSig VE idLoc qualid)
  329.     handle Subscript =>
  330.       fatalError "lookup_VE"
  331.   end;
  332.  
  333. fun lookup_UE (UE : UEnv) loc (ii : IdInfo) =
  334.   let val id = #id(#qualid ii) in
  335.     lookup id UE
  336.     handle Subscript => errorMsg loc ("Unbound type variable: " ^ id)
  337.   end;
  338.  
  339. fun applyTyCon TE (tycon : IdInfo) ts =
  340.   let val tyname = lookup_TE TE tycon
  341.       val arity = List.length ts
  342.   in
  343.     if #tnArity(!(#info tyname)) <> arity then
  344.       errorMsg (#idLoc (#info tycon))
  345.         ("Arity mismatch: "^showQualId (#qualid tycon))
  346.     else ();
  347.     case #tnStr(!(#info tyname)) of
  348.         NILts =>
  349.           type_con ts tyname
  350.       | TYPEts(pars, body) =>
  351.           type_subst (zip2 pars ts) body
  352.       | DATATYPEts _ =>
  353.           type_con ts tyname
  354.       | REAts _ => fatalError "applyTyCon"
  355.   end;
  356.  
  357. fun elabTy (UE : UEnv) (TE : TyEnv) (loc, ty') =
  358.   case ty' of
  359.     TYVARty ii =>
  360.       lookup_UE UE loc ii
  361.   | RECty fs =>
  362.       type_rigid_record (map_fields (elabTy UE TE) fs)
  363.   | CONty(ty_list, tycon) =>
  364.       applyTyCon TE tycon (map (elabTy UE TE) ty_list)
  365.   | FNty(ty,ty') =>
  366.       type_arrow (elabTy UE TE ty) (elabTy UE TE ty')
  367. ;
  368.  
  369. fun elabSCon (INTscon i,    _     ) = type_int
  370.   | elabSCon (CHARscon c,   _     ) = type_char
  371.   | elabSCon (WORDscon c, tyOptRef) =
  372.     let val ty = VARt (newTypeVar false  false  true)
  373.                            (* nonequ nonimp overloaded *)
  374.     in tyOptRef := SOME ty; ty end
  375.   | elabSCon (REALscon r,   _     ) = type_real
  376.   | elabSCon (STRINGscon s, _     ) = type_string
  377. ;
  378.  
  379. fun elabPat (UE : UEnv) (VE : VarEnv) (TE : TyEnv)
  380.                 (pat as (_, pat')) (pat_t : Type) (PE : VarEnv) =
  381.   case pat' of
  382.     SCONpat scon =>
  383.       (unifyPat pat (elabSCon scon) pat_t; PE)
  384.   | VARpat ii =>
  385.       bindInEnv PE (#id (#qualid ii)) (trivial_scheme pat_t)
  386.   | WILDCARDpat => PE
  387.   | NILpat ii => (unifyPat pat (lookup_VE VE ii) pat_t; PE)
  388.   | CONSpat(ii, p) =>
  389.       let val id_t = lookup_VE VE ii
  390.           val p_t = newUnknown()
  391.           val res_t = newUnknown()
  392.       in
  393.         unifyId ii id_t (type_arrow p_t res_t);
  394.         if (looksLikeInfixId ii) andalso (isPairPat p) then
  395.           (unify p_t (newUnknownPair())
  396.            handle Unify reason =>
  397.              typeClashId ii id_t (type_arrow (newUnknownPair()) res_t) reason)
  398.         else ();
  399.         unifyPat pat res_t pat_t;
  400.         elabPat UE VE TE p p_t PE
  401.       end
  402.   | EXNILpat ii =>
  403.       let val id_t = lookup_VE VE ii in
  404.         unifyId ii id_t type_exn;
  405.         unifyPat pat type_exn pat_t;
  406.         PE
  407.       end
  408.   | EXCONSpat(ii, p) =>
  409.       let val id_t = lookup_VE VE ii
  410.           val p_t = newUnknown()
  411.       in
  412.         unifyId ii id_t (type_arrow p_t type_exn);
  413.         if looksLikeInfixId ii andalso isPairPat p then
  414.           (unify p_t (newUnknownPair())
  415.            handle Unify reason =>
  416.              typeClashId ii id_t (type_arrow (newUnknownPair()) type_exn) reason)
  417.         else ();
  418.         unifyPat pat type_exn pat_t;
  419.         elabPat UE VE TE p p_t PE
  420.       end
  421.   | EXNAMEpat _ => fatalError "elabPat"
  422.   | REFpat p =>
  423.       let val p_t = newUnknown() in
  424.         unifyPat pat (type_ref p_t) pat_t;
  425.         elabPat UE VE TE p p_t PE
  426.       end
  427.   | RECpat(ref (RECrp(fs, dots))) =>
  428.       let val ls = map fst fs
  429.           val ps = map snd fs
  430.           val ts = map (fn _ => newUnknown()) ps
  431.           val fs_t = zip2 ls ts
  432.           fun reportClash isRigid reason =
  433.             let val ts' = map (fn _ => newUnknown()) ps
  434.                 val fs_t' = zip2 ls ts'
  435.             in
  436.               if isRigid then
  437.                 typeClashPat pat (type_rigid_record fs_t') pat_t reason
  438.               else
  439.                 typeClashPat pat
  440.                   (type_flexible_record fs_t' (fresh3DotType())) pat_t reason
  441.             end
  442.       in
  443.         (case dots of
  444.             NONE =>     (unify (type_rigid_record fs_t) pat_t
  445.                          handle Unify reason => reportClash true reason)
  446.           | SOME rho => (unify (type_flexible_record fs_t rho) pat_t
  447.                          handle Unify reason => reportClash false reason));
  448.         foldL_zip (elabPat UE VE TE) PE ps ts
  449.       end
  450.   | RECpat(ref (TUPLErp _)) => fatalError "elabPat"
  451.   | VECpat ps =>
  452.       let val p_t = newUnknown() in
  453.         unifyPat pat (type_vector p_t) pat_t;
  454.         foldL (fn p => fn PE => elabPat UE VE TE p p_t PE) PE ps
  455.       end
  456.   | PARpat p =>
  457.       elabPat UE VE TE p pat_t PE
  458.   | INFIXpat _ => fatalError "elabPat"
  459.   | TYPEDpat(p,ty) =>
  460.       let val ty_t = elabTy UE TE ty
  461.           val PE' = elabPat UE VE TE p pat_t PE
  462.       in
  463.         unifyPat p pat_t ty_t;
  464.         PE'
  465.       end
  466.   | LAYEREDpat(p1,p2) =>
  467.       elabPat UE VE TE p2 pat_t
  468.         (elabPat UE VE TE p1 pat_t PE)
  469. ;
  470.  
  471. fun freshTyName tycon arity =
  472.   { qualid=mkGlobalName tycon,
  473.     info=ref { tnStamp=newTypeStamp(), tnArity=arity,
  474.                tnEqu=TRUEequ, tnStr=NILts }}
  475. ;
  476.  
  477. fun makeTyName tyvar_list tycon =
  478.   let val arity = List.length tyvar_list
  479.   in freshTyName tycon arity end
  480. ;
  481.  
  482. fun initialDatBindTE (dbs : DatBind list)=
  483.   foldL
  484.     (fn (tyvar_list, tycon, _) => fn env =>
  485.        let val id = #id (#qualid tycon)
  486.        in bindInEnv env id (makeTyName tyvar_list id) end)
  487.     NILenv dbs
  488. ;
  489.  
  490. fun absTE (TE : TyEnv) =
  491.   traverseEnv
  492.     (fn id => fn tyname =>
  493.        let val {info, ...} = tyname in
  494.          case #tnStr(!info) of
  495.              DATATYPEts dt =>
  496.                (setTnEqu info FALSEequ;
  497.                 setConstructors (!currentSig) dt [])
  498.            | _ => fatalError "absTE"
  499.        end)
  500.     TE
  501. ;
  502.  
  503. fun elabTypBind (TE : TyEnv) ((tyvars, tycon, ty) : TypBind) =
  504.   let val id = #id(#qualid tycon)
  505.       val pars = map (fn tyvar => #id(#qualid tyvar)) tyvars
  506.       val vs = map (fn tv => newExplicitTypeVar tv) pars
  507.       val us = map TypeOfTypeVar vs
  508.       val UE = zip2 pars us
  509.       val t = elabTy UE TE ty
  510.       val tyname = makeTyName tyvars id
  511.   in
  512.     setTnStr (#info tyname) (TYPEts(vs, t));
  513.     (id, tyname)
  514.   end
  515. ;
  516.  
  517. fun elabTypBindList (TE : TyEnv) (tbs : TypBind list) =
  518.   foldL_map (fn (id, tyname) => fn env => bindInEnv env id tyname)
  519.             (elabTypBind TE) NILenv tbs
  520. ;
  521.  
  522. fun elabTypBindList_opt (TE : TyEnv) = fn
  523.     SOME tbs => elabTypBindList TE tbs
  524.   | NONE => NILenv
  525. ;
  526.  
  527. fun elabPrimTypBind equ ((tyvars, tycon) : TypDesc) =
  528.   let val id = #id(#qualid tycon)
  529.       val tyname = makeTyName tyvars id
  530.   in
  531.     setTnEqu (#info tyname) equ;
  532.     (id, tyname)
  533.   end;
  534.  
  535. fun elabPrimTypBindList equ (tbs : TypDesc list) =
  536.   foldL_map (fn (id, tyname) => fn env => bindInEnv env id tyname)
  537.             (elabPrimTypBind equ) NILenv tbs
  538. ;
  539.  
  540. fun closeEE EE =
  541.   mapEnv (fn excon => fn t => generalization false nilLocation true t) EE
  542. ;
  543.  
  544. fun openVE VE =
  545.   mapEnv (fn id => fn sch => TypeOfScheme sch) VE
  546. ;
  547.  
  548. fun isRecTy (loc, ty') =
  549.   case ty' of
  550.     RECty [] => false
  551.   | RECty _ => true
  552.   | _ => false
  553. ;
  554.  
  555. fun arityOfRecTy (loc, ty') =
  556.   case ty' of
  557.       RECty fs => List.length fs
  558.     | _ => fatalError "arityOfRecTy"
  559. ;
  560.  
  561. fun elabConBind (UE : UEnv) (TE : TyEnv) res_t = fn
  562.     ConBind(ii, SOME ty) =>
  563.       let val ci = getConInfo ii
  564.           val arg_t = (elabTy UE TE ty)
  565.       in
  566.         setConType ci
  567.           (generalization false nilLocation false (type_arrow arg_t res_t));
  568.         if #conSpan(!ci) <> 1 andalso isRecTy ty then
  569.           (setConArity ci (arityOfRecTy ty);
  570.            setConIsGreedy ci true)
  571.         else ();
  572.         { qualid= #qualid(!(#idKind(#info ii))), info=ci }
  573.       end
  574.   | ConBind(ii, NONE) =>
  575.       let val ci = getConInfo ii in
  576.         setConType ci (generalization false nilLocation false res_t);
  577.         { qualid= #qualid(!(#idKind(#info ii))), info=ci }
  578.       end
  579. ;
  580.  
  581. fun setEquality (TE :TyEnv) =
  582.   traverseEnv
  583.     (fn _ => fn tyname =>
  584.        let val {info, ...} = tyname in
  585.          case #tnStr(!info) of
  586.              NILts => fatalError "setEquality"
  587.            | TYPEts(_, t) =>
  588.                setTnEqu info
  589.                  (if typeViolatesEquality t then FALSEequ else TRUEequ)
  590.            | DATATYPEts _ => fatalError "setEquality"
  591.            | REAts _ => fatalError "setEquality"
  592.        end)
  593.     TE
  594. ;
  595.  
  596. val equAttrReset = ref false;
  597.  
  598. fun maximizeEquality (TE : TyEnv) =
  599. (
  600.   equAttrReset := true;
  601.   while !equAttrReset do
  602.     (equAttrReset := false;
  603.      traverseEnv
  604.        (fn _ => fn tyname =>
  605.          let val {info, ...} = tyname in
  606.            case #tnStr(!info) of
  607.                NILts => fatalError "maximizeEquality"
  608.              | TYPEts _ => fatalError "maximizeEquality"
  609.              | DATATYPEts dt =>
  610.                  (let val CE = findConstructors (!currentSig) dt in
  611.                     case #tnEqu(!info) of
  612.                         FALSEequ => ()
  613.                       | TRUEequ  =>
  614.                           if exists (fn ci => schemeViolatesEquality
  615.                                        (#conType (!(#info ci))))
  616.                                     CE
  617.                           then
  618.                             (setTnEqu info FALSEequ; equAttrReset := true)
  619.                           else ()
  620.                       | REFequ  => fatalError "maximizeEquality"
  621.                   end)
  622.              | REAts _ => fatalError "maximizeEquality"
  623.          end)
  624.        TE)
  625. );
  626.  
  627. fun setTags (cbs : ConBind list) =
  628.   let prim_val string_of_int : int -> string = 1 "sml_string_of_int";
  629.       val span = List.length cbs
  630.       fun loop n = fn
  631.           [] => ()
  632.         | (ConBind(ii, _)) :: rest =>
  633.             let val {info={idLoc, ...}, ...} = ii
  634.                 val () =
  635.                   if n > maxBlockTag then
  636.                     errorMsg idLoc ("Implementation restriction:\n \
  637.                                     \A datatype cannot declare more than "^
  638.                     string_of_int (maxBlockTag + 1) ^
  639.                     " constructors.")
  640.                   else ();
  641.                 val ci = getConInfo ii
  642.             in
  643.               setConTag ci n;
  644.               setConSpan ci span;
  645.               loop (n+1) rest
  646.             end
  647.   in loop 0 cbs end
  648. ;
  649.  
  650. fun VEofCE (CE : ConEnv) =
  651.   foldR (fn cs => fn env =>
  652.            let val {qualid, info} = cs
  653.            in bindInEnv env (#id qualid) (#conType (!info)) end)
  654.         NILenv CE
  655. ;
  656.  
  657. fun cons x xs = x :: xs;
  658.  
  659. fun elabDatBind (TE:TyEnv) ((tyvars, tycon, conbind_list) : DatBind) =
  660.   let val pars = map (fn ii => #id(#qualid ii)) tyvars
  661.       val () = setTags conbind_list
  662.       val () = incrBindingLevel()
  663.       val vs = map (fn tv => newExplicitTypeVar tv) pars
  664.       val () = decrBindingLevel()
  665.       val us = map TypeOfTypeVar vs
  666.       val UE = zip2 pars us
  667.       val tyname = lookup_TE TE tycon
  668.       val t = type_con us tyname
  669.       val CE = foldL_map cons (elabConBind UE TE t) [] conbind_list
  670.   in
  671.     setTnStr (#info tyname) (DATATYPEts (registerConstructors(rev CE)));
  672.     VEofCE CE
  673.   end
  674. ;
  675.  
  676. fun elabDatBindList (TE : TyEnv) (dbs : DatBind list) =
  677.   foldL_map (fn env' => fn env => plusEnv env env')
  678.             (elabDatBind TE) NILenv dbs
  679. ;
  680.  
  681. fun elabExBind (UE : UEnv) (VE : VarEnv) (TE : TyEnv) = fn
  682.     EXDECexbind(ii, SOME ty) =>
  683.       let val ei = getExConInfo ii
  684.           val arg_t = (elabTy UE TE ty)
  685.       in
  686.         if typeIsImperative arg_t then ()
  687.         else errorMsg (xLR ty) "Non-imperative exception type";
  688.         if isExConStatic ei andalso isRecTy ty then
  689.           (setExConArity ei (arityOfRecTy ty);
  690.            setExConIsGreedy ei true)
  691.         else ();
  692.         (#id(#qualid ii), type_arrow arg_t type_exn)
  693.       end
  694.   | EXDECexbind(ii, NONE) =>
  695.       (#id(#qualid ii), type_exn)
  696.   | EXEQUALexbind(ii, ii') =>
  697.       (#id(#qualid ii), lookup_VE VE ii')
  698. ;
  699.  
  700. fun elabExBindList (UE : UEnv) (VE : VarEnv) (TE : TyEnv) ebs =
  701.   closeEE (foldL_map (fn (id, tau) => fn env => bindInEnv env id tau)
  702.                      (elabExBind UE VE TE) NILenv ebs)
  703. ;
  704.  
  705. (* OVL1TXXo is not a true overloaded type, *)
  706. (* because it needn't be resolved to `int', `real', or `string'. *)
  707. (* This is only a hack to catch the type inferred by the *)
  708. (* type-checker... Thus the attribute `overloaded' mustn't be *)
  709. (* turned on in the type variable. *)
  710. (* The same is true of OVL1TPUo (installPP) and OVL2EEBo (=, <>). *)
  711.  
  712. fun elabOvlExp t ovltype =
  713.   case ovltype of
  714.       REGULARo =>
  715.         fatalError "elabOvlExp"
  716.     | OVL1NNo =>
  717.         (setCurrentBindingLevel true t;
  718.          type_arrow t t)
  719.     | OVL1NSo =>
  720.         (setCurrentBindingLevel true t;
  721.          type_arrow t type_string)
  722.     | OVL2NNBo =>
  723.         (setCurrentBindingLevel true t;
  724.          type_arrow (type_pair t t) type_bool)
  725.     | OVL2NNNo =>
  726.         (setCurrentBindingLevel true t;
  727.          type_arrow (type_pair t t) t)
  728.     | OVL1TXXo =>
  729.         (setCurrentBindingLevel false t;
  730.          type_arrow t t)
  731.     | OVL1TPUo =>
  732.         (setCurrentBindingLevel false t;
  733.          type_arrow
  734.            (type_arrow type_ppstream (type_arrow t type_unit))
  735.            type_unit)
  736.     | OVL2EEBo =>
  737.         (setCurrentBindingLevel false t;
  738.      makeEquality t;
  739.          type_arrow (type_pair t t) type_bool)
  740. ;
  741.  
  742. fun elabExp (UE : UEnv) (VE : VarEnv) (TE : TyEnv)
  743.                  (exp as (_, exp')) exp_t =
  744.   case exp' of
  745.     SCONexp scon =>
  746.       unifyExp exp (elabSCon scon) exp_t
  747.   | VARexp(ref (RESve ii)) =>
  748.       unifyExp exp (lookup_VE VE ii) exp_t
  749.   | VARexp(ref (OVLve(_, ovltype, tau))) =>
  750.       unifyExp exp (elabOvlExp tau ovltype) exp_t
  751.   | FNexp mrules =>
  752.       elabMatch UE VE TE mrules exp_t
  753.   | APPexp(func, arg) =>
  754.       let val func_t = newUnknown()
  755.           val () = elabExp UE VE TE func func_t
  756.           val arg_t = newUnknown()
  757.           val res_t = newUnknown()
  758.       in
  759.         unifyExp func func_t (type_arrow arg_t res_t);
  760.         if looksLikeInfixExp func andalso isPairExp arg then
  761.           (unify arg_t (newUnknownPair())
  762.            handle Unify reason =>
  763.              typeClashExp func func_t (type_arrow (newUnknownPair()) res_t) 
  764.                       reason)
  765.         else ();
  766.         unifyExp exp res_t exp_t;
  767.         elabExp UE VE TE arg arg_t
  768.       end
  769.   | LETexp(dec, body) =>
  770.       let val (VE', TE') = elabDec UE VE TE false dec
  771.       in elabExp UE (plusEnv VE VE') (plusEnv TE TE') body exp_t end
  772.   | RECexp(ref (RECre fs)) =>
  773.       let val ls = map fst fs
  774.           val es = map snd fs
  775.           val ts = map (fn _ => newUnknown()) es
  776.           val fs_t = zip2 ls ts
  777.       in
  778.         (unify (type_rigid_record fs_t) exp_t
  779.          handle Unify reason =>
  780.            let val ts' = map (fn _ => newUnknown()) es
  781.                val fs_t' = zip2 ls ts'
  782.            in typeClashExp exp (type_rigid_record fs_t') exp_t reason end);
  783.         app2 (elabExp UE VE TE) es ts
  784.       end
  785.   | RECexp(ref (TUPLEre _)) => fatalError "elabExp"
  786.   | VECexp es =>
  787.       let val e_t = newUnknown() in
  788.         app (fn e => elabExp UE VE TE e e_t) es;
  789.         unifyExp exp (type_vector e_t) exp_t
  790.       end
  791.   | PARexp e =>
  792.       elabExp UE VE TE e exp_t
  793.   | INFIXexp _ => fatalError "elabExp: unresolved infix exp"
  794.   | TYPEDexp(e,ty) =>
  795.       let val ty_t = elabTy UE TE ty in
  796.         elabExp UE VE TE e exp_t;
  797.         unifyExp e exp_t ty_t
  798.       end
  799.   | ANDALSOexp(e1, e2) =>
  800.       (elabExp UE VE TE e1 type_bool;
  801.        elabExp UE VE TE e2 type_bool;
  802.        unifyExp exp type_bool exp_t)
  803.   | ORELSEexp(e1, e2) =>
  804.       (elabExp UE VE TE e1 type_bool;
  805.        elabExp UE VE TE e2 type_bool;
  806.        unifyExp exp type_bool exp_t)
  807.   | HANDLEexp(e, mrules) =>
  808.       (elabExp UE VE TE e exp_t;
  809.        elabMatch UE VE TE mrules (type_arrow type_exn exp_t))
  810.   | RAISEexp e =>
  811.       elabExp UE VE TE e type_exn
  812.   | IFexp(e0, e1, e2) =>
  813.       (elabExp UE VE TE e0 type_bool;
  814.        elabExp UE VE TE e1 exp_t;
  815.        elabExp UE VE TE e2 exp_t)
  816.   | WHILEexp(e1, e2) =>
  817.       let val e2_t = newUnknown() in
  818.         elabExp UE VE TE e1 type_bool;
  819.         elabExp UE VE TE e2 e2_t;
  820.         unitResultExpected e2 e2_t;
  821.         unifyExp exp type_unit exp_t
  822.       end
  823.   | SEQexp(e1, e2) =>
  824.       let val e1_t = newUnknown() in
  825.         elabExp UE VE TE e1 e1_t;
  826.         unitResultExpected e1 e1_t;
  827.         elabExp UE VE TE e2 exp_t
  828.       end
  829.  
  830. and elabExpSeq UE VE TE es ts =
  831.   let fun loop [] [] = ()
  832.         | loop (e :: es) (t :: ts) =
  833.             (elabExp UE VE TE e t; loop es ts)
  834.         | loop _ _ = fatalError "elabExpSeq"
  835.   in loop es ts end
  836.  
  837. and elabMatch UE VE TE mrules match_t =
  838.   let val MRule(pats1,_) = hd mrules
  839.       val arg_ts = map (fn pat => newUnknown()) pats1
  840.       val res_t = newUnknown()
  841.   in
  842.     unifyMatch mrules (foldR type_arrow res_t arg_ts) match_t;
  843.     app (fn MRule(pats, exp) => elabMRule UE VE TE exp res_t pats arg_ts)
  844.             mrules
  845.   end
  846.  
  847. and elabMRule UE VE TE exp res_t pats arg_ts =
  848.   case (pats, arg_ts) of
  849.       ([], []) => elabExp UE VE TE exp res_t
  850.     | (pat :: pats', arg_t :: arg_ts') =>
  851.         let val VE' = elabPat UE VE TE pat arg_t VE
  852.         in elabMRule UE VE' TE exp res_t pats' arg_ts' end
  853.     | (_, _) => fatalError "elabMRule"
  854.  
  855. and elabDec (UE : UEnv) (VE : VarEnv) (TE : TyEnv)
  856.             (onTop : bool) (loc, dec') =
  857.   case dec' of
  858.     VALdec (tvs, (pvbs, rvbs)) =>
  859.       let val pars = map (fn ii => #id(#qualid ii)) tvs
  860.       val tyvars = scopedTyVars UE pars (unguardedValDec (pvbs, rvbs))
  861.           val ()   = incrBindingLevel()
  862.           val UE'  = incrUE tyvars @ UE
  863.           val VE'  = elabValBind UE' VE TE pvbs
  864.           val VE'' = elabRecValBind UE' VE TE rvbs
  865.       in
  866.         decrBindingLevel();
  867.         (closeValBindVE onTop loc pvbs (plusEnv VE' VE''), NILenv)
  868.       end
  869.   | PRIM_VALdec pbs =>
  870.       let val VE' = foldL_map (fn(id, sc) => fn acc => bindInEnv acc id sc)
  871.                               (elabPrimValBind TE)
  872.                               NILenv pbs
  873.       in (VE', NILenv) end
  874.   | FUNdec _ => fatalError "elabDec"
  875.   | TYPEdec tbs =>
  876.       let val tbsTE = elabTypBindList TE tbs in
  877.         setEquality tbsTE;
  878.         (NILenv, tbsTE)
  879.       end
  880.   | PRIM_TYPEdec(equ, tbs) =>
  881.       (NILenv, elabPrimTypBindList equ tbs)
  882.   | DATATYPEdec(dbs, tbs_opt) =>
  883.       let val dbsTE = initialDatBindTE dbs
  884.           val tbsTE = elabTypBindList_opt (plusEnv TE dbsTE) tbs_opt
  885.           (* Here dbsTE will get destructively updated too. *)
  886.           val CE = elabDatBindList (plusEnv (plusEnv TE dbsTE) tbsTE) dbs
  887.       in
  888.         maximizeEquality dbsTE;
  889.         setEquality tbsTE;
  890.         (CE, plusEnv dbsTE tbsTE)
  891.       end
  892.   | ABSTYPEdec(dbs, tbs_opt, dec2) =>
  893.       let val dbsTE = initialDatBindTE dbs
  894.           val tbsTE = elabTypBindList_opt (plusEnv TE dbsTE) tbs_opt
  895.           (* Here dbsTE will get destructively updated too. *)
  896.           val CE = elabDatBindList (plusEnv (plusEnv TE dbsTE) tbsTE) dbs
  897.           val () = maximizeEquality dbsTE
  898.           val () = setEquality tbsTE
  899.           val (VE2, TE2) =
  900.             elabDec UE (plusEnv VE CE)
  901.                     (plusEnv (plusEnv TE dbsTE) tbsTE) onTop dec2
  902.       in
  903.         (* Now let's destructively update the equality attributes *)
  904.         (* and the lists of constructors! *)
  905.         (* Here VE2 and TE2 will be implicitly influenced too. *)
  906.         absTE dbsTE;
  907.         setEquality tbsTE;
  908.         (VE2, plusEnv(plusEnv dbsTE tbsTE) TE2)
  909.       end
  910.   | EXCEPTIONdec ebs =>
  911.       (elabExBindList UE VE TE ebs, NILenv)
  912.   | LOCALdec (dec1, dec2) =>
  913.       let val (VE', TE')  = elabDec UE VE TE false dec1
  914.           val (VE'',TE'') =
  915.             elabDec UE (plusEnv VE VE') (plusEnv TE TE') onTop dec2
  916.       in (VE'', TE'') end
  917.   | OPENdec ids =>
  918.       let val VE' =
  919.             foldL (fn id => fn acc =>
  920.                      bindTopInEnv acc (#uVarEnv (findSig loc id)))
  921.                   NILenv ids
  922.               val TE' =
  923.             foldL (fn id => fn acc =>
  924.                      bindTopInEnv acc (#uTyEnv (findSig loc id)))
  925.                   NILenv ids
  926.       in (VE', TE') end
  927.   | EMPTYdec => (NILenv, NILenv)
  928.   | SEQdec (dec1, dec2) =>
  929.       let val (VE', TE')  =
  930.             elabDec UE VE TE onTop dec1
  931.           val (VE'',TE'') =
  932.             elabDec UE (plusEnv VE VE') (plusEnv TE TE') onTop dec2
  933.       in (plusEnv VE' VE'', plusEnv TE' TE'') end
  934.   | FIXITYdec _ => (NILenv, NILenv)
  935.  
  936. and elabValBind (UE : UEnv) (VE : VarEnv) (TE : TyEnv)
  937.                 (vbs : ValBind list) =
  938.   let val ps = map (fn ValBind(p,e) => p) vbs
  939.       val es = map (fn ValBind(p,e) => e) vbs
  940.       val pts = map (fn _ => newUnknown()) ps
  941.       val VE' = foldL_zip (elabPat UE VE TE) NILenv ps pts
  942.       val VE'' = mkHashEnv (length ps) VE'
  943.   in
  944.     app2 (elabExp UE VE TE) es pts;
  945.     openVE VE''
  946.   end
  947.  
  948. and elabRecValBind (UE : UEnv) (VE : VarEnv) (TE : TyEnv)
  949.                    (vbs : ValBind list) =
  950.   let val ps = map (fn ValBind(p,e) => p) vbs
  951.       val es = map (fn ValBind(p,e) => e) vbs
  952.       val pts = map (fn _ => newUnknown()) ps
  953.       val VE' = foldL_zip (elabPat UE VE TE) NILenv ps pts
  954.       val VE'' = mkHashEnv (length ps) VE'
  955.       val rec_VE = plusEnv VE VE''
  956.   in
  957.     app2 (elabExp UE rec_VE TE) es pts;
  958.     openVE VE''
  959.   end
  960.  
  961. and elabPrimValBind TE (ii, ty, _, _) =
  962.   let val tyvars = varsOfTy ty
  963.       val pars = map (fn tyvar => #id(#qualid tyvar)) tyvars
  964.       val vs = map (fn tv => newExplicitTypeVar tv) pars
  965.       val us = map TypeOfTypeVar vs
  966.       val UE = zip2 pars us
  967.       val ty_t = elabTy UE TE ty
  968.   in (#id(#qualid ii), mkScheme vs ty_t) end
  969. ;
  970.  
  971. fun elabToplevelDec (dec : Dec) =
  972. (
  973.   if unguardedDec dec <> [] then
  974.     errorMsg (xLR dec) "Unguarded type variables at the top-level"
  975.   else ();
  976.   resetBindingLevel();
  977.   elabDec [] (mkGlobalVE()) (mkGlobalTE()) true dec
  978. );
  979.  
  980.  
  981. (* --- Signatures --- *)
  982.  
  983. fun unguardedExDesc (_, SOME ty) = unguardedTy ty
  984.   | unguardedExDesc (_, NONE) = []
  985. ;
  986.  
  987. fun elabValDesc (TE : TyEnv) ((ii, ty) : ValDesc) =
  988.   let val tyvars = varsOfTy ty
  989.       val pars = map (fn tyvar => #id(#qualid tyvar)) tyvars
  990.       val vs = map (fn tv => newExplicitTypeVar tv) pars
  991.       val us = map TypeOfTypeVar vs
  992.       val UE = zip2 pars us
  993.       val ty_t = elabTy UE TE ty
  994.   in (#id(#qualid ii), mkScheme vs ty_t) end
  995. ;
  996.  
  997. fun elabExDesc (UE : UEnv) (VE : VarEnv) (TE : TyEnv)
  998.                ((ii, ty_opt) : ExDesc) =
  999.   let val {qualid={id, ...}, ...} = ii
  1000.   in
  1001.     case ty_opt of
  1002.       SOME ty =>
  1003.         let val ei = getExConInfo ii
  1004.             val arg_t = (elabTy UE TE ty)
  1005.         in
  1006.           if typeIsImperative arg_t then ()
  1007.           else errorMsg (xLR ty) "Non-imperative exception type";
  1008.           if isExConStatic ei andalso isRecTy ty then
  1009.             (setExConArity ei (arityOfRecTy ty);
  1010.              setExConIsGreedy ei true)
  1011.           else ();
  1012.           (id, type_arrow arg_t type_exn)
  1013.         end
  1014.     | NONE =>
  1015.         (id, type_exn)
  1016.   end;
  1017.  
  1018. fun elabExDescList (UE : UEnv) (VE : VarEnv) (TE : TyEnv) eds =
  1019.   closeEE (foldL_map (fn (id, tau) => fn env => bindInEnv env id tau)
  1020.                      (elabExDesc UE VE TE) NILenv eds)
  1021. ;
  1022.  
  1023. fun elabSpec (VE : VarEnv) (TE : TyEnv) (loc, spec') =
  1024.   case spec' of
  1025.     VALspec vds =>
  1026.       let val VE' = foldL_map (fn(id, sc) => fn acc => bindInEnv acc id sc)
  1027.                               (elabValDesc TE)
  1028.                               NILenv vds
  1029.       in (VE', NILenv) end
  1030.   | PRIM_VALspec pvs =>
  1031.       let val VE' = foldL_map (fn(id, sc) => fn acc => bindInEnv acc id sc)
  1032.                               (elabPrimValBind TE)
  1033.                               NILenv pvs
  1034.       in (VE', NILenv) end
  1035.   | TYPEDESCspec(equ, tds) =>
  1036.       (NILenv, elabPrimTypBindList equ tds)
  1037.   | TYPEspec tbs =>
  1038.       let val tbsTE = elabTypBindList TE tbs in
  1039.         setEquality tbsTE;
  1040.         (NILenv, tbsTE)
  1041.       end
  1042.   | DATATYPEspec(dbs, tbs_opt) =>
  1043.       let val dbsTE = initialDatBindTE dbs
  1044.           val tbsTE = elabTypBindList_opt (plusEnv TE dbsTE) tbs_opt
  1045.           (* Here dbsTE will get destructively updated too. *)
  1046.           val CE = elabDatBindList (plusEnv (plusEnv TE dbsTE) tbsTE) dbs
  1047.       in
  1048.         maximizeEquality dbsTE;
  1049.         setEquality tbsTE;
  1050.         (CE, plusEnv dbsTE tbsTE)
  1051.       end
  1052.   | EXCEPTIONspec eds =>
  1053.       (if U_map unguardedExDesc eds <> [] then
  1054.          errorMsg loc "Type variables in an exception description"
  1055.        else ();
  1056.        (elabExDescList [] VE TE eds, NILenv))
  1057.   | LOCALspec (spec1, spec2) =>
  1058.       let val (VE', TE')  = elabSpec VE TE spec1
  1059.           val (VE'',TE'') =
  1060.             elabSpec (plusEnv VE VE') (plusEnv TE TE') spec2
  1061.       in (VE'', TE'') end
  1062.   | OPENspec ids =>
  1063.       let val VE' =
  1064.             foldL (fn id => fn acc =>
  1065.                      bindTopInEnv acc (#uVarEnv (findSig loc id)))
  1066.                   NILenv ids
  1067.               val TE' =
  1068.             foldL (fn id => fn acc =>
  1069.                      bindTopInEnv acc (#uTyEnv (findSig loc id)))
  1070.                   NILenv ids
  1071.       in (VE', TE') end
  1072.   | EMPTYspec => (NILenv, NILenv)
  1073.   | SEQspec (spec1, spec2) =>
  1074.       let val (VE', TE')  = elabSpec VE TE spec1
  1075.           val (VE'',TE'') =
  1076.             elabSpec (plusEnv VE VE') (plusEnv TE TE') spec2
  1077.       in (plusEnv VE' VE'', plusEnv TE' TE'') end
  1078. ;
  1079.  
  1080. fun elabToplevelSpec (spec : Spec) =
  1081. (
  1082.   resetBindingLevel();
  1083.   elabSpec (mkGlobalVE()) (mkGlobalTE()) spec
  1084. );
  1085.