aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2009-10-15 21:46:31 +0000
committerDavid Robillard <d@drobilla.net>2009-10-15 21:46:31 +0000
commit7426c554dd639200a8541c66b376b9a7fab1ab07 (patch)
treeac57541dfac6a2999d58bb25cc39ab7b1addf761
parent1ea87d79fc98553abec35eb74eb599d254d908b0 (diff)
downloadresp-7426c554dd639200a8541c66b376b9a7fab1ab07.tar.gz
resp-7426c554dd639200a8541c66b376b9a7fab1ab07.tar.bz2
resp-7426c554dd639200a8541c66b376b9a7fab1ab07.zip
Type and const correct Subst::apply.
git-svn-id: http://svn.drobilla.net/resp/tuplr@232 ad02d1e2-f140-0410-9f75-f8b11f17cedd
-rw-r--r--src/compile.cpp2
-rw-r--r--src/constrain.cpp7
-rw-r--r--src/tuplr.hpp30
3 files changed, 20 insertions, 19 deletions
diff --git a/src/compile.cpp b/src/compile.cpp
index 3918617..d525f57 100644
--- a/src/compile.cpp
+++ b/src/compile.cpp
@@ -55,7 +55,7 @@ ACall::compile(CEnv& cenv)
protT.push_back(cenv.type(*i));
AType fnT(loc);
- fnT.push_back(cenv.penv.sym("Fn"));
+ fnT.push_back(cenv.tenv.Fn);
fnT.push_back(&protT);
fnT.push_back(cenv.type(this));
diff --git a/src/constrain.cpp b/src/constrain.cpp
index 982f195..0c9951c 100644
--- a/src/constrain.cpp
+++ b/src/constrain.cpp
@@ -101,7 +101,7 @@ AFn::constrain(TEnv& tenv, Constraints& c) const
(exp = *i)->constrain(tenv, c);
AType* bodyT = tenv.var(exp);
- AType* fnT = tup<AType>(loc, tenv.penv.sym("Fn"), protT, bodyT, 0);
+ AType* fnT = tup<AType>(loc, tenv.Fn, protT, bodyT, 0);
Object::pool.addRoot(fnT);
tenv.pop();
@@ -119,8 +119,7 @@ ACall::constrain(TEnv& tenv, Constraints& c) const
if (fnType->kind != AType::VAR) {
if (fnType->kind == AType::PRIM
|| fnType->size() < 2
- || !fnType->head()->to<const ASymbol*>()
- || fnType->head()->to<const ASymbol*>()->cppstr != "Fn")
+ || fnType->head()->str() != "Fn")
throw Error(loc, (format("call to non-function `%1%'") % head()->str()).str());
size_t numArgs = fnType->prot()->size();
@@ -133,7 +132,7 @@ ACall::constrain(TEnv& tenv, Constraints& c) const
for (const_iterator i = begin() + 1; i != end(); ++i)
argsT->push_back(tenv.var(*i));
- c.constrain(tenv, head(), tup<AType>(head()->loc, tenv.penv.sym("Fn"), argsT, retT, 0));
+ c.constrain(tenv, head(), tup<AType>(head()->loc, tenv.Fn, argsT, retT, 0));
c.constrain(tenv, this, retT);
}
diff --git a/src/tuplr.hpp b/src/tuplr.hpp
index 61e3f41..0390435 100644
--- a/src/tuplr.hpp
+++ b/src/tuplr.hpp
@@ -289,6 +289,7 @@ struct AType : public ATuple {
AType(Cursor c, unsigned i) : ATuple(c), kind(VAR), id(i) {}
AType(Cursor c) : ATuple(c), kind(EXPR), 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; }
const ATuple* prot() const { assert(kind == EXPR); return (*(begin() + 1))->to<const ATuple*>(); }
ATuple* prot() { assert(kind == EXPR); return (*(begin() + 1))->to<ATuple*>(); }
@@ -332,24 +333,21 @@ struct Subst : public list< pair<const AType*,AType*> > {
return j;
return end();
}
- AST* apply(AST* ast) const {
- AType* in = ast->to<AType*>();
- if (!in) return ast;
+ AType* apply(const AType* in) const {
if (in->kind == AType::EXPR) {
AType* out = tup<AType>(in->loc, NULL);
- for (ATuple::iterator i = in->begin(); i != in->end(); ++i)
- out->push_back(apply(*i));
+ for (ATuple::const_iterator i = in->begin(); i != in->end(); ++i)
+ out->push_back(apply((*i)->as<AType*>()));
return out;
} else {
const_iterator i = find(in);
if (i != end()) {
- AST* out = i->second;
- AType* outT = out->to<AType*>();
- if (outT && outT->kind == AType::EXPR && !outT->concrete())
- out = apply(out);
+ AType* out = i->second->as<AType*>();
+ if (out->kind == AType::EXPR && !out->concrete())
+ out = apply(out->as<AType*>());
return out;
} else {
- return in;
+ return new AType(*in);
}
}
}
@@ -547,7 +545,9 @@ inline ostream& operator<<(ostream& out, const Constraints& c) {
/// Type-Time Environment
struct TEnv : public Env<const ASymbol*, AType*> {
- TEnv(PEnv& p) : penv(p), varID(1) {}
+ TEnv(PEnv& p) : penv(p), varID(1), Fn(new AType(penv.sym("Fn"))) {
+ Object::pool.addRoot(Fn);
+ }
AType* fresh(const ASymbol* sym) {
return def(sym, new AType(sym->loc, varID++));
}
@@ -573,9 +573,11 @@ struct TEnv : public Env<const ASymbol*, AType*> {
typedef map<const AST*, AType*> Vars;
- Vars vars;
- PEnv& penv;
- unsigned varID;
+ Vars vars;
+ PEnv& penv;
+ unsigned varID;
+
+ AType* Fn;
};
Subst unify(const Constraints& c);