aboutsummaryrefslogtreecommitdiffstats
path: root/src/lift.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/lift.cpp')
-rw-r--r--src/lift.cpp90
1 files changed, 48 insertions, 42 deletions
diff --git a/src/lift.cpp b/src/lift.cpp
index 563fd5d..81b157d 100644
--- a/src/lift.cpp
+++ b/src/lift.cpp
@@ -57,12 +57,8 @@ AQuote::lift(CEnv& cenv, Code& code) throw()
AST*
ATuple::lift(CEnv& cenv, Code& code) throw()
{
- ATuple* ret = new ATuple(*this);
- iterator ri = ret->begin();
- FOREACHP(const_iterator, t, this)
- *ri++ = (*t)->lift(cenv, code);
- cenv.setTypeSameAs(ret, this);
- return ret;
+ assert(false);
+ return NULL;
}
AST*
@@ -84,24 +80,24 @@ AFn::lift(CEnv& cenv, Code& code) throw()
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()));
+ fnType->prot(new AType(const_cast<AType*>(cenv.tenv.var()), fnType->prot()->as<AType*>(), Cursor()));
paramType = tup<const AType>((*p)->loc, cenv.tenv.Tup, fnType, NULL);
}
- cenv.def((*p)->as<ASymbol*>(), *p, paramType, NULL);
+ cenv.def((*p)->as<const ASymbol*>(), *p, paramType, NULL);
*ip++ = new AType(*paramType);
}
- /* Add closure parameter with dummy name (undefined symbol).
+ /* Prepend closure parameter with dummy name (undefined symbol).
* The name of this parameter will be changed to the name of this
* function after lifting the body (so recursive references correctly
* refer to this function by the closure parameter).
*/
- impl->prot()->push_front(cenv.penv.sym("_"));
+ impl->prot(new ATuple(cenv.penv.sym("_"), impl->prot()));
// Lift body
const AType* implRetT = NULL;
- iterator ci = impl->begin() + 2;
- for (const_iterator i = begin() + 2; i != end(); ++i, ++ci) {
+ iterator ci = impl->iter_at(2);
+ for (iterator i = iter_at(2); i != end(); ++i, ++ci) {
*ci = (*i)->lift(cenv, code);
implRetT = cenv.type(*ci);
}
@@ -117,22 +113,22 @@ AFn::lift(CEnv& cenv, Code& code) throw()
code.push_back(def);
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("Closure"), implName, NULL);
+ TList tupT(loc, cenv.tenv.Tup, cenv.tenv.var(), NULL);
+ TList consT(loc, cenv.tenv.Tup, implT, NULL);
+ List<ACons, AST> cons(loc, cenv.penv.sym("Closure"), implName, NULL);
- *(implT->begin() + 1) = implProtT;
+ implT->list_ref(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);
- tupT->push_back(const_cast<AType*>(cenv.type(*i)));
- consT->push_back(const_cast<AType*>(cenv.type(*i)));
+ cons.push_back(*i);
+ tupT.push_back(const_cast<AType*>(cenv.type(*i)));
+ consT.push_back(const_cast<AType*>(cenv.type(*i)));
}
cenv.liftStack.pop();
- implT->prot()->push_front(tupT);
- *(implT->begin() + 2) = const_cast<AType*>(implRetT);
+ implT->prot(new AType(tupT, implT->prot(), Cursor()));
+ implT->list_ref(2) = const_cast<AType*>(implRetT);
cenv.setType(impl, implT);
cenv.setType(cons, consT);
@@ -147,19 +143,22 @@ AFn::lift(CEnv& cenv, Code& code) throw()
AST*
ACall::lift(CEnv& cenv, Code& code) throw()
{
- ACall* copy = new ACall(this);
- ATuple::iterator ri = copy->begin();
+ List<ACall, AST> copy;
// Lift all children (callee and arguments, recursively)
- for (const_iterator i = begin(); i != end(); ++i)
- *ri++ = (*i)->lift(cenv, code);
+ for (iterator i = begin(); i != end(); ++i)
+ copy.push_back((*i)->lift(cenv, code));
+
+ copy.head->loc = loc;
+ const AType* copyT = NULL;
+
ASymbol* sym = head()->to<ASymbol*>();
if (sym && !cenv.liftStack.empty() && sym->cppstr == cenv.liftStack.top().fn->name) {
/* Recursive call to innermost function, call implementation directly,
* reusing the current "_me" closure parameter (no cons or .).
*/
- copy->push_front(cenv.penv.sym(cenv.liftStack.top().implName));
+ copy.push_front(cenv.penv.sym(cenv.liftStack.top().implName));
} else if (head()->to<AFn*>()) {
/* Special case: ((fn ...) ...)
* Lifting (fn ...) yields: (Fn _impl ...).
@@ -168,24 +167,25 @@ ACall::lift(CEnv& cenv, Code& code) throw()
* closure as the first parameter:
* (_impl (Fn _impl ...) ...)
*/
- ACons* closure = (*copy->begin())->as<ACons*>();
- ASymbol* implSym = (*(closure->begin() + 1))->as<ASymbol*>();
+ ACons* closure = copy.head->list_ref(0)->as<ACons*>();
+ ASymbol* implSym = closure->list_ref(1)->as<ASymbol*>();
const AType* implT = cenv.type(cenv.resolve(implSym));
- copy->push_front(implSym);
- cenv.setType(copy, (*(implT->begin() + 2))->as<const AType*>());
+ copy.push_front(implSym);
+ copyT = implT->list_ref(2)->as<const AType*>();
} else {
// Call to a closure, prepend code to access implementation function
ADot* getFn = tup<ADot>(loc, cenv.penv.sym("."),
- copy->head(),
- new ALiteral<int32_t>(0, Cursor()), NULL);
- const AType* calleeT = cenv.type(copy->head());
+ copy.head->head(),
+ new ALiteral<int32_t>(0, Cursor()), NULL);
+ const AType* calleeT = cenv.type(copy.head->head());
assert(**calleeT->begin() == *cenv.tenv.Tup);
- const AType* implT = (*(calleeT->begin() + 1))->as<const AType*>();
- copy->push_front(getFn);
+ const AType* implT = calleeT->list_ref(1)->as<const AType*>();
+ copy.push_front(getFn);
cenv.setType(getFn, implT);
- cenv.setType(copy, (*(implT->begin() + 2))->as<const AType*>());
+ copyT = implT->list_ref(2)->as<const AType*>();
}
+ cenv.setType(copy, copyT);
return copy;
}
@@ -198,13 +198,19 @@ ADef::lift(CEnv& cenv, Code& code) throw()
if (c)
c->name = sym()->str();
- ADef* copy = new ADef(ATuple::lift(cenv, code)->as<ATuple*>());
+ assert(list_ref(1)->to<const ASymbol*>());
+ List<ADef, AST> copy;
+ copy.push_back(head());
+ copy.push_back(list_ref(1)->lift(cenv, code));
+ for (iterator t = iter_at(2); t != end(); ++t)
+ copy.push_back((*t)->lift(cenv, code));
+
+ cenv.setTypeSameAs(copy, this);
- if (copy->sym() == copy->body())
+ if (copy.head->sym() == copy.head->body())
return NULL; // Definition created by AFn::lift when body was lifted
- cenv.def(copy->sym(), copy->body(), cenv.type(copy->body()), NULL);
- cenv.setTypeSameAs(copy, this);
+ cenv.def(copy.head->sym(), copy.head->body(), cenv.type(copy.head->body()), NULL);
return copy;
}
@@ -213,10 +219,10 @@ AST*
lift_builtin_call(CEnv& cenv, T* call, Code& code) throw()
{
ATuple* copy = new T(call);
- ATuple::iterator ri = copy->begin() + 1;
+ ATuple::iterator ri = copy->iter_at(1);
// Lift all arguments
- for (typename T::const_iterator i = call->begin() + 1; i != call->end(); ++i)
+ for (typename T::iterator i = call->iter_at(1); i != call->end(); ++i)
*ri++ = (*i)->lift(cenv, code);
cenv.setTypeSameAs(copy, call);