Optimize loops better.

This commit is contained in:
Stephen Chung 2021-08-04 17:40:26 +08:00
parent 4807fdf1cf
commit 9b56c1ba78
2 changed files with 25 additions and 7 deletions

View File

@ -2542,15 +2542,30 @@ impl Engine {
})
}
// Loop
Stmt::While(Expr::Unit(_), body, _) => loop {
if !body.is_empty() {
match self.eval_stmt_block(scope, mods, state, lib, this_ptr, body, true, level)
{
Ok(_) => (),
Err(err) => match *err {
EvalAltResult::LoopBreak(false, _) => (),
EvalAltResult::LoopBreak(true, _) => return Ok(Dynamic::UNIT),
_ => return Err(err),
},
}
} else {
#[cfg(not(feature = "unchecked"))]
self.inc_operations(state, body.position())?;
}
},
// While loop
Stmt::While(expr, body, _) => loop {
let condition = if !expr.is_unit() {
self.eval_expr(scope, mods, state, lib, this_ptr, expr, level)?
.as_bool()
.map_err(|typ| self.make_type_mismatch_err::<bool>(typ, expr.position()))?
} else {
true
};
let condition = self
.eval_expr(scope, mods, state, lib, this_ptr, expr, level)?
.as_bool()
.map_err(|typ| self.make_type_mismatch_err::<bool>(typ, expr.position()))?;
if !condition {
return Ok(Dynamic::UNIT);

View File

@ -559,6 +559,9 @@ fn optimize_stmt(stmt: &mut Stmt, state: &mut OptimizerState, preserve_result: b
// while expr { block }
Stmt::While(condition, body, _) => {
optimize_expr(condition, state, false);
if let Expr::BoolConstant(true, pos) = condition {
*condition = Expr::Unit(*pos);
}
let block = mem::take(body.statements_mut()).into_vec();
*body.statements_mut() = optimize_stmt_block(block, state, false, true, false).into();