Correct scope of operator calls

- Enhance reflection module to indicate inheritance
  - Add ability to catch errors thrown from a eval
    inside of a script
This commit is contained in:
Jason Turner 2012-05-24 19:25:29 -06:00
parent f65e095e4d
commit 4233d21e5b
5 changed files with 42 additions and 17 deletions

View File

@ -274,7 +274,11 @@ namespace chaiscript
const Boxed_Value internal_eval_ast(const AST_NodePtr &t_ast)
{
return t_ast->eval(m_engine);
try {
return t_ast->eval(m_engine);
} catch (const exception::eval_error &t_ee) {
throw Boxed_Value(t_ee);
}
}
@ -282,7 +286,11 @@ namespace chaiscript
* Evaluates the given string, used during eval() inside of a script
*/
const Boxed_Value internal_eval(const std::string &t_e) {
return do_eval(t_e, "__EVAL__", true);
try {
return do_eval(t_e, "__EVAL__", true);
} catch (const exception::eval_error &t_ee) {
throw Boxed_Value(t_ee);
}
}
@ -298,6 +306,7 @@ namespace chaiscript
*/
void build_eval_system() {
using namespace bootstrap;
m_engine.add_reserved_word("auto");
m_engine.add_reserved_word("def");
m_engine.add_reserved_word("fun");
m_engine.add_reserved_word("while");

View File

@ -54,6 +54,12 @@ namespace chaiscript
Operators::Opers t_oper, const std::string &t_oper_string, const Boxed_Value &t_lhs, const Boxed_Value &t_rhs)
{
try {
chaiscript::eval::detail::Function_Push_Pop fpp(t_ss);
std::vector<Boxed_Value> params(2);
params.push_back(t_lhs);
params.push_back(t_rhs);
fpp.save_params(params);
if (t_oper != Operators::invalid && t_lhs.get_type_info().is_arithmetic() && t_rhs.get_type_info().is_arithmetic())
{
// If it's an arithmetic operation we want to short circuit dispatch
@ -64,6 +70,7 @@ namespace chaiscript
}
} else {
chaiscript::eval::detail::Stack_Push_Pop spp(t_ss);
return t_ss.call_function(t_oper_string, t_lhs, t_rhs);
}
}
@ -406,11 +413,20 @@ 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 ~Array_Call_AST_Node() {}
virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &t_ss){
chaiscript::eval::detail::Function_Push_Pop fpp(t_ss);
Boxed_Value retval = this->children[0]->eval(t_ss);
std::vector<Boxed_Value> params;
params.push_back(retval);
for (size_t i = 1; i < this->children.size(); ++i) {
try {
retval = t_ss.call_function("[]", retval, this->children[i]->eval(t_ss));
Boxed_Value p1(this->children[i]->eval(t_ss));
chaiscript::eval::detail::Stack_Push_Pop spp(t_ss);
params.push_back(p1);
fpp.save_params(params);
params.clear();
retval = t_ss.call_function("[]", retval, p1);
}
catch(std::out_of_range &) {
throw exception::eval_error("Out of bounds exception");
@ -940,6 +956,7 @@ namespace chaiscript
virtual ~Prefix_AST_Node() {}
virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &t_ss){
chaiscript::eval::detail::Function_Push_Pop fpp(t_ss);
Boxed_Value bv(this->children[1]->eval(t_ss));
Operators::Opers oper = Operators::to_operator(children[0]->text, true);
@ -948,6 +965,10 @@ namespace chaiscript
{
return Boxed_Number::do_oper(oper, bv);
} else {
chaiscript::eval::detail::Stack_Push_Pop spp(t_ss);
std::vector<Boxed_Value> params;
params.push_back(bv);
fpp.save_params(params);
return t_ss.call_function(this->children[0]->text, bv);
}
} catch (const exception::dispatch_error &) {

View File

@ -49,6 +49,7 @@ CHAISCRIPT_MODULE_EXPORT chaiscript::ModulePtr create_chaiscript_module_reflect
m->add(chaiscript::fun(&has_parse_tree), "has_parse_tree");
m->add(chaiscript::fun(&get_parse_tree), "get_parse_tree");
m->add(chaiscript::base_class<std::exception, chaiscript::exception::eval_error>());
chaiscript::bootstrap::standard_library::vector_type<std::vector<boost::shared_ptr<chaiscript::AST_Node> > >("AST_NodeVector", m);

View File

@ -1,14 +1,8 @@
def `+`(x, y)
{
print(i);
load_module("reflection")
try {
eval("def `+`(x, y) \n { \n print(i); \n } \n \n var i = 10; \n \"1\" + 1;\n")
assert_false(true); // we should never get here
} catch (e) {
assert_equal("Error: \"Can not find object: i\" ", e.what());
}
auto i = 10;
// It should fail because `+` should not be able to see the i
"1" + 1;
assert_false(true);

View File

@ -5,7 +5,7 @@ def assert_equal(x, y)
// Passes
} else {
// Fails
print("assert_equal failure: got " + to_string(y) + " expected " + to_string(x));
print("assert_equal failure: got '" + to_string(y) + "' expected '" + to_string(x) + "'");
exit(-1);
}
}