diff options
author | David Robillard <d@drobilla.net> | 2010-12-04 22:17:01 +0000 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2010-12-04 22:17:01 +0000 |
commit | 6b063941f02808b5e510f8a9c102b3d361de78f3 (patch) | |
tree | a8c54efb023830dea046afd7902070c4647d374e /src | |
parent | d68d9bcf0f2ac65f5f9a3ab92216a11dafa8f2ea (diff) | |
download | resp-6b063941f02808b5e510f8a9c102b3d361de78f3.tar.gz resp-6b063941f02808b5e510f8a9c102b3d361de78f3.tar.bz2 resp-6b063941f02808b5e510f8a9c102b3d361de78f3.zip |
Eliminate tuple/list mutation.
Fix AST::str().
git-svn-id: http://svn.drobilla.net/resp/resp@293 ad02d1e2-f140-0410-9f75-f8b11f17cedd
Diffstat (limited to 'src')
-rw-r--r-- | src/lift.cpp | 83 | ||||
-rw-r--r-- | src/resp.hpp | 50 |
2 files changed, 47 insertions, 86 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; diff --git a/src/resp.hpp b/src/resp.hpp index 12d2ca0..0112a9e 100644 --- a/src/resp.hpp +++ b/src/resp.hpp @@ -204,6 +204,9 @@ struct ASymbol; struct AType; struct ALexeme; +class AST; +extern ostream& operator<<(ostream& out, const AST* ast); + /// Base class for all AST nodes struct AST : public Object { AST(Tag t, Cursor c=Cursor()) : loc(c) { this->tag(t); } @@ -263,8 +266,6 @@ struct AST : public Object { Cursor loc; }; -extern ostream& operator<<(ostream& out, const AST* ast); - template<typename T> static T* tup(Cursor c, AST* ast, ...) { @@ -359,42 +360,12 @@ struct ATuple : public AST { void last(AST* ast) { _vec[_len - 1] = ast; } - struct iterator { - iterator(ATuple* n) : node(n) { - assert(!n || n->tup_len() == 0 || n->tup_len() == 2); - if (!n || n->tup_len() == 0) - node = NULL; - } - inline void increment() { - if (node->last()) - node = node->last()->as_tuple(); - else - node = NULL; - } - inline iterator& operator++() { - assert(node); - increment(); - return *this; - } - inline iterator operator++(int) { - assert(node); - const iterator ret(node); - increment(); - return ret; - } - inline bool operator==(const iterator& i) const { return node == i.node; } - inline bool operator!=(const iterator& i) const { return node != i.node; } - AST*& operator*() { return node->head(); } - ATuple* node; - }; - struct const_iterator { const_iterator(const ATuple* n) : node(n) { assert(!n || n->tup_len() == 0 || n->tup_len() == 2); if (!n || n->tup_len() == 0) node = NULL; } - const_iterator(const iterator& i) : node(i.node) {} inline void increment() { if (node->last()) node = node->last()->as_tuple(); @@ -423,9 +394,7 @@ struct ATuple : public AST { }; const_iterator begin() const { assert(_len == 0 || _len == 2); return const_iterator(this); } - iterator begin() { assert(_len == 0 || _len == 2); return iterator(this); } const_iterator end() const { return const_iterator(NULL); } - iterator end() { return iterator(NULL); } const_iterator iter_at(unsigned index) const { const_iterator i = begin(); @@ -435,20 +404,9 @@ struct ATuple : public AST { return i; } - iterator iter_at(unsigned index) { - iterator i = begin(); - for (unsigned idx = 0; idx != index; ++i, ++idx) { - assert(i != end()); - } - return i; - } - - AST*& list_ref(unsigned index) { return *iter_at(index); } const AST* list_ref(unsigned index) const { return *iter_at(index); } - const ATuple* prot() const { return list_ref(1)->as_tuple(); } - ATuple* prot() { return list_ref(1)->as_tuple(); } - void set_prot(ATuple* prot) { *iter_at(1) = prot; } + const ATuple* prot() const { return list_ref(1)->as_tuple(); } private: friend class GC; |