mirror of
https://github.com/ChaiScript/ChaiScript.git
synced 2026-02-07 02:09:57 +08:00
Enhance eval error stack reporting
Use OOP to avoid code duplication for eval error tracking. This results in much more robust stack error reporting and 400 LOC less.
This commit is contained in:
parent
de5822873b
commit
79e8af4f6e
@ -8,6 +8,7 @@
|
|||||||
#define CHAISCRIPT_COMMON_HPP_
|
#define CHAISCRIPT_COMMON_HPP_
|
||||||
|
|
||||||
#include <chaiscript/dispatchkit/dispatchkit.hpp>
|
#include <chaiscript/dispatchkit/dispatchkit.hpp>
|
||||||
|
#include <boost/enable_shared_from_this.hpp>
|
||||||
|
|
||||||
namespace chaiscript
|
namespace chaiscript
|
||||||
{
|
{
|
||||||
@ -57,65 +58,6 @@ namespace chaiscript
|
|||||||
|
|
||||||
typedef boost::shared_ptr<struct AST_Node> AST_NodePtr;
|
typedef boost::shared_ptr<struct AST_Node> AST_NodePtr;
|
||||||
|
|
||||||
/**
|
|
||||||
* The struct that doubles as both a parser ast_node and an AST node
|
|
||||||
*/
|
|
||||||
struct AST_Node {
|
|
||||||
public:
|
|
||||||
const std::string text;
|
|
||||||
const int identifier;
|
|
||||||
boost::shared_ptr<const std::string> filename;
|
|
||||||
File_Position start, end;
|
|
||||||
std::vector<AST_NodePtr> children;
|
|
||||||
AST_NodePtr annotation;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Prints the contents of an AST node, including its children, recursively
|
|
||||||
*/
|
|
||||||
std::string to_string(std::string t_prepend = "") {
|
|
||||||
std::ostringstream oss;
|
|
||||||
|
|
||||||
oss << t_prepend << "(" << ast_node_type_to_string(this->identifier) << ") "
|
|
||||||
<< this->text << " : " << this->start.line << ", " << this->start.column << std::endl;
|
|
||||||
|
|
||||||
for (unsigned int j = 0; j < this->children.size(); ++j) {
|
|
||||||
oss << this->children[j]->to_string(t_prepend + " ");
|
|
||||||
}
|
|
||||||
return oss.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string internal_to_string() {
|
|
||||||
return to_string();
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual Boxed_Value eval(chaiscript::detail::Dispatch_Engine &)
|
|
||||||
{
|
|
||||||
throw std::runtime_error("Undispatched ast_node (internal error)");
|
|
||||||
}
|
|
||||||
|
|
||||||
void replace_child(const AST_NodePtr &t_child, const AST_NodePtr &t_new_child)
|
|
||||||
{
|
|
||||||
std::replace(children.begin(), children.end(), t_child, t_new_child);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
AST_Node(const std::string &t_ast_node_text, int t_id, const boost::shared_ptr<std::string> &t_fname,
|
|
||||||
int t_start_line, int t_start_col, int t_end_line, int t_end_col) :
|
|
||||||
text(t_ast_node_text), identifier(t_id), filename(t_fname),
|
|
||||||
start(t_start_line, t_start_col), end(t_end_line, t_end_col)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
AST_Node(const std::string &t_ast_node_text, int t_id, const boost::shared_ptr<std::string> &t_fname) :
|
|
||||||
text(t_ast_node_text), identifier(t_id), filename(t_fname) {}
|
|
||||||
|
|
||||||
virtual ~AST_Node() {}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
namespace exception
|
namespace exception
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
@ -157,6 +99,76 @@ namespace chaiscript
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The struct that doubles as both a parser ast_node and an AST node
|
||||||
|
*/
|
||||||
|
struct AST_Node : boost::enable_shared_from_this<AST_Node> {
|
||||||
|
public:
|
||||||
|
const std::string text;
|
||||||
|
const int identifier;
|
||||||
|
boost::shared_ptr<const std::string> filename;
|
||||||
|
File_Position start, end;
|
||||||
|
std::vector<AST_NodePtr> children;
|
||||||
|
AST_NodePtr annotation;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prints the contents of an AST node, including its children, recursively
|
||||||
|
*/
|
||||||
|
std::string to_string(std::string t_prepend = "") {
|
||||||
|
std::ostringstream oss;
|
||||||
|
|
||||||
|
oss << t_prepend << "(" << ast_node_type_to_string(this->identifier) << ") "
|
||||||
|
<< this->text << " : " << this->start.line << ", " << this->start.column << std::endl;
|
||||||
|
|
||||||
|
for (unsigned int j = 0; j < this->children.size(); ++j) {
|
||||||
|
oss << this->children[j]->to_string(t_prepend + " ");
|
||||||
|
}
|
||||||
|
return oss.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string internal_to_string() {
|
||||||
|
return to_string();
|
||||||
|
}
|
||||||
|
|
||||||
|
Boxed_Value eval(chaiscript::detail::Dispatch_Engine &t_e)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
return eval_internal(t_e);
|
||||||
|
} catch (exception::eval_error &ee) {
|
||||||
|
ee.call_stack.push_back(shared_from_this());
|
||||||
|
throw ee;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void replace_child(const AST_NodePtr &t_child, const AST_NodePtr &t_new_child)
|
||||||
|
{
|
||||||
|
std::replace(children.begin(), children.end(), t_child, t_new_child);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
AST_Node(const std::string &t_ast_node_text, int t_id, const boost::shared_ptr<std::string> &t_fname,
|
||||||
|
int t_start_line, int t_start_col, int t_end_line, int t_end_col) :
|
||||||
|
text(t_ast_node_text), identifier(t_id), filename(t_fname),
|
||||||
|
start(t_start_line, t_start_col), end(t_end_line, t_end_col)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
AST_Node(const std::string &t_ast_node_text, int t_id, const boost::shared_ptr<std::string> &t_fname) :
|
||||||
|
text(t_ast_node_text), identifier(t_id), filename(t_fname) {}
|
||||||
|
|
||||||
|
virtual ~AST_Node() {}
|
||||||
|
|
||||||
|
virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &)
|
||||||
|
{
|
||||||
|
throw std::runtime_error("Undispatched ast_node (internal error)");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
namespace detail
|
namespace detail
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -28,9 +28,6 @@ namespace chaiscript
|
|||||||
return t_node->eval(t_ss);
|
return t_node->eval(t_ss);
|
||||||
} catch (const detail::Return_Value &rv) {
|
} catch (const detail::Return_Value &rv) {
|
||||||
return rv.retval;
|
return rv.retval;
|
||||||
} catch (exception::eval_error &ee) {
|
|
||||||
ee.call_stack.push_back(t_node);
|
|
||||||
throw;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -42,16 +39,10 @@ namespace chaiscript
|
|||||||
Binary_Operator_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Bitwise_Xor, 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(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Bitwise_Xor, 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) { }
|
AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { }
|
||||||
virtual ~Binary_Operator_AST_Node() {}
|
virtual ~Binary_Operator_AST_Node() {}
|
||||||
virtual Boxed_Value eval(chaiscript::detail::Dispatch_Engine &t_ss){
|
virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &t_ss){
|
||||||
Boxed_Value retval;
|
Boxed_Value retval;
|
||||||
|
|
||||||
try {
|
retval = this->children[0]->eval(t_ss);
|
||||||
retval = this->children[0]->eval(t_ss);
|
|
||||||
}
|
|
||||||
catch (exception::eval_error &ee) {
|
|
||||||
ee.call_stack.push_back(this->children[0]);
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (size_t i = 1; i < this->children.size(); i += 2) {
|
for (size_t i = 1; i < this->children.size(); i += 2) {
|
||||||
try {
|
try {
|
||||||
@ -60,10 +51,6 @@ namespace chaiscript
|
|||||||
catch(const exception::dispatch_error &){
|
catch(const exception::dispatch_error &){
|
||||||
throw exception::eval_error("Can not find appropriate '" + this->children[i]->text + "'");
|
throw exception::eval_error("Can not find appropriate '" + this->children[i]->text + "'");
|
||||||
}
|
}
|
||||||
catch(exception::eval_error &ee) {
|
|
||||||
ee.call_stack.push_back(this->children[i+1]);
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return retval;
|
return retval;
|
||||||
@ -85,7 +72,7 @@ namespace chaiscript
|
|||||||
AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col),
|
AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col),
|
||||||
m_value(const_var(int(atoi(this->text.c_str())))) { }
|
m_value(const_var(int(atoi(this->text.c_str())))) { }
|
||||||
virtual ~Int_AST_Node() {}
|
virtual ~Int_AST_Node() {}
|
||||||
virtual Boxed_Value eval(chaiscript::detail::Dispatch_Engine &){
|
virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &){
|
||||||
return m_value;
|
return m_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -100,7 +87,7 @@ namespace chaiscript
|
|||||||
AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col),
|
AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col),
|
||||||
m_value(const_var(double(atof(this->text.c_str())))) { }
|
m_value(const_var(double(atof(this->text.c_str())))) { }
|
||||||
virtual ~Float_AST_Node() {}
|
virtual ~Float_AST_Node() {}
|
||||||
virtual Boxed_Value eval(chaiscript::detail::Dispatch_Engine &){
|
virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &){
|
||||||
return m_value;
|
return m_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -114,7 +101,7 @@ namespace chaiscript
|
|||||||
Id_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Id, 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) :
|
Id_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Id, 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) { }
|
AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { }
|
||||||
virtual ~Id_AST_Node() {}
|
virtual ~Id_AST_Node() {}
|
||||||
virtual Boxed_Value eval(chaiscript::detail::Dispatch_Engine &t_ss){
|
virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &t_ss){
|
||||||
if (this->text == "true") {
|
if (this->text == "true") {
|
||||||
return const_var(true);
|
return const_var(true);
|
||||||
}
|
}
|
||||||
@ -164,18 +151,12 @@ namespace chaiscript
|
|||||||
Fun_Call_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Fun_Call, 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) :
|
Fun_Call_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Fun_Call, 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) { }
|
AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { }
|
||||||
virtual ~Fun_Call_AST_Node() {}
|
virtual ~Fun_Call_AST_Node() {}
|
||||||
virtual Boxed_Value eval(chaiscript::detail::Dispatch_Engine &t_ss){
|
virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &t_ss){
|
||||||
dispatch::Param_List_Builder plb;
|
dispatch::Param_List_Builder plb;
|
||||||
|
|
||||||
if ((this->children.size() > 1) && (this->children[1]->identifier == AST_Node_Type::Arg_List)) {
|
if ((this->children.size() > 1) && (this->children[1]->identifier == AST_Node_Type::Arg_List)) {
|
||||||
for (size_t i = 0; i < this->children[1]->children.size(); ++i) {
|
for (size_t i = 0; i < this->children[1]->children.size(); ++i) {
|
||||||
try {
|
plb << this->children[1]->children[i]->eval(t_ss);
|
||||||
plb << this->children[1]->children[i]->eval(t_ss);
|
|
||||||
}
|
|
||||||
catch(exception::eval_error &ee) {
|
|
||||||
ee.call_stack.push_back(this->children[1]->children[i]);
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -205,9 +186,8 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch(exception::eval_error &ee) {
|
catch(exception::eval_error &ee) {
|
||||||
ee.call_stack.push_back(this->children[0]);
|
|
||||||
t_ss.set_stack(prev_stack);
|
t_ss.set_stack(prev_stack);
|
||||||
throw exception::eval_error(ee.reason);
|
throw;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -219,42 +199,29 @@ namespace chaiscript
|
|||||||
Inplace_Fun_Call_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Inplace_Fun_Call, 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) :
|
Inplace_Fun_Call_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Inplace_Fun_Call, 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) { }
|
AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { }
|
||||||
virtual ~Inplace_Fun_Call_AST_Node() {}
|
virtual ~Inplace_Fun_Call_AST_Node() {}
|
||||||
virtual Boxed_Value eval(chaiscript::detail::Dispatch_Engine &t_ss){
|
virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &t_ss){
|
||||||
dispatch::Param_List_Builder plb;
|
dispatch::Param_List_Builder plb;
|
||||||
|
|
||||||
if ((this->children.size() > 1) && (this->children[1]->identifier == AST_Node_Type::Arg_List)) {
|
if ((this->children.size() > 1) && (this->children[1]->identifier == AST_Node_Type::Arg_List)) {
|
||||||
for (size_t i = 0; i < this->children[1]->children.size(); ++i) {
|
for (size_t i = 0; i < this->children[1]->children.size(); ++i) {
|
||||||
try {
|
plb << this->children[1]->children[i]->eval(t_ss);
|
||||||
plb << this->children[1]->children[i]->eval(t_ss);
|
|
||||||
}
|
|
||||||
catch (exception::eval_error &ee) {
|
|
||||||
ee.call_stack.push_back(this->children[1]->children[i]);
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Boxed_Value fn = this->children[0]->eval(t_ss);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Boxed_Value fn = this->children[0]->eval(t_ss);
|
return (*boxed_cast<Const_Proxy_Function >(fn))(plb);
|
||||||
|
|
||||||
try {
|
|
||||||
return (*boxed_cast<Const_Proxy_Function >(fn))(plb);
|
|
||||||
}
|
|
||||||
catch(const exception::dispatch_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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
catch(exception::eval_error &ee) {
|
catch(const exception::dispatch_error &e){
|
||||||
ee.call_stack.push_back(this->children[0]);
|
throw exception::eval_error(std::string(e.what()) + " with function '" + this->children[0]->text + "'");
|
||||||
throw exception::eval_error(ee.reason);
|
}
|
||||||
|
catch(detail::Return_Value &rv) {
|
||||||
|
return rv.retval;
|
||||||
|
}
|
||||||
|
catch(...) {
|
||||||
|
throw;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
@ -278,70 +245,45 @@ namespace chaiscript
|
|||||||
Equation_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Equation, 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) :
|
Equation_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Equation, 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) { }
|
AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { }
|
||||||
virtual ~Equation_AST_Node() {}
|
virtual ~Equation_AST_Node() {}
|
||||||
virtual Boxed_Value eval(chaiscript::detail::Dispatch_Engine &t_ss){
|
virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &t_ss){
|
||||||
Boxed_Value retval;
|
Boxed_Value retval = this->children.back()->eval(t_ss);
|
||||||
try {
|
|
||||||
retval = this->children.back()->eval(t_ss);
|
|
||||||
}
|
|
||||||
catch (exception::eval_error &ee) {
|
|
||||||
ee.call_stack.push_back(this->children.back());
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this->children.size() > 1) {
|
if (this->children.size() > 1) {
|
||||||
for (int i = static_cast<int>(this->children.size())-3; i >= 0; i -= 2) {
|
for (int i = static_cast<int>(this->children.size())-3; i >= 0; i -= 2) {
|
||||||
if (this->children[i+1]->text == "=") {
|
if (this->children[i+1]->text == "=") {
|
||||||
|
Boxed_Value lhs = this->children[i]->eval(t_ss);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Boxed_Value lhs = this->children[i]->eval(t_ss);
|
if (lhs.is_undef()) {
|
||||||
|
retval = t_ss.call_function("clone", retval);
|
||||||
|
retval.clear_dependencies();
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (lhs.is_undef()) {
|
retval = t_ss.call_function(this->children[i+1]->text, lhs, retval);
|
||||||
retval = t_ss.call_function("clone", retval);
|
|
||||||
retval.clear_dependencies();
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
retval = t_ss.call_function(this->children[i+1]->text, lhs, retval);
|
|
||||||
}
|
|
||||||
catch(const exception::dispatch_error &){
|
|
||||||
throw exception::eval_error(std::string("Mismatched types in equation") + (lhs.is_const()?", lhs is const.":"."));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
catch(const exception::dispatch_error &){
|
catch(const exception::dispatch_error &){
|
||||||
throw exception::eval_error("Can not clone right hand side of equation");
|
throw exception::eval_error(std::string("Mismatched types in equation") + (lhs.is_const()?", lhs is const.":"."));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch(exception::eval_error &ee) {
|
catch(const exception::dispatch_error &){
|
||||||
ee.call_stack.push_back(this->children[i]);
|
throw exception::eval_error("Can not clone right hand side of equation");
|
||||||
throw;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (this->children[i+1]->text == ":=") {
|
else if (this->children[i+1]->text == ":=") {
|
||||||
try {
|
Boxed_Value lhs = this->children[i]->eval(t_ss);
|
||||||
Boxed_Value lhs = this->children[i]->eval(t_ss);
|
if (lhs.is_undef() || type_match(lhs, retval)) {
|
||||||
if (lhs.is_undef() || type_match(lhs, retval)) {
|
lhs.assign(retval);
|
||||||
lhs.assign(retval);
|
} else {
|
||||||
}
|
throw exception::eval_error("Mismatched types in equation");
|
||||||
else {
|
|
||||||
throw exception::eval_error("Mismatched types in equation");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (exception::eval_error &ee) {
|
|
||||||
ee.call_stack.push_back(this->children[i]);
|
|
||||||
throw;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
try {
|
try {
|
||||||
retval = t_ss.call_function(this->children[i+1]->text, this->children[i]->eval(t_ss), retval);
|
retval = t_ss.call_function(this->children[i+1]->text, this->children[i]->eval(t_ss), retval);
|
||||||
}
|
} catch(const exception::dispatch_error &){
|
||||||
catch(const exception::dispatch_error &){
|
|
||||||
throw exception::eval_error("Can not find appropriate '" + this->children[i+1]->text + "'");
|
throw exception::eval_error("Can not find appropriate '" + this->children[i+1]->text + "'");
|
||||||
}
|
}
|
||||||
catch(exception::eval_error &ee) {
|
|
||||||
ee.call_stack.push_back(this->children[i]);
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -354,7 +296,7 @@ namespace chaiscript
|
|||||||
Var_Decl_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Var_Decl, 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) :
|
Var_Decl_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Var_Decl, 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) { }
|
AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { }
|
||||||
virtual ~Var_Decl_AST_Node() {}
|
virtual ~Var_Decl_AST_Node() {}
|
||||||
virtual Boxed_Value eval(chaiscript::detail::Dispatch_Engine &t_ss){
|
virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &t_ss){
|
||||||
try {
|
try {
|
||||||
t_ss.add_object(this->children[0]->text, Boxed_Value());
|
t_ss.add_object(this->children[0]->text, Boxed_Value());
|
||||||
}
|
}
|
||||||
@ -392,16 +334,8 @@ namespace chaiscript
|
|||||||
Array_Call_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Array_Call, 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) :
|
Array_Call_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Array_Call, 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) { }
|
AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { }
|
||||||
virtual ~Array_Call_AST_Node() {}
|
virtual ~Array_Call_AST_Node() {}
|
||||||
virtual Boxed_Value eval(chaiscript::detail::Dispatch_Engine &t_ss){
|
virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &t_ss){
|
||||||
Boxed_Value retval;
|
Boxed_Value retval = this->children[0]->eval(t_ss);
|
||||||
|
|
||||||
try {
|
|
||||||
retval = this->children[0]->eval(t_ss);
|
|
||||||
}
|
|
||||||
catch (exception::eval_error &ee) {
|
|
||||||
ee.call_stack.push_back(this->children[0]);
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (size_t i = 1; i < this->children.size(); ++i) {
|
for (size_t i = 1; i < this->children.size(); ++i) {
|
||||||
try {
|
try {
|
||||||
@ -413,10 +347,6 @@ namespace chaiscript
|
|||||||
catch(const exception::dispatch_error &){
|
catch(const exception::dispatch_error &){
|
||||||
throw exception::eval_error("Can not find appropriate array lookup '[]' ");
|
throw exception::eval_error("Can not find appropriate array lookup '[]' ");
|
||||||
}
|
}
|
||||||
catch(exception::eval_error &ee) {
|
|
||||||
ee.call_stack.push_back(this->children[i]);
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return retval;
|
return retval;
|
||||||
@ -428,15 +358,8 @@ namespace chaiscript
|
|||||||
Dot_Access_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Dot_Access, 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) :
|
Dot_Access_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Dot_Access, 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) { }
|
AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { }
|
||||||
virtual ~Dot_Access_AST_Node() {}
|
virtual ~Dot_Access_AST_Node() {}
|
||||||
virtual Boxed_Value eval(chaiscript::detail::Dispatch_Engine &t_ss){
|
virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &t_ss){
|
||||||
Boxed_Value retval;
|
Boxed_Value retval = this->children[0]->eval(t_ss);
|
||||||
try {
|
|
||||||
retval = this->children[0]->eval(t_ss);
|
|
||||||
}
|
|
||||||
catch (exception::eval_error &ee) {
|
|
||||||
ee.call_stack.push_back(this->children[0]);
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this->children.size() > 1) {
|
if (this->children.size() > 1) {
|
||||||
for (size_t i = 2; i < this->children.size(); i+=2) {
|
for (size_t i = 2; i < this->children.size(); i+=2) {
|
||||||
@ -445,13 +368,7 @@ namespace chaiscript
|
|||||||
|
|
||||||
if (this->children[i]->children.size() > 1) {
|
if (this->children[i]->children.size() > 1) {
|
||||||
for (size_t j = 0; j < this->children[i]->children[1]->children.size(); ++j) {
|
for (size_t j = 0; j < this->children[i]->children[1]->children.size(); ++j) {
|
||||||
try {
|
plb << this->children[i]->children[1]->children[j]->eval(t_ss);
|
||||||
plb << this->children[i]->children[1]->children[j]->eval(t_ss);
|
|
||||||
}
|
|
||||||
catch (exception::eval_error &ee) {
|
|
||||||
ee.call_stack.push_back(this->children[i]->children[1]->children[j]);
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -494,10 +411,6 @@ namespace chaiscript
|
|||||||
catch(const exception::dispatch_error &){
|
catch(const exception::dispatch_error &){
|
||||||
throw exception::eval_error("Can not find appropriate array lookup '[]' ");
|
throw exception::eval_error("Can not find appropriate array lookup '[]' ");
|
||||||
}
|
}
|
||||||
catch(exception::eval_error &ee) {
|
|
||||||
ee.call_stack.push_back(this->children[i]->children[j]);
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -514,7 +427,7 @@ namespace chaiscript
|
|||||||
AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col),
|
AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col),
|
||||||
m_value(const_var(this->text)) { }
|
m_value(const_var(this->text)) { }
|
||||||
virtual ~Quoted_String_AST_Node() {}
|
virtual ~Quoted_String_AST_Node() {}
|
||||||
virtual Boxed_Value eval(chaiscript::detail::Dispatch_Engine &) {
|
virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &) {
|
||||||
return m_value;
|
return m_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -529,7 +442,7 @@ namespace chaiscript
|
|||||||
AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col),
|
AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col),
|
||||||
m_value(const_var(char(this->text[0]))) { }
|
m_value(const_var(char(this->text[0]))) { }
|
||||||
virtual ~Single_Quoted_String_AST_Node() {}
|
virtual ~Single_Quoted_String_AST_Node() {}
|
||||||
virtual Boxed_Value eval(chaiscript::detail::Dispatch_Engine &){
|
virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &){
|
||||||
return m_value;
|
return m_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -542,7 +455,7 @@ namespace chaiscript
|
|||||||
Lambda_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Lambda, 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) :
|
Lambda_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Lambda, 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) { }
|
AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { }
|
||||||
virtual ~Lambda_AST_Node() {}
|
virtual ~Lambda_AST_Node() {}
|
||||||
virtual Boxed_Value eval(chaiscript::detail::Dispatch_Engine &t_ss){
|
virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &t_ss){
|
||||||
std::vector<std::string> t_param_names;
|
std::vector<std::string> t_param_names;
|
||||||
size_t numparams = 0;
|
size_t numparams = 0;
|
||||||
|
|
||||||
@ -570,7 +483,7 @@ namespace chaiscript
|
|||||||
Block_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Block, 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) :
|
Block_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Block, 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) { }
|
AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { }
|
||||||
virtual ~Block_AST_Node() {}
|
virtual ~Block_AST_Node() {}
|
||||||
virtual Boxed_Value eval(chaiscript::detail::Dispatch_Engine &t_ss){
|
virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &t_ss){
|
||||||
const size_t num_children = this->children.size();
|
const size_t num_children = this->children.size();
|
||||||
|
|
||||||
detail::Scope_Push_Pop spp(t_ss);
|
detail::Scope_Push_Pop spp(t_ss);
|
||||||
@ -587,10 +500,6 @@ namespace chaiscript
|
|||||||
catch (const chaiscript::detail::Return_Value &) {
|
catch (const chaiscript::detail::Return_Value &) {
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
catch (exception::eval_error &ee) {
|
|
||||||
ee.call_stack.push_back(this->children[i]);
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return Boxed_Value();
|
return Boxed_Value();
|
||||||
@ -603,7 +512,7 @@ namespace chaiscript
|
|||||||
Def_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Def, 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) :
|
Def_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Def, 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) { }
|
AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { }
|
||||||
virtual ~Def_AST_Node() {}
|
virtual ~Def_AST_Node() {}
|
||||||
virtual Boxed_Value eval(chaiscript::detail::Dispatch_Engine &t_ss){
|
virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &t_ss){
|
||||||
std::vector<std::string> t_param_names;
|
std::vector<std::string> t_param_names;
|
||||||
size_t numparams = 0;
|
size_t numparams = 0;
|
||||||
AST_NodePtr guardnode;
|
AST_NodePtr guardnode;
|
||||||
@ -657,7 +566,7 @@ namespace chaiscript
|
|||||||
While_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::While, 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) :
|
While_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::While, 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) { }
|
AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { }
|
||||||
virtual ~While_AST_Node() {}
|
virtual ~While_AST_Node() {}
|
||||||
virtual Boxed_Value eval(chaiscript::detail::Dispatch_Engine &t_ss) {
|
virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &t_ss) {
|
||||||
bool cond;
|
bool cond;
|
||||||
|
|
||||||
detail::Scope_Push_Pop spp(t_ss);
|
detail::Scope_Push_Pop spp(t_ss);
|
||||||
@ -668,19 +577,9 @@ namespace chaiscript
|
|||||||
catch (const exception::bad_boxed_cast &) {
|
catch (const exception::bad_boxed_cast &) {
|
||||||
throw exception::eval_error("While condition not boolean");
|
throw exception::eval_error("While condition not boolean");
|
||||||
}
|
}
|
||||||
catch (exception::eval_error &ee) {
|
|
||||||
ee.call_stack.push_back(this->children[0]);
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
while (cond) {
|
while (cond) {
|
||||||
try {
|
try {
|
||||||
try {
|
this->children[1]->eval(t_ss);
|
||||||
this->children[1]->eval(t_ss);
|
|
||||||
}
|
|
||||||
catch (exception::eval_error &ee) {
|
|
||||||
ee.call_stack.push_back(this->children[1]);
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
cond = boxed_cast<bool>(this->children[0]->eval(t_ss));
|
cond = boxed_cast<bool>(this->children[0]->eval(t_ss));
|
||||||
@ -688,10 +587,6 @@ namespace chaiscript
|
|||||||
catch (const exception::bad_boxed_cast &) {
|
catch (const exception::bad_boxed_cast &) {
|
||||||
throw exception::eval_error("While condition not boolean");
|
throw exception::eval_error("While condition not boolean");
|
||||||
}
|
}
|
||||||
catch (exception::eval_error &ee) {
|
|
||||||
ee.call_stack.push_back(this->children[0]);
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
catch (detail::Break_Loop &) {
|
catch (detail::Break_Loop &) {
|
||||||
cond = false;
|
cond = false;
|
||||||
@ -707,7 +602,7 @@ namespace chaiscript
|
|||||||
If_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::If, 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) :
|
If_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::If, 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) { }
|
AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { }
|
||||||
virtual ~If_AST_Node() {}
|
virtual ~If_AST_Node() {}
|
||||||
virtual Boxed_Value eval(chaiscript::detail::Dispatch_Engine &t_ss){
|
virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &t_ss){
|
||||||
bool cond;
|
bool cond;
|
||||||
try {
|
try {
|
||||||
cond = boxed_cast<bool>(this->children[0]->eval(t_ss));
|
cond = boxed_cast<bool>(this->children[0]->eval(t_ss));
|
||||||
@ -715,32 +610,16 @@ namespace chaiscript
|
|||||||
catch (const exception::bad_boxed_cast &) {
|
catch (const exception::bad_boxed_cast &) {
|
||||||
throw exception::eval_error("If condition not boolean");
|
throw exception::eval_error("If condition not boolean");
|
||||||
}
|
}
|
||||||
catch (exception::eval_error &ee) {
|
|
||||||
ee.call_stack.push_back(this->children[0]);
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cond) {
|
if (cond) {
|
||||||
try {
|
return this->children[1]->eval(t_ss);
|
||||||
return this->children[1]->eval(t_ss);
|
|
||||||
}
|
|
||||||
catch (exception::eval_error &ee) {
|
|
||||||
ee.call_stack.push_back(this->children[1]);
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (this->children.size() > 2) {
|
if (this->children.size() > 2) {
|
||||||
size_t i = 2;
|
size_t i = 2;
|
||||||
while ((!cond) && (i < this->children.size())) {
|
while ((!cond) && (i < this->children.size())) {
|
||||||
if (this->children[i]->text == "else") {
|
if (this->children[i]->text == "else") {
|
||||||
try {
|
return this->children[i+1]->eval(t_ss);
|
||||||
return this->children[i+1]->eval(t_ss);
|
|
||||||
}
|
|
||||||
catch (exception::eval_error &ee) {
|
|
||||||
ee.call_stack.push_back(this->children[i+1]);
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (this->children[i]->text == "else if") {
|
else if (this->children[i]->text == "else if") {
|
||||||
try {
|
try {
|
||||||
@ -749,18 +628,8 @@ namespace chaiscript
|
|||||||
catch (const exception::bad_boxed_cast &) {
|
catch (const exception::bad_boxed_cast &) {
|
||||||
throw exception::eval_error("'else if' condition not boolean");
|
throw exception::eval_error("'else if' condition not boolean");
|
||||||
}
|
}
|
||||||
catch (exception::eval_error &ee) {
|
|
||||||
ee.call_stack.push_back(this->children[i+1]);
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
if (cond) {
|
if (cond) {
|
||||||
try {
|
return this->children[i+2]->eval(t_ss);
|
||||||
return this->children[i+2]->eval(t_ss);
|
|
||||||
}
|
|
||||||
catch (exception::eval_error &ee) {
|
|
||||||
ee.call_stack.push_back(this->children[i+2]);
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
i = i + 3;
|
i = i + 3;
|
||||||
@ -778,37 +647,18 @@ namespace chaiscript
|
|||||||
For_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::For, 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) :
|
For_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::For, 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) { }
|
AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { }
|
||||||
virtual ~For_AST_Node() {}
|
virtual ~For_AST_Node() {}
|
||||||
virtual Boxed_Value eval(chaiscript::detail::Dispatch_Engine &t_ss){
|
virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &t_ss){
|
||||||
bool cond;
|
bool cond;
|
||||||
|
|
||||||
detail::Scope_Push_Pop spp(t_ss);
|
detail::Scope_Push_Pop spp(t_ss);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (this->children.size() == 4) {
|
if (this->children.size() == 4) {
|
||||||
try {
|
this->children[0]->eval(t_ss);
|
||||||
this->children[0]->eval(t_ss);
|
|
||||||
}
|
|
||||||
catch (exception::eval_error &ee) {
|
|
||||||
ee.call_stack.push_back(this->children[0]);
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
cond = boxed_cast<bool>(this->children[1]->eval(t_ss));
|
||||||
cond = boxed_cast<bool>(this->children[1]->eval(t_ss));
|
} else {
|
||||||
}
|
cond = boxed_cast<bool>(this->children[0]->eval(t_ss));
|
||||||
catch (exception::eval_error &ee) {
|
|
||||||
ee.call_stack.push_back(this->children[1]);
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
try {
|
|
||||||
cond = boxed_cast<bool>(this->children[0]->eval(t_ss));
|
|
||||||
}
|
|
||||||
catch (exception::eval_error &ee) {
|
|
||||||
ee.call_stack.push_back(this->children[0]);
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (const exception::bad_boxed_cast &) {
|
catch (const exception::bad_boxed_cast &) {
|
||||||
@ -817,54 +667,17 @@ namespace chaiscript
|
|||||||
while (cond) {
|
while (cond) {
|
||||||
try {
|
try {
|
||||||
if (this->children.size() == 4) {
|
if (this->children.size() == 4) {
|
||||||
try {
|
this->children[3]->eval(t_ss);
|
||||||
this->children[3]->eval(t_ss);
|
this->children[2]->eval(t_ss);
|
||||||
}
|
|
||||||
catch (exception::eval_error &ee) {
|
|
||||||
ee.call_stack.push_back(this->children[3]);
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
cond = boxed_cast<bool>(this->children[1]->eval(t_ss));
|
||||||
this->children[2]->eval(t_ss);
|
|
||||||
}
|
|
||||||
catch (exception::eval_error &ee) {
|
|
||||||
ee.call_stack.push_back(this->children[2]);
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
cond = boxed_cast<bool>(this->children[1]->eval(t_ss));
|
|
||||||
}
|
|
||||||
catch (exception::eval_error &ee) {
|
|
||||||
ee.call_stack.push_back(this->children[1]);
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
try {
|
this->children[2]->eval(t_ss);
|
||||||
this->children[2]->eval(t_ss);
|
|
||||||
}
|
|
||||||
catch (exception::eval_error &ee) {
|
|
||||||
ee.call_stack.push_back(this->children[2]);
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
this->children[1]->eval(t_ss);
|
||||||
this->children[1]->eval(t_ss);
|
|
||||||
}
|
|
||||||
catch (exception::eval_error &ee) {
|
|
||||||
ee.call_stack.push_back(this->children[1]);
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
cond = boxed_cast<bool>(this->children[0]->eval(t_ss));
|
||||||
cond = boxed_cast<bool>(this->children[0]->eval(t_ss));
|
|
||||||
}
|
|
||||||
catch (exception::eval_error &ee) {
|
|
||||||
ee.call_stack.push_back(this->children[0]);
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (const exception::bad_boxed_cast &) {
|
catch (const exception::bad_boxed_cast &) {
|
||||||
@ -884,17 +697,11 @@ namespace chaiscript
|
|||||||
Inline_Array_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Inline_Array, 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) :
|
Inline_Array_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Inline_Array, 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) { }
|
AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { }
|
||||||
virtual ~Inline_Array_AST_Node() {}
|
virtual ~Inline_Array_AST_Node() {}
|
||||||
virtual Boxed_Value eval(chaiscript::detail::Dispatch_Engine &t_ss){
|
virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &t_ss){
|
||||||
std::vector<Boxed_Value> vec;
|
std::vector<Boxed_Value> vec;
|
||||||
if (this->children.size() > 0) {
|
if (this->children.size() > 0) {
|
||||||
for (size_t i = 0; i < this->children[0]->children.size(); ++i) {
|
for (size_t i = 0; i < this->children[0]->children.size(); ++i) {
|
||||||
try {
|
vec.push_back(this->children[0]->children[i]->eval(t_ss));
|
||||||
vec.push_back(this->children[0]->children[i]->eval(t_ss));
|
|
||||||
}
|
|
||||||
catch(exception::eval_error &ee) {
|
|
||||||
ee.call_stack.push_back(this->children[0]->children[i]);
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -908,18 +715,12 @@ namespace chaiscript
|
|||||||
Inline_Map_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Inline_Map, 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) :
|
Inline_Map_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Inline_Map, 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) { }
|
AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { }
|
||||||
virtual ~Inline_Map_AST_Node() {}
|
virtual ~Inline_Map_AST_Node() {}
|
||||||
virtual Boxed_Value eval(chaiscript::detail::Dispatch_Engine &t_ss){
|
virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &t_ss){
|
||||||
try {
|
try {
|
||||||
std::map<std::string, Boxed_Value> retval;
|
std::map<std::string, Boxed_Value> retval;
|
||||||
for (size_t i = 0; i < this->children[0]->children.size(); ++i) {
|
for (size_t i = 0; i < this->children[0]->children.size(); ++i) {
|
||||||
try {
|
retval[boxed_cast<std::string>(this->children[0]->children[i]->children[0]->eval(t_ss))]
|
||||||
retval[boxed_cast<std::string>(this->children[0]->children[i]->children[0]->eval(t_ss))]
|
= t_ss.call_function("clone", this->children[0]->children[i]->children[1]->eval(t_ss));
|
||||||
= t_ss.call_function("clone", this->children[0]->children[i]->children[1]->eval(t_ss));
|
|
||||||
}
|
|
||||||
catch(exception::eval_error &ee) {
|
|
||||||
ee.call_stack.push_back(this->children[0]->children[i]);
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return const_var(retval);
|
return const_var(retval);
|
||||||
}
|
}
|
||||||
@ -935,15 +736,9 @@ namespace chaiscript
|
|||||||
Return_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Return, 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) :
|
Return_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Return, 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) { }
|
AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { }
|
||||||
virtual ~Return_AST_Node() {}
|
virtual ~Return_AST_Node() {}
|
||||||
virtual Boxed_Value eval(chaiscript::detail::Dispatch_Engine &t_ss){
|
virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &t_ss){
|
||||||
if (this->children.size() > 0) {
|
if (this->children.size() > 0) {
|
||||||
try {
|
throw detail::Return_Value(this->children[0]->eval(t_ss));
|
||||||
throw detail::Return_Value(this->children[0]->eval(t_ss));
|
|
||||||
}
|
|
||||||
catch (exception::eval_error &ee) {
|
|
||||||
ee.call_stack.push_back(this->children[0]);
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
throw detail::Return_Value(Boxed_Value());
|
throw detail::Return_Value(Boxed_Value());
|
||||||
@ -957,18 +752,12 @@ namespace chaiscript
|
|||||||
File_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::File, 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) :
|
File_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::File, 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) { }
|
AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { }
|
||||||
virtual ~File_AST_Node() {}
|
virtual ~File_AST_Node() {}
|
||||||
virtual Boxed_Value eval(chaiscript::detail::Dispatch_Engine &t_ss) {
|
virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &t_ss) {
|
||||||
const size_t size = this->children.size();
|
const size_t size = this->children.size();
|
||||||
for (size_t i = 0; i < size; ++i) {
|
for (size_t i = 0; i < size; ++i) {
|
||||||
try {
|
const Boxed_Value &retval = this->children[i]->eval(t_ss);
|
||||||
const Boxed_Value &retval = this->children[i]->eval(t_ss);
|
if (i + 1 == size) {
|
||||||
if (i + 1 == size) {
|
return retval;
|
||||||
return retval;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (exception::eval_error &ee) {
|
|
||||||
ee.call_stack.push_back(this->children[i]);
|
|
||||||
throw;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return Boxed_Value();
|
return Boxed_Value();
|
||||||
@ -980,13 +769,8 @@ namespace chaiscript
|
|||||||
Prefix_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Prefix, 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) :
|
Prefix_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Prefix, 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) { }
|
AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { }
|
||||||
virtual ~Prefix_AST_Node() {}
|
virtual ~Prefix_AST_Node() {}
|
||||||
virtual Boxed_Value eval(chaiscript::detail::Dispatch_Engine &t_ss){
|
virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &t_ss){
|
||||||
try {
|
return t_ss.call_function(this->children[0]->text, this->children[1]->eval(t_ss));
|
||||||
return t_ss.call_function(this->children[0]->text, this->children[1]->eval(t_ss));
|
|
||||||
}
|
|
||||||
catch(std::exception &){
|
|
||||||
throw exception::eval_error("Can not find appropriate unary '" + this->children[0]->text + "'");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
@ -996,7 +780,7 @@ namespace chaiscript
|
|||||||
Break_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Break, 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) :
|
Break_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Break, 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) { }
|
AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { }
|
||||||
virtual ~Break_AST_Node() {}
|
virtual ~Break_AST_Node() {}
|
||||||
virtual Boxed_Value eval(chaiscript::detail::Dispatch_Engine &){
|
virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &){
|
||||||
throw detail::Break_Loop();
|
throw detail::Break_Loop();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -1020,7 +804,7 @@ namespace chaiscript
|
|||||||
Inline_Range_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Inline_Range, 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) :
|
Inline_Range_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Inline_Range, 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) { }
|
AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { }
|
||||||
virtual ~Inline_Range_AST_Node() {}
|
virtual ~Inline_Range_AST_Node() {}
|
||||||
virtual Boxed_Value eval(chaiscript::detail::Dispatch_Engine &t_ss){
|
virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &t_ss){
|
||||||
try {
|
try {
|
||||||
return t_ss.call_function("generate_range",
|
return t_ss.call_function("generate_range",
|
||||||
this->children[0]->children[0]->children[0]->eval(t_ss),
|
this->children[0]->children[0]->children[0]->eval(t_ss),
|
||||||
@ -1029,10 +813,6 @@ namespace chaiscript
|
|||||||
catch (const exception::dispatch_error &) {
|
catch (const exception::dispatch_error &) {
|
||||||
throw exception::eval_error("Unable to generate range vector");
|
throw exception::eval_error("Unable to generate range vector");
|
||||||
}
|
}
|
||||||
catch(exception::eval_error &ee) {
|
|
||||||
ee.call_stack.push_back(this->children[0]->children[0]);
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
@ -1049,7 +829,7 @@ namespace chaiscript
|
|||||||
Try_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Try, 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) :
|
Try_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Try, 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) { }
|
AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { }
|
||||||
virtual ~Try_AST_Node() {}
|
virtual ~Try_AST_Node() {}
|
||||||
virtual Boxed_Value eval(chaiscript::detail::Dispatch_Engine &t_ss){
|
virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &t_ss){
|
||||||
Boxed_Value retval;
|
Boxed_Value retval;
|
||||||
|
|
||||||
detail::Scope_Push_Pop spp(t_ss);
|
detail::Scope_Push_Pop spp(t_ss);
|
||||||
@ -1058,15 +838,8 @@ namespace chaiscript
|
|||||||
retval = this->children[0]->eval(t_ss);
|
retval = this->children[0]->eval(t_ss);
|
||||||
}
|
}
|
||||||
catch (exception::eval_error &ee) {
|
catch (exception::eval_error &ee) {
|
||||||
ee.call_stack.push_back(this->children[0]);
|
|
||||||
if (this->children.back()->identifier == AST_Node_Type::Finally) {
|
if (this->children.back()->identifier == AST_Node_Type::Finally) {
|
||||||
try {
|
this->children.back()->children[0]->eval(t_ss);
|
||||||
this->children.back()->children[0]->eval(t_ss);
|
|
||||||
}
|
|
||||||
catch (exception::eval_error &ee2) {
|
|
||||||
ee2.call_stack.push_back(this->children.back()->children[0]);
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
@ -1083,25 +856,13 @@ namespace chaiscript
|
|||||||
|
|
||||||
if (catch_block->children.size() == 1) {
|
if (catch_block->children.size() == 1) {
|
||||||
//No variable capture, no guards
|
//No variable capture, no guards
|
||||||
try {
|
retval = catch_block->children[0]->eval(t_ss);
|
||||||
retval = catch_block->children[0]->eval(t_ss);
|
|
||||||
}
|
|
||||||
catch (exception::eval_error &ee) {
|
|
||||||
ee.call_stack.push_back(catch_block->children[0]);
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else if (catch_block->children.size() == 2) {
|
else if (catch_block->children.size() == 2) {
|
||||||
//Variable capture, no guards
|
//Variable capture, no guards
|
||||||
t_ss.add_object(catch_block->children[0]->text, except);
|
t_ss.add_object(catch_block->children[0]->text, except);
|
||||||
try {
|
retval = catch_block->children[1]->eval(t_ss);
|
||||||
retval = catch_block->children[1]->eval(t_ss);
|
|
||||||
}
|
|
||||||
catch (exception::eval_error &ee) {
|
|
||||||
ee.call_stack.push_back(catch_block->children[1]);
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1114,37 +875,18 @@ namespace chaiscript
|
|||||||
guard = boxed_cast<bool>(catch_block->children[1]->eval(t_ss));
|
guard = boxed_cast<bool>(catch_block->children[1]->eval(t_ss));
|
||||||
} catch (const exception::bad_boxed_cast &) {
|
} catch (const exception::bad_boxed_cast &) {
|
||||||
if (this->children.back()->identifier == AST_Node_Type::Finally) {
|
if (this->children.back()->identifier == AST_Node_Type::Finally) {
|
||||||
try {
|
this->children.back()->children[0]->eval(t_ss);
|
||||||
this->children.back()->children[0]->eval(t_ss);
|
|
||||||
}
|
|
||||||
catch (exception::eval_error &ee) {
|
|
||||||
ee.call_stack.push_back(this->children.back()->children[0]);
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
throw exception::eval_error("Guard condition not boolean");
|
throw exception::eval_error("Guard condition not boolean");
|
||||||
}
|
}
|
||||||
if (guard) {
|
if (guard) {
|
||||||
try {
|
retval = catch_block->children[2]->eval(t_ss);
|
||||||
retval = catch_block->children[2]->eval(t_ss);
|
|
||||||
}
|
|
||||||
catch (exception::eval_error &ee) {
|
|
||||||
ee.call_stack.push_back(catch_block->children[2]);
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (this->children.back()->identifier == AST_Node_Type::Finally) {
|
if (this->children.back()->identifier == AST_Node_Type::Finally) {
|
||||||
try {
|
this->children.back()->children[0]->eval(t_ss);
|
||||||
this->children.back()->children[0]->eval(t_ss);
|
|
||||||
}
|
|
||||||
catch (exception::eval_error &ee) {
|
|
||||||
ee.call_stack.push_back(this->children.back()->children[0]);
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
throw exception::eval_error("Internal error: catch block size unrecognized");
|
throw exception::eval_error("Internal error: catch block size unrecognized");
|
||||||
}
|
}
|
||||||
@ -1156,27 +898,13 @@ namespace chaiscript
|
|||||||
|
|
||||||
if (catch_block->children.size() == 1) {
|
if (catch_block->children.size() == 1) {
|
||||||
//No variable capture, no guards
|
//No variable capture, no guards
|
||||||
try {
|
retval = catch_block->children[0]->eval(t_ss);
|
||||||
retval = catch_block->children[0]->eval(t_ss);
|
|
||||||
}
|
|
||||||
catch (exception::eval_error &ee) {
|
|
||||||
ee.call_stack.push_back(catch_block->children[0]);
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else if (catch_block->children.size() == 2) {
|
else if (catch_block->children.size() == 2) {
|
||||||
//Variable capture, no guards
|
//Variable capture, no guards
|
||||||
t_ss.add_object(catch_block->children[0]->text, except);
|
t_ss.add_object(catch_block->children[0]->text, except);
|
||||||
try {
|
retval = catch_block->children[1]->eval(t_ss);
|
||||||
retval = catch_block->children[1]->eval(t_ss);
|
|
||||||
}
|
|
||||||
catch (exception::eval_error &ee) {
|
|
||||||
ee.call_stack.push_back(catch_block->children[1]);
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else if (catch_block->children.size() == 3) {
|
else if (catch_block->children.size() == 3) {
|
||||||
@ -1189,41 +917,19 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
catch (const exception::bad_boxed_cast &) {
|
catch (const exception::bad_boxed_cast &) {
|
||||||
if (this->children.back()->identifier == AST_Node_Type::Finally) {
|
if (this->children.back()->identifier == AST_Node_Type::Finally) {
|
||||||
try {
|
this->children.back()->children[0]->eval(t_ss);
|
||||||
this->children.back()->children[0]->eval(t_ss);
|
|
||||||
}
|
|
||||||
catch (exception::eval_error &ee) {
|
|
||||||
ee.call_stack.push_back(this->children.back()->children[0]);
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
throw exception::eval_error("Guard condition not boolean");
|
throw exception::eval_error("Guard condition not boolean");
|
||||||
}
|
}
|
||||||
catch (exception::eval_error &ee) {
|
|
||||||
ee.call_stack.push_back(catch_block->children[1]);
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
if (guard) {
|
if (guard) {
|
||||||
try {
|
retval = catch_block->children[2]->eval(t_ss);
|
||||||
retval = catch_block->children[2]->eval(t_ss);
|
|
||||||
}
|
|
||||||
catch (exception::eval_error &ee) {
|
|
||||||
ee.call_stack.push_back(catch_block->children[2]);
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (this->children.back()->identifier == AST_Node_Type::Finally) {
|
if (this->children.back()->identifier == AST_Node_Type::Finally) {
|
||||||
try {
|
this->children.back()->children[0]->eval(t_ss);
|
||||||
this->children.back()->children[0]->eval(t_ss);
|
|
||||||
}
|
|
||||||
catch (exception::eval_error &ee) {
|
|
||||||
ee.call_stack.push_back(this->children.back()->children[0]);
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
throw exception::eval_error("Internal error: catch block size unrecognized");
|
throw exception::eval_error("Internal error: catch block size unrecognized");
|
||||||
}
|
}
|
||||||
@ -1231,25 +937,13 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
catch (...) {
|
catch (...) {
|
||||||
if (this->children.back()->identifier == AST_Node_Type::Finally) {
|
if (this->children.back()->identifier == AST_Node_Type::Finally) {
|
||||||
try {
|
this->children.back()->children[0]->eval(t_ss);
|
||||||
this->children.back()->children[0]->eval(t_ss);
|
|
||||||
}
|
|
||||||
catch (exception::eval_error &ee) {
|
|
||||||
ee.call_stack.push_back(this->children.back()->children[0]);
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this->children.back()->identifier == AST_Node_Type::Finally) {
|
if (this->children.back()->identifier == AST_Node_Type::Finally) {
|
||||||
try {
|
retval = this->children.back()->children[0]->eval(t_ss);
|
||||||
retval = this->children.back()->children[0]->eval(t_ss);
|
|
||||||
}
|
|
||||||
catch (exception::eval_error &ee) {
|
|
||||||
ee.call_stack.push_back(this->children.back()->children[0]);
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return retval;
|
return retval;
|
||||||
@ -1276,7 +970,7 @@ namespace chaiscript
|
|||||||
Method_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Method, 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) :
|
Method_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Method, 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) { }
|
AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { }
|
||||||
virtual ~Method_AST_Node() {}
|
virtual ~Method_AST_Node() {}
|
||||||
virtual Boxed_Value eval(chaiscript::detail::Dispatch_Engine &t_ss){
|
virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &t_ss){
|
||||||
|
|
||||||
std::vector<std::string> t_param_names;
|
std::vector<std::string> t_param_names;
|
||||||
AST_NodePtr guardnode;
|
AST_NodePtr guardnode;
|
||||||
@ -1353,7 +1047,7 @@ namespace chaiscript
|
|||||||
Attr_Decl_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Attr_Decl, 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) :
|
Attr_Decl_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Attr_Decl, 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) { }
|
AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { }
|
||||||
virtual ~Attr_Decl_AST_Node() {}
|
virtual ~Attr_Decl_AST_Node() {}
|
||||||
virtual Boxed_Value eval(chaiscript::detail::Dispatch_Engine &t_ss){
|
virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &t_ss){
|
||||||
try {
|
try {
|
||||||
t_ss.add(fun(boost::function<Boxed_Value (dispatch::Dynamic_Object &)>(boost::bind(&dispatch::detail::Dynamic_Object_Attribute::func, this->children[0]->text,
|
t_ss.add(fun(boost::function<Boxed_Value (dispatch::Dynamic_Object &)>(boost::bind(&dispatch::detail::Dynamic_Object_Attribute::func, this->children[0]->text,
|
||||||
this->children[1]->text, _1))), this->children[1]->text);
|
this->children[1]->text, _1))), this->children[1]->text);
|
||||||
@ -1407,15 +1101,8 @@ namespace chaiscript
|
|||||||
Logical_And_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Logical_And, 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) :
|
Logical_And_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Logical_And, 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) { }
|
AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { }
|
||||||
virtual ~Logical_And_AST_Node() {}
|
virtual ~Logical_And_AST_Node() {}
|
||||||
virtual Boxed_Value eval(chaiscript::detail::Dispatch_Engine &t_ss){
|
virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &t_ss){
|
||||||
Boxed_Value retval;
|
Boxed_Value retval = this->children[0]->eval(t_ss);
|
||||||
try {
|
|
||||||
retval = this->children[0]->eval(t_ss);
|
|
||||||
}
|
|
||||||
catch (exception::eval_error &ee) {
|
|
||||||
ee.call_stack.push_back(this->children[0]);
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this->children.size() > 1) {
|
if (this->children.size() > 1) {
|
||||||
for (size_t i = 1; i < this->children.size(); i += 2) {
|
for (size_t i = 1; i < this->children.size(); i += 2) {
|
||||||
@ -1427,13 +1114,7 @@ namespace chaiscript
|
|||||||
throw exception::eval_error("Condition not boolean");
|
throw exception::eval_error("Condition not boolean");
|
||||||
}
|
}
|
||||||
if (lhs) {
|
if (lhs) {
|
||||||
try {
|
retval = this->children[i+1]->eval(t_ss);
|
||||||
retval = this->children[i+1]->eval(t_ss);
|
|
||||||
}
|
|
||||||
catch (exception::eval_error &ee) {
|
|
||||||
ee.call_stack.push_back(this->children[i+1]);
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
retval = Boxed_Value(false);
|
retval = Boxed_Value(false);
|
||||||
@ -1449,37 +1130,20 @@ namespace chaiscript
|
|||||||
Logical_Or_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Logical_Or, 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) :
|
Logical_Or_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Logical_Or, 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) { }
|
AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { }
|
||||||
virtual ~Logical_Or_AST_Node() {}
|
virtual ~Logical_Or_AST_Node() {}
|
||||||
virtual Boxed_Value eval(chaiscript::detail::Dispatch_Engine &t_ss){
|
virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &t_ss){
|
||||||
Boxed_Value retval;
|
Boxed_Value retval;
|
||||||
|
|
||||||
try {
|
retval = this->children[0]->eval(t_ss);
|
||||||
retval = this->children[0]->eval(t_ss);
|
|
||||||
}
|
|
||||||
catch (exception::eval_error &ee) {
|
|
||||||
ee.call_stack.push_back(this->children[0]);
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this->children.size() > 1) {
|
if (this->children.size() > 1) {
|
||||||
for (size_t i = 1; i < this->children.size(); i += 2) {
|
for (size_t i = 1; i < this->children.size(); i += 2) {
|
||||||
bool lhs;
|
bool lhs = boxed_cast<bool>(retval);
|
||||||
try {
|
|
||||||
lhs = boxed_cast<bool>(retval);
|
|
||||||
}
|
|
||||||
catch (const exception::bad_boxed_cast &) {
|
|
||||||
throw exception::eval_error("Condition not boolean");
|
|
||||||
}
|
|
||||||
if (lhs) {
|
if (lhs) {
|
||||||
retval = Boxed_Value(true);
|
retval = Boxed_Value(true);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
try {
|
retval = this->children[i+1]->eval(t_ss);
|
||||||
retval = this->children[i+1]->eval(t_ss);
|
|
||||||
}
|
|
||||||
catch (exception::eval_error &ee) {
|
|
||||||
ee.call_stack.push_back(this->children[i+1]);
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
22
src/main.cpp
22
src/main.cpp
@ -63,6 +63,17 @@ bool throws_exception(const boost::function<void ()> &f)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
chaiscript::exception::eval_error get_eval_error(const boost::function<void ()> &f)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
f();
|
||||||
|
} catch (const chaiscript::exception::eval_error &e) {
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw std::runtime_error("no exception throw");
|
||||||
|
}
|
||||||
|
|
||||||
std::string get_next_command() {
|
std::string get_next_command() {
|
||||||
std::string retval("quit");
|
std::string retval("quit");
|
||||||
if ( ! std::cin.eof() ) {
|
if ( ! std::cin.eof() ) {
|
||||||
@ -158,6 +169,7 @@ int main(int argc, char *argv[])
|
|||||||
chai.add(chaiscript::fun(&help), "help");
|
chai.add(chaiscript::fun(&help), "help");
|
||||||
chai.add(chaiscript::fun(&version), "version");
|
chai.add(chaiscript::fun(&version), "version");
|
||||||
chai.add(chaiscript::fun(&throws_exception), "throws_exception");
|
chai.add(chaiscript::fun(&throws_exception), "throws_exception");
|
||||||
|
chai.add(chaiscript::fun(&get_eval_error), "get_eval_error");
|
||||||
|
|
||||||
for (int i = 0; i < argc; ++i) {
|
for (int i = 0; i < argc; ++i) {
|
||||||
if ( i == 0 && argc > 1 ) {
|
if ( i == 0 && argc > 1 ) {
|
||||||
@ -209,9 +221,13 @@ int main(int argc, char *argv[])
|
|||||||
std::cout << ee.what();
|
std::cout << ee.what();
|
||||||
if (ee.call_stack.size() > 0) {
|
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 << ")";
|
std::cout << "during evaluation at (" << *(ee.call_stack[0]->filename) << " " << ee.call_stack[0]->start.line << ", " << ee.call_stack[0]->start.column << ")";
|
||||||
for (unsigned int j = 1; j < ee.call_stack.size(); ++j) {
|
for (size_t j = 1; j < ee.call_stack.size(); ++j) {
|
||||||
std::cout << std::endl;
|
if (ee.call_stack[j]->identifier != chaiscript::AST_Node_Type::Block
|
||||||
std::cout << " from " << *(ee.call_stack[j]->filename) << " (" << ee.call_stack[j]->start.line << ", " << ee.call_stack[j]->start.column << ")";
|
&& 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 << std::endl;
|
std::cout << std::endl;
|
||||||
|
|||||||
@ -52,6 +52,13 @@ CHAISCRIPT_MODULE_EXPORT chaiscript::ModulePtr create_chaiscript_module_reflect
|
|||||||
|
|
||||||
chaiscript::bootstrap::standard_library::vector_type<std::vector<boost::shared_ptr<chaiscript::AST_Node> > >("AST_NodeVector", m);
|
chaiscript::bootstrap::standard_library::vector_type<std::vector<boost::shared_ptr<chaiscript::AST_Node> > >("AST_NodeVector", m);
|
||||||
|
|
||||||
|
CHAISCRIPT_CLASS( m,
|
||||||
|
chaiscript::exception::eval_error,
|
||||||
|
,
|
||||||
|
((reason))
|
||||||
|
((call_stack))
|
||||||
|
);
|
||||||
|
|
||||||
CHAISCRIPT_CLASS( m,
|
CHAISCRIPT_CLASS( m,
|
||||||
chaiscript::File_Position,
|
chaiscript::File_Position,
|
||||||
(chaiscript::File_Position())
|
(chaiscript::File_Position())
|
||||||
|
|||||||
39
unittests/eval_error.chai
Normal file
39
unittests/eval_error.chai
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
load_module("reflection")
|
||||||
|
|
||||||
|
def deep()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
} catch {
|
||||||
|
|
||||||
|
} finally {
|
||||||
|
if (2)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def func()
|
||||||
|
{
|
||||||
|
deep();
|
||||||
|
}
|
||||||
|
|
||||||
|
def doing()
|
||||||
|
{
|
||||||
|
for (var i = 0; i < 10; ++i)
|
||||||
|
{
|
||||||
|
func();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def while_doing()
|
||||||
|
{
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
doing();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var f = fun() { while_doing(); }
|
||||||
|
|
||||||
|
assert_equal(get_eval_error(f).call_stack.size(), 16)
|
||||||
@ -10,6 +10,24 @@ def assert_equal(x, y)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def assert_false(f)
|
||||||
|
{
|
||||||
|
if (f)
|
||||||
|
{
|
||||||
|
print("assert_false failure");
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def assert_true(f)
|
||||||
|
{
|
||||||
|
if (!f)
|
||||||
|
{
|
||||||
|
print("assert_false failure");
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
def assert_not_equal(x, y)
|
def assert_not_equal(x, y)
|
||||||
{
|
{
|
||||||
if (!(x == y))
|
if (!(x == y))
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user