Extreme error reporting capabilities update and bug fixes

This commit is contained in:
Jason Turner
2012-06-25 06:31:34 -06:00
parent 5a76d98692
commit a8ea5f151d
5 changed files with 373 additions and 50 deletions

View File

@@ -426,6 +426,7 @@ namespace chaiscript
m->add(fun(&Type_Info::is_void), "is_type_void");
m->add(fun(&Type_Info::is_undef), "is_type_undef");
m->add(fun(&Type_Info::is_pointer), "is_type_pointer");
m->add(fun(&Type_Info::is_arithmetic), "is_type_arithmetic");
m->add(fun(&Type_Info::name), "cpp_name");
m->add(fun(&Type_Info::bare_name), "cpp_bare_name");
m->add(fun(&Type_Info::bare_equal), "bare_equal");

View File

@@ -25,7 +25,6 @@ namespace chaiscript
typedef boost::shared_ptr<struct AST_Node> AST_NodePtr;
namespace dispatch
{
/**
@@ -591,14 +590,16 @@ namespace chaiscript
class dispatch_error : public std::runtime_error
{
public:
dispatch_error(const std::vector<Boxed_Value> &t_bvs)
: std::runtime_error("Error with function dispatch"), parameters(t_bvs)
dispatch_error(const std::vector<Boxed_Value> &t_parameters,
const std::vector<Const_Proxy_Function> &t_functions)
: std::runtime_error("Error with function dispatch"), parameters(t_parameters), functions(t_functions)
{
}
virtual ~dispatch_error() throw() {}
std::vector<Boxed_Value> parameters;
std::vector<Const_Proxy_Function> functions;
};
}
@@ -611,9 +612,10 @@ namespace chaiscript
* function is found or throw dispatch_error if no matching function is found
*/
template<typename InItr>
Boxed_Value dispatch(InItr begin, InItr end,
Boxed_Value dispatch(InItr begin, const InItr &end,
const std::vector<Boxed_Value> &plist)
{
InItr orig(begin);
while (begin != end)
{
try {
@@ -632,7 +634,7 @@ namespace chaiscript
++begin;
}
throw exception::dispatch_error(plist);
throw exception::dispatch_error(plist, std::vector<Const_Proxy_Function>(orig, end));
}
/**

View File

@@ -69,18 +69,23 @@ namespace chaiscript
File_Position start_position;
File_Position end_position;
std::string filename;
std::string detail;
std::vector<AST_NodePtr> call_stack;
eval_error(const std::string &t_why, const File_Position &t_where, const std::string &t_fname,
const std::vector<Boxed_Value> &t_parameters, const chaiscript::detail::Dispatch_Engine &t_ss) :
std::runtime_error(format(t_why, t_where, t_fname, t_parameters, t_ss)),
reason(t_why), start_position(t_where), end_position(t_where), filename(t_fname)
const std::vector<Boxed_Value> &t_parameters, const std::vector<chaiscript::Const_Proxy_Function> &t_functions,
bool t_dot_notation,
const chaiscript::detail::Dispatch_Engine &t_ss) :
std::runtime_error(format(t_why, t_where, t_fname, t_parameters, t_dot_notation, t_ss)),
reason(t_why), start_position(t_where), end_position(t_where), filename(t_fname), detail(format_detail(t_functions, t_dot_notation, t_ss))
{}
eval_error(const std::string &t_why,
const std::vector<Boxed_Value> &t_parameters, const chaiscript::detail::Dispatch_Engine &t_ss) :
std::runtime_error(format(t_why, t_parameters, t_ss)),
reason(t_why)
const std::vector<Boxed_Value> &t_parameters, const std::vector<chaiscript::Const_Proxy_Function> &t_functions,
bool t_dot_notation,
const chaiscript::detail::Dispatch_Engine &t_ss) :
std::runtime_error(format(t_why, t_parameters, t_dot_notation, t_ss)),
reason(t_why), detail(format_detail(t_functions, t_dot_notation, t_ss))
{}
@@ -94,19 +99,181 @@ namespace chaiscript
reason(t_why)
{}
std::string pretty_print() const
{
std::ostringstream ss;
ss << what();
if (call_stack.size() > 0) {
ss << "during evaluation at (" << fname(call_stack[0]) << " " << startpos(call_stack[0]) << ")" << std::endl;
ss << std::endl << detail << std::endl;
ss << " " << fname(call_stack[0]) << " (" << startpos(call_stack[0]) << ") '" << pretty(call_stack[0]) << "'";
for (size_t j = 1; j < call_stack.size(); ++j) {
if (id(call_stack[j]) != chaiscript::AST_Node_Type::Block
&& id(call_stack[j]) != chaiscript::AST_Node_Type::File)
{
ss << std::endl;
ss << " from " << fname(call_stack[j]) << " (" << startpos(call_stack[j]) << ") '" << pretty(call_stack[j]) << "'";
}
}
}
ss << std::endl;
return ss.str();
}
virtual ~eval_error() throw() {}
private:
template<typename T>
static int id(const T& t)
{
return t->identifier;
}
template<typename T>
static std::string pretty(const T& t)
{
return t->pretty_print();
}
template<typename T>
static std::string fname(const T& t)
{
return *t->filename;
}
template<typename T>
static std::string startpos(const T& t)
{
std::ostringstream oss;
oss << t->start.line << ", " << t->start.column;
return oss.str();
}
static std::string format_why(const std::string &t_why)
{
return "Error: \"" + t_why + "\"";
}
static std::string format_parameters(const std::vector<Boxed_Value> &t_parameters,
static std::string format_types(const Const_Proxy_Function &t_func,
bool t_dot_notation,
const chaiscript::detail::Dispatch_Engine &t_ss)
{
int arity = t_func->get_arity();
std::vector<Type_Info> types = t_func->get_param_types();
std::string retval;
if (arity == -1)
{
retval = "(...)";
if (t_dot_notation)
{
retval = "(Object)." + retval;
}
} else if (types.size() <= 1) {
retval = "()";
} else {
std::stringstream ss;
ss << "(";
std::string paramstr;
for (size_t index = 1;
index != types.size();
++index)
{
paramstr += (types[index].is_const()?"const ":"");
paramstr += t_ss.get_type_name(types[index]);
if (index == 1 && t_dot_notation)
{
paramstr += ").(";
if (types.size() == 2)
{
paramstr += ", ";
}
} else {
paramstr += ", ";
}
}
ss << paramstr.substr(0, paramstr.size() - 2);
ss << ")";
retval = ss.str();
}
boost::shared_ptr<const dispatch::Dynamic_Proxy_Function> dynfun
= boost::dynamic_pointer_cast<const dispatch::Dynamic_Proxy_Function>(t_func);
if (dynfun)
{
Proxy_Function f = dynfun->get_guard();
if (f)
{
boost::shared_ptr<const dispatch::Dynamic_Proxy_Function> dynfunguard
= boost::dynamic_pointer_cast<const dispatch::Dynamic_Proxy_Function>(f);
if (dynfunguard)
{
retval += " : " + format_guard(dynfunguard->get_parse_tree());
}
}
retval += "\n Defined at " + format_location(dynfun->get_parse_tree());
}
return retval;
}
template<typename T>
static std::string format_guard(const T &t)
{
return t->pretty_print();
}
template<typename T>
static std::string format_location(const T &t)
{
std::ostringstream oss;
oss << "(" << *t->filename << " " << t->start.line << ", " << t->start.column << ")";
return oss.str();
}
static std::string format_detail(const std::vector<chaiscript::Const_Proxy_Function> &t_functions,
bool t_dot_notation,
const chaiscript::detail::Dispatch_Engine &t_ss)
{
std::stringstream ss;
ss << "With parameters: (";
if (t_functions.size() == 1)
{
ss << " Expected: " << format_types(t_functions[0], t_dot_notation, t_ss) << std::endl;
} else {
ss << " " << t_functions.size() << " overloads available:" << std::endl;
for (std::vector<chaiscript::Const_Proxy_Function>::const_iterator itr = t_functions.begin();
itr != t_functions.end();
++itr)
{
ss << " " << format_types((*itr), t_dot_notation, t_ss) << std::endl;
}
}
return ss.str();
}
static std::string format_parameters(const std::vector<Boxed_Value> &t_parameters,
bool t_dot_notation,
const chaiscript::detail::Dispatch_Engine &t_ss)
{
std::stringstream ss;
ss << "(";
if (!t_parameters.empty())
{
@@ -118,8 +285,18 @@ namespace chaiscript
{
paramstr += (itr->is_const()?"const ":"");
paramstr += t_ss.type_name(*itr);
if (itr == t_parameters.begin() && t_dot_notation)
{
paramstr += ").(";
if (t_parameters.size() == 1)
{
paramstr += ", ";
}
} else {
paramstr += ", ";
}
}
ss << paramstr.substr(0, paramstr.size() - 2);
}
@@ -150,14 +327,14 @@ namespace chaiscript
}
static std::string format(const std::string &t_why, const File_Position &t_where, const std::string &t_fname,
const std::vector<Boxed_Value> &t_parameters, const chaiscript::detail::Dispatch_Engine &t_ss)
const std::vector<Boxed_Value> &t_parameters, bool t_dot_notation, const chaiscript::detail::Dispatch_Engine &t_ss)
{
std::stringstream ss;
ss << format_why(t_why);
ss << " ";
ss << format_parameters(t_parameters, t_ss);
ss << "With parameters: " << format_parameters(t_parameters, t_dot_notation, t_ss);
ss << " ";
ss << format_filename(t_fname);
@@ -169,14 +346,16 @@ namespace chaiscript
}
static std::string format(const std::string &t_why,
const std::vector<Boxed_Value> &t_parameters, const chaiscript::detail::Dispatch_Engine &t_ss)
const std::vector<Boxed_Value> &t_parameters,
bool t_dot_notation,
const chaiscript::detail::Dispatch_Engine &t_ss)
{
std::stringstream ss;
ss << format_why(t_why);
ss << " ";
ss << format_parameters(t_parameters, t_ss);
ss << "With parameters: " << format_parameters(t_parameters, t_dot_notation, t_ss);
ss << " ";
return ss.str();
@@ -222,6 +401,19 @@ namespace chaiscript
std::vector<AST_NodePtr> children;
AST_NodePtr annotation;
virtual std::string pretty_print() const
{
std::ostringstream oss;
oss << text;
for (unsigned int j = 0; j < this->children.size(); ++j) {
oss << this->children[j]->pretty_print();
}
return oss.str();
}
/**
* Prints the contents of an AST node, including its children, recursively
*/

View File

@@ -49,6 +49,16 @@ namespace chaiscript
this->children[2]->eval(t_ss));
}
virtual std::string pretty_print() const
{
if (children.size() == 3)
{
return "(" + this->children[0]->pretty_print() + " " + this->children[1]->text + " " + this->children[2]->pretty_print() + ")";
} else {
return "(" + this->children[0]->pretty_print() + " " + text + " " + this->children[1]->pretty_print() + ")";
}
}
protected:
Boxed_Value do_oper(chaiscript::detail::Dispatch_Engine &t_ss,
Operators::Opers t_oper, const std::string &t_oper_string, const Boxed_Value &t_lhs, const Boxed_Value &t_rhs)
@@ -75,7 +85,7 @@ namespace chaiscript
}
}
catch(const exception::dispatch_error &e){
throw exception::eval_error("Can not find appropriate '" + t_oper_string + "' operator.", e.parameters, t_ss);
throw exception::eval_error("Can not find appropriate '" + t_oper_string + "' operator.", e.parameters, e.functions, false, t_ss);
}
}
};
@@ -181,6 +191,11 @@ namespace chaiscript
Eol_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Eol, const boost::shared_ptr<std::string> &t_fname=boost::shared_ptr<std::string>(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) :
AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { }
virtual ~Eol_AST_Node() {}
virtual std::string pretty_print() const
{
return "\n";
}
};
struct Fun_Call_AST_Node : public AST_Node {
@@ -208,13 +223,45 @@ namespace chaiscript
return retval;
}
catch(const exception::dispatch_error &e){
throw exception::eval_error(std::string(e.what()) + " with function '" + this->children[0]->text + "'", e.parameters, t_ss);
throw exception::eval_error(std::string(e.what()) + " with function '" + this->children[0]->text + "'", e.parameters, e.functions, false, t_ss);
}
catch(const exception::bad_boxed_cast &){
try {
Const_Proxy_Function f = boxed_cast<const Const_Proxy_Function &>(fn);
// handle the case where there is only 1 function to try to call and dispatch fails on it
std::vector<Const_Proxy_Function> funcs;
funcs.push_back(f);
throw exception::eval_error("Error calling function '" + this->children[0]->text + "'", plb.objects, funcs, false, t_ss);
} catch (const exception::bad_boxed_cast &) {
throw exception::eval_error("'" + this->children[0]->text + "' is not a function.");
}
}
catch(const exception::arity_error &e){
throw exception::eval_error(std::string(e.what()) + " with function '" + this->children[0]->text + "'");
}
catch(detail::Return_Value &rv) {
return rv.retval;
}
}
virtual std::string pretty_print() const
{
std::ostringstream oss;
for (unsigned int j = 0; j < this->children.size(); ++j) {
oss << this->children[j]->pretty_print();
if (j == 0)
{
oss << "(";
}
}
oss << ")";
return oss.str();
}
};
struct Inplace_Fun_Call_AST_Node : public AST_Node {
@@ -231,18 +278,50 @@ namespace chaiscript
}
}
Boxed_Value bv;
Const_Proxy_Function fn;
try {
return (*boxed_cast<const Const_Proxy_Function &>(this->children[0]->eval(t_ss)))(plb);
bv = this->children[0]->eval(t_ss);
try {
fn = boxed_cast<const Const_Proxy_Function &>(bv);
} catch (const exception::bad_boxed_cast &) {
throw exception::eval_error("'" + this->children[0]->text + "' is not a function.");
}
return (*fn)(plb);
}
catch(const exception::dispatch_error &e){
throw exception::eval_error(std::string(e.what()) + " with function '" + this->children[0]->text + "'", e.parameters, t_ss);
throw exception::eval_error(std::string(e.what()) + " with function '" + this->children[0]->text + "'", e.parameters, e.functions, false, t_ss);
}
catch(const exception::bad_boxed_cast &){
// handle the case where there is only 1 function to try to call and dispatch fails on it
std::vector<Const_Proxy_Function> funcs;
funcs.push_back(fn);
throw exception::eval_error("Error calling function '" + this->children[0]->text + "'", plb.objects, funcs, false, t_ss);
}
catch(const exception::arity_error &e){
throw exception::eval_error(std::string(e.what()) + " with function '" + this->children[0]->text + "'");
}
catch(detail::Return_Value &rv) {
return rv.retval;
}
catch(...) {
throw;
}
virtual std::string pretty_print() const
{
std::ostringstream oss;
for (unsigned int j = 0; j < this->children.size(); ++j) {
oss << this->children[j]->pretty_print();
if (j == 0)
{
oss << "(";
}
}
oss << ")";
return oss.str();
}
};
@@ -252,6 +331,21 @@ namespace chaiscript
Arg_List_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Arg_List, const boost::shared_ptr<std::string> &t_fname=boost::shared_ptr<std::string>(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) :
AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { }
virtual ~Arg_List_AST_Node() {}
virtual std::string pretty_print() const
{
std::ostringstream oss;
for (unsigned int j = 0; j < this->children.size(); ++j) {
if (j != 0)
{
oss << ", ";
}
oss << this->children[j]->pretty_print();
}
return oss.str();
}
};
struct Variable_AST_Node : public AST_Node {
@@ -295,11 +389,11 @@ namespace chaiscript
retval = t_ss.call_function(this->children[1]->text, lhs, retval);
}
catch(const exception::dispatch_error &e){
throw exception::eval_error("Unable to find appropriate'" + this->children[1]->text + "' operator.", e.parameters, t_ss);
throw exception::eval_error("Unable to find appropriate'" + this->children[1]->text + "' operator.", e.parameters, e.functions, false, t_ss);
}
}
catch(const exception::dispatch_error &e){
throw exception::eval_error("Missing clone or copy constructor for right hand side of equation", e.parameters, t_ss);
throw exception::eval_error("Missing clone or copy constructor for right hand side of equation", e.parameters, e.functions, false, t_ss);
}
}
else if (this->children[1]->text == ":=") {
@@ -313,7 +407,7 @@ namespace chaiscript
try {
retval = t_ss.call_function(this->children[1]->text, lhs, retval);
} catch(const exception::dispatch_error &e){
throw exception::eval_error("Unable to find appropriate'" + this->children[1]->text + "' operator.", e.parameters, t_ss);
throw exception::eval_error("Unable to find appropriate'" + this->children[1]->text + "' operator.", e.parameters, e.functions, false, t_ss);
}
}
}
@@ -338,6 +432,11 @@ namespace chaiscript
return t_ss.get_object(this->children[0]->text);
}
virtual std::string pretty_print() const
{
return "var " + this->children[0]->text;
}
};
struct Comparison_AST_Node : public Binary_Operator_AST_Node {
@@ -349,7 +448,7 @@ namespace chaiscript
struct Addition_AST_Node : public Binary_Operator_AST_Node {
public:
Addition_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Addition,
Addition_AST_Node(const std::string &t_ast_node_text = "+", int t_id = AST_Node_Type::Addition,
const boost::shared_ptr<std::string> &t_fname=boost::shared_ptr<std::string>(),
int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) :
Binary_Operator_AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { }
@@ -361,7 +460,7 @@ namespace chaiscript
struct Subtraction_AST_Node : public Binary_Operator_AST_Node {
public:
Subtraction_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Subtraction,
Subtraction_AST_Node(const std::string &t_ast_node_text = "-", int t_id = AST_Node_Type::Subtraction,
const boost::shared_ptr<std::string> &t_fname=boost::shared_ptr<std::string>(), int t_start_line = 0,
int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) :
Binary_Operator_AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { }
@@ -373,7 +472,7 @@ namespace chaiscript
struct Multiplication_AST_Node : public Binary_Operator_AST_Node {
public:
Multiplication_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Multiplication,
Multiplication_AST_Node(const std::string &t_ast_node_text = "*", int t_id = AST_Node_Type::Multiplication,
const boost::shared_ptr<std::string> &t_fname=boost::shared_ptr<std::string>(), int t_start_line = 0,
int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) :
Binary_Operator_AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { }
@@ -385,7 +484,7 @@ namespace chaiscript
struct Division_AST_Node : public Binary_Operator_AST_Node {
public:
Division_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Division,
Division_AST_Node(const std::string &t_ast_node_text = "/", int t_id = AST_Node_Type::Division,
const boost::shared_ptr<std::string> &t_fname=boost::shared_ptr<std::string>(), int t_start_line = 0,
int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) :
Binary_Operator_AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { }
@@ -397,7 +496,7 @@ namespace chaiscript
struct Modulus_AST_Node : public Binary_Operator_AST_Node {
public:
Modulus_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Modulus,
Modulus_AST_Node(const std::string &t_ast_node_text = "%", int t_id = AST_Node_Type::Modulus,
const boost::shared_ptr<std::string> &t_fname=boost::shared_ptr<std::string>(), int t_start_line = 0,
int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) :
Binary_Operator_AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { }
@@ -432,12 +531,27 @@ namespace chaiscript
throw exception::eval_error("Out of bounds exception");
}
catch(const exception::dispatch_error &e){
throw exception::eval_error("Can not find appropriate array lookup operator '[]'.", e.parameters, t_ss );
throw exception::eval_error("Can not find appropriate array lookup operator '[]'.", e.parameters, e.functions, false, t_ss );
}
}
return retval;
}
virtual std::string pretty_print() const
{
std::ostringstream oss;
oss << this->children[0]->pretty_print();
for (size_t i = 1; i < this->children.size(); ++i)
{
oss << "[";
oss << this->children[i]->pretty_print();
oss << "]";
}
return oss.str();
}
};
struct Dot_Access_AST_Node : public AST_Node {
@@ -475,7 +589,12 @@ namespace chaiscript
retval = t_ss.call_function(fun_name, plb);
}
catch(const exception::dispatch_error &e){
throw exception::eval_error(std::string(e.what()) + " for function: " + fun_name, e.parameters, t_ss);
if (e.functions.empty())
{
throw exception::eval_error("'" + fun_name + "' is not a function.");
} else {
throw exception::eval_error(std::string(e.what()) + " for function '" + fun_name + "'", e.parameters, e.functions, true, t_ss);
}
}
catch(detail::Return_Value &rv) {
retval = rv.retval;
@@ -490,7 +609,7 @@ namespace chaiscript
throw exception::eval_error("Out of bounds exception");
}
catch(const exception::dispatch_error &e){
throw exception::eval_error("Can not find appropriate array lookup operator '[]'.", e.parameters, t_ss);
throw exception::eval_error("Can not find appropriate array lookup operator '[]'.", e.parameters, e.functions, true, t_ss);
}
}
}
@@ -512,6 +631,11 @@ namespace chaiscript
return m_value;
}
virtual std::string pretty_print() const
{
return "\"" + text + "\"";
}
private:
Boxed_Value m_value;
@@ -527,6 +651,11 @@ namespace chaiscript
return m_value;
}
virtual std::string pretty_print() const
{
return "'" + text + "'";
}
private:
Boxed_Value m_value;
};
@@ -909,7 +1038,7 @@ namespace chaiscript
return const_var(retval);
}
catch (const exception::dispatch_error &e) {
throw exception::eval_error("Can not find appropriate copy constructor or 'clone' while inserting into Map.", e.parameters, t_ss);
throw exception::eval_error("Can not find appropriate copy constructor or 'clone' while inserting into Map.", e.parameters, e.functions, false, t_ss);
}
}
@@ -972,7 +1101,7 @@ namespace chaiscript
return t_ss.call_function(this->children[0]->text, bv);
}
} catch (const exception::dispatch_error &e) {
throw exception::eval_error("Error with prefix operator evaluation: '" + children[0]->text + "'", e.parameters, t_ss);
throw exception::eval_error("Error with prefix operator evaluation: '" + children[0]->text + "'", e.parameters, e.functions, false, t_ss);
}
}
@@ -1014,7 +1143,7 @@ namespace chaiscript
this->children[0]->children[0]->children[1]->eval(t_ss));
}
catch (const exception::dispatch_error &e) {
throw exception::eval_error("Unable to generate range vector, while calling 'generate_range'", e.parameters, t_ss);
throw exception::eval_error("Unable to generate range vector, while calling 'generate_range'", e.parameters, e.functions, false, t_ss);
}
}
@@ -1340,6 +1469,11 @@ namespace chaiscript
}
return retval;
}
virtual std::string pretty_print() const
{
return "(" + AST_Node::pretty_print() + ")";
}
};
struct Logical_Or_AST_Node : public AST_Node {
@@ -1367,6 +1501,11 @@ namespace chaiscript
return retval;
}
virtual std::string pretty_print() const
{
return "(" + AST_Node::pretty_print() + ")";
}
};
}

View File

@@ -230,18 +230,7 @@ int main(int argc, char *argv[])
}
}
catch (const chaiscript::exception::eval_error &ee) {
std::cout << ee.what();
if (ee.call_stack.size() > 0) {
std::cout << "during evaluation at (" << *(ee.call_stack[0]->filename) << " " << ee.call_stack[0]->start.line << ", " << ee.call_stack[0]->start.column << ")";
for (size_t j = 1; j < ee.call_stack.size(); ++j) {
if (ee.call_stack[j]->identifier != chaiscript::AST_Node_Type::Block
&& ee.call_stack[j]->identifier != chaiscript::AST_Node_Type::File)
{
std::cout << std::endl;
std::cout << " from " << *(ee.call_stack[j]->filename) << " (" << ee.call_stack[j]->start.line << ", " << ee.call_stack[j]->start.column << ")";
}
}
}
std::cout << ee.pretty_print();
std::cout << std::endl;
return EXIT_FAILURE;
}