diff options
author | David Robillard <d@drobilla.net> | 2009-03-15 15:30:00 +0000 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2009-03-15 15:30:00 +0000 |
commit | d5bff57e97494e5a25626c2877880a7eda5485c7 (patch) | |
tree | b97176827c2d52f3b2a19b3b5210a009e1aabbdb | |
parent | 52ae7f1842e0f079152902ee73008a2a00aaeb3f (diff) | |
download | resp-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
-rw-r--r-- | llvm.cpp | 19 | ||||
-rw-r--r-- | tuplr.hpp | 28 | ||||
-rw-r--r-- | typing.cpp | 20 | ||||
-rw-r--r-- | write.cpp | 12 |
4 files changed, 40 insertions, 39 deletions
@@ -61,7 +61,7 @@ lltype(const AType* t) if (t->at(0)->str() == "Pair") { vector<const Type*> types; for (size_t i = 1; i < t->size(); ++i) - types.push_back(lltype(dynamic_cast<AType*>(t->at(i)))); + types.push_back(lltype(t->at(i)->to<AType*>())); return PointerType::get(StructType::get(types, false), 0); } } @@ -218,10 +218,10 @@ AClosure::liftCall(CEnv& cenv, const vector<AType*>& argsT) if (!genericType->concrete()) { // Find type and build substitution assert(argsT.size() == prot()->size()); - ATuple* genericProtT = dynamic_cast<ATuple*>(genericType->at(1)); + ATuple* genericProtT = genericType->at(1)->to<ATuple*>(); assert(genericProtT); for (size_t i = 0; i < argsT.size(); ++i) - argsSubst[dynamic_cast<AType*>(genericProtT->at(i))] = dynamic_cast<AType*>(argsT.at(i)); + argsSubst[genericProtT->at(i)->to<AType*>()] = argsT.at(i)->to<AType*>(); thisType = argsSubst.apply(genericType)->as<AType*>(); @@ -239,7 +239,7 @@ AClosure::liftCall(CEnv& cenv, const vector<AType*>& argsT) // Write function declaration string name = this->name == "" ? cenv.gensym("_fn") : this->name; Function* f = compileFunction(cenv, name, - lltype(dynamic_cast<AType*>(thisType->at(thisType->size() - 1))), + lltype(thisType->at(thisType->size()-1)->to<AType*>()), *protT); cenv.push(); @@ -281,7 +281,7 @@ static AST* maybeLookup(CEnv& cenv, AST* ast) { - ASymbol* s = dynamic_cast<ASymbol*>(ast); + ASymbol* s = ast->to<ASymbol*>(); if (s && s->addr) return cenv.tenv.deref(s->addr).first; return ast; @@ -290,8 +290,7 @@ maybeLookup(CEnv& cenv, AST* ast) void ACall::lift(CEnv& cenv) { - AClosure* c = dynamic_cast<AClosure*>(maybeLookup(cenv, at(0))); - + AClosure* c = maybeLookup(cenv, at(0))->to<AClosure*>(); vector<AType*> argsT; // Lift arguments @@ -313,7 +312,7 @@ ACall::lift(CEnv& cenv) CValue ACall::compile(CEnv& cenv) { - AClosure* c = dynamic_cast<AClosure*>(maybeLookup(cenv, at(0))); + AClosure* c = maybeLookup(cenv, at(0))->to<AClosure*>(); if (!c) return NULL; // Primitive @@ -341,7 +340,7 @@ ADefinition::lift(CEnv& cenv) { // Define first for recursion cenv.def(at(1)->as<ASymbol*>(), at(2), cenv.type(at(2)), NULL); - AClosure* c = dynamic_cast<AClosure*>(at(2)); + AClosure* c = at(2)->to<AClosure*>(); if (c) c->name = at(1)->str(); at(2)->lift(cenv); @@ -405,7 +404,7 @@ APrimitive::compile(CEnv& cenv) Value* a = LLVal(cenv.compile(at(1))); Value* b = LLVal(cenv.compile(at(2))); bool isFloat = cenv.type(at(1))->str() == "Float"; - const string n = dynamic_cast<ASymbol*>(at(0))->str(); + const string n = at(0)->to<ASymbol*>()->str(); // Binary arithmetic operations Instruction::BinaryOps op = (Instruction::BinaryOps)0; @@ -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)); @@ -21,7 +21,7 @@ void Constraints::constrain(TEnv& tenv, const AST* o, AType* t) { - assert(!dynamic_cast<const AType*>(o)); + assert(!o->to<const AType*>()); push_back(Constraint(tenv.var(o), t, o->loc)); } @@ -65,7 +65,7 @@ AClosure::constrain(TEnv& tenv, Constraints& c) const // Add parameters to environment frame for (size_t i = 0; i < prot()->size(); ++i) { - ASymbol* sym = dynamic_cast<ASymbol*>(prot()->at(i)); + ASymbol* sym = prot()->at(i)->to<ASymbol*>(); if (!sym) throw Error("parameter name is not a symbol", prot()->at(i)->loc); if (defined.find(sym) != defined.end()) @@ -78,7 +78,7 @@ AClosure::constrain(TEnv& tenv, Constraints& c) const size_t e = 2; for (; e < size(); ++e) { AST* exp = at(e); - ADefinition* def = dynamic_cast<ADefinition*>(exp); + ADefinition* def = exp->to<ADefinition*>(); if (def) { ASymbol* sym = def->sym(); if (defined.find(sym) != defined.end()) @@ -95,7 +95,7 @@ AClosure::constrain(TEnv& tenv, Constraints& c) const AType* protT = new AType(loc, NULL); for (size_t i = 0; i < prot()->size(); ++i) { - AType* tvar = tenv.fresh(dynamic_cast<ASymbol*>(prot()->at(i))); + AType* tvar = tenv.fresh(prot()->at(i)->to<ASymbol*>()); protT->push_back(tvar); assert(frame[i].first == prot()->at(i)); frame[i].second.first = prot()->at(i); @@ -127,7 +127,7 @@ ACall::constrain(TEnv& tenv, Constraints& c) const at(i)->constrain(tenv, c); AST* callee = tenv.resolve(at(0)); - AClosure* closure = dynamic_cast<AClosure*>(callee); + AClosure* closure = callee->to<AClosure*>(); if (closure) { if (size() - 1 != closure->prot()->size()) throw Error("incorrect number of arguments", loc); @@ -153,7 +153,7 @@ void ADefinition::constrain(TEnv& tenv, Constraints& c) const { if (size() != 3) throw Error("`def' requires exactly 2 arguments", loc); - const ASymbol* sym = dynamic_cast<const ASymbol*>(at(1)); + const ASymbol* sym = at(1)->to<const ASymbol*>(); if (!sym) throw Error("`def' name is not a symbol", loc); if (tenv.lookup(sym)) @@ -185,7 +185,7 @@ AIf::constrain(TEnv& tenv, Constraints& c) const void APrimitive::constrain(TEnv& tenv, Constraints& c) const { - const string n = dynamic_cast<ASymbol*>(at(0))->str(); + const string n = at(0)->to<ASymbol*>()->str(); enum { ARITHMETIC, BINARY, LOGICAL, COMPARISON } type; if (n == "+" || n == "-" || n == "*" || n == "/") type = ARITHMETIC; @@ -279,7 +279,7 @@ substitute(ATuple* tup, const AST* from, AST* to) if (*tup->at(i) == *from) tup->at(i) = to; else if (tup->at(i) != to) - substitute(dynamic_cast<ATuple*>(tup->at(i)), from, to); + substitute(tup->at(i)->to<ATuple*>(), from, to); } @@ -330,8 +330,8 @@ TEnv::unify(const Constraints& constraints) // TAPL 22.4 return Subst::compose(unify(cp), Subst(t, s)); } else if (s->kind == AType::EXPR && s->kind == t->kind && s->size() == t->size()) { for (size_t i = 0; i < s->size(); ++i) { - AType* si = dynamic_cast<AType*>(s->at(i)); - AType* ti = dynamic_cast<AType*>(t->at(i)); + AType* si = s->at(i)->to<AType*>(); + AType* ti = t->at(i)->to<AType*>(); if (si && ti) cp.push_back(Constraint(si, ti, si->loc)); } @@ -20,23 +20,23 @@ ostream& operator<<(ostream& out, const AST* ast) { - const ALiteral<float>* flit = dynamic_cast<const ALiteral<float>*>(ast); + const ALiteral<float>* flit = ast->to<const ALiteral<float>*>(); if (flit) return out << showpoint << flit->val; - const ALiteral<int32_t>* ilit = dynamic_cast<const ALiteral<int32_t>*>(ast); + const ALiteral<int32_t>* ilit = ast->to<const ALiteral<int32_t>*>(); if (ilit) return out << ilit->val; - const ALiteral<bool>* blit = dynamic_cast<const ALiteral<bool>*>(ast); + const ALiteral<bool>* blit = ast->to<const ALiteral<bool>*>(); if (blit) return out << (blit->val ? "#t" : "#f"); - const ASymbol* sym = dynamic_cast<const ASymbol*>(ast); + const ASymbol* sym = ast->to<const ASymbol*>(); if (sym) return out << sym->cppstr; - const AType* type = dynamic_cast<const AType*>(ast); + const AType* type = ast->to<const AType*>(); if (type) { switch (type->kind) { case AType::VAR: return out << "?" << type->id; @@ -45,7 +45,7 @@ operator<<(ostream& out, const AST* ast) } } - const ATuple* tup = dynamic_cast<const ATuple*>(ast); + const ATuple* tup = ast->to<const ATuple*>(); if (tup) { out << "("; for (size_t i = 0; i != tup->size(); ++i) |