diff options
author | David Robillard <d@drobilla.net> | 2009-03-06 22:12:36 +0000 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2009-03-06 22:12:36 +0000 |
commit | ecef8f697c66e15b85beb934d2b617b915a97aab (patch) | |
tree | 576af3f3063f07c08ecbbd1cfdb9d8034cc5bc2b /typing.cpp | |
parent | 382d3051052fd20ab55f40beb7664bfb3f0379a1 (diff) | |
download | resp-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.cpp | 50 |
1 files changed, 49 insertions, 1 deletions
@@ -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)); |