diff options
author | David Robillard <d@drobilla.net> | 2010-12-02 06:16:29 +0000 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2010-12-02 06:16:29 +0000 |
commit | 563a807be78bfe12e5bfbb9ff0d6da44242696c4 (patch) | |
tree | 13cf7ce3b90d072d6e7106c7d2eb4da33209acb0 /src/constrain.cpp | |
parent | 32ac40a9ef62d2109563e36fb7cd478426c3489f (diff) | |
download | resp-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.cpp | 107 |
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")); |