diff options
Diffstat (limited to 'src/resp.hpp')
-rw-r--r-- | src/resp.hpp | 107 |
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; |