From d5bff57e97494e5a25626c2877880a7eda5485c7 Mon Sep 17 00:00:00 2001 From: David Robillard Date: Sun, 15 Mar 2009 15:30:00 +0000 Subject: 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 --- llvm.cpp | 19 +++++++++---------- tuplr.hpp | 28 +++++++++++++++------------- typing.cpp | 20 ++++++++++---------- write.cpp | 12 ++++++------ 4 files changed, 40 insertions(+), 39 deletions(-) diff --git a/llvm.cpp b/llvm.cpp index 64fc6a6..c354b79 100644 --- a/llvm.cpp +++ b/llvm.cpp @@ -61,7 +61,7 @@ lltype(const AType* t) if (t->at(0)->str() == "Pair") { vector types; for (size_t i = 1; i < t->size(); ++i) - types.push_back(lltype(dynamic_cast(t->at(i)))); + types.push_back(lltype(t->at(i)->to())); return PointerType::get(StructType::get(types, false), 0); } } @@ -218,10 +218,10 @@ AClosure::liftCall(CEnv& cenv, const vector& argsT) if (!genericType->concrete()) { // Find type and build substitution assert(argsT.size() == prot()->size()); - ATuple* genericProtT = dynamic_cast(genericType->at(1)); + ATuple* genericProtT = genericType->at(1)->to(); assert(genericProtT); for (size_t i = 0; i < argsT.size(); ++i) - argsSubst[dynamic_cast(genericProtT->at(i))] = dynamic_cast(argsT.at(i)); + argsSubst[genericProtT->at(i)->to()] = argsT.at(i)->to(); thisType = argsSubst.apply(genericType)->as(); @@ -239,7 +239,7 @@ AClosure::liftCall(CEnv& cenv, const vector& argsT) // Write function declaration string name = this->name == "" ? cenv.gensym("_fn") : this->name; Function* f = compileFunction(cenv, name, - lltype(dynamic_cast(thisType->at(thisType->size() - 1))), + lltype(thisType->at(thisType->size()-1)->to()), *protT); cenv.push(); @@ -281,7 +281,7 @@ static AST* maybeLookup(CEnv& cenv, AST* ast) { - ASymbol* s = dynamic_cast(ast); + ASymbol* s = ast->to(); 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(maybeLookup(cenv, at(0))); - + AClosure* c = maybeLookup(cenv, at(0))->to(); vector argsT; // Lift arguments @@ -313,7 +312,7 @@ ACall::lift(CEnv& cenv) CValue ACall::compile(CEnv& cenv) { - AClosure* c = dynamic_cast(maybeLookup(cenv, at(0))); + AClosure* c = maybeLookup(cenv, at(0))->to(); if (!c) return NULL; // Primitive @@ -341,7 +340,7 @@ ADefinition::lift(CEnv& cenv) { // Define first for recursion cenv.def(at(1)->as(), at(2), cenv.type(at(2)), NULL); - AClosure* c = dynamic_cast(at(2)); + AClosure* c = at(2)->to(); 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(at(0))->str(); + const string n = at(0)->to()->str(); // Binary arithmetic operations Instruction::BinaryOps op = (Instruction::BinaryOps)0; 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 T to() { return dynamic_cast(this); } + template T to() const { return dynamic_cast(this); } template T as() { T t = dynamic_cast(this); if (!t) throw Error("internal error: bad cast", loc); @@ -165,7 +167,7 @@ template struct ALiteral : public AST { ALiteral(VT v, Cursor c) : AST(c), val(v) {} bool operator==(const AST& rhs) const { - const ALiteral* r = dynamic_cast*>(&rhs); + const ALiteral* r = rhs.to*>(); return (r && (val == r->val)); } void constrain(TEnv& tenv, Constraints& c) const; @@ -197,7 +199,7 @@ struct ATuple : public AST, public vector { va_end(args); } bool operator==(const AST& rhs) const { - const ATuple* rt = dynamic_cast(&rhs); + const ATuple* rt = rhs.to(); 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(*i); + AType* typ = (*i)->to(); if (typ) { push_back(new AType(*typ)); continue; } - ATuple* tup = dynamic_cast(*i); + ATuple* tup = (*i)->to(); 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(*t); + AType* kid = (*t)->to(); 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(&rhs); + const AType* rt = rhs.to(); 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& argsT); CValue compile(CEnv& cenv); - ATuple* prot() const { return dynamic_cast(at(1)); } + ATuple* prot() const { return at(1)->to(); } 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(at(1)); } + ASymbol* sym() const { return at(1)->to(); } void constrain(TEnv& tenv, Constraints& c) const; void lift(CEnv& cenv); CValue compile(CEnv& cenv); @@ -433,7 +435,7 @@ struct Subst : public map { 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(ast); + AType* in = ast->to(); 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 > { return ret; } AType* var(const AST* ast=0) { - const ASymbol* sym = dynamic_cast(ast); + const ASymbol* sym = ast->to(); if (sym) return deref(lookup(sym)).second; @@ -480,7 +482,7 @@ struct TEnv : public Env< const ASymbol*, pair > { return ref(penv.sym(name))->second; } AST* resolve(AST* ast) { - ASymbol* sym = dynamic_cast(ast); + ASymbol* sym = ast->to(); 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(ast); + ASymbol* sym = ast->to(); if (sym) return tenv.deref(sym->addr).second; - return dynamic_cast(tsubst.apply(subst.apply(tenv.vars[ast]))); + return tsubst.apply(subst.apply(tenv.vars[ast]))->to(); } void def(ASymbol* sym, AST* c, AType* t, CValue v) { tenv.def(sym, make_pair(c, t)); diff --git a/typing.cpp b/typing.cpp index d7cfff2..518ab00 100644 --- a/typing.cpp +++ b/typing.cpp @@ -21,7 +21,7 @@ void Constraints::constrain(TEnv& tenv, const AST* o, AType* t) { - assert(!dynamic_cast(o)); + assert(!o->to()); 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(prot()->at(i)); + ASymbol* sym = prot()->at(i)->to(); 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(exp); + ADefinition* def = exp->to(); 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(prot()->at(i))); + AType* tvar = tenv.fresh(prot()->at(i)->to()); 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(callee); + AClosure* closure = callee->to(); 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(at(1)); + const ASymbol* sym = at(1)->to(); 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(at(0))->str(); + const string n = at(0)->to()->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(tup->at(i)), from, to); + substitute(tup->at(i)->to(), 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(s->at(i)); - AType* ti = dynamic_cast(t->at(i)); + AType* si = s->at(i)->to(); + AType* ti = t->at(i)->to(); if (si && ti) cp.push_back(Constraint(si, ti, si->loc)); } diff --git a/write.cpp b/write.cpp index 248e1e1..aab3fb1 100644 --- a/write.cpp +++ b/write.cpp @@ -20,23 +20,23 @@ ostream& operator<<(ostream& out, const AST* ast) { - const ALiteral* flit = dynamic_cast*>(ast); + const ALiteral* flit = ast->to*>(); if (flit) return out << showpoint << flit->val; - const ALiteral* ilit = dynamic_cast*>(ast); + const ALiteral* ilit = ast->to*>(); if (ilit) return out << ilit->val; - const ALiteral* blit = dynamic_cast*>(ast); + const ALiteral* blit = ast->to*>(); if (blit) return out << (blit->val ? "#t" : "#f"); - const ASymbol* sym = dynamic_cast(ast); + const ASymbol* sym = ast->to(); if (sym) return out << sym->cppstr; - const AType* type = dynamic_cast(ast); + const AType* type = ast->to(); 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(ast); + const ATuple* tup = ast->to(); if (tup) { out << "("; for (size_t i = 0; i != tup->size(); ++i) -- cgit v1.2.1