aboutsummaryrefslogtreecommitdiffstats
path: root/tuplr.hpp
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2009-03-15 15:30:00 +0000
committerDavid Robillard <d@drobilla.net>2009-03-15 15:30:00 +0000
commitd5bff57e97494e5a25626c2877880a7eda5485c7 (patch)
treeb97176827c2d52f3b2a19b3b5210a009e1aabbdb /tuplr.hpp
parent52ae7f1842e0f079152902ee73008a2a00aaeb3f (diff)
downloadresp-d5bff57e97494e5a25626c2877880a7eda5485c7.tar.gz
resp-d5bff57e97494e5a25626c2877880a7eda5485c7.tar.bz2
resp-d5bff57e97494e5a25626c2877880a7eda5485c7.zip
Abstract away (and prettify/shrink) dynamic_cast of AST objects.
git-svn-id: http://svn.drobilla.net/resp/tuplr@104 ad02d1e2-f140-0410-9f75-f8b11f17cedd
Diffstat (limited to 'tuplr.hpp')
-rw-r--r--tuplr.hpp28
1 files changed, 15 insertions, 13 deletions
diff --git a/tuplr.hpp b/tuplr.hpp
index 3e051c1..f458fd0 100644
--- a/tuplr.hpp
+++ b/tuplr.hpp
@@ -152,6 +152,8 @@ struct AST {
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 as() {
T t = dynamic_cast<T>(this);
if (!t) throw Error("internal error: bad cast", loc);
@@ -165,7 +167,7 @@ template<typename VT>
struct ALiteral : public AST {
ALiteral(VT v, Cursor c) : AST(c), val(v) {}
bool operator==(const AST& rhs) const {
- const ALiteral<VT>* r = dynamic_cast<const ALiteral<VT>*>(&rhs);
+ const ALiteral<VT>* r = rhs.to<const ALiteral<VT>*>();
return (r && (val == r->val));
}
void constrain(TEnv& tenv, Constraints& c) const;
@@ -197,7 +199,7 @@ struct ATuple : public AST, public vector<AST*> {
va_end(args);
}
bool operator==(const AST& rhs) const {
- const ATuple* rt = dynamic_cast<const ATuple*>(&rhs);
+ const ATuple* rt = rhs.to<const ATuple*>();
if (!rt || rt->size() != size()) return false;
const_iterator l = begin();
FOREACH(const_iterator, r, *rt)
@@ -231,12 +233,12 @@ struct AType : public ATuple {
}
AType(const AType& copy) : ATuple(copy.loc), kind(copy.kind), id(copy.id) {
for (AType::const_iterator i = copy.begin(); i != copy.end(); ++i) {
- AType* typ = dynamic_cast<AType*>(*i);
+ AType* typ = (*i)->to<AType*>();
if (typ) {
push_back(new AType(*typ));
continue;
}
- ATuple* tup = dynamic_cast<ATuple*>(*i);
+ ATuple* tup = (*i)->to<ATuple*>();
if (tup)
push_back(new ATuple(*tup));
else
@@ -251,7 +253,7 @@ struct AType : public ATuple {
case PRIM: return true;
case EXPR:
FOREACH(const_iterator, t, *this) {
- AType* kid = dynamic_cast<AType*>(*t);
+ AType* kid = (*t)->to<AType*>();
if (kid && !kid->concrete())
return false;
}
@@ -259,7 +261,7 @@ struct AType : public ATuple {
return true;
}
bool operator==(const AST& rhs) const {
- const AType* rt = dynamic_cast<const AType*>(&rhs);
+ const AType* rt = rhs.to<const AType*>();
if (!rt || kind != rt->kind)
return false;
else
@@ -293,7 +295,7 @@ struct AClosure : public ATuple {
void lift(CEnv& cenv);
void liftCall(CEnv& cenv, const vector<AType*>& argsT);
CValue compile(CEnv& cenv);
- ATuple* prot() const { return dynamic_cast<ATuple*>(at(1)); }
+ ATuple* prot() const { return at(1)->to<ATuple*>(); }
Funcs funcs;
mutable Subst* subst;
string name;
@@ -310,7 +312,7 @@ struct ACall : public ATuple {
/// Definition special form, e.g. "(def x 2)"
struct ADefinition : public ACall {
ADefinition(const SExp& e, const ATuple& t) : ACall(e, t) {}
- ASymbol* sym() const { return dynamic_cast<ASymbol*>(at(1)); }
+ ASymbol* sym() const { return at(1)->to<ASymbol*>(); }
void constrain(TEnv& tenv, Constraints& c) const;
void lift(CEnv& cenv);
CValue compile(CEnv& cenv);
@@ -433,7 +435,7 @@ struct Subst : public map<const AType*,AType*> {
Subst(AType* s=0, AType* t=0) { if (s && t) { assert(s != t); insert(make_pair(s, t)); } }
static Subst compose(const Subst& delta, const Subst& gamma);
AST* apply(AST* ast) const {
- AType* in = dynamic_cast<AType*>(ast);
+ AType* in = ast->to<AType*>();
if (!in) return ast;
if (in->kind == AType::EXPR) {
AType* out = new AType(in->loc, NULL);
@@ -462,7 +464,7 @@ struct TEnv : public Env< const ASymbol*, pair<AST*, AType*> > {
return ret;
}
AType* var(const AST* ast=0) {
- const ASymbol* sym = dynamic_cast<const ASymbol*>(ast);
+ const ASymbol* sym = ast->to<const ASymbol*>();
if (sym)
return deref(lookup(sym)).second;
@@ -480,7 +482,7 @@ struct TEnv : public Env< const ASymbol*, pair<AST*, AType*> > {
return ref(penv.sym(name))->second;
}
AST* resolve(AST* ast) {
- ASymbol* sym = dynamic_cast<ASymbol*>(ast);
+ ASymbol* sym = ast->to<ASymbol*>();
return sym ? ref(sym)->first : ast;
}
static Subst unify(const Constraints& c);
@@ -515,10 +517,10 @@ struct CEnv {
void optimise(CFunction f);
void write(std::ostream& os);
AType* type(AST* ast, const Subst& subst = Subst()) const {
- ASymbol* sym = dynamic_cast<ASymbol*>(ast);
+ ASymbol* sym = ast->to<ASymbol*>();
if (sym)
return tenv.deref(sym->addr).second;
- return dynamic_cast<AType*>(tsubst.apply(subst.apply(tenv.vars[ast])));
+ return tsubst.apply(subst.apply(tenv.vars[ast]))->to<AType*>();
}
void def(ASymbol* sym, AST* c, AType* t, CValue v) {
tenv.def(sym, make_pair(c, t));