aboutsummaryrefslogtreecommitdiffstats
path: root/tuplr.cpp
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2009-03-05 05:27:07 +0000
committerDavid Robillard <d@drobilla.net>2009-03-05 05:27:07 +0000
commitabe7fec15a97f71f2ee1df15a3d85ce59a232dc6 (patch)
tree2dca1e259d0d977241b1b9ef871a0c712920dd6c /tuplr.cpp
parent47aacbec0a14d80e1bec0e3307bd74f0c3cecd61 (diff)
downloadresp-abe7fec15a97f71f2ee1df15a3d85ce59a232dc6.tar.gz
resp-abe7fec15a97f71f2ee1df15a3d85ce59a232dc6.tar.bz2
resp-abe7fec15a97f71f2ee1df15a3d85ce59a232dc6.zip
GCC style error reporting with line and column number.
git-svn-id: http://svn.drobilla.net/resp/tuplr@40 ad02d1e2-f140-0410-9f75-f8b11f17cedd
Diffstat (limited to 'tuplr.cpp')
-rw-r--r--tuplr.cpp218
1 files changed, 116 insertions, 102 deletions
diff --git a/tuplr.cpp b/tuplr.cpp
index c1cd43a..c4ee5d2 100644
--- a/tuplr.cpp
+++ b/tuplr.cpp
@@ -24,6 +24,7 @@
#include <stack>
#include <string>
#include <vector>
+#include <boost/format.hpp>
#include "llvm/Analysis/Verifier.h"
#include "llvm/DerivedTypes.h"
#include "llvm/ExecutionEngine/ExecutionEngine.h"
@@ -39,21 +40,32 @@
using namespace llvm;
using namespace std;
+using boost::format;
+
+struct Cursor {
+ Cursor(const string& n="", unsigned l=1, unsigned c=0) : name(n), line(l), col(c) {}
+ string str() const { return (format("%1%:%2%:%3%") % name % line % col).str(); }
+ string name;
+ unsigned line;
+ unsigned col;
+};
-struct Error : public std::exception {
- Error(const char* m) : msg(m) {}
- const char* what() const throw() { return msg; }
- const char* msg;
+struct Error {
+ Error(const string& m, Cursor c=Cursor()) : msg(m), loc(c) {}
+ const string what() const throw() { return loc.str() + ": error: " + msg; }
+ string msg;
+ Cursor loc;
};
template<typename A>
struct Exp { // ::= Atom | (Exp*)
- Exp() : type(LIST) {}
- Exp(const A& a) : type(ATOM), atom(a) {}
+ Exp(Cursor c) : loc(c), type(LIST) {}
+ Exp(Cursor c, const A& a) : loc(c), type(ATOM), atom(a) {}
+ Cursor loc;
enum { ATOM, LIST } type;
typedef std::vector< Exp<A> > List;
- A atom;
- List list;
+ A atom;
+ List list;
};
@@ -61,34 +73,38 @@ struct Exp { // ::= Atom | (Exp*)
* S-Expression Lexer :: text -> S-Expressions (SExp) *
***************************************************************************/
-struct SyntaxError : public Error { SyntaxError(const char* m) : Error(m) {} };
typedef Exp<string> SExp;
static SExp
-readExpression(std::istream& in)
+readExpression(Cursor& loc, std::istream& in)
{
-#define PUSH(s, t) { if (t != "") { s.top().list.push_back(t); t = ""; } }
-#define YIELD(s, t) { if (s.empty()) return t; else PUSH(s, t) }
+#define PUSH(s, t) { if (t != "") { s.top().list.push_back(SExp(loc, t)); t = ""; } }
+#define YIELD(s, t) { if (s.empty()) return SExp(loc, t); else PUSH(s, t) }
stack<SExp> stk;
string tok;
while (char ch = in.get()) {
+ ++loc.col;
switch (ch) {
case EOF:
- return SExp();
- case ' ': case '\t': case '\n':
+ if (!stk.empty()) throw Error("unexpected end of file", loc);
+ return SExp(loc);
+ case '\n':
+ ++loc.line;
+ loc.col = 0;
+ case ' ': case '\t':
if (tok != "") YIELD(stk, tok);
break;
case '"':
- do { tok.push_back(ch); } while ((ch = in.get()) != '"');
+ do { tok.push_back(ch); ++loc.col; } while ((ch = in.get()) != '"');
YIELD(stk, tok + '"');
break;
case '(':
- stk.push(SExp());
+ stk.push(SExp(loc));
break;
case ')':
switch (stk.size()) {
case 0:
- throw SyntaxError("Unexpected ')'");
+ throw Error("unexpected `)'", loc);
case 1:
PUSH(stk, tok);
return stk.top();
@@ -104,11 +120,11 @@ readExpression(std::istream& in)
}
}
switch (stk.size()) {
- case 0: return tok;
+ case 0: return SExp(loc, tok);
case 1: return stk.top();
- default: throw SyntaxError("Missing ')'");
+ default: throw Error("missing `)'", loc);
}
- return SExp();
+ return SExp(loc);
}
@@ -139,7 +155,7 @@ struct ASTLiteral : public AST {
const ASTLiteral<VT>* r = dynamic_cast<const ASTLiteral<VT>*>(&rhs);
return r && val == r->val;
}
- string str() const { ostringstream s; s << val; return s.str(); }
+ string str() const { return (format("%1%") % val).str(); }
void constrain(TEnv& tenv) const;
Value* compile(CEnv& cenv);
const VT val;
@@ -193,7 +209,7 @@ struct ASTTuple : public AST, public vector<AST*> {
bool isForm(const string& f) { return !empty() && at(0)->str() == f; }
bool contains(AST* child) const;
void constrain(TEnv& tenv) const;
- Value* compile(CEnv& cenv) { throw SyntaxError("Tuple compiled"); }
+ Value* compile(CEnv& cenv) { throw Error("tuple compiled"); }
};
/// Type Expression, e.g. "(Int)" or "(Fn ((Int)) (Float))"
@@ -205,7 +221,7 @@ struct AType : public ASTTuple {
}
string str() const {
if (var) {
- ostringstream s; s << "?" << id; return s.str();
+ return (format("?%1%") % id).str();
} else {
return ASTTuple::str();
}
@@ -267,7 +283,7 @@ struct ASTClosure : public ASTTuple {
ASTClosure(ASTTuple* p, AST* b, const string& n="")
: ASTTuple(0, p, b), prot(p), func(0), name(n) {}
bool operator==(const AST& rhs) const { return this == &rhs; }
- string str() const { ostringstream s; s << this; return s.str(); }
+ string str() const { return (format("%1%") % this).str(); }
void constrain(TEnv& tenv) const;
void lift(CEnv& cenv);
Value* compile(CEnv& cenv);
@@ -279,15 +295,16 @@ private:
/// Function call/application, e.g. "(func arg1 arg2)"
struct ASTCall : public ASTTuple {
- ASTCall(const ASTTuple& t) : ASTTuple(t) {}
+ ASTCall(const SExp& e, const ASTTuple& t) : ASTTuple(t), exp(e) {}
void constrain(TEnv& tenv) const;
void lift(CEnv& cenv);
Value* compile(CEnv& cenv);
+ const SExp& exp;
};
/// Definition special form, e.g. "(def x 2)"
struct ASTDefinition : public ASTCall {
- ASTDefinition(const ASTTuple& t) : ASTCall(t) {}
+ ASTDefinition(const SExp& e, const ASTTuple& t) : ASTCall(e, t) {}
void constrain(TEnv& tenv) const;
void lift(CEnv& cenv);
Value* compile(CEnv& cenv);
@@ -295,14 +312,14 @@ struct ASTDefinition : public ASTCall {
/// Conditional special form, e.g. "(if cond thenexp elseexp)"
struct ASTIf : public ASTCall {
- ASTIf(const ASTTuple& t) : ASTCall(t) {}
+ ASTIf(const SExp& e, const ASTTuple& t) : ASTCall(e, t) {}
void constrain(TEnv& tenv) const;
Value* compile(CEnv& cenv);
};
/// Primitive (builtin arithmetic function), e.g. "(+ 2 3)"
struct ASTPrimitive : public ASTCall {
- ASTPrimitive(const ASTTuple& t, int o, int a=0) : ASTCall(t), op(o), arg(a) {}
+ ASTPrimitive(const SExp& e, const ASTTuple& t, int o, int a=0) : ASTCall(e, t), op(o), arg(a) {}
void constrain(TEnv& tenv) const;
Value* compile(CEnv& cenv);
unsigned op;
@@ -311,12 +328,11 @@ struct ASTPrimitive : public ASTCall {
/// Cons special form, e.g. "(cons 1 2)"
struct ASTConsCall : public ASTCall {
- ASTConsCall(const ASTTuple& t) : ASTCall(t), val(NULL) {}
+ ASTConsCall(const SExp& e, const ASTTuple& t) : ASTCall(e, t) {}
AType* functionType(CEnv& cenv);
void constrain(TEnv& tenv) const;
void lift(CEnv& cenv);
Value* compile(CEnv& cenv);
- Value* val;
static Funcs funcs;
};
@@ -324,14 +340,14 @@ Funcs ASTConsCall::funcs;
/// Car special form, e.g. "(car p)"
struct ASTCarCall : public ASTCall {
- ASTCarCall(const ASTTuple& t) : ASTCall(t) {}
+ ASTCarCall(const SExp& e, const ASTTuple& t) : ASTCall(e, t) {}
void constrain(TEnv& tenv) const;
Value* compile(CEnv& cenv);
};
/// Cdr special form, e.g. "(cdr p)"
struct ASTCdrCall : public ASTCall {
- ASTCdrCall(const ASTTuple& t) : ASTCall(t) {}
+ ASTCdrCall(const SExp& e, const ASTTuple& t) : ASTCall(e, t) {}
void constrain(TEnv& tenv) const;
Value* compile(CEnv& cenv);
};
@@ -348,7 +364,7 @@ typedef Op UD; // User Data argument for parse functions
// Parse Time Environment (symbol table)
struct PEnv : private map<const string, ASTSymbol*> {
- typedef AST* (*PF)(PEnv&, const SExp::List&, UD); // Parse Function
+ typedef AST* (*PF)(PEnv&, const SExp&, UD); // Parse Function
struct Parser { Parser(PF f, UD d) : pf(f), ud(d) {} PF pf; UD ud; };
map<string, Parser> parsers;
void reg(const string& s, const Parser& p) {
@@ -383,13 +399,13 @@ static AST*
parseExpression(PEnv& penv, const SExp& exp)
{
if (exp.type == SExp::LIST) {
- if (exp.list.empty()) throw SyntaxError("Call to empty list");
+ if (exp.list.empty()) throw Error("call to empty list", exp.loc);
if (exp.list.front().type == SExp::ATOM) {
const PEnv::Parser* handler = penv.parser(exp.list.front().atom);
if (handler) // Dispatch to parse function
- return handler->pf(penv, exp.list, handler->ud);
+ return handler->pf(penv, exp, handler->ud);
}
- return new ASTCall(pmap(penv, exp.list)); // Parse as regular call
+ return new ASTCall(exp, pmap(penv, exp.list)); // Parse as regular call
} else if (isdigit(exp.atom[0])) {
if (exp.atom.find('.') == string::npos)
return new ASTLiteral<int32_t>(strtol(exp.atom.c_str(), NULL, 10));
@@ -402,37 +418,37 @@ parseExpression(PEnv& penv, const SExp& exp)
// Special forms
static AST*
-parseIf(PEnv& penv, const SExp::List& c, UD)
- { return new ASTIf(pmap(penv, c)); }
+parseIf(PEnv& penv, const SExp& exp, UD)
+ { return new ASTIf(exp, pmap(penv, exp.list)); }
static AST*
-parseDef(PEnv& penv, const SExp::List& c, UD)
- { return new ASTDefinition(pmap(penv, c)); }
+parseDef(PEnv& penv, const SExp& exp, UD)
+ { return new ASTDefinition(exp, pmap(penv, exp.list)); }
static AST*
-parsePrim(PEnv& penv, const SExp::List& c, UD data)
- { return new ASTPrimitive(pmap(penv, c), data.op, data.arg); }
+parsePrim(PEnv& penv, const SExp& exp, UD data)
+ { return new ASTPrimitive(exp, pmap(penv, exp.list), data.op, data.arg); }
static AST*
-parseFn(PEnv& penv, const SExp::List& c, UD)
+parseFn(PEnv& penv, const SExp& exp, UD)
{
- SExp::List::const_iterator a = c.begin(); ++a;
+ SExp::List::const_iterator a = exp.list.begin(); ++a;
return new ASTClosure(
new ASTTuple(pmap(penv, (*a++).list)),
parseExpression(penv, *a++));
}
static AST*
-parseCons(PEnv& penv, const SExp::List& c, UD)
- { return new ASTConsCall(pmap(penv, c)); }
+parseCons(PEnv& penv, const SExp& exp, UD)
+ { return new ASTConsCall(exp, pmap(penv, exp.list)); }
static AST*
-parseCar(PEnv& penv, const SExp::List& c, UD)
- { return new ASTCarCall(pmap(penv, c)); }
+parseCar(PEnv& penv, const SExp& exp, UD)
+ { return new ASTCarCall(exp, pmap(penv, exp.list)); }
static AST*
-parseCdr(PEnv& penv, const SExp::List& c, UD)
- { return new ASTCdrCall(pmap(penv, c)); }
+parseCdr(PEnv& penv, const SExp& exp, UD)
+ { return new ASTCdrCall(exp, pmap(penv, exp.list)); }
/***************************************************************************
@@ -447,7 +463,7 @@ struct Env : public list< map<K,V> > {
const V& def(const K& k, const V& v) {
typename Frame::iterator existing = this->front().find(k);
if (existing != this->front().end() && existing->second != v)
- throw SyntaxError("Redefinition");
+ throw Error("redefinition");
return (this->front()[k] = v);
}
V* ref(const K& name) {
@@ -464,8 +480,6 @@ struct Env : public list< map<K,V> > {
* Typing *
***************************************************************************/
-struct TypeError : public Error { TypeError (const char* m) : Error(m) {} };
-
struct TSubst : public map<AType*, AType*> {
TSubst(AType* s=0, AType* t=0) { if (s && t) insert(make_pair(s, t)); }
};
@@ -482,7 +496,7 @@ struct TEnv {
}
AType* named(const string& name) const {
Types::const_iterator i = namedTypes.find(penv.sym(name));
- if (i == namedTypes.end()) throw TypeError("Unknown named type");
+ if (i == namedTypes.end()) throw Error("Unknown named type");
return i->second;
}
void name(const string& name, const Type* type) {
@@ -539,9 +553,9 @@ void
ASTDefinition::constrain(TEnv& tenv) const
{
if (size() != 3)
- throw SyntaxError("\"def\" not passed 2 arguments");
+ throw Error("`def' requires exactly 2 arguments", exp.loc);
if (!dynamic_cast<const ASTSymbol*>(at(1)))
- throw SyntaxError("\"def\" name is not a symbol");
+ throw Error("`def' name is not a symbol", exp.loc);
FOREACH(const_iterator, p, *this)
(*p)->constrain(tenv);
AType* tvar = tenv.type(this);
@@ -566,16 +580,18 @@ ASTPrimitive::constrain(TEnv& tenv) const
FOREACH(const_iterator, p, *this)
(*p)->constrain(tenv);
if (OP_IS_A(op, Instruction::BinaryOps)) {
- if (size() <= 1) throw SyntaxError("Primitive call with 0 args");
+ if (size() <= 2) throw Error((format("`%1%' requires at least 2 arguments")
+ % at(0)->str()).str(), exp.loc);
AType* tvar = tenv.type(this);
for (size_t i = 1; i < size(); ++i)
tenv.constrain(at(i), tvar);
} else if (op == Instruction::ICmp) {
- if (size() != 3) throw SyntaxError("Comparison call with != 2 args");
+ if (size() != 3) throw Error((format("`%1%' requires exactly 2 arguments")
+ % at(0)->str()).str(), exp.loc);
tenv.constrain(at(1), tenv.type(at(2)));
tenv.constrain(this, tenv.named("Bool"));
} else {
- throw TypeError("Unknown primitive");
+ throw Error((format("unknown primitive `%1%'") % at(0)->str()).str(), exp.loc);
}
}
@@ -687,7 +703,7 @@ TEnv::unify(const Constraints& constraints) // TAPL 22.4
cp.push_back(make_pair(s2, t2));
return unify(cp);
} else {
- throw TypeError("Type unification failed");
+ throw Error("Type unification failed");
}
}
@@ -705,8 +721,6 @@ TEnv::apply(const TSubst& substs)
* Code Generation *
***************************************************************************/
-struct CompileError : public Error { CompileError(const char* m) : Error(m) {} };
-
class PEnv;
/// Compile-Time Environment
@@ -721,9 +735,7 @@ struct CEnv {
opt.add(createGVNPass()); // Eliminate Common Subexpressions
opt.add(createCFGSimplificationPass()); // Simplify control flow
}
- string gensym(const char* base="_") {
- ostringstream s; s << base << symID++; return s.str();
- }
+ string gensym(const char* s="_") { return (format("%1%%2%") % s % symID++).str(); }
void push() { code.push_front(); vals.push_front(); }
void pop() { code.pop_front(); vals.pop_front(); }
Value* compile(AST* obj) {
@@ -769,17 +781,17 @@ 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 CompileError("Parameter is untyped");
+ if (!at->type() || at->var) throw Error("function parameter is untyped");
cprot.push_back(at->type());
}
- if (!retT) throw CompileError("Return is untyped");
+ if (!retT) throw Error("function return is untyped");
FunctionType* fT = FunctionType::get(retT, cprot, false);
Function* f = Function::Create(fT, linkage, name, cenv.module);
if (f->getName() != name) {
f->eraseFromParent();
- throw CompileError("Function redefined");
+ throw Error("function redefined");
}
// Set argument names in generated code
@@ -798,7 +810,7 @@ Value*
ASTSymbol::compile(CEnv& cenv)
{
AST** c = cenv.code.ref(this);
- if (!c) throw SyntaxError((string("Undefined symbol: ") + cppstr).c_str());
+ if (!c) throw Error((string("Undefined symbol: ") + cppstr).c_str());
return cenv.compile(*c);
}
@@ -806,10 +818,10 @@ void
ASTClosure::lift(CEnv& cenv)
{
if (cenv.tenv.type(at(2))->var)
- throw CompileError("Closure with untyped body lifted");
+ throw Error("Closure with untyped body lifted");
for (size_t i = 0; i < prot->size(); ++i)
if (cenv.tenv.type(prot->at(i))->var)
- throw CompileError("Closure with untyped parameter lifted");
+ throw Error("Closure with untyped parameter lifted");
assert(!func);
cenv.push();
@@ -833,7 +845,7 @@ ASTClosure::lift(CEnv& cenv)
cenv.builder.CreateRet(retVal); // Finish function
cenv.optimise(*f);
func = f;
- } catch (exception e) {
+ } catch (Error& e) {
f->eraseFromParent(); // Error reading body, remove function
throw e;
}
@@ -866,8 +878,10 @@ ASTCall::lift(CEnv& cenv)
// Extend environment with bound and typed parameters
cenv.push();
- if (c->prot->size() != size() - 1)
- throw CompileError("Call to closure with mismatched arguments");
+ if (c->prot->size() < size() - 1)
+ throw Error((format("too many arguments to function `%1%'") % at(0)->str()).str(), exp.loc);
+ if (c->prot->size() > size() - 1)
+ throw Error((format("too few arguments to function `%1%'") % at(0)->str()).str(), exp.loc);
for (size_t i = 1; i < size(); ++i)
cenv.code.def(c->prot->at(i-1), at(i));
@@ -887,7 +901,7 @@ ASTCall::compile(CEnv& cenv)
assert(c);
Function* f = dynamic_cast<Function*>(cenv.compile(c));
- if (!f) throw CompileError("Callee failed to compile");
+ if (!f) throw Error("callee failed to compile", exp.loc);
vector<Value*> params(size() - 1);
for (size_t i = 1; i < size(); ++i)
@@ -899,6 +913,8 @@ ASTCall::compile(CEnv& cenv)
void
ASTDefinition::lift(CEnv& cenv)
{
+ if (cenv.code.ref((ASTSymbol*)at(1)))
+ throw Error(string("`") + at(1)->str() + "' redefined", exp.loc);
cenv.code.def((ASTSymbol*)at(1), at(2)); // Define first for recursion
at(2)->lift(cenv);
}
@@ -960,7 +976,6 @@ ASTIf::compile(CEnv& cenv)
Value*
ASTPrimitive::compile(CEnv& cenv)
{
- if (size() < 3) throw SyntaxError("Too few arguments");
Value* a = cenv.compile(at(1));
Value* b = cenv.compile(at(2));
@@ -985,12 +1000,12 @@ ASTPrimitive::compile(CEnv& cenv)
case CmpInst::ICMP_SGE: arg = CmpInst::FCMP_OGE; break;
case CmpInst::ICMP_SLT: arg = CmpInst::FCMP_OLT; break;
case CmpInst::ICMP_SLE: arg = CmpInst::FCMP_OLE; break;
- default: throw CompileError("Unknown primitive");
+ default: throw Error("Unknown primitive", exp.loc);
}
return cenv.builder.CreateFCmp((CmpInst::Predicate)arg, a, b);
}
}
- throw CompileError("Unknown primitive");
+ throw Error("Unknown primitive", exp.loc);
}
AType*
@@ -1052,15 +1067,11 @@ ASTConsCall::lift(CEnv& cenv)
Value*
ASTConsCall::compile(CEnv& cenv)
{
- if (val != NULL)
- return val;
-
vector<Value*> params(size() - 1);
for (size_t i = 1; i < size(); ++i)
params[i-1] = cenv.compile(at(i));
- val = cenv.builder.CreateCall(funcs.find(functionType(cenv)), params.begin(), params.end());
- return val;
+ return cenv.builder.CreateCall(funcs.find(functionType(cenv)), params.begin(), params.end());
}
Value*
@@ -1104,31 +1115,33 @@ call(AType* retT, void* fp)
}
int
-eval(CEnv& cenv, ExecutionEngine* engine, istream& is)
+eval(CEnv& cenv, ExecutionEngine* engine, const string& name, istream& is)
{
AST* result = NULL;
AType* resultType = NULL;
list< pair<SExp, AST*> > exprs;
- while (true) {
- SExp exp = readExpression(is);
- if (exp.type == SExp::LIST && exp.list.empty())
- break;
+ Cursor cursor(name);
+ try {
+ while (true) {
+ SExp exp = readExpression(cursor, is);
+ if (exp.type == SExp::LIST && exp.list.empty())
+ break;
- try {
result = parseExpression(cenv.penv, exp); // Parse input
result->constrain(cenv.tenv); // Constrain types
cenv.tenv.solve(); // Solve and apply type constraints
resultType = cenv.tenv.type(result);
- if (!resultType) throw TypeError("Call to untyped body");
result->lift(cenv); // Lift functions
exprs.push_back(make_pair(exp, result));
- } catch (Error e) {
- std::cerr << "Error: " << e.what() << endl;
}
+
+ if (!resultType || resultType->var) throw Error("body is undefined/untyped", cursor);
+
+ } catch (Error& e) {
+ std::cerr << e.what() << endl;
+ return 1;
}
- if (resultType->var) throw TypeError("Call to variable typed body");
-
// Create function for top-level of program
ASTTuple prot;
const Type* ctype = resultType->type();
@@ -1157,7 +1170,8 @@ repl(CEnv& cenv, ExecutionEngine* engine)
while (1) {
std::cout << "() ";
std::cout.flush();
- SExp exp = readExpression(std::cin);
+ Cursor cursor("(stdin)");
+ SExp exp = readExpression(cursor, std::cin);
if (exp.type == SExp::LIST && exp.list.empty())
break;
@@ -1167,8 +1181,8 @@ repl(CEnv& cenv, ExecutionEngine* engine)
cenv.tenv.solve(); // Solve and apply type constraints
AType* bodyT = cenv.tenv.type(body);
- if (!bodyT) throw TypeError("REPL call to untyped body");
- if (bodyT->var) throw TypeError("REPL call to variable typed body");
+ if (!bodyT) throw Error("call to untyped body", cursor);
+ if (bodyT->var) throw Error("call to variable typed body", cursor);
body->lift(cenv);
@@ -1182,7 +1196,7 @@ repl(CEnv& cenv, ExecutionEngine* engine)
Value* retVal = cenv.compile(body);
cenv.builder.CreateRet(retVal); // Finish function
cenv.optimise(*f);
- } catch (SyntaxError e) {
+ } catch (Error& e) {
f->eraseFromParent(); // Error reading body, remove function
throw e;
}
@@ -1193,8 +1207,8 @@ repl(CEnv& cenv, ExecutionEngine* engine)
}
std::cout << " : " << cenv.tenv.type(body)->str() << endl;
- } catch (Error e) {
- std::cerr << "Error: " << e.what() << endl;
+ } catch (Error& e) {
+ std::cerr << e.what() << endl;
}
}
@@ -1245,10 +1259,10 @@ main(int argc, char** argv)
int ret;
if (argc > 2 && !strncmp(argv[1], "-e", 3)) {
std::istringstream is(argv[2]);
- ret = eval(cenv, engine, is);
+ ret = eval(cenv, engine, "(command line)", is);
} else if (argc > 2 && !strncmp(argv[1], "-f", 3)) {
std::ifstream is(argv[2]);
- ret = eval(cenv, engine, is);
+ ret = eval(cenv, engine, argv[2], is);
is.close();
} else {
ret = repl(cenv, engine);