aboutsummaryrefslogtreecommitdiffstats
path: root/tuplr.cpp
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2009-03-05 20:00:55 +0000
committerDavid Robillard <d@drobilla.net>2009-03-05 20:00:55 +0000
commit43a365c87a017513be9370557ee2cbbad3f0648a (patch)
treeffe6888e79863ba5321bcf580a3c499334623aa4 /tuplr.cpp
parent0e1d11ad0dae33049b4a22d42a37503db2a698b0 (diff)
downloadresp-43a365c87a017513be9370557ee2cbbad3f0648a.tar.gz
resp-43a365c87a017513be9370557ee2cbbad3f0648a.tar.bz2
resp-43a365c87a017513be9370557ee2cbbad3f0648a.zip
Remove silly looking parenthesis from primitive type expressions.
git-svn-id: http://svn.drobilla.net/resp/tuplr@47 ad02d1e2-f140-0410-9f75-f8b11f17cedd
Diffstat (limited to 'tuplr.cpp')
-rw-r--r--tuplr.cpp67
1 files changed, 42 insertions, 25 deletions
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<AST*> {
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<AType*>(*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<AType*>(*t);
+ if (kid && !kid->concrete())
+ return false;
+ }
}
return true;
}
@@ -238,11 +248,15 @@ struct AType : public ASTTuple {
const AType* rt = dynamic_cast<const AType*>(&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<const Type*> 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);