From a38b254a981776d14b46cfacf4d84188d7b4a378 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Fri, 28 Oct 2016 10:56:12 -0600 Subject: [PATCH] Only allow `class` in top level scope * Throw error if class is in unexpected place * Allow catching of `eval_error` from inside of script closes #297 --- include/chaiscript/language/chaiscript_eval.hpp | 7 ++----- include/chaiscript/language/chaiscript_parser.hpp | 12 ++++++++---- unittests/class_inside_scope.chai | 10 +++++----- 3 files changed, 15 insertions(+), 14 deletions(-) diff --git a/include/chaiscript/language/chaiscript_eval.hpp b/include/chaiscript/language/chaiscript_eval.hpp index ae26fec..4488022 100644 --- a/include/chaiscript/language/chaiscript_eval.hpp +++ b/include/chaiscript/language/chaiscript_eval.hpp @@ -1313,11 +1313,8 @@ namespace chaiscript try { retval = this->children[0]->eval(t_ss); } - catch (exception::eval_error &) { - if (this->children.back()->identifier == AST_Node_Type::Finally) { - this->children.back()->children[0]->eval(t_ss); - } - throw; + catch (const exception::eval_error &e) { + retval = handle_exception(t_ss, Boxed_Value(std::ref(e))); } catch (const std::runtime_error &e) { retval = handle_exception(t_ss, Boxed_Value(std::ref(e))); diff --git a/include/chaiscript/language/chaiscript_parser.hpp b/include/chaiscript/language/chaiscript_parser.hpp index 769c631..3588c07 100644 --- a/include/chaiscript/language/chaiscript_parser.hpp +++ b/include/chaiscript/language/chaiscript_parser.hpp @@ -1700,12 +1700,16 @@ namespace chaiscript } /// Reads a class block from input - bool Class() { + bool Class(const bool t_class_allowed) { bool retval = false; size_t prev_stack_top = m_match_stack.size(); if (Keyword("class")) { + if (!t_class_allowed) { + throw exception::eval_error("Class definitions only allowed at top scope", File_Position(m_position.line, m_position.col), *m_filename); + } + retval = true; if (!Id()) { @@ -2375,7 +2379,7 @@ namespace chaiscript } /// Top level parser, starts parsing of all known parses - bool Statements() { + bool Statements(const bool t_class_allowed = false) { bool retval = false; bool has_more = true; @@ -2383,7 +2387,7 @@ namespace chaiscript while (has_more) { const auto start = m_position; - if (Def() || Try() || If() || While() || Class() || For() || Switch()) { + if (Def() || Try() || If() || While() || Class(t_class_allowed) || For() || Switch()) { if (!saw_eol) { throw exception::eval_error("Two function definitions missing line separator", File_Position(start.line, start.col), *m_filename); } @@ -2424,7 +2428,7 @@ namespace chaiscript /// \todo respect // -*- coding: utf-8 -*- on line 1 or 2 see: http://evanjones.ca/python-utf8.html) } - if (Statements()) { + if (Statements(true)) { if (m_position.has_more()) { throw exception::eval_error("Unparsed input", File_Position(m_position.line, m_position.col), t_fname); } else { diff --git a/unittests/class_inside_scope.chai b/unittests/class_inside_scope.chai index 30d21c1..27fe806 100644 --- a/unittests/class_inside_scope.chai +++ b/unittests/class_inside_scope.chai @@ -1,8 +1,8 @@ -{ - class C { - var data; - def C() {} - } +try { + parse("{ class C { var data; def C() {} } }") + assert_false(true) +} catch (e) { + assert_true(true) }