Enable termination token.
This commit is contained in:
parent
b07a2aa79c
commit
6f3ce96d9d
@ -20,6 +20,8 @@ Breaking changes
|
|||||||
|
|
||||||
* Custom syntax can no longer start with a keyword (even a _reserved_ one), even if it has been disabled. That is to avoid breaking scripts later when the keyword is no longer disabled.
|
* Custom syntax can no longer start with a keyword (even a _reserved_ one), even if it has been disabled. That is to avoid breaking scripts later when the keyword is no longer disabled.
|
||||||
* `EvalAltResult::ErrorAssignmentToUnknownLHS` is moved to `ParseError::AssignmentToInvalidLHS`. `ParseError::AssignmentToCopy` is removed.
|
* `EvalAltResult::ErrorAssignmentToUnknownLHS` is moved to `ParseError::AssignmentToInvalidLHS`. `ParseError::AssignmentToCopy` is removed.
|
||||||
|
* `EvalAltResult::ErrorDataTooLarge` is simplified.
|
||||||
|
* `Engine::on_progress` closure signature now returns `Option<Dynamic>` with the termination value passed on to `EvalAltResult::ErrorTerminated`.
|
||||||
|
|
||||||
New features
|
New features
|
||||||
------------
|
------------
|
||||||
|
@ -17,13 +17,14 @@ engine.on_progress(|&count| { // parameter is '&u64' - number of operations al
|
|||||||
if count % 1000 == 0 {
|
if count % 1000 == 0 {
|
||||||
println!("{}", count); // print out a progress log every 1,000 operations
|
println!("{}", count); // print out a progress log every 1,000 operations
|
||||||
}
|
}
|
||||||
true // return 'true' to continue running the script
|
None // return 'None' to continue running the script
|
||||||
// return 'false' to immediately terminate the script
|
// return 'Some(token)' to immediately terminate the script
|
||||||
});
|
});
|
||||||
```
|
```
|
||||||
|
|
||||||
The closure passed to `Engine::on_progress` will be called once for every operation.
|
The closure passed to `Engine::on_progress` will be called once for every operation.
|
||||||
Return `false` to terminate the script immediately.
|
Return `Some(token)` to terminate the script immediately, with the provided value
|
||||||
|
(any [`Dynamic`] value) passed to `EvalAltResult::ErrorTerminated` as a termination token.
|
||||||
|
|
||||||
|
|
||||||
Operations Count vs. Progress Percentage
|
Operations Count vs. Progress Percentage
|
||||||
|
@ -576,7 +576,7 @@ pub struct Engine {
|
|||||||
/// Callback closure for implementing the `debug` command.
|
/// Callback closure for implementing the `debug` command.
|
||||||
pub(crate) debug: Callback<str, ()>,
|
pub(crate) debug: Callback<str, ()>,
|
||||||
/// Callback closure for progress reporting.
|
/// Callback closure for progress reporting.
|
||||||
pub(crate) progress: Option<Callback<u64, bool>>,
|
pub(crate) progress: Option<Callback<u64, Option<Dynamic>>>,
|
||||||
|
|
||||||
/// Optimize the AST after compilation.
|
/// Optimize the AST after compilation.
|
||||||
pub(crate) optimization_level: OptimizationLevel,
|
pub(crate) optimization_level: OptimizationLevel,
|
||||||
@ -2300,8 +2300,6 @@ impl Engine {
|
|||||||
if s > self.max_string_size() {
|
if s > self.max_string_size() {
|
||||||
return EvalAltResult::ErrorDataTooLarge(
|
return EvalAltResult::ErrorDataTooLarge(
|
||||||
"Length of string".to_string(),
|
"Length of string".to_string(),
|
||||||
self.max_string_size(),
|
|
||||||
s,
|
|
||||||
Position::none(),
|
Position::none(),
|
||||||
)
|
)
|
||||||
.into();
|
.into();
|
||||||
@ -2309,21 +2307,14 @@ impl Engine {
|
|||||||
|
|
||||||
#[cfg(not(feature = "no_index"))]
|
#[cfg(not(feature = "no_index"))]
|
||||||
if _arr > self.max_array_size() {
|
if _arr > self.max_array_size() {
|
||||||
return EvalAltResult::ErrorDataTooLarge(
|
return EvalAltResult::ErrorDataTooLarge("Size of array".to_string(), Position::none())
|
||||||
"Size of array".to_string(),
|
|
||||||
self.max_array_size(),
|
|
||||||
_arr,
|
|
||||||
Position::none(),
|
|
||||||
)
|
|
||||||
.into();
|
.into();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(feature = "no_object"))]
|
#[cfg(not(feature = "no_object"))]
|
||||||
if _map > self.max_map_size() {
|
if _map > self.max_map_size() {
|
||||||
return EvalAltResult::ErrorDataTooLarge(
|
return EvalAltResult::ErrorDataTooLarge(
|
||||||
"Number of properties in object map".to_string(),
|
"Size of object map".to_string(),
|
||||||
self.max_map_size(),
|
|
||||||
_map,
|
|
||||||
Position::none(),
|
Position::none(),
|
||||||
)
|
)
|
||||||
.into();
|
.into();
|
||||||
@ -2345,9 +2336,9 @@ impl Engine {
|
|||||||
|
|
||||||
// Report progress - only in steps
|
// Report progress - only in steps
|
||||||
if let Some(progress) = &self.progress {
|
if let Some(progress) = &self.progress {
|
||||||
if !progress(&state.operations) {
|
if let Some(token) = progress(&state.operations) {
|
||||||
// Terminate script if progress returns false
|
// Terminate script if progress returns a termination token
|
||||||
return EvalAltResult::ErrorTerminated(Position::none()).into();
|
return EvalAltResult::ErrorTerminated(token, Position::none()).into();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1732,12 +1732,12 @@ impl Engine {
|
|||||||
///
|
///
|
||||||
/// engine.on_progress(move |&ops| {
|
/// engine.on_progress(move |&ops| {
|
||||||
/// if ops > 10000 {
|
/// if ops > 10000 {
|
||||||
/// false
|
/// Some("Over 10,000 operations!".into())
|
||||||
/// } else if ops % 800 == 0 {
|
/// } else if ops % 800 == 0 {
|
||||||
/// *logger.write().unwrap() = ops;
|
/// *logger.write().unwrap() = ops;
|
||||||
/// true
|
/// None
|
||||||
/// } else {
|
/// } else {
|
||||||
/// true
|
/// None
|
||||||
/// }
|
/// }
|
||||||
/// });
|
/// });
|
||||||
///
|
///
|
||||||
@ -1752,7 +1752,7 @@ impl Engine {
|
|||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn on_progress(
|
pub fn on_progress(
|
||||||
&mut self,
|
&mut self,
|
||||||
callback: impl Fn(&u64) -> bool + SendSync + 'static,
|
callback: impl Fn(&u64) -> Option<Dynamic> + SendSync + 'static,
|
||||||
) -> &mut Self {
|
) -> &mut Self {
|
||||||
self.progress = Some(Box::new(callback));
|
self.progress = Some(Box::new(callback));
|
||||||
self
|
self
|
||||||
|
@ -160,7 +160,7 @@ impl FnPtr {
|
|||||||
/// clone them _before_ calling this function.
|
/// clone them _before_ calling this function.
|
||||||
pub fn call_dynamic(
|
pub fn call_dynamic(
|
||||||
&self,
|
&self,
|
||||||
context: NativeCallContext,
|
ctx: NativeCallContext,
|
||||||
this_ptr: Option<&mut Dynamic>,
|
this_ptr: Option<&mut Dynamic>,
|
||||||
mut arg_values: impl AsMut<[Dynamic]>,
|
mut arg_values: impl AsMut<[Dynamic]>,
|
||||||
) -> Result<Dynamic, Box<EvalAltResult>> {
|
) -> Result<Dynamic, Box<EvalAltResult>> {
|
||||||
@ -182,11 +182,10 @@ impl FnPtr {
|
|||||||
args.insert(0, obj);
|
args.insert(0, obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
context
|
ctx.engine()
|
||||||
.engine()
|
|
||||||
.exec_fn_call(
|
.exec_fn_call(
|
||||||
&mut Default::default(),
|
&mut Default::default(),
|
||||||
context.lib,
|
ctx.lib,
|
||||||
fn_name,
|
fn_name,
|
||||||
hash_script,
|
hash_script,
|
||||||
args.as_mut(),
|
args.as_mut(),
|
||||||
|
@ -529,9 +529,8 @@ impl Module {
|
|||||||
+ SendSync
|
+ SendSync
|
||||||
+ 'static,
|
+ 'static,
|
||||||
) -> u64 {
|
) -> u64 {
|
||||||
let f = move |context: NativeCallContext, args: &mut FnCallArgs| {
|
let f =
|
||||||
func(context, args).map(Dynamic::from)
|
move |ctx: NativeCallContext, args: &mut FnCallArgs| func(ctx, args).map(Dynamic::from);
|
||||||
};
|
|
||||||
self.set_fn(
|
self.set_fn(
|
||||||
name,
|
name,
|
||||||
FnAccess::Public,
|
FnAccess::Public,
|
||||||
|
@ -41,12 +41,12 @@ macro_rules! gen_array_functions {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[rhai_fn(return_raw)]
|
#[rhai_fn(return_raw)]
|
||||||
pub fn pad(_context: NativeCallContext, list: &mut Array, len: INT, item: $arg_type) -> Result<Dynamic, Box<EvalAltResult>> {
|
pub fn pad(_ctx: NativeCallContext, list: &mut Array, len: INT, item: $arg_type) -> Result<Dynamic, Box<EvalAltResult>> {
|
||||||
// Check if array will be over max size limit
|
// Check if array will be over max size limit
|
||||||
#[cfg(not(feature = "unchecked"))]
|
#[cfg(not(feature = "unchecked"))]
|
||||||
if _context.engine().max_array_size() > 0 && len > 0 && (len as usize) > _context.engine().max_array_size() {
|
if _ctx.engine().max_array_size() > 0 && len > 0 && (len as usize) > _ctx.engine().max_array_size() {
|
||||||
return EvalAltResult::ErrorDataTooLarge(
|
return EvalAltResult::ErrorDataTooLarge(
|
||||||
"Size of array".to_string(), _context.engine().max_array_size(), len as usize, Position::none(),
|
"Size of array".to_string(), Position::none()
|
||||||
).into();
|
).into();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -197,7 +197,7 @@ mod array_functions {
|
|||||||
}
|
}
|
||||||
#[rhai_fn(return_raw)]
|
#[rhai_fn(return_raw)]
|
||||||
pub fn map(
|
pub fn map(
|
||||||
context: NativeCallContext,
|
ctx: NativeCallContext,
|
||||||
list: &mut Array,
|
list: &mut Array,
|
||||||
mapper: FnPtr,
|
mapper: FnPtr,
|
||||||
) -> Result<Dynamic, Box<EvalAltResult>> {
|
) -> Result<Dynamic, Box<EvalAltResult>> {
|
||||||
@ -206,12 +206,12 @@ mod array_functions {
|
|||||||
for (i, item) in list.iter().enumerate() {
|
for (i, item) in list.iter().enumerate() {
|
||||||
array.push(
|
array.push(
|
||||||
mapper
|
mapper
|
||||||
.call_dynamic(context, None, [item.clone()])
|
.call_dynamic(ctx, None, [item.clone()])
|
||||||
.or_else(|err| match *err {
|
.or_else(|err| match *err {
|
||||||
EvalAltResult::ErrorFunctionNotFound(fn_sig, _)
|
EvalAltResult::ErrorFunctionNotFound(fn_sig, _)
|
||||||
if fn_sig.starts_with(mapper.fn_name()) =>
|
if fn_sig.starts_with(mapper.fn_name()) =>
|
||||||
{
|
{
|
||||||
mapper.call_dynamic(context, None, [item.clone(), (i as INT).into()])
|
mapper.call_dynamic(ctx, None, [item.clone(), (i as INT).into()])
|
||||||
}
|
}
|
||||||
_ => Err(err),
|
_ => Err(err),
|
||||||
})
|
})
|
||||||
@ -229,7 +229,7 @@ mod array_functions {
|
|||||||
}
|
}
|
||||||
#[rhai_fn(return_raw)]
|
#[rhai_fn(return_raw)]
|
||||||
pub fn filter(
|
pub fn filter(
|
||||||
context: NativeCallContext,
|
ctx: NativeCallContext,
|
||||||
list: &mut Array,
|
list: &mut Array,
|
||||||
filter: FnPtr,
|
filter: FnPtr,
|
||||||
) -> Result<Dynamic, Box<EvalAltResult>> {
|
) -> Result<Dynamic, Box<EvalAltResult>> {
|
||||||
@ -237,12 +237,12 @@ mod array_functions {
|
|||||||
|
|
||||||
for (i, item) in list.iter().enumerate() {
|
for (i, item) in list.iter().enumerate() {
|
||||||
if filter
|
if filter
|
||||||
.call_dynamic(context, None, [item.clone()])
|
.call_dynamic(ctx, None, [item.clone()])
|
||||||
.or_else(|err| match *err {
|
.or_else(|err| match *err {
|
||||||
EvalAltResult::ErrorFunctionNotFound(fn_sig, _)
|
EvalAltResult::ErrorFunctionNotFound(fn_sig, _)
|
||||||
if fn_sig.starts_with(filter.fn_name()) =>
|
if fn_sig.starts_with(filter.fn_name()) =>
|
||||||
{
|
{
|
||||||
filter.call_dynamic(context, None, [item.clone(), (i as INT).into()])
|
filter.call_dynamic(ctx, None, [item.clone(), (i as INT).into()])
|
||||||
}
|
}
|
||||||
_ => Err(err),
|
_ => Err(err),
|
||||||
})
|
})
|
||||||
@ -264,18 +264,18 @@ mod array_functions {
|
|||||||
}
|
}
|
||||||
#[rhai_fn(return_raw)]
|
#[rhai_fn(return_raw)]
|
||||||
pub fn some(
|
pub fn some(
|
||||||
context: NativeCallContext,
|
ctx: NativeCallContext,
|
||||||
list: &mut Array,
|
list: &mut Array,
|
||||||
filter: FnPtr,
|
filter: FnPtr,
|
||||||
) -> Result<Dynamic, Box<EvalAltResult>> {
|
) -> Result<Dynamic, Box<EvalAltResult>> {
|
||||||
for (i, item) in list.iter().enumerate() {
|
for (i, item) in list.iter().enumerate() {
|
||||||
if filter
|
if filter
|
||||||
.call_dynamic(context, None, [item.clone()])
|
.call_dynamic(ctx, None, [item.clone()])
|
||||||
.or_else(|err| match *err {
|
.or_else(|err| match *err {
|
||||||
EvalAltResult::ErrorFunctionNotFound(fn_sig, _)
|
EvalAltResult::ErrorFunctionNotFound(fn_sig, _)
|
||||||
if fn_sig.starts_with(filter.fn_name()) =>
|
if fn_sig.starts_with(filter.fn_name()) =>
|
||||||
{
|
{
|
||||||
filter.call_dynamic(context, None, [item.clone(), (i as INT).into()])
|
filter.call_dynamic(ctx, None, [item.clone(), (i as INT).into()])
|
||||||
}
|
}
|
||||||
_ => Err(err),
|
_ => Err(err),
|
||||||
})
|
})
|
||||||
@ -297,18 +297,18 @@ mod array_functions {
|
|||||||
}
|
}
|
||||||
#[rhai_fn(return_raw)]
|
#[rhai_fn(return_raw)]
|
||||||
pub fn all(
|
pub fn all(
|
||||||
context: NativeCallContext,
|
ctx: NativeCallContext,
|
||||||
list: &mut Array,
|
list: &mut Array,
|
||||||
filter: FnPtr,
|
filter: FnPtr,
|
||||||
) -> Result<Dynamic, Box<EvalAltResult>> {
|
) -> Result<Dynamic, Box<EvalAltResult>> {
|
||||||
for (i, item) in list.iter().enumerate() {
|
for (i, item) in list.iter().enumerate() {
|
||||||
if !filter
|
if !filter
|
||||||
.call_dynamic(context, None, [item.clone()])
|
.call_dynamic(ctx, None, [item.clone()])
|
||||||
.or_else(|err| match *err {
|
.or_else(|err| match *err {
|
||||||
EvalAltResult::ErrorFunctionNotFound(fn_sig, _)
|
EvalAltResult::ErrorFunctionNotFound(fn_sig, _)
|
||||||
if fn_sig.starts_with(filter.fn_name()) =>
|
if fn_sig.starts_with(filter.fn_name()) =>
|
||||||
{
|
{
|
||||||
filter.call_dynamic(context, None, [item.clone(), (i as INT).into()])
|
filter.call_dynamic(ctx, None, [item.clone(), (i as INT).into()])
|
||||||
}
|
}
|
||||||
_ => Err(err),
|
_ => Err(err),
|
||||||
})
|
})
|
||||||
@ -330,7 +330,7 @@ mod array_functions {
|
|||||||
}
|
}
|
||||||
#[rhai_fn(return_raw)]
|
#[rhai_fn(return_raw)]
|
||||||
pub fn reduce(
|
pub fn reduce(
|
||||||
context: NativeCallContext,
|
ctx: NativeCallContext,
|
||||||
list: &mut Array,
|
list: &mut Array,
|
||||||
reducer: FnPtr,
|
reducer: FnPtr,
|
||||||
) -> Result<Dynamic, Box<EvalAltResult>> {
|
) -> Result<Dynamic, Box<EvalAltResult>> {
|
||||||
@ -338,16 +338,12 @@ mod array_functions {
|
|||||||
|
|
||||||
for (i, item) in list.iter().enumerate() {
|
for (i, item) in list.iter().enumerate() {
|
||||||
result = reducer
|
result = reducer
|
||||||
.call_dynamic(context, None, [result.clone(), item.clone()])
|
.call_dynamic(ctx, None, [result.clone(), item.clone()])
|
||||||
.or_else(|err| match *err {
|
.or_else(|err| match *err {
|
||||||
EvalAltResult::ErrorFunctionNotFound(fn_sig, _)
|
EvalAltResult::ErrorFunctionNotFound(fn_sig, _)
|
||||||
if fn_sig.starts_with(reducer.fn_name()) =>
|
if fn_sig.starts_with(reducer.fn_name()) =>
|
||||||
{
|
{
|
||||||
reducer.call_dynamic(
|
reducer.call_dynamic(ctx, None, [result, item.clone(), (i as INT).into()])
|
||||||
context,
|
|
||||||
None,
|
|
||||||
[result, item.clone(), (i as INT).into()],
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
_ => Err(err),
|
_ => Err(err),
|
||||||
})
|
})
|
||||||
@ -364,12 +360,12 @@ mod array_functions {
|
|||||||
}
|
}
|
||||||
#[rhai_fn(name = "reduce", return_raw)]
|
#[rhai_fn(name = "reduce", return_raw)]
|
||||||
pub fn reduce_with_initial(
|
pub fn reduce_with_initial(
|
||||||
context: NativeCallContext,
|
ctx: NativeCallContext,
|
||||||
list: &mut Array,
|
list: &mut Array,
|
||||||
reducer: FnPtr,
|
reducer: FnPtr,
|
||||||
initial: FnPtr,
|
initial: FnPtr,
|
||||||
) -> Result<Dynamic, Box<EvalAltResult>> {
|
) -> Result<Dynamic, Box<EvalAltResult>> {
|
||||||
let mut result = initial.call_dynamic(context, None, []).map_err(|err| {
|
let mut result = initial.call_dynamic(ctx, None, []).map_err(|err| {
|
||||||
Box::new(EvalAltResult::ErrorInFunctionCall(
|
Box::new(EvalAltResult::ErrorInFunctionCall(
|
||||||
"reduce".to_string(),
|
"reduce".to_string(),
|
||||||
err,
|
err,
|
||||||
@ -379,16 +375,12 @@ mod array_functions {
|
|||||||
|
|
||||||
for (i, item) in list.iter().enumerate() {
|
for (i, item) in list.iter().enumerate() {
|
||||||
result = reducer
|
result = reducer
|
||||||
.call_dynamic(context, None, [result.clone(), item.clone()])
|
.call_dynamic(ctx, None, [result.clone(), item.clone()])
|
||||||
.or_else(|err| match *err {
|
.or_else(|err| match *err {
|
||||||
EvalAltResult::ErrorFunctionNotFound(fn_sig, _)
|
EvalAltResult::ErrorFunctionNotFound(fn_sig, _)
|
||||||
if fn_sig.starts_with(reducer.fn_name()) =>
|
if fn_sig.starts_with(reducer.fn_name()) =>
|
||||||
{
|
{
|
||||||
reducer.call_dynamic(
|
reducer.call_dynamic(ctx, None, [result, item.clone(), (i as INT).into()])
|
||||||
context,
|
|
||||||
None,
|
|
||||||
[result, item.clone(), (i as INT).into()],
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
_ => Err(err),
|
_ => Err(err),
|
||||||
})
|
})
|
||||||
@ -405,7 +397,7 @@ mod array_functions {
|
|||||||
}
|
}
|
||||||
#[rhai_fn(return_raw)]
|
#[rhai_fn(return_raw)]
|
||||||
pub fn reduce_rev(
|
pub fn reduce_rev(
|
||||||
context: NativeCallContext,
|
ctx: NativeCallContext,
|
||||||
list: &mut Array,
|
list: &mut Array,
|
||||||
reducer: FnPtr,
|
reducer: FnPtr,
|
||||||
) -> Result<Dynamic, Box<EvalAltResult>> {
|
) -> Result<Dynamic, Box<EvalAltResult>> {
|
||||||
@ -413,16 +405,12 @@ mod array_functions {
|
|||||||
|
|
||||||
for (i, item) in list.iter().enumerate().rev() {
|
for (i, item) in list.iter().enumerate().rev() {
|
||||||
result = reducer
|
result = reducer
|
||||||
.call_dynamic(context, None, [result.clone(), item.clone()])
|
.call_dynamic(ctx, None, [result.clone(), item.clone()])
|
||||||
.or_else(|err| match *err {
|
.or_else(|err| match *err {
|
||||||
EvalAltResult::ErrorFunctionNotFound(fn_sig, _)
|
EvalAltResult::ErrorFunctionNotFound(fn_sig, _)
|
||||||
if fn_sig.starts_with(reducer.fn_name()) =>
|
if fn_sig.starts_with(reducer.fn_name()) =>
|
||||||
{
|
{
|
||||||
reducer.call_dynamic(
|
reducer.call_dynamic(ctx, None, [result, item.clone(), (i as INT).into()])
|
||||||
context,
|
|
||||||
None,
|
|
||||||
[result, item.clone(), (i as INT).into()],
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
_ => Err(err),
|
_ => Err(err),
|
||||||
})
|
})
|
||||||
@ -439,12 +427,12 @@ mod array_functions {
|
|||||||
}
|
}
|
||||||
#[rhai_fn(name = "reduce_rev", return_raw)]
|
#[rhai_fn(name = "reduce_rev", return_raw)]
|
||||||
pub fn reduce_rev_with_initial(
|
pub fn reduce_rev_with_initial(
|
||||||
context: NativeCallContext,
|
ctx: NativeCallContext,
|
||||||
list: &mut Array,
|
list: &mut Array,
|
||||||
reducer: FnPtr,
|
reducer: FnPtr,
|
||||||
initial: FnPtr,
|
initial: FnPtr,
|
||||||
) -> Result<Dynamic, Box<EvalAltResult>> {
|
) -> Result<Dynamic, Box<EvalAltResult>> {
|
||||||
let mut result = initial.call_dynamic(context, None, []).map_err(|err| {
|
let mut result = initial.call_dynamic(ctx, None, []).map_err(|err| {
|
||||||
Box::new(EvalAltResult::ErrorInFunctionCall(
|
Box::new(EvalAltResult::ErrorInFunctionCall(
|
||||||
"reduce".to_string(),
|
"reduce".to_string(),
|
||||||
err,
|
err,
|
||||||
@ -454,16 +442,12 @@ mod array_functions {
|
|||||||
|
|
||||||
for (i, item) in list.iter().enumerate().rev() {
|
for (i, item) in list.iter().enumerate().rev() {
|
||||||
result = reducer
|
result = reducer
|
||||||
.call_dynamic(context, None, [result.clone(), item.clone()])
|
.call_dynamic(ctx, None, [result.clone(), item.clone()])
|
||||||
.or_else(|err| match *err {
|
.or_else(|err| match *err {
|
||||||
EvalAltResult::ErrorFunctionNotFound(fn_sig, _)
|
EvalAltResult::ErrorFunctionNotFound(fn_sig, _)
|
||||||
if fn_sig.starts_with(reducer.fn_name()) =>
|
if fn_sig.starts_with(reducer.fn_name()) =>
|
||||||
{
|
{
|
||||||
reducer.call_dynamic(
|
reducer.call_dynamic(ctx, None, [result, item.clone(), (i as INT).into()])
|
||||||
context,
|
|
||||||
None,
|
|
||||||
[result, item.clone(), (i as INT).into()],
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
_ => Err(err),
|
_ => Err(err),
|
||||||
})
|
})
|
||||||
@ -480,13 +464,13 @@ mod array_functions {
|
|||||||
}
|
}
|
||||||
#[rhai_fn(return_raw)]
|
#[rhai_fn(return_raw)]
|
||||||
pub fn sort(
|
pub fn sort(
|
||||||
context: NativeCallContext,
|
ctx: NativeCallContext,
|
||||||
list: &mut Array,
|
list: &mut Array,
|
||||||
comparer: FnPtr,
|
comparer: FnPtr,
|
||||||
) -> Result<Dynamic, Box<EvalAltResult>> {
|
) -> Result<Dynamic, Box<EvalAltResult>> {
|
||||||
list.sort_by(|x, y| {
|
list.sort_by(|x, y| {
|
||||||
comparer
|
comparer
|
||||||
.call_dynamic(context, None, [x.clone(), y.clone()])
|
.call_dynamic(ctx, None, [x.clone(), y.clone()])
|
||||||
.ok()
|
.ok()
|
||||||
.and_then(|v| v.as_int().ok())
|
.and_then(|v| v.as_int().ok())
|
||||||
.map(|v| {
|
.map(|v| {
|
||||||
@ -516,7 +500,7 @@ mod array_functions {
|
|||||||
}
|
}
|
||||||
#[rhai_fn(return_raw)]
|
#[rhai_fn(return_raw)]
|
||||||
pub fn drain(
|
pub fn drain(
|
||||||
context: NativeCallContext,
|
ctx: NativeCallContext,
|
||||||
list: &mut Array,
|
list: &mut Array,
|
||||||
filter: FnPtr,
|
filter: FnPtr,
|
||||||
) -> Result<Dynamic, Box<EvalAltResult>> {
|
) -> Result<Dynamic, Box<EvalAltResult>> {
|
||||||
@ -528,12 +512,12 @@ mod array_functions {
|
|||||||
i -= 1;
|
i -= 1;
|
||||||
|
|
||||||
if filter
|
if filter
|
||||||
.call_dynamic(context, None, [list[i].clone()])
|
.call_dynamic(ctx, None, [list[i].clone()])
|
||||||
.or_else(|err| match *err {
|
.or_else(|err| match *err {
|
||||||
EvalAltResult::ErrorFunctionNotFound(fn_sig, _)
|
EvalAltResult::ErrorFunctionNotFound(fn_sig, _)
|
||||||
if fn_sig.starts_with(filter.fn_name()) =>
|
if fn_sig.starts_with(filter.fn_name()) =>
|
||||||
{
|
{
|
||||||
filter.call_dynamic(context, None, [list[i].clone(), (i as INT).into()])
|
filter.call_dynamic(ctx, None, [list[i].clone(), (i as INT).into()])
|
||||||
}
|
}
|
||||||
_ => Err(err),
|
_ => Err(err),
|
||||||
})
|
})
|
||||||
@ -575,7 +559,7 @@ mod array_functions {
|
|||||||
}
|
}
|
||||||
#[rhai_fn(return_raw)]
|
#[rhai_fn(return_raw)]
|
||||||
pub fn retain(
|
pub fn retain(
|
||||||
context: NativeCallContext,
|
ctx: NativeCallContext,
|
||||||
list: &mut Array,
|
list: &mut Array,
|
||||||
filter: FnPtr,
|
filter: FnPtr,
|
||||||
) -> Result<Dynamic, Box<EvalAltResult>> {
|
) -> Result<Dynamic, Box<EvalAltResult>> {
|
||||||
@ -587,12 +571,12 @@ mod array_functions {
|
|||||||
i -= 1;
|
i -= 1;
|
||||||
|
|
||||||
if !filter
|
if !filter
|
||||||
.call_dynamic(context, None, [list[i].clone()])
|
.call_dynamic(ctx, None, [list[i].clone()])
|
||||||
.or_else(|err| match *err {
|
.or_else(|err| match *err {
|
||||||
EvalAltResult::ErrorFunctionNotFound(fn_sig, _)
|
EvalAltResult::ErrorFunctionNotFound(fn_sig, _)
|
||||||
if fn_sig.starts_with(filter.fn_name()) =>
|
if fn_sig.starts_with(filter.fn_name()) =>
|
||||||
{
|
{
|
||||||
filter.call_dynamic(context, None, [list[i].clone(), (i as INT).into()])
|
filter.call_dynamic(ctx, None, [list[i].clone(), (i as INT).into()])
|
||||||
}
|
}
|
||||||
_ => Err(err),
|
_ => Err(err),
|
||||||
})
|
})
|
||||||
|
@ -251,20 +251,16 @@ mod string_functions {
|
|||||||
|
|
||||||
#[rhai_fn(return_raw)]
|
#[rhai_fn(return_raw)]
|
||||||
pub fn pad(
|
pub fn pad(
|
||||||
_context: NativeCallContext,
|
_ctx: NativeCallContext,
|
||||||
s: &mut ImmutableString,
|
s: &mut ImmutableString,
|
||||||
len: INT,
|
len: INT,
|
||||||
ch: char,
|
ch: char,
|
||||||
) -> Result<Dynamic, Box<EvalAltResult>> {
|
) -> Result<Dynamic, Box<EvalAltResult>> {
|
||||||
// Check if string will be over max size limit
|
// Check if string will be over max size limit
|
||||||
#[cfg(not(feature = "unchecked"))]
|
#[cfg(not(feature = "unchecked"))]
|
||||||
if _context.engine().max_string_size() > 0
|
if _ctx.engine().max_string_size() > 0 && len as usize > _ctx.engine().max_string_size() {
|
||||||
&& len as usize > _context.engine().max_string_size()
|
|
||||||
{
|
|
||||||
return EvalAltResult::ErrorDataTooLarge(
|
return EvalAltResult::ErrorDataTooLarge(
|
||||||
"Length of string".to_string(),
|
"Length of string".to_string(),
|
||||||
_context.engine().max_string_size(),
|
|
||||||
len as usize,
|
|
||||||
Position::none(),
|
Position::none(),
|
||||||
)
|
)
|
||||||
.into();
|
.into();
|
||||||
@ -281,13 +277,10 @@ mod string_functions {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(feature = "unchecked"))]
|
#[cfg(not(feature = "unchecked"))]
|
||||||
if _context.engine().max_string_size() > 0
|
if _ctx.engine().max_string_size() > 0 && s.len() > _ctx.engine().max_string_size()
|
||||||
&& s.len() > _context.engine().max_string_size()
|
|
||||||
{
|
{
|
||||||
return EvalAltResult::ErrorDataTooLarge(
|
return EvalAltResult::ErrorDataTooLarge(
|
||||||
"Length of string".to_string(),
|
"Length of string".to_string(),
|
||||||
_context.engine().max_string_size(),
|
|
||||||
s.len(),
|
|
||||||
Position::none(),
|
Position::none(),
|
||||||
)
|
)
|
||||||
.into();
|
.into();
|
||||||
@ -299,20 +292,16 @@ mod string_functions {
|
|||||||
}
|
}
|
||||||
#[rhai_fn(name = "pad", return_raw)]
|
#[rhai_fn(name = "pad", return_raw)]
|
||||||
pub fn pad_with_string(
|
pub fn pad_with_string(
|
||||||
_context: NativeCallContext,
|
_ctx: NativeCallContext,
|
||||||
s: &mut ImmutableString,
|
s: &mut ImmutableString,
|
||||||
len: INT,
|
len: INT,
|
||||||
padding: &str,
|
padding: &str,
|
||||||
) -> Result<Dynamic, Box<EvalAltResult>> {
|
) -> Result<Dynamic, Box<EvalAltResult>> {
|
||||||
// Check if string will be over max size limit
|
// Check if string will be over max size limit
|
||||||
#[cfg(not(feature = "unchecked"))]
|
#[cfg(not(feature = "unchecked"))]
|
||||||
if _context.engine().max_string_size() > 0
|
if _ctx.engine().max_string_size() > 0 && len as usize > _ctx.engine().max_string_size() {
|
||||||
&& len as usize > _context.engine().max_string_size()
|
|
||||||
{
|
|
||||||
return EvalAltResult::ErrorDataTooLarge(
|
return EvalAltResult::ErrorDataTooLarge(
|
||||||
"Length of string".to_string(),
|
"Length of string".to_string(),
|
||||||
_context.engine().max_string_size(),
|
|
||||||
len as usize,
|
|
||||||
Position::none(),
|
Position::none(),
|
||||||
)
|
)
|
||||||
.into();
|
.into();
|
||||||
@ -336,13 +325,10 @@ mod string_functions {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(feature = "unchecked"))]
|
#[cfg(not(feature = "unchecked"))]
|
||||||
if _context.engine().max_string_size() > 0
|
if _ctx.engine().max_string_size() > 0 && s.len() > _ctx.engine().max_string_size()
|
||||||
&& s.len() > _context.engine().max_string_size()
|
|
||||||
{
|
{
|
||||||
return EvalAltResult::ErrorDataTooLarge(
|
return EvalAltResult::ErrorDataTooLarge(
|
||||||
"Length of string".to_string(),
|
"Length of string".to_string(),
|
||||||
_context.engine().max_string_size(),
|
|
||||||
s.len(),
|
|
||||||
Position::none(),
|
Position::none(),
|
||||||
)
|
)
|
||||||
.into();
|
.into();
|
||||||
|
@ -83,11 +83,11 @@ pub enum EvalAltResult {
|
|||||||
ErrorTooManyModules(Position),
|
ErrorTooManyModules(Position),
|
||||||
/// Call stack over maximum limit.
|
/// Call stack over maximum limit.
|
||||||
ErrorStackOverflow(Position),
|
ErrorStackOverflow(Position),
|
||||||
/// Data value over maximum size limit. Wrapped values are the type name, maximum size and current size.
|
/// Data value over maximum size limit. Wrapped value is the type name.
|
||||||
ErrorDataTooLarge(String, usize, usize, Position),
|
ErrorDataTooLarge(String, Position),
|
||||||
/// The script is prematurely terminated.
|
/// The script is prematurely terminated. Wrapped value is the termination token.
|
||||||
ErrorTerminated(Position),
|
ErrorTerminated(Dynamic, Position),
|
||||||
/// Run-time error encountered. Wrapped value is the error.
|
/// Run-time error encountered. Wrapped value is the error token.
|
||||||
ErrorRuntime(Dynamic, Position),
|
ErrorRuntime(Dynamic, Position),
|
||||||
|
|
||||||
/// Breaking out of loops - not an error if within a loop.
|
/// Breaking out of loops - not an error if within a loop.
|
||||||
@ -135,8 +135,8 @@ impl EvalAltResult {
|
|||||||
Self::ErrorTooManyOperations(_) => "Too many operations",
|
Self::ErrorTooManyOperations(_) => "Too many operations",
|
||||||
Self::ErrorTooManyModules(_) => "Too many modules imported",
|
Self::ErrorTooManyModules(_) => "Too many modules imported",
|
||||||
Self::ErrorStackOverflow(_) => "Stack overflow",
|
Self::ErrorStackOverflow(_) => "Stack overflow",
|
||||||
Self::ErrorDataTooLarge(_, _, _, _) => "Data size exceeds maximum limit",
|
Self::ErrorDataTooLarge(_, _) => "Data size exceeds maximum limit",
|
||||||
Self::ErrorTerminated(_) => "Script terminated.",
|
Self::ErrorTerminated(_,_) => "Script terminated.",
|
||||||
Self::ErrorRuntime(_, _) => "Runtime error",
|
Self::ErrorRuntime(_, _) => "Runtime error",
|
||||||
Self::LoopBreak(true, _) => "Break statement not inside a loop",
|
Self::LoopBreak(true, _) => "Break statement not inside a loop",
|
||||||
Self::LoopBreak(false, _) => "Continue statement not inside a loop",
|
Self::LoopBreak(false, _) => "Continue statement not inside a loop",
|
||||||
@ -185,7 +185,7 @@ impl fmt::Display for EvalAltResult {
|
|||||||
| Self::ErrorTooManyOperations(_)
|
| Self::ErrorTooManyOperations(_)
|
||||||
| Self::ErrorTooManyModules(_)
|
| Self::ErrorTooManyModules(_)
|
||||||
| Self::ErrorStackOverflow(_)
|
| Self::ErrorStackOverflow(_)
|
||||||
| Self::ErrorTerminated(_) => f.write_str(desc)?,
|
| Self::ErrorTerminated(_, _) => f.write_str(desc)?,
|
||||||
|
|
||||||
Self::ErrorRuntime(d, _) if d.is::<ImmutableString>() => {
|
Self::ErrorRuntime(d, _) if d.is::<ImmutableString>() => {
|
||||||
let s = d.as_str().unwrap();
|
let s = d.as_str().unwrap();
|
||||||
@ -237,9 +237,7 @@ impl fmt::Display for EvalAltResult {
|
|||||||
"String index {} is out of bounds: only {} characters in the string",
|
"String index {} is out of bounds: only {} characters in the string",
|
||||||
index, max
|
index, max
|
||||||
)?,
|
)?,
|
||||||
Self::ErrorDataTooLarge(typ, max, size, _) => {
|
Self::ErrorDataTooLarge(typ, _) => write!(f, "{} exceeds maximum limit", typ)?,
|
||||||
write!(f, "{} ({}) exceeds the maximum limit ({})", typ, size, max)?
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Do not write any position if None
|
// Do not write any position if None
|
||||||
@ -297,8 +295,8 @@ impl EvalAltResult {
|
|||||||
Self::ErrorTooManyOperations(_)
|
Self::ErrorTooManyOperations(_)
|
||||||
| Self::ErrorTooManyModules(_)
|
| Self::ErrorTooManyModules(_)
|
||||||
| Self::ErrorStackOverflow(_)
|
| Self::ErrorStackOverflow(_)
|
||||||
| Self::ErrorDataTooLarge(_, _, _, _)
|
| Self::ErrorDataTooLarge(_, _)
|
||||||
| Self::ErrorTerminated(_) => false,
|
| Self::ErrorTerminated(_, _) => false,
|
||||||
|
|
||||||
Self::LoopBreak(_, _) | Self::Return(_, _) => unreachable!(),
|
Self::LoopBreak(_, _) | Self::Return(_, _) => unreachable!(),
|
||||||
}
|
}
|
||||||
@ -313,9 +311,9 @@ impl EvalAltResult {
|
|||||||
Self::ErrorTooManyOperations(_)
|
Self::ErrorTooManyOperations(_)
|
||||||
| Self::ErrorTooManyModules(_)
|
| Self::ErrorTooManyModules(_)
|
||||||
| Self::ErrorStackOverflow(_)
|
| Self::ErrorStackOverflow(_)
|
||||||
| Self::ErrorDataTooLarge(_, _, _, _) => true,
|
| Self::ErrorDataTooLarge(_, _) => true,
|
||||||
|
|
||||||
Self::ErrorTerminated(_) => true,
|
Self::ErrorTerminated(_, _) => true,
|
||||||
|
|
||||||
Self::LoopBreak(_, _) | Self::Return(_, _) => unreachable!(),
|
Self::LoopBreak(_, _) | Self::Return(_, _) => unreachable!(),
|
||||||
|
|
||||||
@ -349,8 +347,8 @@ impl EvalAltResult {
|
|||||||
| Self::ErrorTooManyOperations(pos)
|
| Self::ErrorTooManyOperations(pos)
|
||||||
| Self::ErrorTooManyModules(pos)
|
| Self::ErrorTooManyModules(pos)
|
||||||
| Self::ErrorStackOverflow(pos)
|
| Self::ErrorStackOverflow(pos)
|
||||||
| Self::ErrorDataTooLarge(_, _, _, pos)
|
| Self::ErrorDataTooLarge(_, pos)
|
||||||
| Self::ErrorTerminated(pos)
|
| Self::ErrorTerminated(_, pos)
|
||||||
| Self::ErrorRuntime(_, pos)
|
| Self::ErrorRuntime(_, pos)
|
||||||
| Self::LoopBreak(_, pos)
|
| Self::LoopBreak(_, pos)
|
||||||
| Self::Return(_, pos) => *pos,
|
| Self::Return(_, pos) => *pos,
|
||||||
@ -383,8 +381,8 @@ impl EvalAltResult {
|
|||||||
| Self::ErrorTooManyOperations(pos)
|
| Self::ErrorTooManyOperations(pos)
|
||||||
| Self::ErrorTooManyModules(pos)
|
| Self::ErrorTooManyModules(pos)
|
||||||
| Self::ErrorStackOverflow(pos)
|
| Self::ErrorStackOverflow(pos)
|
||||||
| Self::ErrorDataTooLarge(_, _, _, pos)
|
| Self::ErrorDataTooLarge(_, pos)
|
||||||
| Self::ErrorTerminated(pos)
|
| Self::ErrorTerminated(_, pos)
|
||||||
| Self::ErrorRuntime(_, pos)
|
| Self::ErrorRuntime(_, pos)
|
||||||
| Self::LoopBreak(_, pos)
|
| Self::LoopBreak(_, pos)
|
||||||
| Self::Return(_, pos) => *pos = new_position,
|
| Self::Return(_, pos) => *pos = new_position,
|
||||||
|
Loading…
Reference in New Issue
Block a user