Clean up implementation of for and while loops to make them easier to read and reduce code copying
This commit is contained in:
@@ -791,18 +791,10 @@ 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 ~While_AST_Node() {}
|
virtual ~While_AST_Node() {}
|
||||||
virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &t_ss) {
|
virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &t_ss) {
|
||||||
bool cond;
|
|
||||||
|
|
||||||
chaiscript::eval::detail::Scope_Push_Pop spp(t_ss);
|
chaiscript::eval::detail::Scope_Push_Pop spp(t_ss);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
cond = boxed_cast<bool>(this->children[0]->eval(t_ss));
|
while (boxed_cast<bool>(this->children[0]->eval(t_ss))) {
|
||||||
}
|
|
||||||
catch (const exception::bad_boxed_cast &) {
|
|
||||||
throw exception::eval_error("While condition not boolean");
|
|
||||||
}
|
|
||||||
while (cond) {
|
|
||||||
try {
|
|
||||||
try {
|
try {
|
||||||
this->children[1]->eval(t_ss);
|
this->children[1]->eval(t_ss);
|
||||||
} catch (detail::Continue_Loop &) {
|
} catch (detail::Continue_Loop &) {
|
||||||
@@ -810,18 +802,13 @@ namespace chaiscript
|
|||||||
// loop implementation is skipped and we just need to continue to
|
// loop implementation is skipped and we just need to continue to
|
||||||
// the next condition test
|
// the next condition test
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
|
||||||
cond = boxed_cast<bool>(this->children[0]->eval(t_ss));
|
|
||||||
}
|
|
||||||
catch (const exception::bad_boxed_cast &) {
|
|
||||||
throw exception::eval_error("While condition not boolean");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (detail::Break_Loop &) {
|
|
||||||
cond = false;
|
|
||||||
}
|
}
|
||||||
|
} catch (const exception::bad_boxed_cast &) {
|
||||||
|
throw exception::eval_error("While condition not boolean");
|
||||||
|
} catch (detail::Break_Loop &) {
|
||||||
|
// loop was broken intentionally
|
||||||
}
|
}
|
||||||
|
|
||||||
return Boxed_Value();
|
return Boxed_Value();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -838,7 +825,7 @@ 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 &) {
|
||||||
throw exception::eval_error("If condition not boolean");
|
throw exception::eval_error("Ternary if condition not boolean");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cond) {
|
if (cond) {
|
||||||
@@ -901,59 +888,34 @@ 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 ~For_AST_Node() {}
|
virtual ~For_AST_Node() {}
|
||||||
virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &t_ss){
|
virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &t_ss){
|
||||||
bool cond;
|
|
||||||
|
|
||||||
chaiscript::eval::detail::Scope_Push_Pop spp(t_ss);
|
chaiscript::eval::detail::Scope_Push_Pop spp(t_ss);
|
||||||
|
|
||||||
try {
|
// initial expression
|
||||||
if (this->children.size() == 4) {
|
this->children[0]->eval(t_ss);
|
||||||
this->children[0]->eval(t_ss);
|
|
||||||
|
|
||||||
cond = boxed_cast<bool>(this->children[1]->eval(t_ss));
|
try {
|
||||||
} else {
|
// while condition evals to true
|
||||||
cond = boxed_cast<bool>(this->children[0]->eval(t_ss));
|
while (boxed_cast<bool>(this->children[1]->eval(t_ss))) {
|
||||||
|
try {
|
||||||
|
// Body of Loop
|
||||||
|
this->children[3]->eval(t_ss);
|
||||||
|
} catch (detail::Continue_Loop &) {
|
||||||
|
// we got a continue exception, which means all of the remaining
|
||||||
|
// loop implementation is skipped and we just need to continue to
|
||||||
|
// the next iteration step
|
||||||
|
}
|
||||||
|
|
||||||
|
// loop expression
|
||||||
|
this->children[2]->eval(t_ss);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (const exception::bad_boxed_cast &) {
|
catch (const exception::bad_boxed_cast &) {
|
||||||
throw exception::eval_error("For condition not boolean");
|
throw exception::eval_error("For condition not boolean");
|
||||||
}
|
}
|
||||||
while (cond) {
|
catch (detail::Break_Loop &) {
|
||||||
try {
|
// loop broken
|
||||||
if (this->children.size() == 4) {
|
|
||||||
|
|
||||||
try {
|
|
||||||
this->children[3]->eval(t_ss);
|
|
||||||
} catch (detail::Continue_Loop &) {
|
|
||||||
// we got a continue exception, which means all of the remaining
|
|
||||||
// loop implementation is skipped and we just need to continue to
|
|
||||||
// the next iteration step
|
|
||||||
}
|
|
||||||
|
|
||||||
this->children[2]->eval(t_ss);
|
|
||||||
|
|
||||||
cond = boxed_cast<bool>(this->children[1]->eval(t_ss));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
try {
|
|
||||||
this->children[2]->eval(t_ss);
|
|
||||||
} catch (detail::Continue_Loop &) {
|
|
||||||
// we got a continue exception, which means all of the remaining
|
|
||||||
// loop implementation is skipped and we just need to continue to
|
|
||||||
// the next iteration step
|
|
||||||
}
|
|
||||||
|
|
||||||
this->children[1]->eval(t_ss);
|
|
||||||
|
|
||||||
cond = boxed_cast<bool>(this->children[0]->eval(t_ss));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (const exception::bad_boxed_cast &) {
|
|
||||||
throw exception::eval_error("For condition not boolean");
|
|
||||||
}
|
|
||||||
catch (detail::Break_Loop &) {
|
|
||||||
cond = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return Boxed_Value();
|
return Boxed_Value();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1122,6 +1084,7 @@ namespace chaiscript
|
|||||||
|
|
||||||
Operators::Opers oper = Operators::to_operator(children[0]->text, true);
|
Operators::Opers oper = Operators::to_operator(children[0]->text, true);
|
||||||
try {
|
try {
|
||||||
|
// short circuit arithmetic operations
|
||||||
if (bv.get_type_info().is_arithmetic() && oper != Operators::invalid)
|
if (bv.get_type_info().is_arithmetic() && oper != Operators::invalid)
|
||||||
{
|
{
|
||||||
return Boxed_Number::do_oper(oper, bv);
|
return Boxed_Number::do_oper(oper, bv);
|
||||||
|
Reference in New Issue
Block a user