TypeInfer.cxx

Go to the documentation of this file.
00001 /**************************************************************************
00002  *
00003  * Copyright (C) 2008, Johns Hopkins University.
00004  * All rights reserved.
00005  *
00006  * Redistribution and use in source and binary forms, with or
00007  * without modification, are permitted provided that the following
00008  * conditions are met:
00009  *
00010  *   - Redistributions of source code must contain the above 
00011  *     copyright notice, this list of conditions, and the following
00012  *     disclaimer. 
00013  *
00014  *   - Redistributions in binary form must reproduce the above
00015  *     copyright notice, this list of conditions, and the following
00016  *     disclaimer in the documentation and/or other materials 
00017  *     provided with the distribution.
00018  *
00019  *   - Neither the names of the copyright holders nor the names of any
00020  *     of any contributors may be used to endorse or promote products
00021  *     derived from this software without specific prior written
00022  *     permission. 
00023  *
00024  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00025  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00026  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
00027  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
00028  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00029  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
00030  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00031  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
00032  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00033  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00034  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00035  *
00036  **************************************************************************/
00037 
00038 #include <assert.h>
00039 #include <stdint.h>
00040 #include <stdlib.h>
00041 #include <dirent.h>
00042 #include <fstream>
00043 #include <iostream>
00044 #include <string>
00045 #include <sstream>
00046 
00047 #include <libsherpa/UExcept.hxx>
00048 
00049 #include "UocInfo.hxx"
00050 #include "AST.hxx"
00051 #include "Type.hxx"
00052 #include "TypeInfer.hxx"
00053 #include "TypeScheme.hxx"
00054 #include "TypeMut.hxx"
00055 #include "Typeclass.hxx"
00056 #include "inter-pass.hxx"
00057 #include "Unify.hxx"
00058 #include <libsherpa/BigNum.hxx>
00059 #include "TypeInferUtil.hxx"
00060 
00061 using namespace std;
00062 using namespace boost;
00063 using namespace sherpa;
00064 
00065 typedef map<shared_ptr<Type>, shared_ptr<AST> > TypeAstMap;
00066 
00067 /**************************************************************/
00068 /*                     Some Declarations                      */
00069 /**************************************************************/
00070 
00071 // Some compositions of type inference flags, as a shorthand.
00072 // A Type Expression, but not a type application.
00073 #define TI_NON_APP_TYPE    ((ti_flags | TI_TYP_EXP) & (~TI_TYP_APP))
00074 // A value expression
00075 #define TI_EXPRESSION      (ti_flags & (~(TI_TYP_EXP | TI_TYP_APP)))
00076 // A constraint
00077 #define TI_CONSTRAINT      (TI_NON_APP_TYPE)
00078 
00079 //WARNING: **REQUIRES** errFree and errStream
00080 #define TYPEINFER(ast, gamma, instEnv, impTypes, tcc,  \
00081                   trail, mode, flags)                           \
00082   do {                                                          \
00083     CHKERR((errFree),                                           \
00084            (typeInfer(errStream, (ast), (gamma), (instEnv),     \
00085                       (impTypes), (tcc),                        \
00086                       (trail), (mode), (flags))));              \
00087   }while (0)
00088 
00089 //WARNING: **REQUIRES** errFree and errStream
00090 #define UNIFY(trail, errLoc, type1, type2)                      \
00091   do {                                                          \
00092     CHKERR(errFree, unify(errStream, trail, errLoc,             \
00093                           type1, type2, UFLG_NO_FLAGS));        \
00094   }while (0)
00095 
00096 
00097 static bool
00098 typeInfer(std::ostream& errStream, shared_ptr<AST> ast, 
00099           shared_ptr<TSEnvironment > gamma,
00100           shared_ptr<InstEnvironment > instEnv,
00101           TypeAstMap& impTypes,
00102           shared_ptr<TCConstraints> tcc,
00103           shared_ptr<Trail> trail,
00104           ResolutionMode mode,
00105           TI_Flags ti_flags);
00106 
00107 bool isExpansive(std::ostream& errStream, 
00108                  shared_ptr<const TSEnvironment > gamma,
00109                  shared_ptr<AST> ast);
00110 
00111 bool isExpansive(std::ostream& errStream, 
00112                  shared_ptr<const TSEnvironment > gamma,
00113                  shared_ptr<Type> typ);
00114 
00115 bool
00116 generalizePat(std::ostream& errStream,
00117               const sherpa::LexLoc &errLoc,
00118               shared_ptr<TSEnvironment > gamma,
00119               shared_ptr<const InstEnvironment > instEnv,
00120               shared_ptr<AST> bp, shared_ptr<AST> expr,
00121               shared_ptr<TCConstraints> tcc,
00122               shared_ptr<TCConstraints> parentTCC,
00123               shared_ptr<Trail> trail);
00124 
00125 
00126 /**************************************************************/
00127 /*                     Some Helper Functions                  */
00128 /**************************************************************/
00129 
00130 /* Some of the following fure repeated (and marked static) in both 
00131    inference routines due to the use/non-use of maybe types */
00132 
00133 static shared_ptr<Type>
00134 buildFnFromApp(shared_ptr<AST> ast)
00135 {
00136   assert(ast->astType == at_apply);
00137   shared_ptr<Type> targ = Type::make(ty_fnarg);
00138   for (size_t i = 1; i < ast->children.size(); i++) {
00139     shared_ptr<Type> argi = MBF(newTvar());
00140     shared_ptr<comp> ncomp = comp::make(argi);
00141     ncomp->flags |= COMP_MAYBE_BYREF;
00142     targ->components.push_back(ncomp);
00143   }
00144   
00145   shared_ptr<Type> ret = MBF(newTvar());
00146   shared_ptr<Type> fn = Type::make(ty_fn, targ, ret);
00147   return fn;
00148 }
00149 
00150 static shared_ptr<TypeScheme> 
00151 bindIdentDef(shared_ptr<AST> ast, 
00152              shared_ptr<TSEnvironment > gamma,
00153              unsigned long bindFlags,
00154              TI_Flags ti_flags)
00155 {
00156   if (!ast->symType) {
00157     if (ast->isIdentType(id_tvar))
00158       ast->symType = newTvar();
00159     else
00160       ast->symType = MBF(newTvar()); 
00161   }
00162 
00163   shared_ptr<TypeScheme> sigma = TypeScheme::make(ast->symType, ast);
00164   ast->scheme = sigma;
00165   
00166   if (ast->isIdentType(id_tvar)) {
00167     assert(ti_flags & TI_TYP_EXP);
00168     bindFlags |= BF_NO_MERGE;
00169     ast->tvarLB->envs.gamma->addBinding(ast->s, sigma);
00170   }
00171   else {
00172     gamma->addBinding(ast->s, sigma);      
00173   }
00174   
00177   gamma->setFlags(ast->s, bindFlags);    
00178   return sigma;
00179 }
00180 
00181 static shared_ptr<TypeScheme> 
00182 Instantiate(shared_ptr<AST> ast, shared_ptr<TypeScheme> sigma,
00183             shared_ptr<Trail> trail)
00184 {              
00185   if (ast->symbolDef)
00186     ast = ast->symbolDef;
00187   
00188   shared_ptr<TypeScheme> ins = GC_NULL;
00189   
00190   // Are we instantiating a structure/union definition?
00191   bool suInst = (ast->isIdentType(idc_ctor) ||
00192                  ast->isIdentType(id_union)); 
00193   
00194   ins = sigma->ts_instance();
00195   ins->tau->fixupFnTypes();
00196   
00197   if(suInst && !ins->tau->isException())
00198     ins->tau->fixupConstArguments(trail);
00199   
00200   return ins;
00201 }
00202 
00203 static bool
00204 findField(std::ostream& errStream, 
00205           shared_ptr<Type> t, shared_ptr<AST> fld, shared_ptr<Type> &fType)
00206 {
00207   t = t->getBareType();
00208   for (size_t i=0; i < t->components.size(); i++)
00209     if (t->CompName(i) == fld->s) {
00210       fType = t->CompType(i);
00211       return true;
00212     }
00213           
00214   errStream << fld->loc << ": "
00215             << " Unknown field " << fld->s
00216             << " in structure "
00217             << t->defAst->s 
00218             << std::endl;
00219   fType = GC_NULL;
00220   return false;
00221 }
00222 
00225 static bool
00226 findComponent(std::ostream& errStream, 
00227               shared_ptr<Type> sut, shared_ptr<AST> ast,
00228               shared_ptr<Type> &fct, bool orMethod = false)
00229 {
00230   sut = sut->getType();
00231   assert(ast->astType == at_select || 
00232          ast->astType == at_sel_ctr || 
00233          ast->astType == at_fqCtr);
00234   fct = GC_NULL;
00235 
00236   if (sut->isUType())
00237     sut = obtainFullUnionType(sut)->getType();
00238   
00239   if (sut->components.empty() && !sut->isIndexableType()) {
00240     errStream << ast->loc << ": "
00241               << "cannot dereference fields as only "
00242               << "an opaque declaration is available."
00243               << std::endl;
00244     return false;
00245   }
00246   
00247   bool valid=false;
00248   for (size_t i=0; i < sut->components.size(); i++) {
00249     if (sut->CompName(i) == ast->child(1)->s) {
00250       fct = sut->CompType(i)->getType();          
00251       valid = ((sut->CompFlags(i) & COMP_INVALID) == 0);
00252       break;
00253     }
00254   }
00255       
00256   if (orMethod && !fct) {
00257     for (size_t i=0; i < sut->methods.size(); i++) {
00258       if (sut->MethodName(i) == ast->child(1)->s) {
00259         fct = sut->MethodType(i)->getType();          
00260         valid = ((sut->MethodFlags(i) & COMP_INVALID) == 0);
00261         break;
00262       }
00263     }
00264   }
00265 
00266   if (!fct) {
00267     errStream << ast->loc << ": "
00268               << " In the expression " << ast->asString() << ", "
00269               << " structure/constructor " << sut->defAst->s 
00270               << " has no Field/Constructor"
00271               << (orMethod ? "/Method" : "")
00272               << " named " 
00273               << ast->child(1)->s << "." << std::endl;
00274     return false;
00275   } 
00276 
00277   if (!valid) {
00278     errStream << ast->child(0)->loc << ": "
00279               << " The expression " << ast->asString()
00280               << " has no field " 
00281               << ast->child(1)->s << "." << std::endl;
00282 
00283     fct = GC_NULL;
00284     return false;
00285   }
00286 
00287   return true;
00288 }
00289 
00290 static bool
00291 testNonEscaping(std::ostream& errStream, shared_ptr<AST> errAst,
00292                 shared_ptr<Type> t)
00293 {
00294   if(t->isNonEscaping()) {
00295     errStream << errAst->loc << ": Non-Capturable type "
00296               << t->asString()
00297               << " in Captuarable/Escape position."
00298               << std::endl;
00299     return false;
00300   }
00301   
00302   return true;
00303 }
00304 
00305 static bool
00306 ProcessLetExprs(std::ostream& errStream, shared_ptr<AST> lbs, 
00307                 shared_ptr<TSEnvironment > gamma,
00308                 shared_ptr<InstEnvironment > instEnv,
00309                 TypeAstMap& impTypes,
00310                 shared_ptr<TCConstraints> tcc,
00311                 shared_ptr<Trail> trail,
00312                 ResolutionMode mode, TI_Flags ti_flags)
00313 {
00314   bool errFree = true;
00315   for (size_t c = 0; c < lbs->children.size(); c++) {
00316     shared_ptr<AST> lb = lbs->child(c);
00317     shared_ptr<AST> expr = lb->child(1);
00318     TYPEINFER(expr, gamma, instEnv, impTypes, tcc,
00319               trail, USE_MODE, TI_EXPRESSION);
00320     
00321     CHKERR(errFree, testNonEscaping(errStream, expr, expr->symType));
00322   }
00323   return errFree;
00324 }
00325 
00326 static bool
00327 ProcessLetBinds(std::ostream& errStream, shared_ptr<AST> lbs, 
00328                 shared_ptr<TSEnvironment > gamma,
00329                 shared_ptr<InstEnvironment > instEnv,
00330                 TypeAstMap& impTypes,
00331                 shared_ptr<TCConstraints> tcc,
00332                 shared_ptr<Trail> trail,
00333                 ResolutionMode mode, TI_Flags ti_flags)
00334 {
00335   bool errFree = true;
00336   for (size_t c = 0; c < lbs->children.size(); c++) {
00337     shared_ptr<AST> lb = lbs->child(c);
00338     shared_ptr<AST> idPat = lb->child(0);
00339     
00340     TYPEINFER(idPat, gamma, instEnv, impTypes, tcc,
00341               trail, DEF_MODE, TI_EXPRESSION);
00342   }
00343   return errFree;
00344 }
00345 
00346 static bool
00347 UnifyLetBinds(std::ostream& errStream, shared_ptr<AST> lbs,
00348               shared_ptr<Trail> trail)
00349 {
00350   bool errFree = true;
00351   for (size_t c = 0; c < lbs->children.size(); c++) {
00352     shared_ptr<AST> lb = lbs->child(c);
00353     shared_ptr<AST> id = lb->getID();
00354     shared_ptr<AST> expr = lb->child(1);
00355     
00356     // Note: It is safe to say MBF(id->symType) because
00357     // bindIdentDef() introduces identifiers with MBF()
00358     // always.
00359     UNIFY(trail, id->loc, expr->symType, MBF(id->symType));
00360     
00361     lb->symType = id->symType;
00362 
00363     // In the case of heuristic inference, fix the top-most level
00364     // mutability based on the lexical usage analysis of the
00365     // identifier. This must be done in the case of local variables
00366     // only. So, the code is within unifyletbinds
00367     if (Options::heuristicInference) {
00368       shared_ptr<Type> idType = id->symType->getType();
00369 
00370       if ((id->flags & ID_IS_MUTATED) && !idType->isMutable()) {
00371         std::stringstream ss;  
00372         shared_ptr<Type> mTv = Type::make(ty_mutable, newTvar());
00373         
00374         // Not reporting an error here, since it will be reported
00375         // later when the identifier is actually used.
00376         unify(ss, trail, id->loc, idType, mTv, UFLG_NO_FLAGS);
00377       }
00378     }
00379   }
00380   return errFree;
00381 }
00382 
00383 static void
00384 makeLetGather(shared_ptr<AST> lbs, shared_ptr<AST> &bAst, shared_ptr<AST> &vAst)
00385 {
00386   // Because all types in a letrec share a context, we need a
00387   // container form to glue things together temporarily.
00388   // The following loop constructs the container in reversed
00389   // order, but that is okay, because the container only exists
00390   // to let mutual recursion unify correctly.
00391   bAst = AST::make(at_letGather, lbs->child(0)->loc);
00392   vAst = AST::make(at_letGather, lbs->child(0)->loc);
00393   shared_ptr<Type> bType = Type::make(ty_letGather);
00394   shared_ptr<Type> vType = Type::make(ty_letGather);
00395   
00396   for (size_t c = 0; c < lbs->children.size(); c++) {
00397     shared_ptr<AST> lb = lbs->child(c);
00398     
00399     bAst->addChild(lb->child(0));
00400     vAst->addChild(lb->child(1));
00401     bType->components.push_back(comp::make(lb->getID()->symType));
00402     vType->components.push_back(comp::make(lb->child(1)->symType));
00403   }
00404   
00405   bAst->symType = bType;
00406   vAst->symType = vType;
00407 }
00408 
00410 void
00411 die()
00412 {
00413   std::cerr << "Internal Compiler Error, Aborting." << std::endl;
00414   throw 0;
00415 }
00416         
00417 /**************************************************************/
00418 /*                Type consistency checkng                   */
00419 /**************************************************************/
00420 
00421 static bool
00422 checkImpreciseTypes(std::ostream& errStream, 
00423                     const shared_ptr<TSEnvironment > gamma,
00424                     TypeAstMap& impTypes)
00425 {
00426   bool errFree = true;
00427   for (TypeAstMap::iterator itr = impTypes.begin();
00428        itr != impTypes.end(); ++itr) {
00429     shared_ptr<Type> t = itr->first->getBareType();
00430     shared_ptr<AST> ast = itr->second;
00431     switch(t->typeTag) {
00432     case ty_array:
00433       {
00434         if (t->arrLen->len == 0) {
00435           errStream << ast->loc << ": "
00436                     << "Type " << t->asString() 
00437                     << " is not precise enough "
00438                     << "to be instantiable."
00439                     << std::endl;
00440           errFree = false;
00441         }
00442         break;
00443       }
00444       
00445     case ty_int8:
00446     case ty_int16:
00447     case ty_int32:
00448     case ty_int64:
00449     case ty_uint8:
00450     case ty_uint16:
00451     case ty_uint32:
00452     case ty_uint64:
00453     case ty_word:
00454     case ty_float:
00455     case ty_double:
00456     case ty_quad:
00457 
00458 #ifdef KEEP_BF
00459     case ty_bitfield:
00460 #endif
00461     case ty_structv:
00462       //     case ty_unionr:
00463       //     case ty_structr:
00464       break;
00465 
00466     default:
00467       {
00468         errStream << ast->loc << ": "
00469                   << "Internal Compiler Error. "
00470                   << "checkImpreciseTypes obtained "
00471                   << t->asString() << " type."
00472                   << std::endl;
00473         errFree = false;
00474         break;
00475       }
00476     }
00477   }
00478   
00479   return errFree;
00480 }
00481 
00482 static bool
00483 checkConstraints(std::ostream& errStream, 
00484                  const shared_ptr<TypeScheme> defSigma,
00485                  const shared_ptr<TypeScheme> declSigma,
00486                  const shared_ptr<AST> declAst)
00487 {
00488   bool errFree = true;
00489   
00490   shared_ptr<TCConstraints> defTcc = TCConstraints::make();
00491   shared_ptr<TCConstraints> declTcc = TCConstraints::make();
00492   MarkFlags unmatched = MARK_CHECK_CONSTRAINTS;
00493 
00494   defSigma->addConstraints(defTcc);
00495   declSigma->addConstraints(declTcc);
00496 
00497   if (defTcc->size() != declTcc->size()) 
00498     errFree = false;
00499   
00500   for (TypeSet::iterator itr = defTcc->begin();
00501       errFree && itr != defTcc->end(); ++itr)
00502     (*itr)->mark |= unmatched;
00503   for (TypeSet::iterator itr_j = declTcc->begin();
00504       errFree && itr_j != declTcc->end(); ++itr_j)
00505     (*itr_j)->mark |= unmatched;
00506 
00507   for (TypeSet::iterator itr = defTcc->begin();
00508       errFree && itr != defTcc->end(); ++itr) {
00509     shared_ptr<Typeclass> defct = (*itr);
00510       
00511     if ((defct->mark & unmatched) == 0)
00512       continue;
00513       
00514     bool unified = false;
00515       
00516     for (TypeSet::iterator itr_j = declTcc->begin();
00517         errFree && itr_j != declTcc->end(); ++itr_j) {
00518       shared_ptr<Typeclass> declct = (*itr_j);
00519 
00520       if ((defct->mark & unmatched) == 0)
00521         continue;
00522       
00523       if (defct->strictlyEquals(declct)) {
00524         defct->mark &= ~unmatched;
00525         declct->mark &= ~unmatched;
00526         unified = true;
00527         break;
00528       }
00529     }
00530             
00531     if (!unified)
00532       errFree = false;
00533   }
00534 
00535   for (TypeSet::iterator itr = defTcc->begin();
00536       errFree && itr != defTcc->end(); ++itr)
00537     if ((*itr)->mark & unmatched)
00538       errFree = false;
00539   for (TypeSet::iterator itr_j = declTcc->begin();
00540       errFree && itr_j != declTcc->end(); ++itr_j)
00541     if ((*itr_j)->mark & unmatched)
00542       errFree = false;  
00543 
00544   if (!errFree) {
00545     errStream << declAst->loc << ": For the declaration of `" 
00546               << declAst->s << "', the constraints "
00547               << "on the declaration here, do not match "
00548               << "with the definition."
00549               << " Declaration: "
00550               << declSigma->asString()
00551               << " Definition: "
00552               << defSigma->asString()
00553               << std::endl;
00554   }
00555   
00556   return errFree;
00557 }
00558 
00569 static bool
00570 isAsGeneral(std::ostream& errStream,
00571             shared_ptr<Trail> trail,
00572             shared_ptr<const TSEnvironment > gamma,
00573             shared_ptr<InstEnvironment > instEnv,
00574             shared_ptr<TypeScheme> sigmaA,
00575             shared_ptr<TypeScheme> sigmaB)
00576 {
00577   bool isAsGeneral = true;
00578 
00579   shared_ptr<AST> astB = sigmaB->ast;
00580 
00581   size_t num_B_tvs = sigmaB->ftvs.size();
00582 
00583   {
00584     shared_ptr<Trail> testTrail = Trail::make();
00585     bool errFree = true;
00586     UNIFY(testTrail, LexLoc(),
00587           sigmaA->tau->getType(), sigmaB->tau->getType());
00588     CHKERR(isAsGeneral, errFree);
00589     
00590     TypeSet gottenTypes;
00591     for(TypeSet::iterator itr = sigmaB->ftvs.begin();
00592         isAsGeneral && itr != sigmaB->ftvs.end(); ++itr) {
00593       shared_ptr<Type> ftv = (*itr)->getType();
00594       gottenTypes.insert(ftv);
00595       CHKERR(isAsGeneral, (ftv->typeTag == ty_tvar));
00596     }
00597 
00598     if (isAsGeneral)
00599       CHKERR(isAsGeneral, checkConstraints(errStream, sigmaA, sigmaB, astB));
00600 
00601     CHKERR(isAsGeneral, gottenTypes.size() == num_B_tvs);
00602 
00603     testTrail->rollBack();
00604   }
00605 
00606   return isAsGeneral;
00607 }
00608 
00609 /* Checks the types of:
00610      - A definition vs Declaration
00611      - A declaration vs a previous declaration
00612    for EXACT compatibility */
00613 static bool
00614 matchDefDecl(std::ostream& errStream, 
00615              shared_ptr<Trail> trail,
00616              shared_ptr<const TSEnvironment > gamma,
00617              shared_ptr<InstEnvironment > instEnv,
00618              shared_ptr<TypeScheme> declSigma,
00619              shared_ptr<TypeScheme> defSigma,
00620              TI_Flags ti_flags)
00621 {
00622   if (ti_flags & TI_DEF_DECL_NO_MATCH)
00623     return true;  
00624   
00625   bool errorFree = true;   
00626   const shared_ptr<AST> decl = declSigma->ast;
00627   shared_ptr<const AST>  def = defSigma->ast;
00628   bool verbose = false;
00629   DEBUG(DEF_DECL) 
00630     verbose = true;
00631   
00632   if (declSigma->ftvs.size() != defSigma->ftvs.size()) {
00633     errorFree = false;
00634   }
00635   else {
00636     shared_ptr<TypeScheme> declTS = declSigma;
00637     shared_ptr<TypeScheme> defTS = defSigma;
00638     shared_ptr<Type> declT = declTS->tau->getType();
00639     shared_ptr<Type> defT  = defTS->tau->getType();
00640     
00641     CHKERR(errorFree, declT->defEqualsDecl(defT, verbose));
00642 
00643     if (errorFree)
00644       CHKERR(errorFree, checkConstraints(errStream, defTS, declTS, decl));
00645     
00646     // Rigidness preservation:
00647     // Make sure that after unification, the declaration/definition is
00648     // no less general than what was previously declared.
00649     // The number of type variables are initially determined to be
00650     // equal, but this check catches errors such as:
00651     // 1) DECL: \/'a. 'a -> int
00652     //    DEF:  \/'a. int -> 'a 
00653     //    POST UNIFY: int -> int
00654     // 2) DECL: \/'a,'b. 'a -> 'b -> 'b
00655     //    DEF:  \/'a,'b. 'a -> 'a -> 'b
00656     //    POST UNIFY: \/'a. 'a -> 'a -> 'a
00657     {
00658       TypeSet gottenTypes;
00659 
00660       for (TypeSet::iterator itr = defTS->ftvs.begin(); 
00661           errorFree && itr != defTS->ftvs.end(); ++itr) {
00662         shared_ptr<Type> ftv = (*itr)->getType();
00663         gottenTypes.insert(ftv);
00664         CHKERR(errorFree, (ftv->typeTag == ty_tvar));
00665       }
00666 
00667       CHKERR(errorFree, gottenTypes.size() == defTS->ftvs.size());
00668     }
00669   }
00670 
00671   if (!errorFree)
00672     errStream << def->loc <<": The type of " << def->s 
00673               << " at definition/declaration "  << defSigma->asString()
00674               << " does not match that of "
00675               << std::endl
00676               << decl->loc << ": declaration / definition "
00677               << declSigma->asString() << " exactly."
00678               << std::endl;
00679   
00680   return errorFree;
00681 }
00682 
00683 
00684 /* Wrapper around Type's checkMutConsistency function that prints an 
00685    error message. This function is used wherever the programmer writes
00686    an explicit type annotation, to check that the annotated type is
00687    consistent wrt mutability (that is, it does not include types such
00688    as (mutable (pair bool int32)) */
00689 static bool
00690 CheckMutConsistency(std::ostream& errStream, 
00691                     const sherpa::LexLoc &errLoc,
00692                     shared_ptr<Type> t)
00693 {
00694   bool errFree = t->checkMutConsistency();
00695   if(!errFree) 
00696     errStream << errLoc << ": Type Annotation "
00697               << " is inconsistent wrt mutability."
00698               << std::endl;
00699   return errFree;
00700 }
00701 
00702 /* Due to the presence of explicit programmer annotations, the unifier
00703    alone cannot sufficiently check the consistency of mutability at
00704    all AST positions. For example, consider:
00705    
00706    (defstruct St f:bool)
00707 
00708    (lambda (x)                  x: 'a|'b
00709      (let ((p x))               p: 'c|'b
00710         (set! p p)              p:  M'd|'b
00711         x:St))                  x:St, p:M'd|St  ;; ERROR 
00712 
00713   The uniffier cannot detect this error since it is due to non-local 
00714   propagation --  the type of p is not involved in the unification at 
00715   the expression x:St. Therefore, we introduce an extra consistency 
00716   checking pass that traverses all ASTs and reports an error if an 
00717   inconsistent type is found.
00718 
00719   This does not affect inferred types since a failure at this step 
00720   can only lead to a type error. This pass is only necessary if we 
00721   have explicit type annotation (albeit in the form of structure 
00722   definitions) where we control the type of all instantiations 
00723   and copies at one place. */
00724 
00725 static bool
00726 CheckMutConsistency(std::ostream& errStream, 
00727                     shared_ptr<AST> ast)
00728 {
00729   bool errFree = true;
00730 
00731   if(ast->symType &&
00732      // error is better reported on the identifier than the
00733      // let-binding, which will have a ty_letgather type
00734      ast->astType != at_letbindings && ast->astType != at_letbinding)
00735     CHKERR(errFree, ast->symType->checkMutConsistency());
00736   
00737   if(!errFree) { 
00738     errStream << ast->loc << ": Unsound Mutable Type "
00739               << ast->symType->asString()
00740               << std::endl;
00741     return false;
00742   }
00743 
00744   for (size_t i = 0; errFree && i < ast->children.size(); i++) 
00745     CHKERR(errFree, CheckMutConsistency(errStream, ast->child(i)));
00746   
00747   return errFree;
00748 }
00749 
00750 
00751 /**************************************************************/
00752 /****                   MAIN INFERENCE ROUTINES            ****/
00753 /**************************************************************/
00754 
00755 static bool
00756 InferTvList(std::ostream& errStream, shared_ptr<AST> tvList, 
00757             shared_ptr<TSEnvironment > gamma,
00758             shared_ptr<InstEnvironment > instEnv,
00759             TypeAstMap& impTypes,
00760             shared_ptr<TCConstraints> tcc,
00761             shared_ptr<Trail> trail,
00762             ResolutionMode mode, TI_Flags ti_flags,
00763             shared_ptr<Type> container)  
00764 {  
00765   bool errFree = true;
00766   for (size_t i = 0; i < tvList->children.size(); i++) {
00767     shared_ptr<AST> tv = tvList->child(i);
00768     TYPEINFER(tv, gamma, instEnv, impTypes, 
00769               tcc, trail, DEF_MODE, ti_flags | TI_TYP_EXP);
00770     shared_ptr<Type> tvType = tv->symType->getType();
00771     assert(tvType->typeTag == ty_tvar);
00772     tvType->flags |= TY_RIGID;
00773     container->typeArgs.push_back(tvType);
00774   }
00775 
00776   return errFree;
00777 }
00778 
00779 
00780 // Tvs are not added to the typeScheme in InferTvList itself because
00781 // this has to be done after all the components (fields/constructors)
00782 // of a type have been processed. Otherwise, the type will be
00783 // polymorphic within itself.
00784 static void
00785 addTvsToSigma(std::ostream& errStream, shared_ptr<AST> tvList, 
00786               shared_ptr<TypeScheme> sigma, shared_ptr<Trail> trail)  
00787 {  
00788   for (size_t i = 0; i < tvList->children.size(); i++) {
00789     shared_ptr<AST> tv = tvList->child(i);
00790     shared_ptr<Type> tvType = tv->symType->getType();
00791     assert(tvType->typeTag == ty_tvar);
00792     sigma->ftvs.insert(tvType);
00793   }
00794 }
00795 
00796 // In case of value type definitions, mark all those  
00797 // type arguments that are candidiates for copy-compatibility.
00798 static void
00799 markCCC(shared_ptr<Type> ct)
00800 {
00801   if (!ct->isValType())
00802     return;
00803 
00804   // We first need to mark all arguments CCCOK, and then remove
00805   // those that are not OK so that determoneCCC can get recursive
00806   // type definitions right.
00807   for (size_t i = 0; i < ct->typeArgs.size(); i++) {
00808     shared_ptr<Type> arg = ct->TypeArg(i)->getType();
00809     arg->flags |= TY_CCC;
00810   }
00811   
00812   for (size_t i = 0; i < ct->typeArgs.size(); i++) {
00813     shared_ptr<Type> arg = ct->TypeArg(i)->getType();      
00814     if (!arg->determineCCC(ct))
00815       arg->flags &= ~TY_CCC;
00816   }
00817 }
00818 
00819 // Called only for definitions
00820 static bool
00821 InferStruct(std::ostream& errStream, shared_ptr<AST> ast, 
00822             shared_ptr<TSEnvironment > gamma,
00823             shared_ptr<InstEnvironment > instEnv,
00824             TypeAstMap& impTypes,
00825             shared_ptr<TCConstraints> tcc,
00826             shared_ptr<Trail> trail,
00827             ResolutionMode mode,
00828             bool isReference,
00829             bool mustDefine,
00830             bool mustEvalBody,
00831             TI_Flags ti_flags)
00832 {
00833   bool errFree = true;
00834   TypeTag structTypeTag;
00835   
00836   shared_ptr<AST> sIdent = ast->child(0);
00837 
00838   // match at_ident
00839   structTypeTag = (isReference)? ty_structr : ty_structv;
00840    
00841   shared_ptr<Type> st = Type::make(structTypeTag);
00842   st->defAst = sIdent;
00843   st->myContainer = sIdent;
00844   sIdent->symType = st;
00845   shared_ptr<TypeScheme> sigma = TypeScheme::make(st, sIdent, TCConstraints::make());
00846 
00847   // match at_tvlist
00848   shared_ptr<AST> tvList = ast->child(1);
00849   CHKERR(errFree, InferTvList(errStream, tvList, gamma, instEnv, impTypes, 
00850                               sigma->tcc, trail, DEF_MODE, 
00851                               ti_flags | TI_TYP_EXP, st));
00852   sIdent->scheme = sigma;
00853 
00854   // Type all constraints
00855   TYPEINFER(ast->child(5), gamma, instEnv, impTypes, 
00856             sigma->tcc, trail, mode, TI_CONSTRAINT);
00857   
00858   shared_ptr<TypeScheme> declTS = gamma->getBinding(sIdent->s);
00859   unsigned long bindFlags = 0;
00860   if (declTS) {
00861     declTS->tau->getBareType()->defAst = sIdent;
00862     bindFlags = BF_REBIND;
00863   }
00864   gamma->addBinding(sIdent->s, sigma);
00865   gamma->setFlags(sIdent->s, bindFlags);
00866 
00867   // Ignore the category
00868 
00869   // match at_declares
00870   TYPEINFER(ast->child(3), gamma, instEnv, impTypes, sigma->tcc,
00871             trail, mode, ti_flags);
00872     
00873   // match at_fields
00874   shared_ptr<AST> fields = ast->child(4);
00875   for (size_t c = 0; c < fields->children.size(); c++) {
00876     // match at_ident
00877     // match agt_type
00878     shared_ptr<AST> field = fields->child(c);
00879     TYPEINFER(field, gamma, instEnv, impTypes, 
00880               sigma->tcc, trail,  USE_MODE, 
00881               ti_flags | TI_TYP_EXP | TI_TYP_DEFN);
00882     
00883     CHKERR(errFree, CheckMutConsistency(errStream,
00884                                         field->loc, field->symType));
00885     
00886     switch(field->astType) {
00887     case at_field:
00888       {
00889         st->components.push_back(comp::make(field->child(0)->s,
00890                                             field->child(1)->symType));
00891         break;
00892       }
00893       
00894     case at_fill:
00895       {
00896         ast->total_fill += field->field_bits;
00897         break;
00898       }
00899     case at_methdecl:
00900       {
00901         st->methods.push_back(comp::make(field->child(0)->s,
00902                                          field->child(1)->symType));
00903         field->child(1)->symType->myContainer = sIdent;
00904         break;
00905       }
00906 
00907     default:
00908       {
00909         assert(false);
00910         break;
00911       }
00912     }
00913   }
00914   
00915   // Add Ftvs so that they get generalized in future uses
00916   addTvsToSigma(errStream, tvList, sigma, trail); 
00917   
00918   // In case of value type definitions, mark all those  
00919   // type arguments that are candidiates for copy-compatibility.
00920   markCCC(st);
00921   
00923   // still possible.
00924 
00925   // Set the main AST's type.
00926   ast->symType = sIdent->symType;
00927    
00928   // Solve current Predicates.
00929   CHKERR(errFree, sigma->solvePredicates(errStream, ast->loc,
00930                                          instEnv, trail)); 
00931 
00932   // Ensure that the definition matches the declarations
00933   if (declTS)
00934     CHKERR(errFree, matchDefDecl(errStream, trail, gamma, instEnv,
00935                                  declTS, sigma, ti_flags));
00936   
00937   return errFree;
00938 }
00939 
00940 // Called only for definitions
00941 static bool
00942 InferObject(std::ostream& errStream, shared_ptr<AST> ast, 
00943             shared_ptr<TSEnvironment > gamma,
00944             shared_ptr<InstEnvironment > instEnv,
00945             TypeAstMap& impTypes,
00946             shared_ptr<TCConstraints> tcc,
00947             shared_ptr<Trail> trail,
00948             ResolutionMode mode,
00949             bool isReference,
00950             bool mustDefine,
00951             bool mustEvalBody,
00952             TI_Flags ti_flags)
00953 {
00954   bool errFree = true;
00955   TypeTag structTypeTag;
00956   
00957   shared_ptr<AST> sIdent = ast->child(0);
00958 
00959   // match at_ident
00960   structTypeTag = (isReference)? ty_objectr : ty_objectv;
00961    
00962   shared_ptr<Type> st = Type::make(structTypeTag);
00963   st->defAst = sIdent;
00964   st->myContainer = sIdent;
00965   sIdent->symType = st;
00966   shared_ptr<TypeScheme> sigma = TypeScheme::make(st, sIdent, TCConstraints::make());
00967 
00968   // match at_tvlist
00969   shared_ptr<AST> tvList = ast->child(1);
00970   CHKERR(errFree, InferTvList(errStream, tvList, gamma, instEnv, impTypes, 
00971                               sigma->tcc, trail, DEF_MODE, 
00972                               TI_TYP_EXP, st));
00973   sIdent->scheme = sigma;
00974 
00975   // Type all constraints
00976   TYPEINFER(ast->child(5), gamma, instEnv, impTypes, 
00977             sigma->tcc, trail,  mode, TI_CONSTRAINT);
00978   
00979   shared_ptr<TypeScheme> declTS = gamma->getBinding(sIdent->s);
00980   unsigned long bindFlags = 0;
00981   if (declTS) {
00982     declTS->tau->getBareType()->defAst = sIdent;
00983     bindFlags = BF_REBIND;
00984   }
00985   gamma->addBinding(sIdent->s, sigma);
00986   gamma->setFlags(sIdent->s, bindFlags);
00987 
00988   // Ignore the category
00989 
00990   // match at_declares
00991   TYPEINFER(ast->child(3), gamma, instEnv, impTypes, sigma->tcc,
00992             trail,  mode, TI_NO_FLAGS);
00993     
00994   // match at_fields
00995   shared_ptr<AST> fields = ast->child(4);
00996   for (size_t c = 0; c < fields->children.size(); c++) {
00997     // match at_ident
00998     // match agt_type
00999     shared_ptr<AST> field = fields->child(c);
01000     TYPEINFER(field, gamma, instEnv, impTypes, 
01001               sigma->tcc, trail,  USE_MODE, 
01002               TI_TYP_EXP | TI_TYP_DEFN);
01003     
01004     CHKERR(errFree, CheckMutConsistency(errStream,
01005                                         field->loc, field->symType));
01006     
01007     assert(field->astType == at_methdecl);
01008 
01009     st->methods.push_back(comp::make(field->child(0)->s,
01010                                      field->child(1)->symType));
01011     field->child(1)->symType->myContainer = sIdent;
01012     break;
01013   }
01014   
01015   // Add Ftvs so that they get generalized in future uses
01016   addTvsToSigma(errStream, tvList, sigma, trail); 
01017   
01018   // In case of value type definitions, mark all those  
01019   // type arguments that are candidiates for copy-compatibility.
01020   markCCC(st);
01021   
01022   // Set the main AST's type.
01023   ast->symType = sIdent->symType;
01024    
01025   // Solve current Predicates.
01026   CHKERR(errFree, sigma->solvePredicates(errStream, ast->loc,
01027                                          instEnv, trail)); 
01028 
01029 #if 0
01030   // Ensure that the definition matches the declarations
01031   if (declTS)
01032     CHKERR(errFree, matchDefDecl(errStream, trail, gamma, instEnv,
01033                                  declTS, sigma, uflags, false));
01034 #endif
01035   
01036   return errFree;
01037 }
01038 
01039 
01040 // Called only for definitions
01041 static bool
01042 InferUnion(std::ostream& errStream, shared_ptr<AST> ast, 
01043            shared_ptr<TSEnvironment > gamma,
01044            shared_ptr<InstEnvironment > instEnv,
01045            TypeAstMap& impTypes,
01046            shared_ptr<TCConstraints> tcc,
01047            shared_ptr<Trail> trail,
01048            ResolutionMode mode,
01049            bool isReference,
01050            bool mustDefine,
01051            bool mustEvalBody,
01052            TI_Flags ti_flags)
01053 {
01054 
01055   bool errFree = true;
01056   TypeTag unionTypeTag;
01057   
01058   shared_ptr<AST> uIdent = ast->child(0);
01059 
01060   // match at_ident
01061   unionTypeTag = (isReference)? ty_unionr : ty_unionv;
01062   
01063   shared_ptr<Type> ut = Type::make(unionTypeTag);
01064   ut->defAst = uIdent;
01065   ut->myContainer = uIdent;
01066   uIdent->symType = ut;
01067   shared_ptr<TypeScheme> sigma = TypeScheme::make(ut, uIdent, TCConstraints::make());
01068   
01069   // match at_tvlist
01070   shared_ptr<AST> tvList = ast->child(1);
01071   CHKERR(errFree, InferTvList(errStream, tvList, gamma, instEnv, impTypes, 
01072                               sigma->tcc, trail, DEF_MODE, 
01073                               ti_flags | TI_TYP_EXP, ut));
01074   uIdent->scheme = sigma;
01075   
01076   // Type all constraints
01077   TYPEINFER(ast->child(5), gamma, instEnv, impTypes, 
01078             sigma->tcc, trail, mode, TI_CONSTRAINT);
01079   
01080   shared_ptr<TypeScheme> declTS = gamma->getBinding(uIdent->s);
01081   unsigned long bindFlags = 0;
01082   
01083   if (declTS) {
01084     declTS->tau->getType()->defAst = uIdent;
01085     bindFlags = BF_REBIND;
01086   }
01087   gamma->addBinding(uIdent->s, sigma);
01088   gamma->setFlags(uIdent->s, bindFlags);
01089   
01090   // Ignore the category
01091   
01092   // match at_declares
01093   shared_ptr<AST> declares = ast->child(3);
01094   TYPEINFER(declares, gamma, instEnv, impTypes, sigma->tcc,
01095             trail, mode, ti_flags);
01096   
01097   
01098   // match at_constructors
01099   shared_ptr<AST> ctrs = ast->child(4);
01100   for (size_t c = 0; c < ctrs->children.size(); c++) {
01101     // match at_ident
01102     // match agt_type
01103     shared_ptr<AST> ctr = ctrs->child(c);
01104     shared_ptr<AST> ctrId = ctr->child(0);    
01105     // Careful: 
01106     // Constructors with components are typed ucon 
01107     // and those without any are typed uval.
01108     TypeTag ctrTypeTag;
01109 
01110     if (ctr->children.size() > 1)
01111       ctrTypeTag = (isReference) ? ty_uconr : ty_uconv;
01112     else
01113       ctrTypeTag = (isReference) ? ty_uvalr : ty_uvalv;
01114     
01115     ctrId->symType = Type::make(ctrTypeTag);
01116     ctrId->symType->defAst = ctrId;
01117     ctrId->symType->myContainer = uIdent;
01118     ctr->symType = ctrId->symType;
01119     
01120     for (size_t i = 1; i < ctr->children.size(); i++) {
01121       shared_ptr<AST> field = ctr->child(i);
01122       TYPEINFER(field, gamma, instEnv, impTypes, 
01123                 sigma->tcc, trail,  USE_MODE, 
01124                 ti_flags | TI_TYP_EXP | TI_TYP_DEFN);
01125       
01126       CHKERR(errFree, CheckMutConsistency(errStream,
01127                                           field->loc, field->symType));
01128       
01129       switch(field->astType) {
01130       case at_field:
01131         {
01132           shared_ptr<comp> nComp = comp::make(field->child(0)->s,
01133                                               field->child(1)->symType);
01134           if (field->flags & FLD_IS_DISCM)
01135             nComp->flags |= COMP_UNIN_DISCM;
01136           
01137           ctrId->symType->components.push_back(nComp);
01138           break;
01139         }
01140       case at_fill:
01141         {
01142           ctr->total_fill += field->field_bits;
01143           break;
01144         }
01145 
01146         // Note: at_methdecl illegal here, so omission is intentional.
01147       default:
01148         {
01149           assert(false);
01150           break;
01151         }
01152       }
01153     }
01154     
01155     // All constructors share the same type-class constraints
01156     // as the union. This rule -- unlike the one in Haskell -- 
01157     // requires that the tcc be absolutely enforced.
01158     shared_ptr<TypeScheme> ctrSigma = TypeScheme::make(ctrId->symType, 
01159                                                        ctrId, sigma->tcc);
01160     
01161     // This may feel wierd -- that All constructors point to the same
01162     // type arguments rather than a copy. But since every instance is 
01163     // newly obtained, this is OK.
01164     for (size_t i = 0; i < tvList->children.size(); i++)
01165       ctrId->symType->typeArgs.push_back(tvList->child(i)->symType);
01166     
01167     // Don't add ctrSigma to gamma yet. Constructors are 
01168     // bound at the end of the definition
01169     ctrId->scheme = ctrSigma;
01170     
01171     shared_ptr<comp> nComp = comp::make(ctrId->s, ctrId->symType);
01172     uIdent->symType->components.push_back(nComp);
01173   } 
01174 
01175   // Add Ftvs so that they get generalized in future uses
01176   // Mark that the structure must always be copied.
01177   // It is important that this step be done late so that the recursive
01178   // uses do not prompt copy.
01179   addTvsToSigma(errStream, tvList, sigma, trail);
01180   
01181   // In case of value type definitions, mark all those  
01182   // type arguments that are candidiates for copy-compatibility.
01183   markCCC(ut);
01184   
01185   // Solve current Predicates.
01186   CHKERR(errFree, sigma->solvePredicates(errStream, ast->loc,
01187                                          instEnv, trail)); 
01188   
01189   //Now add all constructor bindings to the environment.
01190   for (size_t c = 0; c < ctrs->children.size(); c++) {
01191     shared_ptr<AST> ctr = ctrs->child(c);
01192     shared_ptr<AST> ctrId = ctr->child(0);   
01193     addTvsToSigma(errStream, tvList, ctrId->scheme, trail);
01194     gamma->addBinding(ctrId->s, ctrId->scheme);
01195     
01196     // Solve current Predicates.
01197     // Since we all share the same constraints, automatically solved.
01198   }
01199 
01200   //Build structure types for all constructors.
01201   for (size_t c = 0; c < ctrs->children.size(); c++) {
01202     shared_ptr<AST> ctr = ctrs->child(c)->child(0);
01203     shared_ptr<Type> ctrType = ctr->symType->getType();
01204     shared_ptr<TypeScheme> ctrSigma = ctr->scheme;
01205     shared_ptr<Type> sType = GC_NULL;
01206     shared_ptr<TypeScheme> stSigma = GC_NULL;
01207     
01208     for (size_t i=0; i < c; i++) {
01209       shared_ptr<AST> thatCtr = ctrs->child(i)->child(0);
01210       shared_ptr<Type> thatCtrType = thatCtr->symType->getType();
01211       
01212       if (ctrType->components.size() != 
01213           thatCtrType->components.size())
01214         continue;
01215       
01216       // Since there can be no constructors with only fills
01217       // and no field names are repeated, it is sufficient
01218       // to check types regardless of fills.
01219       bool same = true;
01220       for (size_t j=0; j < ctrType->components.size(); j++) {        
01221         shared_ptr<comp> thisComp = ctrType->Component(j);
01222         shared_ptr<comp> thatComp = thatCtrType->Component(j);
01223         
01224         if ((thisComp->name != thatComp->name) ||
01225             !thisComp->typ->strictlyEquals(thatComp->typ)) {
01226           same = false;
01227           break;
01228         }
01229       }
01230          
01231       if (same) {
01232         assert(thatCtr->stSigma);
01233         stSigma = thatCtr->stSigma;
01234         ctr->stSigma = thatCtr->stSigma;
01235         ctr->stCtr = thatCtr;
01236         break;
01237       }
01238     }
01239     
01240     if (!stSigma) {
01241       TypeTag ctrStructTypeTag = (isReference)?ty_structr:ty_structv;      
01242       sType = Type::make(ctrStructTypeTag);
01243       sType->defAst = ctr; // structures have names like (cons 'a)
01244       for (size_t i=0; i < ctrType->components.size(); i++)
01245         sType->components.push_back(comp::make(ctrType->CompName(i),
01246                                                ctrType->CompType(i)));
01247       // Comp's Flags are not necesary here ?
01248  
01249       
01250       for (size_t i=0; i < ctrType->typeArgs.size(); i++)
01251         sType->typeArgs.push_back(ctrType->TypeArg(i));
01252       
01253       stSigma = TypeScheme::make(sType, ctr, sigma->tcc); 
01254       stSigma->ftvs = ctrSigma->ftvs;
01255 
01256       ctr->stCtr = ctr;
01257       ctr->stSigma = stSigma;
01258     }
01259 
01260     assert(ctr->stSigma);
01261     /* No need to add anything to the environment, these structures
01262        i) Have the same name as the constructor
01263        ii) Are accessible through the stSigma field.
01264 
01265        If necessary, add them with some other name */
01266   }
01267   
01268   // Deal with tag type declaration and Cardelli Optimization
01269 
01270   /* If we are dealing with defrepr, don't perform any
01271      optimization */ 
01272   if (ast->flags & UNION_IS_REPR) {
01273     if (declares->tagType) {
01274       errStream << ast->loc << ": "
01275                 << "tag type declarations cannot be "
01276                 << "given with defreprs."
01277                 << std::endl;
01278       errFree = false;      
01279     }
01280   }
01281   else if (errFree) {  
01282 
01283     //Check if we can do Cardelli Optimization:
01284     
01285     unsigned long long maxCtrs = 0;  
01286     size_t lastTagValue = (ctrs->children.size() - 1);
01287     size_t lastTagValueCardelli = lastTagValue;
01288 
01289     if (declares->tagType) {
01290       maxCtrs = (((unsigned long long)1) << declares->nBits());
01291 
01292       if (lastTagValue > (maxCtrs - 1)) {
01293         errStream << ast->loc << ": "
01294                   << "Not enough bits in the tag type to represent "
01295                   << "all Constructors. Use a bigger tag type. "
01296                   << "[If no tag type declaration is found, "
01297                   << "the defalut is `word']"
01298                   << std::endl;
01299         errFree = false;
01300       }      
01301     }
01302     else if (ctrs->children.size() == 1) {
01303       declares->tagType = Type::make(ty_word);
01304       assert(declares->field_bits == 0);
01305       uIdent->flags |= SINGLE_LEG_UN;
01306     }
01307     else {      
01308       declares->tagType = Type::make(ty_word);     
01309       assert(declares->field_bits == 0);
01310 
01311       maxCtrs = (((unsigned long long)1) << declares->nBits());          
01312       
01313       bool cardelli = true;
01314       bool seenRef = false;
01315       bool isEnum = true;
01316       
01317       for (size_t c = 0; 
01318            cardelli && (c < ctrs->children.size()); 
01319            c++) {
01320         shared_ptr<AST> ctr = ctrs->child(c);
01321         
01322         switch(ctr->children.size()) {
01323         case 0:
01324           assert(false);
01325           break;
01326 
01327         case 1:
01328           break;
01329           
01330         case 2:
01331           isEnum = false;
01332 
01333           if (seenRef) {
01334             cardelli = false;
01335             break;
01336           }
01337           
01338           if (ctr->child(1)->symType->isRefType() || 
01339               ctr->child(1)->symType->isConstrainedToRefType(sigma->tcc) ||
01340               ctr->child(1)->symType->isNullableType())
01341             seenRef = true;
01342           else
01343             cardelli = false;
01344           
01345           break;
01346           
01347         default:
01348           isEnum = false;
01349           cardelli = false;
01350           break;           
01351         }          
01352       }
01353      
01354       // The (nullable 'a) union is declared in the preamble and
01355       // requires special handling for tag numbering.
01356       bool isNullable = (cardelli && uIdent->s == "nullable");
01357 
01358       if (isEnum) {
01359         assert(!seenRef);
01360         cardelli = false;
01361         uIdent->flags |= ENUM_UN;
01362       }
01363       else if (cardelli) {        
01364         assert(!isEnum);
01365         uIdent->flags |= CARDELLI_UN;
01366         if (isNullable)
01367           uIdent->flags |= NULLABLE_UN;
01368         lastTagValueCardelli = (2 * lastTagValue) - 1;
01369       }
01370       
01371       DEBUG(UNION_INF)
01372         errStream << "Union " << uIdent->s << ": " 
01373                   << std::endl
01374                   << "  nBits = " << declares->tagType->nBits() 
01375                   << std::endl 
01376                   << "  maxCtrs = " << maxCtrs 
01377                   << std::endl
01378                   << "  ltv = " << lastTagValue 
01379                   << std::endl
01380                   << "  ltvC = " << lastTagValueCardelli 
01381                   << std::endl
01382                   << "  isEnum = " << isEnum 
01383                   << std::endl
01384                   << "  cardelli = " << cardelli 
01385                   << std::endl
01386                   << "  nullable = " << isNullable
01387                   << std::endl;
01388     }
01389     
01390     uIdent->tagType = declares->tagType;
01391     uIdent->field_bits = declares->field_bits;
01392   }
01393     
01394   // Set the main AST's type.
01395   ast->symType = uIdent->symType;
01396 
01397   // Ensure that the definition matches the declarations
01398   if (declTS)
01399     CHKERR(errFree, matchDefDecl(errStream, trail, gamma, instEnv,
01400                                  declTS, sigma, ti_flags));
01401   
01402   return errFree;
01403 }
01404 
01405 bool
01406 superDAG(shared_ptr<AST> super, shared_ptr<AST> curr)
01407 {
01408   if (super ==  curr)
01409     return false;
01410   
01411   assert(super->scheme);
01412   shared_ptr<TCConstraints> tcc = super->scheme->tcc;
01413   assert(tcc);
01414 
01415   for (TypeSet::iterator itr = tcc->begin();
01416       itr != tcc->end(); ++itr) {
01417     shared_ptr<Typeclass> pred = (*itr);
01418     if (pred->flags & TY_CT_SELF)
01419       continue;
01420 
01421     if (superDAG(pred->defAst, curr) == false)
01422       return false;
01423   }
01424   return true;
01425 }
01426 
01427 static bool
01428 InferTypeClass(std::ostream& errStream, shared_ptr<AST> ast, 
01429                shared_ptr<TSEnvironment > gamma,
01430                shared_ptr<InstEnvironment > instEnv,
01431                TypeAstMap& impTypes,
01432                shared_ptr<TCConstraints> tcc,
01433                shared_ptr<Trail> trail,
01434                ResolutionMode mode,
01435                TI_Flags ti_flags)
01436 {
01437   bool errFree = true;
01438   shared_ptr<AST> ident = ast->child(0);
01439   shared_ptr<Typeclass> tc = Typeclass::make(ty_typeclass);
01440   tc->defAst = ident;
01441   shared_ptr<TypeScheme> sigma = TypeScheme::make(tc, ident, TCConstraints::make());
01442   tc->flags |= TY_CT_SELF;
01443   sigma->tcc->addPred(tc);
01444 
01445   shared_ptr<AST> tvList = ast->child(1);
01446   CHKERR(errFree, InferTvList(errStream, tvList, gamma, instEnv, impTypes, 
01447                               sigma->tcc, trail, DEF_MODE, 
01448                               ti_flags | TI_TYP_EXP, tc));
01449   addTvsToSigma(errStream, tvList, sigma, trail);
01450   ident->symType = tc;
01451   ident->scheme = sigma;
01452   
01453   // Type all constraints
01454   TYPEINFER(ast->child(5), gamma, instEnv, impTypes, 
01455             sigma->tcc, trail, mode, 
01456             TI_CONSTRAINT | TI_TCC_SUB);
01457 
01458   // Typeclass Declarations
01459   shared_ptr<AST> tcdecls = ast->child(2);
01460   for (size_t c = 0; c < tcdecls->children.size(); c++) {
01461     shared_ptr<AST> tcdecl = tcdecls->child(c);
01462     assert(tcdecl->astType == at_tyfn);
01463     shared_ptr<AST> domain = tcdecl->child(0);               
01464     shared_ptr<AST> range =  tcdecl->child(1);
01465     shared_ptr<Type> tyfn = Type::make(ty_tyfn);
01466     tyfn->defAst = tcdecl;
01467     TYPEINFER(domain, gamma, instEnv, impTypes, sigma->tcc, 
01468               trail, USE_MODE, ti_flags | TI_TYP_EXP);
01469     TYPEINFER(range, gamma, instEnv, impTypes, sigma->tcc, 
01470               trail, USE_MODE, ti_flags | TI_TYP_EXP);
01471     tyfn->components.push_back(comp::make(domain->symType));
01472     tyfn->components.push_back(comp::make(range->symType));
01473     
01474     //errStream << "***"
01475     //          << domain->asString() << ": "
01476     //                 << domain->symType->asString(GC_NULL) 
01477     //                 << std::endl
01478     //                 << range->asString() << ": "
01479     //                 << range->symType->asString(GC_NULL)
01480     //                 << std::endl
01481     //                 << "tyfn = " << tyfn->asString(GC_NULL)
01482     //                 << std::endl;
01483     tc->addFnDep(tyfn);
01484   }
01485 
01486   shared_ptr<AST> methods = ast->child(4);
01487   for (size_t c = 0; c < methods->children.size(); c++) {
01488     shared_ptr<AST> method = methods->child(c);
01489     shared_ptr<AST> mID = method->child(0);
01490     shared_ptr<AST> mtType = method->child(1);
01491     
01492     TYPEINFER(mtType, gamma, instEnv, impTypes, sigma->tcc,
01493               trail,  USE_MODE, ti_flags | TI_TYP_EXP);
01494     mID->symType = mtType->symType;
01495     CHKERR(errFree, CheckMutConsistency(errStream,
01496                                         mtType->loc, mtType->symType));
01497     
01498     shared_ptr<Type> mType = mID->symType->getType();
01499     mType->defAst = mID;
01500     mType->myContainer = ident;
01501     
01502     shared_ptr<TypeScheme> mSigma = TypeScheme::make(mType, mID, 
01503                                                      TCConstraints::make());
01504     for (TypeSet::iterator itr = sigma->tcc->begin();
01505         itr != sigma->tcc->end(); ++itr)
01506       mSigma->tcc->addPred((*itr));
01507  
01508     do { // Dummy loop
01509       if (!mType) {
01510         assert(!errFree); 
01511         break;
01512       }
01513         
01514       if (mType->typeTag != ty_fn) {
01515         errStream << ast->loc << ": " 
01516                   << "The type of \"method\" " << mID->s
01517                   << "was infered as " << mType->asString()
01518                   << ", but all methods must have a function type."
01519                   << std::endl;
01520          errFree = false;
01521         break;
01522       }
01523 
01524       mSigma->collectAllFtvs();
01525       
01526       // Solve current Predicates.
01527       CHKERR(errFree, mSigma->solvePredicates(errStream, method->loc,
01528                                               instEnv, trail)); 
01529       
01530       mType->myContainer = ident;
01531       mID->scheme = mSigma;      
01532       shared_ptr<comp> nComp = comp::make(mID->s,mType); 
01533       ident->symType->components.push_back(nComp);      
01534     } while (0);                                   
01535   }
01536 
01537   if (!errFree)
01538     return false;
01539   
01540   gamma->addBinding(ident->s, ident->scheme);
01541   for (size_t c = 0; c < methods->children.size(); c++) {
01542     shared_ptr<AST> method = methods->child(c);
01543     shared_ptr<AST> mID = method->child(0);
01544     gamma->addBinding(mID->s, mID->scheme);
01545   }
01546   
01547   assert(!instEnv->getBinding(ident->fqn.asString()));
01548 
01549   InstanceSet *instSet = new InstanceSet;
01550   shared_ptr<InstanceSet> instSetPtr(instSet);
01551   
01552   instEnv->addBinding(ident->fqn.asString(), instSetPtr);
01553   ast->symType = ident->symType;
01554   return errFree;
01555 }
01556 
01557 static bool
01558 InferInstance(std::ostream& errStream, shared_ptr<AST> ast, 
01559               shared_ptr<TSEnvironment > gamma,
01560               shared_ptr<InstEnvironment > instEnv,
01561               TypeAstMap& impTypes,
01562               shared_ptr<TCConstraints> tcc,
01563               shared_ptr<Trail> trail,
01564               ResolutionMode mode,
01565               TI_Flags ti_flags)
01566 {
01567   bool errFree = true;
01568   
01569   shared_ptr<AST> tcapp = ast->child(0);
01570   shared_ptr<AST> methods = ast->child(1);
01571   shared_ptr<AST> constraints = ast->child(2);
01572   
01573   shared_ptr<AST> TCident = tcapp;
01574   if (tcapp->children.size())
01575     TCident = tcapp->child(0);
01576   
01577   shared_ptr<TSEnvironment > defGamma = gamma->newDefScope();
01578   ast->envs.gamma = defGamma;
01579   ast->envs.instEnv = instEnv;
01580   
01581   ast->symType = Type::make(ty_tvar);
01582   shared_ptr<TCConstraints> myTcc = TCConstraints::make();
01583   TYPEINFER(tcapp, defGamma, instEnv, impTypes,
01584             myTcc, trail, USE_MODE, TI_CONSTRAINT);
01585 
01586   // Mark myself
01587   for (TypeSet::iterator itr = myTcc->begin();
01588       itr != myTcc->end(); ++itr) {
01589     shared_ptr<Typeclass> pred = (*itr);
01590     if (pred->defAst == TCident->symbolDef)
01591       pred->flags |= TY_CT_SELF;
01592   }
01593   
01594   if (!errFree) 
01595     return false;
01596   
01597   // Type all constraints
01598   TYPEINFER(constraints, defGamma, instEnv, impTypes,
01599             myTcc, trail, USE_MODE, TI_CONSTRAINT);
01600 
01601   
01602   if (!errFree) 
01603     return false;
01604       
01605   shared_ptr<Typeclass> tc = tcapp->symType->getType();
01606 
01607   // Get the set of current instances 
01608   shared_ptr<InstanceSet> currInsts = 
01609     instEnv->getBinding(tc->defAst->fqn.asString());
01610 
01611   
01612   if ((ti_flags & TI_ALL_INSTS_OK) == 0) {
01613     
01614     // Make sure that the instance definition is consistent
01615     // with the known functional dependencies.
01616     
01617     //errStream << ast->loc << ": #Preds = " << myTcc->pred->size()
01618     //                << std::endl;
01619     for (TypeSet::iterator itr = myTcc->begin();
01620         itr != myTcc->end(); ++itr) {
01621       shared_ptr<Typeclass> pred = (*itr)->getType();
01622       //errStream << "Processing : " << pred->asString()
01623       //          << std::endl;
01624 
01625       for (TypeSet::iterator itr_d = pred->fnDeps.begin(); 
01626           itr_d != pred->fnDeps.end(); ++itr_d) {
01627         shared_ptr<Typeclass> fnDep =  (*itr_d);
01628         TypeSet domain;
01629         TypeSet range;
01630         fnDep->Args()->collectAllftvs(domain);
01631         fnDep->Ret()->collectAllftvs(range);
01632           
01633         //errStream << "  Processing : " << fnDep->asString()
01634         //              << std::endl;
01635           
01636         for (TypeSet::iterator itr_j = range.begin();
01637             itr_j != range.end(); ++itr_j) {
01638           if (domain.find(*itr_j) == domain.end()) {
01639             errStream << ast->loc << ": "
01640                       << "Invalid Instance. Definition contradicts"
01641                       << " with the functional dependency "
01642                       << fnDep->asString() << " of predicate "
01643                       << pred->asString() << ". At least one "
01644                       << " type variable in the range was not in"
01645                       << " the domain."
01646                       << std::endl;
01647             errFree = false;
01648             break;
01649           }
01650         }
01651       }
01652     }
01653 
01654     if (!errFree) 
01655       return false;
01656 
01657     // Make sure that the instance definition does not contradict
01658     // with any functional dependencies in the presence of 
01659     // previous instance definitions
01660     // This is a O(n^5) loop !!! Hopefully there will not be
01661     // too many typeclass and fnDep constraints, and 
01662     // the compilation will finish in time ... 
01663     // The other way to think about this is that this is actually
01664     // a O(n^3) algorithm ranging over all instances and the 
01665     // functional dependencies. The other two loops occur because
01666     // fnDeps are stored inside predicates. 
01667     // Is there a better algorithm?
01668     for (InstanceSet::iterator itr = currInsts->begin();
01669         itr != currInsts->end(); ++itr) {
01670       shared_ptr<Instance> inst = (*itr);
01671       // Since Equals will not unify any variables in place,
01672       // I don't have to do a ts_instance_copy() here.
01673       shared_ptr<TCConstraints> theirTcc = inst->ast->scheme->tcc;
01674 
01675       for (TypeSet::iterator itr = myTcc->begin();
01676           itr != myTcc->end(); ++itr) {
01677         shared_ptr<Typeclass> myPred = (*itr)->getType();
01678         for (TypeSet::iterator itr_m = theirTcc->begin();
01679             itr_m != theirTcc->end(); ++itr_m) {
01680           shared_ptr<Typeclass> theirPred = (*itr_m)->getType();
01681 
01682           if ((myPred->defAst == theirPred->defAst) &&  
01683              (myPred->fnDeps.size() && theirPred->fnDeps.size()))
01684             for (TypeSet::iterator itr_j = myPred->fnDeps.begin();
01685                 itr_j != myPred->fnDeps.end(); ++itr_j) {
01686               shared_ptr<Type> myFnDep =  (*itr_j)->getType();
01687               shared_ptr<Type> myDomain = myFnDep->Args();
01688                   
01689               for (TypeSet::iterator itr_k = 
01690                     theirPred->fnDeps.begin();
01691                   itr_k != theirPred->fnDeps.end(); ++itr_k) {
01692                 shared_ptr<Type> theirFnDep =  (*itr_k)->getType();
01693                 shared_ptr<Type> theirDomain = theirFnDep->Args();
01694                     
01695                 assert(myFnDep->defAst == theirFnDep->defAst);
01696                     
01697                 if ( myDomain->equals(theirDomain) && 
01698                     !myFnDep->equals(theirFnDep)) {
01699                   errStream << ast->loc << ": "
01700                             << "The following is a contradiction: \n"
01701                             << inst->ast->loc << ": "
01702                             << "Instance definition " 
01703                             << inst->asString()
01704                             << " with Predicate "
01705                             << theirPred->asString() << " and "
01706                             << "associated functional dependency "
01707                             << theirFnDep->asString() << ", and\n"
01708                             << ast->loc << ": "
01709                             << "Instance definition " 
01710                             << tc->asString()
01711                             << " with Predicate "
01712                             << myPred->asString() << " and "
01713                             << "associated functional dependency "
01714                             << myFnDep->asString()
01715                             << std::endl;
01716                   errFree = false;
01717                   break;
01718                 }
01719               }
01720             }
01721         }
01722       }        
01723     }
01724            
01725     if (!errFree) 
01726       return false;
01727 
01728   }
01729  
01730   tcapp->scheme = TypeScheme::make(tc, tcapp, myTcc);
01731       
01732   size_t nMethods = tc->components.size();
01733 
01734   if (methods->children.size() != nMethods) {
01735     errStream << ast->loc << ": "
01736               << "Type class" << tcapp->child(0)->s
01737               << " needs " << nMethods << " methods for "
01738               << "instantiation, but here obtained "
01739               << methods->children.size() << "."
01740               << std::endl;
01741     errFree = false;
01742     return errFree;
01743   }
01744 
01745   for (size_t i = 0; i < tc->components.size(); i++) {
01746     shared_ptr<Type> mtType = tc->CompType(i);
01747     std::string mtName = tc->CompName(i);
01748 
01749     bool found = false;
01750     for (size_t j = 0; j < methods->children.size(); j++) {
01751       shared_ptr<AST> method = methods->child(i);
01752       shared_ptr<AST> method_name = method->child(0);
01753       shared_ptr<AST> method_val = method->child(1);
01754 
01755       if(mtName == method_name->s) {
01756         found = true;
01757 
01758         method_name->symType = mtType;
01759         TYPEINFER(method_val, defGamma, instEnv, impTypes, myTcc,
01760                   trail, USE_MODE, ti_flags);
01761         shared_ptr<Type> methodType = method_val->symType->getType();
01762       
01763         // Methods are functions, remove top mutability.
01764         UNIFY(trail, method->loc, 
01765               mtType, methodType->minimizeMutability());
01766 
01767         // Symbol resolver guarantees that there cannot be duplicate
01768         // method definitions.
01769         break;
01770       }
01771     }
01772     
01773     if(!found) {
01774       errStream << ast->loc << ": No definition for method "
01775                 << mtName << " in this instance."
01776                 << std::endl;
01777       errFree = false;
01778     }
01779   }
01780 
01781   if (!errFree) 
01782     return false;
01783 
01784   shared_ptr<TypeScheme> sigma = tcapp->scheme;
01785 
01786   gamma->mergeBindingsFrom(defGamma);
01787   sigma->generalize(errStream, ast->loc, gamma, instEnv, tcapp, 
01788                     GC_NULL, trail, gen_instance);      
01789   
01790   if (!errFree)
01791     return false;
01792   
01793   shared_ptr<Instance> myInstance = Instance::make(sigma, ast);
01794   
01795   if ((ti_flags & TI_ALL_INSTS_OK) == 0) {
01796     // Make sure there are no absolute conflicts 
01797     // with existing instances
01798     assert(currInsts);
01799   
01800     for (InstanceSet::iterator itr = currInsts->begin();
01801         itr != currInsts->end(); ++itr) {
01802       shared_ptr<Instance> inst = (*itr);
01803       if (inst->overlaps(myInstance)) {
01804         errStream << tcapp->loc << ": "
01805                   << "Instance declaration "
01806                   << sigma->asString() << " conflicts with "
01807                   << " previous definition at "
01808                   << inst->ast->loc 
01809                   << "(" << inst->ts->asString() << ")."
01810                   << std::endl;
01811         errFree = false;
01812         break;
01813       }
01814     } 
01815 
01816     if (!errFree)
01817       return false; 
01818   }
01819   
01820   // Add current Predicate.
01821   currInsts->insert(myInstance);
01822   
01823   //errStream << "Added " << sigma->asString() 
01824   //            << " to " << tc->defAst->s << std::endl;
01825       
01826   ast->symType = tcapp->symType;
01827   ast->scheme =  tcapp->scheme;
01828 
01829   return errFree;
01830 }
01831 
01832 #if 0  
01833 static bool
01834 CheckLetrecFnxnRestriction(std::ostream &errStream, shared_ptr<AST> ast)
01835 {
01836   bool errFree = true;
01837   switch(ast->astType) {
01838   case at_ident:
01839     {
01840       if (!ast->symType->isFnxn() && !ast->symType->isClosure()) {
01841         errStream << ast->loc << ": Identifier " << ast->s
01842                   << " bound in a letrec, has non-function type "
01843                   << ast->symType->asString();
01844         errFree = false;              
01845       }
01846       break;
01847     }
01848     
01849   case at_identPattern:
01850     {
01851       CHKERR(errFree, CheckLetrecFnxnRestriction(errStream, 
01852                                                  ast->child(0)));
01853       break;
01854     }
01855 
01856   case at_uswitch:
01857   case at_try:
01858     {
01859       for (size_t c=0; c < ast->children.size(); c++)
01860         if (c != IGNORE(ast))
01861           CHKERR(errFree, CheckLetrecFnxnRestriction(errStream, 
01862                                                      ast->child(c)));
01863       break;
01864     }
01865 
01866   default:
01867     {
01868       for (size_t c=0; c < ast->children.size(); c++)
01869         CHKERR(errFree, CheckLetrecFnxnRestriction(errStream, 
01870                                                    ast->child(c)));
01871       break;
01872     }
01873   }
01874   return errFree;
01875 }
01876 #endif
01877 
01888 static bool
01889 typeInfer(std::ostream& errStream, shared_ptr<AST> ast, 
01890           shared_ptr<TSEnvironment > gamma,
01891           shared_ptr<InstEnvironment > instEnv,
01892           TypeAstMap& impTypes,
01893           shared_ptr<TCConstraints> tcc,
01894           shared_ptr<Trail> trail,
01895           ResolutionMode mode,
01896           TI_Flags ti_flags)
01897 {
01898   bool errFree = true;
01899 
01900   // Save the current environment in the AST.
01901   // If we create a new environment, we will update it later.
01902   ast->envs.gamma = gamma;
01903   ast->envs.instEnv = instEnv;  
01904 
01905   DEBUG(TI_AST)
01906     errStream << "INF: " << ast->loc << ": " 
01907               << ast->s << " [" << ast->tagName() << "]" 
01908               << "   mode = " << mode
01909               << std::endl;
01910   
01911   switch(ast->astType) {
01912   case agt_expr:
01913   case agt_expr_or_define:
01914   case agt_eform:
01915   case at_Null:
01916   case at_unboxedCat:
01917   case at_boxedCat:
01918   case at_oc_closed:
01919   case at_oc_open:
01920   case at_opaqueCat:
01921   case at_tcmethods:
01922   case at_tcmethod_binding:
01923   case agt_category:
01924   case at_AnyGroup:
01925   case agt_literal:
01926   case agt_var:
01927   case agt_tvar:
01928   case agt_definition:
01929   case agt_type_definition:
01930   case agt_value_definition:
01931   case agt_type:
01932   case at_letbindings:
01933   case at_loopbindings:
01934   case at_loopbinding:
01935   case agt_CompilationUnit:
01936   case agt_tc_definition:
01937   case agt_if_definition:
01938   case agt_openclosed:
01939   case agt_ow:
01940   case agt_qtype:
01941   case agt_fielditem:
01942   case at_ifident:
01943   case at_localFrame:
01944   case at_frameBindings:
01945   case at_identList:
01946   case agt_ucon:
01947   case agt_uselhs:
01948 
01949   case at_defrepr:
01950     //case at_reprbody:
01951     //case agt_reprbodyitem:
01952     //case at_reprcase:
01953     //case at_reprcaselegR:
01954     //case at_reprtag:
01955   case at_reprctrs:
01956   case at_reprctr:
01957   case at_reprrepr:
01958 
01959     {
01960       errStream << ast->loc << ": Internal Compiler Error. Invalid AST type" 
01961                 << ast->tagName() << std::endl;
01962     
01963       errFree = false;
01964       break;
01965     }
01966 
01967   case at_boolLiteral:
01968     {
01969       /*------------------------------------------------
01970           ___________________________________________
01971                  A |- BOOL_LITERAL: bool
01972         ------------------------------------------------*/
01973       ast->symType = Type::make(ty_bool);
01974       break;
01975     }
01976 
01977   case at_charLiteral:
01978     {
01979       /*------------------------------------------------
01980           ___________________________________________
01981                  A |- CHAR_LITERAL: char
01982         ------------------------------------------------*/
01983       ast->symType = Type::make(ty_char);
01984       break;
01985     }
01986 
01987   case at_intLiteral:
01988     {
01989       /*------------------------------------------------
01990           ___________________________________________
01991                  A |- INT_LITEREAL: 'a \ IntLit('a)
01992         ------------------------------------------------*/
01993       
01994       if (Options::noPrelude) {
01995         ast->symType = Type::make(ty_word);
01996         break;
01997       }
01998 
01999       if (ti_flags & TI_NO_MORE_TC) {
02000         ast->symType = Type::make(ty_tvar);
02001         break;
02002       }
02003 
02004       const std::string& intLit = SpecialNames::spNames.sp_integral;
02005       shared_ptr<TypeScheme> icSigma = gamma->getBinding(intLit);
02006       assert(icSigma);
02007       
02008       shared_ptr<Typeclass> ic = icSigma->type_instance();
02009       assert(ic->typeArgs.size() == 1);
02010       ast->symType = ic->TypeArg(0)->getType();
02011       tcc->addPred(ic);
02012       break;
02013     }
02014 
02015   case at_floatLiteral:
02016     {
02017       /*------------------------------------------------
02018           ___________________________________________
02019                  A |- FLOAT_LITERAL: 'a \ FloatLit('a)
02020         ------------------------------------------------*/
02021 
02022       if (Options::noPrelude) {
02023         ast->symType = Type::make(ty_float);
02024         break;
02025       }
02026 
02027       if (ti_flags & TI_NO_MORE_TC) {
02028         ast->symType = Type::make(ty_tvar);
02029         break;
02030       }
02031 
02032       std::string& floatLit = SpecialNames::spNames.sp_fp;
02033       shared_ptr<TypeScheme> fcSigma = gamma->getBinding(floatLit);
02034       assert(fcSigma);
02035       
02036       shared_ptr<Typeclass> fc = fcSigma->type_instance();
02037       assert(fc->typeArgs.size() == 1);
02038       ast->symType = fc->TypeArg(0)->getType();
02039       tcc->addPred(fc);
02040       break;
02041     }
02042     
02043   case at_docString:
02044     // FIX: Not sure this is right. In truth, we really shouldn't be
02045     // bothering to type check these at all.
02046     {
02047       ast->symType = Type::make(ty_string);
02048 
02049       TYPEINFER(ast->child(0), gamma, instEnv, impTypes, tcc,
02050                 trail, mode, ti_flags);
02051       break;
02052     }
02053 
02054   case at_stringLiteral:
02055     {
02056       /*------------------------------------------------
02057           ___________________________________________
02058                     A |- STRING_LITERAL: string
02059         ------------------------------------------------*/
02060       ast->symType = Type::make(ty_string);
02061       break;
02062     }
02063 
02064   case at_ident:
02065     {
02066       /*------------------------------------------------
02067         DEF:
02068                 EXTEND A with x:'b|'a
02069           ___________________________________________
02070                     A |- x: 'b|'a
02071    
02072         USE:
02073                 A(x) = forall 'a* t\C
02074           ___________________________________________
02075                   A |- x: t['b* / 'a*]  \ C
02076         ------------------------------------------------*/
02077       switch(mode) {
02078       case DEF_MODE:
02079         {
02080           unsigned long bindFlags = 0;
02081           shared_ptr<TypeScheme> sigma = gamma->getBinding(ast->s);
02082 
02083           if (sigma && ast->isGlobal()) {            
02084             // NOTE: none of the declaration forms make this 
02085             // recursive call. 
02086             // Therefore, this case MUST be
02087             // a definition for which we have already seen a 
02088             // declaration.
02089 
02090             assert(!ast->isDecl);
02091 
02092             bindFlags = BF_REBIND;
02093             sigma = bindIdentDef(ast, gamma, bindFlags, ti_flags);
02094             ast->symType->defAst = sigma->tau->getType()->defAst = ast;
02095           }
02096           else {
02097             sigma = bindIdentDef(ast, gamma, bindFlags, ti_flags);
02098           }
02099           break;
02100         }
02101         
02102       case USE_MODE:
02103         {
02104           assert(tcc);
02105 
02106           shared_ptr<TypeScheme> sigma = gamma->getBinding(ast->s);
02107 
02108           if (!sigma) {
02109 
02110             // If this is a type variable that is used as in
02111             //
02112             //   (define a:'a 10)
02113             //
02114             // there will be no prior definition of it ('a).  So, it
02115             // should now be defined.  Incorrect usages should be
02116             // taken care of by the symbol resolver.  So, it is safe
02117             // to add this type to Gamma now.
02118 
02119             if (ast->isIdentType(id_tvar)) {
02120               sigma = bindIdentDef(ast, gamma, 0, ti_flags);              
02121             }
02122             else {  
02123               errStream << ast->loc << ": "
02124                         << ast->s << " Unbound in Gamma" << std::endl;
02125               
02126               //errStream << "Available bindings are: "
02127               //          << gamma->asString()
02128               //          << std::endl;              
02129               
02130               ast->symType = newTvar();
02131               return false;
02132             }
02133           }
02134           
02135           shared_ptr<TypeScheme> tsIns =  Instantiate(ast, sigma, trail);
02136           shared_ptr<Type> ins = tsIns->tau->getType();
02137           ast->symType = ins;
02138           
02139           DEBUG(ID_INS)
02140             errStream << " For " << ast->s << ", "
02141                       << "Obtained " << ins->asString(Options::debugTvP)
02142                       << " From " 
02143                       << sigma->asString(Options::debugTvP) 
02144                       << std::endl;
02145               
02146           ins = ins->getBareType();
02147 
02148           if ((ti_flags & TI_TYP_EXP) && 
02149              ((ti_flags & TI_TYP_APP) == 0) && 
02150              (ins->typeArgs.size() > 0)) {
02151             errStream << ast->loc << ": "
02152                       << ast->s << " cannot be instantiated without " 
02153                       << ins->typeArgs.size() << " type arguments."
02154                       << std::endl;
02155             
02156             ast->symType = newTvar();
02157             return false;
02158           }
02159           
02160           if (tsIns->tcc) {
02161             for (TypeSet::iterator itr = tsIns->tcc->begin();
02162                 itr != tsIns->tcc->end(); ++itr) {
02163               shared_ptr<Typeclass> pred = (*itr)->getType();              
02164               if (ti_flags & TI_TCC_SUB)
02165                 pred->flags |= TY_CT_SUBSUMED;
02166               tcc->addPred(pred);
02167             }
02168           }
02169           break;
02170         }
02171       default:
02172         {
02173           assert(false);
02174           break;
02175         }
02176       }
02177       break;
02178     }
02179 
02180   case at_module:
02181     {
02182       for (size_t c = 0; c < ast->children.size(); c++) {
02183         TYPEINFER(ast->child(c), gamma, instEnv, impTypes, tcc,
02184                   trail, mode, ti_flags);
02185         // errStream << " - - - - - - - - - - - - - - - - - - - - - - - - - "
02186         //              << std::endl;
02187       }
02188       break;
02189     }
02190 
02191   case at_interface:
02192     {
02193       // match at_ident
02194       //    TYPEINFER(ast->child(0), gamma, instEnv, impTypes, tcc,
02195       //              trail, mode, TI_EXPRESSION);
02196     
02197       // match agt_definition*
02198 
02199       for (size_t c = 1; c < ast->children.size(); c++)
02200         TYPEINFER(ast->child(c), gamma, instEnv, impTypes, tcc,
02201                   trail, mode, ti_flags);
02202       break;
02203     }
02204 
02205   case at_usesel:
02206     {
02207       // Impossible to get here. Symtab rewrote this as ident.
02208       assert(false);
02209     }
02210     break;
02211 
02212   case at_defunion:
02213     {
02214       shared_ptr<TSEnvironment > defGamma = gamma->newDefScope();
02215       ast->envs.gamma = defGamma;
02216       
02217       shared_ptr<AST> category = ast->child(2);
02218       bool isBoxedType = (category->astType == at_boxedCat);
02219       
02220       CHKERR(errFree, InferUnion(errStream, ast, defGamma, instEnv,
02221                                  impTypes, tcc,
02222                                  trail, mode, isBoxedType, 
02223                                  true, true, ti_flags));
02224       
02225       gamma->mergeBindingsFrom(defGamma);      
02226       break;
02227     }
02228 
02229   case at_defstruct:
02230     {
02231       shared_ptr<TSEnvironment > defGamma = gamma->newDefScope();
02232       ast->envs.gamma = defGamma;
02233 
02234       shared_ptr<AST> category = ast->child(2);
02235       bool isBoxedType = (category->astType == at_boxedCat);
02236 
02237       CHKERR(errFree, InferStruct(errStream, ast, defGamma, instEnv,
02238                                   impTypes, tcc,
02239                                   trail, mode, isBoxedType, 
02240                                   true, true, ti_flags));
02241 
02242       gamma->mergeBindingsFrom(defGamma);      
02243       break;
02244     }
02245 
02246   case at_defobject:
02247     {
02248       shared_ptr<TSEnvironment > defGamma = gamma->newDefScope();
02249       ast->envs.gamma = defGamma;
02250 
02251       shared_ptr<AST> category = ast->child(2);
02252       bool isBoxedType = (category->astType == at_boxedCat);
02253 
02254       CHKERR(errFree, InferObject(errStream, ast, defGamma, instEnv,
02255                                   impTypes, tcc,
02256                                   trail,  mode, isBoxedType, 
02257                                   true, true, TI_NO_FLAGS));
02258 
02259       gamma->mergeBindingsFrom(defGamma);      
02260       break;
02261     }
02262 
02263   case at_declrepr:
02264     {
02265       // reprSimp pass should have trnsformed this into a at_declunion
02266       assert(false);
02267       break;
02268     }
02269 
02270   case at_declunion:
02271   case at_declstruct:
02272     {
02273       shared_ptr<TSEnvironment > defGamma = gamma->newDefScope();
02274       ast->envs.gamma = defGamma;
02275 
02276       shared_ptr<AST> category = ast->child(2);
02277 
02278       bool isBoxedType = (category->astType == at_boxedCat);
02279 
02280       // match at_ident
02281       // FIX: (shap) Not convinced this is correct for opaque...
02282       TypeTag decl_ty;      
02283       switch(ast->astType) {
02284       case at_declunion:
02285         decl_ty = (isBoxedType ?  ty_unionr : ty_unionv);
02286         break;
02287       case at_declstruct:
02288         decl_ty = (isBoxedType ? ty_structr : ty_structv);
02289         break;
02290       default:
02291         die();
02292       }
02293 
02294       shared_ptr<AST> ident = ast->child(0);
02295       ident->symType = Type::make(decl_ty);
02296       ident->symType->defAst = ident;
02297       ident->symType->myContainer = ident;
02298       shared_ptr<TypeScheme> sigma = TypeScheme::make(ident->symType, ident,
02299                                                       TCConstraints::make());
02300 
02301       // match at_tvlist
02302       shared_ptr<AST> tvList = ast->child(1);
02303       CHKERR(errFree, InferTvList(errStream, tvList, defGamma, instEnv,
02304                                   impTypes, sigma->tcc, trail, DEF_MODE, 
02305                                   ti_flags | TI_TYP_EXP, ident->symType));
02306       ident->scheme = sigma;
02307 
02308       // Category keyword at position 2
02309       // Empty declares at position 3
02310       // Empty fields/ctors at position 4
02311 
02312       // Type all constraints
02313       shared_ptr<AST> constraints = ast->child(5);
02314       TYPEINFER(constraints, defGamma, instEnv, impTypes, 
02315                 sigma->tcc, trail, mode, TI_CONSTRAINT);
02316 
02317       // Add Ftvs so that they get generalized in future uses
02318       addTvsToSigma(errStream, tvList, sigma, trail); 
02319 
02320       // In case of value type definitions, mark all those  
02321       // type arguments that are candidiates for copy-compatibility.
02322       markCCC(ident->symType);
02323 
02324       // Solve current Predicates.
02325       CHKERR(errFree, sigma->solvePredicates(errStream, ident->loc,
02326                                              instEnv, trail)); 
02327 
02328       if (sigma->ftvs.size() && ast->getID()->externalName.size()) {
02329         errStream << ast->loc << ": Polymorphic declarations may not specify "
02330                   << "an external identifier."
02331                   << std::endl;
02332         errFree = false;
02333       }
02334     
02335       shared_ptr<TypeScheme> ts = gamma->getBinding(ident->s);
02336       if (ts) {
02337         ident->symType->defAst = ts->tau->getType()->defAst;
02338 
02339         CHKERR(errFree, matchDefDecl(errStream, trail, gamma, instEnv,
02340                                      ts, sigma, ti_flags));
02341       }
02342       else {
02343         defGamma->addBinding(ident->s, sigma);
02344         //         cout << "Added decl for " << ident->s 
02345         //              << " with  base = " 
02346         //           << &(*ident->symType->defAst)
02347         //              << std::endl;
02348       }
02349 
02350       ast->symType = ident->symType;
02351 
02352       gamma->mergeBindingsFrom(defGamma);
02353 
02354       break;
02355     }
02356 
02357   case at_proclaim:
02358     {
02359       /*--------------------------------------------
02360            A(x) = t1   U(t1 = t)
02361         _________________________
02362              A |- (proclaim x:t): t 
02363         
02364           x:t' notin A,  EXTEND A with x:t
02365         _______________________________
02366                   A |- (proclaim x:t): t 
02367         ------------------------------------------------*/
02368       
02369       // FIX Incompeteness Issue here
02370       shared_ptr<TSEnvironment > defGamma = gamma->newDefScope();
02371       ast->envs.gamma = defGamma;
02372 
02373       shared_ptr<TCConstraints> newTcc = TCConstraints::make();
02374       shared_ptr<AST> ident = ast->child(0);
02375       shared_ptr<AST> typ = ast->child(1);
02376       shared_ptr<AST> constraints = ast->child(2);
02377       assert(ident->isDecl);
02378 
02379       // WAS: newBindType() which had a maybe() around.
02380       ident->symType = newTvar();
02381       shared_ptr<TypeScheme> sigma = TypeScheme::make(ident->symType, ident);
02382       ident->scheme = sigma;
02383       
02384       TYPEINFER(typ, defGamma, instEnv, impTypes, newTcc,
02385                 trail, USE_MODE, ti_flags | TI_TYP_EXP);
02386       
02387       UNIFY(trail, ident->loc, ident->symType, typ->symType); 
02388       
02389       TYPEINFER(constraints, defGamma, instEnv, impTypes, 
02390                 newTcc, trail, mode, TI_CONSTRAINT);
02391       
02392       if (!errFree)
02393         break;
02394       
02395       sigma->tcc = newTcc;
02396       CHKERR(errFree, sigma->generalize(errStream, ast->loc, gamma,
02397                                         instEnv, ident, GC_NULL, trail,
02398                                         gen_top)); 
02399       
02400       if (!errFree) {
02401         errStream << ast->loc << ": Invalid Proclaimation"
02402                   << " The type specified could not be"
02403                   << " properly generalized."
02404                   << std::endl;
02405       }
02406       
02407       if (sigma->ftvs.size() && ast->getID()->externalName.size()) {
02408         errStream << ast->loc << ": Polymorphic declarations may not specify "
02409                   << "an external identifier."
02410                   << std::endl;
02411         errFree = false;
02412       }
02413 
02414       shared_ptr<TypeScheme> ts = gamma->getBinding(ident->s);
02415       if (ts) {
02416         ident->symType->defAst = ts->tau->getType()->defAst;
02417         CHKERR(errFree, matchDefDecl(errStream, trail, gamma, instEnv,
02418                                      ts, sigma, ti_flags));      
02419       }
02420       else {
02421         defGamma->addBinding(ident->s, sigma);
02422       }
02423       
02424       gamma->mergeBindingsFrom(defGamma);
02425       ast->symType = ident->symType;      
02426       break;
02427     }
02428 
02429   case at_deftypeclass:
02430     {
02431       shared_ptr<TSEnvironment > defGamma = gamma->newDefScope();
02432       ast->envs.gamma = defGamma;
02433 
02434       CHKERR(errFree, InferTypeClass(errStream, ast, defGamma, instEnv,
02435                                      impTypes, tcc, 
02436                                      trail, DEF_MODE, ti_flags));
02437       
02438       gamma->mergeBindingsFrom(defGamma);
02439       break;
02440     }
02441 
02442   case at_tcdecls:
02443   case at_tyfn:
02444   case at_method_decls:
02445   case at_method_decl:
02446     {
02447       assert(false);
02448       break;
02449     }
02450 
02451   case at_tcapp:
02452     {      
02453       shared_ptr<AST> tcIdent = ast->child(0);
02454       TYPEINFER(tcIdent, gamma, instEnv, impTypes, tcc,
02455                 trail, USE_MODE, 
02456                 ti_flags | TI_TYP_EXP | TI_TYP_APP);
02457       shared_ptr<Typeclass> tc = tcIdent->symType->getType();      
02458 
02459       if (tc->typeTag != ty_typeclass) {
02460         // This is the result of some other error
02461         errFree = false;
02462         break;
02463       }
02464 
02465       if (tc->typeArgs.size() == (ast->children.size() - 1)) {
02466         for (size_t i = 1; i < ast->children.size(); i++) {
02467           TYPEINFER(ast->child(i), gamma, instEnv, impTypes, tcc,
02468                     trail, USE_MODE, TI_NON_APP_TYPE);
02469           UNIFY(trail, ast->child(i)->loc,
02470                 ast->child(i)->symType, tc->TypeArg(i-1));
02471         }
02472       }
02473       else {
02474         errStream << ast->loc << ": "
02475                   << "Typeclass cannot be Partially "
02476                   << "or over instantiated. "
02477                   << "Typeclass " << tc->asString()
02478                   << " expects " << tc->typeArgs.size() 
02479                   << " args, but is here applied to "
02480                   << (ast->children.size() - 1) << "."
02481                   << std::endl;
02482       }
02483 
02484       /* Special Handling for the copy-compatibility constraint 
02485          The copy-compat type-class constraint is transformed into a
02486          unification constraint using maybe-types, and the constraint
02487          is immediately eliminated as solved. */ 
02488       const std::string& copy_compat =
02489         SpecialNames::spNames.sp_copy_compat;
02490       const std::string& copy_from_to =
02491         SpecialNames::spNames.sp_copy_from_to;
02492 
02493       if (tc->defAst->s == copy_compat) {
02494         shared_ptr<Type> tv = newTvar();
02495         UNIFY(trail, ast->child(1)->loc, 
02496               ast->child(1)->symType, MBF(tv));
02497         UNIFY(trail, ast->child(2)->loc,
02498               ast->child(2)->symType, MBF(tv));
02499         tcc->clearPred(tc);
02500       }
02501       else if (tc->defAst->s == copy_from_to) {
02502         shared_ptr<Type> tv = newTvar();
02503         UNIFY(trail, ast->child(1)->loc, 
02504               ast->child(1)->symType, MBF(tv));
02505         UNIFY(trail, ast->child(2)->loc,
02506               ast->child(2)->symType, MBF(tv));
02507         tcc->clearPred(tc);
02508       }
02509       
02510       ast->symType = tc;
02511       break;
02512     }
02513 
02514   case at_definstance:
02515     {
02516       CHKERR(errFree, InferInstance(errStream, ast, gamma, instEnv,
02517                                     impTypes, tcc, trail, 
02518                                     DEF_MODE, ti_flags));                                    
02519       break;
02520     }
02521 
02522   case at_defexception:
02523     {
02524       shared_ptr<AST> ctr = ast->child(0);
02525 
02526       // Maybe, we have a prior declaration?
02527       shared_ptr<TypeScheme> declTS = gamma->getBinding(ctr->s);
02528 
02529       shared_ptr<TSEnvironment > defGamma = gamma->newDefScope();
02530       ast->envs.gamma = defGamma;
02531 
02532       shared_ptr<TCConstraints> myTcc = TCConstraints::make();
02533 
02534       TYPEINFER(ctr, defGamma, instEnv, impTypes, myTcc, 
02535                 trail, DEF_MODE, ti_flags | TI_TYP_EXP);      
02536       
02537       shared_ptr<Type> exn = Type::make(ty_exn);
02538       exn->defAst = ctr;      
02539       ctr->symType->getType()->link = exn;
02540       shared_ptr<TypeScheme> sigma = ctr->scheme;
02541       sigma->tcc = myTcc;
02542       
02543       shared_ptr<Type> t = ctr->symType->getType();
02544 
02545       shared_ptr<AST> fields = ast->child(4);
02546       for (size_t c = 0; c < fields->children.size(); c++) {
02547         shared_ptr<AST> field = fields->child(c);        
02548 
02549         TYPEINFER(field, defGamma, instEnv, impTypes, 
02550                   sigma->tcc,
02551                   trail, USE_MODE, ti_flags | TI_TYP_EXP | TI_TYP_DEFN);
02552         shared_ptr<Type> t1 = field->child(1)->getType();
02553         t->components.push_back(comp::make(field->child(0)->s, t1));
02554       }
02555 
02556       // Build the structure type for the component structure.
02557       shared_ptr<Type> sType = Type::make(ty_structr);
02558       sType->defAst = ctr;
02559       for (size_t i=0; i < t->components.size(); i++)
02560         sType->components.push_back(comp::make(t->CompName(i),
02561                                           t->CompType(i)));
02562       
02563       ctr->stCtr = ctr;
02564       ctr->stSigma = TypeScheme::make(sType, ctr, sigma->tcc);
02565 
02566       // Solve current Predicates.
02567       CHKERR(errFree, sigma->solvePredicates(errStream, ast->loc,
02568                                              instEnv, trail)); 
02569 
02570       ast->symType = ctr->symType;
02571 
02572       gamma->mergeBindingsFrom(defGamma);
02573 
02574       if (declTS)
02575         CHKERR(errFree, matchDefDecl(errStream, trail, gamma, instEnv,
02576                                      declTS, sigma, ti_flags));        
02577       break;
02578     }
02579 
02580   case at_recdef:
02581   case at_define:
02582     {
02583       /*------------------------------------------------
02584                 t' = 'a|'b     [U(t = t')]
02585                          A |- e:t1    U(t1 = 'c|'b)        
02586           S = generalize(A, t', e)   EXTEND A with x:S
02587         _______________________________________________
02588                     A |- (define x:[t] = e): t'
02589 
02590 
02591                   t' = 'a|'b   [U(t = t')]
02592                 A, x:t' |- e:t1    U(t1 = 'c|'b)        
02593           S = generalize(A, t', e)   EXTEND A with x:S
02594         _______________________________________________
02595                     A |- (recdef x:[t] = e): t'
02596      ---------------------------------------------------*/
02597       // Maybe, we have a prior declaration?
02598       shared_ptr<AST> ident = ast->getID();
02599       shared_ptr<TypeScheme> declTS = gamma->getBinding(ident->s);
02600 
02601       shared_ptr<TSEnvironment > defGamma = gamma->newDefScope();
02602       ast->envs.gamma = defGamma;
02603 
02604       shared_ptr<TCConstraints> currTcc = TCConstraints::make();
02605 
02606 
02607       if(ast->child(0)->child(0)->s ==
02608          "_34../../tests/unit/FM.bitc#0:fm-poly#FN1SR0_2S2_5int32") {
02609         errStream << " Came Here " << std::endl;
02610         
02611       }
02612       
02613       if (ast->astType == at_recdef) {
02614         // match agt_bindingPattern
02615         // match agt_expr
02616         TYPEINFER(ast->child(0), defGamma, instEnv, impTypes, 
02617                   currTcc, trail, DEF_MODE, ti_flags);
02618       }
02619 
02620       TYPEINFER(ast->child(1), defGamma, instEnv, impTypes, 
02621                 currTcc, trail, USE_MODE, ti_flags);
02622       
02623       if (ast->astType == at_define) {
02624         // match agt_bindingPattern
02625         // match agt_expr
02626         TYPEINFER(ast->child(0), defGamma, instEnv, impTypes, 
02627                   currTcc, trail, DEF_MODE, ti_flags);
02628       }
02629 
02630       TYPEINFER(ast->child(2), defGamma, instEnv, impTypes, 
02631                 currTcc, trail, mode, TI_CONSTRAINT);
02632 
02633       shared_ptr<Type> idType = ident->symType;
02634       shared_ptr<Type> rhsType = ast->child(1)->symType;
02635       shared_ptr<TypeScheme> sigma = ident->scheme;
02636       sigma->tcc = currTcc;
02637 
02638       DEBUG(DEF_INF)
02639         errStream << "At define " << ident->asString() << ":"
02640                   << " LHS = " << idType->asString()
02641                   << " RHS = " << rhsType->asString()
02642                   << std::endl;
02643       
02644       UNIFY(trail, ast->child(1)->loc, 
02645             ast->child(1)->symType, MBF(ast->child(0)->symType));
02646       
02647       DEBUG(DEF_INF)
02648         errStream << "After Unification: " 
02649                   << ast->getID()->symType->asString()
02650                   << " LHS = " << idType->asString()
02651                   << " RHS = " << rhsType->asString()
02652                   << std::endl;            
02653 
02654       // Check the consistency of types wrt mutability at ALL asts
02655       // in this definition.
02656       if(errFree)
02657         CHKERR(errFree, CheckMutConsistency(errStream, ast));
02658 
02659       CHKERR(errFree, sigma->generalize(errStream, ast->loc, gamma,
02660                                         instEnv,  ast->child(1), GC_NULL, 
02661                                         trail, gen_top));
02662       DEBUG(DEF_INF)
02663         errStream << "After Generalization: " 
02664                   << ast->getID()->scheme->asString()
02665                   << std::endl << std::endl;
02666       
02667       gamma->mergeBindingsFrom(defGamma);
02668       
02669       if (declTS) 
02670         CHKERR(errFree, matchDefDecl(errStream, trail, gamma, instEnv,
02671                                      declTS, ident->scheme, ti_flags));
02672 
02673       ast->symType = ast->child(0)->symType;
02674       break;
02675     }
02676     
02677   case at_importAs:
02678     {
02679       shared_ptr<AST> ifAst = ast->child(0);
02680       shared_ptr<AST> idAst = ast->child(1);
02681 
02682       shared_ptr<TSEnvironment > tmpGamma = gamma->newScope();
02683       ast->envs.gamma = gamma;
02684       
02685       assert(idAst->envs.gamma);
02686       assert(idAst->envs.instEnv);
02687       
02688       useIFGamma(idAst->s, idAst->envs.gamma,
02689                  tmpGamma);
02690       useIFInsts(idAst->s, idAst->envs.instEnv, 
02691                  instEnv);
02692       
02693       gamma->mergeBindingsFrom(tmpGamma);
02694       break;
02695     }
02696 
02697   case at_provide:
02698     {
02699       // In the new at_provide scheme, at_provide does not imply any
02700       // import, so we probably should not be attempting any type
02701       // inference here anymore.
02702       break;
02703     }
02704 
02705   case at_import:
02706     {
02707       shared_ptr<TSEnvironment > tmpGamma = gamma->newScope();
02708       ast->envs.gamma = gamma;
02709 
02710       shared_ptr<AST> ifName = ast->child(0);
02711       
02712       assert(ifName->envs.gamma);
02713       assert(ifName->envs.instEnv);
02714       
02715       if (ast->children.size() == 1) {
02716         // This is an import-all form
02717         useIFGamma(std::string(), ifName->envs.gamma, tmpGamma);
02718         useIFInsts(std::string(), ifName->envs.instEnv, instEnv);
02719       }
02720       else {
02721         for (size_t c = 1; c < ast->children.size(); c++) {
02722           shared_ptr<AST> alias = ast->child(c);
02723           shared_ptr<AST> thisName = alias->child(0);
02724           shared_ptr<AST> thatName = alias->child(1);
02725         
02726           shared_ptr<TypeScheme> sigma = ifName->envs.gamma->getBinding(thatName->s);
02727         
02728           if (!sigma) {
02729             errStream << ast->loc << ": "
02730                       << " attempt to use " << thatName->s 
02731                       << ", which has an unknown, or buggy type"
02732                       << std::endl;
02733             errFree = false;
02734             break;
02735           }
02736           
02737           tmpGamma->addBinding(thisName->s, sigma);
02738           tmpGamma->setFlags(ast->child(0)->s, BF_PRIVATE);
02739         }
02740       }
02741       
02742       gamma->mergeBindingsFrom(tmpGamma);
02743       break;
02744     }
02745 
02746   case at_ifsel:
02747     {
02748       assert(false);
02749       break;
02750     }
02751 
02752   case at_declares:
02753     {
02754       ast->tagType = GC_NULL;
02755       
02756       // match at_declare*
02757       for (size_t c = 0; c < ast->children.size(); c++) {
02758          TYPEINFER(ast->child(c), gamma, instEnv, impTypes, tcc,
02759                   trail, mode, ti_flags);
02760         
02761         if (ast->child(c)->tagType) {
02762           if (!ast->tagType) {
02763             ast->tagType = ast->child(c)->tagType;
02764             ast->field_bits = ast->child(c)->field_bits;
02765           }
02766           else {
02767             errStream << ast->child(c)->loc << ": "
02768                       << "Only one tag type declaration "
02769                       << "is allowed per definition"
02770                       << std::endl;          
02771           }
02772         }
02773       }
02774       ast->symType = Type::make(ty_tvar);
02775       break;
02776     }
02777 
02778   case at_declare:
02779     {
02780       // match at_ident
02781       // The first identifier has special meaning, and must be 
02782       // dealt with by hand.
02783       shared_ptr<AST> ident = ast->child(0);      
02784       shared_ptr<AST> typ = ast->child(1);
02785 
02786       // match agt_type?
02787       if (ast->children.size() > 1) {
02788         TYPEINFER(typ, gamma, instEnv, impTypes, tcc,
02789                   trail,  USE_MODE, ti_flags);
02790 
02791       if (!typ->symType)
02792         typ->symType = Type::make(ty_tvar);
02793       }
02794 
02795       // These names are never mangled.
02796       if (ident->s == "tag") {
02797         // compatible type
02798         
02799         shared_ptr<Type> realType = ast->child(1)->symType->getType();
02800         shared_ptr<Type> t = realType->getBareType();        
02801         if (t->typeTag == ty_mutable) {
02802           errStream << ast->child(1)->loc << ": "
02803                     << "Tag type cannot be mutable"
02804                     << std::endl;
02805           errFree = false;
02806         }
02807         else if (!t->isInteger()) {
02808           errStream << ast->child(1)->loc << ": "
02809                     << "Tag type must be an integral type"
02810                     << std::endl;
02811           errFree = false;
02812           break;
02813         }
02814         else {
02815           ast->tagType = ast->child(1)->symType;
02816           ast->field_bits = ast->child(1)->field_bits;
02817         }          
02818       }
02819 
02820       ast->symType = Type::make(ty_tvar);
02821       break;
02822     }
02823 
02824   case at_tvlist:
02825     // match agt_tvar*
02826   case at_constructors:
02827     // match at_constructor+
02828   case at_constructor:
02829 
02830   case at_fields:
02831     // match at_field*
02832     break;
02833 
02834   case at_methdecl: 
02835     // Handling for at_methdecl is basically the same as for at_field.
02836     // However, note the a post-pass over structures  is made in
02837     // InferStruct to synthesize declarations for the functions
02838     // corresponding to each method.
02839   case at_field: 
02840     {
02841       // match at_ident
02842       shared_ptr<AST> fName = ast->child(0);
02843       fName->symType = Type::make(ty_tvar);
02844       
02845       // match agt_type
02846       shared_ptr<AST> fType = ast->child(1);
02847       TYPEINFER(fType, gamma, instEnv, impTypes, 
02848                 tcc, trail,  USE_MODE, 
02849                 ti_flags | TI_TYP_EXP | TI_TYP_DEFN);
02850       
02851       ast->symType = fType->symType;
02852       ast->field_bits = fType->field_bits;
02853       ast->child(0)->field_bits = fType->field_bits;
02854       break;
02855     }
02856 
02857   case at_fill:
02858     {      
02859       // match agt_type 
02860       shared_ptr<AST> fillType = ast->child(0);
02861       TYPEINFER(fillType, gamma, instEnv, impTypes, 
02862                 tcc, trail,  USE_MODE, 
02863                 ti_flags | TI_TYP_EXP | TI_TYP_DEFN);     
02864       ast->field_bits = fillType->field_bits;
02865   
02866       if(ast->children.size() == 2) {
02867         shared_ptr<AST> fillVal = ast->child(0);
02868         TYPEINFER(fillVal, gamma, instEnv, impTypes, 
02869                   tcc, trail,  USE_MODE, 
02870                   TI_TYP_EXP | TI_TYP_DEFN);     
02871       
02872         uint64_t val = fillVal->litValue.i.as_uint64();
02873         uint64_t maxVal = (((uint64_t)1) << fillType->nBits()) - 1;
02874       
02875         if (val > maxVal) {
02876           errStream << ast->loc << ": "
02877                     << "Not enough bits to store the reserved value"
02878                     << std::endl;
02879           errFree = false;
02880         }
02881       }
02882 
02883       ast->symType = ast->child(0)->symType;
02884       break;
02885     }
02886 
02887   case at_bitfieldType:
02888     {
02889       // match agt_type
02890       TYPEINFER(ast->child(0), gamma, instEnv, impTypes, tcc,
02891                 trail, mode, TI_NON_APP_TYPE);
02892       
02893       shared_ptr<AST> len = ast->child(1);
02894       len->symType = Type::make(ty_word);
02895       
02896       ast->symType = ast->child(0)->symType;
02897       ast->field_bits = len->litValue.i.as_uint32();
02898 
02899       if (!errFree)
02900         break;
02901 
02902       if (ast->field_bits > ast->symType->nBits()) {
02903         errStream << ast->loc << ": Invalid bitfield specification"
02904                   << "No. of bits requested = " << ast->field_bits
02905                   << ", Max available for type = "
02906                   << ast->symType->nBits()
02907                   << std::endl;
02908         errFree = false;
02909       }
02910 #ifdef KEEP_BF
02911       ast->symType = Type::make(ty_bitfield);
02912       ast->symType->components.push_back(comp::make(ast->child(0)->symType));
02913       // match at_intLiteral
02914       TYPEINFER(ast->child(1), gamma, instEnv, impTypes, tcc,
02915                 trail, mode, TI_EXPRESSION);
02916       
02917       ast->child(1)->symType = ast->child(1)->symType->getTheType();
02918 
02919       // FIX TO WORD
02920       CHKERR(errFree, unifyPrim(errStream, trail, ast->child(1), 
02921                                 ast->child(1)->symType, "word", gamma)); 
02922       char lenStr[mpz_sizeinbase(ast->child(1)->litValue.i, 10)];
02923       mpz_get_str(lenStr, 10, ast->child(1)->litValue.i);
02924       ast->symType->Isize = strtoull(lenStr, 0, 10);
02925 #endif
02926     
02927       break;
02928     }
02929 
02930     // The restriction that byref types can only appear on the
02931     // arguments of a function is enforced in the parser.
02932   case at_arrayRefType:
02933     {
02934       // match agt_type
02935       TYPEINFER(ast->child(0), gamma, instEnv, impTypes, tcc,
02936                 trail,  USE_MODE, TI_NON_APP_TYPE);
02937     
02938       shared_ptr<Type> t = ast->child(0)->getType();
02939     
02940       ast->symType = Type::make(ty_array_ref);
02941       ast->symType->components.push_back(comp::make(t));
02942     
02943       break;
02944     }
02945   case at_byRefType:
02946     {
02947       // match agt_type
02948       TYPEINFER(ast->child(0), gamma, instEnv, impTypes, tcc,
02949                 trail,  USE_MODE, TI_NON_APP_TYPE);
02950     
02951       shared_ptr<Type> t = ast->child(0)->getType();
02952     
02953       ast->symType = Type::make(ty_byref);
02954       ast->symType->components.push_back(comp::make(t));
02955     
02956       break;
02957     }
02958 
02959   case at_boxedType:
02960     {
02961       // match agt_type
02962       TYPEINFER(ast->child(0), gamma, instEnv, impTypes, tcc,
02963                 trail,  USE_MODE, TI_NON_APP_TYPE);
02964     
02965       shared_ptr<Type> t = ast->child(0)->getType();
02966     
02967       ast->symType = Type::make(ty_ref);
02968       ast->symType->components.push_back(comp::make(t));
02969     
02970       break;
02971     }
02972 
02973   case at_exceptionType:
02974     {
02975       ast->symType = Type::make(ty_exn);
02976       break;
02977     }
02978 
02979   case at_dummyType:
02980     {
02981       ast->symType = Type::make(ty_dummy);
02982       break;
02983     }
02984 
02985   case at_unboxedType:
02986     {
02987       ast->symType = Type::make(ty_tvar);
02988       
02989       // match agt_type
02990       TYPEINFER(ast->child(0), gamma, instEnv, impTypes, tcc,
02991                 trail,  USE_MODE, TI_NON_APP_TYPE);
02992       
02993       shared_ptr<Type> t1 = ast->child(0)->symType->getType();
02994       shared_ptr<Type> t = ast->child(0)->symType->getBareType();
02995       
02996       switch(t->typeTag) {
02997       case ty_tvar:
02998         {
02999           shared_ptr<Type> tvar = Type::make(ty_tvar);
03000           t->typeTag = ty_ref;          
03001           t->components.push_back(comp::make(tvar));
03002           ast->symType = tvar;
03003           break;
03004         }
03005 
03006       case ty_ref:
03007         {
03008           ast->symType = t->Base();
03009           break;
03010         }
03011 
03012 #ifdef DEADCODE
03013       case ty_vector:
03014         {
03015           errStream << ast->loc << ": Cannot dereference a "
03016                     << "vector type. Obtained: "
03017                     << t->asString()
03018                     << std::endl;
03019           errFree = false;
03020           break;
03021         }
03022 
03023       case ty_structr:
03024       case ty_unionr:
03025         {
03026           if (t->components.size() == 0) {
03027             errStream << ast->loc << ": "
03028                       << "Target of (val 'a) must be a defined type "
03029                       << "(not just declared)." 
03030                     << "But obtained" << t1->asString() << std::endl;
03031             errFree = false;
03032             break;
03033           }               
03034           else {
03035             ast->symType = t->getDCopy();
03036             ast->symType->typeTag = Type::getValTypeTag(t->typeTag);
03037           }
03038           break;
03039         }
03040         
03041       case ty_uconv: 
03042       case ty_uconr:
03043       case ty_uvalv: 
03044       case ty_uvalr:
03045         {        
03046           errStream << ast->loc << ": "
03047                     << "Target of a val should be a reference type." 
03048                     << " you cannot use a value constructor " 
03049                     << "(" << ast->child(0)->s << ") "
03050                     << "here, Use "
03051                     << "the union name."          
03052                     << std::endl;
03053           errFree = false;
03054           break;
03055         }
03056 #endif
03057         
03058       default:
03059         {
03060           errStream << ast->loc << ": "
03061                     << "Target of unbox should be a type of the form (ref 'a). " 
03062                     << " But obtained" << t1->asString() << std::endl;
03063           errFree = false;
03064           break;
03065         }
03066       }
03067       
03068       break;
03069     }    
03070 
03071   case at_methType:
03072   case at_fn:
03073     {
03074       TYPEINFER(ast->child(0), gamma, instEnv, impTypes, tcc,
03075                 trail, mode, TI_NON_APP_TYPE);
03076       TYPEINFER(ast->child(1), gamma, instEnv, impTypes, tcc,
03077                 trail, mode, TI_NON_APP_TYPE);
03078       
03079       ast->symType = Type::make((ast->astType == at_fn) ? ty_fn : ty_method);
03080       shared_ptr<Type> fnarg = ast->child(0)->symType->getType();
03081       shared_ptr<Type> ret = ast->child(1)->symType->getType();
03082       ast->symType->components.push_back(comp::make(fnarg));
03083       ast->symType->components.push_back(comp::make(ret));    
03084       break;
03085     }
03086 
03087   case at_fnargVec:
03088     {      
03089       shared_ptr<Type> fnarg = Type::make(ty_fnarg);
03090       for (size_t c = 0; c < ast->children.size(); c++) {
03091         shared_ptr<AST> arg = ast->child(c);
03092         TYPEINFER(arg, gamma, instEnv, impTypes, tcc,
03093                   trail, mode, TI_NON_APP_TYPE);
03094         shared_ptr<Type> argType = arg->symType->getType();
03095 
03096         shared_ptr<comp> nComp = comp::make(argType);        
03097         if (argType->isByrefType()) {
03098           nComp = comp::make(argType->Base());
03099           nComp->flags |= COMP_BYREF;
03100         }
03101 
03102         fnarg->components.push_back(nComp);
03103       }
03104       ast->symType = fnarg;
03105       break;
03106     }
03107 
03108   case at_primaryType:
03109     {
03110       ast->symType = Type::make(Type::LookupTypeTag(ast->s));
03111       break;
03112     }
03113 
03114   case at_fieldType:
03115     {
03116       shared_ptr<AST> fName = ast->child(0);
03117       shared_ptr<Type> ft = Type::make(ty_field);
03118       ft->litValue.s = fName->s;
03119       ast->symType = fName->symType = ft;
03120       break;
03121     }
03122 
03123   case at_arrayType:
03124     {
03125       // match agt_type
03126       TYPEINFER(ast->child(0), gamma, instEnv, impTypes, tcc,
03127                 trail, mode, TI_NON_APP_TYPE);
03128     
03129       shared_ptr<Type> arrType = Type::make(ty_array);
03130       ast->symType = arrType;
03131       arrType->components.push_back(comp::make(ast->child(0)->symType));
03132 
03133       // match at_intLiteral
03134       TYPEINFER(ast->child(1), gamma, instEnv, impTypes, tcc,
03135                 trail, mode, TI_NON_APP_TYPE);
03136  
03137       // FIX TO WORD
03138       CHKERR(errFree, unifyPrim(errStream, trail, ast->child(1)->loc, 
03139                                 ast->child(1)->symType, "word")); 
03140 
03141       arrType->arrLen->len = ast->child(1)->litValue.i.as_uint32();
03142       break;
03143     }
03144 
03145   case at_vectorType:
03146     {
03147       // match agt_type
03148       TYPEINFER(ast->child(0), gamma, instEnv, impTypes, tcc,
03149                 trail, mode, TI_NON_APP_TYPE);
03150     
03151       ast->symType = Type::make(ty_vector);
03152       ast->symType->components.push_back(comp::make(ast->child(0)->symType));
03153 
03154       break;
03155     }
03156      
03157   case at_mutableType:
03158     {
03159       // match agt_type
03160       TYPEINFER(ast->child(0), gamma, instEnv, impTypes, tcc,
03161                 trail,  USE_MODE, TI_NON_APP_TYPE);
03162     
03163       shared_ptr<Type> t = ast->child(0)->symType->getType();
03164       
03165       if (t->typeTag == ty_mutable) {
03166         //The Type is already mutable
03167         ast->symType = t;
03168       }
03169       if (t->isMaybe()) {
03170         assert(false);
03171       }
03172       else {
03173         ast->symType = Type::make(ty_mutable);
03174         ast->symType->components.push_back(comp::make(t));
03175       }
03176       break;
03177     }
03178 
03179   case at_constType:
03180     {
03181       // match agt_type
03182       TYPEINFER(ast->child(0), gamma, instEnv, impTypes, tcc,
03183                 trail,  USE_MODE, TI_NON_APP_TYPE);
03184       
03185       shared_ptr<Type> t = ast->child(0)->symType->getType();
03186 
03187       // If the inner type is already const, we are done.
03188       if (t->typeTag == ty_const) {
03189         ast->symType = t;
03190         break;
03191       }
03192       
03193       // To ensure completeness of inference, bare type variables cannot
03194       // occur within a const meta-constructor. They must only occur
03195       // within mbFull types. 
03196       //
03197       // For example:
03198       //
03199       // \x:ref(const('a)). \y.ref(const('b)). if true then x else y.
03200       // 
03201       // here, 'a gets unified with 'b, which leads to incompleteness,
03202       // and the expression 
03203       //
03204       // \x:ref(const('a)). \y.ref(const('b)). 
03205       //   (if true then x else y, (p:'a:bool, q:'b:(mutable bool)))
03206       // will fail to type check.
03207       //
03208       // We need to ensure that bare type variables do not occur at
03209       // any shallow position within a const type. For example,
03210       //
03211       // (const (pair 'a 'b)) must be turned into
03212       //
03213       // (const (pair 'a1|'a 'b1|'b) and NOT
03214       //
03215       // (const 'a|(pair 'a 'b))
03216       //
03217       // since unification under mutability minimization will fix 'a
03218       // and 'b without scope of mutability variance.
03219       //
03220       // The theoritical development does not have this probllem,
03221       // since pair types are correctly generated with appropriate
03222       // mbFull types. Here, since the type within the annotation is
03223       // programmer controlled, we must take extra care.
03224 
03225       
03226 
03227       const bool markOnly = ti_flags & TI_TYP_DEFN;
03228       t->ensureMinimizability(trail, markOnly);
03229 
03230       ast->symType = Type::make(ty_const);
03231       ast->symType->components.push_back(comp::make(t));
03232       break;
03233     }
03234 
03235   case at_typeapp:
03236     {
03237       // match agt_var 
03238       // match agt_tvar+
03239       ast->symType = Type::make(ty_tvar);
03240       TYPEINFER(ast->child(0), gamma, instEnv, impTypes, tcc,
03241                 trail,  USE_MODE,                 
03242                 ti_flags | TI_TYP_EXP | TI_TYP_APP);
03243     
03244       // Constructor cannot return a mutable type by default
03245       shared_ptr<Type> t = ast->child(0)->getType(); 
03246       shared_ptr<Type> realType = t;
03247       t = t->getBareType(); 
03248       
03249       if (t->typeTag != ty_structv && t->typeTag != ty_structr &&
03250          t->typeTag != ty_unionv && t->typeTag != ty_unionr) {
03251         
03252         if (t->typeTag == ty_uconv || t->typeTag == ty_uconr || 
03253            t->typeTag == ty_uvalv || t->typeTag == ty_uvalr) {
03254           
03255           errStream << ast->loc << ": "
03256                     << "cannot use a value constructor "
03257                     << "(" << ast->child(0)->s << ") "            
03258                     << "here, Use the "
03259                     << "union name."
03260                     << std::endl;
03261           errFree = false;
03262           break;
03263         }
03264 
03265         errStream << ast->child(0)->loc << ": "
03266                   << ast->child(0)->s << " cannot be resolved" 
03267                   << " to a structure or union type."
03268                   << " But obtained " 
03269                   << ast->child(0)->symType->asString()
03270                   << std::endl;
03271         
03272         errFree = false;
03273         break;
03274       }
03275       
03276       ast->symType = realType;
03277       
03278       shared_ptr<Type> sut = t;
03279       
03280       if ((ast->children.size()-1) != sut->typeArgs.size()) {
03281         errStream << ast->child(0)->loc << ": "
03282                   << ast->child(0)->s << " - Type cannot be" 
03283                   << " partially/over instantiated" 
03284                   << " For type " << sut->asString()
03285                   << ", " << sut->typeArgs.size()
03286                   << " arguments are needed. But "
03287                   << ast->children.size() -1
03288                   << " were provided."
03289                   << std::endl;
03290         errFree = false;
03291       }
03292       else { 
03293         for (size_t i=0; i < sut->typeArgs.size(); i++) {
03294           TYPEINFER(ast->child(i+1), gamma, instEnv, impTypes, tcc,
03295                     trail,  USE_MODE, TI_NON_APP_TYPE);
03296           
03297           UNIFY(trail, ast->child(i+1)->loc, 
03298                 ast->child(i+1)->symType, sut->TypeArg(i));
03299         }
03300       }
03301       
03302       break;
03303     }
03304 
03305   case at_qualType:
03306     {
03307       TYPEINFER(ast->child(0), gamma, instEnv, impTypes, tcc,
03308                 trail, mode, TI_CONSTRAINT);
03309       TYPEINFER(ast->child(1), gamma, instEnv, impTypes, tcc,
03310                 trail, mode, TI_NON_APP_TYPE);
03311       ast->symType = ast->child(1)->symType;
03312       break;
03313     }
03314 
03315   case at_constraints:
03316     {
03317       for (size_t c=0; c < ast->children.size(); c++)      
03318         TYPEINFER(ast->child(c), gamma, instEnv, impTypes, tcc,
03319                   trail, mode, TI_CONSTRAINT);
03320       ast->symType = Type::make(ty_tvar);
03321       break;
03322     }    
03323 
03324   case at_identPattern:
03325     {
03326       // match agt_var
03327       TYPEINFER(ast->child(0), gamma, instEnv, impTypes, tcc,
03328                 trail, mode, TI_EXPRESSION);
03329       
03330       
03331       // Type Qualifications ONLY in Binding Patterns
03332       // match agt_type?
03333       if (ast->children.size() > 1) {
03334         TYPEINFER(ast->child(1), gamma, instEnv, impTypes, tcc,
03335                   trail,  USE_MODE, TI_NON_APP_TYPE);
03336       
03337         if (ast->child(1)->symType->isByrefType()) {
03338           UNIFY(trail, ast->child(0)->loc, 
03339                 ast->child(0)->symType, ast->child(1)->getType()->Base());
03340         }
03341         else {
03342           UNIFY(trail, ast->child(0)->loc, 
03343                 ast->child(0)->symType, ast->child(1)->symType);
03344         }
03345         
03346         // Very Important that we pick the type of 
03347         // the qualification, in light of by-ref types.
03348         ast->symType = ast->child(1)->symType;
03349       }
03350       else {
03351         ast->symType = ast->child(0)->symType;
03352       }
03353       
03354       break;
03355     }
03356 
03357   case at_typeAnnotation:
03358     {
03359       /*------------------------------------------------
03360               A |- e:t1  U(t = t1)
03361           ______________________________
03362                 A |- (e:t): t
03363         ------------------------------------------------*/
03364       // match agt_eform
03365       TYPEINFER(ast->child(0), gamma, instEnv, impTypes, tcc,
03366                 trail,  USE_MODE, TI_EXPRESSION);
03367     
03368       TYPEINFER(ast->child(1), gamma, instEnv, impTypes, tcc,
03369                 trail,  USE_MODE, TI_NON_APP_TYPE);
03370 
03371       CHKERR(errFree, CheckMutConsistency(errStream,
03372                                           ast->child(1)->loc,
03373                                           ast->child(1)->symType));
03374       
03375       // tqExpr: U(t1 == t2)
03376       UNIFY(trail, ast->child(1)->loc, 
03377             ast->child(0)->symType, ast->child(1)->symType);
03378 
03379       ast->symType = ast->child(0)->symType;
03380       break;
03381     }
03382     
03383   case at_suspend:
03384     {
03385       // match agt_eform
03386       TYPEINFER(ast->child(0), gamma, instEnv, impTypes, tcc,
03387                 trail,  USE_MODE, TI_EXPRESSION);
03388 
03389       TYPEINFER(ast->child(1), gamma, instEnv, impTypes, tcc,
03390                 trail,  USE_MODE, TI_EXPRESSION);
03391       
03392       ast->symType = ast->child(1)->symType;
03393       break;
03394     }
03395 
03396   case at_unit:
03397     {
03398       /*------------------------------------------------
03399           ___________________________________________
03400               A |- unit: ()
03401         ------------------------------------------------*/
03402       ast->symType = Type::make(ty_unit);
03403       break;
03404     }
03405 
03406   case at_letGather:
03407     {
03408       /*------------------------------------------------
03409                  A |- e1:t1  ...  A |- en:tn 
03410           ___________________________________________
03411               A |- (let-gather e1 ... en): (t1, ..., tn)
03412         ------------------------------------------------*/
03413 
03414       ast->symType = Type::make(ty_letGather);
03415       shared_ptr<Type> gatherType = ast->symType->getBareType();
03416 
03417       for (size_t c=0; c < ast->children.size(); c++) {
03418         TYPEINFER(ast->child(c), gamma, instEnv, impTypes, tcc,
03419                   trail, mode, TI_EXPRESSION);
03420       
03421         gatherType->components.push_back(comp::make(ast->child(c)->symType));
03422       }
03423       break;
03424     }
03425 
03426 
03427   case at_mkArrayRef:
03428     {
03429       /*------------------------------------------------
03430                  A |- e:t  U(t = 'w|(array 'a ?))
03431           _________________________________________________
03432             A |- (make-array-byref e): (array-byref 'a)
03433         ------------------------------------------------*/
03434       // match agt_expr
03435       shared_ptr<AST> arg = ast->child(0);
03436 
03437       // Usually, the type of the child is always inferred because 
03438       // at_maArrayByref is constructed from at_apply case after
03439       // observing the type of the argument
03440       if(!arg->symType)
03441         TYPEINFER(arg, gamma, instEnv, impTypes, tcc,
03442                   trail,  USE_MODE, TI_EXPRESSION);
03443       
03444       shared_ptr<Type> var = Type::make(ty_tvar);
03445       shared_ptr<Type> arr = Type::make(ty_array, var);
03446       
03447       UNIFY(trail, arg->loc, arg->symType, MBF(arr));
03448       if(errFree)
03449         ast->symType = Type::make(ty_array_ref, arr->Base());
03450       else
03451         ast->symType = Type::make(ty_tvar);
03452       
03453       break;
03454     }
03455 
03456   case at_MakeVector:
03457     {
03458       /*------------------------------------------------
03459                  A |- en:tn  U(tn =  'w|word)
03460                  A |- el:tl  U(tl = 'f|('a|word -> 'b|'c))
03461                        tv = vector('d|'c)              
03462           ___________________________________________
03463                 A |- (make-vector en el): tv
03464         ------------------------------------------------*/
03465 
03466       // match agt_expr
03467       TYPEINFER(ast->child(0), gamma, instEnv, impTypes, tcc,
03468                 trail,  USE_MODE, TI_EXPRESSION);
03469       // FIX TO WORD
03470       UNIFY(trail, ast->child(0)->loc, 
03471             ast->child(0)->symType, MBF(Type::make(ty_word)));
03472 
03473       // match agt_expr
03474       TYPEINFER(ast->child(1), gamma, instEnv, impTypes, tcc,
03475                 trail,  USE_MODE, TI_EXPRESSION);
03476 
03477       // Build a type that I expect the second argument to be, and
03478       // unify with it.
03479       // Thee type of the function that builds the vector
03480       // is built as:
03481       // (fn ('a|word) 'b|'c)
03482       shared_ptr<Type> wordType = MBF(Type::make(ty_word));
03483       shared_ptr<Type> arg = Type::make(ty_fnarg, wordType);
03484       shared_ptr<Type> ret = MBF(newTvar());
03485       shared_ptr<Type> fnType = MBF(Type::make(ty_fn, arg, ret));
03486       
03487       UNIFY(trail, ast->child(1)->loc, 
03488             ast->child(1)->symType, fnType);
03489       
03490       CHKERR(errFree, testNonEscaping(errStream, ast, ret));
03491 
03492       ast->symType = Type::make(ty_vector, MBF(ret));
03493       break;
03494     }
03495 
03496   case at_array:
03497   case at_vector:
03498     {
03499     /*------------------------------------------------
03500                 A |- e1: t1 ... A |- en: tn
03501              U(t1 = 'a1|'b) ... U(tn = 'an|'b)
03502           _________________________________________
03503              A |- (array e1 ... en): array('a|'b, n)
03504 
03505 
03506                 A |- e1: t1 ... A |- en: tn
03507              U(t1 = 'a1|'b) ... U(tn = 'an|'b)
03508           _________________________________________
03509              A |- (vector e1 ... en): vector('a|'b)
03510        ------------------------------------------------*/
03511 
03512       TypeTag ttag = (ast->astType == at_array) ? ty_array : ty_vector;
03513       shared_ptr<Type> compType = MBF(newTvar());
03514       ast->symType = Type::make(ttag, compType);
03515       if(ttag == ty_array)
03516         ast->symType->arrLen->len = ast->children.size();
03517       
03518       // match agt_expr+
03519       for (size_t c = 0; c < ast->children.size(); c++) {
03520         shared_ptr<AST> expr = ast->child(c);
03521         TYPEINFER(expr, gamma, instEnv, impTypes, tcc,
03522                   trail,  USE_MODE, TI_EXPRESSION);
03523         
03524         CHKERR(errFree, testNonEscaping(errStream, expr,
03525                                         expr->symType)); 
03526         
03527         UNIFY(trail, expr->loc, expr->symType, MBF(compType));
03528       }
03529       
03530       break;
03531     }
03532 
03533 #ifdef HAVE_INDEXABLE_LENGTH_OPS
03534   case at_array_length:
03535   case at_array_ref_length:
03536   case at_vector_length:
03537     {
03538     /*------------------------------------------------
03539              A |- e: t   U(t = 'a|array('c|'b, ?len))
03540           _________________________________________
03541              A |- (array-length e): word
03542 
03543 
03544              A |- e: t   U(t = 'a|array-ref('c|'b))
03545           _________________________________________
03546              A |- (array-ref-length e): word
03547 
03548              A |- e: t   U(t = 'a|vector('c|'b))
03549           _________________________________________
03550              A |- (vector-length e): word
03551        ------------------------------------------------*/
03552       TypeTag ttag = ((ast->astType == at_array_length) ? ty_array :
03553                 ((ast->astType == at_array_ref_length) ? ty_array_ref :
03554                  ty_vector));
03555       
03556       // match agt_expr
03557       TYPEINFER(ast->child(0), gamma, instEnv, impTypes, tcc,
03558                 trail,  USE_MODE, TI_EXPRESSION);
03559       
03560       shared_ptr<Type> av = MBF(Type::make(k, MBF(newTvar())));
03561       if (ast->astType == at_array_length)
03562         impTypes[av] = ast->child(0);
03563 
03564       UNIFY(trail, ast->child(0)->loc, ast->child(0)->symType, av);
03565  
03566       // FIX TO WORD, not mutable
03567       ast->symType = Type::make(ty_word);
03568       break;    
03569     }
03570 #endif
03571 
03572   case at_array_nth:
03573   case at_array_ref_nth:
03574   case at_vector_nth:
03575   case at_nth:
03576     {
03577       /* Shap: Canonical form in array types must be preserved. It's
03578        * either (array T) or (mutable (array (mutable T))). The
03579        * "mutable" in both cases expresses top-level mutability.
03580        *
03581        * In the type rules, ! is the half downarrow (left harpoon),
03582        * while | is the full downarrow (harpoon). ! signals
03583        * introduction of possible top-level mutability, while |
03584        * signals introduction of possible full (up-to-ref) mutability.
03585        *
03586        * In this case, the vector case could be written as either ! or
03587        * |, because there isn't any "deep" mutability in a ref, so
03588        * there isn't really a difference. The type rule below was
03589        * originally written as
03590        *
03591        *     A |- e: t   U(t = 'a|vector('b|'c))
03592        *     A |- en: tn  U(tn = 'd|word)
03593        *  _________________________________________
03594        *     A |- (vector-nth e en): 'b|'c
03595        *
03596        * but the implementation always used MBT. Since it doesn't
03597        * matter, shap updated the type rule to use !
03598        */
03599 
03600       /*------------------------------------------------
03601              A |- e: t   U(t = 'a!array('b|'c, ?len))
03602              A |- en: tn  U(tn = 'd|word)
03603           _________________________________________
03604              A |- (array-nth e en): 'b|'c
03605 
03606              A |- e: t   U(t = 'a!array-ref('b|'c))
03607              A |- en: tn  U(tn = 'd|word)
03608           _________________________________________
03609              A |- (array-ref-nth e en): 'b|'c
03610 
03611              A |- e: t   U(t = 'a!vector('b|'c))
03612              A |- en: tn  U(tn = 'd|word)
03613           _________________________________________
03614              A |- (vector-nth e en): 'b|'c
03615 
03616           !! Note that at_nth is a kludge that will be
03617           !! rewritten in-place here to one of the cases above.
03618        ------------------------------------------------*/
03619       TYPEINFER(ast->child(0), gamma, instEnv, impTypes, tcc,
03620                 trail,  USE_MODE, TI_EXPRESSION);
03621 
03622       // Type-directed inference here for at_nth. If a type is already
03623       // known (either through declaration or previous inference), and
03624       // it is a type that is compatible with the indexing operation,
03625       // whack the AST type to match and then behave as if we had that
03626       // AST type in the first place. We whack the AST type so that
03627       // later passes don't need to deal with this issue at all.
03628       //
03629       // This is unquestionably a kludge, and an ugly one at that.
03630 
03631       if (ast->astType == at_nth) {
03632         shared_ptr<Type> t = ast->child(0)->symType->getBareType();
03633         switch(t->typeTag) {
03634         case ty_array_ref:
03635           ast->astType = at_array_ref_nth;
03636           break;
03637         case ty_array:
03638           ast->astType = at_array_nth;
03639           break;
03640         case ty_vector:
03641         default:
03642           // In the absence of an already-defined type, it's
03643           // presumptively a vector.
03644           ast->astType = at_vector_nth;
03645           break;
03646         }
03647       }
03648 
03649       shared_ptr<Type> av = GC_NULL;
03650       shared_ptr<Type> cmp = MBF(newTvar());
03651       TypeTag ttag = ((ast->astType == at_array_nth) ? ty_array :
03652                 ((ast->astType == at_array_ref_nth) ? ty_array_ref :
03653                  ty_vector));
03654       
03655       av = MBT(Type::make(ttag, cmp));
03656       if (ast->astType == at_array_nth)
03657         impTypes[av] = ast->child(0);
03658       
03659       UNIFY(trail, ast->child(0)->loc, ast->child(0)->symType, av);
03660       
03661       TYPEINFER(ast->child(1), gamma, instEnv, impTypes, tcc,
03662                 trail,  USE_MODE, TI_EXPRESSION);
03663 
03664       // FIX TO WORD
03665       UNIFY(trail, ast->child(1)->loc, 
03666             ast->child(1)->symType, MBF(Type::make(ty_word)));
03667 
03668       ast->symType = cmp;
03669       break;
03670     }
03671 
03672   case at_labeledBlock:
03673     {
03674     /*------------------------------------------------
03675               A |- x: 'a|'b   A |- e: t
03676                     U(t = 'c|'b)
03677           _________________________________________
03678                  A |- (block x e): 'd|'b
03679        ------------------------------------------------*/
03680 
03681       TYPEINFER(ast->child(0), gamma, instEnv, impTypes, tcc,
03682                 trail,  DEF_MODE, ti_flags);
03683       TYPEINFER(ast->child(1), gamma, instEnv, impTypes, tcc,
03684                 trail,  USE_MODE, TI_EXPRESSION);
03685 
03686       UNIFY(trail, ast->child(0)->loc,
03687             ast->child(0)->symType, MBF(ast->child(1)->symType));  
03688       
03689       ast->symType = MBF(ast->child(1)->symType);
03690       break;
03691     }
03692 
03693   case at_return_from:
03694     {
03695     /*------------------------------------------------
03696                 A(x) = tx   A |- e: t
03697               U(tx = 'a|'b)   U('c|'b)
03698           _________________________________________
03699                  A |- (return-from x e): 'd
03700        ------------------------------------------------*/
03701 
03702       TYPEINFER(ast->child(0), gamma, instEnv, impTypes, tcc,
03703                 trail,  USE_MODE, TI_EXPRESSION);
03704       TYPEINFER(ast->child(1), gamma, instEnv, impTypes, tcc,
03705                 trail,  USE_MODE, TI_EXPRESSION);
03706 
03707       UNIFY(trail, ast->child(0)->loc,
03708             ast->child(0)->symType, MBF(ast->child(1)->symType));  
03709       
03710       // Not returning, so don't really care about return type, but it
03711       // needs to unify compatibly in various other situations, so
03712       // generate a new tyep variable.
03713       ast->symType = newTvar();    
03714       break;
03715     }
03716 
03717   case at_begin:
03718     {
03719     /*------------------------------------------------
03720              A |- e1: t1 ... A |- en: tn
03721           _________________________________________
03722              A |- (begin e1 ... en): tn
03723 
03724 
03725              (empty)
03726           _________________________________________
03727              A |- (begin): ()
03728 
03729        ------------------------------------------------*/
03730       // match agt_expr*
03731       for (size_t c = 0; c < ast->children.size(); c++)
03732         TYPEINFER(ast->child(c), gamma, instEnv, impTypes, tcc,
03733                   trail,  USE_MODE, TI_EXPRESSION);
03734       
03735       
03736       if (ast->children.size())
03737         ast->symType = ast->child(ast->children.size()-1)->symType;
03738       else
03739         ast->symType = Type::make(ty_unit);
03740       break;
03741     }
03742 
03743   case at_select:
03744     {
03745       /*
03746        * A is the environment. "r" is the name of the record whose
03747        * field we are looking up. "tr" is the type of the record.
03748        * What d' does is provide a placeholder where we determine the
03749        * top-level mutability of the record as a whole OR the
03750        * reference that names it.
03751        */
03752 
03753       /*------------------------------------------------
03754                 A(r) = ['a1.. 'am] {... fld:t ... }  
03755           A |- e: tr     tr' = 'd!r('c1|'b1, ... 'c1|'bm)
03756                  U(tr = tr')   tf = tr'.fld
03757             _________________________________________
03758                     A |- e.fld: tf
03759 
03760                             A |- e:'a    
03761          ___________________________________________________
03762             A |- e.fld: 'b \ HasField('a, field(fld), 'b)
03763 
03764          ------------------------------------------------*/
03765 
03766       // match agt_expr 
03767       /* Selection is only permitted on 
03768          - structures: for selecting field or method
03769          - union values: determining tag (need to convert it to at_sel_ctr)
03770          Note that selection for fqn-naming a union constructor
03771          is already handled by the symbol resolver pass  */
03772       ast->symType = Type::make(ty_tvar); 
03773       TYPEINFER(ast->child(0), gamma, instEnv, impTypes, tcc,
03774                 trail,  USE_MODE, TI_EXPRESSION);
03775             
03776       shared_ptr<Type> t = ast->child(0)->symType->getType();
03777       shared_ptr<Type> t1 = t->getBareType();
03778       
03779       if (t1->isUType()) {
03780         ast->astType = at_sel_ctr;
03781         TYPEINFER(ast, gamma, instEnv, impTypes, tcc,
03782                   trail, USE_MODE, TI_EXPRESSION);
03783         break;
03784       }
03785 
03786       if(t1->isTvar() && !Options::noPrelude) {
03787 
03788         if (ti_flags & TI_NO_MORE_TC) {
03789           ast->symType = Type::make(ty_tvar);
03790           break;
03791         }
03792         
03793         const std::string& hasFld = SpecialNames::spNames.sp_has_field;
03794         shared_ptr<TypeScheme> hfSigma = gamma->getBinding(hasFld);
03795         assert(hfSigma);
03796         
03797         shared_ptr<Typeclass> hf = hfSigma->type_instance();
03798         assert(hf->typeArgs.size() == 3);
03799         
03800         shared_ptr<Type> fldName = Type::make(ty_field);
03801         fldName->litValue.s = ast->child(1)->s;
03802 
03803         // HasField constraint is of the form:
03804         // HasField('structure, 'field-name, 'field-type)
03805         UNIFY(trail, ast->loc, hf->TypeArg(0), t1);
03806         UNIFY(trail, ast->loc, hf->TypeArg(1), fldName);
03807         UNIFY(trail, ast->loc, hf->TypeArg(2), ast->symType);
03808 
03809         tcc->addPred(hf);
03810         break;
03811       }
03812       
03813       // If it is one of the "by courtesy" fields, then we are trivially
03814       // done:
03815       if (t1->isIndexableType() && ast->child(1)->s == "length") {
03816         // Note: NOT mutable word. The length pseudo-field is constant!
03817         ast->symType = Type::make(ty_word);
03818         ast->child(1)->symType = Type::make(ty_word);
03819         // UNIFY(trail, ast->child(1)->loc, ast->child(1)->symType, ast->symType);
03820         break;
03821       }
03822 
03823       if (t1->typeTag != ty_structv && t1->typeTag != ty_structr) {
03824         errStream << ast->child(0)->loc << ": "
03825                   << ast->child(0)->s << " has type "
03826                   << t1->asString() << " which does not have fields."
03827                   << std::endl;
03828         errFree = false;
03829         break;
03830       }
03831       
03832       shared_ptr<TypeScheme> stScheme;
03833       if (t1->defAst->symType->isULeg() ||
03834          t1->defAst->symType->isException()) 
03835         stScheme = t1->defAst->stSigma;
03836       else
03837         stScheme = t1->defAst->scheme;
03838       
03839       shared_ptr<Type> tr = stScheme->type_instance();
03840 
03841       if (tr->isValType())
03842         for (size_t i=0; i < tr->typeArgs.size(); i++) {
03843           shared_ptr<Type> arg = tr->TypeArg(i)->getType();
03844           if (tr->argCCOK(i))
03845             trail->subst(arg, MBF(newTvar()));
03846         }
03847       
03848       // MBT because the record or the reference *might* be mutable.
03849       shared_ptr<Type> trt = MBT(tr);
03850 
03851       UNIFY(trail, ast->child(0)->loc, t, trt);
03852       
03853       shared_ptr<Type> fld;
03854       CHKERR(errFree, findComponent(errStream, tr, ast, fld, ti_flags & TI_METHOD_OK));
03855       if (errFree)
03856         ast->symType = fld;
03857       
03858       break;
03859     }
03860 
03861   case at_fqCtr:
03862     {
03863       /*------------------------------------------------
03864            A(v) = ['a1.. 'am] ... | Ctr{...} | ...
03865           _________________________________________
03866                   A |- v.Ctr:t
03867        ------------------------------------------------*/
03868 
03869 
03870       TYPEINFER(ast->child(0), gamma, instEnv, impTypes, tcc,
03871                 trail,  USE_MODE, TI_EXPRESSION);
03872       
03873       shared_ptr<Type> t1 = ast->child(0)->symType->getBareType();
03874       if (!t1->isUType()) {
03875         errStream << ast->child(0)->loc << ": "
03876                   << ast->child(0)->s << " cannot be resolved" 
03877                   << " to a union, or exception type." 
03878                   << " but obtained " << t1->asString() 
03879                   << std::endl;
03880         errFree = false;
03881         break;
03882       }
03883       
03884       shared_ptr<Type> fct;
03885       CHKERR(errFree, findComponent(errStream, t1, ast, fct));
03886       
03887       if (!errFree) {
03888         ast->symType = Type::make(ty_tvar); 
03889         break;
03890       }
03891       
03892       ast->child(1)->symbolDef = fct->defAst;          
03893       ast->child(1)->flags |= fct->defAst->flags;
03894       ast->child(1)->flags |= fct->defAst->flags;
03895       ast->child(1)->symType = fct;
03896       ast->symType = ast->child(1)->symType;
03897       break;
03898     }
03899     
03900   case at_sel_ctr:
03901     {
03902       /*------------------------------------------------
03903            A(v) = ['a1.. 'am] ... | Ctr{...} | ...
03904             tv = v(...) or mutable(v(...)) or 'a!v(...)
03905                       A |- e:tv  
03906           _________________________________________
03907                   A |- e.Ctr:bool
03908        ------------------------------------------------*/
03909 
03910       TYPEINFER(ast->child(0), gamma, instEnv, impTypes, tcc,
03911                 trail,  USE_MODE, TI_EXPRESSION);
03912 
03913       shared_ptr<Type> t1 = ast->child(0)->symType->getBareType();
03914       if (!t1->isUType()) {
03915         errStream << ast->child(0)->loc << ": "
03916                   << ast->child(0)->s << " cannot be resolved" 
03917                   << " to a union, or exception type." 
03918                   << " but obtained " << t1->asString() 
03919                   << std::endl;
03920         errFree = false;
03921         break;
03922       }
03923 
03924       ast->symType = Type::make(ty_bool);
03925       
03926       shared_ptr<Type> fct;
03927       CHKERR(errFree, findComponent(errStream, t1, ast, fct));
03928       if (!errFree)
03929         break;
03930       
03931       ast->child(1)->symbolDef = fct->defAst;          
03932       ast->child(1)->flags |= fct->defAst->flags;
03933       ast->child(1)->flags |= fct->defAst->flags;
03934       ast->child(1)->symType = fct;
03935       break;
03936     }
03937     
03938   case at_lambda:
03939     {
03940       /*------------------------------------------------
03941               [U(t1 = 'b1|'a1)] ... [U(tn = 'bn|'an)]
03942              A, x1:'b1|'a1 ... xn:'bn|'an |- e: tr
03943            t1' = IF (t1 = byref(t1'') THEN t1 ELSE 'c1|'a1
03944                               ...
03945            tn' = IF (tn = byref(tn'') THEN tn ELSE 'cn|'an
03946                            U(tr = 'd|'g)
03947        _____________________________________________________________
03948        A |- (lambda (x1[:t1] ... xn[:tn]) e): (t1' ... tn') -> 'h|'g
03949        ------------------------------------------------*/
03950 
03951       // match agt_bindingPattern
03952       // match agt_expr
03953       shared_ptr<TSEnvironment > lamGamma = gamma->newScope();
03954       ast->envs.gamma = lamGamma;
03955       
03956       shared_ptr<AST> argVec = ast->child(0);
03957       shared_ptr<Type> fnarg = Type::make(ty_fnarg);
03958       argVec->symType = fnarg;      
03959       
03960       for (size_t c = 0; c < argVec->children.size(); c++) {
03961         TYPEINFER(argVec->child(c), lamGamma, instEnv, impTypes, 
03962                   tcc, trail,  DEF_MODE, TI_EXPRESSION);
03963 
03964         shared_ptr<Type> argType = argVec->child(c)->getType();
03965         shared_ptr<comp> nComp = GC_NULL;
03966         if (argType->isByrefType()) {
03967           nComp = comp::make(argType->Base());
03968           nComp->flags |= COMP_BYREF;
03969         }
03970         else {
03971           nComp = comp::make(MBF(argType));
03972         }
03973         
03974         fnarg->components.push_back(nComp);
03975       }
03976 
03977       TYPEINFER(ast->child(1), lamGamma, instEnv, impTypes, 
03978                 tcc, trail,  USE_MODE, TI_EXPRESSION);
03979       UNIFY(trail, ast->child(1)->loc, 
03980             ast->child(1)->symType, MBF(newTvar()));
03981       
03982       shared_ptr<Type> retType = MBF(ast->child(1)->getType());
03983       ast->symType = Type::make(ty_fn, fnarg, retType);      
03984       break;
03985     }
03986 
03987   case at_argVec:
03988     {
03989       assert(false);
03990       break;
03991     }
03992 
03993   case at_allocREF:
03994     {
03995       /*------------------------------------------------
03996                     A |- e:t
03997           __________________________
03998               A |- (alloc-ref e): t
03999        ------------------------------------------------*/
04000       TYPEINFER(ast->child(0), gamma, instEnv, impTypes, tcc,
04001                 trail, USE_MODE, TI_NON_APP_TYPE);
04002       ast->symType = ast->child(0)->symType;
04003       break;
04004     }
04005     
04006   case at_copyREF:
04007     {
04008        /*------------------------------------------------
04009             A |- e1:t1   A |- e2:t2    U(t1 = t2)
04010           ___________________________________________
04011               A |- (copy-ref e1 e2): ()
04012        ------------------------------------------------*/
04013       shared_ptr<AST> lhs = ast->child(0);
04014       shared_ptr<AST> rhs = ast->child(1);
04015 
04016       TYPEINFER(lhs, gamma, instEnv, impTypes, tcc,
04017                 trail, USE_MODE, TI_EXPRESSION);
04018       TYPEINFER(rhs, gamma, instEnv, impTypes, tcc,
04019                 trail, USE_MODE, TI_EXPRESSION);
04020       
04021       UNIFY(trail, lhs->loc, lhs->symType, rhs->symType);
04022       
04023       ast->symType =  Type::make(ty_unit);
04024       break;      
04025     }
04026 
04027   case at_mkClosure:
04028     {
04029        /*------------------------------------------------
04030              mkclosure: TODO
04031        ------------------------------------------------*/
04032 
04033       shared_ptr<AST> clEnv = ast->child(0);
04034       // Type check the closure structure apply
04035       TYPEINFER(clEnv, gamma, instEnv, impTypes, tcc,
04036                 trail,  USE_MODE, TI_EXPRESSION);
04037       
04038       shared_ptr<AST> thisLambda = ast->child(1);
04039       // Type check the lambda forms
04040       TYPEINFER(thisLambda, gamma, instEnv, impTypes, tcc,
04041                 trail, USE_MODE, TI_EXPRESSION);
04042       
04043       shared_ptr<Type> fullClFnType = thisLambda->symType->getType();
04044       shared_ptr<Type> clFnType = fullClFnType->getBareType();
04045       assert(clFnType->isFnxn());
04046       shared_ptr<Type> args = clFnType->Args()->getType();
04047       assert(args->components.size() >= 1);
04048       shared_ptr<Type> clArg = args->CompType(0);
04049       // Make sure we have the right env on all the functions.
04050       UNIFY(trail, clEnv->loc, clArg, clEnv->symType);
04051       
04052       // Build the closure Type.      
04053       shared_ptr<Type> fullMkClType = fullClFnType->getDCopy();
04054       shared_ptr<Type> mkClType= fullMkClType->getBareType();
04055       shared_ptr<Type> mkClArg = mkClType->Args()->getType(); 
04056       assert(mkClArg->typeTag == ty_fnarg);
04057       
04058       mkClArg->components.erase(mkClArg->components.begin());
04059 
04060       ast->symType = fullMkClType;
04061       break;
04062     }
04063 
04064   case at_setClosure:
04065     {
04066        /*------------------------------------------------
04067              setclosure: TODO
04068        ------------------------------------------------*/
04069       TYPEINFER(ast->child(0), gamma, instEnv, impTypes, 
04070                 tcc, trail, USE_MODE, TI_EXPRESSION);
04071       
04072       TYPEINFER(ast->child(1), gamma, instEnv, impTypes, 
04073                 tcc, trail, USE_MODE, TI_EXPRESSION);
04074       
04075       for (size_t c = 2; c < ast->children.size(); c++) {
04076             TYPEINFER(ast->child(c), gamma, instEnv, impTypes, tcc,
04077                       trail, USE_MODE, TI_EXPRESSION);
04078       }
04079     
04080       ast->symType = Type::make(ty_unit);
04081       break;      
04082     }
04083     
04084   case at_apply:
04085     {
04086        /*------------------------------------------------
04087            A |- ef:tf      A |- e1:t1 ... A |- en: tn
04088            U(tf = 'a|('c1|'b1 ... 'cn|'bn) -> 'cr|'br   
04089        IF byref(1) THEN U(t1 = 'c1|'b1) ELSE U(t1 = 'd1|'b1)
04090                             ... 
04091        IF byref(1) THEN U(t1 = 'cn|'bn) ELSE U(tn = 'dn|'bn)
04092           ______________________________________________
04093               A |- (ef e1 ... en): 'e|'br 
04094        ------------------------------------------------*/
04095 
04096       TI_Flags appFlags = TI_EXPRESSION;
04097 
04098       // A method selector is ONLY permitted in applicative position,
04099       // and that will necessarily involve a select AST in that
04100       // position. We refuse to accept that in any other context.
04101       if (ast->child(0)->astType == at_select)
04102         appFlags |= TI_METHOD_OK;
04103 
04104       // match agt_expr agt_expr
04105       //NOTE: One operation safe. (+)
04106 
04107       TYPEINFER(ast->child(0), gamma, instEnv, impTypes, tcc,
04108                 trail, USE_MODE, appFlags);
04109       shared_ptr<Type> fType = ast->child(0)->getType();
04110 
04111       if (fType->isStruct()) {
04112         ast->astType = at_struct_apply;
04113         TYPEINFER(ast, gamma, instEnv, impTypes, tcc,
04114                   trail,  USE_MODE, TI_EXPRESSION);
04115         break;
04116       }
04117       if (fType->isObject()) {
04118         ast->astType = at_object_apply;
04119         TYPEINFER(ast, gamma, instEnv, impTypes, tcc,
04120                   trail,  USE_MODE, TI_EXPRESSION);
04121         break;
04122       }
04123       else if (fType->isMethod()) {
04124         assert (ast->child(0)->astType == at_select);
04125         // Need to re-write this AST as a normal application. Given
04126         // "(s.M args...)", where s is an instance of type S, rewrite
04127         // this as (S.M s args...):
04128 
04129         shared_ptr<AST> theSelect = ast->child(0);
04130         shared_ptr<AST> theMethod = theSelect->child(1);
04131         shared_ptr<AST> theStructure = theSelect->child(0);
04132 
04133         ast->children.insert(ast->children.begin() + 1, theStructure);
04134 
04135         std::stringstream qs;
04136         if((ti_flags & TI_USING_FQNS) == 0)
04137           qs << fType->myContainer->s;
04138         else
04139           qs << fType->myContainer->fqn.asString();
04140         qs << "." << theMethod->s;
04141         theMethod->s = qs.str();
04142         
04143         theMethod->symbolDef = ast->envs.env->getBinding(theMethod->s);
04144         assert(theMethod->symbolDef);
04145         ast->children[0] = theMethod;
04146 
04147         TYPEINFER(ast, gamma, instEnv, impTypes, tcc,
04148                   trail,  USE_MODE, TI_EXPRESSION);
04149         break;
04150       }
04151       else if (fType->isUType() || fType->isException()) {
04152         ast->astType = at_ucon_apply;
04153         TYPEINFER(ast, gamma, instEnv, impTypes, tcc,
04154                   trail,  USE_MODE, TI_EXPRESSION);
04155         break;
04156       }
04157 
04158       shared_ptr<Type> Fn = buildFnFromApp(ast);
04159       shared_ptr<Type> expectFn = MBF(Fn);
04160 
04161       UNIFY(trail, ast->child(0)->loc, fType, expectFn);
04162       
04163       if (!errFree) {
04164         ast->symType = newTvar(); 
04165         break;
04166       }
04167       
04168       shared_ptr<Type> fnArgs = Fn->Args();
04169       for (size_t i = 0; i < ast->children.size()-1; i++) {
04170         shared_ptr<AST> arg = ast->child(i+1);
04171         TYPEINFER(arg, gamma, instEnv, impTypes, tcc,
04172                   trail,  USE_MODE, TI_EXPRESSION);
04173         
04174         shared_ptr<Type> fnArg = fnArgs->CompType(i)->getType();
04175         shared_ptr<Type> acArg = arg->symType->getType();
04176         
04177         // by-ref arguments need strict compatibility.
04178         // by-value arguments can have copy-compatibility.
04179         if (fnArgs->CompFlags(i) & COMP_BYREF)
04180           UNIFY(trail, arg->loc, fnArg, acArg);
04181         else if(fnArg->isArrayByref()) {
04182 
04183           // This case is an array argument being applied when an
04184           // array-byref is expected, so need to construct the
04185           // array-byref pair.
04186           if(acArg->isArray()) {
04187             ast->child(1) = AST::make(at_mkArrayRef, arg->loc, arg);
04188             arg = ast->child(1);
04189             TYPEINFER(arg, gamma, instEnv, impTypes, tcc,
04190                       trail,  USE_MODE, TI_EXPRESSION);
04191             acArg = arg->symType->getType();
04192           }
04193           
04194           UNIFY(trail, arg->loc, fnArg, acArg);
04195         }
04196         else
04197           UNIFY(trail, arg->loc, MBF(fnArg), acArg);
04198         
04199       }
04200       
04201       shared_ptr<Type> ret = MBF(Fn->Ret());
04202       CHKERR(errFree, testNonEscaping(errStream, ast, ret));
04203 
04204       ast->symType = ret;
04205       break;
04206     }
04207     
04208   case at_ucon_apply:
04209     {
04210        /*------------------------------------------------
04211         A(v) = ['a1.. 'am] ... | Ctr{f1:t1 ... fn:tn} | ...
04212        A |- ef:v(s1 ... sm)    A |- e1:t1' ... A |- en: tn'
04213                      
04214                U(t1  = 'c1|'b1) ... U(tn  = 'cn|'bn)
04215                U(t1' = 'd1|'b1) ... U(tn' = 'dn|'bn)
04216       ______________________________________________________
04217               A |- (Ctr e1 ... en): v(s1 ... sm)
04218 
04219       NOTE: s and t both denote standard types
04220        ------------------------------------------------*/
04221 
04222       ast->symType = newTvar();
04223       shared_ptr<AST> ctr = ast->child(0);
04224 
04225       if ((ctr->astType == at_ident) &&
04226          (ctr->symbolDef->isIdentType(idc_uctor))) {
04227         // Constructor direct usage
04228       }
04229       else if ((ctr->astType == at_fqCtr) &&
04230                (ctr->child(1)->symbolDef->isIdentType(idc_uctor))) {
04231         // Constructor qualified usage 
04232       }
04233       else {
04234         errStream << ctr->loc << ": "
04235                   << "union/exception"
04236                   << " constructor expected."
04237                   << std::endl;
04238         errFree = false;            
04239         break;
04240       }
04241       
04242       if (!ctr->symType) {
04243         TYPEINFER(ctr, gamma, instEnv, impTypes, tcc,
04244                   trail,  USE_MODE, TI_EXPRESSION);
04245       }
04246       
04247       // The constructor type cannot be a mutable or a maybe type
04248       shared_ptr<Type> t = ctr->symType->getType();
04249       if (t->typeTag != ty_uconv && t->typeTag != ty_uconr && 
04250          t->typeTag != ty_exn) {
04251         
04252         errStream << ast->child(0)->loc << ": "
04253                   << ast->child(0)->s << " cannot be resolved" 
04254                   << " to a Union (or exception) Constructor."
04255                   << std::endl;
04256         errFree = false;
04257         break;
04258      }
04259     
04260       size_t cnt = nCtArgs(t);
04261       if (cnt != (ast->children.size() - 1)) {
04262           errStream << ast->child(0)->loc << ": "
04263                     << "Constructor " << ast->child(0)->s << " needs "
04264                     << cnt << " arguments, but obtained"
04265                     << (ast->children.size() - 1)
04266                     << std::endl;
04267           errFree = false;
04268           break;
04269       }
04270 
04271       for (size_t i=0, j=1; i < t->components.size(); i++) {
04272         shared_ptr<comp> ctrComp = t->components[i];
04273         if (ctrComp->flags & COMP_UNIN_DISCM)
04274           continue;
04275         
04276         shared_ptr<AST> arg = ast->child(j);        
04277         
04278         TYPEINFER(arg, gamma, instEnv, impTypes, tcc,
04279                   trail, USE_MODE, TI_EXPRESSION);
04280 
04281         CHKERR(errFree, testNonEscaping(errStream, arg,
04282                                         arg->symType)); 
04283 
04284         shared_ptr<Type> tv = newTvar();
04285         UNIFY(trail, arg->loc, t->CompType(i), MBF(tv)); 
04286         UNIFY(trail, arg->loc, arg->symType, MBF(tv));
04287         j++;
04288       }
04289       
04290       if (!errFree)
04291         break;
04292 
04293       if (t->isUType()) {
04294         // A uval type was being returned here.
04295         ast->symType = obtainFullUnionType(t);
04296       }
04297       else {
04298         ast->symType = t;
04299       }
04300       
04301       break;
04302     }
04303     
04304   case at_struct_apply:
04305     {
04306        /*------------------------------------------------
04307            A(r) = ['a1.. 'am] {f1:t1 ... fn:tn}
04308       A |- ef:r(s1 ... sm)   A |- e1:t1' ... A |- en: tn'
04309       
04310                U(t1  = 'c1|'b1) ... U(tn  = 'cn|'bn)
04311                U(t1' = 'd1|'b1) ... U(tn' = 'dn|'bn)
04312       ______________________________________________________
04313               A |- (r e1 ... en): r(s1 ... sm)
04314        ------------------------------------------------*/
04315       // match at_ident
04316       
04317       ast->symType = newTvar();
04318       shared_ptr<AST> ctr = ast->child(0);
04319       if (!ctr->symType)
04320         TYPEINFER(ctr, gamma, instEnv, impTypes, tcc,
04321                   trail,  USE_MODE, TI_EXPRESSION);
04322       
04323       // Structure constructor cannot be a mutable or maybe type.
04324       shared_ptr<Type> t = ctr->symType->getType();
04325       if ((ctr->astType != at_ident) ||
04326           (!ctr->symbolDef->isIdentType(id_struct))) {
04327         errStream << ctr->loc
04328                   << ": Expected structure"
04329                   << " constructor taking at least one argument."
04330                   << std::endl;
04331         errFree = false;
04332         break;
04333       }
04334       if (t->components.size() == 0) {
04335         errStream << ast->child(0)->loc << ": "
04336                   << ast->child(0)->s << " cannot instantiate without "
04337                   << "definition in scope."
04338                   << std::endl;
04339         errFree = false;
04340         break;
04341       }
04342       if ((ast->children.size()-1) != t->components.size()) {
04343         errStream << ast->child(0)->loc << ": "
04344                   << "Structure " << ast->child(0)->s << " cannot be" 
04345                   << " partially/over instantiated." << '\n'
04346                   << "Constructor call has " << (ast->children.size()-1)
04347                   << " arguments but structure type has" 
04348                   << t->components.size() << " components."
04349                   << std::endl;
04350         
04351         errFree = false;
04352         break;
04353       }
04354 
04355       for (size_t i=0; i < t->components.size(); i++) {
04356         shared_ptr<AST> arg = ast->child(i+1);
04357         TYPEINFER(arg, gamma, instEnv, impTypes, tcc,
04358                   trail,  USE_MODE, TI_EXPRESSION);
04359         
04360         shared_ptr<Type> tv = newTvar();
04361         UNIFY(trail, arg->loc, t->CompType(i), MBF(tv));
04362         
04363         UNIFY(trail, arg->loc, arg->symType, MBF(tv));
04364       }
04365 
04366       ast->symType = t;
04367       break;
04368     }
04369 
04370   case at_object_apply:
04371     // FIX!!
04372     {
04373        /*------------------------------------------------
04374            A(r) = ['a1.. 'am] {f1:t1 ... fn:tn}
04375       A |- ef:r(s1 ... sm)   A |- e1:t1' ... A |- en: tn'
04376       
04377                U(t1  = 'c1|'b1) ... U(tn  = 'cn|'bn)
04378                U(t1' = 'd1|'b1) ... U(tn' = 'dn|'bn)
04379       ______________________________________________________
04380               A |- (r e1 ... en): r(s1 ... sm)
04381        ------------------------------------------------*/
04382       // match at_ident
04383       
04384       ast->symType = newTvar();
04385       shared_ptr<AST> ctr = ast->child(0);
04386       if (!ctr->symType)
04387         TYPEINFER(ctr, gamma, instEnv, impTypes, tcc,
04388                   trail,  USE_MODE, TI_EXPRESSION);
04389       
04390       // Object constructor cannot be a mutable or maybe type.
04391       shared_ptr<Type> t = ctr->symType->getType();
04392       if ((ctr->astType != at_ident) ||
04393           (!ctr->symbolDef->isIdentType(id_struct))) {
04394         errStream << ctr->loc
04395                   << ": Expected object"
04396                   << " constructor taking at least one argument."
04397                   << std::endl;
04398         errFree = false;
04399         break;
04400       }
04401       if (t->components.size() == 0) {
04402         errStream << ast->child(0)->loc << ": "
04403                   << ast->child(0)->s << " cannot instantiate without "
04404                   << "definition in scope."
04405                   << std::endl;
04406         errFree = false;
04407         break;
04408       }
04409 
04410       // Object construction takes exactly one argument, which must be
04411       // a compatible structure type:
04412       if ((ast->children.size()-1) != 1) {
04413         errStream << ast->child(0)->loc << ": "
04414                   << "Object " << ast->child(0)->s
04415                   << " should be instantiated with exactly one"
04416                   << " argument of compatible structure type." 
04417                   << std::endl;
04418         
04419         // FIX: Rest of checks here.
04420 
04421         errFree = false;
04422         break;
04423       }
04424 
04425       for (size_t i=0; i < t->components.size(); i++) {
04426         shared_ptr<AST> arg = ast->child(i+1);
04427         TYPEINFER(arg, gamma, instEnv, impTypes, tcc,
04428                   trail,  USE_MODE, TI_EXPRESSION);
04429 
04430         CHKERR(errFree, testNonEscaping(errStream, arg,
04431                                         arg->symType)); 
04432 
04433         shared_ptr<Type> tv = newTvar();
04434         UNIFY(trail, arg->loc, t->CompType(i), MBF(tv));
04435         
04436         UNIFY(trail, arg->loc, arg->symType, MBF(tv));
04437       }
04438 
04439       ast->symType = t;
04440       break;
04441     }
04442     
04443   case at_if:
04444     {
04445        /*------------------------------------------------
04446                A |- e0:t0   A |- e1:t1    A |- e2: t2
04447          U(t0 = 'a|bool)  U(t1 = 'b|'c)  U(t2 = 'd|'c)
04448       ______________________________________________________
04449                    A |- (if e0 e1 e2): 'e|'c
04450        ------------------------------------------------*/
04451 
04452       // match agt_expr
04453       TYPEINFER(ast->child(0), gamma, instEnv, impTypes, tcc,
04454                 trail, mode, TI_EXPRESSION);      
04455       
04456       UNIFY(trail, ast->child(0)->loc, 
04457             ast->child(0)->symType, MBF(Type::make(ty_bool)));
04458       
04459       // match agt_expr
04460       TYPEINFER(ast->child(1), gamma, instEnv, impTypes, tcc,
04461                 trail, mode, TI_EXPRESSION);
04462       // match agt_expr
04463       TYPEINFER(ast->child(2), gamma, instEnv, impTypes, tcc,
04464                 trail, mode, TI_EXPRESSION);
04465       
04466       shared_ptr<Type> tv = newTvar();
04467       UNIFY(trail, ast->child(1)->loc, 
04468             ast->child(1)->symType, MBF(tv));
04469       UNIFY(trail, ast->child(2)->loc, 
04470             ast->child(2)->symType, MBF(tv));
04471       ast->symType = MBF(tv);
04472       break;
04473     }
04474 
04475   case at_when:
04476   case at_unless:
04477     {
04478        /*------------------------------------------------
04479                A |- e0:t0   A |- e1:t1  U(t0 = 'a|bool)
04480       ______________________________________________________
04481                  A |- (when e0 e1): ()
04482 
04483                A |- e0:t0   A |- e1:t1  U(t0 = 'a|bool)
04484       ______________________________________________________
04485                  A |- (unless e0 e1): ()
04486        ------------------------------------------------*/
04487 
04488       // match agt_expr
04489       TYPEINFER(ast->child(0), gamma, instEnv, impTypes, tcc,
04490                 trail, mode, TI_EXPRESSION);      
04491       
04492       UNIFY(trail, ast->child(0)->loc, 
04493             ast->child(0)->symType, MBF(Type::make(ty_bool)));
04494       
04495       // match agt_expr
04496       TYPEINFER(ast->child(1), gamma, instEnv, impTypes, tcc,
04497                 trail, mode, TI_EXPRESSION);
04498       
04499       ast->symType = Type::make(ty_unit);
04500       break;
04501     }
04502 
04503   case at_and:
04504   case at_or:
04505     {
04506        /*------------------------------------------------
04507                       A |- e1:t1  ...  A |- en: tn
04508             U(t1 = 'a1|bool) ...  U(tn = 'an|bool)
04509        ________________________________________________
04510                    A |- (and e1 ... en): bool
04511 
04512                       A |- e1:t1  ...  A |- en: tn
04513             U(t1 = 'a1|bool) ...  U(tn = 'an|bool)
04514        ________________________________________________
04515                    A |- (or e1 ... en): bool
04516 
04517        ------------------------------------------------*/
04518 
04519       // match agt_expr+
04520       
04521       ast->symType = Type::make(ty_bool);
04522       
04523       for (size_t c = 0; c < ast->children.size(); c++) {
04524         TYPEINFER(ast->child(c), gamma, instEnv, impTypes, tcc,
04525                   trail, mode, TI_EXPRESSION);
04526         
04527         UNIFY(trail, ast->child(c)->loc, 
04528               ast->child(c)->symType, MBF(ast->symType));
04529       }
04530       break;
04531     }
04532 
04533  case at_cond:
04534    {
04535        /*------------------------------------------------
04536               A |- c1: t1  ...  A |- cn: tn   A |- ow: tw
04537          U(t1 = 'a1|'b) ... U(tn = 'an|'b) U(tw = 'aw|'b)
04538        _____________________________________________________
04539                    A |- (cond c1 ... cn ow): 'c|'b
04540        ------------------------------------------------*/
04541 
04542      shared_ptr<Type> tv = newTvar();
04543      // match at_cond_legs
04544      shared_ptr<AST> conds = ast->child(0);
04545      for (size_t c = 0; c < conds->children.size(); c++) {
04546        shared_ptr<AST> cond = conds->child(c);
04547        TYPEINFER(cond, gamma, instEnv, impTypes, tcc,
04548                  trail, USE_MODE, TI_EXPRESSION);
04549        
04550        UNIFY(trail, cond->loc, cond->symType, MBF(tv));
04551      }
04552      conds->symType = MBF(tv);
04553      
04554      // match at_otherwise
04555      TYPEINFER(ast->child(1), gamma, instEnv, impTypes, tcc,
04556                trail,  USE_MODE, TI_EXPRESSION);    
04557      
04558      UNIFY(trail, ast->child(1)->loc, 
04559            ast->child(1)->symType, MBF(tv));
04560      ast->symType = MBF(tv);
04561      break;
04562    }
04563    
04564  case at_cond_legs:
04565    {
04566      assert(false);
04567      break;
04568    }
04569 
04570  case at_cond_leg:
04571    {
04572      /*------------------------------------------------
04573          A |- cond: t1      A |- e: t     U(t1 = 'a|bool)
04574        __________________________________________________
04575                     A |- (cond e): t
04576        ------------------------------------------------*/
04577      shared_ptr<Type> t = newTvar();
04578      CHKERR(errFree, unifyPrim(errStream, trail, ast->loc, t, "bool"));
04579       
04580      TYPEINFER(ast->child(0), gamma, instEnv, impTypes, tcc,
04581                trail,  USE_MODE, TI_EXPRESSION);
04582      UNIFY(trail, ast->child(0)->loc, 
04583            ast->child(0)->symType, MBF(Type::make(ty_bool)));
04584 
04585      TYPEINFER(ast->child(1), gamma, instEnv, impTypes, tcc,
04586                trail,  USE_MODE, TI_EXPRESSION);
04587      
04588      ast->symType = ast->child(1)->symType;
04589      break;
04590    }
04591 
04592   case at_setbang:
04593     {
04594      /*------------------------------------------------
04595             A |- e1: t1    A |- e2: t2    |-lval e1
04596              U(t1 = (mutable 'a)|'b   U(t1 = 'c|'b)  
04597        __________________________________________________
04598                     A |- (set! e1 e2): ()
04599 
04600        NOTE: lval(e1) check enforced in the loc-chk pass
04601        ------------------------------------------------*/
04602       // match agt_expr
04603       ast->symType = Type::make(ty_unit);
04604       
04605       TYPEINFER(ast->child(0), gamma, instEnv, impTypes, tcc,
04606                 trail,  USE_MODE, TI_EXPRESSION);
04607       
04608       TYPEINFER(ast->child(1), gamma, instEnv, impTypes, tcc,
04609                 trail,  USE_MODE, TI_EXPRESSION);
04610       
04611       shared_ptr<Type> base = newTvar();
04612       shared_ptr<Type> mTv = Type::make(ty_mutable, newTvar());
04613       shared_ptr<Type> mb = Type::make(ty_mbFull, mTv, base);
04614       
04615       UNIFY(trail, ast->child(0)->loc,
04616             ast->child(0)->symType, mb);
04617       
04618       UNIFY(trail, ast->child(1)->loc,
04619             ast->child(1)->symType, MBF(base));
04620 
04621       CHKERR(errFree, testNonEscaping(errStream, ast->child(0), base));
04622       break;
04623     }
04624 
04625   case at_sizeof:
04626   case at_bitsizeof:
04627     {
04628       /*------------------------------------------------
04629           ___________________________________________
04630                  A |- sizeof(t): word
04631         ------------------------------------------------*/
04632 
04633       // match agt_type
04634       TYPEINFER(ast->child(0), gamma, instEnv, impTypes, 
04635                 tcc, trail,  USE_MODE, 
04636                 TI_NON_APP_TYPE);
04637 
04638       ast->symType = Type::make(ty_word);
04639 
04640       break;      
04641     }    
04642 
04643   case at_dup:
04644     {
04645      /*------------------------------------------------
04646             A |- e: t     U(t = 'c|'b)
04647        _____________________________________
04648              A |- (dup t): ref('a|'b)
04649        ------------------------------------------------*/
04650       // match agt_expr
04651       TYPEINFER(ast->child(0), gamma, instEnv, impTypes, tcc,
04652                 trail,  USE_MODE, TI_EXPRESSION);
04653       
04654       shared_ptr<Type> tv = newTvar();
04655       UNIFY(trail, ast->child(0)->loc,
04656             ast->child(0)->symType, MBF(tv));
04657       ast->symType = Type::make(ty_ref, MBF(tv));
04658       break;      
04659     }
04660 
04661   case at_deref:
04662     {
04663      /*------------------------------------------------
04664             A |- e: t     U(t = 'b|ref('a))
04665        _____________________________________
04666              A |- (dup t): 'a
04667        ------------------------------------------------*/
04668 
04669       // match agt_expr
04670       TYPEINFER(ast->child(0), gamma, instEnv, impTypes, tcc,
04671                 trail,  USE_MODE, TI_EXPRESSION);
04672 
04673       ast->symType = newTvar();
04674       UNIFY(trail, ast->child(0)->loc,
04675             ast->child(0)->symType,
04676             MBF(Type::make(ty_ref, ast->symType)));
04677       break;
04678     }
04679 
04680   case at_inner_ref:
04681     {
04682      /*------------------------------------------------
04683         A |- e: 'a|ref(array t n)     U(en = 'a|word)
04684        _____________________________________________
04685              A |- (inner-ref e en): ref(t)
04686 
04687 
04688         A |- e: 'a|(vector t n)    U(en = 'a|word)
04689        ____________________________________________
04690              A |- (inner-ref e en): ref(t)
04691 
04692 
04693           A(r) = ['a1.. 'am] (unboxed) {... f:t ...} 
04694               A |- e: 'a|ref('b|r(t1...tm))
04695         _______________________________________________
04696              A |- (inner-ref e f): ref(t)
04697 
04698 
04699           A(r) = ['a1.. 'am] (boxed) {... f:t ...} 
04700                   A |- e: 'a|r(t1...tm)
04701         _______________________________________________
04702              A |- (inner-ref e f): ref(t)
04703        ------------------------------------------------*/
04704 
04705       ast->symType = newTvar();
04706       // match agt_expr
04707       TYPEINFER(ast->child(0), gamma, instEnv, impTypes, tcc,
04708                 trail,  USE_MODE, TI_EXPRESSION);
04709       
04710       shared_ptr<Type> t = ast->child(0)->symType->getBareType();
04711       bool process_ndx = false;
04712       
04713       switch(t->typeTag) {
04714       case ty_ref:
04715         {                  
04716           shared_ptr<Type> drType = t->Base()->getBareType();
04717           if (drType->typeTag == ty_array) {
04718             ast->symType = Type::make(ty_ref, drType->Base());
04719             process_ndx = true;
04720           }
04721           else if (drType->typeTag == ty_structv) {
04722             shared_ptr<Type> fType = GC_NULL;
04723             CHKERR(errFree, findField(errStream, drType, 
04724                                       ast->child(1), fType));
04725             if (errFree)
04726               ast->symType = Type::make(ty_ref, fType);
04727           }
04728           
04729           break;
04730         }
04731         
04732       case ty_structr:
04733         {
04734           shared_ptr<Type> fType = GC_NULL;
04735           CHKERR(errFree, findField(errStream, t, 
04736                                      ast->child(1), fType));
04737           if (errFree)
04738             ast->symType = Type::make(ty_ref, fType);
04739           
04740           break;
04741         }
04742 
04743       case ty_vector:
04744         {
04745           process_ndx = true;
04746           ast->symType = Type::make(ty_ref, t->Base());
04747           break;
04748         }
04749 
04750       default:
04751         {        
04752           errStream << ast->loc << ": "
04753                     << "Invalid use of inner-ref."  << std::endl;
04754           
04755           errFree = false;
04756           break;
04757         }
04758       }
04759       
04760       if (process_ndx) {
04761         ast->flags |= INNER_REF_NDX;
04762         // match agt_expr
04763         TYPEINFER(ast->child(1), gamma, instEnv, impTypes, tcc,
04764                   trail,  USE_MODE, TI_EXPRESSION);
04765         
04766         // FIX TO WORD
04767         UNIFY(trail, ast->child(1)->loc, 
04768               ast->child(1)->symType, MBF(Type::make(ty_word)));
04769       }
04770       break;
04771     }
04772     
04773   case at_uswitch:    
04774     {      
04775       /*------------------------------------------------
04776         A(v) = ['a1.. 'am] C11(r1) | ... | C1p(r1) |
04777                      ... | Cn1(rn) | ... | Cnq(rn) | ...
04778 
04779                    A|- e: t  U(t = v(s1 ... sm)
04780          A, x:r1 |- e1:t1 ... A, x:rn |- en:tn   A |- ew: tw
04781          U(t1 = 'a1|'b) ... U(tn = 'an|'b)   U(tw = 'aw|'b)
04782         _________________________________________________
04783            A |- (switch x e (C11 ... C1p x1 e1)
04784                                  ...
04785                             (Cn1 ... Cnq xn en)
04786                             (ow             ew)): 'c|'b
04787         ------------------------------------------------*/
04788 
04789       // match at at_ident
04790 
04791       // match at agt_expr
04792       shared_ptr<AST> topExpr = ast->child(1);
04793       TYPEINFER(topExpr, gamma, instEnv, impTypes, tcc,
04794                 trail,  USE_MODE, TI_EXPRESSION);
04795       
04796       shared_ptr<Type> tv = newTvar();
04797       // match at_case_legs
04798       shared_ptr<AST> cases = ast->child(2);
04799       for (size_t c = 0; c < cases->children.size(); c++) {
04800         shared_ptr<AST> thecase = cases->child(c);
04801         for (size_t j=2; j < thecase->children.size(); j++) {
04802           shared_ptr<AST> aCtr = thecase->child(j);
04803           
04804           TYPEINFER(aCtr, gamma, instEnv, impTypes, 
04805                     tcc, trail,  USE_MODE, TI_EXPRESSION);      
04806           
04807           shared_ptr<Type> aCtrType = aCtr->symType->getType();
04808           UNIFY(trail, aCtr->loc, 
04809                 topExpr->symType, aCtrType);
04810         }
04811         
04812         TYPEINFER(thecase, gamma, instEnv, impTypes, tcc,
04813                   trail,  USE_MODE, TI_EXPRESSION);
04814         
04815         if (!errFree)
04816           continue;
04817         
04818         UNIFY(trail, thecase->loc,
04819               thecase->symType, MBF(tv));
04820       }
04821       cases->symType = MBF(tv);
04822 
04823       // match at_otherwise
04824       shared_ptr<AST> otherwise = ast->child(3);
04825       if (otherwise->astType != at_Null) {
04826         shared_ptr<TSEnvironment > legGamma = gamma->newScope();
04827         otherwise->envs.gamma = legGamma;
04828 
04829         shared_ptr<AST> stIdent = otherwise->child(0); 
04830         TYPEINFER(stIdent, legGamma, instEnv, impTypes, 
04831                   tcc, trail,  DEF_MODE, TI_EXPRESSION);
04832 
04833         stIdent->symType->link = topExpr->symType;
04834 
04835         // match agt_expr
04836         TYPEINFER(otherwise->child(1), legGamma, instEnv, impTypes, 
04837                   tcc, trail,  USE_MODE, TI_EXPRESSION);
04838 
04839         otherwise->symType = otherwise->child(1)->symType;
04840 
04841         UNIFY(trail, otherwise->loc, 
04842               otherwise->symType, MBF(tv));
04843       }
04844 
04845       ast->symType = MBF(tv);
04846       
04847       /* Check consistency and coverage of the switch */
04848       if (!topExpr->symType->isUType()) {
04849         errStream << topExpr->loc << ": "
04850                   << "Only unions are permitted for switching"
04851                   << " but obtained "
04852                   << topExpr->symType->asString()
04853                   << std::endl;
04854         ast->symType = newTvar();
04855         errFree = false;
04856         break;
04857       } 
04858 
04859       shared_ptr<Type> ut = topExpr->symType->getBareType();
04860       shared_ptr<Type> uType = obtainFullUnionType(ut);
04861       
04862       for (size_t c = 0; c < cases->children.size(); c++) {
04863         shared_ptr<AST> thecase = cases->child(c);
04864         for (size_t i=2; i < thecase->children.size(); i++) {
04865           shared_ptr<AST> ctr = thecase->child(i)->getCtr();          
04866           bool found=false;
04867           
04868           for (size_t j=0; j < uType->components.size(); j++) {
04869             if (!uType->CompType(j))
04870               continue;
04871             
04872             shared_ptr<Type> cTyp = uType->CompType(j)->getType();
04873             if (cTyp->defAst == ctr->symbolDef) {
04874               found = true;
04875               uType->CompType(j) = GC_NULL;
04876               break;
04877             }
04878           }
04879           
04880           if (!found) {
04881             errStream << ctr->loc << ": "
04882                       << "Duplicate case label"
04883                       << ctr->asString()
04884                       << "." << endl;
04885             errFree = false;
04886           }
04887         }
04888       }
04889 
04890 
04891       bool moreCases = false;
04892       for (size_t j=0; j < uType->components.size(); j++) 
04893         if (uType->CompType(j)) {
04894           moreCases = true;
04895           break;
04896         }
04897       
04898       if (moreCases) {
04899         if (otherwise->astType == at_Null) {
04900           errStream << ast->loc << ": The following cases"
04901                     << " are not covered: ";
04902           for (size_t j=0; j < uType->components.size(); j++) {
04903             shared_ptr<Type> cTyp = uType->CompType(j)->getType();
04904             if (j > 0)
04905               errStream << ", ";
04906             errStream << cTyp->defAst->s;
04907           }
04908           errStream << std::endl;
04909           errFree = false;
04910         }
04911       }
04912       else {
04913         if (otherwise->astType != at_Null) {
04914           errStream << otherwise->loc << ": "
04915                     << "Otherwise is present even after all cases"
04916                     << "are covered."
04917                     << std::endl;
04918           errFree = false;
04919         }
04920       }
04921       break;
04922     }
04923 
04924   case at_usw_legs:
04925     /* FIX: I forgot if I really mean break here or assert(false); */
04926     break;
04927 
04928   case at_condelse:
04929     {
04930       // match agt_expr
04931       TYPEINFER(ast->child(0), gamma, instEnv, impTypes, tcc,
04932                 trail,  USE_MODE, TI_EXPRESSION);
04933     
04934       ast->symType = ast->child(0)->symType;
04935       break;
04936     }
04937 
04938   case at_otherwise:
04939     {
04940       // Handled explicitly in at_try and at_switch
04941       assert(false);
04942     }
04943   case at_usw_leg:
04944     {
04945       // This is used only in the case of a union leg match.
04946       // match agt_valuePattern
04947       shared_ptr<TSEnvironment > legGamma = gamma->newScope();
04948       ast->envs.gamma = legGamma;
04949 
04950       /* Deal with the constructors first */
04951       shared_ptr<AST> aCtr = ast->child(2)->getCtr();
04952       shared_ptr<Type> aCtrType = ast->child(2)->symType->getBareType();
04953 
04954       /* Deal with the component structure identifier */
04955       shared_ptr<TypeScheme> stSigma = aCtr->symbolDef->stSigma;
04956       shared_ptr<Type> stType = stSigma->type_instance();
04957       /* If we decide to alow the unification of the structure
04958          type with the union type, this must be done there */
04959       assert(stType->typeArgs.size() == aCtrType->typeArgs.size());      
04960       for (size_t m=0; m < stType->typeArgs.size(); m++) {
04961         UNIFY(trail, ast->loc, 
04962               stType->TypeArg(m), aCtrType->TypeArg(m));
04963       }
04964       
04965       /* Checking compatibility of different constructors used in the
04966          same leg of as switch is done in differently for unions
04967          and reprs. 
04968          ** In the case of unions, all union legs must have
04969          the same field structure. 
04970          **In  the case of reprs, we have more
04971          constraints on field layout -- identically named fields must
04972          be at the same bit-offset and be of the same type. Therefore,
04973          we can allow different constructors such that only common
04974          fields are efective within the switch-leg.
04975 
04976          Therefore, in the case of unions, we check for stSigma
04977          compatibility, but in the case of reprs, we just give the
04978          switched-leg identifier the type obtained from the stSigma of
04979          the first constructor, but mark fields that are not in the
04980          intersection of all constructors as invalid. This flag (on
04981          the component) is ONLY checked in at_select.  */
04982       shared_ptr<AST> uninID = aCtr->symType->myContainer;
04983       bool isRepr = (uninID->flags & UNION_IS_REPR);
04984 
04985 
04986       for (size_t c=2; c < ast->children.size(); c++) {
04987          shared_ptr<AST> ctr = ast->child(c)->getCtr()->symbolDef;
04988         if (!ctr->stSigma) {
04989           errStream << ctr->loc << ": Use of constructor "
04990                     << ctr->s << " whose definition had an error"
04991                     << std::endl;
04992           errFree = false;
04993           break;
04994         }
04995 
04996         if (!isRepr) {
04997           if (ctr->stSigma != stSigma) {
04998             errStream << ctr->loc << ": Use of constructor " 
04999                       << ctr->s << " whose components are "
05000                       << "incompatible with other constructors used "
05001                       << "in this case"
05002                       << std::endl;
05003             errFree = false;
05004             break;
05005           }
05006         }
05007         else {
05008           if (aCtr == ctr)
05009             continue;
05010           
05011           const shared_ptr<const Type> ctType = ctr->stSigma->tau;
05012           for (size_t ac=0; ac < stType->components.size(); ac++) {
05013             shared_ptr<comp> stComp = stType->Component(ac);
05014             bool found=false;            
05015             
05016             for (size_t tc=0; tc < ctType->components.size(); tc++) {
05017               const shared_ptr<const comp> ctComp = ctType->Component(tc);
05018               
05019               if (ctComp->name == stComp->name) {
05020                 found = true;
05021                 break;
05022               }
05023             }
05024             
05025             if (!found) 
05026               stComp->flags |= COMP_INVALID;
05027           }
05028         }
05029       }
05030       
05031       if (!errFree) {
05032         ast->symType = newTvar();
05033         break;
05034       }
05035       
05036       shared_ptr<AST> stIdent = ast->child(0); 
05037       TYPEINFER(stIdent, legGamma, instEnv, impTypes, 
05038                 tcc, trail,  DEF_MODE, TI_EXPRESSION);
05039       stIdent->symType = stType;
05040       stIdent->scheme->tau = stType;
05041       assert(stIdent->scheme->ftvs.empty());
05042 
05043       // match agt_expr
05044       TYPEINFER(ast->child(1), legGamma, instEnv, impTypes, 
05045                 tcc, trail,  USE_MODE, TI_EXPRESSION);
05046 
05047       ast->symType = ast->child(1)->symType;
05048       break;
05049     }
05050     
05051   case at_try:
05052     {
05053       /*------------------------------------------------
05054            A(exn) =  E11(r11) | ... | E1p(r1p) | ... |
05055                      Em(rm)   | ... 
05056 
05057                      A|- e: t     U(t = 'a|'b)
05058       A |- e1:t1 ...  A, x:rm |- em:tm ...   [A |- ew: tw]
05059       U(t1 = 'a1|'b) ... U(tm = 'am|'b) ... [U(tw = 'aw|'b)]
05060         _________________________________________________
05061          A |- (try e x
05062                    (catch (E11 ... E1p    e1)
05063                                ...
05064                           (Em          xm em)
05065                                ...
05066                          [(ow             ew)]): 'c|'b
05067         ------------------------------------------------*/
05068 
05069       // match agt_expr
05070       shared_ptr<Type> tv = newTvar();
05071       shared_ptr<AST> expr = ast->child(0);     
05072       TYPEINFER(expr, gamma, instEnv, impTypes, tcc,
05073                 trail,  USE_MODE, TI_EXPRESSION);
05074       UNIFY(trail, expr->loc, expr->symType, MBF(tv));
05075       
05076       ast->symType = MBF(tv);
05077       
05078       if (!errFree)
05079         break;
05080 
05081       // match at_ident: ignore
05082 
05083       // match at_usw_legs
05084       shared_ptr<AST> cases = ast->child(2);     
05085       cases->symType = MBF(tv);
05086       for (size_t c = 0; c < cases->children.size(); c++) {
05087         shared_ptr<AST> theCase = cases->child(c);
05088         
05089         for (size_t j=2; j < theCase->children.size(); j++) {
05090           shared_ptr<AST> aCtr = theCase->child(j);
05091           
05092           TYPEINFER(aCtr, gamma, instEnv, impTypes, 
05093                     tcc, trail, USE_MODE, TI_EXPRESSION);      
05094           
05095           if (aCtr->symType->getType()->typeTag != ty_exn) {
05096             errStream << aCtr->loc << ": "
05097                       << " Only Exceptions can be caught"
05098                       << " Obtained type " 
05099                       << aCtr->symType->asString()
05100                       << std::endl;
05101             errFree = false;
05102           }
05103         }        
05104         
05105         shared_ptr<TSEnvironment > legGamma = gamma;
05106 
05107         // The deconstructed identifier is bound for use in the
05108         // legGamma environment only if we are catching a single
05109         // constructor.
05110         if (theCase->children.size() == 3) {
05111           legGamma = gamma->newScope();
05112           theCase->envs.gamma = legGamma;
05113 
05114           shared_ptr<AST> stIdent = theCase->child(0);
05115           // Add sIdent to the legGamma environment.
05116           TYPEINFER(stIdent, legGamma, instEnv, impTypes, 
05117                     tcc, trail,  DEF_MODE, TI_EXPRESSION);
05118 
05119           // Make sIdent's type the correct type.
05120           shared_ptr<AST> onlyCtr = theCase->child(2)->getCtr();
05121           assert(onlyCtr->symbolDef->stSigma);
05122           shared_ptr<Type> stType = onlyCtr->symbolDef->stSigma->type_instance();
05123           stIdent->symType = stType;
05124           stIdent->scheme->tau = stType;
05125           assert(stIdent->scheme->ftvs.empty());
05126         }
05127         
05128         shared_ptr<AST> expr = theCase->child(1);
05129         TYPEINFER(expr, legGamma, instEnv, impTypes, tcc,
05130                   trail, USE_MODE, TI_EXPRESSION);
05131 
05132         UNIFY(trail, expr->loc, expr->symType, MBF(tv));
05133         
05134         theCase->symType = expr->symType;
05135       }
05136       
05137       // match agt_ow
05138       shared_ptr<AST> ow = ast->child(3);
05139       if (ow->astType != at_Null) {
05140         shared_ptr<TSEnvironment > legGamma = gamma->newScope();
05141         ow->envs.gamma = legGamma;
05142 
05143         shared_ptr<AST> stIdent = ow->child(0);
05144 
05145         // Add sIdent to the legGamma environment.
05146         TYPEINFER(stIdent, legGamma, instEnv, impTypes, 
05147                   tcc, trail,  DEF_MODE, TI_EXPRESSION);
05148 
05149         stIdent->symType->link = Type::make(ty_exn);
05150 
05151         TYPEINFER(ow->child(1), legGamma, instEnv, impTypes, tcc,
05152                   trail,  USE_MODE, TI_EXPRESSION);
05153         UNIFY(trail, ow->child(1)->loc,
05154               ow->child(1)->symType, MBF(tv));  
05155         ow->symType = ow->child(1)->symType;
05156       }
05157       
05158       break;
05159     }
05160 
05161   case at_throw:
05162     {
05163       /*------------------------------------------------
05164                 A |- e: t   U(t = 'b|exn)
05165         _________________________________________________
05166                    A |- (throw e): 'a
05167         ------------------------------------------------*/
05168       // match agt_var
05169       TYPEINFER(ast->child(0), gamma, instEnv, impTypes, tcc,
05170                 trail,  USE_MODE, TI_EXPRESSION);
05171       
05172       // HACK: We now allow exception legs as arguments to throw. If
05173       // an exception leg is being presented, then it is presented as
05174       // an identifier that is known to be lexically in scope.
05175       //
05176       // If that case pertains, then TYPEINFER will have looked up the
05177       // identifier and arrived at a structure type, and we can chase
05178       // the pointers to determine whether we built that structure
05179       // type as a leg type for some exception.
05180       //
05181       // If that check fails, or if the argument to THROW is something
05182       // other than an identifier, we should introduce a unification
05183       // constraint that the argument must be of some exception type.
05184 
05185       shared_ptr<AST> id = ast->child(0);
05186       if (id->astType == at_ident &&
05187           (id->symbolDef->flags & ID_FOR_USWITCH) &&
05188           (id->symType->defAst->symType->isException())) {
05189         // Concrete type already determined; nothing further to do.
05190       }
05191       else {
05192         // Try to resolve it. See if resolved result is marked as a
05193         // switched id. If so we are good, and no unification is
05194         // required here.
05195         //
05196         // If that fails, then unify with ty_exn.
05197         UNIFY(trail, ast->child(0)->loc,
05198               ast->child(0)->symType, MBF(Type::make(ty_exn)));
05199       }
05200       
05201       ast->symType = newTvar();    
05202       break;
05203     }
05204 
05205   case at_container:
05206     {
05207       TYPEINFER(ast->child(1), gamma, instEnv, impTypes, tcc,
05208                 trail,  USE_MODE, TI_EXPRESSION);
05209       ast->symType = ast->child(1)->symType;
05210       break;
05211     }    
05212 
05213   case at_loop:
05214     {      
05215       /*------------------------------------------------
05216                A |- ei1: t1 ... A |- ein: tn
05217              U(t1 = 'a1|'b1) ... U(tn = 'an|'bn)
05218                
05219           A, x1:'c1|'b1, ... xn:'cn|'bn |- es1: ts1 ...
05220           A, x1:'c1|'b1, ... xn:'cn|'bn |- esn: tsn
05221              U(ts1 = 'd1|'b1) ... U(tsn = 'dn|'bn)
05222 
05223            A, x1:'a1|'b1, ... xn:'an|'bn |- (et er): tr
05224            A, x1:'a1|'b1, ... xn:'an|'bn |- eb: t
05225         _________________________________________________
05226                    A |- (loop ((x1 ei1 es1)
05227                                  ...
05228                                (xn ein esn))
05229                          (et  er)  eb): tr
05230         ------------------------------------------------*/
05231 
05232       // match at_letbindings
05233       shared_ptr<TSEnvironment > loopGamma = gamma->newScope();
05234       ast->envs.gamma = loopGamma;
05235 
05236       shared_ptr<AST> lbs = ast->child(0);
05237       lbs->symType = Type::make(ty_tvar);
05238 
05239       // Initializers
05240       for (size_t c = 0; c < lbs->children.size(); c++) {
05241         shared_ptr<AST> lb = lbs->child(c);
05242         shared_ptr<AST> init = lb->child(1);
05243         shared_ptr<Type> tv = newTvar();
05244         TYPEINFER(init, loopGamma, instEnv, impTypes, tcc,
05245                   trail, USE_MODE, TI_EXPRESSION);
05246         UNIFY(trail, init->loc, 
05247               init->symType, MBF(tv));
05248       }
05249       
05250       // Definitions
05251       for (size_t c = 0; c < lbs->children.size(); c++) {
05252         shared_ptr<AST> lb = lbs->child(c);
05253         shared_ptr<AST> localDefPat = lb->child(0);
05254         shared_ptr<AST> localDef = localDefPat->child(0);
05255         shared_ptr<AST> init = lb->child(1);
05256         
05257         localDef->symType = MBF(init->symType);
05258         TYPEINFER(localDefPat, loopGamma, instEnv, impTypes, tcc,
05259                   trail, DEF_MODE, TI_EXPRESSION);
05260       }
05261 
05262       // Next step initializers
05263       for (size_t c = 0; c < lbs->children.size(); c++) {
05264         shared_ptr<AST> lb = lbs->child(c);
05265         shared_ptr<AST> localDef = lb->getID();
05266         shared_ptr<AST> step = lb->child(2);
05267         
05268         TYPEINFER(step, loopGamma, instEnv, impTypes, tcc,
05269                   trail, USE_MODE, TI_EXPRESSION);
05270         
05271         UNIFY(trail, step->loc, step->symType, 
05272               MBF(localDef->symType));
05273       }
05274 
05275       // Finally evaluate the test and the final expression           
05276       TYPEINFER(ast->child(1), loopGamma, instEnv, impTypes, 
05277                 tcc, trail, USE_MODE, TI_EXPRESSION);
05278       TYPEINFER(ast->child(2), loopGamma, instEnv, impTypes, 
05279                 tcc, trail, USE_MODE, TI_EXPRESSION);
05280 
05281       ast->symType = ast->child(1)->symType;      
05282       break;
05283     }
05284 
05285   case at_looptest:
05286     {
05287       /*------------------------------------------------
05288                A |- et: tb ... A |- er: tr
05289             U(tb = 'a|bool)   U(tr = 'a|'b)
05290         _________________________________________________
05291                    A |- ((et  er)): 'c|'b
05292         ------------------------------------------------*/
05293       shared_ptr<AST> test = ast->child(0);
05294       shared_ptr<AST> result = ast->child(1);
05295       TYPEINFER(test, gamma, instEnv, impTypes, tcc,
05296                 trail,  USE_MODE, TI_EXPRESSION);
05297 
05298       UNIFY(trail, test->loc, test->symType, 
05299             MBF(Type::make(ty_bool)));
05300       
05301       shared_ptr<Type> tv = newTvar();
05302       TYPEINFER(result, gamma, instEnv, impTypes, tcc,
05303                 trail,  USE_MODE, TI_EXPRESSION);
05304 
05305       UNIFY(trail, result->loc, 
05306             result->symType, MBF(tv));
05307       
05308       ast->symType = MBF(tv);
05309       break;
05310     }
05311 
05312   case at_letrec:
05313   case at_let:
05314     {
05315       /*------------------------------------------------
05316                  A |- e1: t1'  ...  A |- en: tn'
05317              U(t1' = 'c1|'b1)  ...  U(tn' = 'cn|'bn)
05318             [U(t1  = 'a1|'b1)] ... [U(tn  = 'an|'bn)]
05319                
05320       (S1, ..., Sn) = Generalize(A, ('a1|'b1, ..., 'an|'bn),
05321                                     (e1, ... en))
05322                
05323                A, x1:S1, ... xn:Sn |- e: t
05324         _________________________________________________
05325          A |- (let ((x1[:t1] e1) ... (xn[:tn] en)) e): t
05326 
05327 
05328          
05329                 [U(t1 = 'a1|'b1)] ... [U(tn = 'an|'bn)]
05330            A, x1:'a1|'b1, ..., xn:'a1:'bn |- e1: t1' ... 
05331              A, x1:'a1|'b1, ..., xn:'a1:'bn |- en: tn'
05332              U(t1' = 'c1|'b1) ... U(tn' = 'cn|'bn)
05333                
05334       (S1, ..., Sn) = Generalize(A, ('a1|'b1, ..., 'an|'bn),
05335                                     (e1, ... en))
05336                
05337                A, x1:S1, ... xn:Sn |- e: t
05338      __________________________________________________________
05339          A |- (letrec ((x1[:t1] e1) ... (xn[:tn] en)) e): t
05340         ------------------------------------------------*/
05341 
05342       // match at_letbindings
05343       shared_ptr<TSEnvironment > letGamma = gamma->newScope();
05344       shared_ptr<TCConstraints> letTcc = TCConstraints::make();
05345 
05346       shared_ptr<AST> lbs = ast->child(0);
05347       lbs->symType = Type::make(ty_tvar);
05348       
05349       ast->envs.gamma = letGamma;
05350       ast->envs.instEnv = instEnv;
05351       lbs->envs.gamma = letGamma;
05352       lbs->envs.instEnv = instEnv;
05353 
05354          
05355       if (ast->astType == at_let) {
05356         CHKERR(errFree, 
05357                ProcessLetExprs(errStream, lbs, letGamma, instEnv,
05358                                impTypes, letTcc, trail,
05359                                USE_MODE, TI_EXPRESSION)); 
05360         CHKERR(errFree, 
05361                ProcessLetBinds(errStream, lbs, letGamma, instEnv,
05362                                impTypes, letTcc, trail,
05363                                DEF_MODE, TI_EXPRESSION)); 
05364       }
05365       else {
05366         CHKERR(errFree, 
05367                ProcessLetBinds(errStream, lbs, letGamma, instEnv,
05368                                impTypes, letTcc, trail,
05369                                DEF_MODE, TI_EXPRESSION)); 
05370         CHKERR(errFree, 
05371                ProcessLetExprs(errStream, lbs, letGamma, instEnv,
05372                                impTypes, letTcc, trail, 
05373                                USE_MODE, TI_EXPRESSION)); 
05374       }
05375       CHKERR(errFree, UnifyLetBinds(errStream, lbs, trail));
05376 
05377       if (!errFree) {
05378         ast->symType = newTvar();
05379         break;
05380       }
05381       
05382       // BEGIN stuff not needed in at_letStar
05383 
05384       // Consider all constraints
05385       TYPEINFER(ast->child(2), letGamma, instEnv, impTypes, 
05386                 letTcc, trail, mode, TI_CONSTRAINT);
05387    
05388       shared_ptr<AST> bAst, vAst;
05389       makeLetGather(lbs, bAst, vAst);
05390       
05391       CHKERR(errFree, generalizePat(errStream, ast->loc, 
05392                                     gamma, instEnv, bAst, vAst, 
05393                                     letTcc, tcc, trail));
05394       
05395       lbs->symType = bAst->symType;
05396       lbs->scheme = bAst->scheme;
05397       
05398       // END stuff not needed in at_letStar
05399 
05400       // Finally evaluate the final expression
05401       TYPEINFER(ast->child(1), letGamma, instEnv, impTypes, 
05402                 tcc, trail, USE_MODE, TI_EXPRESSION);
05403       
05404       ast->symType = ast->child(1)->symType;
05405       break;
05406     }
05407     
05408     // The SSA pass introduces at_letStar, which is structurally
05409     // similar to the Scheme or Common LISP let* construct.  In the
05410     // current top-level syntax, there is no way to introduce one of
05411     // these. This may change with the block syntax, or I may
05412     // (probably) just use an at_let with a single binding
05413     //
05414     // at_letStar nodes get introduced during the SSA pass, which is
05415     // post-polyinstantiation. A consequence is that no generalization
05416     // can occur on one of these nodes or its body, so we do not call
05417     // the generalizer.
05418   case at_letStar:
05419     {
05420       /*------------------------------------------------
05421                          A |- e1: t1'    
05422               U(t1' = 'c1|'b1)     [U(t1  = 'a1|'b1)]
05423                 A, x1:'a1|'b1 |- e2: t2'     
05424                   U(t2' = 'c2|'b2)      [U(t2  = 'a2|'b2)]
05425                              ...
05426         A, x1:'a1|'b1, ... xn-1:'an-1|'n-1 |- en: tn' ...
05427                   U(tn' = 'cn|'bn)      [U(tn  = 'an|'bn)]
05428 
05429              A, x1:'a1|'b1, ... xn:'an|'bn |- e: t
05430         _________________________________________________
05431          A |- (let* ((x1[:t1] e1) ... (xn[:tn] en)) e): t
05432         ------------------------------------------------*/
05433 
05434       // match at_letbindings
05435       shared_ptr<TSEnvironment > letGamma = gamma->newScope();
05436       
05437       shared_ptr<AST> lbs = ast->child(0);
05438       lbs->symType = Type::make(ty_tvar);
05439       
05440       ast->envs.gamma = letGamma;
05441       ast->envs.instEnv = instEnv;
05442       lbs->envs.gamma = letGamma;
05443       lbs->envs.instEnv = instEnv;
05444       
05445       for (size_t c = 0; c < lbs->children.size(); c++) {
05446         shared_ptr<AST> lb = lbs->child(c);
05447         shared_ptr<AST> id = lb->getID();
05448         shared_ptr<AST> ip = lb->child(0);
05449         shared_ptr<AST> expr = lb->child(1);
05450         
05451         TYPEINFER(expr, letGamma, instEnv, impTypes, 
05452                   tcc, trail, USE_MODE, TI_EXPRESSION);
05453         
05454         TYPEINFER(ip, letGamma, instEnv, impTypes, 
05455                   tcc, trail, DEF_MODE, TI_EXPRESSION);
05456         
05457         UNIFY(trail, lb->getID()->loc,
05458               expr->symType, MBF(id->symType));
05459       }
05460       
05461       TYPEINFER(ast->child(1), letGamma, instEnv, impTypes, 
05462                 tcc, trail, USE_MODE, TI_EXPRESSION);
05463       
05464       ast->symType = ast->child(1)->symType;
05465       break;
05466     }
05467 
05468     // CAREFUL: CAREFUL:
05469     //
05470     // This is *NOT* dead code, though, it appears to be so, from the
05471     // way the above let-cases are written. 
05472     // this case is used by the (new) polyinstantiator to R&T
05473     // let-binding instantiations. It is OK to use it ther because we
05474     // don't have any more polymorphism at that stage.
05475     //
05476     // THIS CASE MUST NOT BE USED BY OTHER LET FORMS
05477   case at_letbinding:
05478     {
05479       shared_ptr<AST> id = ast->getID();
05480       shared_ptr<AST> ip = ast->child(0);
05481       shared_ptr<AST> expr = ast->child(1);
05482       if (ast->flags & LB_REC_BIND) {
05483         TYPEINFER(ip, gamma, instEnv, impTypes, 
05484                   tcc, trail, DEF_MODE, TI_EXPRESSION);
05485 
05486         TYPEINFER(expr, gamma, instEnv, impTypes, 
05487                   tcc, trail, USE_MODE, TI_EXPRESSION);        
05488       }        
05489       else {
05490         TYPEINFER(expr, gamma, instEnv, impTypes, 
05491                   tcc, trail, USE_MODE, TI_EXPRESSION);
05492         
05493         TYPEINFER(ip, gamma, instEnv, impTypes, 
05494                   tcc, trail, DEF_MODE, TI_EXPRESSION);
05495       }
05496       
05497       UNIFY(trail, ast->getID()->loc, 
05498             expr->symType, MBF(id->symType));
05499       break;
05500     }
05501     
05502   } /* switch */
05503 
05504   DEBUG(TI_AST)
05505     if (ast->symType)
05506       errStream << "\t Obtained [" << ast->atKwd() << "] " 
05507                 << ast->asString() << ": "
05508                 << ast->symType->asString(Options::debugTvP) 
05509                 << "{" << (errFree?"OK":"ERR") << "}"
05510                 << endl;
05511   
05512   return errFree;
05513 }
05514 
05515 /**************************************************************/
05516 /*              Interface to the outside world                */
05517 /**************************************************************/
05518 
05519 bool 
05520 UocInfo::DoTypeCheck(std::ostream& errStream, bool init, 
05521                      TI_Flags ti_flags)
05522 {
05523   DEBUG(TI_UNITWISE)
05524     errStream << "Now Processing " << uocName
05525               << " ast = " << uocAst->tagName()
05526               << std::endl;
05527   
05528   TypeAstMap impTypes;
05529   shared_ptr<Trail> trail = Trail::make();
05530   bool errFree = true;
05531 
05532   if (Options::noPrelude)
05533     ti_flags |= TI_NO_PRELUDE;
05534   
05535   if (init) {
05536     
05537     if (false) {
05538       assert(gamma);      
05539       assert(gamma->parent);
05540       gamma = gamma->parent->newDefScope();
05541 
05542       assert(instEnv);      
05543       assert(instEnv->parent);
05544       instEnv = instEnv->parent->newDefScope();      
05545     }
05546     else {
05547       gamma = TSEnvironment::make(uocName);
05548       instEnv = InstEnvironment::make(uocName);
05549     }
05550     if ((ti_flags & TI_NO_PRELUDE) == 0)
05551       CHKERR(errFree, initGamma(std::cerr, gamma, instEnv, uocAst));
05552     
05553     if (!errFree)
05554       return false;
05555   }
05556 
05557   CHKERR(errFree, typeInfer(errStream, uocAst, gamma, instEnv, 
05558                             impTypes, 
05559                             TCConstraints::make(), trail, 
05560                             USE_MODE, ti_flags));
05561   CHKERR(errFree, checkImpreciseTypes(errStream, gamma, impTypes));
05562 
05563   DEBUG(TI_UNITWISE) {
05564     errStream << "- - - - - - - - - - - - - - - - - - - - - - - " 
05565               << endl;
05566     
05567     shared_ptr<AST> mod = uocAst;
05568     for (size_t i=0; i < mod->children.size(); i++) {
05569       shared_ptr<AST> ast = mod->child(i);
05570       //errStream << ast->atKwd() << std::endl;
05571       if (ast->astType == at_define || ast->astType == at_recdef) {
05572         shared_ptr<AST> id = ast->child(0)->child(0);
05573         errStream << id->asString() << ": "        
05574                   << id->scheme->asString(Options::debugTvP, true)
05575                   << std::endl;
05576       }
05577     }
05578     
05579     errStream << "________________________________________" 
05580               << std::endl;
05581   }
05582 
05583   
05584   return errFree;
05585 }
05586 
05587 bool 
05588 UocInfo::TypeCheck(std::ostream& errStream, bool init, 
05589                    TI_Flags ti_flags, std::string mesg)
05590 {
05591   bool errFree = true;
05592 
05593   // If one considers removing this clear clause,
05594   // be careful about old types. Pay attention to
05595   // bindIdentDef() function which preserves types
05596   // if a type already exists.
05597   uocAst->clearTypes();  
05598 
05599   errFree = DoTypeCheck(errStream, init, ti_flags);
05600   if (!errFree) 
05601     errStream << mesg
05602               << std::endl;
05603   return errFree;
05604 }
05605 
05606 bool
05607 UocInfo::fe_typeCheck(std::ostream& errStream,
05608                       bool init, unsigned long flags)
05609 {
05610   // Careful: the input flags are interface flags `uflags,'
05611   // and not the internal flags `flags.' 
05612   return DoTypeCheck(errStream, init, TI_NO_FLAGS);    
05613 }

Generated on Thu May 17 23:59:16 2012 for BitC Compiler by  doxygen 1.4.7