Add constant NO_POS.
This commit is contained in:
parent
6f3ce96d9d
commit
d7d6f74dfd
@ -22,6 +22,7 @@ Breaking changes
|
||||
* `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`.
|
||||
* `ParseErrorType::BadInput` now wraps a `LexError` instead of a text string.
|
||||
|
||||
New features
|
||||
------------
|
||||
|
@ -294,9 +294,8 @@ engine.register_custom_syntax_raw(
|
||||
"update" | "check" | "add" | "remove" => Ok(Some("$ident$".to_string())),
|
||||
"cleanup" => Ok(None),
|
||||
cmd => Err(ParseError(Box::new(ParseErrorType::BadInput(
|
||||
format!("Improper command: {}", cmd))),
|
||||
Position::none(),
|
||||
)),
|
||||
LexError::ImproperSymbol(format!("Improper command: {}", cmd))
|
||||
)), NO_POS)),
|
||||
},
|
||||
// perform command arg ...
|
||||
3 => match (stream[1].as_str(), stream[2].as_str()) {
|
||||
@ -308,9 +307,10 @@ engine.register_custom_syntax_raw(
|
||||
("add", arg) => Ok(None),
|
||||
("remove", arg) => Ok(None),
|
||||
(cmd, arg) => Err(ParseError(Box::new(ParseErrorType::BadInput(
|
||||
format!("Invalid argument for command {}: {}", cmd, arg))),
|
||||
Position::none(),
|
||||
)),
|
||||
LexError::ImproperSymbol(
|
||||
format!("Invalid argument for command {}: {}", cmd, arg)
|
||||
)
|
||||
)), NO_POS)),
|
||||
},
|
||||
_ => unreachable!(),
|
||||
},
|
||||
@ -335,8 +335,8 @@ where:
|
||||
|
||||
The return value is `Result<Option<String>, ParseError>` where:
|
||||
|
||||
| Value | Description |
|
||||
| ------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `Ok(None)` | parsing complete and there are no more symbols to match |
|
||||
| `Ok(Some(symbol))` | next symbol to match, which can also be `"$expr$"`, `"$ident$"` or `"$block$"` |
|
||||
| `Err(ParseError)` | error that is reflected back to the [`Engine`].<br/>Normally this is `ParseError(ParseErrorType::BadInput(message), Position::none())` to indicate that there is a syntax error, but it can be any `ParseError`. |
|
||||
| Value | Description |
|
||||
| ------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `Ok(None)` | parsing complete and there are no more symbols to match |
|
||||
| `Ok(Some(symbol))` | next symbol to match, which can also be `"$expr$"`, `"$ident$"` or `"$block$"` |
|
||||
| `Err(ParseError)` | error that is reflected back to the [`Engine`].<br/>Normally this is `ParseError(ParseErrorType::BadInput(LexError::ImproperSymbol(message)), NO_POS)` to indicate that there is a syntax error, but it can be any `ParseError`. |
|
||||
|
@ -21,11 +21,11 @@ engine.on_var(|name, index, context| {
|
||||
"MYSTIC_NUMBER" => Ok(Some((42 as INT).into())),
|
||||
// Override a variable - make it not found even if it exists!
|
||||
"DO_NOT_USE" => Err(Box::new(
|
||||
EvalAltResult::ErrorVariableNotFound(name.to_string(), Position::none())
|
||||
EvalAltResult::ErrorVariableNotFound(name.to_string(), NO_POS)
|
||||
)),
|
||||
// Silently maps 'chameleon' into 'innocent'.
|
||||
"chameleon" => context.scope.get_value("innocent").map(Some).ok_or_else(|| Box::new(
|
||||
EvalAltResult::ErrorVariableNotFound(name.to_string(), Position::none())
|
||||
EvalAltResult::ErrorVariableNotFound(name.to_string(), NO_POS)
|
||||
)),
|
||||
// Return Ok(None) to continue with the normal variable resolution process.
|
||||
_ => Ok(None)
|
||||
@ -82,8 +82,8 @@ where:
|
||||
|
||||
The return value is `Result<Option<Dynamic>, Box<EvalAltResult>>` where:
|
||||
|
||||
| Value | Description |
|
||||
| ------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
||||
| `Ok(None)` | normal variable resolution process should continue, i.e. continue searching through the [`Scope`] |
|
||||
| `Ok(Some(Dynamic))` | value of the variable, treated as a constant |
|
||||
| `Err(Box<EvalAltResult>)` | error that is reflected back to the [`Engine`].<br/>Normally this is `EvalAltResult::ErrorVariableNotFound(var_name, Position::none())` to indicate that the variable does not exist, but it can be any `EvalAltResult`. |
|
||||
| Value | Description |
|
||||
| ------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `Ok(None)` | normal variable resolution process should continue, i.e. continue searching through the [`Scope`] |
|
||||
| `Ok(Some(Dynamic))` | value of the variable, treated as a constant |
|
||||
| `Err(Box<EvalAltResult>)` | error that is reflected back to the [`Engine`].<br/>Normally this is `EvalAltResult::ErrorVariableNotFound(var_name, NO_POS)` to indicate that the variable does not exist, but it can be any `EvalAltResult`. |
|
||||
|
@ -117,7 +117,7 @@ pub fn greet(context: NativeCallContext, callback: FnPtr)
|
||||
The native call context is also useful in another scenario: protecting a function from malicious scripts.
|
||||
|
||||
```rust
|
||||
use rhai::{Dynamic, Array, NativeCallContext, EvalAltResult, Position};
|
||||
use rhai::{Dynamic, Array, NativeCallContext, EvalAltResult, NO_POS};
|
||||
use rhai::plugin::*; // a "prelude" import for macros
|
||||
|
||||
// This function builds an array of arbitrary size, but is protected
|
||||
@ -137,7 +137,7 @@ pub fn grow(context: NativeCallContext, size: i64)
|
||||
"Size to grow".to_string(),
|
||||
context.engine().max_array_size(),
|
||||
size as usize,
|
||||
Position::none(),
|
||||
NO_POS,
|
||||
).into();
|
||||
}
|
||||
|
||||
|
@ -376,7 +376,7 @@ mod my_module {
|
||||
The native call context is also useful in another scenario: protecting a function from malicious scripts.
|
||||
|
||||
```rust
|
||||
use rhai::{Dynamic, Array, NativeCallContext, EvalAltResult, Position};
|
||||
use rhai::{Dynamic, Array, NativeCallContext, EvalAltResult, NO_POS};
|
||||
use rhai::plugin::*; // a "prelude" import for macros
|
||||
|
||||
#[export_module]
|
||||
@ -397,7 +397,7 @@ mod my_module {
|
||||
"Size to grow".to_string(),
|
||||
context.engine().max_array_size(),
|
||||
size as usize,
|
||||
Position::none(),
|
||||
NO_POS,
|
||||
).into();
|
||||
}
|
||||
|
||||
|
@ -11,7 +11,7 @@ use crate::r#unsafe::unsafe_cast_var_name_to_lifetime;
|
||||
use crate::result::EvalAltResult;
|
||||
use crate::scope::{EntryType as ScopeEntryType, Scope};
|
||||
use crate::syntax::CustomSyntax;
|
||||
use crate::token::Position;
|
||||
use crate::token::{Position, NO_POS};
|
||||
use crate::{calc_native_fn_hash, StaticVec};
|
||||
|
||||
#[cfg(not(feature = "no_index"))]
|
||||
@ -351,7 +351,7 @@ impl<'a> Target<'a> {
|
||||
#[cfg(not(feature = "no_index"))]
|
||||
Self::StringChar(_, _, ch) => {
|
||||
let char_value = ch.clone();
|
||||
self.set_value((char_value, Position::none())).unwrap();
|
||||
self.set_value((char_value, NO_POS)).unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -993,7 +993,7 @@ impl Engine {
|
||||
{
|
||||
EvalAltResult::ErrorIndexingType(
|
||||
self.map_type_name(val_type_name).into(),
|
||||
Position::none(),
|
||||
NO_POS,
|
||||
)
|
||||
}
|
||||
err => err,
|
||||
@ -1463,20 +1463,16 @@ impl Engine {
|
||||
.map(|(v, _)| v.into())
|
||||
.map_err(|err| match *err {
|
||||
EvalAltResult::ErrorFunctionNotFound(fn_sig, _) if fn_sig.ends_with(']') => {
|
||||
Box::new(EvalAltResult::ErrorIndexingType(
|
||||
type_name.into(),
|
||||
Position::none(),
|
||||
))
|
||||
Box::new(EvalAltResult::ErrorIndexingType(type_name.into(), NO_POS))
|
||||
}
|
||||
_ => err,
|
||||
})
|
||||
}
|
||||
|
||||
_ => EvalAltResult::ErrorIndexingType(
|
||||
self.map_type_name(val.type_name()).into(),
|
||||
Position::none(),
|
||||
)
|
||||
.into(),
|
||||
_ => {
|
||||
EvalAltResult::ErrorIndexingType(self.map_type_name(val.type_name()).into(), NO_POS)
|
||||
.into()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -2036,7 +2032,7 @@ impl Engine {
|
||||
let value = if let EvalAltResult::ErrorRuntime(ref x, _) = err {
|
||||
x.clone()
|
||||
} else {
|
||||
err.set_position(Position::none());
|
||||
err.set_position(NO_POS);
|
||||
err.to_string().into()
|
||||
};
|
||||
|
||||
@ -2298,26 +2294,18 @@ impl Engine {
|
||||
let (_arr, _map, s) = calc_size(result.as_ref().unwrap());
|
||||
|
||||
if s > self.max_string_size() {
|
||||
return EvalAltResult::ErrorDataTooLarge(
|
||||
"Length of string".to_string(),
|
||||
Position::none(),
|
||||
)
|
||||
.into();
|
||||
return EvalAltResult::ErrorDataTooLarge("Length of string".to_string(), NO_POS).into();
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "no_index"))]
|
||||
if _arr > self.max_array_size() {
|
||||
return EvalAltResult::ErrorDataTooLarge("Size of array".to_string(), Position::none())
|
||||
.into();
|
||||
return EvalAltResult::ErrorDataTooLarge("Size of array".to_string(), NO_POS).into();
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "no_object"))]
|
||||
if _map > self.max_map_size() {
|
||||
return EvalAltResult::ErrorDataTooLarge(
|
||||
"Size of object map".to_string(),
|
||||
Position::none(),
|
||||
)
|
||||
.into();
|
||||
return EvalAltResult::ErrorDataTooLarge("Size of object map".to_string(), NO_POS)
|
||||
.into();
|
||||
}
|
||||
|
||||
result
|
||||
@ -2331,14 +2319,14 @@ impl Engine {
|
||||
#[cfg(not(feature = "unchecked"))]
|
||||
// Guard against too many operations
|
||||
if self.max_operations() > 0 && state.operations > self.max_operations() {
|
||||
return EvalAltResult::ErrorTooManyOperations(Position::none()).into();
|
||||
return EvalAltResult::ErrorTooManyOperations(NO_POS).into();
|
||||
}
|
||||
|
||||
// Report progress - only in steps
|
||||
if let Some(progress) = &self.progress {
|
||||
if let Some(token) = progress(&state.operations) {
|
||||
// Terminate script if progress returns a termination token
|
||||
return EvalAltResult::ErrorTerminated(token, Position::none()).into();
|
||||
return EvalAltResult::ErrorTerminated(token, NO_POS).into();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -8,7 +8,7 @@ use crate::optimize::OptimizationLevel;
|
||||
use crate::parse_error::ParseError;
|
||||
use crate::result::EvalAltResult;
|
||||
use crate::scope::Scope;
|
||||
use crate::token::Position;
|
||||
use crate::token::{Position, NO_POS};
|
||||
|
||||
#[cfg(not(feature = "no_index"))]
|
||||
use crate::{
|
||||
@ -1391,7 +1391,7 @@ impl Engine {
|
||||
EvalAltResult::ErrorMismatchOutputType(
|
||||
self.map_type_name(type_name::<T>()).into(),
|
||||
typ.into(),
|
||||
Position::none(),
|
||||
NO_POS,
|
||||
)
|
||||
.into()
|
||||
});
|
||||
@ -1527,7 +1527,7 @@ impl Engine {
|
||||
EvalAltResult::ErrorMismatchOutputType(
|
||||
self.map_type_name(type_name::<T>()).into(),
|
||||
typ.into(),
|
||||
Position::none(),
|
||||
NO_POS,
|
||||
)
|
||||
.into()
|
||||
});
|
||||
@ -1617,7 +1617,7 @@ impl Engine {
|
||||
) -> Result<Dynamic, Box<EvalAltResult>> {
|
||||
let fn_def = lib
|
||||
.get_script_fn(name, args.len(), true)
|
||||
.ok_or_else(|| EvalAltResult::ErrorFunctionNotFound(name.into(), Position::none()))?;
|
||||
.ok_or_else(|| EvalAltResult::ErrorFunctionNotFound(name.into(), NO_POS))?;
|
||||
|
||||
let mut state = Default::default();
|
||||
let mut mods = Default::default();
|
||||
|
@ -14,7 +14,7 @@ use crate::parse_error::ParseErrorType;
|
||||
use crate::result::EvalAltResult;
|
||||
use crate::scope::Scope;
|
||||
use crate::stdlib::ops::Deref;
|
||||
use crate::token::Position;
|
||||
use crate::token::NO_POS;
|
||||
use crate::utils::ImmutableString;
|
||||
use crate::{calc_native_fn_hash, calc_script_fn_hash, StaticVec, INT};
|
||||
|
||||
@ -159,7 +159,7 @@ pub fn ensure_no_data_race(
|
||||
{
|
||||
return EvalAltResult::ErrorDataRace(
|
||||
format!("argument #{} of function '{}'", n + 1 + skip, fn_name),
|
||||
Position::none(),
|
||||
NO_POS,
|
||||
)
|
||||
.into();
|
||||
}
|
||||
@ -223,7 +223,7 @@ impl Engine {
|
||||
EvalAltResult::ErrorMismatchOutputType(
|
||||
self.map_type_name(type_name::<ImmutableString>()).into(),
|
||||
typ.into(),
|
||||
Position::none(),
|
||||
NO_POS,
|
||||
)
|
||||
})?)
|
||||
.into(),
|
||||
@ -234,7 +234,7 @@ impl Engine {
|
||||
EvalAltResult::ErrorMismatchOutputType(
|
||||
self.map_type_name(type_name::<ImmutableString>()).into(),
|
||||
typ.into(),
|
||||
Position::none(),
|
||||
NO_POS,
|
||||
)
|
||||
})?)
|
||||
.into(),
|
||||
@ -265,7 +265,7 @@ impl Engine {
|
||||
prop,
|
||||
self.map_type_name(args[0].type_name())
|
||||
),
|
||||
Position::none(),
|
||||
NO_POS,
|
||||
)
|
||||
.into();
|
||||
}
|
||||
@ -279,7 +279,7 @@ impl Engine {
|
||||
self.map_type_name(args[0].type_name()),
|
||||
self.map_type_name(args[1].type_name()),
|
||||
),
|
||||
Position::none(),
|
||||
NO_POS,
|
||||
)
|
||||
.into();
|
||||
}
|
||||
@ -293,7 +293,7 @@ impl Engine {
|
||||
self.map_type_name(args[0].type_name()),
|
||||
self.map_type_name(args[1].type_name()),
|
||||
),
|
||||
Position::none(),
|
||||
NO_POS,
|
||||
)
|
||||
.into();
|
||||
}
|
||||
@ -307,7 +307,7 @@ impl Engine {
|
||||
self.map_type_name(args[0].type_name()),
|
||||
self.map_type_name(args[1].type_name()),
|
||||
),
|
||||
Position::none(),
|
||||
NO_POS,
|
||||
)
|
||||
.into();
|
||||
}
|
||||
@ -326,7 +326,7 @@ impl Engine {
|
||||
.collect::<Vec<_>>()
|
||||
.join(", ")
|
||||
),
|
||||
Position::none(),
|
||||
NO_POS,
|
||||
)
|
||||
.into()
|
||||
}
|
||||
@ -357,9 +357,7 @@ impl Engine {
|
||||
#[cfg(not(feature = "no_function"))]
|
||||
#[cfg(not(feature = "unchecked"))]
|
||||
if level > self.max_call_levels() {
|
||||
return Err(Box::new(
|
||||
EvalAltResult::ErrorStackOverflow(Position::none()),
|
||||
));
|
||||
return Err(Box::new(EvalAltResult::ErrorStackOverflow(NO_POS)));
|
||||
}
|
||||
|
||||
let orig_scope_level = state.scope_level;
|
||||
@ -396,29 +394,25 @@ impl Engine {
|
||||
// Evaluate the function at one higher level of call depth
|
||||
let stmt = &fn_def.body;
|
||||
|
||||
let result = self
|
||||
.eval_stmt(scope, mods, state, unified_lib, this_ptr, stmt, level + 1)
|
||||
.or_else(|err| match *err {
|
||||
// Convert return statement to return value
|
||||
EvalAltResult::Return(x, _) => Ok(x),
|
||||
EvalAltResult::ErrorInFunctionCall(name, err, _) => {
|
||||
EvalAltResult::ErrorInFunctionCall(
|
||||
format!("{} > {}", fn_def.name, name),
|
||||
err,
|
||||
Position::none(),
|
||||
)
|
||||
.into()
|
||||
}
|
||||
// System errors are passed straight-through
|
||||
err if err.is_system_exception() => Err(Box::new(err)),
|
||||
// Other errors are wrapped in `ErrorInFunctionCall`
|
||||
_ => EvalAltResult::ErrorInFunctionCall(
|
||||
fn_def.name.to_string(),
|
||||
err,
|
||||
Position::none(),
|
||||
)
|
||||
.into(),
|
||||
});
|
||||
let result =
|
||||
self.eval_stmt(scope, mods, state, unified_lib, this_ptr, stmt, level + 1)
|
||||
.or_else(|err| match *err {
|
||||
// Convert return statement to return value
|
||||
EvalAltResult::Return(x, _) => Ok(x),
|
||||
EvalAltResult::ErrorInFunctionCall(name, err, _) => {
|
||||
EvalAltResult::ErrorInFunctionCall(
|
||||
format!("{} > {}", fn_def.name, name),
|
||||
err,
|
||||
NO_POS,
|
||||
)
|
||||
.into()
|
||||
}
|
||||
// System errors are passed straight-through
|
||||
err if err.is_system_exception() => Err(Box::new(err)),
|
||||
// Other errors are wrapped in `ErrorInFunctionCall`
|
||||
_ => EvalAltResult::ErrorInFunctionCall(fn_def.name.to_string(), err, NO_POS)
|
||||
.into(),
|
||||
});
|
||||
|
||||
// Remove all local variables
|
||||
scope.rewind(prev_scope_len);
|
||||
@ -519,7 +513,7 @@ impl Engine {
|
||||
fn_name, fn_name
|
||||
)
|
||||
.into(),
|
||||
Position::none(),
|
||||
NO_POS,
|
||||
)
|
||||
.into()
|
||||
}
|
||||
@ -656,9 +650,7 @@ impl Engine {
|
||||
#[cfg(not(feature = "no_function"))]
|
||||
#[cfg(not(feature = "unchecked"))]
|
||||
if _level > self.max_call_levels() {
|
||||
return Err(Box::new(
|
||||
EvalAltResult::ErrorStackOverflow(Position::none()),
|
||||
));
|
||||
return Err(Box::new(EvalAltResult::ErrorStackOverflow(NO_POS)));
|
||||
}
|
||||
|
||||
// Compile the script text
|
||||
@ -1218,7 +1210,7 @@ impl Engine {
|
||||
.collect::<Vec<_>>()
|
||||
.join(", ")
|
||||
),
|
||||
Position::none(),
|
||||
NO_POS,
|
||||
)
|
||||
.into(),
|
||||
}
|
||||
|
@ -6,7 +6,7 @@ use crate::engine::{Engine, EvalContext};
|
||||
use crate::module::Module;
|
||||
use crate::plugin::PluginFunction;
|
||||
use crate::result::EvalAltResult;
|
||||
use crate::token::{is_valid_identifier, Position};
|
||||
use crate::token::{is_valid_identifier, NO_POS};
|
||||
use crate::utils::ImmutableString;
|
||||
use crate::{calc_script_fn_hash, StaticVec};
|
||||
|
||||
@ -215,7 +215,7 @@ impl TryFrom<ImmutableString> for FnPtr {
|
||||
if is_valid_identifier(value.chars()) {
|
||||
Ok(Self(value, Default::default()))
|
||||
} else {
|
||||
EvalAltResult::ErrorFunctionNotFound(value.into(), Position::none()).into()
|
||||
EvalAltResult::ErrorFunctionNotFound(value.into(), NO_POS).into()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -115,11 +115,11 @@ pub use engine::{Engine, EvalContext};
|
||||
pub use fn_native::{FnPtr, NativeCallContext};
|
||||
pub use fn_register::{RegisterFn, RegisterResultFn};
|
||||
pub use module::Module;
|
||||
pub use parse_error::{ParseError, ParseErrorType};
|
||||
pub use parse_error::{LexError, ParseError, ParseErrorType};
|
||||
pub use result::EvalAltResult;
|
||||
pub use scope::Scope;
|
||||
pub use syntax::Expression;
|
||||
pub use token::Position;
|
||||
pub use token::{Position, NO_POS};
|
||||
pub use utils::ImmutableString;
|
||||
|
||||
#[cfg(feature = "internals")]
|
||||
|
@ -5,7 +5,7 @@ use crate::dynamic::{Dynamic, Variant};
|
||||
use crate::fn_native::{CallableFunction, FnCallArgs, IteratorFn, NativeCallContext, SendSync};
|
||||
use crate::fn_register::by_value as cast_arg;
|
||||
use crate::result::EvalAltResult;
|
||||
use crate::token::{Position, Token};
|
||||
use crate::token::{Token, NO_POS};
|
||||
use crate::utils::{ImmutableString, StraightHasherBuilder};
|
||||
use crate::{calc_native_fn_hash, calc_script_fn_hash, StaticVec};
|
||||
|
||||
@ -271,11 +271,11 @@ impl Module {
|
||||
hash_var: u64,
|
||||
) -> Result<&mut Dynamic, Box<EvalAltResult>> {
|
||||
if hash_var == 0 {
|
||||
Err(EvalAltResult::ErrorVariableNotFound(String::new(), Position::none()).into())
|
||||
Err(EvalAltResult::ErrorVariableNotFound(String::new(), NO_POS).into())
|
||||
} else {
|
||||
self.all_variables.get_mut(&hash_var).ok_or_else(|| {
|
||||
EvalAltResult::ErrorVariableNotFound(String::new(), Position::none()).into()
|
||||
})
|
||||
self.all_variables
|
||||
.get_mut(&hash_var)
|
||||
.ok_or_else(|| EvalAltResult::ErrorVariableNotFound(String::new(), NO_POS).into())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -10,7 +10,7 @@ use crate::fn_call::run_builtin_binary_op;
|
||||
use crate::module::Module;
|
||||
use crate::parser::map_dynamic_to_expr;
|
||||
use crate::scope::Scope;
|
||||
use crate::token::{is_valid_identifier, Position};
|
||||
use crate::token::{is_valid_identifier, NO_POS};
|
||||
use crate::{calc_native_fn_hash, StaticVec};
|
||||
|
||||
#[cfg(not(feature = "no_function"))]
|
||||
@ -726,7 +726,7 @@ fn optimize(
|
||||
.iter()
|
||||
.filter(|(_, typ, _)| *typ)
|
||||
.for_each(|(name, _, value)| {
|
||||
if let Some(val) = map_dynamic_to_expr(value, Position::none()) {
|
||||
if let Some(val) = map_dynamic_to_expr(value, NO_POS) {
|
||||
state.push_constant(name, val);
|
||||
}
|
||||
});
|
||||
|
@ -4,7 +4,7 @@ use crate::def_package;
|
||||
use crate::plugin::*;
|
||||
use crate::INT;
|
||||
|
||||
use crate::{result::EvalAltResult, token::Position};
|
||||
use crate::{result::EvalAltResult, token::NO_POS};
|
||||
|
||||
#[cfg(not(feature = "no_float"))]
|
||||
use crate::FLOAT;
|
||||
@ -17,7 +17,7 @@ use crate::stdlib::{format, string::String};
|
||||
|
||||
#[inline(always)]
|
||||
pub fn make_err(msg: impl Into<String>) -> Box<EvalAltResult> {
|
||||
EvalAltResult::ErrorArithmetic(msg.into(), Position::none()).into()
|
||||
EvalAltResult::ErrorArithmetic(msg.into(), NO_POS).into()
|
||||
}
|
||||
|
||||
macro_rules! gen_arithmetic_functions {
|
||||
|
@ -7,7 +7,7 @@ use crate::engine::Array;
|
||||
use crate::fn_native::{FnPtr, NativeCallContext};
|
||||
use crate::plugin::*;
|
||||
use crate::result::EvalAltResult;
|
||||
use crate::token::Position;
|
||||
use crate::token::NO_POS;
|
||||
use crate::utils::ImmutableString;
|
||||
use crate::INT;
|
||||
|
||||
@ -46,7 +46,7 @@ macro_rules! gen_array_functions {
|
||||
#[cfg(not(feature = "unchecked"))]
|
||||
if _ctx.engine().max_array_size() > 0 && len > 0 && (len as usize) > _ctx.engine().max_array_size() {
|
||||
return EvalAltResult::ErrorDataTooLarge(
|
||||
"Size of array".to_string(), Position::none()
|
||||
"Size of array".to_string(), NO_POS
|
||||
).into();
|
||||
}
|
||||
|
||||
@ -219,7 +219,7 @@ mod array_functions {
|
||||
Box::new(EvalAltResult::ErrorInFunctionCall(
|
||||
"map".to_string(),
|
||||
err,
|
||||
Position::none(),
|
||||
NO_POS,
|
||||
))
|
||||
})?,
|
||||
);
|
||||
@ -250,7 +250,7 @@ mod array_functions {
|
||||
Box::new(EvalAltResult::ErrorInFunctionCall(
|
||||
"filter".to_string(),
|
||||
err,
|
||||
Position::none(),
|
||||
NO_POS,
|
||||
))
|
||||
})?
|
||||
.as_bool()
|
||||
@ -283,7 +283,7 @@ mod array_functions {
|
||||
Box::new(EvalAltResult::ErrorInFunctionCall(
|
||||
"filter".to_string(),
|
||||
err,
|
||||
Position::none(),
|
||||
NO_POS,
|
||||
))
|
||||
})?
|
||||
.as_bool()
|
||||
@ -316,7 +316,7 @@ mod array_functions {
|
||||
Box::new(EvalAltResult::ErrorInFunctionCall(
|
||||
"filter".to_string(),
|
||||
err,
|
||||
Position::none(),
|
||||
NO_POS,
|
||||
))
|
||||
})?
|
||||
.as_bool()
|
||||
@ -351,7 +351,7 @@ mod array_functions {
|
||||
Box::new(EvalAltResult::ErrorInFunctionCall(
|
||||
"reduce".to_string(),
|
||||
err,
|
||||
Position::none(),
|
||||
NO_POS,
|
||||
))
|
||||
})?;
|
||||
}
|
||||
@ -369,7 +369,7 @@ mod array_functions {
|
||||
Box::new(EvalAltResult::ErrorInFunctionCall(
|
||||
"reduce".to_string(),
|
||||
err,
|
||||
Position::none(),
|
||||
NO_POS,
|
||||
))
|
||||
})?;
|
||||
|
||||
@ -388,7 +388,7 @@ mod array_functions {
|
||||
Box::new(EvalAltResult::ErrorInFunctionCall(
|
||||
"reduce".to_string(),
|
||||
err,
|
||||
Position::none(),
|
||||
NO_POS,
|
||||
))
|
||||
})?;
|
||||
}
|
||||
@ -418,7 +418,7 @@ mod array_functions {
|
||||
Box::new(EvalAltResult::ErrorInFunctionCall(
|
||||
"reduce".to_string(),
|
||||
err,
|
||||
Position::none(),
|
||||
NO_POS,
|
||||
))
|
||||
})?;
|
||||
}
|
||||
@ -436,7 +436,7 @@ mod array_functions {
|
||||
Box::new(EvalAltResult::ErrorInFunctionCall(
|
||||
"reduce".to_string(),
|
||||
err,
|
||||
Position::none(),
|
||||
NO_POS,
|
||||
))
|
||||
})?;
|
||||
|
||||
@ -455,7 +455,7 @@ mod array_functions {
|
||||
Box::new(EvalAltResult::ErrorInFunctionCall(
|
||||
"reduce".to_string(),
|
||||
err,
|
||||
Position::none(),
|
||||
NO_POS,
|
||||
))
|
||||
})?;
|
||||
}
|
||||
@ -525,7 +525,7 @@ mod array_functions {
|
||||
Box::new(EvalAltResult::ErrorInFunctionCall(
|
||||
"filter".to_string(),
|
||||
err,
|
||||
Position::none(),
|
||||
NO_POS,
|
||||
))
|
||||
})?
|
||||
.as_bool()
|
||||
@ -584,7 +584,7 @@ mod array_functions {
|
||||
Box::new(EvalAltResult::ErrorInFunctionCall(
|
||||
"filter".to_string(),
|
||||
err,
|
||||
Position::none(),
|
||||
NO_POS,
|
||||
))
|
||||
})?
|
||||
.as_bool()
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
use crate::def_package;
|
||||
use crate::plugin::*;
|
||||
use crate::token::Position;
|
||||
use crate::token::NO_POS;
|
||||
use crate::INT;
|
||||
|
||||
#[cfg(not(feature = "no_float"))]
|
||||
@ -85,11 +85,8 @@ mod int_functions {
|
||||
#[rhai_fn(name = "parse_int", return_raw)]
|
||||
pub fn parse_int_radix(s: &str, radix: INT) -> Result<Dynamic, Box<EvalAltResult>> {
|
||||
if radix < 2 || radix > 36 {
|
||||
return EvalAltResult::ErrorArithmetic(
|
||||
format!("Invalid radix: '{}'", radix),
|
||||
Position::none(),
|
||||
)
|
||||
.into();
|
||||
return EvalAltResult::ErrorArithmetic(format!("Invalid radix: '{}'", radix), NO_POS)
|
||||
.into();
|
||||
}
|
||||
|
||||
INT::from_str_radix(s.trim(), radix as u32)
|
||||
@ -97,7 +94,7 @@ mod int_functions {
|
||||
.map_err(|err| {
|
||||
EvalAltResult::ErrorArithmetic(
|
||||
format!("Error parsing integer number '{}': {}", s, err),
|
||||
Position::none(),
|
||||
NO_POS,
|
||||
)
|
||||
.into()
|
||||
})
|
||||
@ -206,11 +203,8 @@ mod float_functions {
|
||||
#[rhai_fn(name = "to_int", return_raw)]
|
||||
pub fn f32_to_int(x: f32) -> Result<Dynamic, Box<EvalAltResult>> {
|
||||
if cfg!(not(feature = "unchecked")) && x > (MAX_INT as f32) {
|
||||
EvalAltResult::ErrorArithmetic(
|
||||
format!("Integer overflow: to_int({})", x),
|
||||
Position::none(),
|
||||
)
|
||||
.into()
|
||||
EvalAltResult::ErrorArithmetic(format!("Integer overflow: to_int({})", x), NO_POS)
|
||||
.into()
|
||||
} else {
|
||||
Ok((x.trunc() as INT).into())
|
||||
}
|
||||
@ -218,11 +212,8 @@ mod float_functions {
|
||||
#[rhai_fn(name = "to_int", return_raw)]
|
||||
pub fn f64_to_int(x: f64) -> Result<Dynamic, Box<EvalAltResult>> {
|
||||
if cfg!(not(feature = "unchecked")) && x > (MAX_INT as f64) {
|
||||
EvalAltResult::ErrorArithmetic(
|
||||
format!("Integer overflow: to_int({})", x),
|
||||
Position::none(),
|
||||
)
|
||||
.into()
|
||||
EvalAltResult::ErrorArithmetic(format!("Integer overflow: to_int({})", x), NO_POS)
|
||||
.into()
|
||||
} else {
|
||||
Ok((x.trunc() as INT).into())
|
||||
}
|
||||
@ -235,7 +226,7 @@ mod float_functions {
|
||||
.map_err(|err| {
|
||||
EvalAltResult::ErrorArithmetic(
|
||||
format!("Error parsing floating-point number '{}': {}", s, err),
|
||||
Position::none(),
|
||||
NO_POS,
|
||||
)
|
||||
.into()
|
||||
})
|
||||
|
@ -9,7 +9,7 @@ use crate::StaticVec;
|
||||
use crate::INT;
|
||||
|
||||
#[cfg(not(feature = "unchecked"))]
|
||||
use crate::{result::EvalAltResult, token::Position};
|
||||
use crate::{result::EvalAltResult, token::NO_POS};
|
||||
|
||||
use crate::stdlib::{
|
||||
any::TypeId, boxed::Box, format, mem, string::String, string::ToString, vec::Vec,
|
||||
@ -259,11 +259,7 @@ mod string_functions {
|
||||
// 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() {
|
||||
return EvalAltResult::ErrorDataTooLarge(
|
||||
"Length of string".to_string(),
|
||||
Position::none(),
|
||||
)
|
||||
.into();
|
||||
return EvalAltResult::ErrorDataTooLarge("Length of string".to_string(), NO_POS).into();
|
||||
}
|
||||
|
||||
if len > 0 {
|
||||
@ -281,7 +277,7 @@ mod string_functions {
|
||||
{
|
||||
return EvalAltResult::ErrorDataTooLarge(
|
||||
"Length of string".to_string(),
|
||||
Position::none(),
|
||||
NO_POS,
|
||||
)
|
||||
.into();
|
||||
}
|
||||
@ -300,11 +296,7 @@ mod string_functions {
|
||||
// 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() {
|
||||
return EvalAltResult::ErrorDataTooLarge(
|
||||
"Length of string".to_string(),
|
||||
Position::none(),
|
||||
)
|
||||
.into();
|
||||
return EvalAltResult::ErrorDataTooLarge("Length of string".to_string(), NO_POS).into();
|
||||
}
|
||||
|
||||
if len > 0 {
|
||||
@ -329,7 +321,7 @@ mod string_functions {
|
||||
{
|
||||
return EvalAltResult::ErrorDataTooLarge(
|
||||
"Length of string".to_string(),
|
||||
Position::none(),
|
||||
NO_POS,
|
||||
)
|
||||
.into();
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
//! Module containing error definitions for the parsing process.
|
||||
|
||||
use crate::result::EvalAltResult;
|
||||
use crate::token::Position;
|
||||
use crate::token::{Position, NO_POS};
|
||||
|
||||
use crate::stdlib::{
|
||||
boxed::Box,
|
||||
@ -43,26 +43,34 @@ impl fmt::Display for LexError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
Self::UnexpectedInput(s) => write!(f, "Unexpected '{}'", s),
|
||||
Self::MalformedEscapeSequence(s) => write!(f, "Invalid escape sequence: '{}'", s),
|
||||
Self::MalformedNumber(s) => write!(f, "Invalid number: '{}'", s),
|
||||
Self::MalformedChar(s) => write!(f, "Invalid character: '{}'", s),
|
||||
Self::MalformedIdentifier(s) => write!(f, "Variable name is not proper: '{}'", s),
|
||||
Self::UnterminatedString => write!(f, "Open string is not terminated"),
|
||||
Self::StringTooLong(max) => write!(
|
||||
f,
|
||||
"Length of string literal exceeds the maximum limit ({})",
|
||||
max
|
||||
),
|
||||
Self::MalformedEscapeSequence(s) => write!(f, "{}: '{}'", self.desc(), s),
|
||||
Self::MalformedNumber(s) => write!(f, "{}: '{}'", self.desc(), s),
|
||||
Self::MalformedChar(s) => write!(f, "{}: '{}'", self.desc(), s),
|
||||
Self::MalformedIdentifier(s) => write!(f, "{}: '{}'", self.desc(), s),
|
||||
Self::UnterminatedString => f.write_str(self.desc()),
|
||||
Self::StringTooLong(max) => write!(f, "{} ({})", self.desc(), max),
|
||||
Self::ImproperSymbol(s) => f.write_str(s),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl LexError {
|
||||
/// Convert a `LexError` into a `ParseError`.
|
||||
pub(crate) fn desc(&self) -> &str {
|
||||
match self {
|
||||
Self::UnexpectedInput(_) => "Unexpected character encountered",
|
||||
Self::UnterminatedString => "Open string is not terminated",
|
||||
Self::StringTooLong(_) => "Length of string literal exceeds the maximum limit",
|
||||
Self::MalformedEscapeSequence(_) => "Invalid escape sequence",
|
||||
Self::MalformedNumber(_) => "Invalid number",
|
||||
Self::MalformedChar(_) => "Invalid character",
|
||||
Self::MalformedIdentifier(_) => "Variable name is not proper",
|
||||
Self::ImproperSymbol(_) => "Invalid symbol encountered",
|
||||
}
|
||||
}
|
||||
/// Convert a `&LexError` into a `ParseError`.
|
||||
#[inline(always)]
|
||||
pub fn into_err(&self, pos: Position) -> ParseError {
|
||||
ParseError(Box::new(self.into()), pos)
|
||||
ParseError(Box::new(self.clone().into()), pos)
|
||||
}
|
||||
}
|
||||
|
||||
@ -74,10 +82,10 @@ impl LexError {
|
||||
#[derive(Debug, Eq, PartialEq, Clone, Hash)]
|
||||
#[non_exhaustive]
|
||||
pub enum ParseErrorType {
|
||||
/// Error in the script text. Wrapped value is the error message.
|
||||
BadInput(String),
|
||||
/// The script ends prematurely.
|
||||
UnexpectedEOF,
|
||||
/// Error in the script text. Wrapped value is the lex error.
|
||||
BadInput(LexError),
|
||||
/// An unknown operator is encountered. Wrapped value is the operator.
|
||||
UnknownOperator(String),
|
||||
/// Expecting a particular token but not finding one. Wrapped values are the token and description.
|
||||
@ -164,8 +172,8 @@ impl ParseErrorType {
|
||||
|
||||
pub(crate) fn desc(&self) -> &str {
|
||||
match self {
|
||||
Self::BadInput(p) => p,
|
||||
Self::UnexpectedEOF => "Script is incomplete",
|
||||
Self::BadInput(p) => p.desc(),
|
||||
Self::UnknownOperator(_) => "Unknown operator",
|
||||
Self::MissingToken(_, _) => "Expecting a certain token that is missing",
|
||||
Self::MalformedCallExpr(_) => "Invalid expression in function call arguments",
|
||||
@ -196,9 +204,9 @@ impl ParseErrorType {
|
||||
impl fmt::Display for ParseErrorType {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
Self::BadInput(s) | ParseErrorType::MalformedCallExpr(s) => {
|
||||
f.write_str(if s.is_empty() { self.desc() } else { s })
|
||||
}
|
||||
Self::BadInput(err) => write!(f, "{}", err),
|
||||
|
||||
Self::MalformedCallExpr(s) => f.write_str(if s.is_empty() { self.desc() } else { s }),
|
||||
Self::UnknownOperator(s) => write!(f, "{}: '{}'", self.desc(), s),
|
||||
|
||||
Self::MalformedIndexExpr(s) | Self::MalformedInExpr(s) | Self::MalformedCapture(s) => {
|
||||
@ -247,14 +255,14 @@ impl fmt::Display for ParseErrorType {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&LexError> for ParseErrorType {
|
||||
impl From<LexError> for ParseErrorType {
|
||||
#[inline(always)]
|
||||
fn from(err: &LexError) -> Self {
|
||||
fn from(err: LexError) -> Self {
|
||||
match err {
|
||||
LexError::StringTooLong(max) => {
|
||||
Self::LiteralTooLarge("Length of string literal".to_string(), *max)
|
||||
Self::LiteralTooLarge("Length of string literal".to_string(), max)
|
||||
}
|
||||
_ => Self::BadInput(err.to_string()),
|
||||
_ => Self::BadInput(err),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -282,7 +290,7 @@ impl fmt::Display for ParseError {
|
||||
impl From<ParseErrorType> for Box<EvalAltResult> {
|
||||
#[inline(always)]
|
||||
fn from(err: ParseErrorType) -> Self {
|
||||
Box::new(EvalAltResult::ErrorParsing(err, Position::none()))
|
||||
Box::new(EvalAltResult::ErrorParsing(err, NO_POS))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -10,7 +10,9 @@ use crate::optimize::{optimize_into_ast, OptimizationLevel};
|
||||
use crate::parse_error::{LexError, ParseError, ParseErrorType};
|
||||
use crate::scope::{EntryType as ScopeEntryType, Scope};
|
||||
use crate::syntax::CustomSyntax;
|
||||
use crate::token::{is_keyword_function, is_valid_identifier, Position, Token, TokenStream};
|
||||
use crate::token::{
|
||||
is_keyword_function, is_valid_identifier, Position, Token, TokenStream, NO_POS,
|
||||
};
|
||||
use crate::utils::StraightHasherBuilder;
|
||||
use crate::{calc_script_fn_hash, StaticVec};
|
||||
|
||||
@ -816,10 +818,11 @@ fn parse_primary(
|
||||
// Access to `this` as a variable is OK
|
||||
Token::Reserved(s) if s == KEYWORD_THIS && *next_token != Token::LeftParen => {
|
||||
if !settings.is_function_scope {
|
||||
return Err(
|
||||
PERR::BadInput(format!("'{}' can only be used in functions", s))
|
||||
.into_err(settings.pos),
|
||||
);
|
||||
return Err(PERR::BadInput(LexError::ImproperSymbol(format!(
|
||||
"'{}' can only be used in functions",
|
||||
s
|
||||
)))
|
||||
.into_err(settings.pos));
|
||||
} else {
|
||||
Expr::Variable(Box::new((Ident::new(s, settings.pos), None, 0, None)))
|
||||
}
|
||||
@ -840,7 +843,8 @@ fn parse_primary(
|
||||
|
||||
_ => {
|
||||
return Err(
|
||||
PERR::BadInput(format!("Unexpected '{}'", token.syntax())).into_err(settings.pos)
|
||||
PERR::BadInput(LexError::UnexpectedInput(token.syntax().to_string()))
|
||||
.into_err(settings.pos),
|
||||
);
|
||||
}
|
||||
};
|
||||
@ -862,8 +866,10 @@ fn parse_primary(
|
||||
return Err(if !match_token(input, Token::LeftParen).0 {
|
||||
LexError::UnexpectedInput(Token::Bang.syntax().to_string()).into_err(token_pos)
|
||||
} else {
|
||||
PERR::BadInput("'!' cannot be used to call module functions".to_string())
|
||||
.into_err(token_pos)
|
||||
PERR::BadInput(LexError::ImproperSymbol(
|
||||
"'!' cannot be used to call module functions".to_string(),
|
||||
))
|
||||
.into_err(token_pos)
|
||||
});
|
||||
}
|
||||
// Function call with !
|
||||
@ -1140,9 +1146,10 @@ fn make_assignment_stmt<'a>(
|
||||
Err(PERR::AssignmentToConstant("".into()).into_err(lhs.position()))
|
||||
}
|
||||
// ??? && ??? = rhs, ??? || ??? = rhs
|
||||
Expr::And(_, _) | Expr::Or(_, _) => {
|
||||
Err(PERR::BadInput("Possibly a typo of '=='?".to_string()).into_err(pos))
|
||||
}
|
||||
Expr::And(_, _) | Expr::Or(_, _) => Err(PERR::BadInput(LexError::ImproperSymbol(
|
||||
"Possibly a typo of '=='?".to_string(),
|
||||
))
|
||||
.into_err(pos)),
|
||||
// expr = rhs
|
||||
_ => Err(PERR::AssignmentToInvalidLHS("".to_string()).into_err(lhs.position())),
|
||||
}
|
||||
@ -1238,10 +1245,10 @@ fn make_dot_expr(lhs: Expr, rhs: Expr, op_pos: Position) -> Result<Expr, ParseEr
|
||||
(_, Expr::FnCall(x, pos))
|
||||
if x.args.len() == 0 && [KEYWORD_FN_PTR, KEYWORD_EVAL].contains(&x.name.as_ref()) =>
|
||||
{
|
||||
return Err(PERR::BadInput(format!(
|
||||
return Err(PERR::BadInput(LexError::ImproperSymbol(format!(
|
||||
"'{}' should not be called in method style. Try {}(...);",
|
||||
x.name, x.name
|
||||
))
|
||||
)))
|
||||
.into_err(pos));
|
||||
}
|
||||
// lhs.func!(...)
|
||||
@ -1734,9 +1741,10 @@ fn ensure_not_statement_expr(input: &mut TokenStream, type_name: &str) -> Result
|
||||
/// Make sure that the expression is not a mis-typed assignment (i.e. `a = b` instead of `a == b`).
|
||||
fn ensure_not_assignment(input: &mut TokenStream) -> Result<(), ParseError> {
|
||||
match input.peek().unwrap() {
|
||||
(Token::Equals, pos) => {
|
||||
Err(PERR::BadInput("Possibly a typo of '=='?".to_string()).into_err(*pos))
|
||||
}
|
||||
(Token::Equals, pos) => Err(PERR::BadInput(LexError::ImproperSymbol(
|
||||
"Possibly a typo of '=='?".to_string(),
|
||||
))
|
||||
.into_err(*pos)),
|
||||
(Token::PlusAssign, pos)
|
||||
| (Token::MinusAssign, pos)
|
||||
| (Token::MultiplyAssign, pos)
|
||||
@ -1747,9 +1755,9 @@ fn ensure_not_assignment(input: &mut TokenStream) -> Result<(), ParseError> {
|
||||
| (Token::PowerOfAssign, pos)
|
||||
| (Token::AndAssign, pos)
|
||||
| (Token::OrAssign, pos)
|
||||
| (Token::XOrAssign, pos) => Err(PERR::BadInput(
|
||||
| (Token::XOrAssign, pos) => Err(PERR::BadInput(LexError::ImproperSymbol(
|
||||
"Expecting a boolean expression, not an assignment".to_string(),
|
||||
)
|
||||
))
|
||||
.into_err(*pos)),
|
||||
|
||||
_ => Ok(()),
|
||||
@ -2683,7 +2691,7 @@ impl Engine {
|
||||
is_function_scope: false,
|
||||
is_breakable: false,
|
||||
level: 0,
|
||||
pos: Position::none(),
|
||||
pos: NO_POS,
|
||||
};
|
||||
let expr = parse_expr(input, &mut state, &mut functions, settings)?;
|
||||
|
||||
@ -2694,7 +2702,8 @@ impl Engine {
|
||||
// Return error if the expression doesn't end
|
||||
(token, pos) => {
|
||||
return Err(
|
||||
PERR::BadInput(format!("Unexpected '{}'", token.syntax())).into_err(*pos)
|
||||
PERR::BadInput(LexError::UnexpectedInput(token.syntax().to_string()))
|
||||
.into_err(*pos),
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -2732,7 +2741,7 @@ impl Engine {
|
||||
is_function_scope: false,
|
||||
is_breakable: false,
|
||||
level: 0,
|
||||
pos: Position::none(),
|
||||
pos: NO_POS,
|
||||
};
|
||||
|
||||
let stmt = match parse_stmt(input, &mut state, &mut functions, settings)? {
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
use crate::dynamic::Dynamic;
|
||||
use crate::parse_error::ParseErrorType;
|
||||
use crate::token::Position;
|
||||
use crate::token::{Position, NO_POS};
|
||||
use crate::utils::ImmutableString;
|
||||
use crate::INT;
|
||||
|
||||
@ -252,7 +252,7 @@ impl fmt::Display for EvalAltResult {
|
||||
impl<T: AsRef<str>> From<T> for EvalAltResult {
|
||||
#[inline(always)]
|
||||
fn from(err: T) -> Self {
|
||||
Self::ErrorRuntime(err.as_ref().to_string().into(), Position::none())
|
||||
Self::ErrorRuntime(err.as_ref().to_string().into(), NO_POS)
|
||||
}
|
||||
}
|
||||
|
||||
@ -261,7 +261,7 @@ impl<T: AsRef<str>> From<T> for Box<EvalAltResult> {
|
||||
fn from(err: T) -> Self {
|
||||
Box::new(EvalAltResult::ErrorRuntime(
|
||||
err.as_ref().to_string().into(),
|
||||
Position::none(),
|
||||
NO_POS,
|
||||
))
|
||||
}
|
||||
}
|
||||
@ -324,7 +324,7 @@ impl EvalAltResult {
|
||||
/// Get the `Position` of this error.
|
||||
pub fn position(&self) -> Position {
|
||||
match self {
|
||||
Self::ErrorSystem(_, _) => Position::none(),
|
||||
Self::ErrorSystem(_, _) => NO_POS,
|
||||
|
||||
Self::ErrorParsing(_, pos)
|
||||
| Self::ErrorFunctionNotFound(_, pos)
|
||||
|
@ -4,7 +4,7 @@ use super::str::ImmutableStringDeserializer;
|
||||
use crate::dynamic::{Dynamic, Union};
|
||||
use crate::parse_error::ParseErrorType;
|
||||
use crate::result::EvalAltResult;
|
||||
use crate::token::Position;
|
||||
use crate::token::NO_POS;
|
||||
use crate::utils::ImmutableString;
|
||||
|
||||
use serde::de::{
|
||||
@ -45,12 +45,8 @@ impl<'de> DynamicDeserializer<'de> {
|
||||
}
|
||||
/// Shortcut for a type conversion error.
|
||||
fn type_error_str<T>(&self, error: &str) -> Result<T, Box<EvalAltResult>> {
|
||||
EvalAltResult::ErrorMismatchOutputType(
|
||||
error.into(),
|
||||
self.value.type_name().into(),
|
||||
Position::none(),
|
||||
)
|
||||
.into()
|
||||
EvalAltResult::ErrorMismatchOutputType(error.into(), self.value.type_name().into(), NO_POS)
|
||||
.into()
|
||||
}
|
||||
fn deserialize_int<V: Visitor<'de>>(
|
||||
&mut self,
|
||||
@ -127,8 +123,11 @@ pub fn from_dynamic<'de, T: Deserialize<'de>>(
|
||||
|
||||
impl Error for Box<EvalAltResult> {
|
||||
fn custom<T: fmt::Display>(err: T) -> Self {
|
||||
EvalAltResult::ErrorParsing(ParseErrorType::BadInput(err.to_string()), Position::none())
|
||||
.into()
|
||||
EvalAltResult::ErrorParsing(ParseErrorType::BadInput(
|
||||
LexError::ImproperSymbol(err.to_string()),
|
||||
NO_POS,
|
||||
))
|
||||
.into()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
use crate::dynamic::Dynamic;
|
||||
use crate::result::EvalAltResult;
|
||||
use crate::token::Position;
|
||||
use crate::token::NO_POS;
|
||||
|
||||
#[cfg(not(feature = "no_index"))]
|
||||
use crate::engine::Array;
|
||||
@ -99,7 +99,7 @@ pub fn to_dynamic<T: Serialize>(value: T) -> Result<Dynamic, Box<EvalAltResult>>
|
||||
|
||||
impl Error for Box<EvalAltResult> {
|
||||
fn custom<T: fmt::Display>(err: T) -> Self {
|
||||
EvalAltResult::ErrorRuntime(err.to_string().into(), Position::none()).into()
|
||||
EvalAltResult::ErrorRuntime(err.to_string().into(), NO_POS).into()
|
||||
}
|
||||
}
|
||||
|
||||
@ -295,24 +295,16 @@ impl Serializer for &mut DynamicSerializer {
|
||||
make_variant(_variant, content)
|
||||
}
|
||||
#[cfg(feature = "no_object")]
|
||||
return EvalAltResult::ErrorMismatchOutputType(
|
||||
"Dynamic".into(),
|
||||
"map".into(),
|
||||
Position::none(),
|
||||
)
|
||||
.into();
|
||||
return EvalAltResult::ErrorMismatchOutputType("Dynamic".into(), "map".into(), NO_POS)
|
||||
.into();
|
||||
}
|
||||
|
||||
fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq, Box<EvalAltResult>> {
|
||||
#[cfg(not(feature = "no_index"))]
|
||||
return Ok(DynamicSerializer::new(Array::new().into()));
|
||||
#[cfg(feature = "no_index")]
|
||||
return EvalAltResult::ErrorMismatchOutputType(
|
||||
"Dynamic".into(),
|
||||
"array".into(),
|
||||
Position::none(),
|
||||
)
|
||||
.into();
|
||||
return EvalAltResult::ErrorMismatchOutputType("Dynamic".into(), "array".into(), NO_POS)
|
||||
.into();
|
||||
}
|
||||
|
||||
fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple, Box<EvalAltResult>> {
|
||||
@ -345,12 +337,7 @@ impl Serializer for &mut DynamicSerializer {
|
||||
let err_type = "map";
|
||||
#[cfg(not(feature = "no_object"))]
|
||||
let err_type = "array";
|
||||
EvalAltResult::ErrorMismatchOutputType(
|
||||
"Dynamic".into(),
|
||||
err_type.into(),
|
||||
Position::none(),
|
||||
)
|
||||
.into()
|
||||
EvalAltResult::ErrorMismatchOutputType("Dynamic".into(), err_type.into(), NO_POS).into()
|
||||
}
|
||||
}
|
||||
|
||||
@ -358,12 +345,8 @@ impl Serializer for &mut DynamicSerializer {
|
||||
#[cfg(not(feature = "no_object"))]
|
||||
return Ok(DynamicSerializer::new(Map::new().into()));
|
||||
#[cfg(feature = "no_object")]
|
||||
return EvalAltResult::ErrorMismatchOutputType(
|
||||
"Dynamic".into(),
|
||||
"map".into(),
|
||||
Position::none(),
|
||||
)
|
||||
.into();
|
||||
return EvalAltResult::ErrorMismatchOutputType("Dynamic".into(), "map".into(), NO_POS)
|
||||
.into();
|
||||
}
|
||||
|
||||
fn serialize_struct(
|
||||
@ -387,12 +370,8 @@ impl Serializer for &mut DynamicSerializer {
|
||||
map: Map::with_capacity(_len),
|
||||
});
|
||||
#[cfg(feature = "no_object")]
|
||||
return EvalAltResult::ErrorMismatchOutputType(
|
||||
"Dynamic".into(),
|
||||
"map".into(),
|
||||
Position::none(),
|
||||
)
|
||||
.into();
|
||||
return EvalAltResult::ErrorMismatchOutputType("Dynamic".into(), "map".into(), NO_POS)
|
||||
.into();
|
||||
}
|
||||
}
|
||||
|
||||
@ -501,11 +480,7 @@ impl SerializeMap for DynamicSerializer {
|
||||
let key = mem::take(&mut self._key)
|
||||
.take_immutable_string()
|
||||
.map_err(|typ| {
|
||||
EvalAltResult::ErrorMismatchOutputType(
|
||||
"string".into(),
|
||||
typ.into(),
|
||||
Position::none(),
|
||||
)
|
||||
EvalAltResult::ErrorMismatchOutputType("string".into(), typ.into(), NO_POS)
|
||||
})?;
|
||||
let _value = _value.serialize(&mut *self)?;
|
||||
let map = self._value.downcast_mut::<Map>().unwrap();
|
||||
@ -525,11 +500,7 @@ impl SerializeMap for DynamicSerializer {
|
||||
{
|
||||
let _key: Dynamic = _key.serialize(&mut *self)?;
|
||||
let _key = _key.take_immutable_string().map_err(|typ| {
|
||||
EvalAltResult::ErrorMismatchOutputType(
|
||||
"string".into(),
|
||||
typ.into(),
|
||||
Position::none(),
|
||||
)
|
||||
EvalAltResult::ErrorMismatchOutputType("string".into(), typ.into(), NO_POS)
|
||||
})?;
|
||||
let _value = _value.serialize(&mut *self)?;
|
||||
let map = self._value.downcast_mut::<Map>().unwrap();
|
||||
|
@ -1,7 +1,7 @@
|
||||
//! Implement deserialization support of `ImmutableString` for [`serde`](https://crates.io/crates/serde).
|
||||
|
||||
use crate::result::EvalAltResult;
|
||||
use crate::token::Position;
|
||||
use crate::token::NO_POS;
|
||||
use crate::utils::ImmutableString;
|
||||
|
||||
use serde::de::{Deserializer, Visitor};
|
||||
@ -20,12 +20,8 @@ impl<'a> ImmutableStringDeserializer<'a> {
|
||||
}
|
||||
/// Shortcut for a type conversion error.
|
||||
fn type_error<T>(&self) -> Result<T, Box<EvalAltResult>> {
|
||||
EvalAltResult::ErrorMismatchOutputType(
|
||||
type_name::<T>().into(),
|
||||
"string".into(),
|
||||
Position::none(),
|
||||
)
|
||||
.into()
|
||||
EvalAltResult::ErrorMismatchOutputType(type_name::<T>().into(), "string".into(), NO_POS)
|
||||
.into()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -6,7 +6,7 @@ use crate::engine::{Engine, EvalContext, MARKER_BLOCK, MARKER_EXPR, MARKER_IDENT
|
||||
use crate::fn_native::{SendSync, Shared};
|
||||
use crate::parse_error::{LexError, ParseError};
|
||||
use crate::result::EvalAltResult;
|
||||
use crate::token::{is_valid_identifier, Position, Token};
|
||||
use crate::token::{is_valid_identifier, Position, Token, NO_POS};
|
||||
use crate::utils::ImmutableString;
|
||||
use crate::StaticVec;
|
||||
|
||||
@ -139,7 +139,7 @@ impl Engine {
|
||||
segments.len() + 1,
|
||||
s
|
||||
))
|
||||
.into_err(Position::none())
|
||||
.into_err(NO_POS)
|
||||
.into());
|
||||
}
|
||||
// Identifier in first position
|
||||
@ -156,7 +156,7 @@ impl Engine {
|
||||
segments.len() + 1,
|
||||
s
|
||||
))
|
||||
.into_err(Position::none())
|
||||
.into_err(NO_POS)
|
||||
.into());
|
||||
}
|
||||
};
|
||||
|
@ -44,6 +44,9 @@ pub struct Position {
|
||||
pos: u16,
|
||||
}
|
||||
|
||||
/// No `Position`.
|
||||
pub const NO_POS: Position = Position { line: 0, pos: 0 };
|
||||
|
||||
impl Position {
|
||||
/// Create a new `Position`.
|
||||
///
|
||||
@ -121,7 +124,7 @@ impl Position {
|
||||
/// Create a `Position` representing no position.
|
||||
#[inline(always)]
|
||||
pub fn none() -> Self {
|
||||
Self { line: 0, pos: 0 }
|
||||
NO_POS
|
||||
}
|
||||
|
||||
/// Is there no `Position`?
|
||||
|
@ -38,7 +38,7 @@ fn test_max_string_size() -> Result<(), Box<EvalAltResult>> {
|
||||
"#
|
||||
)
|
||||
.expect_err("should error"),
|
||||
EvalAltResult::ErrorDataTooLarge(_, 10, 13, _)
|
||||
EvalAltResult::ErrorDataTooLarge(_, _)
|
||||
));
|
||||
|
||||
#[cfg(not(feature = "no_object"))]
|
||||
@ -52,7 +52,7 @@ fn test_max_string_size() -> Result<(), Box<EvalAltResult>> {
|
||||
"#
|
||||
)
|
||||
.expect_err("should error"),
|
||||
EvalAltResult::ErrorDataTooLarge(_, 10, 100, _)
|
||||
EvalAltResult::ErrorDataTooLarge(_, _)
|
||||
));
|
||||
|
||||
engine.set_max_string_size(0);
|
||||
@ -98,7 +98,7 @@ fn test_max_array_size() -> Result<(), Box<EvalAltResult>> {
|
||||
"
|
||||
)
|
||||
.expect_err("should error"),
|
||||
EvalAltResult::ErrorDataTooLarge(_, 10, 12, _)
|
||||
EvalAltResult::ErrorDataTooLarge(_, _)
|
||||
));
|
||||
|
||||
#[cfg(not(feature = "no_object"))]
|
||||
@ -112,7 +112,7 @@ fn test_max_array_size() -> Result<(), Box<EvalAltResult>> {
|
||||
"
|
||||
)
|
||||
.expect_err("should error"),
|
||||
EvalAltResult::ErrorDataTooLarge(_, 10, 100, _)
|
||||
EvalAltResult::ErrorDataTooLarge(_, _)
|
||||
));
|
||||
|
||||
assert!(matches!(
|
||||
@ -124,7 +124,7 @@ fn test_max_array_size() -> Result<(), Box<EvalAltResult>> {
|
||||
"
|
||||
)
|
||||
.expect_err("should error"),
|
||||
EvalAltResult::ErrorDataTooLarge(_, 10, 12, _)
|
||||
EvalAltResult::ErrorDataTooLarge(_, _)
|
||||
));
|
||||
|
||||
#[cfg(not(feature = "no_object"))]
|
||||
@ -137,7 +137,7 @@ fn test_max_array_size() -> Result<(), Box<EvalAltResult>> {
|
||||
"
|
||||
)
|
||||
.expect_err("should error"),
|
||||
EvalAltResult::ErrorDataTooLarge(_, 10, 12, _)
|
||||
EvalAltResult::ErrorDataTooLarge(_, _)
|
||||
));
|
||||
|
||||
assert!(matches!(
|
||||
@ -151,7 +151,7 @@ fn test_max_array_size() -> Result<(), Box<EvalAltResult>> {
|
||||
"
|
||||
)
|
||||
.expect_err("should error"),
|
||||
EvalAltResult::ErrorDataTooLarge(_, 10, 12, _)
|
||||
EvalAltResult::ErrorDataTooLarge(_, _)
|
||||
));
|
||||
|
||||
engine.set_max_array_size(0);
|
||||
@ -216,7 +216,7 @@ fn test_max_map_size() -> Result<(), Box<EvalAltResult>> {
|
||||
"
|
||||
)
|
||||
.expect_err("should error"),
|
||||
EvalAltResult::ErrorDataTooLarge(_, 10, 12, _)
|
||||
EvalAltResult::ErrorDataTooLarge(_, _)
|
||||
));
|
||||
|
||||
assert!(matches!(
|
||||
@ -228,7 +228,7 @@ fn test_max_map_size() -> Result<(), Box<EvalAltResult>> {
|
||||
"
|
||||
)
|
||||
.expect_err("should error"),
|
||||
EvalAltResult::ErrorDataTooLarge(_, 10, 12, _)
|
||||
EvalAltResult::ErrorDataTooLarge(_, _)
|
||||
));
|
||||
|
||||
#[cfg(not(feature = "no_index"))]
|
||||
@ -241,7 +241,7 @@ fn test_max_map_size() -> Result<(), Box<EvalAltResult>> {
|
||||
"
|
||||
)
|
||||
.expect_err("should error"),
|
||||
EvalAltResult::ErrorDataTooLarge(_, 10, 12, _)
|
||||
EvalAltResult::ErrorDataTooLarge(_, _)
|
||||
));
|
||||
|
||||
engine.set_max_map_size(0);
|
||||
|
@ -1,5 +1,5 @@
|
||||
#![cfg(not(feature = "unchecked"))]
|
||||
use rhai::{Engine, EvalAltResult};
|
||||
use rhai::{Engine, EvalAltResult, INT};
|
||||
|
||||
#[test]
|
||||
fn test_max_operations() -> Result<(), Box<EvalAltResult>> {
|
||||
@ -10,7 +10,7 @@ fn test_max_operations() -> Result<(), Box<EvalAltResult>> {
|
||||
if count % 100 == 0 {
|
||||
println!("{}", count);
|
||||
}
|
||||
true
|
||||
None
|
||||
});
|
||||
|
||||
engine.eval::<()>("let x = 0; while x < 20 { x += 1; }")?;
|
||||
@ -38,7 +38,7 @@ fn test_max_operations_functions() -> Result<(), Box<EvalAltResult>> {
|
||||
if count % 100 == 0 {
|
||||
println!("{}", count);
|
||||
}
|
||||
true
|
||||
None
|
||||
});
|
||||
|
||||
engine.eval::<()>(
|
||||
@ -94,7 +94,7 @@ fn test_max_operations_eval() -> Result<(), Box<EvalAltResult>> {
|
||||
if count % 100 == 0 {
|
||||
println!("{}", count);
|
||||
}
|
||||
true
|
||||
None
|
||||
});
|
||||
|
||||
assert!(matches!(
|
||||
@ -117,13 +117,19 @@ fn test_max_operations_progress() -> Result<(), Box<EvalAltResult>> {
|
||||
let mut engine = Engine::new();
|
||||
engine.set_max_operations(500);
|
||||
|
||||
engine.on_progress(|&count| count < 100);
|
||||
engine.on_progress(|&count| {
|
||||
if count < 100 {
|
||||
None
|
||||
} else {
|
||||
Some((42 as INT).into())
|
||||
}
|
||||
});
|
||||
|
||||
assert!(matches!(
|
||||
*engine
|
||||
.eval::<()>("for x in range(0, 500) {}")
|
||||
.expect_err("should error"),
|
||||
EvalAltResult::ErrorTerminated(_)
|
||||
EvalAltResult::ErrorTerminated(x, _) if x.as_int()? == 42
|
||||
));
|
||||
|
||||
Ok(())
|
||||
|
@ -1,4 +1,4 @@
|
||||
use rhai::{Engine, EvalAltResult, ParseError, ParseErrorType, Position, INT};
|
||||
use rhai::{Engine, EvalAltResult, LexError, ParseError, ParseErrorType, INT, NO_POS};
|
||||
|
||||
#[test]
|
||||
fn test_custom_syntax() -> Result<(), Box<EvalAltResult>> {
|
||||
@ -68,9 +68,9 @@ fn test_custom_syntax() -> Result<(), Box<EvalAltResult>> {
|
||||
.register_custom_syntax(&["!"], 0, |_, _| Ok(().into()))
|
||||
.expect_err("should error")
|
||||
.0,
|
||||
ParseErrorType::BadInput(
|
||||
ParseErrorType::BadInput(LexError::ImproperSymbol(
|
||||
"Improper symbol for custom syntax at position #1: '!'".to_string()
|
||||
)
|
||||
))
|
||||
);
|
||||
|
||||
Ok(())
|
||||
@ -88,8 +88,10 @@ fn test_custom_syntax_raw() -> Result<(), Box<EvalAltResult>> {
|
||||
2 => match stream[1].as_str() {
|
||||
"world" | "kitty" => Ok(None),
|
||||
s => Err(ParseError(
|
||||
Box::new(ParseErrorType::BadInput(s.to_string())),
|
||||
Position::none(),
|
||||
Box::new(ParseErrorType::BadInput(LexError::ImproperSymbol(
|
||||
s.to_string(),
|
||||
))),
|
||||
NO_POS,
|
||||
)),
|
||||
},
|
||||
_ => unreachable!(),
|
||||
@ -109,7 +111,7 @@ fn test_custom_syntax_raw() -> Result<(), Box<EvalAltResult>> {
|
||||
assert_eq!(engine.eval::<INT>("hello kitty")?, 42);
|
||||
assert_eq!(
|
||||
*engine.compile("hello hey").expect_err("should error").0,
|
||||
ParseErrorType::BadInput("hey".to_string())
|
||||
ParseErrorType::BadInput(LexError::ImproperSymbol("hey".to_string()))
|
||||
);
|
||||
|
||||
Ok(())
|
||||
|
@ -1,4 +1,4 @@
|
||||
use rhai::{Engine, EvalAltResult, ParseErrorType, RegisterFn, INT};
|
||||
use rhai::{Engine, EvalAltResult, LexError, ParseErrorType, RegisterFn, INT};
|
||||
|
||||
#[test]
|
||||
fn test_tokens_disabled() {
|
||||
@ -16,10 +16,13 @@ fn test_tokens_disabled() {
|
||||
|
||||
engine.disable_symbol("+="); // disable the '+=' operator
|
||||
|
||||
assert!(matches!(
|
||||
*engine.compile("let x = 40 + 2; x += 1;").expect_err("should error").0,
|
||||
ParseErrorType::BadInput(ref s) if s == "Unexpected '+='"
|
||||
));
|
||||
assert_eq!(
|
||||
*engine
|
||||
.compile("let x = 40 + 2; x += 1;")
|
||||
.expect_err("should error")
|
||||
.0,
|
||||
ParseErrorType::BadInput(LexError::UnexpectedInput("+=".to_string()))
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -1,4 +1,4 @@
|
||||
use rhai::{Engine, EvalAltResult, Position, Scope, INT};
|
||||
use rhai::{Engine, EvalAltResult, Scope, INT, NO_POS};
|
||||
|
||||
#[test]
|
||||
fn test_var_scope() -> Result<(), Box<EvalAltResult>> {
|
||||
@ -67,7 +67,7 @@ fn test_var_resolver() -> Result<(), Box<EvalAltResult>> {
|
||||
"MYSTIC_NUMBER" => Ok(Some((42 as INT).into())),
|
||||
// Override a variable - make it not found even if it exists!
|
||||
"DO_NOT_USE" => {
|
||||
Err(EvalAltResult::ErrorVariableNotFound(name.to_string(), Position::none()).into())
|
||||
Err(EvalAltResult::ErrorVariableNotFound(name.to_string(), NO_POS).into())
|
||||
}
|
||||
// Silently maps 'chameleon' into 'innocent'.
|
||||
"chameleon" => context
|
||||
@ -75,7 +75,7 @@ fn test_var_resolver() -> Result<(), Box<EvalAltResult>> {
|
||||
.get_value("innocent")
|
||||
.map(Some)
|
||||
.ok_or_else(|| {
|
||||
EvalAltResult::ErrorVariableNotFound(name.to_string(), Position::none()).into()
|
||||
EvalAltResult::ErrorVariableNotFound(name.to_string(), NO_POS).into()
|
||||
}),
|
||||
// Return Ok(None) to continue with the normal variable resolution process.
|
||||
_ => Ok(None),
|
||||
|
Loading…
Reference in New Issue
Block a user