aboutsummaryrefslogtreecommitdiffstats
path: root/src/lift.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/lift.cpp')
-rw-r--r--src/lift.cpp23
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);