aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm.cpp10
-rw-r--r--tuplr.cpp4
-rw-r--r--tuplr.hpp1
-rw-r--r--typing.cpp14
4 files changed, 15 insertions, 14 deletions
diff --git a/llvm.cpp b/llvm.cpp
index e2b5992..dcf8365 100644
--- a/llvm.cpp
+++ b/llvm.cpp
@@ -155,11 +155,11 @@ compileFunction(CEnv& cenv, const std::string& name, const Type* retT, const ATu
vector<const Type*> cprot;
for (size_t i = 0; i < protT.size(); ++i) {
AType* at = protT.at(i)->as<AType*>();
- if (!lltype(at)) throw Error("function parameter is untyped");
+ THROW_IF(!lltype(at), "function parameter is untyped")
cprot.push_back(lltype(at));
}
- if (!retT) throw Error("function return is untyped");
+ THROW_IF(!retT, "function return is untyped")
FunctionType* fT = FunctionType::get(static_cast<const Type*>(retT), cprot, false);
Function* f = Function::Create(fT, linkage, name, llengine(cenv)->module);
@@ -312,7 +312,7 @@ ACall::compile(CEnv& cenv)
assert(gt != cenv.tenv.genericTypes.end());
AType* fnT = new AType(loc, cenv.penv.sym("Fn"), protT, cenv.type(this), 0);
Function* f = (Function*)c->funcs.find(fnT);
- if (!f) throw Error((format("callee failed to compile for type %1%") % fnT->str()).str(), loc);
+ THROW_IF(!f, (format("callee failed to compile for type %1%") % fnT->str()).str(), loc)
vector<Value*> params(size() - 1);
for (size_t i = 1; i < size(); ++i)
@@ -560,7 +560,7 @@ eval(CEnv& cenv, const string& name, istream& is)
}
const Type* ctype = lltype(resultType);
- if (!ctype) throw Error("body has non-compilable type", cursor);
+ THROW_IF(!ctype, "body has non-compilable type", cursor)
// Create function for top-level of program
Function* f = compileFunction(cenv, "main", ctype, ATuple(cursor));
@@ -604,7 +604,7 @@ repl(CEnv& cenv)
cenv.tsubst = Subst::compose(cenv.tsubst, TEnv::unify(c)); // Solve type constraints
AType* bodyT = cenv.type(body);
- if (!bodyT) throw Error("call to untyped body", cursor);
+ THROW_IF(!bodyT, "call to untyped body", cursor)
body->lift(cenv);
diff --git a/tuplr.cpp b/tuplr.cpp
index c13b9bc..fbd3bd3 100644
--- a/tuplr.cpp
+++ b/tuplr.cpp
@@ -72,7 +72,7 @@ readExpression(Cursor& cur, istream& in)
while (int c = readChar(cur, in)) {
switch (c) {
case EOF:
- if (!stk.empty()) throw Error("unexpected end of file", cur);
+ THROW_IF(!stk.empty(), "unexpected end of file", cur)
return SExp(cur);
case ';':
while ((c = readChar(cur, in)) != '\n') {}
@@ -127,7 +127,7 @@ readExpression(Cursor& cur, istream& in)
inline SExp
macDef(PEnv& penv, const SExp& exp)
{
- if (exp.size() != 3) throw Error("`def' requires exactly 2 arguments", exp.loc);
+ THROW_IF(exp.size() != 3, "[MAC] `def' requires exactly 2 arguments", exp.loc)
if (exp.at(1).type == SExp::ATOM) {
return exp;
} else {
diff --git a/tuplr.hpp b/tuplr.hpp
index 081428d..efcba1f 100644
--- a/tuplr.hpp
+++ b/tuplr.hpp
@@ -28,6 +28,7 @@
#include <boost/format.hpp>
#define FOREACH(IT, i, c) for (IT i = (c).begin(); i != (c).end(); ++i)
+#define THROW_IF(cond, error, ...) { if (cond) throw Error(error, __VA_ARGS__); }
using namespace std;
using boost::format;
diff --git a/typing.cpp b/typing.cpp
index aba4449..3f2f8e0 100644
--- a/typing.cpp
+++ b/typing.cpp
@@ -149,9 +149,9 @@ ACall::constrain(TEnv& tenv, Constraints& c) const
void
ADefinition::constrain(TEnv& tenv, Constraints& c) const
{
- if (size() != 3) throw Error("`def' requires exactly 2 arguments", loc);
+ THROW_IF(size() != 3, "`def' requires exactly 2 arguments", loc);
const ASymbol* sym = this->sym();
- if (!sym) throw Error("`def' has no symbol", loc);
+ THROW_IF(!sym, "`def' has no symbol", loc)
AType* tvar = tenv.var(at(2));
tenv.def(sym, make_pair(at(2), tvar));
@@ -162,8 +162,8 @@ ADefinition::constrain(TEnv& tenv, Constraints& c) const
void
AIf::constrain(TEnv& tenv, Constraints& c) const
{
- if (size() < 3) throw Error("`if' requires exactly 3 arguments", loc);
- if (size() % 2 != 0) throw Error("`if' missing final else clause", loc);
+ THROW_IF(size() < 4, "`if' requires at least 3 argumentsz", loc);
+ THROW_IF(size() % 2 != 0, "`if' missing final else clause", loc)
for (size_t i = 1; i < size(); ++i)
at(i)->constrain(tenv, c);
AType* retT = tenv.var(this);
@@ -230,7 +230,7 @@ APrimitive::constrain(TEnv& tenv, Constraints& c) const
void
AConsCall::constrain(TEnv& tenv, Constraints& c) const
{
- if (size() != 3) throw Error("`cons' requires exactly 2 arguments", loc);
+ THROW_IF(size() != 3, "`cons' requires exactly 2 arguments", loc)
AType* t = new AType(loc, tenv.penv.sym("Pair"), 0);
for (size_t i = 1; i < size(); ++i) {
at(i)->constrain(tenv, c);
@@ -242,7 +242,7 @@ AConsCall::constrain(TEnv& tenv, Constraints& c) const
void
ACarCall::constrain(TEnv& tenv, Constraints& c) const
{
- if (size() != 2) throw Error("`car' requires exactly 1 argument", loc);
+ THROW_IF(size() != 2, "`car' requires exactly 1 argument", loc)
at(1)->constrain(tenv, c);
AType* carT = tenv.var(this);
AType* pairT = new AType(at(1)->loc, tenv.penv.sym("Pair"), carT, tenv.var(), 0);
@@ -253,7 +253,7 @@ ACarCall::constrain(TEnv& tenv, Constraints& c) const
void
ACdrCall::constrain(TEnv& tenv, Constraints& c) const
{
- if (size() != 2) throw Error("`cdr' requires exactly 1 argument", loc);
+ THROW_IF(size() != 2, "`cdr' requires exactly 1 argument", loc)
at(1)->constrain(tenv, c);
AType* cdrT = tenv.var(this);
AType* pairT = new AType(at(1)->loc, tenv.penv.sym("Pair"), tenv.var(), cdrT, 0);