aboutsummaryrefslogtreecommitdiffstats
path: root/typing.cpp
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2009-03-06 22:12:36 +0000
committerDavid Robillard <d@drobilla.net>2009-03-06 22:12:36 +0000
commitecef8f697c66e15b85beb934d2b617b915a97aab (patch)
tree576af3f3063f07c08ecbbd1cfdb9d8034cc5bc2b /typing.cpp
parent382d3051052fd20ab55f40beb7664bfb3f0379a1 (diff)
downloadresp-ecef8f697c66e15b85beb934d2b617b915a97aab.tar.gz
resp-ecef8f697c66e15b85beb934d2b617b915a97aab.tar.bz2
resp-ecef8f697c66e15b85beb934d2b617b915a97aab.zip
Cleanup and de-llvm-ify primitive stuff.
Fix type inference (only treat actual type expressions as type expressions). git-svn-id: http://svn.drobilla.net/resp/tuplr@64 ad02d1e2-f140-0410-9f75-f8b11f17cedd
Diffstat (limited to 'typing.cpp')
-rw-r--r--typing.cpp50
1 files changed, 49 insertions, 1 deletions
diff --git a/typing.cpp b/typing.cpp
index 9dc94f6..071e582 100644
--- a/typing.cpp
+++ b/typing.cpp
@@ -83,6 +83,54 @@ ASTIf::constrain(TEnv& tenv) const
}
void
+ASTPrimitive::constrain(TEnv& tenv) const
+{
+ const string n = dynamic_cast<ASTSymbol*>(at(0))->str();
+ enum { ARITHMETIC, BINARY, BITWISE, COMPARISON } type;
+ if (n == "+" || n == "-" || n == "*" || n == "/")
+ type = ARITHMETIC;
+ else if (n == "%")
+ type = BINARY;
+ else if (n == "&" || n == "|" || n == "^")
+ type = BITWISE;
+ else if (n == "=" || n == "!=" || n == ">" || n == ">=" || n == "<" || n == "<=")
+ type = COMPARISON;
+ else
+ throw Error((format("unknown primitive `%1%'") % n).str(), exp.loc);
+
+ FOREACH(const_iterator, p, *this)
+ (*p)->constrain(tenv);
+
+ switch (type) {
+ case ARITHMETIC:
+ if (size() < 3)
+ throw Error((format("`%1%' requires at least 2 arguments") % n).str(), exp.loc);
+ for (size_t i = 1; i < size(); ++i)
+ tenv.constrain(this, tenv.type(at(i)));
+ break;
+ case BINARY:
+ if (size() != 3)
+ throw Error((format("`%1%' requires exactly 2 arguments") % n).str(), exp.loc);
+ tenv.constrain(this, tenv.type(at(1)));
+ tenv.constrain(this, tenv.type(at(2)));
+ break;
+ case BITWISE:
+ if (size() != 3)
+ throw Error((format("`%1%' requires exactly 2 arguments") % n).str(), exp.loc);
+ tenv.constrain(this, tenv.named("Bool"));
+ tenv.constrain(at(1), tenv.named("Bool"));
+ tenv.constrain(at(2), tenv.named("Bool"));
+ break;
+ case COMPARISON:
+ if (size() != 3)
+ throw Error((format("`%1%' requires exactly 2 arguments") % n).str(), exp.loc);
+ tenv.constrain(this, tenv.named("Bool"));
+ tenv.constrain(at(1), tenv.type(at(2)));
+ break;
+ }
+}
+
+void
ASTConsCall::constrain(TEnv& tenv) const
{
AType* t = new AType(ASTTuple(tenv.penv.sym("Pair"), 0));
@@ -174,7 +222,7 @@ TEnv::unify(const Constraints& constraints) // TAPL 22.4
} else if (t->var() && !s->contains(t)) {
substConstraints(cp, t, s);
return compose(unify(cp), TSubst(t, s));
- } else if (s->size() == t->size()) {
+ } else if (s->kind == AType::EXPR && s->kind == t->kind && s->size() == t->size()) {
for (size_t i = 0; i < s->size(); ++i) {
AType* si = dynamic_cast<AType*>(s->at(i));
AType* ti = dynamic_cast<AType*>(t->at(i));