00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
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 "UocInfo.hxx"
00046 #include "Options.hxx"
00047 #include "AST.hxx"
00048 #include "Type.hxx"
00049 #include "TypeScheme.hxx"
00050 #include "TypeMut.hxx"
00051 #include "Typeclass.hxx"
00052 #include "inter-pass.hxx"
00053 #include "TypeInfer.hxx"
00054 #include "TypeInferCommon.hxx"
00055
00056 using namespace sherpa;
00057 using namespace std;
00058
00059
00060
00061
00062
00063
00064
00065 GCPtr<Type>
00066 obtainFullUnionType(GCPtr<Type> t)
00067 {
00068
00069
00070
00071
00072 t = t->getBareType();
00073 assert(t->isUType());
00074 GCPtr<AST> unin = t->myContainer;
00075 GCPtr<TypeScheme> uScheme = unin->scheme;
00076 GCPtr<Type> uType = uScheme->type_instance_copy();
00077
00078 assert(uType->typeArgs->size() == t->typeArgs->size());
00079
00080 for(size_t c=0; c < uType->typeArgs->size(); c++)
00081 t->TypeArg(c)->unifyWith(uType->TypeArg(c));
00082
00083
00084
00085
00086
00087 return uType;
00088 }
00089
00090
00091
00092
00093
00094
00095
00096
00097 void
00098 useIFGamma(const std::string& idName,
00099 GCPtr<Environment<TypeScheme> > fromEnv,
00100 GCPtr<Environment<TypeScheme> > toEnv)
00101 {
00102 for (size_t i = 0; i < fromEnv->bindings->size(); i++) {
00103 GCPtr<Binding<TypeScheme> > bdng = fromEnv->bindings->elem(i);
00104
00105 if (bdng->flags & BF_PRIVATE)
00106 continue;
00107
00108 std::string s = bdng->nm;
00109 GCPtr<TypeScheme> ts = bdng->val;
00110
00111 if (idName.size())
00112 s = idName + "." + s;
00113
00114 toEnv->addBinding(s, ts);
00115 toEnv->setFlags(s, BF_PRIVATE|BF_COMPLETE);
00116 }
00117 }
00118
00119
00120
00121
00122
00123 bool
00124 useIFInsts(std::ostream &errStream,
00125 LexLoc &errLoc,
00126 GCPtr<Environment< CVector<GCPtr<Instance> > > >fromEnv,
00127 GCPtr<Environment< CVector<GCPtr<Instance> > > >toEnv,
00128 unsigned long uflags)
00129 {
00130 bool errFree = true;
00131 for (size_t i = 0; i < fromEnv->bindings->size(); i++) {
00132 GCPtr<Binding< CVector<GCPtr<Instance> > > >bdng =
00133 fromEnv->bindings->elem(i);
00134
00135 if (bdng->flags & BF_PRIVATE)
00136 continue;
00137
00138 std::string s = bdng->nm;
00139 GCPtr<CVector<GCPtr<Instance> > > fromInsts = bdng->val;
00140 GCPtr<CVector<GCPtr<Instance> > > toInsts = toEnv->getBinding(s);
00141
00142 if(!toInsts) {
00143 toInsts = new CVector<GCPtr<Instance> >;
00144 for (size_t j = 0; j < fromInsts->size(); j++)
00145 toInsts->append(fromInsts->elem(j));
00146 toEnv->addBinding(s, toInsts);
00147 }
00148 else {
00149 for (size_t j = 0; j < fromInsts->size(); j++) {
00150 size_t k;
00151 bool mustAppend = true;
00152 GCPtr<Instance> fromInst = fromInsts->elem(j);
00153
00154 for (k = 0; k < toInsts->size(); k++) {
00155 GCPtr<Instance> toInst = toInsts->elem(k);
00156
00157 if(toInst == fromInst) {
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167 mustAppend = false;
00168 break;
00169 }
00170
00171 if((uflags & ALL_INSTS_OK) == 0)
00172 if(toInst->equals(errStream, fromInst, toEnv)) {
00173 errStream << errLoc << ": "
00174 << "Conflict in Instance declarations "
00175 << " of type "
00176 << toInsts->elem(k)->asString()
00177 << " defined at "
00178 << toInsts->elem(k)->ast->loc << " and "
00179 << fromInsts->elem(j)->ast->loc << "."
00180 << std::endl;
00181 errFree = false;
00182 mustAppend = false;
00183 break;
00184 }
00185 }
00186
00187 if(mustAppend)
00188 toInsts->append(fromInsts->elem(j));
00189 }
00190 }
00191 }
00192
00193 return errFree;
00194 }
00195
00196
00197 bool
00198 initGamma(std::ostream& errStream,
00199 GCPtr<Environment<TypeScheme> > gamma,
00200 GCPtr<Environment< CVector<GCPtr<Instance> > > > instEnv,
00201 const GCPtr<AST> ast, unsigned long uflags)
00202 {
00203 bool errFree = true;
00204
00205
00206
00207 if(ast->child(0)->astType == at_interface &&
00208 ast->child(0)->child(0)->s == "bitc.prelude") {
00209
00210 return true;
00211 }
00212
00213
00214 GCPtr<Environment<TypeScheme> > preenv = 0;
00215 GCPtr<Environment< CVector<GCPtr<Instance> > > > preInsts = 0;
00216
00217 size_t i;
00218
00219 for(i=0; i < UocInfo::ifList->size(); i++) {
00220 if(UocInfo::ifList->elem(i)->uocName == "bitc.prelude") {
00221 preenv = UocInfo::ifList->elem(i)->gamma;
00222 preInsts = UocInfo::ifList->elem(i)->instEnv;
00223 break;
00224 }
00225 }
00226
00227 if(i == UocInfo::ifList->size()) {
00228 errStream << ast->loc << ": "
00229 << "Internal Compiler Error. "
00230 << "Prelude has NOT been processed till "
00231 << "type inference."
00232 << std::endl;
00233 return false;
00234 }
00235
00236 if(!preenv || !preInsts) {
00237 errStream << ast->loc << ": "
00238 << "Internal Compiler Error. "
00239 << "Prelude's Gamma is NULL "
00240 << std::endl;
00241 return false;
00242 }
00243
00244 useIFGamma(std::string(), preenv, gamma);
00245 LexLoc internalLocation;
00246 CHKERR(errFree, useIFInsts(errStream, internalLocation,
00247 preInsts, instEnv, uflags));
00248 return errFree;
00249 }
00250
00251