From ecef8f697c66e15b85beb934d2b617b915a97aab Mon Sep 17 00:00:00 2001 From: David Robillard Date: Fri, 6 Mar 2009 22:12:36 +0000 Subject: 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 --- typing.cpp | 50 +++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 49 insertions(+), 1 deletion(-) (limited to 'typing.cpp') diff --git a/typing.cpp b/typing.cpp index 9dc94f6..071e582 100644 --- a/typing.cpp +++ b/typing.cpp @@ -82,6 +82,54 @@ ASTIf::constrain(TEnv& tenv) const tenv.constrain(at(3), tvar); } +void +ASTPrimitive::constrain(TEnv& tenv) const +{ + const string n = dynamic_cast(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 { @@ -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(s->at(i)); AType* ti = dynamic_cast(t->at(i)); -- cgit v1.2.1