diff options
Diffstat (limited to 'tuplr.hpp')
-rw-r--r-- | tuplr.hpp | 28 |
1 files changed, 15 insertions, 13 deletions
@@ -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)); |