aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm.cpp19
-rw-r--r--tuplr.hpp28
-rw-r--r--typing.cpp20
-rw-r--r--write.cpp12
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<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;
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));
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<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));
}
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<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)