Use RAII for scope management
Possibly fixes a few bugs where scope pops where missed.
This commit is contained in:
@@ -90,7 +90,6 @@ namespace chaiscript
|
|||||||
|
|
||||||
virtual Boxed_Value eval(chaiscript::detail::Dispatch_Engine &)
|
virtual Boxed_Value eval(chaiscript::detail::Dispatch_Engine &)
|
||||||
{
|
{
|
||||||
Boxed_Value bv;
|
|
||||||
throw std::runtime_error("Undispatched ast_node (internal error)");
|
throw std::runtime_error("Undispatched ast_node (internal error)");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -175,6 +174,26 @@ namespace chaiscript
|
|||||||
struct Break_Loop {
|
struct Break_Loop {
|
||||||
Break_Loop() { }
|
Break_Loop() { }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// Creates a new scope then pops it on destruction
|
||||||
|
struct Scope_Push_Pop
|
||||||
|
{
|
||||||
|
Scope_Push_Pop(chaiscript::detail::Dispatch_Engine &t_de)
|
||||||
|
: m_de(t_de)
|
||||||
|
{
|
||||||
|
m_de.new_scope();
|
||||||
|
}
|
||||||
|
|
||||||
|
~Scope_Push_Pop()
|
||||||
|
{
|
||||||
|
m_de.pop_scope();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
chaiscript::detail::Dispatch_Engine &m_de;
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -18,25 +18,18 @@ namespace chaiscript
|
|||||||
*/
|
*/
|
||||||
template <typename Eval_System>
|
template <typename Eval_System>
|
||||||
const Boxed_Value eval_function (Eval_System &t_ss, const AST_NodePtr &t_node, const std::vector<std::string> &t_param_names, const std::vector<Boxed_Value> &t_vals) {
|
const Boxed_Value eval_function (Eval_System &t_ss, const AST_NodePtr &t_node, const std::vector<std::string> &t_param_names, const std::vector<Boxed_Value> &t_vals) {
|
||||||
t_ss.new_scope();
|
detail::Scope_Push_Pop spp(t_ss);
|
||||||
|
|
||||||
for (unsigned int i = 0; i < t_param_names.size(); ++i) {
|
for (unsigned int i = 0; i < t_param_names.size(); ++i) {
|
||||||
t_ss.add_object(t_param_names[i], t_vals[i]);
|
t_ss.add_object(t_param_names[i], t_vals[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Boxed_Value retval(t_node->eval(t_ss));
|
return t_node->eval(t_ss);
|
||||||
t_ss.pop_scope();
|
|
||||||
return retval;
|
|
||||||
} catch (const detail::Return_Value &rv) {
|
} catch (const detail::Return_Value &rv) {
|
||||||
t_ss.pop_scope();
|
|
||||||
return rv.retval;
|
return rv.retval;
|
||||||
} catch (exception::eval_error &ee) {
|
} catch (exception::eval_error &ee) {
|
||||||
ee.call_stack.push_back(t_node);
|
ee.call_stack.push_back(t_node);
|
||||||
t_ss.pop_scope();
|
|
||||||
throw;
|
|
||||||
} catch (...) {
|
|
||||||
t_ss.pop_scope();
|
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -89,7 +82,8 @@ namespace chaiscript
|
|||||||
struct Int_AST_Node : public AST_Node {
|
struct Int_AST_Node : public AST_Node {
|
||||||
public:
|
public:
|
||||||
Int_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Int, 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) :
|
Int_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Int, 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), m_value(const_var(int(atoi(this->text.c_str())))) { }
|
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())))) { }
|
||||||
virtual ~Int_AST_Node() {}
|
virtual ~Int_AST_Node() {}
|
||||||
virtual Boxed_Value eval(chaiscript::detail::Dispatch_Engine &){
|
virtual Boxed_Value eval(chaiscript::detail::Dispatch_Engine &){
|
||||||
return m_value;
|
return m_value;
|
||||||
@@ -577,35 +571,28 @@ 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) { }
|
||||||
virtual ~Block_AST_Node() {}
|
virtual ~Block_AST_Node() {}
|
||||||
virtual Boxed_Value eval(chaiscript::detail::Dispatch_Engine &t_ss){
|
virtual Boxed_Value eval(chaiscript::detail::Dispatch_Engine &t_ss){
|
||||||
size_t num_children = this->children.size();
|
const size_t num_children = this->children.size();
|
||||||
|
|
||||||
|
detail::Scope_Push_Pop spp(t_ss);
|
||||||
|
|
||||||
t_ss.new_scope();
|
|
||||||
for (size_t i = 0; i < num_children; ++i) {
|
for (size_t i = 0; i < num_children; ++i) {
|
||||||
try {
|
try {
|
||||||
const Boxed_Value &retval = this->children[i]->eval(t_ss);
|
const Boxed_Value &retval = this->children[i]->eval(t_ss);
|
||||||
|
|
||||||
if (i + 1 == num_children)
|
if (i + 1 == num_children)
|
||||||
{
|
{
|
||||||
t_ss.pop_scope();
|
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (const chaiscript::detail::Return_Value &) {
|
catch (const chaiscript::detail::Return_Value &) {
|
||||||
t_ss.pop_scope();
|
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
catch (exception::eval_error &ee) {
|
catch (exception::eval_error &ee) {
|
||||||
ee.call_stack.push_back(this->children[i]);
|
ee.call_stack.push_back(this->children[i]);
|
||||||
t_ss.pop_scope();
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
catch (...) {
|
|
||||||
t_ss.pop_scope();
|
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
t_ss.pop_scope();
|
|
||||||
return Boxed_Value();
|
return Boxed_Value();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -673,18 +660,16 @@ namespace chaiscript
|
|||||||
virtual Boxed_Value eval(chaiscript::detail::Dispatch_Engine &t_ss) {
|
virtual Boxed_Value eval(chaiscript::detail::Dispatch_Engine &t_ss) {
|
||||||
bool cond;
|
bool cond;
|
||||||
|
|
||||||
t_ss.new_scope();
|
detail::Scope_Push_Pop spp(t_ss);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
cond = boxed_cast<bool>(this->children[0]->eval(t_ss));
|
cond = boxed_cast<bool>(this->children[0]->eval(t_ss));
|
||||||
}
|
}
|
||||||
catch (const exception::bad_boxed_cast &) {
|
catch (const exception::bad_boxed_cast &) {
|
||||||
t_ss.pop_scope();
|
|
||||||
throw exception::eval_error("While condition not boolean");
|
throw exception::eval_error("While condition not boolean");
|
||||||
}
|
}
|
||||||
catch (exception::eval_error &ee) {
|
catch (exception::eval_error &ee) {
|
||||||
ee.call_stack.push_back(this->children[0]);
|
ee.call_stack.push_back(this->children[0]);
|
||||||
t_ss.pop_scope();
|
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
while (cond) {
|
while (cond) {
|
||||||
@@ -701,12 +686,10 @@ namespace chaiscript
|
|||||||
cond = boxed_cast<bool>(this->children[0]->eval(t_ss));
|
cond = boxed_cast<bool>(this->children[0]->eval(t_ss));
|
||||||
}
|
}
|
||||||
catch (const exception::bad_boxed_cast &) {
|
catch (const exception::bad_boxed_cast &) {
|
||||||
t_ss.pop_scope();
|
|
||||||
throw exception::eval_error("While condition not boolean");
|
throw exception::eval_error("While condition not boolean");
|
||||||
}
|
}
|
||||||
catch (exception::eval_error &ee) {
|
catch (exception::eval_error &ee) {
|
||||||
ee.call_stack.push_back(this->children[0]);
|
ee.call_stack.push_back(this->children[0]);
|
||||||
t_ss.pop_scope();
|
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -714,10 +697,9 @@ namespace chaiscript
|
|||||||
cond = false;
|
cond = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
t_ss.pop_scope();
|
|
||||||
return Boxed_Value();
|
return Boxed_Value();
|
||||||
}
|
}
|
||||||
;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct If_AST_Node : public AST_Node {
|
struct If_AST_Node : public AST_Node {
|
||||||
@@ -799,7 +781,7 @@ namespace chaiscript
|
|||||||
virtual Boxed_Value eval(chaiscript::detail::Dispatch_Engine &t_ss){
|
virtual Boxed_Value eval(chaiscript::detail::Dispatch_Engine &t_ss){
|
||||||
bool cond;
|
bool cond;
|
||||||
|
|
||||||
t_ss.new_scope();
|
detail::Scope_Push_Pop spp(t_ss);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (this->children.size() == 4) {
|
if (this->children.size() == 4) {
|
||||||
@@ -825,13 +807,11 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
catch (exception::eval_error &ee) {
|
catch (exception::eval_error &ee) {
|
||||||
ee.call_stack.push_back(this->children[0]);
|
ee.call_stack.push_back(this->children[0]);
|
||||||
t_ss.pop_scope();
|
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (const exception::bad_boxed_cast &) {
|
catch (const exception::bad_boxed_cast &) {
|
||||||
t_ss.pop_scope();
|
|
||||||
throw exception::eval_error("For condition not boolean");
|
throw exception::eval_error("For condition not boolean");
|
||||||
}
|
}
|
||||||
while (cond) {
|
while (cond) {
|
||||||
@@ -883,20 +863,17 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
catch (exception::eval_error &ee) {
|
catch (exception::eval_error &ee) {
|
||||||
ee.call_stack.push_back(this->children[0]);
|
ee.call_stack.push_back(this->children[0]);
|
||||||
t_ss.pop_scope();
|
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (const exception::bad_boxed_cast &) {
|
catch (const exception::bad_boxed_cast &) {
|
||||||
t_ss.pop_scope();
|
|
||||||
throw exception::eval_error("For condition not boolean");
|
throw exception::eval_error("For condition not boolean");
|
||||||
}
|
}
|
||||||
catch (detail::Break_Loop &) {
|
catch (detail::Break_Loop &) {
|
||||||
cond = false;
|
cond = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
t_ss.pop_scope();
|
|
||||||
return Boxed_Value();
|
return Boxed_Value();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1075,7 +1052,8 @@ namespace chaiscript
|
|||||||
virtual Boxed_Value eval(chaiscript::detail::Dispatch_Engine &t_ss){
|
virtual Boxed_Value eval(chaiscript::detail::Dispatch_Engine &t_ss){
|
||||||
Boxed_Value retval;
|
Boxed_Value retval;
|
||||||
|
|
||||||
t_ss.new_scope();
|
detail::Scope_Push_Pop spp(t_ss);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
retval = this->children[0]->eval(t_ss);
|
retval = this->children[0]->eval(t_ss);
|
||||||
}
|
}
|
||||||
@@ -1087,11 +1065,9 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
catch (exception::eval_error &ee2) {
|
catch (exception::eval_error &ee2) {
|
||||||
ee2.call_stack.push_back(this->children.back()->children[0]);
|
ee2.call_stack.push_back(this->children.back()->children[0]);
|
||||||
t_ss.pop_scope();
|
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
t_ss.pop_scope();
|
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
catch (const std::exception &e) {
|
catch (const std::exception &e) {
|
||||||
@@ -1143,11 +1119,9 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
catch (exception::eval_error &ee) {
|
catch (exception::eval_error &ee) {
|
||||||
ee.call_stack.push_back(this->children.back()->children[0]);
|
ee.call_stack.push_back(this->children.back()->children[0]);
|
||||||
t_ss.pop_scope();
|
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
t_ss.pop_scope();
|
|
||||||
throw exception::eval_error("Guard condition not boolean");
|
throw exception::eval_error("Guard condition not boolean");
|
||||||
}
|
}
|
||||||
if (guard) {
|
if (guard) {
|
||||||
@@ -1169,17 +1143,14 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
catch (exception::eval_error &ee) {
|
catch (exception::eval_error &ee) {
|
||||||
ee.call_stack.push_back(this->children.back()->children[0]);
|
ee.call_stack.push_back(this->children.back()->children[0]);
|
||||||
t_ss.pop_scope();
|
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
t_ss.pop_scope();
|
|
||||||
throw exception::eval_error("Internal error: catch block size unrecognized");
|
throw exception::eval_error("Internal error: catch block size unrecognized");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Boxed_Value &bv) {
|
catch (Boxed_Value &except) {
|
||||||
Boxed_Value except = bv;
|
|
||||||
for (size_t i = 1; i < this->children.size(); ++i) {
|
for (size_t i = 1; i < this->children.size(); ++i) {
|
||||||
AST_NodePtr catch_block = this->children[i];
|
AST_NodePtr catch_block = this->children[i];
|
||||||
|
|
||||||
@@ -1223,12 +1194,10 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
catch (exception::eval_error &ee) {
|
catch (exception::eval_error &ee) {
|
||||||
ee.call_stack.push_back(this->children.back()->children[0]);
|
ee.call_stack.push_back(this->children.back()->children[0]);
|
||||||
t_ss.pop_scope();
|
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
t_ss.pop_scope();
|
|
||||||
throw exception::eval_error("Guard condition not boolean");
|
throw exception::eval_error("Guard condition not boolean");
|
||||||
}
|
}
|
||||||
catch (exception::eval_error &ee) {
|
catch (exception::eval_error &ee) {
|
||||||
@@ -1253,11 +1222,9 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
catch (exception::eval_error &ee) {
|
catch (exception::eval_error &ee) {
|
||||||
ee.call_stack.push_back(this->children.back()->children[0]);
|
ee.call_stack.push_back(this->children.back()->children[0]);
|
||||||
t_ss.pop_scope();
|
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
t_ss.pop_scope();
|
|
||||||
throw exception::eval_error("Internal error: catch block size unrecognized");
|
throw exception::eval_error("Internal error: catch block size unrecognized");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1269,11 +1236,9 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
catch (exception::eval_error &ee) {
|
catch (exception::eval_error &ee) {
|
||||||
ee.call_stack.push_back(this->children.back()->children[0]);
|
ee.call_stack.push_back(this->children.back()->children[0]);
|
||||||
t_ss.pop_scope();
|
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
t_ss.pop_scope();
|
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1283,13 +1248,10 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
catch (exception::eval_error &ee) {
|
catch (exception::eval_error &ee) {
|
||||||
ee.call_stack.push_back(this->children.back()->children[0]);
|
ee.call_stack.push_back(this->children.back()->children[0]);
|
||||||
t_ss.pop_scope();
|
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
t_ss.pop_scope();
|
|
||||||
|
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user