diff --git a/RELEASES.md b/RELEASES.md index bd65e687..a4c31fee 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -32,6 +32,8 @@ New features * `AST::iter_functions` and `Module::iter_script_fn_info` to iterate functions. * Functions iteration functions now take `FnMut` instead of `Fn`. * New `FileModuleResolver` that encapsulates the entire `AST` of the module script, allowing function cross-calling. The old version is renamed `MergingFileModuleResolver`. +* `split` function for splitting strings. + Version 0.18.3 ============== diff --git a/doc/src/language/string-fn.md b/doc/src/language/string-fn.md index 5c3be69c..a9caaa94 100644 --- a/doc/src/language/string-fn.md +++ b/doc/src/language/string-fn.md @@ -6,20 +6,20 @@ Built-in String Functions The following standard methods (mostly defined in the [`MoreStringPackage`][packages] but excluded if using a [raw `Engine`]) operate on [strings]: -| Function | Parameter(s) | Description | -| ------------------------- | ------------------------------------------------------------ | ------------------------------------------------------------------------------------------------- | -| `len` method and property | _none_ | returns the number of characters (not number of bytes) in the string | -| `pad` | character to pad, target length | pads the string with an character to at least a specified length | -| `+=` operator, `append` | character/string to append | Adds a character or a string to the end of another string | -| `clear` | _none_ | empties the string | -| `truncate` | target length | cuts off the string at exactly a specified number of characters | -| `contains` | character/sub-string to search for | checks if a certain character or sub-string occurs in the string | -| `index_of` | character/sub-string to search for, start index _(optional)_ | returns the index that a certain character or sub-string occurs in the string, or -1 if not found | -| `sub_string` | start index, length _(optional)_ | extracts a sub-string (to the end of the string if length is not specified) | -| `split` | delimiter character/string | splits the string by the specified delimiter, returning an [array] of string segments | -| `crop` | start index, length _(optional)_ | retains only a portion of the string (to the end of the string if length is not specified) | -| `replace` | target character/sub-string, replacement character/string | replaces a sub-string with another | -| `trim` | _none_ | trims the string of whitespace at the beginning and end | +| Function | Parameter(s) | Description | +| ------------------------- | ------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------- | +| `len` method and property | _none_ | returns the number of characters (not number of bytes) in the string | +| `pad` | character to pad, target length | pads the string with an character to at least a specified length | +| `+=` operator, `append` | character/string to append | Adds a character or a string to the end of another string | +| `clear` | _none_ | empties the string | +| `truncate` | target length | cuts off the string at exactly a specified number of characters | +| `contains` | character/sub-string to search for | checks if a certain character or sub-string occurs in the string | +| `index_of` | character/sub-string to search for, start index _(optional)_ | returns the index that a certain character or sub-string occurs in the string, or -1 if not found | +| `sub_string` | start index, length _(optional)_ | extracts a sub-string (to the end of the string if length is not specified) | +| `split` | delimiter character/string | splits the string by the specified delimiter, returning an [array] of string segments; not available under [`no_index`] | +| `crop` | start index, length _(optional)_ | retains only a portion of the string (to the end of the string if length is not specified) | +| `replace` | target character/sub-string, replacement character/string | replaces a sub-string with another | +| `trim` | _none_ | trims the string of whitespace at the beginning and end | Examples -------- diff --git a/src/engine.rs b/src/engine.rs index d4715eca..cceda886 100644 --- a/src/engine.rs +++ b/src/engine.rs @@ -769,7 +769,7 @@ impl Engine { let args = &mut [val, &mut idx_val2, &mut new_val]; self.exec_fn_call( - state, lib, FN_IDX_SET, 0, args, is_ref, true, false, None, None, + state, lib, FN_IDX_SET, 0, args, is_ref, true, false, None, &None, level, ) .map_err(|err| match *err { @@ -798,8 +798,9 @@ impl Engine { // xxx.fn_name(arg_expr_list) Expr::FnCall(x) if x.1.is_none() => { let ((name, native, _, pos), _, hash, _, def_val) = x.as_ref(); + let def_val = def_val.map(Into::::into); self.make_method_call( - state, lib, name, *hash, target, idx_val, *def_val, *native, false, + state, lib, name, *hash, target, idx_val, &def_val, *native, false, level, ) .map_err(|err| err.new_position(*pos)) @@ -833,7 +834,7 @@ impl Engine { let mut new_val = new_val; let mut args = [target.as_mut(), new_val.as_mut().unwrap()]; self.exec_fn_call( - state, lib, setter, 0, &mut args, is_ref, true, false, None, None, + state, lib, setter, 0, &mut args, is_ref, true, false, None, &None, level, ) .map(|(v, _)| (v, true)) @@ -844,7 +845,7 @@ impl Engine { let ((_, getter, _), pos) = x.as_ref(); let mut args = [target.as_mut()]; self.exec_fn_call( - state, lib, getter, 0, &mut args, is_ref, true, false, None, None, + state, lib, getter, 0, &mut args, is_ref, true, false, None, &None, level, ) .map(|(v, _)| (v, false)) @@ -865,9 +866,10 @@ impl Engine { // {xxx:map}.fn_name(arg_expr_list)[expr] | {xxx:map}.fn_name(arg_expr_list).expr Expr::FnCall(x) if x.1.is_none() => { let ((name, native, _, pos), _, hash, _, def_val) = x.as_ref(); + let def_val = def_val.map(Into::::into); let (val, _) = self .make_method_call( - state, lib, name, *hash, target, idx_val, *def_val, + state, lib, name, *hash, target, idx_val, &def_val, *native, false, level, ) .map_err(|err| err.new_position(*pos))?; @@ -898,7 +900,7 @@ impl Engine { let (mut val, updated) = self .exec_fn_call( state, lib, getter, 0, args, is_ref, true, false, None, - None, level, + &None, level, ) .map_err(|err| err.new_position(*pos))?; @@ -924,7 +926,7 @@ impl Engine { arg_values[1] = val; self.exec_fn_call( state, lib, setter, 0, arg_values, is_ref, true, false, - None, None, level, + None, &None, level, ) .or_else( |err| match *err { @@ -942,9 +944,10 @@ impl Engine { // xxx.fn_name(arg_expr_list)[expr] | xxx.fn_name(arg_expr_list).expr Expr::FnCall(x) if x.1.is_none() => { let ((name, native, _, pos), _, hash, _, def_val) = x.as_ref(); + let def_val = def_val.map(Into::::into); let (mut val, _) = self .make_method_call( - state, lib, name, *hash, target, idx_val, *def_val, + state, lib, name, *hash, target, idx_val, &def_val, *native, false, level, ) .map_err(|err| err.new_position(*pos))?; @@ -1202,7 +1205,7 @@ impl Engine { let mut idx = idx; let args = &mut [val, &mut idx]; self.exec_fn_call( - state, _lib, FN_IDX_GET, 0, args, is_ref, true, false, None, None, _level, + state, _lib, FN_IDX_GET, 0, args, is_ref, true, false, None, &None, _level, ) .map(|(v, _)| v.into()) .map_err(|err| match *err { @@ -1245,8 +1248,9 @@ impl Engine { let op = "=="; // Call the `==` operator to compare each value + let def_value = Some(false.into()); + for value in rhs_value.iter_mut() { - let def_value = Some(false); let args = &mut [&mut lhs_value.clone(), value]; // Qualifiers (none) + function name + number of arguments + argument `TypeId`'s. @@ -1254,7 +1258,7 @@ impl Engine { calc_fn_hash(empty(), op, args.len(), args.iter().map(|a| a.type_id())); if self - .call_native_fn(state, lib, op, hash, args, false, false, def_value) + .call_native_fn(state, lib, op, hash, args, false, false, &def_value) .map_err(|err| err.new_position(rhs.position()))? .0 .as_bool() @@ -1264,7 +1268,7 @@ impl Engine { } } - Ok(false.into()) + Ok(def_value.unwrap()) } #[cfg(not(feature = "no_object"))] Dynamic(Union::Map(rhs_value)) => match lhs_value { @@ -1395,7 +1399,7 @@ impl Engine { // Run function let (value, _) = self .exec_fn_call( - state, lib, op, 0, args, false, false, false, None, None, + state, lib, op, 0, args, false, false, false, None, &None, level, ) .map_err(|err| err.new_position(*op_pos))?; @@ -1431,7 +1435,7 @@ impl Engine { &mut rhs_val, ]; self.exec_fn_call( - state, lib, op, 0, args, false, false, false, None, None, level, + state, lib, op, 0, args, false, false, false, None, &None, level, ) .map(|(v, _)| v) .map_err(|err| err.new_position(*op_pos))? @@ -1499,8 +1503,9 @@ impl Engine { // Normal function call Expr::FnCall(x) if x.1.is_none() => { let ((name, native, capture, pos), _, hash, args_expr, def_val) = x.as_ref(); + let def_val = def_val.map(Into::::into); self.make_function_call( - scope, mods, state, lib, this_ptr, name, args_expr, *def_val, *hash, *native, + scope, mods, state, lib, this_ptr, name, args_expr, &def_val, *hash, *native, false, *capture, level, ) .map_err(|err| err.new_position(*pos)) diff --git a/src/fn_call.rs b/src/fn_call.rs index eeba460a..9ee74b86 100644 --- a/src/fn_call.rs +++ b/src/fn_call.rs @@ -211,7 +211,7 @@ impl Engine { args: &mut FnCallArgs, is_ref: bool, pub_only: bool, - def_val: Option, + def_val: &Option, ) -> Result<(Dynamic, bool), Box> { self.inc_operations(state)?; @@ -281,7 +281,7 @@ impl Engine { // Return default value (if any) if let Some(val) = def_val { - return Ok((val.into(), false)); + return Ok((val.clone(), false)); } // Getter function not found? @@ -469,7 +469,7 @@ impl Engine { _is_method: bool, pub_only: bool, _capture: Option, - def_val: Option, + def_val: &Option, _level: usize, ) -> Result<(Dynamic, bool), Box> { // Check for data race. @@ -669,7 +669,7 @@ impl Engine { hash_script: u64, target: &mut Target, idx_val: Dynamic, - def_val: Option, + def_val: &Option, native: bool, pub_only: bool, level: usize, @@ -815,7 +815,7 @@ impl Engine { this_ptr: &mut Option<&mut Dynamic>, name: &str, args_expr: &[Expr], - def_val: Option, + def_val: &Option, mut hash_script: u64, native: bool, pub_only: bool, diff --git a/src/fn_native.rs b/src/fn_native.rs index 820e5dc7..041ff224 100644 --- a/src/fn_native.rs +++ b/src/fn_native.rs @@ -145,7 +145,7 @@ impl FnPtr { has_this, true, None, - None, + &None, 0, ) .map(|(v, _)| v) diff --git a/src/optimize.rs b/src/optimize.rs index 60bfb2cc..0e916878 100644 --- a/src/optimize.rs +++ b/src/optimize.rs @@ -142,7 +142,7 @@ fn call_fn_with_constant_arguments( arg_values.iter_mut().collect::>().as_mut(), false, true, - None, + &None, ) .ok() .map(|(v, _)| v) diff --git a/src/parser.rs b/src/parser.rs index 9366a3d6..98de18fb 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -790,7 +790,7 @@ pub enum Expr { Option>, u64, StaticVec, - Option, + Option, // Default value is `bool` in order for `Expr` to be `Hash`. )>, ), /// expr op= expr