From 9b56c1ba7809716641f6ba172aa82c267de3a326 Mon Sep 17 00:00:00 2001 From: Stephen Chung Date: Wed, 4 Aug 2021 17:40:26 +0800 Subject: [PATCH] Optimize loops better. --- src/engine.rs | 29 ++++++++++++++++++++++------- src/optimize.rs | 3 +++ 2 files changed, 25 insertions(+), 7 deletions(-) diff --git a/src/engine.rs b/src/engine.rs index cdba7f9f..d72b2dac 100644 --- a/src/engine.rs +++ b/src/engine.rs @@ -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::(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::(typ, expr.position()))?; if !condition { return Ok(Dynamic::UNIT); diff --git a/src/optimize.rs b/src/optimize.rs index 3376240e..08f3fadd 100644 --- a/src/optimize.rs +++ b/src/optimize.rs @@ -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();