aboutsummaryrefslogtreecommitdiffstats
path: root/src/resp.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/resp.hpp')
-rw-r--r--src/resp.hpp107
1 files changed, 76 insertions, 31 deletions
diff --git a/src/resp.hpp b/src/resp.hpp
index a092fb9..e4caac5 100644
--- a/src/resp.hpp
+++ b/src/resp.hpp
@@ -206,22 +206,67 @@ extern ostream& operator<<(ostream& out, const AST* ast);
typedef list<AST*> Code;
+struct ATuple;
+struct ASymbol;
+struct AType;
+struct ALexeme;
+
/// Base class for all AST nodes
struct AST : public Object {
AST(Tag t, Cursor c=Cursor()) : loc(c) { this->tag(t); }
- virtual ~AST() {}
bool operator==(const AST& o) const;
string str() const { ostringstream ss; ss << this; return ss.str(); }
- template<typename T> T to() { return dynamic_cast<T>(this); }
- template<typename T> T const to() const { return dynamic_cast<T const>(this); }
- template<typename T> T as() {
- T t = dynamic_cast<T>(this);
- return t ? t : throw Error(loc, "internal error: bad cast");
+
+ ATuple* as_tuple() {
+ assert(tag() == T_TUPLE || tag() == T_TYPE);
+ return (ATuple*)this;
+ }
+ const ATuple* as_tuple() const {
+ assert(tag() == T_TUPLE || tag() == T_TYPE);
+ return (ATuple*)this;
+ }
+
+ ATuple* to_tuple() {
+ if (tag() == T_TUPLE || tag() == T_TYPE)
+ return (ATuple*)this;
+ return NULL;
+ }
+ const ATuple* to_tuple() const {
+ if (tag() == T_TUPLE || tag() == T_TYPE)
+ return (const ATuple*)this;
+ return NULL;
+ }
+
+ template<typename T>
+ T* as_a(Tag t) {
+ assert(tag() == t);
+ return (T*)this;
+ }
+ template<typename T>
+ T* as_a(Tag t) const {
+ assert(tag() == t);
+ return (T*)this;
+ }
+
+ template<typename T>
+ T* to_a(Tag t) {
+ if (tag() == t)
+ return (T*)this;
+ return NULL;
}
- template<typename T> T const as() const {
- T const t = dynamic_cast<T const>(this);
- return t ? t : throw Error(loc, "internal error: bad cast");
+ template<typename T>
+ T* to_a(Tag t) const {
+ if (tag() == t)
+ return (T*)this;
+ return NULL;
}
+
+ const ASymbol* as_symbol() const { return as_a<const ASymbol>(T_SYMBOL); }
+ const ASymbol* to_symbol() const { return to_a<const ASymbol>(T_SYMBOL); }
+ const ALexeme* to_lexeme() const { return to_a<const ALexeme>(T_LEXEME); }
+ const AType* as_type() const { return as_a<const AType>(T_TYPE); }
+ const AType* to_type() const { return to_a<const AType>(T_TYPE); }
+
Cursor loc;
};
@@ -290,7 +335,6 @@ struct ATuple : public AST {
}
}
- ~ATuple() { free(_vec); }
const AST* head() const { assert(_len > 0); return _vec[0]; }
AST*& head() { assert(_len > 0); return _vec[0]; }
const AST* last() const { return _vec[_len - 1]; }
@@ -328,7 +372,7 @@ struct ATuple : public AST {
}
inline void increment() {
if (node->last())
- node = node->last()->as<ATuple*>();
+ node = node->last()->as_tuple();
else
node = NULL;
}
@@ -358,7 +402,7 @@ struct ATuple : public AST {
const_iterator(const iterator& i) : node(i.node) {}
inline void increment() {
if (node->last())
- node = node->last()->as<const ATuple*>();
+ node = node->last()->as_tuple();
else
node = NULL;
}
@@ -407,11 +451,12 @@ struct ATuple : public AST {
AST*& list_ref(unsigned index) { return *iter_at(index); }
const AST* list_ref(unsigned index) const { return *iter_at(index); }
- const ATuple* prot() const { return list_ref(1)->as<const ATuple*>(); }
- ATuple* prot() { return list_ref(1)->as<ATuple*>(); }
+ const ATuple* prot() const { return list_ref(1)->as_tuple(); }
+ ATuple* prot() { return list_ref(1)->as_tuple(); }
void set_prot(ATuple* prot) { *iter_at(1) = prot; }
private:
+ friend class GC;
size_t _len;
AST** _vec;
};
@@ -425,7 +470,7 @@ list_contains(const ATuple* head, const AST* child) {
if (**p == *child)
return true;
- const ATuple* tup = (*p)->to<const ATuple*>();
+ const ATuple* tup = (*p)->to_tuple();
if (tup && list_contains(tup, child))
return true;
}
@@ -450,7 +495,7 @@ struct AType : public ATuple {
case PRIM: return head()->str() != "Nothing";
case EXPR:
FOREACHP(const_iterator, t, this) {
- const AType* kid = (*t)->to<const AType*>();
+ const AType* kid = (*t)->to_type();
if (kid && !kid->concrete())
return false;
}
@@ -526,21 +571,21 @@ AST::operator==(const AST& rhs) const
switch (tag) {
case T_BOOL:
- return literal_equals(this->as<const ALiteral<bool>*>(), rhs.as<const ALiteral<bool>*>());
+ return literal_equals((const ALiteral<bool>*)this, (const ALiteral<bool>*)&rhs);
case T_FLOAT:
- return literal_equals(this->as<const ALiteral<float>*>(), rhs.as<const ALiteral<float>*>());
+ return literal_equals((const ALiteral<float>*)this, (const ALiteral<float>*)&rhs);
case T_INT32:
- return literal_equals(this->as<const ALiteral<int32_t>*>(), rhs.as<const ALiteral<int32_t>*>());
+ return literal_equals((const ALiteral<int32_t>*)this, (const ALiteral<int32_t>*)&rhs);
case T_TUPLE:
{
- const ATuple* me = this->as<const ATuple*>();
- const ATuple* rt = rhs.to<const ATuple*>();
+ const ATuple* me = this->as_tuple();
+ const ATuple* rt = rhs.to_tuple();
return list_equals(me, rt);
}
case T_TYPE:
{
- const AType* me = this->as<const AType*>();
- const AType* rt = rhs.to<const AType*>();
+ const AType* me = this->as_type();
+ const AType* rt = rhs.to_type();
if (!rt || me->kind != rt->kind) {
assert(str() != rt->str());
return false;
@@ -640,15 +685,15 @@ struct Subst : public list<Constraint> {
if (in->kind == AType::EXPR) {
TList out;
for (ATuple::const_iterator i = in->begin(); i != in->end(); ++i)
- out.push_back(const_cast<AType*>(apply((*i)->as<const AType*>())));
+ out.push_back(const_cast<AType*>(apply((*i)->as_type())));
out.head->loc = in->loc;
return out.head;
} else {
const_iterator i = find(in);
if (i != end()) {
- const AType* out = i->second->as<const AType*>();
+ const AType* out = i->second->as_type();
if (out->kind == AType::EXPR && !out->concrete())
- out = const_cast<AType*>(apply(out->as<const AType*>()));
+ out = const_cast<AType*>(apply(out->as_type()));
return out;
} else {
return new AType(*in);
@@ -790,7 +835,7 @@ struct CEnv {
}
const AType* type(const AST* ast, const Subst& subst = Subst()) const {
const AType* ret = NULL;
- const ASymbol* sym = ast->to<const ASymbol*>();
+ const ASymbol* sym = ast->to_symbol();
if (sym) {
const AType** rec = tenv.ref(sym);
if (rec)
@@ -799,7 +844,7 @@ struct CEnv {
if (!ret)
ret = tenv.vars[ast];
if (ret)
- return tsubst.apply(subst.apply(ret))->to<const AType*>();
+ return tsubst.apply(subst.apply(ret))->to_type();
return NULL;
}
void def(const ASymbol* sym, const AST* c, const AType* t, CVal v) {
@@ -808,7 +853,7 @@ struct CEnv {
vals.def(sym, v);
}
const AST* resolve(const AST* ast) {
- const ASymbol* sym = ast->to<const ASymbol*>();
+ const ASymbol* sym = ast->to_symbol();
const AST** rec = code.ref(sym);
return rec ? *rec : ast;
}
@@ -846,11 +891,11 @@ struct CEnv {
CFunc currentFn; ///< Currently compiling function
- struct FreeVars : public std::vector<ASymbol*> {
+ struct FreeVars : public std::vector<const ASymbol*> {
FreeVars(ATuple* f, const std::string& n) : fn(f), implName(n) {}
ATuple* const fn;
const std::string implName;
- int32_t index(ASymbol* sym) {
+ int32_t index(const ASymbol* sym) {
const_iterator i = find(begin(), end(), sym);
if (i != end()) {
return i - begin() + 1;