From d3bebf39b6992814207643c238c47c3e3ceddefe Mon Sep 17 00:00:00 2001 From: David Robillard Date: Fri, 3 Jul 2009 22:17:56 +0000 Subject: Improved const correctness. Use iterators over indices (towards non-vector ATuple). git-svn-id: http://svn.drobilla.net/resp/tuplr@176 ad02d1e2-f140-0410-9f75-f8b11f17cedd --- src/constrain.cpp | 42 ++++++++++++++++++++--------------- src/cps.cpp | 20 +++++++++-------- src/gc.cpp | 4 ++-- src/llvm.cpp | 21 ++++++++++-------- src/pprint.cpp | 2 +- src/tuplr.hpp | 66 +++++++++++++++++++++++++++++++++++++------------------ 6 files changed, 95 insertions(+), 60 deletions(-) diff --git a/src/constrain.cpp b/src/constrain.cpp index 46da500..f9a0e11 100644 --- a/src/constrain.cpp +++ b/src/constrain.cpp @@ -50,12 +50,12 @@ AFn::constrain(TEnv& tenv, Constraints& c) const if (gt != tenv.genericTypes.end()) { genericType = gt->second; } else { - set defined; + set defined; TEnv::Frame frame; // Add parameters to environment frame for (size_t i = 0; i < prot()->size(); ++i) { - ASymbol* sym = prot()->at(i)->to(); + const ASymbol* sym = prot()->at(i)->to(); if (!sym) throw Error(prot()->at(i)->loc, "parameter name is not a symbol"); if (defined.find(sym) != defined.end()) @@ -67,14 +67,15 @@ AFn::constrain(TEnv& tenv, Constraints& c) const // Add internal definitions to environment frame size_t e = 2; for (; e < size(); ++e) { - AST* exp = at(e); - ADef* def = exp->to(); + const AST* exp = at(e); + const ADef* def = exp->to(); if (def) { - ASymbol* sym = def->sym(); + const ASymbol* sym = def->sym(); if (defined.find(sym) != defined.end()) throw Error(def->loc, (format("`%1%' defined twice") % sym->str()).str()); defined.insert(def->sym()); - frame.push_back(make_pair(def->sym(), make_pair(def->at(2), (AType*)NULL))); + frame.push_back(make_pair(def->sym(), + make_pair(const_cast(def->at(2)), (AType*)NULL))); } } @@ -84,12 +85,13 @@ AFn::constrain(TEnv& tenv, Constraints& c) const cp.push_back(Constraint(tenv.var(this), tenv.var(), loc)); AType* protT = tup(loc, NULL); - for (size_t i = 0; i < prot()->size(); ++i) { - AType* tvar = tenv.fresh(prot()->at(i)->to()); + size_t s = 0; + for (ATuple::const_iterator i = prot()->begin(); i != prot()->end(); ++i, ++s) { + AType* tvar = tenv.fresh((*i)->to()); protT->push_back(tvar); - assert(frame[i].first == prot()->at(i)); - frame[i].second.first = prot()->at(i); - frame[i].second.second = tvar; + assert(frame[s].first == (*i)); + frame[s].second.first = (*i); + frame[s].second.second = tvar; } c.push_back(Constraint(tenv.var(at(1)), protT, at(1)->loc)); @@ -118,17 +120,21 @@ ACall::constrain(TEnv& tenv, Constraints& c) const for (size_t i = 1; i < size(); ++i) at(i)->constrain(tenv, c); - AST* callee = tenv.resolve(at(0)); - AFn* closure = callee->to(); + const AST* callee = tenv.resolve(at(0)); + const AFn* closure = callee->to(); if (closure) { if (size() - 1 != closure->prot()->size()) throw Error(loc, "incorrect number of arguments"); TEnv::GenericTypes::iterator gt = tenv.genericTypes.find(closure); if (gt != tenv.genericTypes.end()) { - for (size_t i = 1; i < size(); ++i) - c.constrain(tenv, at(i), gt->second->at(1)->as()->at(i-1)->as()); + const ATuple* prot = gt->second->at(1)->to(); + const_iterator i = begin(); + const_iterator prot_i = prot->begin(); + for (++i; i != end(); ++i, ++prot_i) + c.constrain(tenv, *i, (*prot_i)->as()); AType* retT = tenv.var(this); - c.constrain(tenv, at(0), tup(at(0)->loc, tenv.penv.sym("Fn"), tenv.var(), retT, 0)); + c.constrain(tenv, at(0), + tup(at(0)->loc, tenv.penv.sym("Fn"), tenv.var(), retT, 0)); c.constrain(tenv, this, retT); return; } @@ -149,7 +155,7 @@ ADef::constrain(TEnv& tenv, Constraints& c) const THROW_IF(!sym, loc, "`def' has no symbol") AType* tvar = tenv.var(at(2)); - tenv.def(sym, make_pair(at(2), tvar)); + tenv.def(sym, make_pair(const_cast(at(2)), tvar)); at(2)->constrain(tenv, c); c.constrain(tenv, this, tvar); } @@ -175,7 +181,7 @@ AIf::constrain(TEnv& tenv, Constraints& c) const void APrimitive::constrain(TEnv& tenv, Constraints& c) const { - const string n = at(0)->to()->str(); + const string n = at(0)->to()->str(); enum { ARITHMETIC, BINARY, LOGICAL, COMPARISON } type; if (n == "+" || n == "-" || n == "*" || n == "/") type = ARITHMETIC; diff --git a/src/cps.cpp b/src/cps.cpp index 9d80170..75b771f 100644 --- a/src/cps.cpp +++ b/src/cps.cpp @@ -29,7 +29,7 @@ AST::cps(TEnv& tenv, AST* cont) return tup(loc, cont, this, 0); } -/** (cps (fn (a ...) body) cont) => (cont (fn (a ... k) (cps body k))*/ +/** (cps (fn (a ...) body) cont) => (cont (fn (a ... k) (cps body k)) */ AST* AFn::cps(TEnv& tenv, AST* cont) { @@ -63,25 +63,27 @@ ACall::cps(TEnv& tenv, AST* cont) // Each makes a tail call to the next, and the last makes a tail // call to the continuation of this call ssize_t firstFn = -1; - for (size_t i = 0; i < size(); ++i) { - if (!at(i)->to()) { - funcs.push_back(make_pair((AFn*)NULL, at(i))); + ssize_t index = 0; + FOREACH(iterator, i, *this) { + if (!(*i)->to()) { + funcs.push_back(make_pair((AFn*)NULL, (*i))); } else { arg = tenv.penv.gensym("a"); if (firstFn == -1) - firstFn = i; + firstFn = index; AFn* thisFn = tup(loc, tenv.penv.sym("fn"), - tup(at(i)->loc, arg, 0), + tup((*i)->loc, arg, 0), 0); if (fn) - fn->push_back(at(i)->cps(tenv, thisFn)); + fn->push_back((*i)->cps(tenv, thisFn)); funcs.push_back(make_pair(thisFn, arg)); fn = thisFn; } + ++index; } if (firstFn != -1) { @@ -97,8 +99,8 @@ ACall::cps(TEnv& tenv, AST* cont) } else { assert(at(0)->value()); ACall* ret = tup(loc, 0); - for (size_t i = 0; i < size(); ++i) - ret->push_back(at(i)); + FOREACH(iterator, i, *this) + ret->push_back((*i)); if (!to()) ret->push_back(cont); return ret; diff --git a/src/gc.cpp b/src/gc.cpp index 7550893..09bd78c 100644 --- a/src/gc.cpp +++ b/src/gc.cpp @@ -29,12 +29,12 @@ using namespace std; GC::GC(size_t pool_size) { - _pool = tlsf_init(malloc(pool_size), pool_size); + _pool = tlsf_init(malloc(pool_size), pool_size); } GC::~GC() { - tlsf_destroy((tlsf_t*)_pool); + tlsf_destroy((tlsf_t*)_pool); } void* diff --git a/src/llvm.cpp b/src/llvm.cpp index 39cf2d0..0f13f76 100644 --- a/src/llvm.cpp +++ b/src/llvm.cpp @@ -109,9 +109,9 @@ struct LLVMEngine : public Engine { Function::LinkageTypes linkage = Function::ExternalLinkage; vector cprot; - for (size_t i = 0; i < argsT.size(); ++i) { - AType* at = argsT.at(i)->as(); - THROW_IF(!llType(at), Cursor(), string("parameter has non-concrete type ") + FOREACH(ATuple::const_iterator, i, argsT) { + AType* at = (*i)->as(); + THROW_IF(!llType(at), Cursor(), string("non-concrete parameter :: ") + at->str()) cprot.push_back(llType(at)); } @@ -263,18 +263,21 @@ AFn::liftCall(CEnv& cenv, const AType& argsT) if (!genericType->concrete()) { // Build substitution to apply to generic type assert(argsT.size() == prot()->size()); - ATuple* genericProtT = gt->second->at(1)->as(); - for (size_t i = 0; i < argsT.size(); ++i) { - const AType* genericArgT = genericProtT->at(i)->to(); - AType* callArgT = argsT.at(i)->to(); + const ATuple* genericProtT = gt->second->at(1)->as(); + ATuple::const_iterator g = genericProtT->begin(); + AType::const_iterator a = argsT.begin(); + for (; a != argsT.end(); ++a, ++g) { + assert(g != genericProtT->end()); + const AType* genericArgT = (*g)->to(); + AType* callArgT = (*a)->to(); assert(genericArgT); assert(callArgT); if (callArgT->kind == AType::EXPR) { assert(genericArgT->kind == AType::EXPR); assert(callArgT->size() == genericArgT->size()); for (size_t i = 0; i < callArgT->size(); ++i) { - AType* gT = genericArgT->at(i)->to(); - AType* aT = callArgT->at(i)->to(); + const AType* gT = genericArgT->at(i)->to(); + AType* aT = callArgT->at(i)->to(); if (gT && aT) argsSubst.add(gT, aT); } diff --git a/src/pprint.cpp b/src/pprint.cpp index adf4ece..cb507b1 100644 --- a/src/pprint.cpp +++ b/src/pprint.cpp @@ -66,7 +66,7 @@ pprint_internal(ostream& out, const AST* ast, unsigned indent) const ATuple* tup = ast->to(); if (tup && tup->size() > 0) { const string head = tup->at(0)->str(); - ASymbol* headSym = tup->at(0)->to(); + const ASymbol* headSym = tup->at(0)->to(); out << "("; pprint_internal(out, tup->at(0), indent); unsigned child_indent = indent; diff --git a/src/tuplr.hpp b/src/tuplr.hpp index 03bae10..38929b5 100644 --- a/src/tuplr.hpp +++ b/src/tuplr.hpp @@ -151,15 +151,15 @@ struct GC { }; typedef std::list Roots; typedef std::list Heap; - GC(size_t pool_size); - ~GC(); + GC(size_t pool_size); + ~GC(); void* alloc(size_t size, Tag tag); void collect(const Roots& roots); void addRoot(const Object* obj) { assert(obj); _roots.push_back(obj); } void lock() { _roots.insert(_roots.end(), _heap.begin(), _heap.end()); } const Roots& roots() const { return _roots; } private: - void* _pool; + void* _pool; Heap _heap; Roots _roots; }; @@ -208,13 +208,18 @@ struct AST : public Object { virtual void lift(CEnv& cenv) {} virtual CValue compile(CEnv& cenv) = 0; string str() const { ostringstream ss; ss << this; return ss.str(); } - template T to() { return dynamic_cast(this); } - template T to() const { return dynamic_cast(this); } + template T to() { return dynamic_cast(this); } + template T const to() const { return dynamic_cast(this); } template T as() { T t = dynamic_cast(this); if (!t) throw Error(loc, "internal error: bad cast"); return t; } + template T const as() const { + T const t = dynamic_cast(this); + if (!t) throw Error(loc, "internal error: bad cast"); + return t; + } Cursor loc; }; @@ -254,14 +259,28 @@ private: }; /// Tuple (heterogeneous sequence of fixed length), e.g. "(a b c)" -struct ATuple : public AST, public vector { - ATuple(Cursor c, const vector& v=vector()) : AST(c), vector(v) {} +struct ATuple : public AST, private vector { + ATuple(Cursor c) : AST(c) {} + //ATuple(Cursor c, const vector& v=vector()) : AST(c), vector(v) {} + ATuple(Cursor c, const ATuple& t) : AST(c), vector(t) {} ATuple(Cursor c, AST* ast, va_list args) : AST(c) { if (!ast) return; push_back(ast); for (AST* a = va_arg(args, AST*); a; a = va_arg(args, AST*)) push_back(a); } + void push_back(AST* ast) { vector::push_back(ast); } + const AST* at(size_t i) const { return vector::at(i); } + AST*& at(size_t i) { return vector::at(i); } + size_t size() const { return vector::size(); } + bool empty() const { return vector::empty(); } + + typedef vector::iterator iterator; + typedef vector::const_iterator const_iterator; + const_iterator begin() const { return vector::begin(); } + iterator begin() { return vector::begin(); } + const_iterator end() const { return vector::end(); } + iterator end() { return vector::end(); } bool value() const { return false; } bool operator==(const AST& rhs) const { const ATuple* rt = rhs.to(); @@ -346,8 +365,8 @@ struct Subst : public list< pair > { if (!in) return ast; if (in->kind == AType::EXPR) { AType* out = tup(in->loc, NULL); - for (size_t i = 0; i < in->size(); ++i) - out->push_back(apply(in->at(i))); + for (ATuple::iterator i = in->begin(); i != in->end(); ++i) + out->push_back(apply(*i)); return out; } else { const_iterator i = find(in); @@ -379,7 +398,8 @@ struct AFn : public ATuple { void lift(CEnv& cenv); void liftCall(CEnv& cenv, const AType& argsT); CValue compile(CEnv& cenv); - ATuple* prot() const { return at(1)->to(); } + const ATuple* prot() const { return at(1)->to(); } + ATuple* prot() { return at(1)->to(); } /// System level implementations of this (polymorphic) fn struct Impls : public list< pair > { CFunction find(AType* type) const { @@ -408,12 +428,12 @@ struct ACall : public ATuple { struct ADef : public ACall { ADef(const SExp& e, const ATuple& t) : ACall(e, t) {} ADef(Cursor c, AST* ast, va_list args) : ACall(c, ast, args) {} - ASymbol* sym() const { - ASymbol* sym = at(1)->to(); + const ASymbol* sym() const { + const ASymbol* sym = at(1)->to(); if (!sym) { - ATuple* tup = at(1)->to(); + const ATuple* tup = at(1)->to(); if (tup && !tup->empty()) - return tup->at(0)->to(); + return tup->at(0)->to(); } return sym; } @@ -436,8 +456,9 @@ struct AIf : public ACall { struct APrimitive : public ACall { APrimitive(const SExp& e, const ATuple& t) : ACall(e, t) {} bool value() const { - for (size_t i = 1; i < size(); ++i) - if (!at(i)->value()) + ATuple::const_iterator i = begin(); + for (++i; i != end(); ++i) + if (!(*i)->value()) return false;; return true; } @@ -488,10 +509,9 @@ struct PEnv : private map { } } ATuple parseTuple(const SExp& e) { - ATuple ret(e.loc, vector(e.size())); - size_t n = 0; + ATuple ret(e.loc); FOREACH(SExp::const_iterator, i, e) - ret[n++] = parse(*i); + ret.push_back(parse(*i)); return ret; } AST* parse(const SExp& exp) { @@ -572,7 +592,11 @@ struct TEnv : public Env< const ASymbol*, pair > { return ref(penv.sym(name))->second; } AST* resolve(AST* ast) { - ASymbol* sym = ast->to(); + const ASymbol* sym = ast->to(); + return (sym && sym->addr) ? ref(sym)->first : ast; + } + const AST* resolve(const AST* ast) { + const ASymbol* sym = ast->to(); return (sym && sym->addr) ? ref(sym)->first : ast; } @@ -632,7 +656,7 @@ struct CEnv { return sym->addr ? tenv.deref(sym->addr).second : NULL; return tsubst.apply(subst.apply(tenv.vars[ast]))->to(); } - void def(ASymbol* sym, AST* c, AType* t, CValue v) { + void def(const ASymbol* sym, AST* c, AType* t, CValue v) { tenv.def(sym, make_pair(c, t)); vals.def(sym, v); } -- cgit v1.2.1