diff options
Diffstat (limited to 'src/lift.cpp')
-rw-r--r-- | src/lift.cpp | 83 |
1 files changed, 43 insertions, 40 deletions
diff --git a/src/lift.cpp b/src/lift.cpp index 04bf61b..979f3c1 100644 --- a/src/lift.cpp +++ b/src/lift.cpp @@ -52,7 +52,9 @@ lift_symbol(CEnv& cenv, Code& code, const ASymbol* sym) throw() static AST* lift_fn(CEnv& cenv, Code& code, ATuple* fn) throw() { - ATuple* impl = new ATuple(*fn); + List<ATuple,AST> impl; + impl.push_back(fn->head()); + const string fnName = cenv.name(fn); const string nameBase = cenv.penv.gensymstr(((fnName != "") ? fnName : "fn").c_str()); const string implNameStr = string("_") + nameBase; @@ -64,53 +66,48 @@ lift_fn(CEnv& cenv, Code& code, ATuple* fn) throw() cenv.push(); const AType* type = cenv.type(fn); AType::const_iterator tp = type->prot()->begin(); - AType* implProtT = new AType(*type->prot()->as_type()); - ATuple::iterator ip = implProtT->begin(); + List<AType,AType> implProtT; + + List<ATuple,AST> implProt; + + // Prepend closure parameter + implProt.push_back(const_cast<ASymbol*>(cenv.penv.sym("_me"))); + for (ATuple::const_iterator p = fn->prot()->begin(); p != fn->prot()->end(); ++p) { const AType* paramType = (*tp++)->as_type(); if (paramType->kind == AType::EXPR && *paramType->head() == *cenv.tenv.Fn) { - AType* fnType = new AType(*paramType); - fnType->set_prot(new AType(const_cast<AType*>(cenv.tenv.var()), - const_cast<AType*>(fnType->prot()->as_type()), - Cursor())); + AType* fnType = new AType(const_cast<AType*>(cenv.tenv.var()), + const_cast<AType*>(paramType), + fnType->loc); paramType = tup<const AType>((*p)->loc, cenv.tenv.Tup, fnType, NULL); } cenv.def((*p)->as_symbol(), *p, paramType, NULL); - *ip++ = new AType(*paramType); + implProt.push_back(const_cast<AST*>(*p)); + implProtT.push_back(new AType(*paramType)); } - /* 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->set_prot(new ATuple(cenv.penv.sym("_"), impl->prot())); + impl.push_back(implProt); // Lift body const AType* implRetT = NULL; - ATuple::iterator ci = impl->iter_at(2); - for (ATuple::iterator i = fn->iter_at(2); i != fn->end(); ++i, ++ci) { - *ci = resp_lift(cenv, code, *i); - implRetT = cenv.type(*ci); + for (ATuple::const_iterator i = fn->iter_at(2); i != fn->end(); ++i) { + AST* lifted = resp_lift(cenv, code, const_cast<AST*>(*i)); + impl.push_back(lifted); + implRetT = cenv.type(lifted); } cenv.pop(); - // Set name of closure parameter to "me" - *impl->prot()->begin() = cenv.penv.sym("_me"); - // Create definition for implementation fn ASymbol* implName = cenv.penv.sym(implNameStr); - ATuple* def = tup<ATuple>(fn->loc, cenv.penv.sym("def"), implName, impl, NULL); + ATuple* def = tup<ATuple>(fn->loc, cenv.penv.sym("def"), implName, impl.head, NULL); code.push_back(def); - AType* implT = new AType(*type); // Type of the implementation function - TList tupT(fn->loc, cenv.tenv.Tup, cenv.tenv.var(), NULL); - TList consT(fn->loc, cenv.tenv.Tup, implT, NULL); + TList implT; // Type of the implementation function + TList tupT(fn->loc, cenv.tenv.Tup, cenv.tenv.var(), NULL); + TList consT; List<ATuple, AST> cons(fn->loc, cenv.penv.sym("Closure"), implName, NULL); - 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(const_cast<ASymbol*>(*i)); @@ -119,9 +116,15 @@ lift_fn(CEnv& cenv, Code& code, ATuple* fn) throw() } cenv.liftStack.pop(); - implT->set_prot(new AType(tupT, implT->prot(), Cursor())); - implT->list_ref(2) = const_cast<AType*>(implRetT); + implProtT.push_front(tupT); + + implT.push_back(const_cast<AType*>((AType*)type->head())); + implT.push_back(const_cast<AType*>(implProtT.head)); + implT.push_back(const_cast<AType*>(implRetT)); + consT.push_front(implT.head); + consT.push_front(cenv.tenv.Tup); + cenv.setType(impl, implT); cenv.setType(cons, consT); @@ -138,8 +141,8 @@ lift_call(CEnv& cenv, Code& code, ATuple* call) throw() List<ATuple, AST> copy; // Lift all children (callee and arguments, recursively) - for (ATuple::iterator i = call->begin(); i != call->end(); ++i) - copy.push_back(resp_lift(cenv, code, *i)); + for (ATuple::const_iterator i = call->begin(); i != call->end(); ++i) + copy.push_back(const_cast<AST*>(resp_lift(cenv, code, const_cast<AST*>(*i)))); copy.head->loc = call->loc; @@ -159,9 +162,9 @@ lift_call(CEnv& cenv, Code& code, ATuple* call) throw() * closure as the first parameter: * (_impl (Fn _impl ...) ...) */ - ATuple* closure = copy.head->list_ref(0)->as_tuple(); - ASymbol* implSym = const_cast<ASymbol*>(closure->list_ref(1)->as_symbol()); - const AType* implT = cenv.type(cenv.resolve(implSym)); + const ATuple* closure = copy.head->list_ref(0)->as_tuple(); + ASymbol* implSym = const_cast<ASymbol*>(closure->list_ref(1)->as_symbol()); + const AType* implT = cenv.type(cenv.resolve(implSym)); copy.push_front(implSym); copyT = implT->list_ref(2)->as_type(); } else { @@ -186,7 +189,7 @@ lift_def(CEnv& cenv, Code& code, ATuple* def) throw() { // Define stub first for recursion const ASymbol* const sym = def->list_ref(1)->as_symbol(); - AST* const body = def->list_ref(2); + const AST* const body = def->list_ref(2); cenv.def(sym, body, cenv.type(body), NULL); if (is_form(body, "fn")) cenv.setName(body->as_tuple(), sym->str()); @@ -194,9 +197,9 @@ lift_def(CEnv& cenv, Code& code, ATuple* def) throw() assert(def->list_ref(1)->to_symbol()); List<ATuple, AST> copy; copy.push_back(def->head()); - copy.push_back(resp_lift(cenv, code, def->list_ref(1))); - for (ATuple::iterator t = def->iter_at(2); t != def->end(); ++t) - copy.push_back(resp_lift(cenv, code, *t)); + copy.push_back(resp_lift(cenv, code, const_cast<AST*>(def->list_ref(1)))); + for (ATuple::const_iterator t = def->iter_at(2); t != def->end(); ++t) + copy.push_back(resp_lift(cenv, code, const_cast<AST*>(*t))); cenv.setTypeSameAs(copy, def); @@ -217,8 +220,8 @@ lift_builtin_call(CEnv& cenv, Code& code, ATuple* call) throw() copy.push_back(call->head()); // Lift all arguments - for (ATuple::iterator i = call->iter_at(1); i != call->end(); ++i) - copy.push_back(resp_lift(cenv, code, *i)); + for (ATuple::const_iterator i = call->iter_at(1); i != call->end(); ++i) + copy.push_back(resp_lift(cenv, code, const_cast<AST*>(*i))); cenv.setTypeSameAs(copy, call); return copy; |