From e2bd0705b176316f11aa8644ac37cfa2e296bde7 Mon Sep 17 00:00:00 2001 From: Stephen Chung Date: Sun, 4 Dec 2022 22:47:10 +0800 Subject: [PATCH] Refine auto_restore syntax. --- src/api/call_fn.rs | 6 ++++-- src/eval/chaining.rs | 24 +++++++++++++++--------- src/eval/expr.rs | 4 ++-- src/eval/stmt.rs | 28 ++++++++++++++++++---------- src/func/call.rs | 6 +++--- src/types/restore.rs | 26 +++++++++++++++++++++----- tests/call_fn.rs | 2 +- 7 files changed, 64 insertions(+), 32 deletions(-) diff --git a/src/api/call_fn.rs b/src/api/call_fn.rs index d15e7c37..7d248e30 100644 --- a/src/api/call_fn.rs +++ b/src/api/call_fn.rs @@ -238,8 +238,10 @@ impl Engine { let rewind_scope = options.rewind_scope; let result = if options.eval_ast && !statements.is_empty() { - let orig_scope_len = scope.len(); - auto_restore!(scope; rewind_scope => move |s| { s.rewind(orig_scope_len); }); + auto_restore! { + scope if rewind_scope => rewind; + let orig_scope_len = scope.len(); + } self.eval_global_statements(global, caches, scope, statements) } else { diff --git a/src/eval/chaining.rs b/src/eval/chaining.rs index b7cece39..d2008802 100644 --- a/src/eval/chaining.rs +++ b/src/eval/chaining.rs @@ -684,15 +684,17 @@ impl Engine { let reset = self.run_debugger_with_reset(global, caches, scope, this_ptr, rhs)?; #[cfg(feature = "debugging")] - auto_restore!(global; reset.is_some() => move |g| g.debugger_mut().reset_status(reset)); + auto_restore!(global if reset.is_some() => move |g| g.debugger_mut().reset_status(reset)); let crate::ast::FnCallExpr { name, hashes, args, .. } = &**x; // Truncate the index values upon exit - let offset = idx_values.len() - args.len(); - auto_restore!(idx_values => move |v| v.truncate(offset)); + auto_restore! { + idx_values => truncate; + let offset = idx_values.len() - args.len(); + } let call_args = &mut idx_values[offset..]; let arg1_pos = args.get(0).map_or(Position::NONE, Expr::position); @@ -854,15 +856,17 @@ impl Engine { global, caches, scope, this_ptr, _node, )?; #[cfg(feature = "debugging")] - auto_restore!(global; reset.is_some() => move |g| g.debugger_mut().reset_status(reset)); + auto_restore!(global if reset.is_some() => move |g| g.debugger_mut().reset_status(reset)); let crate::ast::FnCallExpr { name, hashes, args, .. } = &**x; // Truncate the index values upon exit - let offset = idx_values.len() - args.len(); - auto_restore!(idx_values => move |v| v.truncate(offset)); + auto_restore! { + idx_values => truncate; + let offset = idx_values.len() - args.len(); + } let call_args = &mut idx_values[offset..]; let arg1_pos = args.get(0).map_or(Position::NONE, Expr::position); @@ -973,15 +977,17 @@ impl Engine { global, caches, scope, this_ptr, _node, )?; #[cfg(feature = "debugging")] - auto_restore!(global; reset.is_some() => move |g| g.debugger_mut().reset_status(reset)); + auto_restore!(global if reset.is_some() => move |g| g.debugger_mut().reset_status(reset)); let crate::ast::FnCallExpr { name, hashes, args, .. } = &**f; // Truncate the index values upon exit - let offset = idx_values.len() - args.len(); - auto_restore!(idx_values => move |v| v.truncate(offset)); + auto_restore! { + idx_values => truncate; + let offset = idx_values.len() - args.len(); + } let call_args = &mut idx_values[offset..]; let pos1 = args.get(0).map_or(Position::NONE, Expr::position); diff --git a/src/eval/expr.rs b/src/eval/expr.rs index 4ed0e4ab..9f104691 100644 --- a/src/eval/expr.rs +++ b/src/eval/expr.rs @@ -234,7 +234,7 @@ impl Engine { #[cfg(feature = "debugging")] let reset = self.run_debugger_with_reset(global, caches, scope, this_ptr, expr)?; #[cfg(feature = "debugging")] - auto_restore!(global; reset.is_some() => move |g| g.debugger_mut().reset_status(reset)); + auto_restore!(global if reset.is_some() => move |g| g.debugger_mut().reset_status(reset)); self.track_operation(global, expr.position())?; @@ -265,7 +265,7 @@ impl Engine { #[cfg(feature = "debugging")] let reset = self.run_debugger_with_reset(global, caches, scope, this_ptr, expr)?; #[cfg(feature = "debugging")] - auto_restore!(global; reset.is_some() => move |g| g.debugger_mut().reset_status(reset)); + auto_restore!(global if reset.is_some() => move |g| g.debugger_mut().reset_status(reset)); self.track_operation(global, expr.position())?; diff --git a/src/eval/stmt.rs b/src/eval/stmt.rs index 50c3cc0e..04681410 100644 --- a/src/eval/stmt.rs +++ b/src/eval/stmt.rs @@ -41,8 +41,10 @@ impl Engine { } // Restore scope at end of block if necessary - let orig_scope_len = scope.len(); - auto_restore!(scope; restore_orig_state => move |s| { s.rewind(orig_scope_len); }); + auto_restore! { + scope if restore_orig_state => rewind; + let orig_scope_len = scope.len(); + } // Restore global state at end of block if necessary let orig_always_search_scope = global.always_search_scope; @@ -53,7 +55,7 @@ impl Engine { global.scope_level += 1; } - auto_restore!(global; restore_orig_state => move |g| { + auto_restore!(global if restore_orig_state => move |g| { g.scope_level -= 1; #[cfg(not(feature = "no_module"))] @@ -65,8 +67,10 @@ impl Engine { }); // Pop new function resolution caches at end of block - let orig_fn_resolution_caches_len = caches.fn_resolution_caches_len(); - auto_restore!(caches => move |c| c.rewind_fn_resolution_caches(orig_fn_resolution_caches_len)); + auto_restore! { + caches => rewind_fn_resolution_caches; + let orig_fn_resolution_caches_len = caches.fn_resolution_caches_len(); + } // Run the statements statements.iter().try_fold(Dynamic::UNIT, |_, stmt| { @@ -204,7 +208,7 @@ impl Engine { #[cfg(feature = "debugging")] let reset = self.run_debugger_with_reset(global, caches, scope, this_ptr, stmt)?; #[cfg(feature = "debugging")] - auto_restore!(global; reset.is_some() => move |g| g.debugger_mut().reset_status(reset)); + auto_restore!(global if reset.is_some() => move |g| g.debugger_mut().reset_status(reset)); // Coded this way for better branch prediction. // Popular branches are lifted out of the `match` statement into their own branches. @@ -515,8 +519,10 @@ impl Engine { let iter_func = iter_func.ok_or_else(|| ERR::ErrorFor(expr.start_position()))?; // Restore scope at end of statement - let orig_scope_len = scope.len(); - auto_restore!(scope => move |s| { s.rewind(orig_scope_len); }); + auto_restore! { + scope => rewind; + let orig_scope_len = scope.len(); + } // Add the loop variables let counter_index = if counter.is_empty() { usize::MAX @@ -643,8 +649,10 @@ impl Engine { }; // Restore scope at end of block - let orig_scope_len = scope.len(); - auto_restore!(scope; !catch_var.is_empty() => move |s| { s.rewind(orig_scope_len); }); + auto_restore! { + scope if !catch_var.is_empty() => rewind; + let orig_scope_len = scope.len(); + } if !catch_var.is_empty() { scope.push(catch_var.name.clone(), err_value); diff --git a/src/func/call.rs b/src/func/call.rs index 5eb3585f..a425e845 100644 --- a/src/func/call.rs +++ b/src/func/call.rs @@ -380,7 +380,7 @@ impl Engine { // Clone the first argument backup.change_first_arg_to_copy(args); } - auto_restore!(args; swap => move |a| backup.restore_first_arg(a)); + auto_restore!(args if swap => move |a| backup.restore_first_arg(a)); #[cfg(feature = "debugging")] if self.is_debugger_registered() { @@ -679,7 +679,7 @@ impl Engine { backup.change_first_arg_to_copy(_args); } - auto_restore!(args = _args; swap => move |a| backup.restore_first_arg(a)); + auto_restore!(args = (_args) if swap => move |a| backup.restore_first_arg(a)); let mut this = Dynamic::NULL; @@ -725,7 +725,7 @@ impl Engine { }) }); #[cfg(feature = "debugging")] - auto_restore!(global; reset.is_some() => move |g| g.debugger_mut().reset_status(reset)); + auto_restore!(global if reset.is_some() => move |g| g.debugger_mut().reset_status(reset)); self.eval_expr(global, caches, scope, this_ptr, arg_expr) .map(|r| (r, arg_expr.start_position())) diff --git a/src/types/restore.rs b/src/types/restore.rs index d22cc2f7..eb11e84b 100644 --- a/src/types/restore.rs +++ b/src/types/restore.rs @@ -14,16 +14,32 @@ macro_rules! auto_restore { $code auto_restore!($var => $restore); }; - ($var:ident => $restore: expr) => { + ($var:ident => $restore:ident; let $temp:ident = $save:expr;) => { + auto_restore!($var => $restore; let $temp = $save; {}); + }; + ($var:ident if $guard:expr => $restore:ident; let $temp:ident = $save:expr;) => { + auto_restore!($var if $guard => $restore; let $temp = $save; {}); + }; + ($var:ident => $restore:ident; let $temp:ident = $save:expr; $code:stmt) => { + let $temp = $save; + $code + auto_restore!($var => move |v| { v.$restore($temp); }); + }; + ($var:ident if $guard:expr => $restore:ident; let $temp:ident = $save:expr; $code:stmt) => { + let $temp = $save; + $code + auto_restore!($var if $guard => move |v| { v.$restore($temp); }); + }; + ($var:ident => $restore:expr) => { auto_restore!($var = $var => $restore); }; - ($var:ident = $value:expr => $restore: expr) => { + ($var:ident = $value:expr => $restore:expr) => { let $var = &mut *crate::types::RestoreOnDrop::lock($value, $restore); }; - ($var:ident; $guard:expr => $restore: expr) => { - auto_restore!($var = $var; $guard => $restore); + ($var:ident if $guard:expr => $restore:expr) => { + auto_restore!($var = ($var) if $guard => $restore); }; - ($var:ident = $value:expr; $guard:expr => $restore: expr) => { + ($var:ident = ( $value:expr ) if $guard:expr => $restore:expr) => { let mut __rx__; let $var = if $guard { __rx__ = crate::types::RestoreOnDrop::lock($value, $restore); diff --git a/tests/call_fn.rs b/tests/call_fn.rs index a6efae01..26b3ec8b 100644 --- a/tests/call_fn.rs +++ b/tests/call_fn.rs @@ -352,7 +352,7 @@ fn test_call_fn_events() -> Result<(), Box> { let mut handler = Handler::new(); assert!(!handler.scope.get_value::("state").unwrap()); - handler.on_event("update", 999); + let _ = handler.on_event("update", 999); assert!(handler.scope.get_value::("state").unwrap()); assert_eq!(handler.on_event("start", 999).as_int().unwrap(), 1041);