aboutsummaryrefslogtreecommitdiffstats
path: root/src/constrain.cpp
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2010-12-02 06:16:29 +0000
committerDavid Robillard <d@drobilla.net>2010-12-02 06:16:29 +0000
commit563a807be78bfe12e5bfbb9ff0d6da44242696c4 (patch)
tree13cf7ce3b90d072d6e7106c7d2eb4da33209acb0 /src/constrain.cpp
parent32ac40a9ef62d2109563e36fb7cd478426c3489f (diff)
downloadresp-563a807be78bfe12e5bfbb9ff0d6da44242696c4.tar.gz
resp-563a807be78bfe12e5bfbb9ff0d6da44242696c4.tar.bz2
resp-563a807be78bfe12e5bfbb9ff0d6da44242696c4.zip
Represent code as list structure (i.e. traditional LISP lists built from pairs), rather than tuple structure.
Remove unused/crufty depoly stage. Remove cps from AST interface (but keep cps.cpp code around for later). Improved command line interface for compilation stages (options -T -L -S). git-svn-id: http://svn.drobilla.net/resp/resp@277 ad02d1e2-f140-0410-9f75-f8b11f17cedd
Diffstat (limited to 'src/constrain.cpp')
-rw-r--r--src/constrain.cpp107
1 files changed, 56 insertions, 51 deletions
diff --git a/src/constrain.cpp b/src/constrain.cpp
index ef8e3bf..b9ce471 100644
--- a/src/constrain.cpp
+++ b/src/constrain.cpp
@@ -49,7 +49,7 @@ void
AQuote::constrain(TEnv& tenv, Constraints& c) const throw(Error)
{
c.constrain(tenv, this, tenv.named("Quote"));
- (*(begin() + 1))->constrain(tenv, c);
+ list_ref(1)->constrain(tenv, c);
}
void
@@ -63,11 +63,12 @@ ASymbol::constrain(TEnv& tenv, Constraints& c) const throw(Error)
void
ATuple::constrain(TEnv& tenv, Constraints& c) const throw(Error)
{
- AType* t = tup<AType>(loc, NULL);
+ TList t;
FOREACHP(const_iterator, p, this) {
(*p)->constrain(tenv, c);
- t->push_back(const_cast<AType*>(tenv.var(*p)));
+ t.push_back(const_cast<AType*>(tenv.var(*p)));
}
+ t.head->loc = loc;
c.constrain(tenv, this, t);
}
@@ -78,7 +79,7 @@ AFn::constrain(TEnv& tenv, Constraints& c) const throw(Error)
TEnv::Frame frame;
// Add parameters to environment frame
- AType* protT = tup<AType>(loc, NULL);
+ TList protT;
for (ATuple::const_iterator i = prot()->begin(); i != prot()->end(); ++i) {
const ASymbol* sym = (*i)->to<const ASymbol*>();
THROW_IF(!sym, (*i)->loc, "parameter name is not a symbol");
@@ -87,10 +88,11 @@ AFn::constrain(TEnv& tenv, Constraints& c) const throw(Error)
defs.insert(sym);
const AType* tvar = tenv.fresh(sym);
frame.push_back(make_pair(sym, tvar));
- protT->push_back(const_cast<AType*>(tvar));
+ protT.push_back(const_cast<AType*>(tvar));
}
+ protT.head->loc = loc;
- const_iterator i = begin() + 1;
+ const_iterator i = iter_at(1);
c.constrain(tenv, *i, protT);
// Add internal definitions to environment frame
@@ -108,12 +110,14 @@ AFn::constrain(TEnv& tenv, Constraints& c) const throw(Error)
tenv.push(frame);
- AST* exp = NULL;
- for (i = begin() + 2; i != end(); ++i)
- (exp = *i)->constrain(tenv, c);
+ const AST* exp = NULL;
+ for (i = iter_at(2); i != end(); ++i) {
+ exp = *i;
+ exp->constrain(tenv, c);
+ }
const AType* bodyT = tenv.var(exp);
- const AType* fnT = tup<const AType>(loc, tenv.Fn, protT, bodyT, 0);
+ const AType* fnT = tup<const AType>(loc, tenv.Fn, protT.head, bodyT, 0);
Object::pool.addRoot(fnT);
tenv.pop();
@@ -130,28 +134,28 @@ ACall::constrain(TEnv& tenv, Constraints& c) const throw(Error)
const AType* fnType = tenv.var(head());
if (fnType->kind != AType::VAR) {
if (fnType->kind == AType::PRIM
- || fnType->size() < 2
+ || fnType->list_len() < 2
|| fnType->head()->str() != "Fn")
throw Error(loc, (format("call to non-function `%1%'") % head()->str()).str());
- size_t numArgs = fnType->prot()->size();
- THROW_IF(numArgs != size() - 1, loc,
- (format("expected %1% arguments, got %2%") % numArgs % (size() - 1)).str());
+ size_t numArgs = fnType->prot()->list_len();
+ THROW_IF(numArgs != list_len() - 1, loc,
+ (format("expected %1% arguments, got %2%") % numArgs % (list_len() - 1)).str());
}
const AType* retT = tenv.var(this);
- AType* argsT = tup<AType>(loc, 0);
- for (const_iterator i = begin() + 1; i != end(); ++i)
- argsT->push_back(const_cast<AType*>(tenv.var(*i)));
-
- c.constrain(tenv, head(), tup<AType>(head()->loc, tenv.Fn, argsT, retT, 0));
+ TList argsT;
+ for (const_iterator i = iter_at(1); i != end(); ++i)
+ argsT.push_back(const_cast<AType*>(tenv.var(*i)));
+ argsT.head->loc = loc;
+ c.constrain(tenv, head(), tup<AType>(head()->loc, tenv.Fn, argsT.head, retT, 0));
c.constrain(tenv, this, retT);
}
void
ADef::constrain(TEnv& tenv, Constraints& c) const throw(Error)
{
- THROW_IF(size() != 3, loc, "`def' requires exactly 2 arguments");
+ THROW_IF(list_len() != 3, loc, "`def' requires exactly 2 arguments");
const ASymbol* sym = this->sym();
THROW_IF(!sym, loc, "`def' has no symbol")
@@ -165,12 +169,12 @@ ADef::constrain(TEnv& tenv, Constraints& c) const throw(Error)
void
AIf::constrain(TEnv& tenv, Constraints& c) const throw(Error)
{
- THROW_IF(size() < 4, loc, "`if' requires at least 3 arguments");
- THROW_IF(size() % 2 != 0, loc, "`if' missing final else clause")
- for (const_iterator i = begin() + 1; i != end(); ++i)
+ THROW_IF(list_len() < 4, loc, "`if' requires at least 3 arguments");
+ THROW_IF(list_len() % 2 != 0, loc, "`if' missing final else clause");
+ for (const_iterator i = iter_at(1); i != end(); ++i)
(*i)->constrain(tenv, c);
const AType* retT = tenv.var(this);
- for (const_iterator i = begin() + 1; true; ++i) {
+ for (const_iterator i = iter_at(1); true; ++i) {
const_iterator next = i;
++next;
if (next == end()) { // final (else) expression
@@ -187,12 +191,12 @@ AIf::constrain(TEnv& tenv, Constraints& c) const throw(Error)
void
AMatch::constrain(TEnv& tenv, Constraints& c) const throw(Error)
{
- THROW_IF(size() < 5, loc, "`match' requires at least 4 arguments");
- const AST* matchee = (*(begin() + 1));
+ THROW_IF(list_len() < 5, loc, "`match' requires at least 4 arguments");
+ const AST* matchee = list_ref(1);
const AType* retT = tenv.var();
const AType* matcheeT = NULL;// = tup<AType>(loc, tenv.U, 0);
matchee->constrain(tenv, c);
- for (const_iterator i = begin() + 2; i != end();) {
+ for (const_iterator i = iter_at(2); i != end();) {
const AST* exp = *i++;
const ATuple* pattern = exp->to<const ATuple*>();
THROW_IF(!pattern, exp->loc, "pattern expression expected");
@@ -218,25 +222,26 @@ AMatch::constrain(TEnv& tenv, Constraints& c) const throw(Error)
void
ADefType::constrain(TEnv& tenv, Constraints& c) const throw(Error)
{
- THROW_IF(size() < 3, loc, "`def-type' requires at least 2 arguments");
- const_iterator i = begin() + 1;
+ THROW_IF(list_len() < 3, loc, "`def-type' requires at least 2 arguments");
+ const_iterator i = iter_at(1);
const ATuple* prot = (*i)->to<const ATuple*>();
THROW_IF(!prot, (*i)->loc, "first argument of `def-type' is not a tuple");
const ASymbol* sym = (*prot->begin())->as<const ASymbol*>();
THROW_IF(!sym, (*prot->begin())->loc, "type name is not a symbol");
THROW_IF(tenv.ref(sym), loc, "type redefinition");
- AType* type = tup<AType>(loc, tenv.U, 0);
- for (const_iterator i = begin() + 2; i != end(); ++i) {
+ TList type(new AType(tenv.U, NULL, loc));
+ for (const_iterator i = iter_at(2); i != end(); ++i) {
const ATuple* exp = (*i)->as<const ATuple*>();
const ASymbol* tag = (*exp->begin())->as<const ASymbol*>();
- AType* consT = new AType(exp->loc, AType::EXPR);
- consT->push_back(new AType(const_cast<ASymbol*>(sym), AType::NAME));
+ TList consT;
+ consT.push_back(new AType(const_cast<ASymbol*>(sym), AType::NAME));
for (ATuple::const_iterator i = exp->begin(); i != exp->end(); ++i) {
const ASymbol* sym = (*i)->to<const ASymbol*>();
THROW_IF(!sym, (*i)->loc, "type expression element is not a symbol");
- consT->push_back(new AType(const_cast<ASymbol*>(sym), AType::NAME));
+ consT.push_back(new AType(const_cast<ASymbol*>(sym), AType::NAME));
}
- type->push_back(consT);
+ consT.head->loc = exp->loc;
+ type.push_back(consT);
tenv.def(tag, consT);
}
tenv.def(sym, type);
@@ -248,13 +253,13 @@ ACons::constrain(TEnv& tenv, Constraints& c) const throw(Error)
const ASymbol* sym = (*begin())->as<const ASymbol*>();
const AType* type = NULL;
- for (const_iterator i = begin() + 1; i != end(); ++i)
+ for (const_iterator i = iter_at(1); i != end(); ++i)
(*i)->constrain(tenv, c);
if (sym->cppstr == "Tup") {
- AType* tupT = tup<AType>(loc, tenv.Tup, 0);
- for (const_iterator i = begin() + 1; i != end(); ++i) {
- tupT->push_back(const_cast<AType*>(tenv.var(*i)));
+ TList tupT(new AType(tenv.Tup, NULL, loc));
+ for (const_iterator i = iter_at(1); i != end(); ++i) {
+ tupT.push_back(const_cast<AType*>(tenv.var(*i)));
}
type = tupT;
} else {
@@ -269,21 +274,21 @@ ACons::constrain(TEnv& tenv, Constraints& c) const throw(Error)
void
ADot::constrain(TEnv& tenv, Constraints& c) const throw(Error)
{
- THROW_IF(size() != 3, loc, "`.' requires exactly 2 arguments");
- const_iterator i = begin();
- AST* obj = *++i;
- ALiteral<int32_t>* idx = (*++i)->to<ALiteral<int32_t>*>();
+ THROW_IF(list_len() != 3, loc, "`.' requires exactly 2 arguments");
+ const_iterator i = begin();
+ const AST* obj = *++i;
+ const ALiteral<int32_t>* idx = (*++i)->to<const ALiteral<int32_t>*>();
THROW_IF(!idx, loc, "the 2nd argument to `.' must be a literal integer");
obj->constrain(tenv, c);
const AType* retT = tenv.var(this);
c.constrain(tenv, this, retT);
- AType* objT = tup<AType>(loc, tenv.Tup, 0);
+ TList objT(new AType(tenv.Tup, NULL, loc));
for (int i = 0; i < idx->val; ++i)
- objT->push_back(const_cast<AType*>(tenv.var()));
- objT->push_back(const_cast<AType*>(retT));
- objT->push_back(new AType(obj->loc, AType::DOTS));
+ objT.push_back(const_cast<AType*>(tenv.var()));
+ objT.push_back(const_cast<AType*>(retT));
+ objT.push_back(new AType(obj->loc, AType::DOTS));
c.constrain(tenv, obj, objT);
}
@@ -313,26 +318,26 @@ APrimitive::constrain(TEnv& tenv, Constraints& c) const throw(Error)
const AType* var = NULL;
switch (type) {
case ARITHMETIC:
- if (size() < 3)
+ if (list_len() < 3)
throw Error(loc, (format("`%1%' requires at least 2 arguments") % n).str());
for (++i; i != end(); ++i)
c.constrain(tenv, *i, tenv.var(this));
break;
case BINARY:
- if (size() != 3)
+ if (list_len() != 3)
throw Error(loc, (format("`%1%' requires exactly 2 arguments") % n).str());
c.constrain(tenv, *++i, tenv.var(this));
c.constrain(tenv, *++i, tenv.var(this));
break;
case LOGICAL:
- if (size() != 3)
+ if (list_len() != 3)
throw Error(loc, (format("`%1%' requires exactly 2 arguments") % n).str());
c.constrain(tenv, this, tenv.named("Bool"));
c.constrain(tenv, *++i, tenv.named("Bool"));
c.constrain(tenv, *++i, tenv.named("Bool"));
break;
case COMPARISON:
- if (size() != 3)
+ if (list_len() != 3)
throw Error(loc, (format("`%1%' requires exactly 2 arguments") % n).str());
var = tenv.var(*++i);
c.constrain(tenv, this, tenv.named("Bool"));