From 805163912d420c65a45b6f63b7266a3f16996336 Mon Sep 17 00:00:00 2001 From: Stephen Chung Date: Fri, 6 Aug 2021 15:30:47 +0800 Subject: [PATCH 01/10] Bump version. --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index f0a66805..8b0fe1cc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,7 +3,7 @@ members = [".", "codegen"] [package] name = "rhai" -version = "1.0.0" +version = "1.0.1" edition = "2018" authors = ["Jonathan Turner", "Lukáš Hozda", "Stephen Chung", "jhwgh1968"] description = "Embedded scripting for Rust" From d9f1f663ee641443e1840e84b0f9e93c191519ac Mon Sep 17 00:00:00 2001 From: Stephen Chung Date: Wed, 11 Aug 2021 19:27:15 +0800 Subject: [PATCH 02/10] Simplify custom syntax test. --- tests/custom_syntax.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/custom_syntax.rs b/tests/custom_syntax.rs index 34c84115..a5947453 100644 --- a/tests/custom_syntax.rs +++ b/tests/custom_syntax.rs @@ -25,8 +25,8 @@ fn test_custom_syntax() -> Result<(), Box> { |context, inputs| { let var_name = inputs[0].get_variable_name().unwrap().to_string(); let max = inputs[1].get_literal_value::().unwrap(); - let stmt = inputs.get(2).unwrap(); - let condition = inputs.get(3).unwrap(); + let stmt = &inputs[2]; + let condition = &inputs[3]; context.scope_mut().push(var_name.clone(), 0 as INT); From 4bf22e6cb7cc21bbfa26b29dd9042ef269eef8e6 Mon Sep 17 00:00:00 2001 From: Stephen Chung Date: Thu, 12 Aug 2021 11:53:05 +0800 Subject: [PATCH 03/10] Fix test output. --- codegen/ui_tests/rhai_mod_unknown_type.stderr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/codegen/ui_tests/rhai_mod_unknown_type.stderr b/codegen/ui_tests/rhai_mod_unknown_type.stderr index 6997a79d..9ea2728f 100644 --- a/codegen/ui_tests/rhai_mod_unknown_type.stderr +++ b/codegen/ui_tests/rhai_mod_unknown_type.stderr @@ -10,7 +10,7 @@ error[E0412]: cannot find type `Pointer` in this scope help: a struct with a similar name exists | 12 | pub fn test_fn(input: Point) -> bool { - | ^^^^^ + | ~~~~~ help: consider importing one of these items | 11 | use core::fmt::Pointer; From dba451045695359a95acc273d001a32707220504 Mon Sep 17 00:00:00 2001 From: Stephen Chung Date: Fri, 13 Aug 2021 13:42:39 +0800 Subject: [PATCH 04/10] Better function parameter names. --- src/engine.rs | 24 ++++++--- src/fn_call.rs | 4 +- src/optimize.rs | 15 ++++-- src/packages/array_basic.rs | 16 +++--- src/packages/fn_basic.rs | 8 +-- src/packages/map_basic.rs | 23 ++++---- src/packages/math_basic.rs | 22 ++++---- src/packages/string_more.rs | 15 ++++-- src/packages/time_basic.rs | 32 +++++------ src/parse.rs | 105 ++++++++++++++++++++++++++---------- src/token.rs | 7 +-- 11 files changed, 174 insertions(+), 97 deletions(-) diff --git a/src/engine.rs b/src/engine.rs index d72b2dac..95dbf331 100644 --- a/src/engine.rs +++ b/src/engine.rs @@ -1235,13 +1235,14 @@ impl Engine { target: &mut Target, root: (&str, Position), rhs: &Expr, - _terminate_chaining: bool, + terminate_chaining: bool, idx_values: &mut StaticVec, chain_type: ChainType, level: usize, new_val: Option<((Dynamic, Position), (Option, Position))>, ) -> Result<(Dynamic, bool), Box> { let is_ref_mut = target.is_ref(); + let _terminate_chaining = terminate_chaining; // Pop the last index value let idx_val = idx_values @@ -1725,7 +1726,7 @@ impl Engine { this_ptr: &mut Option<&mut Dynamic>, expr: &Expr, terminate_chaining: bool, - _parent_chain_type: ChainType, + parent_chain_type: ChainType, idx_values: &mut StaticVec, size: usize, level: usize, @@ -1733,6 +1734,8 @@ impl Engine { #[cfg(not(feature = "unchecked"))] self.inc_operations(state, expr.position())?; + let _parent_chain_type = parent_chain_type; + match expr { #[cfg(not(feature = "no_object"))] Expr::FnCall(x, _) if _parent_chain_type == ChainType::Dotting && !x.is_qualified() => { @@ -1848,15 +1851,18 @@ impl Engine { state: &mut EvalState, lib: &[&Module], target: &'t mut Dynamic, - mut idx: Dynamic, + idx: Dynamic, idx_pos: Position, - _create: bool, - indexers: bool, + add_if_not_found: bool, + use_indexers: bool, level: usize, ) -> Result, Box> { #[cfg(not(feature = "unchecked"))] self.inc_operations(state, Position::NONE)?; + let mut idx = idx; + let _add_if_not_found = add_if_not_found; + match target { #[cfg(not(feature = "no_index"))] Dynamic(Union::Array(arr, _, _)) => { @@ -1907,7 +1913,7 @@ impl Engine { self.make_type_mismatch_err::(idx.type_name(), idx_pos) })?; - if _create && !map.contains_key(index.as_str()) { + if _add_if_not_found && !map.contains_key(index.as_str()) { map.insert(index.clone().into(), Default::default()); } @@ -1988,7 +1994,7 @@ impl Engine { Ok(Target::StringChar(target, offset, ch.into())) } - _ if indexers => { + _ if use_indexers => { let args = &mut [target, &mut idx]; let hash_get = FnCallHashes::from_native(crate::calc_fn_hash(FN_IDX_GET, 2)); let idx_pos = Position::NONE; @@ -2298,13 +2304,15 @@ impl Engine { op_pos: Position, target: &mut Target, root: (&str, Position), - mut new_val: Dynamic, + new_val: Dynamic, ) -> Result<(), Box> { if target.is_read_only() { // Assignment to constant variable return EvalAltResult::ErrorAssignmentToConstant(root.0.to_string(), root.1).into(); } + let mut new_val = new_val; + if let Some(OpAssignment { hash_op_assign, hash_op, diff --git a/src/fn_call.rs b/src/fn_call.rs index e79e906a..8ed8430c 100644 --- a/src/fn_call.rs +++ b/src/fn_call.rs @@ -611,7 +611,7 @@ impl Engine { hashes: FnCallHashes, args: &mut FnCallArgs, is_ref_mut: bool, - _is_method_call: bool, + is_method_call: bool, pos: Position, _capture_scope: Option, _level: usize, @@ -625,6 +625,8 @@ impl Engine { #[cfg(not(feature = "no_closure"))] ensure_no_data_race(fn_name, args, is_ref_mut)?; + let _is_method_call = is_method_call; + // These may be redirected from method style calls. match fn_name { // Handle type_of() diff --git a/src/optimize.rs b/src/optimize.rs index 08f3fadd..299098c0 100644 --- a/src/optimize.rs +++ b/src/optimize.rs @@ -686,7 +686,7 @@ fn optimize_stmt(stmt: &mut Stmt, state: &mut OptimizerState, preserve_result: b } /// Optimize an [expression][Expr]. -fn optimize_expr(expr: &mut Expr, state: &mut OptimizerState, _chaining: bool) { +fn optimize_expr(expr: &mut Expr, state: &mut OptimizerState, chaining: bool) { // These keywords are handled specially const DONT_EVAL_KEYWORDS: &[&str] = &[ KEYWORD_PRINT, // side effects @@ -694,6 +694,8 @@ fn optimize_expr(expr: &mut Expr, state: &mut OptimizerState, _chaining: bool) { KEYWORD_EVAL, // arbitrary scripts ]; + let _chaining = chaining; + match expr { // {} Expr::Stmt(x) if x.is_empty() => { state.set_dirty(); *expr = Expr::Unit(x.position()) } @@ -1061,12 +1063,14 @@ fn optimize_expr(expr: &mut Expr, state: &mut OptimizerState, _chaining: bool) { /// Optimize a block of [statements][Stmt] at top level. fn optimize_top_level( - mut statements: Vec, + statements: Vec, engine: &Engine, scope: &Scope, lib: &[&Module], optimization_level: OptimizationLevel, ) -> Vec { + let mut statements = statements; + // If optimization level is None then skip optimizing if optimization_level == OptimizationLevel::None { statements.shrink_to_fit(); @@ -1093,8 +1097,8 @@ fn optimize_top_level( pub fn optimize_into_ast( engine: &Engine, scope: &Scope, - mut statements: Vec, - _functions: Vec>, + statements: Vec, + functions: Vec>, optimization_level: OptimizationLevel, ) -> AST { let level = if cfg!(feature = "no_optimize") { @@ -1103,6 +1107,9 @@ pub fn optimize_into_ast( optimization_level }; + let mut statements = statements; + let _functions = functions; + #[cfg(not(feature = "no_function"))] let lib = { let mut module = Module::new(); diff --git a/src/packages/array_basic.rs b/src/packages/array_basic.rs index 3400f1d1..a8422e98 100644 --- a/src/packages/array_basic.rs +++ b/src/packages/array_basic.rs @@ -753,17 +753,19 @@ mod array_functions { #[rhai_fn(name = "==", return_raw, pure)] pub fn equals( ctx: NativeCallContext, - array: &mut Array, - mut array2: Array, + array1: &mut Array, + array2: Array, ) -> Result> { - if array.len() != array2.len() { + if array1.len() != array2.len() { return Ok(false); } - if array.is_empty() { + if array1.is_empty() { return Ok(true); } - for (a1, a2) in array.iter_mut().zip(array2.iter_mut()) { + let mut array2 = array2; + + for (a1, a2) in array1.iter_mut().zip(array2.iter_mut()) { if !ctx .call_fn_dynamic_raw(OP_EQUALS, true, &mut [a1, a2]) .or_else(|err| match *err { @@ -791,9 +793,9 @@ mod array_functions { #[rhai_fn(name = "!=", return_raw, pure)] pub fn not_equals( ctx: NativeCallContext, - array: &mut Array, + array1: &mut Array, array2: Array, ) -> Result> { - equals(ctx, array, array2).map(|r| !r) + equals(ctx, array1, array2).map(|r| !r) } } diff --git a/src/packages/fn_basic.rs b/src/packages/fn_basic.rs index 063bd42c..dbe86112 100644 --- a/src/packages/fn_basic.rs +++ b/src/packages/fn_basic.rs @@ -10,15 +10,15 @@ def_package!(crate:BasicFnPackage:"Basic Fn functions.", lib, { #[export_module] mod fn_ptr_functions { #[rhai_fn(name = "name", get = "name", pure)] - pub fn name(f: &mut FnPtr) -> ImmutableString { - f.fn_name_raw().into() + pub fn name(fn_ptr: &mut FnPtr) -> ImmutableString { + fn_ptr.fn_name_raw().into() } #[cfg(not(feature = "no_function"))] pub mod functions { #[rhai_fn(name = "is_anonymous", get = "is_anonymous", pure)] - pub fn is_anonymous(f: &mut FnPtr) -> bool { - f.is_anonymous() + pub fn is_anonymous(fn_ptr: &mut FnPtr) -> bool { + fn_ptr.is_anonymous() } } diff --git a/src/packages/map_basic.rs b/src/packages/map_basic.rs index a7f068da..b7e52bc3 100644 --- a/src/packages/map_basic.rs +++ b/src/packages/map_basic.rs @@ -34,9 +34,10 @@ mod map_functions { map.extend(map2.into_iter()); } #[rhai_fn(name = "+")] - pub fn merge(mut map: Map, map2: Map) -> Map { - map.extend(map2.into_iter()); - map + pub fn merge(map1: Map, map2: Map) -> Map { + let mut map1 = map1; + map1.extend(map2.into_iter()); + map1 } pub fn fill_with(map: &mut Map, map2: Map) { map2.into_iter().for_each(|(key, value)| { @@ -46,17 +47,19 @@ mod map_functions { #[rhai_fn(name = "==", return_raw, pure)] pub fn equals( ctx: NativeCallContext, - map: &mut Map, - mut map2: Map, + map1: &mut Map, + map2: Map, ) -> Result> { - if map.len() != map2.len() { + if map1.len() != map2.len() { return Ok(false); } - if map.is_empty() { + if map1.is_empty() { return Ok(true); } - for (m1, v1) in map.iter_mut() { + let mut map2 = map2; + + for (m1, v1) in map1.iter_mut() { if let Some(v2) = map2.get_mut(m1) { let equals = ctx .call_fn_dynamic_raw(OP_EQUALS, true, &mut [v1, v2]) @@ -75,10 +78,10 @@ mod map_functions { #[rhai_fn(name = "!=", return_raw, pure)] pub fn not_equals( ctx: NativeCallContext, - map: &mut Map, + map1: &mut Map, map2: Map, ) -> Result> { - equals(ctx, map, map2).map(|r| !r) + equals(ctx, map1, map2).map(|r| !r) } #[cfg(not(feature = "no_index"))] diff --git a/src/packages/math_basic.rs b/src/packages/math_basic.rs index 674a6a2e..1f281390 100644 --- a/src/packages/math_basic.rs +++ b/src/packages/math_basic.rs @@ -112,7 +112,7 @@ def_package!(crate:BasicMathPackage:"Basic mathematic functions.", lib, { #[export_module] mod int_functions { #[rhai_fn(name = "parse_int", return_raw)] - pub fn parse_int_radix(s: &str, radix: INT) -> Result> { + pub fn parse_int_radix(string: &str, radix: INT) -> Result> { if !(2..=36).contains(&radix) { return EvalAltResult::ErrorArithmetic( format!("Invalid radix: '{}'", radix), @@ -121,17 +121,17 @@ mod int_functions { .into(); } - INT::from_str_radix(s.trim(), radix as u32).map_err(|err| { + INT::from_str_radix(string.trim(), radix as u32).map_err(|err| { EvalAltResult::ErrorArithmetic( - format!("Error parsing integer number '{}': {}", s, err), + format!("Error parsing integer number '{}': {}", string, err), Position::NONE, ) .into() }) } #[rhai_fn(name = "parse_int", return_raw)] - pub fn parse_int(s: &str) -> Result> { - parse_int_radix(s, 10) + pub fn parse_int(string: &str) -> Result> { + parse_int_radix(string, 10) } } @@ -283,10 +283,10 @@ mod float_functions { } } #[rhai_fn(return_raw)] - pub fn parse_float(s: &str) -> Result> { - s.trim().parse::().map_err(|err| { + pub fn parse_float(string: &str) -> Result> { + string.trim().parse::().map_err(|err| { EvalAltResult::ErrorArithmetic( - format!("Error parsing floating-point number '{}': {}", s, err), + format!("Error parsing floating-point number '{}': {}", string, err), Position::NONE, ) .into() @@ -427,12 +427,12 @@ mod decimal_functions { x.fract() } #[rhai_fn(return_raw)] - pub fn parse_decimal(s: &str) -> Result> { - Decimal::from_str(s) + pub fn parse_decimal(string: &str) -> Result> { + Decimal::from_str(string) .or_else(|_| Decimal::from_scientific(s)) .map_err(|err| { EvalAltResult::ErrorArithmetic( - format!("Error parsing decimal number '{}': {}", s, err), + format!("Error parsing decimal number '{}': {}", string, err), Position::NONE, ) .into() diff --git a/src/packages/string_more.rs b/src/packages/string_more.rs index 22c9074d..c72a695a 100644 --- a/src/packages/string_more.rs +++ b/src/packages/string_more.rs @@ -50,12 +50,13 @@ mod string_functions { string1 + string2 } #[rhai_fn(name = "+", name = "append")] - pub fn add_append_char(string: ImmutableString, ch: char) -> ImmutableString { - string + ch + pub fn add_append_char(string: ImmutableString, character: char) -> ImmutableString { + string + character } #[rhai_fn(name = "+", name = "append")] - pub fn add_append_unit(string: ImmutableString, _item: ()) -> ImmutableString { + pub fn add_append_unit(string: ImmutableString, item: ()) -> ImmutableString { + let _item = item; string } #[rhai_fn(name = "+")] @@ -369,11 +370,13 @@ mod string_functions { #[rhai_fn(return_raw)] pub fn pad( - _ctx: NativeCallContext, + ctx: NativeCallContext, string: &mut ImmutableString, len: INT, character: char, ) -> Result<(), Box> { + let _ctx = ctx; + // Check if string will be over max size limit #[cfg(not(feature = "unchecked"))] if _ctx.engine().max_string_size() > 0 && len as usize > _ctx.engine().max_string_size() { @@ -411,11 +414,13 @@ mod string_functions { } #[rhai_fn(name = "pad", return_raw)] pub fn pad_with_string( - _ctx: NativeCallContext, + ctx: NativeCallContext, string: &mut ImmutableString, len: INT, padding: &str, ) -> Result<(), Box> { + let _ctx = ctx; + // Check if string will be over max size limit #[cfg(not(feature = "unchecked"))] if _ctx.engine().max_string_size() > 0 && len as usize > _ctx.engine().max_string_size() { diff --git a/src/packages/time_basic.rs b/src/packages/time_basic.rs index 0ef705c9..44961872 100644 --- a/src/packages/time_basic.rs +++ b/src/packages/time_basic.rs @@ -54,14 +54,14 @@ mod time_functions { #[rhai_fn(return_raw, name = "-")] pub fn time_diff( - timestamp: Instant, + timestamp1: Instant, timestamp2: Instant, ) -> Result> { #[cfg(not(feature = "no_float"))] - return Ok(if timestamp2 > timestamp { - -(timestamp2 - timestamp).as_secs_f64() as FLOAT + return Ok(if timestamp2 > timestamp1 { + -(timestamp2 - timestamp1).as_secs_f64() as FLOAT } else { - (timestamp - timestamp2).as_secs_f64() as FLOAT + (timestamp1 - timestamp2).as_secs_f64() as FLOAT } .into()); @@ -225,27 +225,27 @@ mod time_functions { } #[rhai_fn(name = "==")] - pub fn eq(timestamp: Instant, timestamp2: Instant) -> bool { - timestamp == timestamp2 + pub fn eq(timestamp1: Instant, timestamp2: Instant) -> bool { + timestamp1 == timestamp2 } #[rhai_fn(name = "!=")] - pub fn ne(timestamp: Instant, timestamp2: Instant) -> bool { - timestamp != timestamp2 + pub fn ne(timestamp1: Instant, timestamp2: Instant) -> bool { + timestamp1 != timestamp2 } #[rhai_fn(name = "<")] - pub fn lt(timestamp: Instant, timestamp2: Instant) -> bool { - timestamp < timestamp2 + pub fn lt(timestamp1: Instant, timestamp2: Instant) -> bool { + timestamp1 < timestamp2 } #[rhai_fn(name = "<=")] - pub fn lte(timestamp: Instant, timestamp2: Instant) -> bool { - timestamp <= timestamp2 + pub fn lte(timestamp1: Instant, timestamp2: Instant) -> bool { + timestamp1 <= timestamp2 } #[rhai_fn(name = ">")] - pub fn gt(timestamp: Instant, timestamp2: Instant) -> bool { - timestamp > timestamp2 + pub fn gt(timestamp1: Instant, timestamp2: Instant) -> bool { + timestamp1 > timestamp2 } #[rhai_fn(name = ">=")] - pub fn gte(timestamp: Instant, timestamp2: Instant) -> bool { - timestamp >= timestamp2 + pub fn gte(timestamp1: Instant, timestamp2: Instant) -> bool { + timestamp1 >= timestamp2 } } diff --git a/src/parse.rs b/src/parse.rs index 777020d8..4b132653 100644 --- a/src/parse.rs +++ b/src/parse.rs @@ -142,8 +142,9 @@ impl<'e> ParseState<'e> { /// /// Return `None` when the variable name is not found in the `stack`. #[inline] - pub fn access_var(&mut self, name: &str, _pos: Position) -> Option { + pub fn access_var(&mut self, name: &str, pos: Position) -> Option { let mut barrier = false; + let _pos = pos; let index = self .stack @@ -393,8 +394,10 @@ fn parse_paren_expr( input: &mut TokenStream, state: &mut ParseState, lib: &mut FunctionsLib, - mut settings: ParseSettings, + settings: ParseSettings, ) -> Result { + let mut settings = settings; + #[cfg(not(feature = "unchecked"))] settings.ensure_level_within_max_limit(state.max_expr_depth)?; @@ -428,7 +431,7 @@ fn parse_fn_call( lib: &mut FunctionsLib, id: Identifier, capture: bool, - mut namespace: Option, + namespace: Option, settings: ParseSettings, ) -> Result { #[cfg(not(feature = "unchecked"))] @@ -436,6 +439,7 @@ fn parse_fn_call( let (token, token_pos) = input.peek().expect(NEVER_ENDS); + let mut namespace = namespace; let mut args = StaticVec::new(); match token { @@ -565,8 +569,10 @@ fn parse_index_chain( state: &mut ParseState, lib: &mut FunctionsLib, lhs: Expr, - mut settings: ParseSettings, + settings: ParseSettings, ) -> Result { + let mut settings = settings; + #[cfg(not(feature = "unchecked"))] settings.ensure_level_within_max_limit(state.max_expr_depth)?; @@ -726,8 +732,10 @@ fn parse_array_literal( input: &mut TokenStream, state: &mut ParseState, lib: &mut FunctionsLib, - mut settings: ParseSettings, + settings: ParseSettings, ) -> Result { + let mut settings = settings; + #[cfg(not(feature = "unchecked"))] settings.ensure_level_within_max_limit(state.max_expr_depth)?; @@ -798,8 +806,10 @@ fn parse_map_literal( input: &mut TokenStream, state: &mut ParseState, lib: &mut FunctionsLib, - mut settings: ParseSettings, + settings: ParseSettings, ) -> Result { + let mut settings = settings; + #[cfg(not(feature = "unchecked"))] settings.ensure_level_within_max_limit(state.max_expr_depth)?; @@ -914,8 +924,10 @@ fn parse_switch( input: &mut TokenStream, state: &mut ParseState, lib: &mut FunctionsLib, - mut settings: ParseSettings, + settings: ParseSettings, ) -> Result { + let mut settings = settings; + #[cfg(not(feature = "unchecked"))] settings.ensure_level_within_max_limit(state.max_expr_depth)?; @@ -1059,8 +1071,10 @@ fn parse_primary( input: &mut TokenStream, state: &mut ParseState, lib: &mut FunctionsLib, - mut settings: ParseSettings, + settings: ParseSettings, ) -> Result { + let mut settings = settings; + #[cfg(not(feature = "unchecked"))] settings.ensure_level_within_max_limit(state.max_expr_depth)?; @@ -1439,8 +1453,10 @@ fn parse_unary( input: &mut TokenStream, state: &mut ParseState, lib: &mut FunctionsLib, - mut settings: ParseSettings, + settings: ParseSettings, ) -> Result { + let mut settings = settings; + let (token, token_pos) = input.peek().expect(NEVER_ENDS); settings.pos = *token_pos; @@ -1623,8 +1639,10 @@ fn parse_op_assignment_stmt( state: &mut ParseState, lib: &mut FunctionsLib, lhs: Expr, - mut settings: ParseSettings, + settings: ParseSettings, ) -> Result { + let mut settings = settings; + #[cfg(not(feature = "unchecked"))] settings.ensure_level_within_max_limit(state.max_expr_depth)?; @@ -1774,8 +1792,10 @@ fn parse_binary_op( lib: &mut FunctionsLib, parent_precedence: Option, lhs: Expr, - mut settings: ParseSettings, + settings: ParseSettings, ) -> Result { + let mut settings = settings; + #[cfg(not(feature = "unchecked"))] settings.ensure_level_within_max_limit(state.max_expr_depth)?; @@ -1955,11 +1975,12 @@ fn parse_custom_syntax( input: &mut TokenStream, state: &mut ParseState, lib: &mut FunctionsLib, - mut settings: ParseSettings, + settings: ParseSettings, key: &str, syntax: &CustomSyntax, pos: Position, ) -> Result { + let mut settings = settings; let mut keywords: StaticVec = Default::default(); let mut segments: StaticVec<_> = Default::default(); let mut tokens: StaticVec<_> = Default::default(); @@ -2101,8 +2122,10 @@ fn parse_expr( input: &mut TokenStream, state: &mut ParseState, lib: &mut FunctionsLib, - mut settings: ParseSettings, + settings: ParseSettings, ) -> Result { + let mut settings = settings; + #[cfg(not(feature = "unchecked"))] settings.ensure_level_within_max_limit(state.max_expr_depth)?; @@ -2144,8 +2167,10 @@ fn parse_if( input: &mut TokenStream, state: &mut ParseState, lib: &mut FunctionsLib, - mut settings: ParseSettings, + settings: ParseSettings, ) -> Result { + let mut settings = settings; + #[cfg(not(feature = "unchecked"))] settings.ensure_level_within_max_limit(state.max_expr_depth)?; @@ -2183,8 +2208,10 @@ fn parse_while_loop( input: &mut TokenStream, state: &mut ParseState, lib: &mut FunctionsLib, - mut settings: ParseSettings, + settings: ParseSettings, ) -> Result { + let mut settings = settings; + #[cfg(not(feature = "unchecked"))] settings.ensure_level_within_max_limit(state.max_expr_depth)?; @@ -2212,8 +2239,10 @@ fn parse_do( input: &mut TokenStream, state: &mut ParseState, lib: &mut FunctionsLib, - mut settings: ParseSettings, + settings: ParseSettings, ) -> Result { + let mut settings = settings; + #[cfg(not(feature = "unchecked"))] settings.ensure_level_within_max_limit(state.max_expr_depth)?; @@ -2254,8 +2283,10 @@ fn parse_for( input: &mut TokenStream, state: &mut ParseState, lib: &mut FunctionsLib, - mut settings: ParseSettings, + settings: ParseSettings, ) -> Result { + let mut settings = settings; + #[cfg(not(feature = "unchecked"))] settings.ensure_level_within_max_limit(state.max_expr_depth)?; @@ -2353,9 +2384,11 @@ fn parse_let( state: &mut ParseState, lib: &mut FunctionsLib, var_type: AccessMode, - export: bool, - mut settings: ParseSettings, + is_export: bool, + settings: ParseSettings, ) -> Result { + let mut settings = settings; + #[cfg(not(feature = "unchecked"))] settings.ensure_level_within_max_limit(state.max_expr_depth)?; @@ -2381,7 +2414,7 @@ fn parse_let( state.stack.push((name, var_type)); - let export = if export { + let export = if is_export { AST_OPTION_EXPORTED } else { AST_OPTION_NONE @@ -2406,8 +2439,10 @@ fn parse_import( input: &mut TokenStream, state: &mut ParseState, lib: &mut FunctionsLib, - mut settings: ParseSettings, + settings: ParseSettings, ) -> Result { + let mut settings = settings; + #[cfg(not(feature = "unchecked"))] settings.ensure_level_within_max_limit(state.max_expr_depth)?; @@ -2446,8 +2481,10 @@ fn parse_export( input: &mut TokenStream, state: &mut ParseState, lib: &mut FunctionsLib, - mut settings: ParseSettings, + settings: ParseSettings, ) -> Result { + let mut settings = settings; + #[cfg(not(feature = "unchecked"))] settings.ensure_level_within_max_limit(state.max_expr_depth)?; @@ -2518,8 +2555,10 @@ fn parse_block( input: &mut TokenStream, state: &mut ParseState, lib: &mut FunctionsLib, - mut settings: ParseSettings, + settings: ParseSettings, ) -> Result { + let mut settings = settings; + // Must start with { settings.pos = match input.next().expect(NEVER_ENDS) { (Token::LeftBrace, pos) => pos, @@ -2619,8 +2658,10 @@ fn parse_expr_stmt( input: &mut TokenStream, state: &mut ParseState, lib: &mut FunctionsLib, - mut settings: ParseSettings, + settings: ParseSettings, ) -> Result { + let mut settings = settings; + #[cfg(not(feature = "unchecked"))] settings.ensure_level_within_max_limit(state.max_expr_depth)?; @@ -2636,10 +2677,12 @@ fn parse_stmt( input: &mut TokenStream, state: &mut ParseState, lib: &mut FunctionsLib, - mut settings: ParseSettings, + settings: ParseSettings, ) -> Result { use AccessMode::{ReadOnly, ReadWrite}; + let mut settings = settings; + #[cfg(not(feature = "no_function"))] #[cfg(feature = "metadata")] let comments = { @@ -2836,8 +2879,10 @@ fn parse_try_catch( input: &mut TokenStream, state: &mut ParseState, lib: &mut FunctionsLib, - mut settings: ParseSettings, + settings: ParseSettings, ) -> Result { + let mut settings = settings; + #[cfg(not(feature = "unchecked"))] settings.ensure_level_within_max_limit(state.max_expr_depth)?; @@ -2892,11 +2937,13 @@ fn parse_fn( state: &mut ParseState, lib: &mut FunctionsLib, access: FnAccess, - mut settings: ParseSettings, + settings: ParseSettings, #[cfg(not(feature = "no_function"))] #[cfg(feature = "metadata")] comments: StaticVec, ) -> Result { + let mut settings = settings; + #[cfg(not(feature = "unchecked"))] settings.ensure_level_within_max_limit(state.max_expr_depth)?; @@ -3039,8 +3086,10 @@ fn parse_anon_fn( input: &mut TokenStream, state: &mut ParseState, lib: &mut FunctionsLib, - mut settings: ParseSettings, + settings: ParseSettings, ) -> Result<(Expr, ScriptFnDef), ParseError> { + let mut settings = settings; + #[cfg(not(feature = "unchecked"))] settings.ensure_level_within_max_limit(state.max_expr_depth)?; diff --git a/src/token.rs b/src/token.rs index cc425efd..3fd2d8b3 100644 --- a/src/token.rs +++ b/src/token.rs @@ -1266,11 +1266,12 @@ fn eat_next(stream: &mut impl InputStream, pos: &mut Position) -> Option { /// Scan for a block comment until the end. fn scan_block_comment( stream: &mut impl InputStream, - mut level: usize, + level: usize, pos: &mut Position, - mut comment: Option<&mut String>, + comment: Option<&mut String>, ) -> usize { - let comment = &mut comment; + let mut level = level; + let mut comment = comment; while let Some(c) = stream.get_next() { pos.advance(); From 0f46bc772527c9dcf342aad97bfeebf99043a92b Mon Sep 17 00:00:00 2001 From: Stephen Chung Date: Fri, 13 Aug 2021 14:04:27 +0800 Subject: [PATCH 05/10] Fix builds. --- src/packages/math_basic.rs | 2 +- src/packages/time_basic.rs | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/packages/math_basic.rs b/src/packages/math_basic.rs index 1f281390..2b07a5bc 100644 --- a/src/packages/math_basic.rs +++ b/src/packages/math_basic.rs @@ -429,7 +429,7 @@ mod decimal_functions { #[rhai_fn(return_raw)] pub fn parse_decimal(string: &str) -> Result> { Decimal::from_str(string) - .or_else(|_| Decimal::from_scientific(s)) + .or_else(|_| Decimal::from_scientific(string)) .map_err(|err| { EvalAltResult::ErrorArithmetic( format!("Error parsing decimal number '{}': {}", string, err), diff --git a/src/packages/time_basic.rs b/src/packages/time_basic.rs index 44961872..eeff7a50 100644 --- a/src/packages/time_basic.rs +++ b/src/packages/time_basic.rs @@ -66,8 +66,8 @@ mod time_functions { .into()); #[cfg(feature = "no_float")] - if timestamp2 > timestamp { - let seconds = (timestamp2 - timestamp).as_secs(); + if timestamp2 > timestamp1 { + let seconds = (timestamp2 - timestamp1).as_secs(); if cfg!(not(feature = "unchecked")) && seconds > (MAX_INT as u64) { Err(make_arithmetic_err(format!( @@ -78,7 +78,7 @@ mod time_functions { Ok((-(seconds as INT)).into()) } } else { - let seconds = (timestamp - timestamp2).as_secs(); + let seconds = (timestamp1 - timestamp2).as_secs(); if cfg!(not(feature = "unchecked")) && seconds > (MAX_INT as u64) { Err(make_arithmetic_err(format!( From 3610b5eb7e996a5d05cec966cd4445cfbe98be0e Mon Sep 17 00:00:00 2001 From: Stephen Chung Date: Sat, 14 Aug 2021 15:10:37 +0800 Subject: [PATCH 06/10] Change some inline(always) into inline. --- src/custom_syntax.rs | 2 +- src/dynamic.rs | 32 ++++++++++++++++---------------- src/engine.rs | 16 ++++++++-------- src/engine_api.rs | 8 ++++---- src/error.rs | 2 +- src/fn_register.rs | 2 +- src/module/mod.rs | 8 ++++---- src/parse.rs | 6 +++--- src/scope.rs | 16 ++++++++-------- 9 files changed, 46 insertions(+), 46 deletions(-) diff --git a/src/custom_syntax.rs b/src/custom_syntax.rs index e77bee10..6e98eee1 100644 --- a/src/custom_syntax.rs +++ b/src/custom_syntax.rs @@ -81,7 +81,7 @@ impl Expression<'_> { /// [`ImmutableString`][crate::ImmutableString]. /// /// Returns [`None`] also if the constant is not of the specified type. - #[inline(always)] + #[inline] #[must_use] pub fn get_literal_value(&self) -> Option { // Coded this way in order to maximally leverage potentials for dead-code removal. diff --git a/src/dynamic.rs b/src/dynamic.rs index 8441a940..401e3907 100644 --- a/src/dynamic.rs +++ b/src/dynamic.rs @@ -1038,7 +1038,7 @@ impl Dynamic { /// assert_eq!(new_result.type_name(), "string"); /// assert_eq!(new_result.to_string(), "hello"); /// ``` - #[inline(always)] + #[inline] #[must_use] pub fn from(mut value: T) -> Self { // Coded this way in order to maximally leverage potentials for dead-code removal. @@ -1179,7 +1179,7 @@ impl Dynamic { /// /// assert_eq!(x.try_cast::().unwrap(), 42); /// ``` - #[inline(always)] + #[inline] #[must_use] pub fn try_cast(self) -> Option { // Coded this way in order to maximally leverage potentials for dead-code removal. @@ -1538,7 +1538,7 @@ impl Dynamic { /// Casting to [`Dynamic`] just returns a reference to it. /// /// Returns [`None`] if the cast fails, or if the value is shared. - #[inline(always)] + #[inline] #[must_use] pub(crate) fn downcast_ref(&self) -> Option<&T> { // Coded this way in order to maximally leverage potentials for dead-code removal. @@ -1629,7 +1629,7 @@ impl Dynamic { /// Casting to [`Dynamic`] just returns a mutable reference to it. /// /// Returns [`None`] if the cast fails, or if the value is shared. - #[inline(always)] + #[inline] #[must_use] pub(crate) fn downcast_mut(&mut self) -> Option<&mut T> { // Coded this way in order to maximally leverage potentials for dead-code removal. @@ -1728,7 +1728,7 @@ impl Dynamic { } /// Cast the [`Dynamic`] as a unit `()` and return it. /// Returns the name of the actual type if the cast fails. - #[inline(always)] + #[inline] pub fn as_unit(&self) -> Result<(), &'static str> { match self.0 { Union::Unit(value, _, _) => Ok(value), @@ -1739,7 +1739,7 @@ impl Dynamic { } /// Cast the [`Dynamic`] as the system integer type [`INT`] and return it. /// Returns the name of the actual type if the cast fails. - #[inline(always)] + #[inline] pub fn as_int(&self) -> Result { match self.0 { Union::Int(n, _, _) => Ok(n), @@ -1753,7 +1753,7 @@ impl Dynamic { /// /// Not available under `no_float`. #[cfg(not(feature = "no_float"))] - #[inline(always)] + #[inline] pub fn as_float(&self) -> Result { match self.0 { Union::Float(n, _, _) => Ok(*n), @@ -1767,7 +1767,7 @@ impl Dynamic { /// /// Exported under the `decimal` feature only. #[cfg(feature = "decimal")] - #[inline(always)] + #[inline] pub fn as_decimal(&self) -> Result { match self.0 { Union::Decimal(ref n, _, _) => Ok(**n), @@ -1778,7 +1778,7 @@ impl Dynamic { } /// Cast the [`Dynamic`] as a [`bool`] and return it. /// Returns the name of the actual type if the cast fails. - #[inline(always)] + #[inline] pub fn as_bool(&self) -> Result { match self.0 { Union::Bool(b, _, _) => Ok(b), @@ -1789,7 +1789,7 @@ impl Dynamic { } /// Cast the [`Dynamic`] as a [`char`] and return it. /// Returns the name of the actual type if the cast fails. - #[inline(always)] + #[inline] pub fn as_char(&self) -> Result { match self.0 { Union::Char(n, _, _) => Ok(n), @@ -1804,7 +1804,7 @@ impl Dynamic { /// # Panics /// /// Panics if the value is shared. - #[inline(always)] + #[inline] pub(crate) fn as_str_ref(&self) -> Result<&str, &'static str> { match self.0 { Union::Str(ref s, _, _) => Ok(s), @@ -1816,7 +1816,7 @@ impl Dynamic { /// Convert the [`Dynamic`] into a [`String`] and return it. /// If there are other references to the same string, a cloned copy is returned. /// Returns the name of the actual type if the cast fails. - #[inline(always)] + #[inline] pub fn as_string(self) -> Result { self.as_immutable_string().map(ImmutableString::into_owned) } @@ -1954,7 +1954,7 @@ impl Dynamic { impl, T: Variant + Clone> From> for Dynamic { - #[inline(always)] + #[inline] fn from(value: std::collections::HashMap) -> Self { Self(Union::Map( Box::new( @@ -1971,7 +1971,7 @@ impl, T: Variant + Clone> From> From> for Dynamic { - #[inline(always)] + #[inline] fn from(value: std::collections::HashSet) -> Self { Self(Union::Map( Box::new( @@ -1989,7 +1989,7 @@ impl> From> for Dynamic impl, T: Variant + Clone> From> for Dynamic { - #[inline(always)] + #[inline] fn from(value: std::collections::BTreeMap) -> Self { Self(Union::Map( Box::new( @@ -2005,7 +2005,7 @@ impl, T: Variant + Clone> From> From> for Dynamic { - #[inline(always)] + #[inline] fn from(value: std::collections::BTreeSet) -> Self { Self(Union::Map( Box::new( diff --git a/src/engine.rs b/src/engine.rs index 95dbf331..8d9df163 100644 --- a/src/engine.rs +++ b/src/engine.rs @@ -98,7 +98,7 @@ impl Imports { self.modules.get_mut(index) } /// Get the index of an imported [module][Module] by name. - #[inline(always)] + #[inline] #[must_use] pub fn find(&self, name: &str) -> Option { self.keys @@ -121,7 +121,7 @@ impl Imports { } /// Get an iterator to this stack of imported [modules][Module] in reverse order. #[allow(dead_code)] - #[inline(always)] + #[inline] pub fn iter(&self) -> impl Iterator { self.keys .iter() @@ -131,13 +131,13 @@ impl Imports { } /// Get an iterator to this stack of imported [modules][Module] in reverse order. #[allow(dead_code)] - #[inline(always)] + #[inline] pub(crate) fn iter_raw(&self) -> impl Iterator)> { self.keys.iter().rev().zip(self.modules.iter().rev()) } /// Get an iterator to this stack of imported [modules][Module] in forward order. #[allow(dead_code)] - #[inline(always)] + #[inline] pub(crate) fn scan_raw(&self) -> impl Iterator)> { self.keys.iter().zip(self.modules.iter()) } @@ -149,7 +149,7 @@ impl Imports { self.modules.iter().any(|m| m.contains_qualified_fn(hash)) } /// Get the specified function via its hash key from this stack of imported [modules][Module]. - #[inline(always)] + #[inline] #[must_use] pub fn get_fn(&self, hash: u64) -> Option<(&CallableFunction, Option<&Identifier>)> { self.modules @@ -167,7 +167,7 @@ impl Imports { } /// Get the specified [`TypeId`][std::any::TypeId] iterator from this stack of imported /// [modules][Module]. - #[inline(always)] + #[inline] #[must_use] pub fn get_iter(&self, id: TypeId) -> Option { self.modules @@ -182,7 +182,7 @@ impl IntoIterator for Imports { type IntoIter = Zip>, Rev; 4]>>>; - #[inline(always)] + #[inline] fn into_iter(self) -> Self::IntoIter { self.keys .into_iter() @@ -694,7 +694,7 @@ impl EvalState { self.scope_level == 0 } /// Get a mutable reference to the current function resolution cache. - #[inline(always)] + #[inline] #[must_use] pub fn fn_resolution_cache_mut(&mut self) -> &mut FnResolutionCache { if self.fn_resolution_caches.is_empty() { diff --git a/src/engine_api.rs b/src/engine_api.rs index 99213283..9b29a6ba 100644 --- a/src/engine_api.rs +++ b/src/engine_api.rs @@ -574,7 +574,7 @@ impl Engine { /// # } /// ``` #[cfg(any(not(feature = "no_index"), not(feature = "no_object")))] - #[inline(always)] + #[inline] pub fn register_indexer_get( &mut self, get_fn: impl Fn(&mut T, X) -> V + SendSync + 'static, @@ -648,7 +648,7 @@ impl Engine { /// # } /// ``` #[cfg(any(not(feature = "no_index"), not(feature = "no_object")))] - #[inline(always)] + #[inline] pub fn register_indexer_get_result< T: Variant + Clone, X: Variant + Clone, @@ -724,7 +724,7 @@ impl Engine { /// # } /// ``` #[cfg(any(not(feature = "no_index"), not(feature = "no_object")))] - #[inline(always)] + #[inline] pub fn register_indexer_set( &mut self, set_fn: impl Fn(&mut T, X, V) + SendSync + 'static, @@ -799,7 +799,7 @@ impl Engine { /// # } /// ``` #[cfg(any(not(feature = "no_index"), not(feature = "no_object")))] - #[inline(always)] + #[inline] pub fn register_indexer_set_result< T: Variant + Clone, X: Variant + Clone, diff --git a/src/error.rs b/src/error.rs index acdb4499..270bfacd 100644 --- a/src/error.rs +++ b/src/error.rs @@ -447,7 +447,7 @@ impl EvalAltResult { } /// Consume the current [`EvalAltResult`] and return a new one with the specified [`Position`] /// if the current position is [`Position::None`]. - #[inline(always)] + #[inline] #[must_use] pub(crate) fn fill_position(mut self: Box, new_position: Position) -> Box { if self.position().is_none() { diff --git a/src/fn_register.rs b/src/fn_register.rs index cb90c62e..57a4e34f 100644 --- a/src/fn_register.rs +++ b/src/fn_register.rs @@ -39,7 +39,7 @@ pub fn by_ref(data: &mut Dynamic) -> DynamicWriteLock { } /// Dereference into value. -#[inline(always)] +#[inline] #[must_use] pub fn by_value(data: &mut Dynamic) -> T { if TypeId::of::() == TypeId::of::<&str>() { diff --git a/src/module/mod.rs b/src/module/mod.rs index c9d10706..3e80a579 100644 --- a/src/module/mod.rs +++ b/src/module/mod.rs @@ -455,7 +455,7 @@ impl Module { /// Get a reference to a namespace-qualified variable. /// Name and Position in [`EvalAltResult`] are [`None`] and [`NONE`][Position::NONE] and must be set afterwards. - #[inline(always)] + #[inline] pub(crate) fn get_qualified_var(&self, hash_var: u64) -> Result<&Dynamic, Box> { self.all_variables.get(&hash_var).ok_or_else(|| { EvalAltResult::ErrorVariableNotFound(String::new(), Position::NONE).into() @@ -497,7 +497,7 @@ impl Module { /// Get a shared reference to the script-defined function in the [`Module`] based on name /// and number of parameters. #[cfg(not(feature = "no_function"))] - #[inline(always)] + #[inline] #[must_use] pub fn get_script_fn( &self, @@ -965,7 +965,7 @@ impl Module { /// assert!(module.contains_fn(hash)); /// ``` #[cfg(any(not(feature = "no_index"), not(feature = "no_object")))] - #[inline(always)] + #[inline] pub fn set_indexer_get_fn(&mut self, func: F) -> u64 where A: Variant + Clone, @@ -1026,7 +1026,7 @@ impl Module { /// assert!(module.contains_fn(hash)); /// ``` #[cfg(any(not(feature = "no_index"), not(feature = "no_object")))] - #[inline(always)] + #[inline] pub fn set_indexer_set_fn(&mut self, func: F) -> u64 where A: Variant + Clone, diff --git a/src/parse.rs b/src/parse.rs index 4b132653..7162081d 100644 --- a/src/parse.rs +++ b/src/parse.rs @@ -189,7 +189,7 @@ impl<'e> ParseState<'e> { /// /// Panics when called under `no_module`. #[cfg(not(feature = "no_module"))] - #[inline(always)] + #[inline] #[must_use] pub fn find_module(&self, name: &str) -> Option { self.modules @@ -325,7 +325,7 @@ impl Expr { } /// Make sure that the next expression is not a statement expression (i.e. wrapped in `{}`). -#[inline(always)] +#[inline] fn ensure_not_statement_expr(input: &mut TokenStream, type_name: &str) -> Result<(), ParseError> { match input.peek().expect(NEVER_ENDS) { (Token::LeftBrace, pos) => Err(PERR::ExprExpected(type_name.to_string()).into_err(*pos)), @@ -334,7 +334,7 @@ fn ensure_not_statement_expr(input: &mut TokenStream, type_name: &str) -> Result } /// Make sure that the next expression is not a mis-typed assignment (i.e. `a = b` instead of `a == b`). -#[inline(always)] +#[inline] fn ensure_not_assignment(input: &mut TokenStream) -> Result<(), ParseError> { match input.peek().expect(NEVER_ENDS) { (Token::Equals, pos) => Err(LexError::ImproperSymbol( diff --git a/src/scope.rs b/src/scope.rs index bd99207a..823d640d 100644 --- a/src/scope.rs +++ b/src/scope.rs @@ -63,7 +63,7 @@ impl<'a> IntoIterator for Scope<'a> { type Item = (Cow<'a, str>, Dynamic); type IntoIter = Box + 'a>; - #[inline(always)] + #[inline] fn into_iter(self) -> Self::IntoIter { Box::new( self.values @@ -293,7 +293,7 @@ impl<'a> Scope<'a> { /// assert!(my_scope.contains("x")); /// assert!(!my_scope.contains("y")); /// ``` - #[inline(always)] + #[inline] #[must_use] pub fn contains(&self, name: &str) -> bool { self.names @@ -302,7 +302,7 @@ impl<'a> Scope<'a> { .any(|(key, _)| name == key.as_ref()) } /// Find an entry in the [`Scope`], starting from the last. - #[inline(always)] + #[inline] #[must_use] pub(crate) fn get_index(&self, name: &str) -> Option<(usize, AccessMode)> { self.names @@ -329,7 +329,7 @@ impl<'a> Scope<'a> { /// my_scope.push("x", 42_i64); /// assert_eq!(my_scope.get_value::("x").unwrap(), 42); /// ``` - #[inline(always)] + #[inline] #[must_use] pub fn get_value(&self, name: &str) -> Option { self.names @@ -398,7 +398,7 @@ impl<'a> Scope<'a> { /// /// assert_eq!(my_scope.get_value::("x").unwrap(), 123); /// ``` - #[inline(always)] + #[inline] #[must_use] pub fn get_mut(&mut self, name: &str) -> Option<&mut Dynamic> { self.get_index(name) @@ -444,7 +444,7 @@ impl<'a> Scope<'a> { } /// Clone the [`Scope`], keeping only the last instances of each variable name. /// Shadowed variables are omitted in the copy. - #[inline(always)] + #[inline] #[must_use] pub(crate) fn clone_visible(&self) -> Self { let mut entries = Self::new(); @@ -463,7 +463,7 @@ impl<'a> Scope<'a> { entries } /// Get an iterator to entries in the [`Scope`]. - #[inline(always)] + #[inline] #[allow(dead_code)] pub(crate) fn into_iter( self, @@ -507,7 +507,7 @@ impl<'a> Scope<'a> { } /// Get an iterator to entries in the [`Scope`]. /// Shared values are not expanded. - #[inline(always)] + #[inline] pub fn iter_raw(&self) -> impl Iterator { self.names .iter() From 8a8bc2adfb8369c6d0d4115dd13268bf341a0662 Mon Sep 17 00:00:00 2001 From: Stephen Chung Date: Tue, 17 Aug 2021 15:32:12 +0800 Subject: [PATCH 07/10] Improve FnPtr debug display. --- src/fn_ptr.rs | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/fn_ptr.rs b/src/fn_ptr.rs index 6815ce0c..3b9350cb 100644 --- a/src/fn_ptr.rs +++ b/src/fn_ptr.rs @@ -13,9 +13,19 @@ use std::{ /// A general function pointer, which may carry additional (i.e. curried) argument values /// to be passed onto a function during a call. -#[derive(Debug, Clone, Hash)] +#[derive(Clone, Hash)] pub struct FnPtr(Identifier, StaticVec); +impl fmt::Debug for FnPtr { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + if !self.is_curried() { + write!(f, "Fn({})", self.fn_name()) + } else { + f.debug_tuple("Fn").field(&self.0).field(&self.1).finish() + } + } +} + impl FnPtr { /// Create a new function pointer. #[inline(always)] From 224a2dfb6045031961c922f92e53afb316071cc8 Mon Sep 17 00:00:00 2001 From: Stephen Chung Date: Tue, 17 Aug 2021 15:32:48 +0800 Subject: [PATCH 08/10] Fix bug in dotting-indexing. --- src/parse.rs | 75 ++++++++++++++++++++++++------------------------- tests/arrays.rs | 3 ++ 2 files changed, 40 insertions(+), 38 deletions(-) diff --git a/src/parse.rs b/src/parse.rs index 7162081d..a98154cc 100644 --- a/src/parse.rs +++ b/src/parse.rs @@ -1697,52 +1697,51 @@ fn make_dot_expr( (lhs, prop @ Expr::Property(_)) => { Expr::Dot(BinaryExpr { lhs, rhs: prop }.into(), false, op_pos) } - // lhs.dot_lhs.dot_rhs - (lhs, Expr::Dot(x, _, pos)) => match x.lhs { - Expr::Variable(_, _, _) | Expr::Property(_) => { - let rhs = Expr::Dot( - BinaryExpr { + // lhs.dot_lhs.dot_rhs or lhs.dot_lhs[idx_rhs] + (lhs, rhs @ Expr::Dot(_, _, _)) | (lhs, rhs @ Expr::Index(_, _, _)) => { + let (x, term, pos, is_dot) = match rhs { + Expr::Dot(x, term, pos) => (x, term, pos, true), + Expr::Index(x, term, pos) => (x, term, pos, false), + _ => unreachable!(), + }; + + match x.lhs { + Expr::Variable(_, _, _) | Expr::Property(_) => { + let new_lhs = BinaryExpr { lhs: x.lhs.into_property(state), rhs: x.rhs, } - .into(), - false, - pos, - ); - Expr::Dot(BinaryExpr { lhs, rhs }.into(), false, op_pos) - } - Expr::FnCall(mut func, func_pos) => { - // Recalculate hash - func.hashes = FnCallHashes::from_script_and_native( - calc_fn_hash(&func.name, func.args.len()), - calc_fn_hash(&func.name, func.args.len() + 1), - ); + .into(); - let rhs = Expr::Dot( - BinaryExpr { + let rhs = if is_dot { + Expr::Dot(new_lhs, term, pos) + } else { + Expr::Index(new_lhs, term, pos) + }; + Expr::Dot(BinaryExpr { lhs, rhs }.into(), false, op_pos) + } + Expr::FnCall(mut func, func_pos) => { + // Recalculate hash + func.hashes = FnCallHashes::from_script_and_native( + calc_fn_hash(&func.name, func.args.len()), + calc_fn_hash(&func.name, func.args.len() + 1), + ); + + let new_lhs = BinaryExpr { lhs: Expr::FnCall(func, func_pos), rhs: x.rhs, } - .into(), - false, - pos, - ); - Expr::Dot(BinaryExpr { lhs, rhs }.into(), false, op_pos) - } - _ => unreachable!("invalid dot expression: {:?}", x.lhs), - }, - // lhs.idx_lhs[idx_rhs] - (lhs, Expr::Index(x, term, pos)) => { - let rhs = Expr::Index( - BinaryExpr { - lhs: x.lhs.into_property(state), - rhs: x.rhs, + .into(); + + let rhs = if is_dot { + Expr::Dot(new_lhs, term, pos) + } else { + Expr::Index(new_lhs, term, pos) + }; + Expr::Dot(BinaryExpr { lhs, rhs }.into(), false, op_pos) } - .into(), - term, - pos, - ); - Expr::Dot(BinaryExpr { lhs, rhs }.into(), false, op_pos) + _ => unreachable!("invalid dot expression: {:?}", x.lhs), + } } // lhs.nnn::func(...) (_, Expr::FnCall(x, _)) if x.is_qualified() => { diff --git a/tests/arrays.rs b/tests/arrays.rs index 486bfbe8..a230e561 100644 --- a/tests/arrays.rs +++ b/tests/arrays.rs @@ -168,6 +168,9 @@ fn test_array_with_structs() -> Result<(), Box> { fn test_arrays_map_reduce() -> Result<(), Box> { let engine = Engine::new(); + assert_eq!(engine.eval::("[1].map(|x| x + 41)[0]")?, 42); + assert_eq!(engine.eval::("([1].map(|x| x + 41))[0]")?, 42); + assert_eq!( convert_to_vec::(engine.eval( " From d0f6a2283f3acd1a79d3053e15d5b1f842177226 Mon Sep 17 00:00:00 2001 From: Stephen Chung Date: Tue, 17 Aug 2021 15:41:46 +0800 Subject: [PATCH 09/10] Bump version. --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 8b0fe1cc..4b34bc6e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,7 +3,7 @@ members = [".", "codegen"] [package] name = "rhai" -version = "1.0.1" +version = "1.0.2" edition = "2018" authors = ["Jonathan Turner", "Lukáš Hozda", "Stephen Chung", "jhwgh1968"] description = "Embedded scripting for Rust" From 0481073ed97d68fedc2e2e5ebdf8793f7e96ebb8 Mon Sep 17 00:00:00 2001 From: Stephen Chung Date: Tue, 17 Aug 2021 15:43:02 +0800 Subject: [PATCH 10/10] Bump version. --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 4b34bc6e..701fdd60 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,7 +3,7 @@ members = [".", "codegen"] [package] name = "rhai" -version = "1.0.2" +version = "1.0.3" edition = "2018" authors = ["Jonathan Turner", "Lukáš Hozda", "Stephen Chung", "jhwgh1968"] description = "Embedded scripting for Rust"