diff options
Diffstat (limited to 'src/lift.cpp')
-rw-r--r-- | src/lift.cpp | 23 |
1 files changed, 18 insertions, 5 deletions
diff --git a/src/lift.cpp b/src/lift.cpp index 7e7ec57..2c20aa8 100644 --- a/src/lift.cpp +++ b/src/lift.cpp @@ -70,9 +70,20 @@ AFn::lift(CEnv& cenv, Code& code) throw() // Create a new stub environment frame for parameters cenv.push(); - AType::const_iterator tp = cenv.type(this)->prot()->begin(); - for (const_iterator p = prot()->begin(); p != prot()->end(); ++p) - cenv.def((*p)->as<ASymbol*>(), *p, (*tp++)->as<AType*>(), NULL); + const AType* type = cenv.type(this); + AType::const_iterator tp = type->prot()->begin(); + AType* implProtT = new AType(*type->prot()->as<const AType*>()); + ATuple::iterator ip = implProtT->begin(); + for (const_iterator p = prot()->begin(); p != prot()->end(); ++p) { + const AType* paramType = (*tp++)->as<const AType*>(); + if (paramType->kind == AType::EXPR && *paramType->head() == *cenv.tenv.Fn) { + AType* fnType = new AType(*paramType); + fnType->prot()->push_front(const_cast<AType*>(cenv.tenv.var())); + paramType = tup<const AType>((*p)->loc, cenv.tenv.Tup, fnType, NULL); + } + cenv.def((*p)->as<ASymbol*>(), *p, paramType, NULL); + *ip++ = new AType(*paramType); + } /* Add closure parameter with dummy name (undefined symbol). * The name of this parameter will be changed to the name of this @@ -91,7 +102,7 @@ AFn::lift(CEnv& cenv, Code& code) throw() cenv.pop(); - // Set name of closure parameter to actual name of this function + // Set name of closure parameter to "me" *impl->prot()->begin() = cenv.penv.sym("me"); // Create definition for implementation fn @@ -99,11 +110,13 @@ AFn::lift(CEnv& cenv, Code& code) throw() ADef* def = tup<ADef>(loc, cenv.penv.sym("def"), implName, impl, NULL); code.push_back(def); - AType* implT = new AType(*cenv.type(this)); // Type of the implementation function + AType* implT = new AType(*type); // Type of the implementation function AType* tupT = tup<AType>(loc, cenv.tenv.Tup, cenv.tenv.var(), NULL); AType* consT = tup<AType>(loc, cenv.tenv.Tup, implT, NULL); ACons* cons = tup<ACons>(loc, cenv.penv.sym("cons"), implName, NULL); // Closure + *(implT->begin() + 1) = implProtT; + const CEnv::FreeVars& freeVars = cenv.liftStack.top(); for (CEnv::FreeVars::const_iterator i = freeVars.begin(); i != freeVars.end(); ++i) { cons->push_back(*i); |