diff options
author | David Robillard <d@drobilla.net> | 2010-04-08 20:53:09 +0000 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2010-04-08 20:53:09 +0000 |
commit | 1f988f420ba3827941886962680f3e2ad6f01740 (patch) | |
tree | 9e89d69b1b1796491b144ba2253fda9f5226d3df | |
parent | 55b6a3f313670d2cb13847d1f1b04fe3e4b21d63 (diff) | |
download | resp-1f988f420ba3827941886962680f3e2ad6f01740.tar.gz resp-1f988f420ba3827941886962680f3e2ad6f01740.tar.bz2 resp-1f988f420ba3827941886962680f3e2ad6f01740.zip |
Exception specifiers.
More efficient constraints construction (c') in unify().
git-svn-id: http://svn.drobilla.net/resp/resp@253 ad02d1e2-f140-0410-9f75-f8b11f17cedd
-rw-r--r-- | src/compile.cpp | 18 | ||||
-rw-r--r-- | src/constrain.cpp | 22 | ||||
-rw-r--r-- | src/lift.cpp | 22 | ||||
-rw-r--r-- | src/resp.hpp | 66 | ||||
-rw-r--r-- | src/unify.cpp | 17 |
5 files changed, 71 insertions, 74 deletions
diff --git a/src/compile.cpp b/src/compile.cpp index 2cf3b74..4f24994 100644 --- a/src/compile.cpp +++ b/src/compile.cpp @@ -24,7 +24,7 @@ using namespace std; #define COMPILE_LITERAL(CT) \ -template<> CVal ALiteral<CT>::compile(CEnv& cenv) { \ +template<> CVal ALiteral<CT>::compile(CEnv& cenv) throw() { \ return cenv.engine()->compileLiteral(cenv, this); \ } COMPILE_LITERAL(int32_t); @@ -32,7 +32,7 @@ COMPILE_LITERAL(float); COMPILE_LITERAL(bool); CVal -ASymbol::compile(CEnv& cenv) +ASymbol::compile(CEnv& cenv) throw() { if (cenv.vals.topLevel(this) && cenv.type(this)->head()->str() != "Fn") return cenv.engine()->getGlobal(cenv, *cenv.vals.ref(this)); @@ -41,13 +41,13 @@ ASymbol::compile(CEnv& cenv) } CVal -AFn::compile(CEnv& cenv) +AFn::compile(CEnv& cenv) throw() { return impls.find(cenv.type(this)); } CVal -ACall::compile(CEnv& cenv) +ACall::compile(CEnv& cenv) throw() { AFn* c = cenv.resolve(head())->to<AFn*>(); @@ -73,7 +73,7 @@ ACall::compile(CEnv& cenv) } CVal -ADef::compile(CEnv& cenv) +ADef::compile(CEnv& cenv) throw() { cenv.def(sym(), body(), cenv.type(body()), NULL); // define stub first for recursion CVal val = body()->compile(cenv); @@ -87,13 +87,13 @@ ADef::compile(CEnv& cenv) } CVal -AIf::compile(CEnv& cenv) +AIf::compile(CEnv& cenv) throw() { return cenv.engine()->compileIf(cenv, this); } CVal -ACons::compile(CEnv& cenv) +ACons::compile(CEnv& cenv) throw() { const AType* type = cenv.type(this); vector<CVal> fields; @@ -103,7 +103,7 @@ ACons::compile(CEnv& cenv) } CVal -ADot::compile(CEnv& cenv) +ADot::compile(CEnv& cenv) throw() { const_iterator i = begin(); AST* tup = *++i; @@ -113,7 +113,7 @@ ADot::compile(CEnv& cenv) } CVal -APrimitive::compile(CEnv& cenv) +APrimitive::compile(CEnv& cenv) throw() { return cenv.engine()->compilePrimitive(cenv, this); } diff --git a/src/constrain.cpp b/src/constrain.cpp index 4ab3924..c815bac 100644 --- a/src/constrain.cpp +++ b/src/constrain.cpp @@ -24,7 +24,7 @@ #define CONSTRAIN_LITERAL(CT, NAME) \ template<> void \ -ALiteral<CT>::constrain(TEnv& tenv, Constraints& c) const { \ +ALiteral<CT>::constrain(TEnv& tenv, Constraints& c) const throw(Error) { \ c.constrain(tenv, this, tenv.named(NAME)); \ } @@ -34,13 +34,13 @@ CONSTRAIN_LITERAL(float, "Float") CONSTRAIN_LITERAL(bool, "Bool") void -AString::constrain(TEnv& tenv, Constraints& c) const +AString::constrain(TEnv& tenv, Constraints& c) const throw(Error) { c.constrain(tenv, this, tenv.named("String")); } void -ASymbol::constrain(TEnv& tenv, Constraints& c) const +ASymbol::constrain(TEnv& tenv, Constraints& c) const throw(Error) { AType** ref = tenv.ref(this); THROW_IF(!ref, loc, (format("undefined symbol `%1%'") % cppstr).str()); @@ -48,7 +48,7 @@ ASymbol::constrain(TEnv& tenv, Constraints& c) const } void -ATuple::constrain(TEnv& tenv, Constraints& c) const +ATuple::constrain(TEnv& tenv, Constraints& c) const throw(Error) { AType* t = tup<AType>(loc, NULL); FOREACHP(const_iterator, p, this) { @@ -59,7 +59,7 @@ ATuple::constrain(TEnv& tenv, Constraints& c) const } void -AFn::constrain(TEnv& tenv, Constraints& c) const +AFn::constrain(TEnv& tenv, Constraints& c) const throw(Error) { set<const ASymbol*> defs; TEnv::Frame frame; @@ -110,7 +110,7 @@ AFn::constrain(TEnv& tenv, Constraints& c) const } void -ACall::constrain(TEnv& tenv, Constraints& c) const +ACall::constrain(TEnv& tenv, Constraints& c) const throw(Error) { for (const_iterator i = begin(); i != end(); ++i) (*i)->constrain(tenv, c); @@ -137,7 +137,7 @@ ACall::constrain(TEnv& tenv, Constraints& c) const } void -ADef::constrain(TEnv& tenv, Constraints& c) const +ADef::constrain(TEnv& tenv, Constraints& c) const throw(Error) { THROW_IF(size() != 3, loc, "`def' requires exactly 2 arguments"); const ASymbol* sym = this->sym(); @@ -151,7 +151,7 @@ ADef::constrain(TEnv& tenv, Constraints& c) const } void -AIf::constrain(TEnv& tenv, Constraints& c) const +AIf::constrain(TEnv& tenv, Constraints& c) const throw(Error) { THROW_IF(size() < 4, loc, "`if' requires at least 3 arguments"); THROW_IF(size() % 2 != 0, loc, "`if' missing final else clause") @@ -173,7 +173,7 @@ AIf::constrain(TEnv& tenv, Constraints& c) const } void -ACons::constrain(TEnv& tenv, Constraints& c) const +ACons::constrain(TEnv& tenv, Constraints& c) const throw(Error) { AType* type = tup<AType>(loc, tenv.Tup, 0); for (const_iterator i = begin() + 1; i != end(); ++i) { @@ -185,7 +185,7 @@ ACons::constrain(TEnv& tenv, Constraints& c) const } void -ADot::constrain(TEnv& tenv, Constraints& c) const +ADot::constrain(TEnv& tenv, Constraints& c) const throw(Error) { THROW_IF(size() != 3, loc, "`.' requires exactly 2 arguments"); const_iterator i = begin(); @@ -206,7 +206,7 @@ ADot::constrain(TEnv& tenv, Constraints& c) const } void -APrimitive::constrain(TEnv& tenv, Constraints& c) const +APrimitive::constrain(TEnv& tenv, Constraints& c) const throw(Error) { const string n = head()->to<const ASymbol*>()->str(); enum { ARITHMETIC, BINARY, LOGICAL, COMPARISON } type; diff --git a/src/lift.cpp b/src/lift.cpp index 733c7b6..94f70e0 100644 --- a/src/lift.cpp +++ b/src/lift.cpp @@ -24,8 +24,9 @@ using namespace std; void -AFn::lift(CEnv& cenv) +AFn::lift(CEnv& cenv) throw() { + // Create a new stub environment frame for parameters cenv.push(); for (const_iterator p = prot()->begin(); p != prot()->end(); ++p) cenv.def((*p)->as<ASymbol*>(), *p, NULL, NULL); @@ -45,35 +46,30 @@ AFn::lift(CEnv& cenv) } void -ACall::lift(CEnv& cenv) +ACall::lift(CEnv& cenv) throw() { AFn* c = cenv.resolve(head())->to<AFn*>(); AType argsT(loc); - // Lift arguments + // Lift arguments and build arguments type for (iterator i = begin() + 1; i != end(); ++i) { (*i)->lift(cenv); argsT.push_back(cenv.type(*i)); } - if (!c) return; // Primitive - - if (c->prot()->size() < size() - 1) - throw Error(loc, (format("too many arguments to function `%1%'") % head()->str()).str()); - if (c->prot()->size() > size() - 1) - throw Error(loc, (format("too few arguments to function `%1%'") % head()->str()).str()); - - cenv.engine()->compileFunction(cenv, c, argsT); // Lift called closure + // Lift callee (if it's not a primitive) + if (c) + cenv.engine()->compileFunction(cenv, c, argsT); } void -ADot::lift(CEnv& cenv) +ADot::lift(CEnv& cenv) throw() { (*(begin() + 1))->lift(cenv); } void -ADef::lift(CEnv& cenv) +ADef::lift(CEnv& cenv) throw() { // Define stub first for recursion cenv.def(sym(), body(), cenv.type(body()), NULL); diff --git a/src/resp.hpp b/src/resp.hpp index 81574e9..ade7257 100644 --- a/src/resp.hpp +++ b/src/resp.hpp @@ -194,10 +194,10 @@ struct AST : public Object { virtual bool value() const { return true; } virtual bool operator==(const AST& o) const = 0; virtual bool contains(const AST* child) const { return false; } - virtual void constrain(TEnv& tenv, Constraints& c) const {} + virtual void constrain(TEnv& tenv, Constraints& c) const throw(Error) {} virtual AST* cps(TEnv& tenv, AST* cont) const; - virtual void lift(CEnv& cenv) {} - virtual CVal compile(CEnv& cenv) = 0; + virtual void lift(CEnv& cenv) throw() {} + virtual CVal compile(CEnv& cenv) throw() = 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 const to() const { return dynamic_cast<T const>(this); } @@ -230,8 +230,8 @@ struct ALiteral : public AST { const ALiteral<T>* r = rhs.to<const ALiteral<T>*>(); return (r && (val == r->val)); } - void constrain(TEnv& tenv, Constraints& c) const; - CVal compile(CEnv& cenv); + void constrain(TEnv& tenv, Constraints& c) const throw(Error); + CVal compile(CEnv& cenv) throw(); const T val; }; @@ -239,15 +239,15 @@ struct ALiteral : public AST { struct AString : public AST, public std::string { AString(Cursor c, const string& s) : AST(c), std::string(s) {} bool operator==(const AST& rhs) const { return this == &rhs; } - void constrain(TEnv& tenv, Constraints& c) const; - CVal compile(CEnv& cenv) { return NULL; } + void constrain(TEnv& tenv, Constraints& c) const throw(Error); + CVal compile(CEnv& cenv) throw() { return NULL; } }; /// Symbol, e.g. "a" struct ASymbol : public AST { bool operator==(const AST& rhs) const { return this == &rhs; } - void constrain(TEnv& tenv, Constraints& c) const; - CVal compile(CEnv& cenv); + void constrain(TEnv& tenv, Constraints& c) const throw(Error); + CVal compile(CEnv& cenv) throw(); const string cppstr; private: friend class PEnv; @@ -304,10 +304,10 @@ struct ATuple : public AST { return true; return false; } - void constrain(TEnv& tenv, Constraints& c) const; - void lift(CEnv& cenv) { FOREACHP(iterator, t, this) (*t)->lift(cenv); } + void constrain(TEnv& tenv, Constraints& c) const throw(Error); + void lift(CEnv& cenv) throw() { FOREACHP(iterator, t, this) (*t)->lift(cenv); } - CVal compile(CEnv& cenv) { throw Error(loc, "tuple compiled"); } + CVal compile(CEnv& cenv) throw() { return NULL; } private: size_t _len; @@ -322,7 +322,7 @@ struct AType : public ATuple { AType(Cursor c, Kind k=EXPR) : ATuple(c), kind(k), id(0) {} AType(Cursor c, AST* ast, va_list args) : ATuple(c, ast, args), kind(EXPR), id(0) {} AType(const AType& copy) : ATuple(copy), kind(copy.kind), id(copy.id) {} - CVal compile(CEnv& cenv) { return NULL; } + CVal compile(CEnv& cenv) throw() { return NULL; } const ATuple* prot() const { assert(kind == EXPR); return (*(begin() + 1))->to<const ATuple*>(); } ATuple* prot() { assert(kind == EXPR); return (*(begin() + 1))->to<ATuple*>(); } bool concrete() const { @@ -395,10 +395,10 @@ inline ostream& operator<<(ostream& out, const Subst& s) { struct AFn : public ATuple { AFn(Cursor c, AST* ast, va_list args) : ATuple(c, ast, args) {} bool operator==(const AST& rhs) const { return this == &rhs; } - void constrain(TEnv& tenv, Constraints& c) const; + void constrain(TEnv& tenv, Constraints& c) const throw(Error); AST* cps(TEnv& tenv, AST* cont) const; - void lift(CEnv& cenv); - CVal compile(CEnv& cenv); + void lift(CEnv& cenv) throw(); + CVal compile(CEnv& cenv) throw(); const ATuple* prot() const { return (*(begin() + 1))->to<const ATuple*>(); } ATuple* prot() { return (*(begin() + 1))->to<ATuple*>(); } /// System level implementations of this (polymorphic) fn @@ -418,10 +418,10 @@ struct AFn : public ATuple { struct ACall : public ATuple { ACall(const ATuple* exp) : ATuple(*exp) {} ACall(Cursor c, AST* ast, va_list args) : ATuple(c, ast, args) {} - void constrain(TEnv& tenv, Constraints& c) const; + void constrain(TEnv& tenv, Constraints& c) const throw(Error); AST* cps(TEnv& tenv, AST* cont) const; - void lift(CEnv& cenv); - CVal compile(CEnv& cenv); + void lift(CEnv& cenv) throw(); + CVal compile(CEnv& cenv) throw(); }; /// Definition special form, e.g. "(def x 2)" @@ -440,32 +440,32 @@ struct ADef : public ACall { } const AST* body() const { return *(begin() + 2); } AST* body() { return *(begin() + 2); } - void constrain(TEnv& tenv, Constraints& c) const; + void constrain(TEnv& tenv, Constraints& c) const throw(Error); AST* cps(TEnv& tenv, AST* cont) const; - void lift(CEnv& cenv); - CVal compile(CEnv& cenv); + void lift(CEnv& cenv) throw(); + CVal compile(CEnv& cenv) throw(); }; /// Conditional special form, e.g. "(if cond thenexp elseexp)" struct AIf : public ACall { AIf(const ATuple* exp) : ACall(exp) {} AIf(Cursor c, AST* ast, va_list args) : ACall(c, ast, args) {} - void constrain(TEnv& tenv, Constraints& c) const; + void constrain(TEnv& tenv, Constraints& c) const throw(Error); AST* cps(TEnv& tenv, AST* cont) const; - CVal compile(CEnv& cenv); + CVal compile(CEnv& cenv) throw(); }; struct ACons : public ACall { ACons(const ATuple* exp) : ACall(exp) {} - void constrain(TEnv& tenv, Constraints& c) const; - CVal compile(CEnv& cenv); + void constrain(TEnv& tenv, Constraints& c) const throw(Error); + CVal compile(CEnv& cenv) throw(); }; struct ADot : public ACall { ADot(const ATuple* exp) : ACall(exp) {} - void constrain(TEnv& tenv, Constraints& c) const; - void lift(CEnv& cenv); - CVal compile(CEnv& cenv); + void constrain(TEnv& tenv, Constraints& c) const throw(Error); + void lift(CEnv& cenv) throw(); + CVal compile(CEnv& cenv) throw(); }; /// Primitive (builtin arithmetic function), e.g. "(+ 2 3)" @@ -478,9 +478,9 @@ struct APrimitive : public ACall { return false;; return true; } - void constrain(TEnv& tenv, Constraints& c) const; + void constrain(TEnv& tenv, Constraints& c) const throw(Error); AST* cps(TEnv& tenv, AST* cont) const; - CVal compile(CEnv& cenv); + CVal compile(CEnv& cenv) throw(); }; @@ -578,8 +578,10 @@ struct Constraint : public pair<AType*,AType*> { /// Type constraint set struct Constraints : public list<Constraint> { + Constraints() : list<Constraint>() {} + Constraints(const_iterator begin, const_iterator end) : list<Constraint>(begin, end) {} void constrain(TEnv& tenv, const AST* o, AType* t); - void replace(AType* s, AType* t); + Constraints& replace(AType* s, AType* t); }; inline ostream& operator<<(ostream& out, const Constraints& c) { diff --git a/src/unify.cpp b/src/unify.cpp index 3f06868..93dd78b 100644 --- a/src/unify.cpp +++ b/src/unify.cpp @@ -92,7 +92,7 @@ Subst::compose(const Subst& delta, const Subst& gamma) } /// Replace all occurrences of @a s with @a t -void +Constraints& Constraints::replace(AType* s, AType* t) { for (Constraints::iterator c = begin(); c != end();) { @@ -103,6 +103,7 @@ Constraints::replace(AType* s, AType* t) substitute(c->second, s, t); c = next; } + return *this; } /// Unify a type constraint set (TAPL 22.4) @@ -112,19 +113,17 @@ unify(const Constraints& constraints) if (constraints.empty()) return Subst(); - AType* s = constraints.begin()->first; - AType* t = constraints.begin()->second; - Constraints cp = constraints; - cp.erase(cp.begin()); + Constraints::const_iterator i = constraints.begin(); + AType* s = i->first; + AType* t = i->second; + Constraints cp(++i, constraints.end()); if (*s == *t) { return unify(cp); } else if (s->kind == AType::VAR && !t->contains(s)) { - cp.replace(s, t); - return Subst::compose(unify(cp), Subst(s, t)); + return Subst::compose(unify(cp.replace(s, t)), Subst(s, t)); } else if (t->kind == AType::VAR && !s->contains(t)) { - cp.replace(t, s); - return Subst::compose(unify(cp), Subst(t, s)); + return Subst::compose(unify(cp.replace(t, s)), Subst(t, s)); } else if (s->kind == AType::EXPR && t->kind == AType::EXPR) { AType::iterator si = s->begin() + 1; AType::iterator ti = t->begin() + 1; |