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
This commit is contained in:
Jason Turner 2016-10-28 10:56:12 -06:00
parent 77231461ca
commit a38b254a98
3 changed files with 15 additions and 14 deletions

View File

@ -1313,11 +1313,8 @@ namespace chaiscript
try { try {
retval = this->children[0]->eval(t_ss); retval = this->children[0]->eval(t_ss);
} }
catch (exception::eval_error &) { catch (const exception::eval_error &e) {
if (this->children.back()->identifier == AST_Node_Type::Finally) { retval = handle_exception(t_ss, Boxed_Value(std::ref(e)));
this->children.back()->children[0]->eval(t_ss);
}
throw;
} }
catch (const std::runtime_error &e) { catch (const std::runtime_error &e) {
retval = handle_exception(t_ss, Boxed_Value(std::ref(e))); retval = handle_exception(t_ss, Boxed_Value(std::ref(e)));

View File

@ -1700,12 +1700,16 @@ namespace chaiscript
} }
/// Reads a class block from input /// Reads a class block from input
bool Class() { bool Class(const bool t_class_allowed) {
bool retval = false; bool retval = false;
size_t prev_stack_top = m_match_stack.size(); size_t prev_stack_top = m_match_stack.size();
if (Keyword("class")) { 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; retval = true;
if (!Id()) { if (!Id()) {
@ -2375,7 +2379,7 @@ namespace chaiscript
} }
/// Top level parser, starts parsing of all known parses /// Top level parser, starts parsing of all known parses
bool Statements() { bool Statements(const bool t_class_allowed = false) {
bool retval = false; bool retval = false;
bool has_more = true; bool has_more = true;
@ -2383,7 +2387,7 @@ namespace chaiscript
while (has_more) { while (has_more) {
const auto start = m_position; 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) { if (!saw_eol) {
throw exception::eval_error("Two function definitions missing line separator", File_Position(start.line, start.col), *m_filename); 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) /// \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()) { if (m_position.has_more()) {
throw exception::eval_error("Unparsed input", File_Position(m_position.line, m_position.col), t_fname); throw exception::eval_error("Unparsed input", File_Position(m_position.line, m_position.col), t_fname);
} else { } else {

View File

@ -1,8 +1,8 @@
{ try {
class C { parse("{ class C { var data; def C() {} } }")
var data; assert_false(true)
def C() {} } catch (e) {
} assert_true(true)
} }