aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2010-04-08 20:53:09 +0000
committerDavid Robillard <d@drobilla.net>2010-04-08 20:53:09 +0000
commit1f988f420ba3827941886962680f3e2ad6f01740 (patch)
tree9e89d69b1b1796491b144ba2253fda9f5226d3df
parent55b6a3f313670d2cb13847d1f1b04fe3e4b21d63 (diff)
downloadresp-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.cpp18
-rw-r--r--src/constrain.cpp22
-rw-r--r--src/lift.cpp22
-rw-r--r--src/resp.hpp66
-rw-r--r--src/unify.cpp17
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;