From 43a365c87a017513be9370557ee2cbbad3f0648a Mon Sep 17 00:00:00 2001 From: David Robillard Date: Thu, 5 Mar 2009 20:00:55 +0000 Subject: Remove silly looking parenthesis from primitive type expressions. git-svn-id: http://svn.drobilla.net/resp/tuplr@47 ad02d1e2-f140-0410-9f75-f8b11f17cedd --- tuplr.cpp | 67 +++++++++++++++++++++++++++++++++++++++------------------------ 1 file changed, 42 insertions(+), 25 deletions(-) (limited to 'tuplr.cpp') diff --git a/tuplr.cpp b/tuplr.cpp index b93918b..9920172 100644 --- a/tuplr.cpp +++ b/tuplr.cpp @@ -215,22 +215,32 @@ struct ASTTuple : public AST, public vector { Value* compile(CEnv& cenv) { throw Error("tuple compiled"); } }; -/// Type Expression, e.g. "(Int)" or "(Fn ((Int)) (Float))" +/// Type Expression, e.g. "Int", "(Fn (Int Int) Float)" struct AType : public ASTTuple { - AType(const ASTTuple& t) : ASTTuple(t), var(false), ctype(0) {} - AType(unsigned i) : var(true), id(i), ctype(0) {} - AType(ASTSymbol* n, const Type* t) : var(false), ctype(t) { - push_back(n); + AType(const ASTTuple& t) : ASTTuple(t), kind(EXPR), ctype(0) {} + AType(unsigned i) : kind(VAR), id(i), ctype(0) {} + AType(ASTSymbol* n, const Type* t) : kind(PRIM), ctype(t) { push_back(n); } + string str() const { + switch (kind) { + case VAR: return (format("?%1%") % id).str(); + case PRIM: return at(0)->str(); + case EXPR: return ASTTuple::str(); + } + return ""; // never reached } - string str() const { return var ? (format("?%1%") % id).str() : ASTTuple::str(); } void constrain(TEnv& tenv) const {} Value* compile(CEnv& cenv) { return NULL; } + bool var() const { return kind == VAR; } bool concrete() const { - if (var) return false; - FOREACH(const_iterator, t, *this) { - AType* kid = dynamic_cast(*t); - if (kid && !kid->concrete()) - return false; + switch (kind) { + case VAR: return false; + case PRIM: return true; + case EXPR: + FOREACH(const_iterator, t, *this) { + AType* kid = dynamic_cast(*t); + if (kid && !kid->concrete()) + return false; + } } return true; } @@ -238,11 +248,15 @@ struct AType : public ASTTuple { const AType* rt = dynamic_cast(&rhs); if (!rt) return false; - else if (var && rt->var) - return id == rt->id; - else if (!var && !rt->var) - return ASTTuple::operator==(rhs); - return false; + else if (kind != rt->kind) + return false; + else + switch (kind) { + case VAR: return id == rt->id; + case PRIM: return at(0)->str() == rt->at(0)->str(); + case EXPR: return ASTTuple::operator==(rhs); + } + return false; // never reached } const Type* type() { if (at(0)->str() == "Pair") { @@ -256,8 +270,9 @@ struct AType : public ASTTuple { return ctype; } } - bool var; - unsigned id; + enum Kind { VAR, PRIM, EXPR }; + Kind kind; + unsigned id; private: const Type* ctype; }; @@ -680,14 +695,16 @@ TEnv::unify(const Constraints& constraints) // TAPL 22.4 AType* s = constraints.begin()->first; AType* t = constraints.begin()->second; Constraints cp = constraints; + //FOREACH(Constraints::const_iterator, c, cp) + // out << c->first->str() << " : " << c->second->str() << endl; cp.erase(cp.begin()); if (*s == *t) { return unify(cp); - } else if (s->var && !t->contains(s)) { + } else if (s->var() && !t->contains(s)) { substConstraints(cp, s, t); return compose(unify(cp), TSubst(s, t)); - } else if (t->var && !s->contains(t)) { + } else if (t->var() && !s->contains(t)) { substConstraints(cp, t, s); return compose(unify(cp), TSubst(t, s)); } else if (s->size() == t->size()) { @@ -779,7 +796,7 @@ compileFunction(CEnv& cenv, const std::string& name, const Type* retT, ASTTuple& vector cprot; for (size_t i = 0; i < prot.size(); ++i) { AType* at = cenv.tenv.type(prot.at(i)); - if (!at->type() || at->var) throw Error("function parameter is untyped"); + if (!at->type() || at->var()) throw Error("function parameter is untyped"); cprot.push_back(at->type()); } @@ -986,7 +1003,7 @@ ASTPrimitive::compile(CEnv& cenv) val = cenv.builder.CreateBinOp(bo, val, cenv.compile(at(i))); return val; } else if (op == Instruction::ICmp) { - bool isInt = cenv.tenv.type(at(1))->str() == "(Int)"; + bool isInt = cenv.tenv.type(at(1))->str() == "Int"; if (isInt) { return cenv.builder.CreateICmp((CmpInst::Predicate)arg, a, b); } else { @@ -1133,7 +1150,7 @@ eval(CEnv& cenv, ExecutionEngine* engine, const string& name, istream& is) exprs.push_back(make_pair(exp, result)); } - if (!resultType || resultType->var) throw Error("body is undefined/untyped", cursor); + if (!resultType || resultType->var()) throw Error("body is undefined/untyped", cursor); } catch (Error& e) { err << e.what() << endl; @@ -1184,8 +1201,8 @@ repl(CEnv& cenv, ExecutionEngine* engine) cenv.tenv.solve(); // Solve and apply type constraints AType* bodyT = cenv.tenv.type(body); - if (!bodyT) throw Error("call to untyped body", cursor); - if (bodyT->var) throw Error("call to variable typed body", cursor); + if (!bodyT) throw Error("call to untyped body", cursor); + if (!bodyT->concrete()) throw Error("call to variable typed body", cursor); body->lift(cenv); -- cgit v1.2.1