aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2009-07-03 22:17:56 +0000
committerDavid Robillard <d@drobilla.net>2009-07-03 22:17:56 +0000
commitd3bebf39b6992814207643c238c47c3e3ceddefe (patch)
tree18959e2c752b8787fccf6174efa13108b886f992
parent22dac3110718ed92672d22f0438034c7e1b77dfd (diff)
downloadresp-d3bebf39b6992814207643c238c47c3e3ceddefe.tar.gz
resp-d3bebf39b6992814207643c238c47c3e3ceddefe.tar.bz2
resp-d3bebf39b6992814207643c238c47c3e3ceddefe.zip
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
-rw-r--r--src/constrain.cpp42
-rw-r--r--src/cps.cpp20
-rw-r--r--src/gc.cpp4
-rw-r--r--src/llvm.cpp21
-rw-r--r--src/pprint.cpp2
-rw-r--r--src/tuplr.hpp66
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<ASymbol*> defined;
+ set<const ASymbol*> defined;
TEnv::Frame frame;
// Add parameters to environment frame
for (size_t i = 0; i < prot()->size(); ++i) {
- ASymbol* sym = prot()->at(i)->to<ASymbol*>();
+ const ASymbol* sym = prot()->at(i)->to<const ASymbol*>();
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<ADef*>();
+ const AST* exp = at(e);
+ const ADef* def = exp->to<const ADef*>();
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<AST*>(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<AType>(loc, NULL);
- for (size_t i = 0; i < prot()->size(); ++i) {
- AType* tvar = tenv.fresh(prot()->at(i)->to<ASymbol*>());
+ size_t s = 0;
+ for (ATuple::const_iterator i = prot()->begin(); i != prot()->end(); ++i, ++s) {
+ AType* tvar = tenv.fresh((*i)->to<ASymbol*>());
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<AFn*>();
+ const AST* callee = tenv.resolve(at(0));
+ const AFn* closure = callee->to<const AFn*>();
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<ATuple*>()->at(i-1)->as<AType*>());
+ const ATuple* prot = gt->second->at(1)->to<const ATuple*>();
+ 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*>());
AType* retT = tenv.var(this);
- c.constrain(tenv, at(0), tup<AType>(at(0)->loc, tenv.penv.sym("Fn"), tenv.var(), retT, 0));
+ c.constrain(tenv, at(0),
+ tup<AType>(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<AST*>(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<ASymbol*>()->str();
+ const string n = at(0)->to<const ASymbol*>()->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<ACall>(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<ATuple*>()) {
- funcs.push_back(make_pair((AFn*)NULL, at(i)));
+ ssize_t index = 0;
+ FOREACH(iterator, i, *this) {
+ if (!(*i)->to<ATuple*>()) {
+ funcs.push_back(make_pair((AFn*)NULL, (*i)));
} else {
arg = tenv.penv.gensym("a");
if (firstFn == -1)
- firstFn = i;
+ firstFn = index;
AFn* thisFn = tup<AFn>(loc, tenv.penv.sym("fn"),
- tup<ATuple>(at(i)->loc, arg, 0),
+ tup<ATuple>((*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<ACall>(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<APrimitive*>())
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<const Type*> cprot;
- for (size_t i = 0; i < argsT.size(); ++i) {
- AType* at = argsT.at(i)->as<AType*>();
- THROW_IF(!llType(at), Cursor(), string("parameter has non-concrete type ")
+ FOREACH(ATuple::const_iterator, i, argsT) {
+ AType* at = (*i)->as<AType*>();
+ 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<ATuple*>();
- for (size_t i = 0; i < argsT.size(); ++i) {
- const AType* genericArgT = genericProtT->at(i)->to<const AType*>();
- AType* callArgT = argsT.at(i)->to<AType*>();
+ const ATuple* genericProtT = gt->second->at(1)->as<const ATuple*>();
+ 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<const AType*>();
+ AType* callArgT = (*a)->to<AType*>();
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*>();
- AType* aT = callArgT->at(i)->to<AType*>();
+ const AType* gT = genericArgT->at(i)->to<const AType*>();
+ AType* aT = callArgT->at(i)->to<AType*>();
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<const ATuple*>();
if (tup && tup->size() > 0) {
const string head = tup->at(0)->str();
- ASymbol* headSym = tup->at(0)->to<ASymbol*>();
+ const ASymbol* headSym = tup->at(0)->to<const ASymbol*>();
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<const Object*> Roots;
typedef std::list<Object*> 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<typename T> T to() { return dynamic_cast<T>(this); }
- template<typename T> T to() const { return dynamic_cast<T>(this); }
+ template<typename T> T to() { return dynamic_cast<T>(this); }
+ template<typename T> T const to() const { return dynamic_cast<T const>(this); }
template<typename T> T as() {
T t = dynamic_cast<T>(this);
if (!t) throw Error(loc, "internal error: bad cast");
return t;
}
+ template<typename T> T const as() const {
+ T const t = dynamic_cast<T const>(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<AST*> {
- ATuple(Cursor c, const vector<AST*>& v=vector<AST*>()) : AST(c), vector<AST*>(v) {}
+struct ATuple : public AST, private vector<AST*> {
+ ATuple(Cursor c) : AST(c) {}
+ //ATuple(Cursor c, const vector<AST*>& v=vector<AST*>()) : AST(c), vector<AST*>(v) {}
+ ATuple(Cursor c, const ATuple& t) : AST(c), vector<AST*>(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<AST*>::push_back(ast); }
+ const AST* at(size_t i) const { return vector<AST*>::at(i); }
+ AST*& at(size_t i) { return vector<AST*>::at(i); }
+ size_t size() const { return vector<AST*>::size(); }
+ bool empty() const { return vector<AST*>::empty(); }
+
+ typedef vector<AST*>::iterator iterator;
+ typedef vector<AST*>::const_iterator const_iterator;
+ const_iterator begin() const { return vector<AST*>::begin(); }
+ iterator begin() { return vector<AST*>::begin(); }
+ const_iterator end() const { return vector<AST*>::end(); }
+ iterator end() { return vector<AST*>::end(); }
bool value() const { return false; }
bool operator==(const AST& rhs) const {
const ATuple* rt = rhs.to<const ATuple*>();
@@ -346,8 +365,8 @@ struct Subst : public list< pair<const AType*,AType*> > {
if (!in) return ast;
if (in->kind == AType::EXPR) {
AType* out = tup<AType>(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<ATuple*>(); }
+ const ATuple* prot() const { return at(1)->to<const ATuple*>(); }
+ ATuple* prot() { return at(1)->to<ATuple*>(); }
/// System level implementations of this (polymorphic) fn
struct Impls : public list< pair<AType*, CFunction> > {
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<ASymbol*>();
+ const ASymbol* sym() const {
+ const ASymbol* sym = at(1)->to<const ASymbol*>();
if (!sym) {
- ATuple* tup = at(1)->to<ATuple*>();
+ const ATuple* tup = at(1)->to<const ATuple*>();
if (tup && !tup->empty())
- return tup->at(0)->to<ASymbol*>();
+ return tup->at(0)->to<const ASymbol*>();
}
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<const string, ASymbol*> {
}
}
ATuple parseTuple(const SExp& e) {
- ATuple ret(e.loc, vector<AST*>(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<AST*, AType*> > {
return ref(penv.sym(name))->second;
}
AST* resolve(AST* ast) {
- ASymbol* sym = ast->to<ASymbol*>();
+ const ASymbol* sym = ast->to<const ASymbol*>();
+ return (sym && sym->addr) ? ref(sym)->first : ast;
+ }
+ const AST* resolve(const AST* ast) {
+ const ASymbol* sym = ast->to<const ASymbol*>();
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<AType*>();
}
- 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);
}