From de5822873b9831361256441df7d62b9f605d1541 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Sun, 27 Mar 2011 10:03:37 -0600 Subject: [PATCH] Use RAII for scope management Possibly fixes a few bugs where scope pops where missed. --- .../chaiscript/language/chaiscript_common.hpp | 21 +++++- .../chaiscript/language/chaiscript_eval.hpp | 66 ++++--------------- 2 files changed, 34 insertions(+), 53 deletions(-) diff --git a/include/chaiscript/language/chaiscript_common.hpp b/include/chaiscript/language/chaiscript_common.hpp index 8eee132..176c599 100644 --- a/include/chaiscript/language/chaiscript_common.hpp +++ b/include/chaiscript/language/chaiscript_common.hpp @@ -90,7 +90,6 @@ namespace chaiscript virtual Boxed_Value eval(chaiscript::detail::Dispatch_Engine &) { - Boxed_Value bv; throw std::runtime_error("Undispatched ast_node (internal error)"); } @@ -175,6 +174,26 @@ namespace chaiscript struct 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; + }; + } } diff --git a/include/chaiscript/language/chaiscript_eval.hpp b/include/chaiscript/language/chaiscript_eval.hpp index d918016..729fa9d 100644 --- a/include/chaiscript/language/chaiscript_eval.hpp +++ b/include/chaiscript/language/chaiscript_eval.hpp @@ -18,27 +18,20 @@ namespace chaiscript */ template const Boxed_Value eval_function (Eval_System &t_ss, const AST_NodePtr &t_node, const std::vector &t_param_names, const std::vector &t_vals) { - t_ss.new_scope(); + detail::Scope_Push_Pop spp(t_ss); for (unsigned int i = 0; i < t_param_names.size(); ++i) { t_ss.add_object(t_param_names[i], t_vals[i]); } try { - Boxed_Value retval(t_node->eval(t_ss)); - t_ss.pop_scope(); - return retval; + return t_node->eval(t_ss); } catch (const detail::Return_Value &rv) { - t_ss.pop_scope(); return rv.retval; } catch (exception::eval_error &ee) { ee.call_stack.push_back(t_node); - t_ss.pop_scope(); throw; - } catch (...) { - t_ss.pop_scope(); - throw; - } + } } @@ -89,7 +82,8 @@ namespace chaiscript struct Int_AST_Node : public AST_Node { public: Int_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Int, const boost::shared_ptr &t_fname=boost::shared_ptr(), 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 Boxed_Value eval(chaiscript::detail::Dispatch_Engine &){ 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) { } virtual ~Block_AST_Node() {} 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) { try { const Boxed_Value &retval = this->children[i]->eval(t_ss); if (i + 1 == num_children) { - t_ss.pop_scope(); return retval; } } catch (const chaiscript::detail::Return_Value &) { - t_ss.pop_scope(); throw; } catch (exception::eval_error &ee) { ee.call_stack.push_back(this->children[i]); - t_ss.pop_scope(); - throw; - } - catch (...) { - t_ss.pop_scope(); throw; } } - t_ss.pop_scope(); return Boxed_Value(); } @@ -673,18 +660,16 @@ namespace chaiscript virtual Boxed_Value eval(chaiscript::detail::Dispatch_Engine &t_ss) { bool cond; - t_ss.new_scope(); + detail::Scope_Push_Pop spp(t_ss); try { cond = boxed_cast(this->children[0]->eval(t_ss)); } catch (const exception::bad_boxed_cast &) { - t_ss.pop_scope(); throw exception::eval_error("While condition not boolean"); } catch (exception::eval_error &ee) { ee.call_stack.push_back(this->children[0]); - t_ss.pop_scope(); throw; } while (cond) { @@ -701,12 +686,10 @@ namespace chaiscript cond = boxed_cast(this->children[0]->eval(t_ss)); } catch (const exception::bad_boxed_cast &) { - t_ss.pop_scope(); throw exception::eval_error("While condition not boolean"); } catch (exception::eval_error &ee) { ee.call_stack.push_back(this->children[0]); - t_ss.pop_scope(); throw; } } @@ -714,10 +697,9 @@ namespace chaiscript cond = false; } } - t_ss.pop_scope(); return Boxed_Value(); } - ; + }; struct If_AST_Node : public AST_Node { @@ -799,7 +781,7 @@ namespace chaiscript virtual Boxed_Value eval(chaiscript::detail::Dispatch_Engine &t_ss){ bool cond; - t_ss.new_scope(); + detail::Scope_Push_Pop spp(t_ss); try { if (this->children.size() == 4) { @@ -825,13 +807,11 @@ namespace chaiscript } catch (exception::eval_error &ee) { ee.call_stack.push_back(this->children[0]); - t_ss.pop_scope(); throw; } } } catch (const exception::bad_boxed_cast &) { - t_ss.pop_scope(); throw exception::eval_error("For condition not boolean"); } while (cond) { @@ -883,20 +863,17 @@ namespace chaiscript } catch (exception::eval_error &ee) { ee.call_stack.push_back(this->children[0]); - t_ss.pop_scope(); throw; } } } catch (const exception::bad_boxed_cast &) { - t_ss.pop_scope(); throw exception::eval_error("For condition not boolean"); } catch (detail::Break_Loop &) { cond = false; } } - t_ss.pop_scope(); return Boxed_Value(); } @@ -1075,7 +1052,8 @@ namespace chaiscript virtual Boxed_Value eval(chaiscript::detail::Dispatch_Engine &t_ss){ Boxed_Value retval; - t_ss.new_scope(); + detail::Scope_Push_Pop spp(t_ss); + try { retval = this->children[0]->eval(t_ss); } @@ -1087,11 +1065,9 @@ namespace chaiscript } catch (exception::eval_error &ee2) { ee2.call_stack.push_back(this->children.back()->children[0]); - t_ss.pop_scope(); throw; } } - t_ss.pop_scope(); throw; } catch (const std::exception &e) { @@ -1143,11 +1119,9 @@ namespace chaiscript } catch (exception::eval_error &ee) { ee.call_stack.push_back(this->children.back()->children[0]); - t_ss.pop_scope(); throw; } } - t_ss.pop_scope(); throw exception::eval_error("Guard condition not boolean"); } if (guard) { @@ -1169,17 +1143,14 @@ namespace chaiscript } catch (exception::eval_error &ee) { ee.call_stack.push_back(this->children.back()->children[0]); - t_ss.pop_scope(); throw; } } - t_ss.pop_scope(); throw exception::eval_error("Internal error: catch block size unrecognized"); } } } - catch (Boxed_Value &bv) { - Boxed_Value except = bv; + catch (Boxed_Value &except) { for (size_t i = 1; i < this->children.size(); ++i) { AST_NodePtr catch_block = this->children[i]; @@ -1223,12 +1194,10 @@ namespace chaiscript } catch (exception::eval_error &ee) { ee.call_stack.push_back(this->children.back()->children[0]); - t_ss.pop_scope(); throw; } } - t_ss.pop_scope(); throw exception::eval_error("Guard condition not boolean"); } catch (exception::eval_error &ee) { @@ -1253,11 +1222,9 @@ namespace chaiscript } catch (exception::eval_error &ee) { ee.call_stack.push_back(this->children.back()->children[0]); - t_ss.pop_scope(); throw; } } - t_ss.pop_scope(); throw exception::eval_error("Internal error: catch block size unrecognized"); } } @@ -1269,11 +1236,9 @@ namespace chaiscript } catch (exception::eval_error &ee) { ee.call_stack.push_back(this->children.back()->children[0]); - t_ss.pop_scope(); throw; } } - t_ss.pop_scope(); throw; } @@ -1283,13 +1248,10 @@ namespace chaiscript } catch (exception::eval_error &ee) { ee.call_stack.push_back(this->children.back()->children[0]); - t_ss.pop_scope(); throw; } } - t_ss.pop_scope(); - return retval; }