TypeEqInfer.cxx

Go to the documentation of this file.
00001 /**************************************************************************
00002  *
00003  * Copyright (C) 2006, 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 <stdint.h>
00039 #include <stdlib.h>
00040 #include <iostream>
00041 #include <string>
00042 #include <sstream>
00043 #include <libsherpa/UExcept.hxx>
00044 #include <libsherpa/CVector.hxx>
00045 #include <assert.h>
00046 #include "UocInfo.hxx"
00047 #include "Options.hxx"
00048 #include "AST.hxx"
00049 #include "Type.hxx"
00050 #include "TypeScheme.hxx"
00051 #include "Typeclass.hxx"
00052 #include "inter-pass.hxx"
00053 #include <libsherpa/BigNum.hxx>
00054 #include "TypeInfer.hxx"
00055 #include "TypeEqInfer.hxx"
00056 #include "TypeInferCommon.hxx"
00057 
00058 
00059 //WARNING: **REQUIRES** errFree.
00060 #define TYPEEQINFER(ast, gamma, instEnv, impTypes, isVP, tcc,   \
00061                     uflags, trail, mode, flags)                 \
00062   do {                                                          \
00063     CHKERR((errFree),                                           \
00064            (typeEqInfer(errStream, (ast), (gamma), (instEnv),   \
00065                         (impTypes), (isVP), (tcc), (uflags),    \
00066                         (trail), (mode), (flags))));            \
00067   }while(0)
00068 
00069 #define PRINT(out, ast, ct)                             \
00070   do {                                                  \
00071     out << "[" << ast->atKwd() << "]"                   \
00072         << ast->asString() << " : "                     \
00073         << ctypeAsString(ast->symType, ct, true)        \
00074         << std::endl;                                   \
00075   } while(0)
00076 
00077 std::string
00078 ctypeAsString(GCPtr<Type> t, GCPtr<Constraints> cset,
00079               bool showAllCts=false);
00080 
00081 
00082 /**************************************************************/
00083 /*                     Some Helper Functions                  */
00084 /**************************************************************/
00085 
00086 /* Some of the following fure repeated (and marked static) in both 
00087    inference routines due to the use/non-use of maybe types */
00088 
00089 static GCPtr<Type> 
00090 buildFnFromApp(GCPtr<AST> ast, unsigned long uflags)
00091 {
00092   assert(ast->astType == at_apply);
00093   GCPtr<Type> fn = new Type (ty_fn, ast);
00094   GCPtr<Type> targ = new Type(ty_fnarg, ast);
00095   for (size_t i = 1; i < ast->children->size(); i++) {
00096     GCPtr<Type> argi = new Type(ty_tvar, ast->child(i));
00097     targ->components->append(new comp(argi));
00098   }
00099   
00100   fn->components->append(new comp(targ));
00101   GCPtr<Type> ret = new Type(ty_tvar, ast);
00102   fn->components->append(new comp(ret));
00103   
00104   return fn;
00105 }
00106 
00107 
00108 static GCPtr<TypeScheme> 
00109 bindIdentDef(GCPtr<AST> ast, 
00110              GCPtr<Environment<TypeScheme> > gamma,
00111              unsigned long bindFlags,
00112              unsigned long flags)
00113 {
00114   if(ast->Flags2 & ID_IS_MUTATED) {
00115     assert((flags & TI_TYP_EXP) == 0);
00116     assert((ast->Flags & ID_IS_TVAR) == 0);
00117     ast->symType = new Type(ty_mutable, new Type(ty_tvar, ast));
00118   }
00119   else
00120     ast->symType = new Type(ty_tvar, ast); 
00121   
00122   GCPtr<TypeScheme> sigma = new TypeScheme(ast->symType);
00123   ast->scheme = sigma;
00124   
00125   if (ast->Flags & ID_IS_TVAR) {
00126     assert(flags & TI_TYP_EXP);
00127     bindFlags |= BF_NO_MERGE;
00128     ast->tvarLB->envs.gamma->addBinding(ast->s, sigma);
00129   }
00130   else {
00131     gamma->addBinding(ast->s, sigma);      
00132   }
00133   
00134   gamma->setFlags(ast->s, bindFlags);    
00135   return sigma;
00136 }
00137 
00138 static GCPtr<TypeScheme> 
00139 Instantiate(GCPtr<AST> ast, GCPtr<TypeScheme> sigma)
00140 {             
00141   if(ast->symbolDef)
00142     ast = ast->symbolDef;
00143   
00144   if(ast->Flags & ID_IS_CTOR)
00145     return sigma->ts_instance_copy();
00146   else
00147     return sigma->ts_instance();
00148 }
00149 
00150 /**************************************************************/
00151 /*                     Constraint Generation                  */
00152 /**************************************************************/
00153 
00154 void
00155 addSubCst(GCPtr<AST> errAst, GCPtr<Type> t1, GCPtr<Type> t2,
00156           GCPtr<Constraints> tcc)
00157 {
00158   GCPtr<Constraint> sub = new Constraint(ty_subtype, errAst, 
00159                                          t1->getType(), t2->getType());
00160   tcc->addPred(sub);
00161 }
00162 
00163 void
00164 addEqCst(GCPtr<AST> errAst, GCPtr<Type> t1, GCPtr<Type> t2,
00165          GCPtr<Constraints> tcc)
00166 {
00167   addSubCst(errAst, t1, t2, tcc);
00168   addSubCst(errAst, t2, t1, tcc);
00169 }
00170         
00171 void
00172 addCcCst(GCPtr<AST> errAst, GCPtr<Type> t1, GCPtr<Type> t2,
00173          GCPtr<Constraints> tcc)
00174 {
00175   GCPtr<Type> via = new Type(ty_tvar, errAst);
00176   addSubCst(errAst, t1, via, tcc);
00177   addSubCst(errAst, t2, via, tcc);
00178 }
00179 
00180 void
00181 addPcst(GCPtr<AST> errAst, GCPtr<Type> t, GCPtr<Constraints> tcc)
00182 {
00183   GCPtr<Type> k = new Type(ty_kvar, errAst);
00184   t = t->getType();
00185   GCPtr<Constraint> pcst = new Constraint(ty_pcst, errAst);  
00186   pcst->components->append(new comp(k));
00187   pcst->components->append(new comp(t));
00188   pcst->components->append(new comp(t));
00189   tcc->addPred(pcst);
00190 }
00191 
00192 /**************************************************************/
00193 /****                   MAIN INFERENCE FUNCTION            ****/
00194 /**************************************************************/
00195 
00196 
00197 bool
00198 typeEqInfer(std::ostream& errStream, GCPtr<AST> ast, 
00199             GCPtr<Environment<TypeScheme> > gamma,
00200             GCPtr<Environment< CVector<GCPtr<Instance> > > > instEnv,
00201             GCPtr< CVector<GCPtr<Type> > >impTypes,
00202             bool isVP, 
00203             GCPtr<Constraints> tcc,
00204             unsigned long uflags,
00205             GCPtr<Trail> trail,
00206             int mode,
00207             unsigned flags)
00208 {
00209   bool errFree = true;
00210   
00211   // Save the current environment in the AST.
00212   // If we create a new environment, we will update it later.
00213   ast->envs.gamma = gamma;
00214   ast->envs.instEnv = instEnv;  
00215   
00216   switch(ast->astType) {
00217     
00218   default:
00219     {
00220       errStream << ast->loc << ": Unhandled case: " 
00221                 << ast->astTypeName() << std::endl;
00222       
00223       errFree = false;
00224       break;
00225     }
00226 
00227   case at_boolLiteral:
00228     {
00229       ast->symType = new Type(ty_bool, ast);
00230       PRINT(errStream, ast, tcc);
00231       break;
00232     }
00233 
00234   case at_charLiteral:
00235     {
00236       ast->symType = new Type(ty_char, ast);
00237       PRINT(errStream, ast, tcc);
00238       break;
00239     }
00240 
00241   case at_intLiteral:
00242     {      
00243       ast->symType = new Type(ty_int32, ast);
00244       PRINT(errStream, ast, tcc);
00245       break;
00246     }
00247 
00248   case at_floatLiteral:
00249     {
00250       ast->symType = new Type(ty_float, ast);
00251       PRINT(errStream, ast, tcc);
00252       break;
00253     }
00254     
00255   case at_stringLiteral:
00256     {
00257       ast->symType = new Type(ty_string, ast);
00258       PRINT(errStream, ast, tcc);
00259       break;
00260     }
00261 
00262   case at_ident:
00263     {
00264       switch(mode) {
00265       case DEF_MODE:
00266         {
00267           unsigned long bindFlags = 0;
00268           GCPtr<TypeScheme> sigma = gamma->getBinding(ast->s);
00269 
00270           if(sigma) {       
00271             if(ast->isDecl) {
00272               /* Note: This case is ONLY used for proclaims. 
00273                  structure and union declarations and definitions
00274                  do not make this recursive call */
00275               
00276               // We need to preserve this un-unified until after the
00277               // real type is inferred. So, this unification will now be
00278               // done in handle-decls.
00279               //
00280               //   CHKERR(errFree, unify(errStream, trail, gamma, 
00281               //                         ast, ast->symType, 
00282               //                               sigma->tau, uflags));
00283               //
00284               // Make way for the actual definition of the type.
00285              
00286               ast->symType = new Type(ty_tvar, ast);
00287               GCPtr<TypeScheme> sigma = new TypeScheme(ast->symType, ast, NULL);
00288               ast->symType->getBareType()->defAst = sigma->tau->getBareType()->defAst;
00289               ast->scheme = sigma;
00290             }
00291             else {            
00292               bindFlags = BF_REBIND;
00293               sigma = bindIdentDef(ast, gamma, bindFlags, flags);
00294               ast->symType->defAst = sigma->tau->getType()->defAst = ast;
00295               break;
00296             }
00297           }
00298           else
00299             sigma = bindIdentDef(ast, gamma, bindFlags, flags);   
00300           break;
00301         }
00302       
00303       case REDEF_MODE:
00304         {
00305           (void) bindIdentDef(ast, gamma, BF_REBIND, flags);
00306           break;
00307         }
00308 
00309       case USE_MODE:
00310         {
00311           assert(tcc);
00312 
00313           GCPtr<TypeScheme> sigma = gamma->getBinding(ast->s);
00314           if(!sigma) {
00315 
00316             // If this is a type variable that is used as in
00317             //
00318             //   (define a:'a 10)
00319             //
00320             // there will be no prior definition of it ('a).  So, it
00321             // should now be defined.  In-correct usages should be
00322             // taken care of by the symbol resolver.  So, it is safe
00323             // to add this type to Gamma now.
00324 
00325             if((ast->identType == id_type) && (ast->Flags & ID_IS_TVAR)) {
00326               sigma = bindIdentDef(ast, gamma, 0, flags);             
00327             }
00328             else {  
00329               errStream << ast->loc << ": "
00330                         << ast->s << " Unbound in Gamma" << std::endl;
00331               
00332               //errStream << "Available bindings are: "
00333               //          << gamma->asString()
00334               //          << std::endl;       
00335               
00336               ast->symType = new Type(ty_tvar, ast);
00337               return false;
00338             }
00339           }
00340           
00341           GCPtr<TypeScheme> tsIns =  Instantiate(ast, sigma);
00342           GCPtr<Type> ins = tsIns->tau->getType();
00343           ast->symType = ins;
00344           
00345 #ifdef VERBOSE  
00346           errStream << " For " << ast->s << ":\n";
00347           errStream << "Obtained " << ins->asString()
00348                     << " From " << sigma->asString() << std::endl;
00349 #endif
00350               
00351           ins = ins->getBareType();
00352 
00353           if((flags & TI_TYP_EXP) && 
00354              ((flags & TI_TYP_APP) == 0) && 
00355              (ins->typeArgs->size() > 0)) {
00356             errStream << ast->loc << ": "
00357                       << ast->s << " cannot be instantiated without " 
00358                       << ins->typeArgs->size() << " type arguments."
00359                       << std::endl;
00360             
00361             ast->symType = new Type(ty_tvar, ast);
00362             return false;
00363           }
00364           
00365           if(tsIns->tcc) {
00366             for(size_t i = 0; i < tsIns->tcc->pred->size(); i++) {
00367               GCPtr<Typeclass> pred = tsIns->tcc->Pred(i)->getType();         
00368               if(flags & TI_TCC_SUB)
00369                 pred->flags |= TY_CT_SUBSUMED;
00370               tcc->addPred(pred);
00371             }
00372           }
00373           break;
00374         }
00375       }
00376       PRINT(errStream, ast, tcc);
00377       break;
00378     }
00379 
00380   case at_start:
00381     {
00382       // match at_module
00383     
00384       TYPEEQINFER(ast->child(0), gamma, instEnv, impTypes, isVP, tcc,
00385                   uflags, trail,  mode, TI_NONE);
00386     
00387       if (ast->children->size() > 1) {
00388         // match at_version
00389         TYPEEQINFER(ast->child(1), gamma, instEnv, impTypes, isVP, tcc,
00390                     uflags, trail,  mode, TI_NONE);
00391       }
00392 
00393       break;
00394     }
00395 
00396   case at_version:
00397     {
00398       break;
00399     }
00400     
00401   case at_module:
00402     {
00403       // FIX: This must be eventually removed when 
00404       // new constraint sets are created at every define
00405       GCPtr<TCConstraints> tcc = new TCConstraints;
00406       for(size_t c = 0; c < ast->children->size(); c++) {
00407         TYPEEQINFER(ast->child(c), gamma, instEnv, impTypes, isVP, tcc,
00408                     uflags, trail,  mode, TI_NONE);
00409       }
00410       break;
00411     }
00412     
00413   case at_interface:
00414     {
00415       // match agt_definition*
00416       
00417       // FIX: This must be eventually removed when 
00418       // new constraint sets are created at every define
00419       GCPtr<TCConstraints> tcc = new TCConstraints;
00420       for(size_t c = 1; c < ast->children->size(); c++)
00421         TYPEEQINFER(ast->child(c), gamma, instEnv, impTypes, isVP, tcc,
00422                     uflags, trail,  mode, TI_NONE);
00423       break;
00424     }
00425 
00426   case at_define:
00427     {
00428       // Maybe, we have a prior declaration?
00429       GCPtr<AST> ident = ast->child(0)->child(0);
00430       
00431       GCPtr<TypeScheme> declTS = gamma->getBinding(ident->s);
00432       
00433       GCPtr<Environment<TypeScheme> > defGamma = gamma->newDefScope();
00434       ast->envs.gamma = defGamma;
00435 
00436       // This is the right place to start constraints, but for now, 
00437       // define is like  let .... 
00438       //GCPtr<TCConstraints> currTcc = new TCConstraints;
00439       GCPtr<TCConstraints> currTcc = tcc;
00440       
00441       // match agt_bindingPattern
00442       // match agt_expr
00443       TYPEEQINFER(ast->child(0), defGamma, instEnv, impTypes, isVP, 
00444                   currTcc, uflags, trail, DEF_MODE, TI_NONE);
00445       
00446       TYPEEQINFER(ast->child(1), defGamma, instEnv, impTypes, isVP, 
00447                   currTcc, uflags, trail, USE_MODE, TI_NONE);
00448       
00449       TYPEEQINFER(ast->child(2), defGamma, instEnv, impTypes, isVP, 
00450                   currTcc, uflags, trail,  mode, TI_CONSTR);
00451       
00452       GCPtr<Type> lhsType = ast->child(0)->symType->getType();
00453       GCPtr<Type> rhsType = ast->child(1)->symType;
00454       
00455       addCcCst(ast, lhsType, rhsType, currTcc);
00456       //       CHKERR(errFree, unify(errStream, trail, ast->child(0), 
00457       //                            lhsType, rhsType, uflags));
00458       
00459       //       CHKERR(errFree, generalizePat(errStream, ast->loc, 
00460       //                                    gamma, instEnv, 
00461       //                                    ast->child(0),
00462       //                                    ast->child(1), 
00463       //                                    false, currTcc, NULL, trail));
00464       
00465       gamma->mergeBindingsFrom(defGamma);
00466       //       if(declTS) 
00467       //        CHKERR(errFree, matchDefDecl(errStream, trail, gamma, instEnv,
00468       //                                     declTS, ident->scheme, uflags, true));     
00469       
00470       ast->symType = ast->child(0)->symType;
00471       
00472       GCPtr<AST> id = ast->getID();
00473 
00474       addPcst(ast, id->symType, currTcc);
00475       
00476       errStream << "[define]"           
00477                 << id->asString() << ": "       
00478                 << ctypeAsString(id->symType, currTcc, true)
00479                 << std::endl;
00480       
00481       EqUnify(errStream, currTcc, trail);
00482       errStream << "  UNF:"
00483                 << id->asString() << ": "
00484                 << ctypeAsString(id->symType, currTcc, true)
00485                 << std::endl;
00486       
00487       id->scheme = new TypeScheme(id->symType, currTcc);
00488 
00489       //PRINT(errStream, ast, currTcc);
00490       break;
00491     }
00492     
00493   case at_constraints:
00494     {
00495       for(size_t c=0; c < ast->children->size(); c++)      
00496         TYPEEQINFER(ast->child(c), gamma, instEnv, impTypes, isVP, tcc,
00497                     uflags, trail,  mode, TI_CONSTR);
00498       ast->symType = new Type(ty_tvar, ast);
00499       break;
00500     }    
00501 
00502 
00503   case at_refType:
00504     {
00505       // match agt_type
00506       TYPEEQINFER(ast->child(0), gamma, instEnv, impTypes, isVP, tcc,
00507                   uflags, trail,  USE_MODE, TI_COMP1);
00508     
00509       GCPtr<Type> t = ast->child(0)->getType();
00510       
00511       ast->symType = new Type(ty_ref, ast);
00512       ast->symType->components->append(new comp(t));
00513       
00514       PRINT(errStream, ast, tcc);
00515       break;
00516     }
00517     
00518   case at_exceptionType:
00519     {
00520       ast->symType = new Type(ty_exn, ast);
00521       PRINT(errStream, ast, tcc);
00522       break;
00523     }
00524 
00525   case at_dummyType:
00526     {
00527       ast->symType = new Type(ty_dummy, ast);
00528       PRINT(errStream, ast, tcc);
00529       break;
00530     }
00531 
00532   case at_fn:
00533     {
00534       TYPEEQINFER(ast->child(0), gamma, instEnv, impTypes, isVP, tcc,
00535                   uflags, trail,  mode, TI_COMP1);
00536       TYPEEQINFER(ast->child(1), gamma, instEnv, impTypes, isVP, tcc,
00537                   uflags, trail,  mode, TI_COMP1);
00538       
00539       ast->symType = new Type(ty_fn, ast);
00540       GCPtr<Type> fnarg = ast->child(0)->symType->getType();
00541       ast->symType->components->append(new comp(fnarg));
00542       GCPtr<comp> nComp = new comp(ast->child(1)->getType());
00543       ast->symType->components->append(nComp);    
00544       PRINT(errStream, ast, tcc);
00545       break;
00546     }
00547 
00548   case at_fnargVec:
00549     {      
00550       GCPtr<Type> fnarg = new Type(ty_fnarg, ast);
00551       for (size_t c = 0; c < ast->children->size(); c++) {
00552         TYPEEQINFER(ast->child(c), gamma, instEnv, impTypes, isVP, tcc,
00553                     uflags, trail, mode, TI_COMP1);
00554         GCPtr<Type> argType = ast->child(c)->symType->getType();
00555 
00556         GCPtr<comp> nComp = new comp(argType);  
00557         if(argType->isByrefType()) {
00558           nComp = new comp(argType->CompType(0));
00559           nComp->flags |= COMP_BYREF;
00560         }
00561         
00562         fnarg->components->append(nComp);
00563       }
00564       ast->symType = fnarg;
00565       break;
00566     }
00567 
00568   case at_primaryType:
00569     {
00570       ast->symType = new Type(Type::LookupKind(ast->s), ast);
00571       PRINT(errStream, ast, tcc);
00572       break;
00573     }
00574 
00575   case at_mutableType:
00576     {
00577       // match agt_type
00578       TYPEEQINFER(ast->child(0), gamma, instEnv, impTypes, isVP, tcc,
00579                   uflags, trail,  USE_MODE, TI_COMP1);
00580     
00581       GCPtr<Type> t = ast->child(0)->symType->getType();
00582       
00583       if(t->kind == ty_mutable) {
00584         //The Type is already mutable
00585         ast->symType = t;
00586       }
00587       else {
00588         ast->symType = new Type(ty_mutable, ast);
00589         ast->symType->components->append(new comp(t));
00590       }
00591       PRINT(errStream, ast, tcc);
00592       break;
00593     }
00594 
00595   case at_identPattern:
00596     {
00597       
00598       if(ast->Flags & AST_IS_VALPAT) {
00599         // AST_IS_VALPAT ONLY for the ROOT of a case leg
00600         assert(mode == REDEF_MODE);
00601 
00602         GCPtr<AST> var = ast->child(0);
00603         GCPtr<AST> def = var->symbolDef;
00604 
00605         if((def) && def->isUnionLeg()) {
00606           TYPEEQINFER(ast->child(0), gamma, instEnv, impTypes, isVP, tcc,
00607                       uflags, trail, USE_MODE, TI_COMP2);
00608         }
00609         else {
00610           // match agt_var
00611           TYPEEQINFER(ast->child(0), gamma, instEnv, impTypes, isVP, tcc,
00612                       uflags, trail, REDEF_MODE, TI_COMP2);
00613         }      
00614       }
00615       else {
00616         // match agt_var
00617         TYPEEQINFER(ast->child(0), gamma, instEnv, impTypes, isVP, tcc,
00618                     uflags, trail,  mode, TI_COMP2);
00619       }
00620       
00621       // Type Qualifications ONLY in Binding Patterns
00622       // match agt_type?
00623       if (ast->children->size() > 1) {
00624         TYPEEQINFER(ast->child(1), gamma, instEnv, impTypes, isVP, tcc,
00625                     uflags, trail,  USE_MODE, TI_COMP1);
00626       
00627         GCPtr<Type> qualType = (ast->child(1)->symType->isByrefType()?
00628                                 ast->child(1)->getType()->CompType(0):
00629                                 ast->child(1)->symType);
00630         
00631         addEqCst(ast, ast->child(0)->symType, qualType, tcc);
00632         
00633         // Very Important that we pick the type of 
00634         // the qualification, in light of by-ref types.
00635         ast->symType = ast->child(1)->symType;
00636         PRINT(errStream, ast, tcc);
00637       }
00638       else {
00639         ast->symType = ast->child(0)->symType;
00640       }
00641       
00642       break;
00643     }
00644 
00645   case at_tqexpr:
00646     {
00647       // match agt_eform
00648       TYPEEQINFER(ast->child(0), gamma, instEnv, impTypes, isVP, tcc,
00649                   uflags, trail,  USE_MODE, TI_COMP2);
00650     
00651       TYPEEQINFER(ast->child(1), gamma, instEnv, impTypes, isVP, tcc,
00652                   uflags, trail,  USE_MODE, TI_COMP1);
00653  
00654       addEqCst(ast, ast->child(0)->symType, 
00655                ast->child(1)->symType, tcc);
00656       
00657       ast->symType = ast->child(0)->symType;
00658       PRINT(errStream, ast, tcc);
00659       break;
00660     }
00661     
00662   case at_unit:
00663     {
00664       ast->symType = new Type(ty_unit, ast);
00665       PRINT(errStream, ast, tcc);
00666       break;
00667     }
00668     
00669   case at_lambda:
00670     {
00671       // match agt_bindingPattern
00672       // match agt_expr
00673       GCPtr<Environment<TypeScheme> > lamGamma = gamma->newScope();
00674       ast->envs.gamma = lamGamma;
00675       
00676       GCPtr<AST> argVec = ast->child(0);      
00677       GCPtr<Type> fnarg = new Type(ty_fnarg, ast->child(0));
00678       
00679       for (size_t c = 0; c < argVec->children->size(); c++) {
00680         GCPtr<AST> arg = argVec->child(c);
00681         TYPEEQINFER(arg, lamGamma, instEnv, impTypes, 
00682                     isVP, tcc, uflags, trail,  REDEF_MODE, TI_COMP2);
00683 
00684         GCPtr<Type> argInfType = arg->getType();
00685         
00686         if(argInfType->isByrefType()) {
00687           GCPtr<comp> nComp = new comp(argInfType->CompType(0));
00688           nComp->flags |= COMP_BYREF;
00689           fnarg->components->append(nComp);
00690         }
00691         else {  
00692           GCPtr<Type> argFnType = new Type(ty_tvar, arg);
00693           addSubCst(arg, argInfType, argFnType, tcc);
00694           GCPtr<comp> nComp = new comp(argFnType);
00695           fnarg->components->append(nComp);
00696         }
00697       }
00698       argVec->symType = fnarg;      
00699       
00700       GCPtr<AST> ret = ast->child(1);
00701       TYPEEQINFER(ret, lamGamma, instEnv, impTypes, 
00702                   isVP, tcc, uflags, trail,  USE_MODE, TI_COMP2);
00703       
00704       GCPtr<Type> retInfType = ast->child(1)->getType();
00705       GCPtr<Type> retFnType = new Type(ty_tvar, ret);
00706       addSubCst(ret, retFnType, retInfType, tcc);
00707       
00708       ast->symType = new Type(ty_fn, ast, fnarg, retFnType);
00709       PRINT(errStream, ast, tcc);
00710       break;
00711     }
00712 
00713   case at_argVec:
00714     {
00715       assert(false);
00716       break;
00717     }
00718 
00719   case at_apply:
00720     {
00721       // match agt_expr agt_expr
00722       ast->symType = new Type(ty_tvar, ast); 
00723       
00724       TYPEEQINFER(ast->child(0), gamma, instEnv, impTypes, isVP, tcc,
00725                   uflags, trail, USE_MODE, TI_COMP2);
00726       GCPtr<Type> t = ast->child(0)->symType->getType();
00727       GCPtr<Type> innerT = ast->child(0)->symType->getBareType();
00728       
00729       switch(innerT->kind) {
00730       case ty_tvar:
00731         {
00732           GCPtr<Type> fn = buildFnFromApp(ast, uflags);
00733           addSubCst(ast->child(0), t, fn, tcc);
00734           t = fn;
00735           // fall through
00736         }
00737         
00738       case ty_fn:
00739         {
00740           GCPtr<Type> targ = t->CompType(0)->getType();
00741           // This is what we fall in to in all of the apply cases.
00742           if ((ast->children->size()-1) != targ->components->size()) {
00743             errStream << ast->child(0)->loc << ": "
00744                       << "Function applied to wrong number of"
00745                       << " arguments.." 
00746                       << " at AST " << ast->asString()
00747                       << " fn Type is " 
00748                       << t->asString() << ", "
00749                       << "Expecting " << targ->components->size()
00750                       << " but obtained " 
00751                       << (ast->children->size()-1) << ";"
00752                       << std::endl;
00753             errFree = false;
00754             break;
00755           }
00756           
00757           for (size_t i = 0; i < ast->children->size()-1; i++) {
00758             GCPtr<AST> arg = ast->child(i+1);
00759             TYPEEQINFER(arg, gamma, instEnv, impTypes, isVP, tcc,
00760                         uflags, trail,  USE_MODE, TI_COMP2);
00761             
00762             GCPtr<Type> fnArgType = targ->CompType(i);
00763             GCPtr<Type> argType = arg->symType;
00764             
00765             if(targ->CompFlags(i) & COMP_BYREF) {
00766               // by-ref arguments need strict compatibality.
00767               addEqCst(arg, argType, fnArgType, tcc);
00768             }
00769             else {
00770               // by-value arguments can have copy-compatibility.
00771               addSubCst(arg, argType, fnArgType, tcc); 
00772             }
00773           }
00774           
00775           GCPtr<Type> retType = t->CompType(1);
00776           addSubCst(ast, retType, ast->symType, tcc);
00777           break;
00778         }
00779         
00780       case ty_structv:
00781       case ty_structr:
00782         {
00783           if(ast->child(0)->astType == at_ident &&
00784              (ast->child(0)->symbolDef->Flags & ID_IS_CTOR)) {
00785             ast->astType = at_struct_apply;
00786             TYPEEQINFER(ast, gamma, instEnv, impTypes, isVP, tcc,
00787                         uflags, trail,  USE_MODE, TI_COMP2);
00788           }
00789           else {
00790             errStream << ast->child(0)->loc
00791                       << ": Expected structure"
00792                       << " constructor taking at least one argument."
00793                       << std::endl;
00794             errFree = false;
00795           }
00796         
00797           break;
00798         }
00799 
00800       case ty_uconr:
00801       case ty_uconv:
00802       case ty_exn:
00803         {                 
00804           GCPtr<AST> ctr = ast->child(0);
00805           if((ctr->astType != at_ident) && 
00806              (ctr->astType != at_select)) {
00807             errStream << ast->child(0)->loc
00808                       << ": union/exception"
00809                       << " constructor expected."
00810                       << std::endl;
00811             errFree = false;        
00812             break;
00813           }         
00814 
00815           ctr = ctr->getCtr();
00816           if(ctr->symbolDef->Flags & ID_IS_CTOR) {
00817             ast->astType = at_ucon_apply;
00818             TYPEEQINFER(ast, gamma, instEnv, impTypes, isVP, tcc,
00819                         uflags, trail,  USE_MODE, TI_COMP2);
00820           }
00821           else { 
00822             errStream << ast->child(0)->loc
00823                       << ": Expected union/exception"
00824                       << " constructor taking at least one argument."
00825                       << std::endl;
00826             errFree = false;
00827           }
00828           break;
00829         }
00830       case ty_unionv:
00831       case ty_unionr:
00832         {
00833           errStream << ast->loc << ": "
00834                     << " Cannot use the union name to construct values."
00835                     << " Use one of its value constructors."
00836                     << std::endl;
00837           errFree = false;
00838           break;
00839         }
00840         //case at_usesel:
00841         //      assert(false);
00842         
00843       default: 
00844         {
00845           errStream << ast->child(0)->loc
00846                     << ": First argument in application must be a function"
00847                     << " or a value constructor."
00848                     << std::endl;
00849           errFree = false;
00850           break;
00851         }
00852       }
00853 
00854       PRINT(errStream, ast, tcc);
00855       break;
00856     }
00857 
00858   case at_if:
00859     {
00860       // match agt_expr
00861       TYPEEQINFER(ast->child(0), gamma, instEnv, impTypes, isVP, tcc,
00862                   uflags, trail,  mode, TI_COMP2);      
00863       
00864       addSubCst(ast->child(0), ast->child(0)->symType,
00865                 new Type(ty_bool, ast->child(0)), tcc); 
00866       
00867       // match agt_expr
00868       TYPEEQINFER(ast->child(1), gamma, instEnv, impTypes, isVP, tcc,
00869                   uflags, trail,  mode, TI_COMP2);
00870 
00871       // match agt_expr
00872       TYPEEQINFER(ast->child(2), gamma, instEnv, impTypes, isVP, tcc,
00873                   uflags, trail,  mode, TI_COMP2);
00874       
00875       // Type of the full expression
00876       ast->symType = new Type(ty_tvar, ast);
00877       
00878       // I am not using addCcCst() because it uses new type variables 
00879       // on every invocation.
00880       GCPtr<Type> latticeTop = new Type(ty_tvar, ast);
00881       addSubCst(ast->child(1), ast->child(1)->symType,
00882                 latticeTop, tcc);
00883       addSubCst(ast->child(2), ast->child(2)->symType,
00884                 latticeTop, tcc);
00885       addSubCst(ast, ast->symType,
00886                 latticeTop, tcc);
00887       
00888       PRINT(errStream, ast, tcc);
00889       break;
00890     }
00891 
00892   case at_setbang:
00893     {
00894       ast->symType = new Type(ty_unit, ast);
00895       
00896       // match agt_expr
00897       TYPEEQINFER(ast->child(0), gamma, instEnv, impTypes, isVP, tcc,
00898                   uflags, trail,  USE_MODE, TI_COMP2);
00899       
00900       GCPtr<Type> t = ast->child(0)->symType->getType();
00901       addSubCst(ast->child(0), ast->child(0)->symType, 
00902                 new Type(ty_mutable, 
00903                          new Type(ty_tvar, ast->child(0))), tcc);
00904       
00905       // match agt_expr
00906       TYPEEQINFER(ast->child(1), gamma, instEnv, impTypes, isVP, tcc,
00907                   uflags, trail,  USE_MODE, TI_COMP2);
00908       
00909       addSubCst(ast->child(1), ast->child(0)->symType, 
00910                 ast->child(0)->symType, tcc);
00911       
00912       PRINT(errStream, ast, tcc);
00913       break;
00914     }
00915 
00916   case at_dup:
00917     {
00918       // match agt_expr
00919       TYPEEQINFER(ast->child(0), gamma, instEnv, impTypes, isVP, tcc,
00920                   uflags, trail,  USE_MODE, TI_COMP2);
00921       
00922       GCPtr<Type> copyType = new Type(ty_tvar, ast->child(0));
00923       ast->symType = new Type(ty_ref, copyType);
00924       
00925       addCcCst(ast->child(0), copyType, ast->child(0)->symType, tcc);
00926       
00927       PRINT(errStream, ast, tcc);
00928       break;      
00929     }
00930 
00931   case at_deref:
00932     {
00933       // match agt_expr
00934       TYPEEQINFER(ast->child(0), gamma, instEnv, impTypes, isVP, tcc,
00935                   uflags, trail,  USE_MODE, TI_COMP2);
00936       
00937       ast->symType = new Type(ty_tvar, ast);
00938       GCPtr<Type> expectType = new Type(ty_ref, ast->symType);
00939       
00940       addSubCst(ast->child(0), ast->child(0)->symType,
00941                 expectType, tcc);
00942       
00943       PRINT(errStream, ast, tcc);
00944       break;
00945     }
00946     
00947   } /* switch */
00948   
00949   return errFree;  
00950 }
00951 

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