Simplify using ..
This commit is contained in:
parent
187a20fd8b
commit
f8cee0fe4e
@ -50,9 +50,9 @@ no_object = [] # no custom objects
|
|||||||
no_function = ["no_closure"] # no script-defined functions (meaning no closures)
|
no_function = ["no_closure"] # no script-defined functions (meaning no closures)
|
||||||
no_closure = [] # no automatic sharing and capture of anonymous functions to external variables
|
no_closure = [] # no automatic sharing and capture of anonymous functions to external variables
|
||||||
no_module = [] # no modules
|
no_module = [] # no modules
|
||||||
internals = [] # expose internal data structures
|
|
||||||
unicode-xid-ident = ["unicode-xid"] # allow Unicode Standard Annex #31 for identifiers.
|
unicode-xid-ident = ["unicode-xid"] # allow Unicode Standard Annex #31 for identifiers.
|
||||||
metadata = ["serde", "serde_json", "rhai_codegen/metadata", "smartstring/serde"] # enable exporting functions metadata
|
metadata = ["serde", "serde_json", "rhai_codegen/metadata", "smartstring/serde"] # enable exporting functions metadata
|
||||||
|
internals = [] # expose internal data structures
|
||||||
debugging = ["internals"] # enable debugging
|
debugging = ["internals"] # enable debugging
|
||||||
|
|
||||||
# compiling for no-std
|
# compiling for no-std
|
||||||
|
@ -252,7 +252,7 @@ impl ExportedParams for ExportedFnParams {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
(attr, _) => {
|
(attr, ..) => {
|
||||||
return Err(syn::Error::new(
|
return Err(syn::Error::new(
|
||||||
key.span(),
|
key.span(),
|
||||||
format!("unknown attribute '{}'", attr),
|
format!("unknown attribute '{}'", attr),
|
||||||
@ -379,7 +379,7 @@ impl Parse for ExportedFn {
|
|||||||
|
|
||||||
// Check return type.
|
// Check return type.
|
||||||
match fn_all.sig.output {
|
match fn_all.sig.output {
|
||||||
syn::ReturnType::Type(_, ref ret_type) => {
|
syn::ReturnType::Type(.., ref ret_type) => {
|
||||||
match flatten_type_groups(ret_type.as_ref()) {
|
match flatten_type_groups(ret_type.as_ref()) {
|
||||||
syn::Type::Ptr(_) => {
|
syn::Type::Ptr(_) => {
|
||||||
return Err(syn::Error::new(
|
return Err(syn::Error::new(
|
||||||
@ -425,10 +425,10 @@ impl ExportedFn {
|
|||||||
|
|
||||||
pub fn update_scope(&mut self, parent_scope: &ExportScope) {
|
pub fn update_scope(&mut self, parent_scope: &ExportScope) {
|
||||||
let keep = match (self.params.skip, parent_scope) {
|
let keep = match (self.params.skip, parent_scope) {
|
||||||
(true, _) => false,
|
(true, ..) => false,
|
||||||
(_, ExportScope::PubOnly) => self.is_public(),
|
(.., ExportScope::PubOnly) => self.is_public(),
|
||||||
(_, ExportScope::Prefix(s)) => self.name().to_string().starts_with(s),
|
(.., ExportScope::Prefix(s)) => self.name().to_string().starts_with(s),
|
||||||
(_, ExportScope::All) => true,
|
(.., ExportScope::All) => true,
|
||||||
};
|
};
|
||||||
self.params.skip = !keep;
|
self.params.skip = !keep;
|
||||||
}
|
}
|
||||||
@ -502,7 +502,7 @@ impl ExportedFn {
|
|||||||
|
|
||||||
pub fn return_type(&self) -> Option<&syn::Type> {
|
pub fn return_type(&self) -> Option<&syn::Type> {
|
||||||
match self.signature.output {
|
match self.signature.output {
|
||||||
syn::ReturnType::Type(_, ref ret_type) => Some(flatten_type_groups(ret_type)),
|
syn::ReturnType::Type(.., ref ret_type) => Some(flatten_type_groups(ret_type)),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -69,7 +69,7 @@ impl ExportedParams for ExportedModParams {
|
|||||||
("export_all", Some(s)) => {
|
("export_all", Some(s)) => {
|
||||||
return Err(syn::Error::new(s.span(), "extraneous value"))
|
return Err(syn::Error::new(s.span(), "extraneous value"))
|
||||||
}
|
}
|
||||||
(attr, _) => {
|
(attr, ..) => {
|
||||||
return Err(syn::Error::new(
|
return Err(syn::Error::new(
|
||||||
key.span(),
|
key.span(),
|
||||||
format!("unknown attribute '{}'", attr),
|
format!("unknown attribute '{}'", attr),
|
||||||
@ -109,7 +109,7 @@ impl Parse for Module {
|
|||||||
let mut consts = Vec::new();
|
let mut consts = Vec::new();
|
||||||
let mut sub_modules = Vec::new();
|
let mut sub_modules = Vec::new();
|
||||||
|
|
||||||
if let Some((_, ref mut content)) = mod_all.content {
|
if let Some((.., ref mut content)) = mod_all.content {
|
||||||
// Gather and parse functions.
|
// Gather and parse functions.
|
||||||
fns = content
|
fns = content
|
||||||
.iter_mut()
|
.iter_mut()
|
||||||
@ -211,10 +211,10 @@ impl Module {
|
|||||||
|
|
||||||
pub fn update_scope(&mut self, parent_scope: &ExportScope) {
|
pub fn update_scope(&mut self, parent_scope: &ExportScope) {
|
||||||
let keep = match (self.params.skip, parent_scope) {
|
let keep = match (self.params.skip, parent_scope) {
|
||||||
(true, _) => false,
|
(true, ..) => false,
|
||||||
(_, ExportScope::PubOnly) => matches!(self.mod_all.vis, syn::Visibility::Public(_)),
|
(.., ExportScope::PubOnly) => matches!(self.mod_all.vis, syn::Visibility::Public(_)),
|
||||||
(_, ExportScope::Prefix(s)) => self.mod_all.ident.to_string().starts_with(s),
|
(.., ExportScope::Prefix(s)) => self.mod_all.ident.to_string().starts_with(s),
|
||||||
(_, ExportScope::All) => true,
|
(.., ExportScope::All) => true,
|
||||||
};
|
};
|
||||||
self.params.skip = !keep;
|
self.params.skip = !keep;
|
||||||
}
|
}
|
||||||
@ -245,7 +245,7 @@ impl Module {
|
|||||||
} = self;
|
} = self;
|
||||||
let mod_vis = mod_all.vis;
|
let mod_vis = mod_all.vis;
|
||||||
let mod_name = mod_all.ident.clone();
|
let mod_name = mod_all.ident.clone();
|
||||||
let (_, orig_content) = mod_all.content.take().unwrap();
|
let (.., orig_content) = mod_all.content.take().unwrap();
|
||||||
let mod_attrs = mem::take(&mut mod_all.attrs);
|
let mod_attrs = mem::take(&mut mod_all.attrs);
|
||||||
|
|
||||||
if !params.skip {
|
if !params.skip {
|
||||||
@ -312,7 +312,7 @@ impl Module {
|
|||||||
pub fn content(&self) -> Option<&[syn::Item]> {
|
pub fn content(&self) -> Option<&[syn::Item]> {
|
||||||
match self.mod_all {
|
match self.mod_all {
|
||||||
syn::ItemMod {
|
syn::ItemMod {
|
||||||
content: Some((_, ref vec)),
|
content: Some((.., ref vec)),
|
||||||
..
|
..
|
||||||
} => Some(vec),
|
} => Some(vec),
|
||||||
_ => None,
|
_ => None,
|
||||||
|
@ -240,7 +240,7 @@ pub fn generate_body(
|
|||||||
})
|
})
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let (_, generate_call_content) = generate_fn_call.content.take().unwrap();
|
let (.., generate_call_content) = generate_fn_call.content.take().unwrap();
|
||||||
|
|
||||||
quote! {
|
quote! {
|
||||||
#(#generate_call_content)*
|
#(#generate_call_content)*
|
||||||
@ -275,7 +275,7 @@ pub fn check_rename_collisions(fns: &[ExportedFn]) -> Result<(), syn::Error> {
|
|||||||
.map(|n| (n.clone(), n.clone()))
|
.map(|n| (n.clone(), n.clone()))
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
if let Some((s, n, _)) = item_fn.params().special.get_fn_name() {
|
if let Some((s, n, ..)) = item_fn.params().special.get_fn_name() {
|
||||||
names.push((s, n));
|
names.push((s, n));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -99,7 +99,7 @@ impl Engine {
|
|||||||
) {
|
) {
|
||||||
ast.walk(&mut |path| match path.last().unwrap() {
|
ast.walk(&mut |path| match path.last().unwrap() {
|
||||||
// Collect all `import` statements with a string constant path
|
// Collect all `import` statements with a string constant path
|
||||||
ASTNode::Stmt(Stmt::Import(Expr::StringConstant(s, _), _, _))
|
ASTNode::Stmt(Stmt::Import(Expr::StringConstant(s, ..), ..))
|
||||||
if !resolver.contains_path(s) && !imports.contains(s.as_str()) =>
|
if !resolver.contains_path(s) && !imports.contains(s.as_str()) =>
|
||||||
{
|
{
|
||||||
imports.insert(s.clone().into());
|
imports.insert(s.clone().into());
|
||||||
|
@ -72,9 +72,9 @@ impl Expression<'_> {
|
|||||||
pub fn get_string_value(&self) -> Option<&str> {
|
pub fn get_string_value(&self) -> Option<&str> {
|
||||||
match self.0 {
|
match self.0 {
|
||||||
#[cfg(not(feature = "no_module"))]
|
#[cfg(not(feature = "no_module"))]
|
||||||
Expr::Variable(_, _, x) if x.1.is_some() => None,
|
Expr::Variable(.., _, x) if x.1.is_some() => None,
|
||||||
Expr::Variable(_, _, x) => Some(x.2.as_str()),
|
Expr::Variable(.., _, x) => Some(x.2.as_str()),
|
||||||
Expr::StringConstant(x, _) => Some(x.as_str()),
|
Expr::StringConstant(x, ..) => Some(x.as_str()),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -94,18 +94,18 @@ impl Expression<'_> {
|
|||||||
pub fn get_literal_value<T: Variant>(&self) -> Option<T> {
|
pub fn get_literal_value<T: Variant>(&self) -> Option<T> {
|
||||||
// Coded this way in order to maximally leverage potentials for dead-code removal.
|
// Coded this way in order to maximally leverage potentials for dead-code removal.
|
||||||
match self.0 {
|
match self.0 {
|
||||||
Expr::IntegerConstant(x, _) => reify!(*x, |x: T| Some(x), || None),
|
Expr::IntegerConstant(x, ..) => reify!(*x, |x: T| Some(x), || None),
|
||||||
|
|
||||||
#[cfg(not(feature = "no_float"))]
|
#[cfg(not(feature = "no_float"))]
|
||||||
Expr::FloatConstant(x, _) => reify!(*x, |x: T| Some(x), || None),
|
Expr::FloatConstant(x, ..) => reify!(*x, |x: T| Some(x), || None),
|
||||||
|
|
||||||
Expr::CharConstant(x, _) => reify!(*x, |x: T| Some(x), || None),
|
Expr::CharConstant(x, ..) => reify!(*x, |x: T| Some(x), || None),
|
||||||
Expr::StringConstant(x, _) => reify!(x.clone(), |x: T| Some(x), || None),
|
Expr::StringConstant(x, ..) => reify!(x.clone(), |x: T| Some(x), || None),
|
||||||
Expr::Variable(_, _, x) => {
|
Expr::Variable(.., _, x) => {
|
||||||
let x: ImmutableString = x.2.clone().into();
|
let x: ImmutableString = x.2.clone().into();
|
||||||
reify!(x, |x: T| Some(x), || None)
|
reify!(x, |x: T| Some(x), || None)
|
||||||
}
|
}
|
||||||
Expr::BoolConstant(x, _) => reify!(*x, |x: T| Some(x), || None),
|
Expr::BoolConstant(x, ..) => reify!(*x, |x: T| Some(x), || None),
|
||||||
Expr::Unit(_) => reify!((), |x: T| Some(x), || None),
|
Expr::Unit(_) => reify!((), |x: T| Some(x), || None),
|
||||||
|
|
||||||
_ => None,
|
_ => None,
|
||||||
|
@ -53,7 +53,7 @@ impl fmt::Debug for AST {
|
|||||||
|
|
||||||
#[cfg(not(feature = "no_function"))]
|
#[cfg(not(feature = "no_function"))]
|
||||||
if !self.lib.is_empty() {
|
if !self.lib.is_empty() {
|
||||||
for (_, _, _, _, ref fn_def) in self.lib.iter_script_fn() {
|
for (.., ref fn_def) in self.lib.iter_script_fn() {
|
||||||
let sig = fn_def.to_string();
|
let sig = fn_def.to_string();
|
||||||
fp.field(&sig, &fn_def.body.as_slice());
|
fp.field(&sig, &fn_def.body.as_slice());
|
||||||
}
|
}
|
||||||
@ -640,7 +640,7 @@ impl AST {
|
|||||||
pub fn iter_fn_def(&self) -> impl Iterator<Item = &super::ScriptFnDef> {
|
pub fn iter_fn_def(&self) -> impl Iterator<Item = &super::ScriptFnDef> {
|
||||||
self.lib
|
self.lib
|
||||||
.iter_script_fn()
|
.iter_script_fn()
|
||||||
.map(|(_, _, _, _, fn_def)| fn_def.as_ref())
|
.map(|(.., fn_def)| fn_def.as_ref())
|
||||||
}
|
}
|
||||||
/// Iterate through all function definitions.
|
/// Iterate through all function definitions.
|
||||||
///
|
///
|
||||||
@ -652,7 +652,7 @@ impl AST {
|
|||||||
pub(crate) fn iter_fn_def(&self) -> impl Iterator<Item = &super::ScriptFnDef> {
|
pub(crate) fn iter_fn_def(&self) -> impl Iterator<Item = &super::ScriptFnDef> {
|
||||||
self.lib
|
self.lib
|
||||||
.iter_script_fn()
|
.iter_script_fn()
|
||||||
.map(|(_, _, _, _, fn_def)| fn_def.as_ref())
|
.map(|(.., fn_def)| fn_def.as_ref())
|
||||||
}
|
}
|
||||||
/// Iterate through all function definitions.
|
/// Iterate through all function definitions.
|
||||||
///
|
///
|
||||||
@ -662,7 +662,7 @@ impl AST {
|
|||||||
pub fn iter_functions<'a>(&'a self) -> impl Iterator<Item = super::ScriptFnMetadata> + 'a {
|
pub fn iter_functions<'a>(&'a self) -> impl Iterator<Item = super::ScriptFnMetadata> + 'a {
|
||||||
self.lib
|
self.lib
|
||||||
.iter_script_fn()
|
.iter_script_fn()
|
||||||
.map(|(_, _, _, _, fn_def)| fn_def.as_ref().into())
|
.map(|(.., fn_def)| fn_def.as_ref().into())
|
||||||
}
|
}
|
||||||
/// Clear all function definitions in the [`AST`].
|
/// Clear all function definitions in the [`AST`].
|
||||||
///
|
///
|
||||||
@ -744,7 +744,7 @@ impl AST {
|
|||||||
include_variables: bool,
|
include_variables: bool,
|
||||||
) -> impl Iterator<Item = (&str, bool, Dynamic)> {
|
) -> impl Iterator<Item = (&str, bool, Dynamic)> {
|
||||||
self.statements().iter().filter_map(move |stmt| match stmt {
|
self.statements().iter().filter_map(move |stmt| match stmt {
|
||||||
Stmt::Var(expr, name, options, _)
|
Stmt::Var(expr, name, options, ..)
|
||||||
if options.contains(AST_OPTION_CONSTANT) && include_constants
|
if options.contains(AST_OPTION_CONSTANT) && include_constants
|
||||||
|| !options.contains(AST_OPTION_CONSTANT) && include_variables =>
|
|| !options.contains(AST_OPTION_CONSTANT) && include_variables =>
|
||||||
{
|
{
|
||||||
|
270
src/ast/expr.rs
270
src/ast/expr.rs
@ -443,24 +443,24 @@ impl fmt::Debug for Expr {
|
|||||||
let mut display_pos = self.start_position();
|
let mut display_pos = self.start_position();
|
||||||
|
|
||||||
match self {
|
match self {
|
||||||
Self::DynamicConstant(value, _) => write!(f, "{:?}", value),
|
Self::DynamicConstant(value, ..) => write!(f, "{:?}", value),
|
||||||
Self::BoolConstant(value, _) => write!(f, "{:?}", value),
|
Self::BoolConstant(value, ..) => write!(f, "{:?}", value),
|
||||||
Self::IntegerConstant(value, _) => write!(f, "{:?}", value),
|
Self::IntegerConstant(value, ..) => write!(f, "{:?}", value),
|
||||||
#[cfg(not(feature = "no_float"))]
|
#[cfg(not(feature = "no_float"))]
|
||||||
Self::FloatConstant(value, _) => write!(f, "{:?}", value),
|
Self::FloatConstant(value, ..) => write!(f, "{:?}", value),
|
||||||
Self::CharConstant(value, _) => write!(f, "{:?}", value),
|
Self::CharConstant(value, ..) => write!(f, "{:?}", value),
|
||||||
Self::StringConstant(value, _) => write!(f, "{:?}", value),
|
Self::StringConstant(value, ..) => write!(f, "{:?}", value),
|
||||||
Self::Unit(_) => f.write_str("()"),
|
Self::Unit(_) => f.write_str("()"),
|
||||||
|
|
||||||
Self::InterpolatedString(x, _) => {
|
Self::InterpolatedString(x, ..) => {
|
||||||
f.write_str("InterpolatedString")?;
|
f.write_str("InterpolatedString")?;
|
||||||
return f.debug_list().entries(x.iter()).finish();
|
return f.debug_list().entries(x.iter()).finish();
|
||||||
}
|
}
|
||||||
Self::Array(x, _) => {
|
Self::Array(x, ..) => {
|
||||||
f.write_str("Array")?;
|
f.write_str("Array")?;
|
||||||
f.debug_list().entries(x.iter()).finish()
|
f.debug_list().entries(x.iter()).finish()
|
||||||
}
|
}
|
||||||
Self::Map(x, _) => {
|
Self::Map(x, ..) => {
|
||||||
f.write_str("Map")?;
|
f.write_str("Map")?;
|
||||||
f.debug_map()
|
f.debug_map()
|
||||||
.entries(x.0.iter().map(|(k, v)| (k, v)))
|
.entries(x.0.iter().map(|(k, v)| (k, v)))
|
||||||
@ -470,7 +470,7 @@ impl fmt::Debug for Expr {
|
|||||||
f.write_str("Variable(")?;
|
f.write_str("Variable(")?;
|
||||||
|
|
||||||
#[cfg(not(feature = "no_module"))]
|
#[cfg(not(feature = "no_module"))]
|
||||||
if let Some((_, ref namespace)) = x.1 {
|
if let Some((.., ref namespace)) = x.1 {
|
||||||
write!(f, "{}{}", namespace, Token::DoubleColon.literal_syntax())?
|
write!(f, "{}{}", namespace, Token::DoubleColon.literal_syntax())?
|
||||||
}
|
}
|
||||||
f.write_str(&x.2)?;
|
f.write_str(&x.2)?;
|
||||||
@ -479,13 +479,13 @@ impl fmt::Debug for Expr {
|
|||||||
}
|
}
|
||||||
f.write_str(")")
|
f.write_str(")")
|
||||||
}
|
}
|
||||||
Self::Property(x, _) => write!(f, "Property({})", x.2),
|
Self::Property(x, ..) => write!(f, "Property({})", x.2),
|
||||||
Self::Stack(x, _) => write!(f, "ConstantArg#{}", x),
|
Self::Stack(x, ..) => write!(f, "ConstantArg#{}", x),
|
||||||
Self::Stmt(x) => {
|
Self::Stmt(x) => {
|
||||||
f.write_str("ExprStmtBlock")?;
|
f.write_str("ExprStmtBlock")?;
|
||||||
f.debug_list().entries(x.iter()).finish()
|
f.debug_list().entries(x.iter()).finish()
|
||||||
}
|
}
|
||||||
Self::FnCall(x, _) => fmt::Debug::fmt(x, f),
|
Self::FnCall(x, ..) => fmt::Debug::fmt(x, f),
|
||||||
Self::Index(x, term, pos) => {
|
Self::Index(x, term, pos) => {
|
||||||
display_pos = *pos;
|
display_pos = *pos;
|
||||||
|
|
||||||
@ -497,9 +497,9 @@ impl fmt::Debug for Expr {
|
|||||||
}
|
}
|
||||||
Self::Dot(x, _, pos) | Self::And(x, pos) | Self::Or(x, pos) => {
|
Self::Dot(x, _, pos) | Self::And(x, pos) | Self::Or(x, pos) => {
|
||||||
let op_name = match self {
|
let op_name = match self {
|
||||||
Self::Dot(_, _, _) => "Dot",
|
Self::Dot(..) => "Dot",
|
||||||
Self::And(_, _) => "And",
|
Self::And(..) => "And",
|
||||||
Self::Or(_, _) => "Or",
|
Self::Or(..) => "Or",
|
||||||
expr => unreachable!(
|
expr => unreachable!(
|
||||||
"Self::Dot or Self::And or Self::Or expected but gets {:?}",
|
"Self::Dot or Self::And or Self::Or expected but gets {:?}",
|
||||||
expr
|
expr
|
||||||
@ -513,7 +513,7 @@ impl fmt::Debug for Expr {
|
|||||||
.field("rhs", &x.rhs)
|
.field("rhs", &x.rhs)
|
||||||
.finish()
|
.finish()
|
||||||
}
|
}
|
||||||
Self::Custom(x, _) => f.debug_tuple("Custom").field(x).finish(),
|
Self::Custom(x, ..) => f.debug_tuple("Custom").field(x).finish(),
|
||||||
}?;
|
}?;
|
||||||
|
|
||||||
display_pos.debug_print(f)
|
display_pos.debug_print(f)
|
||||||
@ -528,24 +528,24 @@ impl Expr {
|
|||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn get_literal_value(&self) -> Option<Dynamic> {
|
pub fn get_literal_value(&self) -> Option<Dynamic> {
|
||||||
Some(match self {
|
Some(match self {
|
||||||
Self::DynamicConstant(x, _) => x.as_ref().clone(),
|
Self::DynamicConstant(x, ..) => x.as_ref().clone(),
|
||||||
Self::IntegerConstant(x, _) => (*x).into(),
|
Self::IntegerConstant(x, ..) => (*x).into(),
|
||||||
#[cfg(not(feature = "no_float"))]
|
#[cfg(not(feature = "no_float"))]
|
||||||
Self::FloatConstant(x, _) => (*x).into(),
|
Self::FloatConstant(x, ..) => (*x).into(),
|
||||||
Self::CharConstant(x, _) => (*x).into(),
|
Self::CharConstant(x, ..) => (*x).into(),
|
||||||
Self::StringConstant(x, _) => x.clone().into(),
|
Self::StringConstant(x, ..) => x.clone().into(),
|
||||||
Self::BoolConstant(x, _) => (*x).into(),
|
Self::BoolConstant(x, ..) => (*x).into(),
|
||||||
Self::Unit(_) => Dynamic::UNIT,
|
Self::Unit(_) => Dynamic::UNIT,
|
||||||
|
|
||||||
#[cfg(not(feature = "no_index"))]
|
#[cfg(not(feature = "no_index"))]
|
||||||
Self::Array(x, _) if self.is_constant() => {
|
Self::Array(x, ..) if self.is_constant() => {
|
||||||
let mut arr = crate::Array::with_capacity(x.len());
|
let mut arr = crate::Array::with_capacity(x.len());
|
||||||
arr.extend(x.iter().map(|v| v.get_literal_value().unwrap()));
|
arr.extend(x.iter().map(|v| v.get_literal_value().unwrap()));
|
||||||
Dynamic::from_array(arr)
|
Dynamic::from_array(arr)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(feature = "no_object"))]
|
#[cfg(not(feature = "no_object"))]
|
||||||
Self::Map(x, _) if self.is_constant() => {
|
Self::Map(x, ..) if self.is_constant() => {
|
||||||
Dynamic::from_map(x.0.iter().fold(x.1.clone(), |mut map, (k, v)| {
|
Dynamic::from_map(x.0.iter().fold(x.1.clone(), |mut map, (k, v)| {
|
||||||
let value_ref = map.get_mut(k.name.as_str()).unwrap();
|
let value_ref = map.get_mut(k.name.as_str()).unwrap();
|
||||||
*value_ref = v.get_literal_value().unwrap();
|
*value_ref = v.get_literal_value().unwrap();
|
||||||
@ -554,10 +554,10 @@ impl Expr {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Fn
|
// Fn
|
||||||
Self::FnCall(ref x, _)
|
Self::FnCall(ref x, ..)
|
||||||
if !x.is_qualified() && x.args.len() == 1 && x.name == KEYWORD_FN_PTR =>
|
if !x.is_qualified() && x.args.len() == 1 && x.name == KEYWORD_FN_PTR =>
|
||||||
{
|
{
|
||||||
if let Expr::StringConstant(ref s, _) = x.args[0] {
|
if let Expr::StringConstant(ref s, ..) = x.args[0] {
|
||||||
if let Ok(fn_ptr) = FnPtr::new(s) {
|
if let Ok(fn_ptr) = FnPtr::new(s) {
|
||||||
fn_ptr.into()
|
fn_ptr.into()
|
||||||
} else {
|
} else {
|
||||||
@ -569,33 +569,35 @@ impl Expr {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Binary operators
|
// Binary operators
|
||||||
Self::FnCall(x, _) if !x.is_qualified() && x.args.len() == 2 => match x.name.as_str() {
|
Self::FnCall(x, ..) if !x.is_qualified() && x.args.len() == 2 => {
|
||||||
// x..y
|
match x.name.as_str() {
|
||||||
OP_EXCLUSIVE_RANGE => {
|
// x..y
|
||||||
if let Expr::IntegerConstant(ref start, _) = x.args[0] {
|
OP_EXCLUSIVE_RANGE => {
|
||||||
if let Expr::IntegerConstant(ref end, _) = x.args[1] {
|
if let Expr::IntegerConstant(ref start, ..) = x.args[0] {
|
||||||
(*start..*end).into()
|
if let Expr::IntegerConstant(ref end, ..) = x.args[1] {
|
||||||
|
(*start..*end).into()
|
||||||
|
} else {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
return None;
|
|
||||||
}
|
}
|
||||||
}
|
// x..=y
|
||||||
// x..=y
|
OP_INCLUSIVE_RANGE => {
|
||||||
OP_INCLUSIVE_RANGE => {
|
if let Expr::IntegerConstant(ref start, ..) = x.args[0] {
|
||||||
if let Expr::IntegerConstant(ref start, _) = x.args[0] {
|
if let Expr::IntegerConstant(ref end, ..) = x.args[1] {
|
||||||
if let Expr::IntegerConstant(ref end, _) = x.args[1] {
|
(*start..=*end).into()
|
||||||
(*start..=*end).into()
|
} else {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
return None;
|
|
||||||
}
|
}
|
||||||
|
_ => return None,
|
||||||
}
|
}
|
||||||
_ => return None,
|
}
|
||||||
},
|
|
||||||
|
|
||||||
_ => return None,
|
_ => return None,
|
||||||
})
|
})
|
||||||
@ -605,25 +607,25 @@ impl Expr {
|
|||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn from_dynamic(value: Dynamic, pos: Position) -> Self {
|
pub fn from_dynamic(value: Dynamic, pos: Position) -> Self {
|
||||||
match value.0 {
|
match value.0 {
|
||||||
Union::Unit(_, _, _) => Self::Unit(pos),
|
Union::Unit(..) => Self::Unit(pos),
|
||||||
Union::Bool(b, _, _) => Self::BoolConstant(b, pos),
|
Union::Bool(b, ..) => Self::BoolConstant(b, pos),
|
||||||
Union::Str(s, _, _) => Self::StringConstant(s, pos),
|
Union::Str(s, ..) => Self::StringConstant(s, pos),
|
||||||
Union::Char(c, _, _) => Self::CharConstant(c, pos),
|
Union::Char(c, ..) => Self::CharConstant(c, pos),
|
||||||
Union::Int(i, _, _) => Self::IntegerConstant(i, pos),
|
Union::Int(i, ..) => Self::IntegerConstant(i, pos),
|
||||||
|
|
||||||
#[cfg(feature = "decimal")]
|
#[cfg(feature = "decimal")]
|
||||||
Union::Decimal(value, _, _) => Self::DynamicConstant(Box::new((*value).into()), pos),
|
Union::Decimal(value, ..) => Self::DynamicConstant(Box::new((*value).into()), pos),
|
||||||
|
|
||||||
#[cfg(not(feature = "no_float"))]
|
#[cfg(not(feature = "no_float"))]
|
||||||
Union::Float(f, _, _) => Self::FloatConstant(f, pos),
|
Union::Float(f, ..) => Self::FloatConstant(f, pos),
|
||||||
|
|
||||||
#[cfg(not(feature = "no_index"))]
|
#[cfg(not(feature = "no_index"))]
|
||||||
Union::Array(a, _, _) => Self::DynamicConstant(Box::new((*a).into()), pos),
|
Union::Array(a, ..) => Self::DynamicConstant(Box::new((*a).into()), pos),
|
||||||
|
|
||||||
#[cfg(not(feature = "no_object"))]
|
#[cfg(not(feature = "no_object"))]
|
||||||
Union::Map(m, _, _) => Self::DynamicConstant(Box::new((*m).into()), pos),
|
Union::Map(m, ..) => Self::DynamicConstant(Box::new((*m).into()), pos),
|
||||||
|
|
||||||
Union::FnPtr(f, _, _) if !f.is_curried() => Self::FnCall(
|
Union::FnPtr(f, ..) if !f.is_curried() => Self::FnCall(
|
||||||
FnCallExpr {
|
FnCallExpr {
|
||||||
#[cfg(not(feature = "no_module"))]
|
#[cfg(not(feature = "no_module"))]
|
||||||
namespace: None,
|
namespace: None,
|
||||||
@ -651,8 +653,8 @@ impl Expr {
|
|||||||
|
|
||||||
match self {
|
match self {
|
||||||
#[cfg(not(feature = "no_module"))]
|
#[cfg(not(feature = "no_module"))]
|
||||||
Self::Variable(_, _, x) if _non_qualified && x.1.is_some() => false,
|
Self::Variable(.., x) if _non_qualified && x.1.is_some() => false,
|
||||||
Self::Variable(_, _, _) => true,
|
Self::Variable(..) => true,
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -666,8 +668,8 @@ impl Expr {
|
|||||||
|
|
||||||
match self {
|
match self {
|
||||||
#[cfg(not(feature = "no_module"))]
|
#[cfg(not(feature = "no_module"))]
|
||||||
Self::Variable(_, _, x) if _non_qualified && x.1.is_some() => None,
|
Self::Variable(.., x) if _non_qualified && x.1.is_some() => None,
|
||||||
Self::Variable(_, _, x) => Some(x.2.as_str()),
|
Self::Variable(.., x) => Some(x.2.as_str()),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -677,27 +679,27 @@ impl Expr {
|
|||||||
pub const fn position(&self) -> Position {
|
pub const fn position(&self) -> Position {
|
||||||
match self {
|
match self {
|
||||||
#[cfg(not(feature = "no_float"))]
|
#[cfg(not(feature = "no_float"))]
|
||||||
Self::FloatConstant(_, pos) => *pos,
|
Self::FloatConstant(.., pos) => *pos,
|
||||||
|
|
||||||
Self::DynamicConstant(_, pos)
|
Self::DynamicConstant(.., pos)
|
||||||
| Self::BoolConstant(_, pos)
|
| Self::BoolConstant(.., pos)
|
||||||
| Self::IntegerConstant(_, pos)
|
| Self::IntegerConstant(.., pos)
|
||||||
| Self::CharConstant(_, pos)
|
| Self::CharConstant(.., pos)
|
||||||
| Self::Unit(pos)
|
| Self::Unit(pos)
|
||||||
| Self::StringConstant(_, pos)
|
| Self::StringConstant(.., pos)
|
||||||
| Self::Array(_, pos)
|
| Self::Array(.., pos)
|
||||||
| Self::Map(_, pos)
|
| Self::Map(.., pos)
|
||||||
| Self::Variable(_, pos, _)
|
| Self::Variable(.., pos, _)
|
||||||
| Self::Stack(_, pos)
|
| Self::Stack(.., pos)
|
||||||
| Self::And(_, pos)
|
| Self::And(.., pos)
|
||||||
| Self::Or(_, pos)
|
| Self::Or(.., pos)
|
||||||
| Self::Index(_, _, pos)
|
| Self::Index(.., pos)
|
||||||
| Self::Dot(_, _, pos)
|
| Self::Dot(.., pos)
|
||||||
| Self::Custom(_, pos)
|
| Self::Custom(.., pos)
|
||||||
| Self::InterpolatedString(_, pos)
|
| Self::InterpolatedString(.., pos)
|
||||||
| Self::Property(_, pos) => *pos,
|
| Self::Property(.., pos) => *pos,
|
||||||
|
|
||||||
Self::FnCall(x, _) => x.pos,
|
Self::FnCall(x, ..) => x.pos,
|
||||||
|
|
||||||
Self::Stmt(x) => x.position(),
|
Self::Stmt(x) => x.position(),
|
||||||
}
|
}
|
||||||
@ -708,10 +710,10 @@ impl Expr {
|
|||||||
#[must_use]
|
#[must_use]
|
||||||
pub const fn start_position(&self) -> Position {
|
pub const fn start_position(&self) -> Position {
|
||||||
match self {
|
match self {
|
||||||
Self::And(x, _) | Self::Or(x, _) | Self::Index(x, _, _) | Self::Dot(x, _, _) => {
|
Self::And(x, ..) | Self::Or(x, ..) | Self::Index(x, ..) | Self::Dot(x, ..) => {
|
||||||
x.lhs.start_position()
|
x.lhs.start_position()
|
||||||
}
|
}
|
||||||
Self::FnCall(_, pos) => *pos,
|
Self::FnCall(.., pos) => *pos,
|
||||||
_ => self.position(),
|
_ => self.position(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -720,26 +722,26 @@ impl Expr {
|
|||||||
pub fn set_position(&mut self, new_pos: Position) -> &mut Self {
|
pub fn set_position(&mut self, new_pos: Position) -> &mut Self {
|
||||||
match self {
|
match self {
|
||||||
#[cfg(not(feature = "no_float"))]
|
#[cfg(not(feature = "no_float"))]
|
||||||
Self::FloatConstant(_, pos) => *pos = new_pos,
|
Self::FloatConstant(.., pos) => *pos = new_pos,
|
||||||
|
|
||||||
Self::DynamicConstant(_, pos)
|
Self::DynamicConstant(.., pos)
|
||||||
| Self::BoolConstant(_, pos)
|
| Self::BoolConstant(.., pos)
|
||||||
| Self::IntegerConstant(_, pos)
|
| Self::IntegerConstant(.., pos)
|
||||||
| Self::CharConstant(_, pos)
|
| Self::CharConstant(.., pos)
|
||||||
| Self::Unit(pos)
|
| Self::Unit(pos)
|
||||||
| Self::StringConstant(_, pos)
|
| Self::StringConstant(.., pos)
|
||||||
| Self::Array(_, pos)
|
| Self::Array(.., pos)
|
||||||
| Self::Map(_, pos)
|
| Self::Map(.., pos)
|
||||||
| Self::And(_, pos)
|
| Self::And(.., pos)
|
||||||
| Self::Or(_, pos)
|
| Self::Or(.., pos)
|
||||||
| Self::Dot(_, _, pos)
|
| Self::Dot(.., pos)
|
||||||
| Self::Index(_, _, pos)
|
| Self::Index(.., pos)
|
||||||
| Self::Variable(_, pos, _)
|
| Self::Variable(.., pos, _)
|
||||||
| Self::Stack(_, pos)
|
| Self::Stack(.., pos)
|
||||||
| Self::FnCall(_, pos)
|
| Self::FnCall(.., pos)
|
||||||
| Self::Custom(_, pos)
|
| Self::Custom(.., pos)
|
||||||
| Self::InterpolatedString(_, pos)
|
| Self::InterpolatedString(.., pos)
|
||||||
| Self::Property(_, pos) => *pos = new_pos,
|
| Self::Property(.., pos) => *pos = new_pos,
|
||||||
|
|
||||||
Self::Stmt(x) => x.set_position(new_pos, Position::NONE),
|
Self::Stmt(x) => x.set_position(new_pos, Position::NONE),
|
||||||
}
|
}
|
||||||
@ -753,15 +755,15 @@ impl Expr {
|
|||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn is_pure(&self) -> bool {
|
pub fn is_pure(&self) -> bool {
|
||||||
match self {
|
match self {
|
||||||
Self::InterpolatedString(x, _) | Self::Array(x, _) => x.iter().all(Self::is_pure),
|
Self::InterpolatedString(x, ..) | Self::Array(x, ..) => x.iter().all(Self::is_pure),
|
||||||
|
|
||||||
Self::Map(x, _) => x.0.iter().map(|(_, v)| v).all(Self::is_pure),
|
Self::Map(x, ..) => x.0.iter().map(|(.., v)| v).all(Self::is_pure),
|
||||||
|
|
||||||
Self::And(x, _) | Self::Or(x, _) => x.lhs.is_pure() && x.rhs.is_pure(),
|
Self::And(x, ..) | Self::Or(x, ..) => x.lhs.is_pure() && x.rhs.is_pure(),
|
||||||
|
|
||||||
Self::Stmt(x) => x.iter().all(Stmt::is_pure),
|
Self::Stmt(x) => x.iter().all(Stmt::is_pure),
|
||||||
|
|
||||||
Self::Variable(_, _, _) | Self::Stack(_, _) => true,
|
Self::Variable(..) | Self::Stack(..) => true,
|
||||||
|
|
||||||
_ => self.is_constant(),
|
_ => self.is_constant(),
|
||||||
}
|
}
|
||||||
@ -778,19 +780,19 @@ impl Expr {
|
|||||||
pub fn is_constant(&self) -> bool {
|
pub fn is_constant(&self) -> bool {
|
||||||
match self {
|
match self {
|
||||||
#[cfg(not(feature = "no_float"))]
|
#[cfg(not(feature = "no_float"))]
|
||||||
Self::FloatConstant(_, _) => true,
|
Self::FloatConstant(..) => true,
|
||||||
|
|
||||||
Self::DynamicConstant(_, _)
|
Self::DynamicConstant(..)
|
||||||
| Self::BoolConstant(_, _)
|
| Self::BoolConstant(..)
|
||||||
| Self::IntegerConstant(_, _)
|
| Self::IntegerConstant(..)
|
||||||
| Self::CharConstant(_, _)
|
| Self::CharConstant(..)
|
||||||
| Self::StringConstant(_, _)
|
| Self::StringConstant(..)
|
||||||
| Self::Unit(_)
|
| Self::Unit(_)
|
||||||
| Self::Stack(_, _) => true,
|
| Self::Stack(..) => true,
|
||||||
|
|
||||||
Self::InterpolatedString(x, _) | Self::Array(x, _) => x.iter().all(Self::is_constant),
|
Self::InterpolatedString(x, ..) | Self::Array(x, ..) => x.iter().all(Self::is_constant),
|
||||||
|
|
||||||
Self::Map(x, _) => x.0.iter().map(|(_, expr)| expr).all(Self::is_constant),
|
Self::Map(x, ..) => x.0.iter().map(|(.., expr)| expr).all(Self::is_constant),
|
||||||
|
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
@ -807,31 +809,31 @@ impl Expr {
|
|||||||
|
|
||||||
match self {
|
match self {
|
||||||
#[cfg(not(feature = "no_float"))]
|
#[cfg(not(feature = "no_float"))]
|
||||||
Self::FloatConstant(_, _) => false,
|
Self::FloatConstant(..) => false,
|
||||||
|
|
||||||
Self::DynamicConstant(_, _)
|
Self::DynamicConstant(..)
|
||||||
| Self::BoolConstant(_, _)
|
| Self::BoolConstant(..)
|
||||||
| Self::CharConstant(_, _)
|
| Self::CharConstant(..)
|
||||||
| Self::And(_, _)
|
| Self::And(..)
|
||||||
| Self::Or(_, _)
|
| Self::Or(..)
|
||||||
| Self::Unit(_) => false,
|
| Self::Unit(_) => false,
|
||||||
|
|
||||||
Self::IntegerConstant(_, _)
|
Self::IntegerConstant(..)
|
||||||
| Self::StringConstant(_, _)
|
| Self::StringConstant(..)
|
||||||
| Self::InterpolatedString(_, _)
|
| Self::InterpolatedString(..)
|
||||||
| Self::FnCall(_, _)
|
| Self::FnCall(..)
|
||||||
| Self::Stmt(_)
|
| Self::Stmt(_)
|
||||||
| Self::Dot(_, _, _)
|
| Self::Dot(..)
|
||||||
| Self::Index(_, _, _)
|
| Self::Index(..)
|
||||||
| Self::Array(_, _)
|
| Self::Array(..)
|
||||||
| Self::Map(_, _)
|
| Self::Map(..)
|
||||||
| Self::Custom(_, _) => match token {
|
| Self::Custom(..) => match token {
|
||||||
#[cfg(not(feature = "no_index"))]
|
#[cfg(not(feature = "no_index"))]
|
||||||
Token::LeftBracket => true,
|
Token::LeftBracket => true,
|
||||||
_ => false,
|
_ => false,
|
||||||
},
|
},
|
||||||
|
|
||||||
Self::Variable(_, _, _) => match token {
|
Self::Variable(..) => match token {
|
||||||
#[cfg(not(feature = "no_index"))]
|
#[cfg(not(feature = "no_index"))]
|
||||||
Token::LeftBracket => true,
|
Token::LeftBracket => true,
|
||||||
Token::LeftParen => true,
|
Token::LeftParen => true,
|
||||||
@ -840,14 +842,14 @@ impl Expr {
|
|||||||
_ => false,
|
_ => false,
|
||||||
},
|
},
|
||||||
|
|
||||||
Self::Property(_, _) => match token {
|
Self::Property(..) => match token {
|
||||||
#[cfg(not(feature = "no_index"))]
|
#[cfg(not(feature = "no_index"))]
|
||||||
Token::LeftBracket => true,
|
Token::LeftBracket => true,
|
||||||
Token::LeftParen => true,
|
Token::LeftParen => true,
|
||||||
_ => false,
|
_ => false,
|
||||||
},
|
},
|
||||||
|
|
||||||
Self::Stack(_, _) => false,
|
Self::Stack(..) => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/// Recursively walk this expression.
|
/// Recursively walk this expression.
|
||||||
@ -872,21 +874,21 @@ impl Expr {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Self::InterpolatedString(x, _) | Self::Array(x, _) => {
|
Self::InterpolatedString(x, ..) | Self::Array(x, ..) => {
|
||||||
for e in x.as_ref() {
|
for e in x.as_ref() {
|
||||||
if !e.walk(path, on_node) {
|
if !e.walk(path, on_node) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Self::Map(x, _) => {
|
Self::Map(x, ..) => {
|
||||||
for (_, e) in &x.0 {
|
for (.., e) in &x.0 {
|
||||||
if !e.walk(path, on_node) {
|
if !e.walk(path, on_node) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Self::Index(x, _, _) | Self::Dot(x, _, _) | Expr::And(x, _) | Expr::Or(x, _) => {
|
Self::Index(x, ..) | Self::Dot(x, ..) | Expr::And(x, ..) | Expr::Or(x, ..) => {
|
||||||
if !x.lhs.walk(path, on_node) {
|
if !x.lhs.walk(path, on_node) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -894,14 +896,14 @@ impl Expr {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Self::FnCall(x, _) => {
|
Self::FnCall(x, ..) => {
|
||||||
for e in &x.args {
|
for e in &x.args {
|
||||||
if !e.walk(path, on_node) {
|
if !e.walk(path, on_node) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Self::Custom(x, _) => {
|
Self::Custom(x, ..) => {
|
||||||
for e in &x.inputs {
|
for e in &x.inputs {
|
||||||
if !e.walk(path, on_node) {
|
if !e.walk(path, on_node) {
|
||||||
return false;
|
return false;
|
||||||
|
169
src/ast/stmt.rs
169
src/ast/stmt.rs
@ -411,25 +411,25 @@ impl Stmt {
|
|||||||
pub const fn position(&self) -> Position {
|
pub const fn position(&self) -> Position {
|
||||||
match self {
|
match self {
|
||||||
Self::Noop(pos)
|
Self::Noop(pos)
|
||||||
| Self::BreakLoop(_, pos)
|
| Self::BreakLoop(.., pos)
|
||||||
| Self::Block(_, (pos, _))
|
| Self::Block(.., (pos, ..))
|
||||||
| Self::Assignment(_, pos)
|
| Self::Assignment(.., pos)
|
||||||
| Self::FnCall(_, pos)
|
| Self::FnCall(.., pos)
|
||||||
| Self::If(_, _, pos)
|
| Self::If(.., pos)
|
||||||
| Self::Switch(_, _, pos)
|
| Self::Switch(.., pos)
|
||||||
| Self::While(_, _, pos)
|
| Self::While(.., pos)
|
||||||
| Self::Do(_, _, _, pos)
|
| Self::Do(.., pos)
|
||||||
| Self::For(_, _, pos)
|
| Self::For(.., pos)
|
||||||
| Self::Return(_, _, pos)
|
| Self::Return(.., pos)
|
||||||
| Self::Var(_, _, _, pos)
|
| Self::Var(.., pos)
|
||||||
| Self::TryCatch(_, pos) => *pos,
|
| Self::TryCatch(.., pos) => *pos,
|
||||||
|
|
||||||
Self::Expr(x) => x.start_position(),
|
Self::Expr(x) => x.start_position(),
|
||||||
|
|
||||||
#[cfg(not(feature = "no_module"))]
|
#[cfg(not(feature = "no_module"))]
|
||||||
Self::Import(_, _, pos) => *pos,
|
Self::Import(.., pos) => *pos,
|
||||||
#[cfg(not(feature = "no_module"))]
|
#[cfg(not(feature = "no_module"))]
|
||||||
Self::Export(_, pos) => *pos,
|
Self::Export(.., pos) => *pos,
|
||||||
|
|
||||||
#[cfg(not(feature = "no_closure"))]
|
#[cfg(not(feature = "no_closure"))]
|
||||||
Self::Share(_) => Position::NONE,
|
Self::Share(_) => Position::NONE,
|
||||||
@ -439,27 +439,27 @@ impl Stmt {
|
|||||||
pub fn set_position(&mut self, new_pos: Position) -> &mut Self {
|
pub fn set_position(&mut self, new_pos: Position) -> &mut Self {
|
||||||
match self {
|
match self {
|
||||||
Self::Noop(pos)
|
Self::Noop(pos)
|
||||||
| Self::BreakLoop(_, pos)
|
| Self::BreakLoop(.., pos)
|
||||||
| Self::Block(_, (pos, _))
|
| Self::Block(.., (pos, ..))
|
||||||
| Self::Assignment(_, pos)
|
| Self::Assignment(.., pos)
|
||||||
| Self::FnCall(_, pos)
|
| Self::FnCall(.., pos)
|
||||||
| Self::If(_, _, pos)
|
| Self::If(.., pos)
|
||||||
| Self::Switch(_, _, pos)
|
| Self::Switch(.., pos)
|
||||||
| Self::While(_, _, pos)
|
| Self::While(.., pos)
|
||||||
| Self::Do(_, _, _, pos)
|
| Self::Do(.., pos)
|
||||||
| Self::For(_, _, pos)
|
| Self::For(.., pos)
|
||||||
| Self::Return(_, _, pos)
|
| Self::Return(.., pos)
|
||||||
| Self::Var(_, _, _, pos)
|
| Self::Var(.., pos)
|
||||||
| Self::TryCatch(_, pos) => *pos = new_pos,
|
| Self::TryCatch(.., pos) => *pos = new_pos,
|
||||||
|
|
||||||
Self::Expr(x) => {
|
Self::Expr(x) => {
|
||||||
x.set_position(new_pos);
|
x.set_position(new_pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(feature = "no_module"))]
|
#[cfg(not(feature = "no_module"))]
|
||||||
Self::Import(_, _, pos) => *pos = new_pos,
|
Self::Import(.., pos) => *pos = new_pos,
|
||||||
#[cfg(not(feature = "no_module"))]
|
#[cfg(not(feature = "no_module"))]
|
||||||
Self::Export(_, pos) => *pos = new_pos,
|
Self::Export(.., pos) => *pos = new_pos,
|
||||||
|
|
||||||
#[cfg(not(feature = "no_closure"))]
|
#[cfg(not(feature = "no_closure"))]
|
||||||
Self::Share(_) => (),
|
Self::Share(_) => (),
|
||||||
@ -471,25 +471,20 @@ impl Stmt {
|
|||||||
#[must_use]
|
#[must_use]
|
||||||
pub const fn returns_value(&self) -> bool {
|
pub const fn returns_value(&self) -> bool {
|
||||||
match self {
|
match self {
|
||||||
Self::If(_, _, _)
|
Self::If(..)
|
||||||
| Self::Switch(_, _, _)
|
| Self::Switch(..)
|
||||||
| Self::Block(_, _)
|
| Self::Block(..)
|
||||||
| Self::Expr(_)
|
| Self::Expr(_)
|
||||||
| Self::FnCall(_, _) => true,
|
| Self::FnCall(..) => true,
|
||||||
|
|
||||||
Self::Noop(_)
|
Self::Noop(_) | Self::While(..) | Self::Do(..) | Self::For(..) | Self::TryCatch(..) => {
|
||||||
| Self::While(_, _, _)
|
false
|
||||||
| Self::Do(_, _, _, _)
|
}
|
||||||
| Self::For(_, _, _)
|
|
||||||
| Self::TryCatch(_, _) => false,
|
|
||||||
|
|
||||||
Self::Var(_, _, _, _)
|
Self::Var(..) | Self::Assignment(..) | Self::BreakLoop(..) | Self::Return(..) => false,
|
||||||
| Self::Assignment(_, _)
|
|
||||||
| Self::BreakLoop(_, _)
|
|
||||||
| Self::Return(_, _, _) => false,
|
|
||||||
|
|
||||||
#[cfg(not(feature = "no_module"))]
|
#[cfg(not(feature = "no_module"))]
|
||||||
Self::Import(_, _, _) | Self::Export(_, _) => false,
|
Self::Import(..) | Self::Export(..) => false,
|
||||||
|
|
||||||
#[cfg(not(feature = "no_closure"))]
|
#[cfg(not(feature = "no_closure"))]
|
||||||
Self::Share(_) => false,
|
Self::Share(_) => false,
|
||||||
@ -499,28 +494,28 @@ impl Stmt {
|
|||||||
#[must_use]
|
#[must_use]
|
||||||
pub const fn is_self_terminated(&self) -> bool {
|
pub const fn is_self_terminated(&self) -> bool {
|
||||||
match self {
|
match self {
|
||||||
Self::If(_, _, _)
|
Self::If(..)
|
||||||
| Self::Switch(_, _, _)
|
| Self::Switch(..)
|
||||||
| Self::While(_, _, _)
|
| Self::While(..)
|
||||||
| Self::For(_, _, _)
|
| Self::For(..)
|
||||||
| Self::Block(_, _)
|
| Self::Block(..)
|
||||||
| Self::TryCatch(_, _) => true,
|
| Self::TryCatch(..) => true,
|
||||||
|
|
||||||
// A No-op requires a semicolon in order to know it is an empty statement!
|
// A No-op requires a semicolon in order to know it is an empty statement!
|
||||||
Self::Noop(_) => false,
|
Self::Noop(_) => false,
|
||||||
|
|
||||||
Self::Expr(Expr::Custom(x, _)) if x.is_self_terminated() => true,
|
Self::Expr(Expr::Custom(x, ..)) if x.is_self_terminated() => true,
|
||||||
|
|
||||||
Self::Var(_, _, _, _)
|
Self::Var(..)
|
||||||
| Self::Assignment(_, _)
|
| Self::Assignment(..)
|
||||||
| Self::Expr(_)
|
| Self::Expr(_)
|
||||||
| Self::FnCall(_, _)
|
| Self::FnCall(..)
|
||||||
| Self::Do(_, _, _, _)
|
| Self::Do(..)
|
||||||
| Self::BreakLoop(_, _)
|
| Self::BreakLoop(..)
|
||||||
| Self::Return(_, _, _) => false,
|
| Self::Return(..) => false,
|
||||||
|
|
||||||
#[cfg(not(feature = "no_module"))]
|
#[cfg(not(feature = "no_module"))]
|
||||||
Self::Import(_, _, _) | Self::Export(_, _) => false,
|
Self::Import(..) | Self::Export(..) => false,
|
||||||
|
|
||||||
#[cfg(not(feature = "no_closure"))]
|
#[cfg(not(feature = "no_closure"))]
|
||||||
Self::Share(_) => false,
|
Self::Share(_) => false,
|
||||||
@ -534,18 +529,18 @@ impl Stmt {
|
|||||||
match self {
|
match self {
|
||||||
Self::Noop(_) => true,
|
Self::Noop(_) => true,
|
||||||
Self::Expr(expr) => expr.is_pure(),
|
Self::Expr(expr) => expr.is_pure(),
|
||||||
Self::If(condition, x, _) => {
|
Self::If(condition, x, ..) => {
|
||||||
condition.is_pure()
|
condition.is_pure()
|
||||||
&& x.0.iter().all(Stmt::is_pure)
|
&& x.0.iter().all(Stmt::is_pure)
|
||||||
&& x.1.iter().all(Stmt::is_pure)
|
&& x.1.iter().all(Stmt::is_pure)
|
||||||
}
|
}
|
||||||
Self::Switch(expr, x, _) => {
|
Self::Switch(expr, x, ..) => {
|
||||||
expr.is_pure()
|
expr.is_pure()
|
||||||
&& x.cases.values().all(|block| {
|
&& x.cases.values().all(|block| {
|
||||||
block.condition.as_ref().map(Expr::is_pure).unwrap_or(true)
|
block.condition.as_ref().map(Expr::is_pure).unwrap_or(true)
|
||||||
&& block.statements.iter().all(Stmt::is_pure)
|
&& block.statements.iter().all(Stmt::is_pure)
|
||||||
})
|
})
|
||||||
&& x.ranges.iter().all(|(_, _, _, block)| {
|
&& x.ranges.iter().all(|(.., block)| {
|
||||||
block.condition.as_ref().map(Expr::is_pure).unwrap_or(true)
|
block.condition.as_ref().map(Expr::is_pure).unwrap_or(true)
|
||||||
&& block.statements.iter().all(Stmt::is_pure)
|
&& block.statements.iter().all(Stmt::is_pure)
|
||||||
})
|
})
|
||||||
@ -553,31 +548,31 @@ impl Stmt {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Loops that exit can be pure because it can never be infinite.
|
// Loops that exit can be pure because it can never be infinite.
|
||||||
Self::While(Expr::BoolConstant(false, _), _, _) => true,
|
Self::While(Expr::BoolConstant(false, ..), ..) => true,
|
||||||
Self::Do(body, Expr::BoolConstant(x, _), options, _)
|
Self::Do(body, Expr::BoolConstant(x, ..), options, ..)
|
||||||
if *x == options.contains(AST_OPTION_NEGATED) =>
|
if *x == options.contains(AST_OPTION_NEGATED) =>
|
||||||
{
|
{
|
||||||
body.iter().all(Stmt::is_pure)
|
body.iter().all(Stmt::is_pure)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Loops are never pure since they can be infinite - and that's a side effect.
|
// Loops are never pure since they can be infinite - and that's a side effect.
|
||||||
Self::While(_, _, _) | Self::Do(_, _, _, _) => false,
|
Self::While(..) | Self::Do(..) => false,
|
||||||
|
|
||||||
// For loops can be pure because if the iterable is pure, it is finite,
|
// For loops can be pure because if the iterable is pure, it is finite,
|
||||||
// so infinite loops can never occur.
|
// so infinite loops can never occur.
|
||||||
Self::For(iterable, x, _) => iterable.is_pure() && x.2.iter().all(Stmt::is_pure),
|
Self::For(iterable, x, ..) => iterable.is_pure() && x.2.iter().all(Stmt::is_pure),
|
||||||
|
|
||||||
Self::Var(_, _, _, _) | Self::Assignment(_, _) | Self::FnCall(_, _) => false,
|
Self::Var(..) | Self::Assignment(..) | Self::FnCall(..) => false,
|
||||||
Self::Block(block, _) => block.iter().all(|stmt| stmt.is_pure()),
|
Self::Block(block, ..) => block.iter().all(|stmt| stmt.is_pure()),
|
||||||
Self::BreakLoop(_, _) | Self::Return(_, _, _) => false,
|
Self::BreakLoop(..) | Self::Return(..) => false,
|
||||||
Self::TryCatch(x, _) => {
|
Self::TryCatch(x, ..) => {
|
||||||
x.try_block.iter().all(Stmt::is_pure) && x.catch_block.iter().all(Stmt::is_pure)
|
x.try_block.iter().all(Stmt::is_pure) && x.catch_block.iter().all(Stmt::is_pure)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(feature = "no_module"))]
|
#[cfg(not(feature = "no_module"))]
|
||||||
Self::Import(_, _, _) => false,
|
Self::Import(..) => false,
|
||||||
#[cfg(not(feature = "no_module"))]
|
#[cfg(not(feature = "no_module"))]
|
||||||
Self::Export(_, _) => false,
|
Self::Export(..) => false,
|
||||||
|
|
||||||
#[cfg(not(feature = "no_closure"))]
|
#[cfg(not(feature = "no_closure"))]
|
||||||
Self::Share(_) => false,
|
Self::Share(_) => false,
|
||||||
@ -594,16 +589,16 @@ impl Stmt {
|
|||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn is_block_dependent(&self) -> bool {
|
pub fn is_block_dependent(&self) -> bool {
|
||||||
match self {
|
match self {
|
||||||
Self::Var(_, _, _, _) => true,
|
Self::Var(..) => true,
|
||||||
|
|
||||||
Self::Expr(Expr::Stmt(s)) => s.iter().all(Stmt::is_block_dependent),
|
Self::Expr(Expr::Stmt(s)) => s.iter().all(Stmt::is_block_dependent),
|
||||||
|
|
||||||
Self::FnCall(x, _) | Self::Expr(Expr::FnCall(x, _)) => {
|
Self::FnCall(x, ..) | Self::Expr(Expr::FnCall(x, ..)) => {
|
||||||
!x.is_qualified() && x.name == KEYWORD_EVAL
|
!x.is_qualified() && x.name == KEYWORD_EVAL
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(feature = "no_module"))]
|
#[cfg(not(feature = "no_module"))]
|
||||||
Self::Import(_, _, _) | Self::Export(_, _) => true,
|
Self::Import(..) | Self::Export(..) => true,
|
||||||
|
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
@ -618,14 +613,14 @@ impl Stmt {
|
|||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn is_internally_pure(&self) -> bool {
|
pub fn is_internally_pure(&self) -> bool {
|
||||||
match self {
|
match self {
|
||||||
Self::Var(expr, _, _, _) => expr.is_pure(),
|
Self::Var(expr, _, ..) => expr.is_pure(),
|
||||||
|
|
||||||
Self::Expr(Expr::Stmt(s)) => s.iter().all(Stmt::is_internally_pure),
|
Self::Expr(Expr::Stmt(s)) => s.iter().all(Stmt::is_internally_pure),
|
||||||
|
|
||||||
#[cfg(not(feature = "no_module"))]
|
#[cfg(not(feature = "no_module"))]
|
||||||
Self::Import(expr, _, _) => expr.is_pure(),
|
Self::Import(expr, ..) => expr.is_pure(),
|
||||||
#[cfg(not(feature = "no_module"))]
|
#[cfg(not(feature = "no_module"))]
|
||||||
Self::Export(_, _) => true,
|
Self::Export(..) => true,
|
||||||
|
|
||||||
_ => self.is_pure(),
|
_ => self.is_pure(),
|
||||||
}
|
}
|
||||||
@ -639,7 +634,7 @@ impl Stmt {
|
|||||||
#[must_use]
|
#[must_use]
|
||||||
pub const fn is_control_flow_break(&self) -> bool {
|
pub const fn is_control_flow_break(&self) -> bool {
|
||||||
match self {
|
match self {
|
||||||
Self::Return(_, _, _) | Self::BreakLoop(_, _) => true,
|
Self::Return(..) | Self::BreakLoop(..) => true,
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -658,12 +653,12 @@ impl Stmt {
|
|||||||
}
|
}
|
||||||
|
|
||||||
match self {
|
match self {
|
||||||
Self::Var(e, _, _, _) => {
|
Self::Var(e, _, ..) => {
|
||||||
if !e.walk(path, on_node) {
|
if !e.walk(path, on_node) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Self::If(e, x, _) => {
|
Self::If(e, x, ..) => {
|
||||||
if !e.walk(path, on_node) {
|
if !e.walk(path, on_node) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -678,7 +673,7 @@ impl Stmt {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Self::Switch(e, x, _) => {
|
Self::Switch(e, x, ..) => {
|
||||||
if !e.walk(path, on_node) {
|
if !e.walk(path, on_node) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -697,7 +692,7 @@ impl Stmt {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (_, _, _, b) in &x.ranges {
|
for (.., b) in &x.ranges {
|
||||||
if !b
|
if !b
|
||||||
.condition
|
.condition
|
||||||
.as_ref()
|
.as_ref()
|
||||||
@ -718,7 +713,7 @@ impl Stmt {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Self::While(e, s, _) | Self::Do(s, e, _, _) => {
|
Self::While(e, s, ..) | Self::Do(s, e, ..) => {
|
||||||
if !e.walk(path, on_node) {
|
if !e.walk(path, on_node) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -728,7 +723,7 @@ impl Stmt {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Self::For(e, x, _) => {
|
Self::For(e, x, ..) => {
|
||||||
if !e.walk(path, on_node) {
|
if !e.walk(path, on_node) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -738,7 +733,7 @@ impl Stmt {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Self::Assignment(x, _) => {
|
Self::Assignment(x, ..) => {
|
||||||
if !x.1.lhs.walk(path, on_node) {
|
if !x.1.lhs.walk(path, on_node) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -746,21 +741,21 @@ impl Stmt {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Self::FnCall(x, _) => {
|
Self::FnCall(x, ..) => {
|
||||||
for s in &x.args {
|
for s in &x.args {
|
||||||
if !s.walk(path, on_node) {
|
if !s.walk(path, on_node) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Self::Block(x, _) => {
|
Self::Block(x, ..) => {
|
||||||
for s in x.iter() {
|
for s in x.iter() {
|
||||||
if !s.walk(path, on_node) {
|
if !s.walk(path, on_node) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Self::TryCatch(x, _) => {
|
Self::TryCatch(x, ..) => {
|
||||||
for s in x.try_block.iter() {
|
for s in x.try_block.iter() {
|
||||||
if !s.walk(path, on_node) {
|
if !s.walk(path, on_node) {
|
||||||
return false;
|
return false;
|
||||||
@ -778,7 +773,7 @@ impl Stmt {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#[cfg(not(feature = "no_module"))]
|
#[cfg(not(feature = "no_module"))]
|
||||||
Self::Import(e, _, _) => {
|
Self::Import(e, ..) => {
|
||||||
if !e.walk(path, on_node) {
|
if !e.walk(path, on_node) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -584,7 +584,7 @@ fn main() {
|
|||||||
while let Err(err) = engine.run_ast_with_scope(&mut Scope::new(), &main_ast) {
|
while let Err(err) = engine.run_ast_with_scope(&mut Scope::new(), &main_ast) {
|
||||||
match *err {
|
match *err {
|
||||||
// Loop back to restart
|
// Loop back to restart
|
||||||
EvalAltResult::ErrorTerminated(_, _) => (),
|
EvalAltResult::ErrorTerminated(..) => (),
|
||||||
// Break evaluation
|
// Break evaluation
|
||||||
_ => {
|
_ => {
|
||||||
print_error(&script, *err);
|
print_error(&script, *err);
|
||||||
|
@ -489,7 +489,7 @@ fn main() {
|
|||||||
.iter()
|
.iter()
|
||||||
.rev()
|
.rev()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.find(|&(_, h)| h.contains(text))
|
.find(|&(.., h)| h.contains(text))
|
||||||
{
|
{
|
||||||
replacement = Some(line.clone());
|
replacement = Some(line.clone());
|
||||||
replacement_index = history_offset + (rl.history().len() - 1 - n);
|
replacement_index = history_offset + (rl.history().len() - 1 - n);
|
||||||
@ -514,7 +514,7 @@ fn main() {
|
|||||||
.iter()
|
.iter()
|
||||||
.rev()
|
.rev()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.find(|&(_, h)| h.trim_start().starts_with(prefix))
|
.find(|&(.., h)| h.trim_start().starts_with(prefix))
|
||||||
{
|
{
|
||||||
replacement = Some(line.clone());
|
replacement = Some(line.clone());
|
||||||
replacement_index = history_offset + (rl.history().len() - 1 - n);
|
replacement_index = history_offset + (rl.history().len() - 1 - n);
|
||||||
|
@ -323,7 +323,7 @@ impl Engine {
|
|||||||
match result {
|
match result {
|
||||||
Ok(ref mut r) => {
|
Ok(ref mut r) => {
|
||||||
// Concentrate all empty strings into one instance to save memory
|
// Concentrate all empty strings into one instance to save memory
|
||||||
if let Dynamic(Union::Str(s, _, _)) = r {
|
if let Dynamic(Union::Str(s, ..)) = r {
|
||||||
if s.is_empty() {
|
if s.is_empty() {
|
||||||
if !s.ptr_eq(&self.empty_string) {
|
if !s.ptr_eq(&self.empty_string) {
|
||||||
*s = self.const_empty_string();
|
*s = self.const_empty_string();
|
||||||
|
@ -25,9 +25,9 @@ impl From<&Expr> for ChainType {
|
|||||||
fn from(expr: &Expr) -> Self {
|
fn from(expr: &Expr) -> Self {
|
||||||
match expr {
|
match expr {
|
||||||
#[cfg(not(feature = "no_index"))]
|
#[cfg(not(feature = "no_index"))]
|
||||||
Expr::Index(_, _, _) => Self::Indexing,
|
Expr::Index(..) => Self::Indexing,
|
||||||
#[cfg(not(feature = "no_object"))]
|
#[cfg(not(feature = "no_object"))]
|
||||||
Expr::Dot(_, _, _) => Self::Dotting,
|
Expr::Dot(..) => Self::Dotting,
|
||||||
expr => unreachable!("Expr::Index or Expr::Dot expected but gets {:?}", expr),
|
expr => unreachable!("Expr::Index or Expr::Dot expected but gets {:?}", expr),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -58,7 +58,7 @@ impl ChainArgument {
|
|||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn into_index_value(self) -> Option<Dynamic> {
|
pub fn into_index_value(self) -> Option<Dynamic> {
|
||||||
match self {
|
match self {
|
||||||
Self::IndexValue(value, _) => Some(value),
|
Self::IndexValue(value, ..) => Some(value),
|
||||||
#[cfg(not(feature = "no_object"))]
|
#[cfg(not(feature = "no_object"))]
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
@ -89,9 +89,9 @@ impl ChainArgument {
|
|||||||
#[cfg(not(feature = "no_object"))]
|
#[cfg(not(feature = "no_object"))]
|
||||||
ChainArgument::Property(pos) => *pos,
|
ChainArgument::Property(pos) => *pos,
|
||||||
#[cfg(not(feature = "no_object"))]
|
#[cfg(not(feature = "no_object"))]
|
||||||
ChainArgument::MethodCallArgs(_, pos) => *pos,
|
ChainArgument::MethodCallArgs(.., pos) => *pos,
|
||||||
#[cfg(not(feature = "no_index"))]
|
#[cfg(not(feature = "no_index"))]
|
||||||
ChainArgument::IndexValue(_, pos) => *pos,
|
ChainArgument::IndexValue(.., pos) => *pos,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/// Create n [`MethodCallArgs`][ChainArgument::MethodCallArgs].
|
/// Create n [`MethodCallArgs`][ChainArgument::MethodCallArgs].
|
||||||
@ -193,7 +193,7 @@ impl Engine {
|
|||||||
true, root_pos, level,
|
true, root_pos, level,
|
||||||
) {
|
) {
|
||||||
// Just ignore if there is no index setter
|
// Just ignore if there is no index setter
|
||||||
if !matches!(*err, ERR::ErrorFunctionNotFound(_, _)) {
|
if !matches!(*err, ERR::ErrorFunctionNotFound(..)) {
|
||||||
return Err(err);
|
return Err(err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -225,9 +225,7 @@ impl Engine {
|
|||||||
}
|
}
|
||||||
// Can't index - try to call an index setter
|
// Can't index - try to call an index setter
|
||||||
#[cfg(not(feature = "no_index"))]
|
#[cfg(not(feature = "no_index"))]
|
||||||
Err(err) if matches!(*err, ERR::ErrorIndexingType(_, _)) => {
|
Err(err) if matches!(*err, ERR::ErrorIndexingType(..)) => Some(new_val),
|
||||||
Some(new_val)
|
|
||||||
}
|
|
||||||
// Any other error
|
// Any other error
|
||||||
Err(err) => return Err(err),
|
Err(err) => return Err(err),
|
||||||
};
|
};
|
||||||
@ -283,11 +281,11 @@ impl Engine {
|
|||||||
result
|
result
|
||||||
}
|
}
|
||||||
// xxx.fn_name(...) = ???
|
// xxx.fn_name(...) = ???
|
||||||
Expr::FnCall(_, _) if new_val.is_some() => {
|
Expr::FnCall(..) if new_val.is_some() => {
|
||||||
unreachable!("method call cannot be assigned to")
|
unreachable!("method call cannot be assigned to")
|
||||||
}
|
}
|
||||||
// xxx.module::fn_name(...) - syntax error
|
// xxx.module::fn_name(...) - syntax error
|
||||||
Expr::FnCall(_, _) => {
|
Expr::FnCall(..) => {
|
||||||
unreachable!("function call in dot chain should not be namespace-qualified")
|
unreachable!("function call in dot chain should not be namespace-qualified")
|
||||||
}
|
}
|
||||||
// {xxx:map}.id op= ???
|
// {xxx:map}.id op= ???
|
||||||
@ -333,14 +331,14 @@ impl Engine {
|
|||||||
if op_info.is_some() {
|
if op_info.is_some() {
|
||||||
let hash = crate::ast::FnCallHashes::from_native(*hash_get);
|
let hash = crate::ast::FnCallHashes::from_native(*hash_get);
|
||||||
let args = &mut [target.as_mut()];
|
let args = &mut [target.as_mut()];
|
||||||
let (mut orig_val, _) = self
|
let (mut orig_val, ..) = self
|
||||||
.exec_fn_call(
|
.exec_fn_call(
|
||||||
None, global, state, lib, getter, hash, args, is_ref_mut, true,
|
None, global, state, lib, getter, hash, args, is_ref_mut, true,
|
||||||
*pos, level,
|
*pos, level,
|
||||||
)
|
)
|
||||||
.or_else(|err| match *err {
|
.or_else(|err| match *err {
|
||||||
// Try an indexer if property does not exist
|
// Try an indexer if property does not exist
|
||||||
ERR::ErrorDotExpr(_, _) => {
|
ERR::ErrorDotExpr(..) => {
|
||||||
let prop = name.into();
|
let prop = name.into();
|
||||||
self.get_indexed_mut(
|
self.get_indexed_mut(
|
||||||
global, state, lib, target, prop, *pos, false, true,
|
global, state, lib, target, prop, *pos, false, true,
|
||||||
@ -349,7 +347,7 @@ impl Engine {
|
|||||||
.map(|v| (v.take_or_clone(), false))
|
.map(|v| (v.take_or_clone(), false))
|
||||||
.map_err(
|
.map_err(
|
||||||
|idx_err| match *idx_err {
|
|idx_err| match *idx_err {
|
||||||
ERR::ErrorIndexingType(_, _) => err,
|
ERR::ErrorIndexingType(..) => err,
|
||||||
_ => idx_err,
|
_ => idx_err,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
@ -381,7 +379,7 @@ impl Engine {
|
|||||||
)
|
)
|
||||||
.or_else(|err| match *err {
|
.or_else(|err| match *err {
|
||||||
// Try an indexer if property does not exist
|
// Try an indexer if property does not exist
|
||||||
ERR::ErrorDotExpr(_, _) => {
|
ERR::ErrorDotExpr(..) => {
|
||||||
let args = &mut [target, &mut name.into(), &mut new_val];
|
let args = &mut [target, &mut name.into(), &mut new_val];
|
||||||
let fn_name = crate::engine::FN_IDX_SET;
|
let fn_name = crate::engine::FN_IDX_SET;
|
||||||
let hash_set =
|
let hash_set =
|
||||||
@ -394,7 +392,7 @@ impl Engine {
|
|||||||
)
|
)
|
||||||
.map_err(
|
.map_err(
|
||||||
|idx_err| match *idx_err {
|
|idx_err| match *idx_err {
|
||||||
ERR::ErrorIndexingType(_, _) => err,
|
ERR::ErrorIndexingType(..) => err,
|
||||||
_ => idx_err,
|
_ => idx_err,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
@ -417,7 +415,7 @@ impl Engine {
|
|||||||
.map_or_else(
|
.map_or_else(
|
||||||
|err| match *err {
|
|err| match *err {
|
||||||
// Try an indexer if property does not exist
|
// Try an indexer if property does not exist
|
||||||
ERR::ErrorDotExpr(_, _) => {
|
ERR::ErrorDotExpr(..) => {
|
||||||
let prop = name.into();
|
let prop = name.into();
|
||||||
self.get_indexed_mut(
|
self.get_indexed_mut(
|
||||||
global, state, lib, target, prop, *pos, false, true, level,
|
global, state, lib, target, prop, *pos, false, true, level,
|
||||||
@ -425,7 +423,7 @@ impl Engine {
|
|||||||
.map(|v| (v.take_or_clone(), false))
|
.map(|v| (v.take_or_clone(), false))
|
||||||
.map_err(|idx_err| {
|
.map_err(|idx_err| {
|
||||||
match *idx_err {
|
match *idx_err {
|
||||||
ERR::ErrorIndexingType(_, _) => err,
|
ERR::ErrorIndexingType(..) => err,
|
||||||
_ => idx_err,
|
_ => idx_err,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -433,7 +431,7 @@ impl Engine {
|
|||||||
_ => Err(err),
|
_ => Err(err),
|
||||||
},
|
},
|
||||||
// Assume getters are always pure
|
// Assume getters are always pure
|
||||||
|(v, _)| Ok((v, false)),
|
|(v, ..)| Ok((v, false)),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
// {xxx:map}.sub_lhs[expr] | {xxx:map}.sub_lhs.expr
|
// {xxx:map}.sub_lhs[expr] | {xxx:map}.sub_lhs.expr
|
||||||
@ -475,7 +473,7 @@ impl Engine {
|
|||||||
result?.0.into()
|
result?.0.into()
|
||||||
}
|
}
|
||||||
// {xxx:map}.module::fn_name(...) - syntax error
|
// {xxx:map}.module::fn_name(...) - syntax error
|
||||||
Expr::FnCall(_, _) => unreachable!(
|
Expr::FnCall(..) => unreachable!(
|
||||||
"function call in dot chain should not be namespace-qualified"
|
"function call in dot chain should not be namespace-qualified"
|
||||||
),
|
),
|
||||||
// Others - syntax error
|
// Others - syntax error
|
||||||
@ -509,14 +507,14 @@ impl Engine {
|
|||||||
let args = &mut arg_values[..1];
|
let args = &mut arg_values[..1];
|
||||||
|
|
||||||
// Assume getters are always pure
|
// Assume getters are always pure
|
||||||
let (mut val, _) = self
|
let (mut val, ..) = self
|
||||||
.exec_fn_call(
|
.exec_fn_call(
|
||||||
None, global, state, lib, getter, hash_get, args,
|
None, global, state, lib, getter, hash_get, args,
|
||||||
is_ref_mut, true, pos, level,
|
is_ref_mut, true, pos, level,
|
||||||
)
|
)
|
||||||
.or_else(|err| match *err {
|
.or_else(|err| match *err {
|
||||||
// Try an indexer if property does not exist
|
// Try an indexer if property does not exist
|
||||||
ERR::ErrorDotExpr(_, _) => {
|
ERR::ErrorDotExpr(..) => {
|
||||||
let prop = name.into();
|
let prop = name.into();
|
||||||
self.get_indexed_mut(
|
self.get_indexed_mut(
|
||||||
global, state, lib, target, prop, pos, false, true,
|
global, state, lib, target, prop, pos, false, true,
|
||||||
@ -525,7 +523,7 @@ impl Engine {
|
|||||||
.map(|v| (v.take_or_clone(), false))
|
.map(|v| (v.take_or_clone(), false))
|
||||||
.map_err(
|
.map_err(
|
||||||
|idx_err| match *idx_err {
|
|idx_err| match *idx_err {
|
||||||
ERR::ErrorIndexingType(_, _) => err,
|
ERR::ErrorIndexingType(..) => err,
|
||||||
_ => idx_err,
|
_ => idx_err,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
@ -565,7 +563,7 @@ impl Engine {
|
|||||||
.or_else(
|
.or_else(
|
||||||
|err| match *err {
|
|err| match *err {
|
||||||
// Try an indexer if property does not exist
|
// Try an indexer if property does not exist
|
||||||
ERR::ErrorDotExpr(_, _) => {
|
ERR::ErrorDotExpr(..) => {
|
||||||
let args =
|
let args =
|
||||||
&mut [target.as_mut(), &mut name.into(), val];
|
&mut [target.as_mut(), &mut name.into(), val];
|
||||||
let fn_name = crate::engine::FN_IDX_SET;
|
let fn_name = crate::engine::FN_IDX_SET;
|
||||||
@ -578,7 +576,7 @@ impl Engine {
|
|||||||
args, is_ref_mut, true, pos, level,
|
args, is_ref_mut, true, pos, level,
|
||||||
)
|
)
|
||||||
.or_else(|idx_err| match *idx_err {
|
.or_else(|idx_err| match *idx_err {
|
||||||
ERR::ErrorIndexingType(_, _) => {
|
ERR::ErrorIndexingType(..) => {
|
||||||
// If there is no setter, no need to feed it back because
|
// If there is no setter, no need to feed it back because
|
||||||
// the property is read-only
|
// the property is read-only
|
||||||
Ok((Dynamic::UNIT, false))
|
Ok((Dynamic::UNIT, false))
|
||||||
@ -621,7 +619,7 @@ impl Engine {
|
|||||||
.map_err(|err| err.fill_position(pos))
|
.map_err(|err| err.fill_position(pos))
|
||||||
}
|
}
|
||||||
// xxx.module::fn_name(...) - syntax error
|
// xxx.module::fn_name(...) - syntax error
|
||||||
Expr::FnCall(_, _) => unreachable!(
|
Expr::FnCall(..) => unreachable!(
|
||||||
"function call in dot chain should not be namespace-qualified"
|
"function call in dot chain should not be namespace-qualified"
|
||||||
),
|
),
|
||||||
// Others - syntax error
|
// Others - syntax error
|
||||||
@ -665,14 +663,14 @@ impl Engine {
|
|||||||
|
|
||||||
match lhs {
|
match lhs {
|
||||||
// id.??? or id[???]
|
// id.??? or id[???]
|
||||||
Expr::Variable(_, var_pos, x) => {
|
Expr::Variable(.., var_pos, x) => {
|
||||||
#[cfg(feature = "debugging")]
|
#[cfg(feature = "debugging")]
|
||||||
self.run_debugger(scope, global, state, lib, this_ptr, lhs, level)?;
|
self.run_debugger(scope, global, state, lib, this_ptr, lhs, level)?;
|
||||||
|
|
||||||
#[cfg(not(feature = "unchecked"))]
|
#[cfg(not(feature = "unchecked"))]
|
||||||
self.inc_operations(&mut global.num_operations, *var_pos)?;
|
self.inc_operations(&mut global.num_operations, *var_pos)?;
|
||||||
|
|
||||||
let (mut target, _) =
|
let (mut target, ..) =
|
||||||
self.search_namespace(scope, global, state, lib, this_ptr, lhs, level)?;
|
self.search_namespace(scope, global, state, lib, this_ptr, lhs, level)?;
|
||||||
|
|
||||||
let obj_ptr = &mut target;
|
let obj_ptr = &mut target;
|
||||||
@ -682,7 +680,7 @@ impl Engine {
|
|||||||
global, state, lib, &mut None, obj_ptr, root, expr, rhs, term, idx_values,
|
global, state, lib, &mut None, obj_ptr, root, expr, rhs, term, idx_values,
|
||||||
chain_type, level, new_val,
|
chain_type, level, new_val,
|
||||||
)
|
)
|
||||||
.map(|(v, _)| v)
|
.map(|(v, ..)| v)
|
||||||
.map_err(|err| err.fill_position(op_pos))
|
.map_err(|err| err.fill_position(op_pos))
|
||||||
}
|
}
|
||||||
// {expr}.??? = ??? or {expr}[???] = ???
|
// {expr}.??? = ??? or {expr}[???] = ???
|
||||||
@ -696,7 +694,7 @@ impl Engine {
|
|||||||
global, state, lib, this_ptr, obj_ptr, root, expr, rhs, term, idx_values,
|
global, state, lib, this_ptr, obj_ptr, root, expr, rhs, term, idx_values,
|
||||||
chain_type, level, new_val,
|
chain_type, level, new_val,
|
||||||
)
|
)
|
||||||
.map(|(v, _)| if is_assignment { Dynamic::UNIT } else { v })
|
.map(|(v, ..)| if is_assignment { Dynamic::UNIT } else { v })
|
||||||
.map_err(|err| err.fill_position(op_pos))
|
.map_err(|err| err.fill_position(op_pos))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -726,7 +724,7 @@ impl Engine {
|
|||||||
|
|
||||||
match expr {
|
match expr {
|
||||||
#[cfg(not(feature = "no_object"))]
|
#[cfg(not(feature = "no_object"))]
|
||||||
Expr::FnCall(x, _) if _parent_chain_type == ChainType::Dotting && !x.is_qualified() => {
|
Expr::FnCall(x, ..) if _parent_chain_type == ChainType::Dotting && !x.is_qualified() => {
|
||||||
let crate::ast::FnCallExpr {
|
let crate::ast::FnCallExpr {
|
||||||
args, constants, ..
|
args, constants, ..
|
||||||
} = x.as_ref();
|
} = x.as_ref();
|
||||||
@ -748,29 +746,29 @@ impl Engine {
|
|||||||
idx_values.push(super::ChainArgument::from_fn_call_args(values, pos));
|
idx_values.push(super::ChainArgument::from_fn_call_args(values, pos));
|
||||||
}
|
}
|
||||||
#[cfg(not(feature = "no_object"))]
|
#[cfg(not(feature = "no_object"))]
|
||||||
Expr::FnCall(_, _) if _parent_chain_type == ChainType::Dotting => {
|
Expr::FnCall(..) if _parent_chain_type == ChainType::Dotting => {
|
||||||
unreachable!("function call in dot chain should not be namespace-qualified")
|
unreachable!("function call in dot chain should not be namespace-qualified")
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(feature = "no_object"))]
|
#[cfg(not(feature = "no_object"))]
|
||||||
Expr::Property(_, pos) if _parent_chain_type == ChainType::Dotting => {
|
Expr::Property(.., pos) if _parent_chain_type == ChainType::Dotting => {
|
||||||
idx_values.push(super::ChainArgument::Property(*pos))
|
idx_values.push(super::ChainArgument::Property(*pos))
|
||||||
}
|
}
|
||||||
Expr::Property(_, _) => unreachable!("unexpected Expr::Property for indexing"),
|
Expr::Property(..) => unreachable!("unexpected Expr::Property for indexing"),
|
||||||
|
|
||||||
Expr::Index(x, term, _) | Expr::Dot(x, term, _) if !terminate_chaining => {
|
Expr::Index(x, term, ..) | Expr::Dot(x, term, ..) if !terminate_chaining => {
|
||||||
let crate::ast::BinaryExpr { lhs, rhs, .. } = x.as_ref();
|
let crate::ast::BinaryExpr { lhs, rhs, .. } = x.as_ref();
|
||||||
|
|
||||||
// Evaluate in left-to-right order
|
// Evaluate in left-to-right order
|
||||||
let lhs_arg_val = match lhs {
|
let lhs_arg_val = match lhs {
|
||||||
#[cfg(not(feature = "no_object"))]
|
#[cfg(not(feature = "no_object"))]
|
||||||
Expr::Property(_, pos) if _parent_chain_type == ChainType::Dotting => {
|
Expr::Property(.., pos) if _parent_chain_type == ChainType::Dotting => {
|
||||||
super::ChainArgument::Property(*pos)
|
super::ChainArgument::Property(*pos)
|
||||||
}
|
}
|
||||||
Expr::Property(_, _) => unreachable!("unexpected Expr::Property for indexing"),
|
Expr::Property(..) => unreachable!("unexpected Expr::Property for indexing"),
|
||||||
|
|
||||||
#[cfg(not(feature = "no_object"))]
|
#[cfg(not(feature = "no_object"))]
|
||||||
Expr::FnCall(x, _)
|
Expr::FnCall(x, ..)
|
||||||
if _parent_chain_type == ChainType::Dotting && !x.is_qualified() =>
|
if _parent_chain_type == ChainType::Dotting && !x.is_qualified() =>
|
||||||
{
|
{
|
||||||
let crate::ast::FnCallExpr {
|
let crate::ast::FnCallExpr {
|
||||||
@ -793,7 +791,7 @@ impl Engine {
|
|||||||
super::ChainArgument::from_fn_call_args(values, pos)
|
super::ChainArgument::from_fn_call_args(values, pos)
|
||||||
}
|
}
|
||||||
#[cfg(not(feature = "no_object"))]
|
#[cfg(not(feature = "no_object"))]
|
||||||
Expr::FnCall(_, _) if _parent_chain_type == ChainType::Dotting => {
|
Expr::FnCall(..) if _parent_chain_type == ChainType::Dotting => {
|
||||||
unreachable!("function call in dot chain should not be namespace-qualified")
|
unreachable!("function call in dot chain should not be namespace-qualified")
|
||||||
}
|
}
|
||||||
#[cfg(not(feature = "no_object"))]
|
#[cfg(not(feature = "no_object"))]
|
||||||
@ -862,7 +860,7 @@ impl Engine {
|
|||||||
|
|
||||||
match target {
|
match target {
|
||||||
#[cfg(not(feature = "no_index"))]
|
#[cfg(not(feature = "no_index"))]
|
||||||
Dynamic(Union::Array(arr, _, _)) => {
|
Dynamic(Union::Array(arr, ..)) => {
|
||||||
// val_array[idx]
|
// val_array[idx]
|
||||||
let index = idx
|
let index = idx
|
||||||
.as_int()
|
.as_int()
|
||||||
@ -876,7 +874,7 @@ impl Engine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(feature = "no_index"))]
|
#[cfg(not(feature = "no_index"))]
|
||||||
Dynamic(Union::Blob(arr, _, _)) => {
|
Dynamic(Union::Blob(arr, ..)) => {
|
||||||
// val_blob[idx]
|
// val_blob[idx]
|
||||||
let index = idx
|
let index = idx
|
||||||
.as_int()
|
.as_int()
|
||||||
@ -896,7 +894,7 @@ impl Engine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(feature = "no_object"))]
|
#[cfg(not(feature = "no_object"))]
|
||||||
Dynamic(Union::Map(map, _, _)) => {
|
Dynamic(Union::Map(map, ..)) => {
|
||||||
// val_map[idx]
|
// val_map[idx]
|
||||||
let index = idx.read_lock::<crate::ImmutableString>().ok_or_else(|| {
|
let index = idx.read_lock::<crate::ImmutableString>().ok_or_else(|| {
|
||||||
self.make_type_mismatch_err::<crate::ImmutableString>(idx.type_name(), pos)
|
self.make_type_mismatch_err::<crate::ImmutableString>(idx.type_name(), pos)
|
||||||
@ -913,7 +911,7 @@ impl Engine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(feature = "no_index"))]
|
#[cfg(not(feature = "no_index"))]
|
||||||
Dynamic(Union::Int(value, _, _))
|
Dynamic(Union::Int(value, ..))
|
||||||
if idx.is::<crate::ExclusiveRange>() || idx.is::<crate::InclusiveRange>() =>
|
if idx.is::<crate::ExclusiveRange>() || idx.is::<crate::InclusiveRange>() =>
|
||||||
{
|
{
|
||||||
// val_int[range]
|
// val_int[range]
|
||||||
@ -984,7 +982,7 @@ impl Engine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(feature = "no_index"))]
|
#[cfg(not(feature = "no_index"))]
|
||||||
Dynamic(Union::Int(value, _, _)) => {
|
Dynamic(Union::Int(value, ..)) => {
|
||||||
// val_int[idx]
|
// val_int[idx]
|
||||||
let index = idx
|
let index = idx
|
||||||
.as_int()
|
.as_int()
|
||||||
@ -1006,7 +1004,7 @@ impl Engine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(feature = "no_index"))]
|
#[cfg(not(feature = "no_index"))]
|
||||||
Dynamic(Union::Str(s, _, _)) => {
|
Dynamic(Union::Str(s, ..)) => {
|
||||||
// val_string[idx]
|
// val_string[idx]
|
||||||
let index = idx
|
let index = idx
|
||||||
.as_int()
|
.as_int()
|
||||||
@ -1052,7 +1050,7 @@ impl Engine {
|
|||||||
self.exec_fn_call(
|
self.exec_fn_call(
|
||||||
None, global, state, lib, fn_name, hash_get, args, true, true, pos, level,
|
None, global, state, lib, fn_name, hash_get, args, true, true, pos, level,
|
||||||
)
|
)
|
||||||
.map(|(v, _)| v.into())
|
.map(|(v, ..)| v.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
_ => Err(ERR::ErrorIndexingType(
|
_ => Err(ERR::ErrorIndexingType(
|
||||||
|
@ -21,51 +21,51 @@ impl Engine {
|
|||||||
|
|
||||||
match value.0 {
|
match value.0 {
|
||||||
#[cfg(not(feature = "no_index"))]
|
#[cfg(not(feature = "no_index"))]
|
||||||
Union::Array(ref arr, _, _) => {
|
Union::Array(ref arr, ..) => {
|
||||||
arr.iter()
|
arr.iter()
|
||||||
.fold((0, 0, 0), |(arrays, maps, strings), value| match value.0 {
|
.fold((0, 0, 0), |(arrays, maps, strings), value| match value.0 {
|
||||||
Union::Array(_, _, _) => {
|
Union::Array(..) => {
|
||||||
let (a, m, s) = Self::calc_data_sizes(value, false);
|
let (a, m, s) = Self::calc_data_sizes(value, false);
|
||||||
(arrays + a + 1, maps + m, strings + s)
|
(arrays + a + 1, maps + m, strings + s)
|
||||||
}
|
}
|
||||||
Union::Blob(ref a, _, _) => (arrays + 1 + a.len(), maps, strings),
|
Union::Blob(ref a, ..) => (arrays + 1 + a.len(), maps, strings),
|
||||||
#[cfg(not(feature = "no_object"))]
|
#[cfg(not(feature = "no_object"))]
|
||||||
Union::Map(_, _, _) => {
|
Union::Map(..) => {
|
||||||
let (a, m, s) = Self::calc_data_sizes(value, false);
|
let (a, m, s) = Self::calc_data_sizes(value, false);
|
||||||
(arrays + a + 1, maps + m, strings + s)
|
(arrays + a + 1, maps + m, strings + s)
|
||||||
}
|
}
|
||||||
Union::Str(ref s, _, _) => (arrays + 1, maps, strings + s.len()),
|
Union::Str(ref s, ..) => (arrays + 1, maps, strings + s.len()),
|
||||||
_ => (arrays + 1, maps, strings),
|
_ => (arrays + 1, maps, strings),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
#[cfg(not(feature = "no_index"))]
|
#[cfg(not(feature = "no_index"))]
|
||||||
Union::Blob(ref arr, _, _) => (arr.len(), 0, 0),
|
Union::Blob(ref arr, ..) => (arr.len(), 0, 0),
|
||||||
#[cfg(not(feature = "no_object"))]
|
#[cfg(not(feature = "no_object"))]
|
||||||
Union::Map(ref map, _, _) => {
|
Union::Map(ref map, ..) => {
|
||||||
map.values()
|
map.values()
|
||||||
.fold((0, 0, 0), |(arrays, maps, strings), value| match value.0 {
|
.fold((0, 0, 0), |(arrays, maps, strings), value| match value.0 {
|
||||||
#[cfg(not(feature = "no_index"))]
|
#[cfg(not(feature = "no_index"))]
|
||||||
Union::Array(_, _, _) => {
|
Union::Array(..) => {
|
||||||
let (a, m, s) = Self::calc_data_sizes(value, false);
|
let (a, m, s) = Self::calc_data_sizes(value, false);
|
||||||
(arrays + a, maps + m + 1, strings + s)
|
(arrays + a, maps + m + 1, strings + s)
|
||||||
}
|
}
|
||||||
#[cfg(not(feature = "no_index"))]
|
#[cfg(not(feature = "no_index"))]
|
||||||
Union::Blob(ref a, _, _) => (arrays + a.len(), maps, strings),
|
Union::Blob(ref a, ..) => (arrays + a.len(), maps, strings),
|
||||||
Union::Map(_, _, _) => {
|
Union::Map(..) => {
|
||||||
let (a, m, s) = Self::calc_data_sizes(value, false);
|
let (a, m, s) = Self::calc_data_sizes(value, false);
|
||||||
(arrays + a, maps + m + 1, strings + s)
|
(arrays + a, maps + m + 1, strings + s)
|
||||||
}
|
}
|
||||||
Union::Str(ref s, _, _) => (arrays, maps + 1, strings + s.len()),
|
Union::Str(ref s, ..) => (arrays, maps + 1, strings + s.len()),
|
||||||
_ => (arrays, maps + 1, strings),
|
_ => (arrays, maps + 1, strings),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
Union::Str(ref s, _, _) => (0, 0, s.len()),
|
Union::Str(ref s, ..) => (0, 0, s.len()),
|
||||||
#[cfg(not(feature = "no_closure"))]
|
#[cfg(not(feature = "no_closure"))]
|
||||||
Union::Shared(_, _, _) if _top => {
|
Union::Shared(..) if _top => {
|
||||||
Self::calc_data_sizes(&*value.read_lock::<Dynamic>().unwrap(), true)
|
Self::calc_data_sizes(&*value.read_lock::<Dynamic>().unwrap(), true)
|
||||||
}
|
}
|
||||||
#[cfg(not(feature = "no_closure"))]
|
#[cfg(not(feature = "no_closure"))]
|
||||||
Union::Shared(_, _, _) => {
|
Union::Shared(..) => {
|
||||||
unreachable!("shared values discovered within data: {}", value)
|
unreachable!("shared values discovered within data: {}", value)
|
||||||
}
|
}
|
||||||
_ => (0, 0, 0),
|
_ => (0, 0, 0),
|
||||||
|
@ -271,7 +271,7 @@ impl Debugger {
|
|||||||
} else {
|
} else {
|
||||||
DebuggerStatus::CONTINUE
|
DebuggerStatus::CONTINUE
|
||||||
},
|
},
|
||||||
state: if let Some((ref init, _)) = engine.debugger {
|
state: if let Some((ref init, ..)) = engine.debugger {
|
||||||
init()
|
init()
|
||||||
} else {
|
} else {
|
||||||
Dynamic::UNIT
|
Dynamic::UNIT
|
||||||
@ -348,8 +348,8 @@ impl Debugger {
|
|||||||
self.break_points()
|
self.break_points()
|
||||||
.iter()
|
.iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.filter(|&(_, bp)| bp.is_enabled())
|
.filter(|&(.., bp)| bp.is_enabled())
|
||||||
.find(|&(_, bp)| match bp {
|
.find(|&(.., bp)| match bp {
|
||||||
#[cfg(not(feature = "no_position"))]
|
#[cfg(not(feature = "no_position"))]
|
||||||
BreakPoint::AtPosition { pos, .. } if pos.is_none() => false,
|
BreakPoint::AtPosition { pos, .. } if pos.is_none() => false,
|
||||||
#[cfg(not(feature = "no_position"))]
|
#[cfg(not(feature = "no_position"))]
|
||||||
@ -361,26 +361,26 @@ impl Debugger {
|
|||||||
node.position() == *pos && _src == source
|
node.position() == *pos && _src == source
|
||||||
}
|
}
|
||||||
BreakPoint::AtFunctionName { name, .. } => match node {
|
BreakPoint::AtFunctionName { name, .. } => match node {
|
||||||
ASTNode::Expr(Expr::FnCall(x, _))
|
ASTNode::Expr(Expr::FnCall(x, ..))
|
||||||
| ASTNode::Stmt(Stmt::FnCall(x, _))
|
| ASTNode::Stmt(Stmt::FnCall(x, ..))
|
||||||
| ASTNode::Stmt(Stmt::Expr(Expr::FnCall(x, _))) => x.name == *name,
|
| ASTNode::Stmt(Stmt::Expr(Expr::FnCall(x, ..))) => x.name == *name,
|
||||||
_ => false,
|
_ => false,
|
||||||
},
|
},
|
||||||
BreakPoint::AtFunctionCall { name, args, .. } => match node {
|
BreakPoint::AtFunctionCall { name, args, .. } => match node {
|
||||||
ASTNode::Expr(Expr::FnCall(x, _))
|
ASTNode::Expr(Expr::FnCall(x, ..))
|
||||||
| ASTNode::Stmt(Stmt::FnCall(x, _))
|
| ASTNode::Stmt(Stmt::FnCall(x, ..))
|
||||||
| ASTNode::Stmt(Stmt::Expr(Expr::FnCall(x, _))) => {
|
| ASTNode::Stmt(Stmt::Expr(Expr::FnCall(x, ..))) => {
|
||||||
x.args.len() == *args && x.name == *name
|
x.args.len() == *args && x.name == *name
|
||||||
}
|
}
|
||||||
_ => false,
|
_ => false,
|
||||||
},
|
},
|
||||||
#[cfg(not(feature = "no_object"))]
|
#[cfg(not(feature = "no_object"))]
|
||||||
BreakPoint::AtProperty { name, .. } => match node {
|
BreakPoint::AtProperty { name, .. } => match node {
|
||||||
ASTNode::Expr(Expr::Property(x, _)) => x.2 == *name,
|
ASTNode::Expr(Expr::Property(x, ..)) => x.2 == *name,
|
||||||
_ => false,
|
_ => false,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
.map(|(i, _)| i)
|
.map(|(i, ..)| i)
|
||||||
}
|
}
|
||||||
/// Get a slice of all [`BreakPoint`]'s.
|
/// Get a slice of all [`BreakPoint`]'s.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
@ -525,7 +525,7 @@ impl Engine {
|
|||||||
level,
|
level,
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some((_, ref on_debugger)) = self.debugger {
|
if let Some((.., ref on_debugger)) = self.debugger {
|
||||||
let command = on_debugger(&mut context, event, node, source, node.position())?;
|
let command = on_debugger(&mut context, event, node, source, node.position())?;
|
||||||
|
|
||||||
match command {
|
match command {
|
||||||
@ -548,9 +548,9 @@ impl Engine {
|
|||||||
DebuggerCommand::FunctionExit => {
|
DebuggerCommand::FunctionExit => {
|
||||||
// Bump a level if it is a function call
|
// Bump a level if it is a function call
|
||||||
let level = match node {
|
let level = match node {
|
||||||
ASTNode::Expr(Expr::FnCall(_, _))
|
ASTNode::Expr(Expr::FnCall(..))
|
||||||
| ASTNode::Stmt(Stmt::FnCall(_, _))
|
| ASTNode::Stmt(Stmt::FnCall(..))
|
||||||
| ASTNode::Stmt(Stmt::Expr(Expr::FnCall(_, _))) => context.call_level() + 1,
|
| ASTNode::Stmt(Stmt::Expr(Expr::FnCall(..))) => context.call_level() + 1,
|
||||||
_ => context.call_level(),
|
_ => context.call_level(),
|
||||||
};
|
};
|
||||||
global.debugger.status = DebuggerStatus::FunctionExit(level);
|
global.debugger.status = DebuggerStatus::FunctionExit(level);
|
||||||
|
@ -53,7 +53,7 @@ impl Engine {
|
|||||||
level: usize,
|
level: usize,
|
||||||
) -> RhaiResultOf<(Target<'s>, Position)> {
|
) -> RhaiResultOf<(Target<'s>, Position)> {
|
||||||
match expr {
|
match expr {
|
||||||
Expr::Variable(Some(_), _, _) => {
|
Expr::Variable(Some(_), ..) => {
|
||||||
self.search_scope_only(scope, global, state, lib, this_ptr, expr, level)
|
self.search_scope_only(scope, global, state, lib, this_ptr, expr, level)
|
||||||
}
|
}
|
||||||
Expr::Variable(None, _var_pos, v) => match v.as_ref() {
|
Expr::Variable(None, _var_pos, v) => match v.as_ref() {
|
||||||
@ -80,7 +80,7 @@ impl Engine {
|
|||||||
Ok((target.into(), *_var_pos))
|
Ok((target.into(), *_var_pos))
|
||||||
}
|
}
|
||||||
Err(err) => Err(match *err {
|
Err(err) => Err(match *err {
|
||||||
ERR::ErrorVariableNotFound(_, _) => ERR::ErrorVariableNotFound(
|
ERR::ErrorVariableNotFound(..) => ERR::ErrorVariableNotFound(
|
||||||
format!(
|
format!(
|
||||||
"{}{}{}",
|
"{}{}{}",
|
||||||
namespace,
|
namespace,
|
||||||
@ -155,7 +155,7 @@ impl Engine {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ if state.always_search_scope => (0, expr.start_position()),
|
_ if state.always_search_scope => (0, expr.start_position()),
|
||||||
Expr::Variable(Some(i), pos, _) => (i.get() as usize, *pos),
|
Expr::Variable(Some(i), pos, ..) => (i.get() as usize, *pos),
|
||||||
Expr::Variable(None, pos, v) => (v.0.map(NonZeroUsize::get).unwrap_or(0), *pos),
|
Expr::Variable(None, pos, v) => (v.0.map(NonZeroUsize::get).unwrap_or(0), *pos),
|
||||||
_ => unreachable!("Expr::Variable expected but gets {:?}", expr),
|
_ => unreachable!("Expr::Variable expected but gets {:?}", expr),
|
||||||
};
|
};
|
||||||
@ -270,7 +270,7 @@ impl Engine {
|
|||||||
|
|
||||||
// Function calls should account for a relatively larger portion of expressions because
|
// Function calls should account for a relatively larger portion of expressions because
|
||||||
// binary operators are also function calls.
|
// binary operators are also function calls.
|
||||||
if let Expr::FnCall(x, _) = expr {
|
if let Expr::FnCall(x, ..) = expr {
|
||||||
#[cfg(feature = "debugging")]
|
#[cfg(feature = "debugging")]
|
||||||
let reset_debugger =
|
let reset_debugger =
|
||||||
self.run_debugger_with_reset(scope, global, state, lib, this_ptr, expr, level)?;
|
self.run_debugger_with_reset(scope, global, state, lib, this_ptr, expr, level)?;
|
||||||
@ -304,7 +304,7 @@ impl Engine {
|
|||||||
.ok_or_else(|| ERR::ErrorUnboundThis(*var_pos).into())
|
.ok_or_else(|| ERR::ErrorUnboundThis(*var_pos).into())
|
||||||
} else {
|
} else {
|
||||||
self.search_namespace(scope, global, state, lib, this_ptr, expr, level)
|
self.search_namespace(scope, global, state, lib, this_ptr, expr, level)
|
||||||
.map(|(val, _)| val.take_or_clone())
|
.map(|(val, ..)| val.take_or_clone())
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -317,13 +317,13 @@ impl Engine {
|
|||||||
|
|
||||||
let result = match expr {
|
let result = match expr {
|
||||||
// Constants
|
// Constants
|
||||||
Expr::DynamicConstant(x, _) => Ok(x.as_ref().clone()),
|
Expr::DynamicConstant(x, ..) => Ok(x.as_ref().clone()),
|
||||||
Expr::IntegerConstant(x, _) => Ok((*x).into()),
|
Expr::IntegerConstant(x, ..) => Ok((*x).into()),
|
||||||
#[cfg(not(feature = "no_float"))]
|
#[cfg(not(feature = "no_float"))]
|
||||||
Expr::FloatConstant(x, _) => Ok((*x).into()),
|
Expr::FloatConstant(x, ..) => Ok((*x).into()),
|
||||||
Expr::StringConstant(x, _) => Ok(x.clone().into()),
|
Expr::StringConstant(x, ..) => Ok(x.clone().into()),
|
||||||
Expr::CharConstant(x, _) => Ok((*x).into()),
|
Expr::CharConstant(x, ..) => Ok((*x).into()),
|
||||||
Expr::BoolConstant(x, _) => Ok((*x).into()),
|
Expr::BoolConstant(x, ..) => Ok((*x).into()),
|
||||||
Expr::Unit(_) => Ok(Dynamic::UNIT),
|
Expr::Unit(_) => Ok(Dynamic::UNIT),
|
||||||
|
|
||||||
// `... ${...} ...`
|
// `... ${...} ...`
|
||||||
@ -364,7 +364,7 @@ impl Engine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(feature = "no_index"))]
|
#[cfg(not(feature = "no_index"))]
|
||||||
Expr::Array(x, _) => {
|
Expr::Array(x, ..) => {
|
||||||
let mut arr = crate::Array::with_capacity(x.len());
|
let mut arr = crate::Array::with_capacity(x.len());
|
||||||
let mut result = Ok(Dynamic::UNIT);
|
let mut result = Ok(Dynamic::UNIT);
|
||||||
|
|
||||||
@ -402,7 +402,7 @@ impl Engine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(feature = "no_object"))]
|
#[cfg(not(feature = "no_object"))]
|
||||||
Expr::Map(x, _) => {
|
Expr::Map(x, ..) => {
|
||||||
let mut map = x.1.clone();
|
let mut map = x.1.clone();
|
||||||
let mut result = Ok(Dynamic::UNIT);
|
let mut result = Ok(Dynamic::UNIT);
|
||||||
|
|
||||||
@ -440,7 +440,7 @@ impl Engine {
|
|||||||
result.map(|_| map.into())
|
result.map(|_| map.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
Expr::And(x, _) => {
|
Expr::And(x, ..) => {
|
||||||
let lhs = self
|
let lhs = self
|
||||||
.eval_expr(scope, global, state, lib, this_ptr, &x.lhs, level)
|
.eval_expr(scope, global, state, lib, this_ptr, &x.lhs, level)
|
||||||
.and_then(|v| {
|
.and_then(|v| {
|
||||||
@ -463,7 +463,7 @@ impl Engine {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Expr::Or(x, _) => {
|
Expr::Or(x, ..) => {
|
||||||
let lhs = self
|
let lhs = self
|
||||||
.eval_expr(scope, global, state, lib, this_ptr, &x.lhs, level)
|
.eval_expr(scope, global, state, lib, this_ptr, &x.lhs, level)
|
||||||
.and_then(|v| {
|
.and_then(|v| {
|
||||||
@ -519,12 +519,12 @@ impl Engine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(feature = "no_index"))]
|
#[cfg(not(feature = "no_index"))]
|
||||||
Expr::Index(_, _, _) => {
|
Expr::Index(..) => {
|
||||||
self.eval_dot_index_chain(scope, global, state, lib, this_ptr, expr, level, None)
|
self.eval_dot_index_chain(scope, global, state, lib, this_ptr, expr, level, None)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(feature = "no_object"))]
|
#[cfg(not(feature = "no_object"))]
|
||||||
Expr::Dot(_, _, _) => {
|
Expr::Dot(..) => {
|
||||||
self.eval_dot_index_chain(scope, global, state, lib, this_ptr, expr, level, None)
|
self.eval_dot_index_chain(scope, global, state, lib, this_ptr, expr, level, None)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,13 +67,13 @@ impl Engine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(feature = "no_module"))]
|
#[cfg(not(feature = "no_module"))]
|
||||||
if matches!(stmt, Stmt::Import(_, _, _)) {
|
if matches!(stmt, Stmt::Import(..)) {
|
||||||
// Get the extra modules - see if any functions are marked global.
|
// Get the extra modules - see if any functions are marked global.
|
||||||
// Without global functions, the extra modules never affect function resolution.
|
// Without global functions, the extra modules never affect function resolution.
|
||||||
if global
|
if global
|
||||||
.scan_imports_raw()
|
.scan_imports_raw()
|
||||||
.skip(imports_len)
|
.skip(imports_len)
|
||||||
.any(|(_, m)| m.contains_indexed_global_functions())
|
.any(|(.., m)| m.contains_indexed_global_functions())
|
||||||
{
|
{
|
||||||
if state.fn_resolution_caches_len() > orig_fn_resolution_caches_len {
|
if state.fn_resolution_caches_len() > orig_fn_resolution_caches_len {
|
||||||
// When new module is imported with global functions and there is already
|
// When new module is imported with global functions and there is already
|
||||||
@ -162,10 +162,10 @@ impl Engine {
|
|||||||
#[cfg(not(feature = "unchecked"))]
|
#[cfg(not(feature = "unchecked"))]
|
||||||
self.check_data_size(&args[0], root.1)?;
|
self.check_data_size(&args[0], root.1)?;
|
||||||
}
|
}
|
||||||
Err(err) if matches!(*err, ERR::ErrorFunctionNotFound(ref f, _) if f.starts_with(op_assign)) =>
|
Err(err) if matches!(*err, ERR::ErrorFunctionNotFound(ref f, ..) if f.starts_with(op_assign)) =>
|
||||||
{
|
{
|
||||||
// Expand to `var = var op rhs`
|
// Expand to `var = var op rhs`
|
||||||
let (value, _) = self.call_native_fn(
|
let (value, ..) = self.call_native_fn(
|
||||||
global, state, lib, op, hash_op, args, true, false, op_pos, level,
|
global, state, lib, op, hash_op, args, true, false, op_pos, level,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
@ -211,7 +211,7 @@ impl Engine {
|
|||||||
// Popular branches are lifted out of the `match` statement into their own branches.
|
// Popular branches are lifted out of the `match` statement into their own branches.
|
||||||
|
|
||||||
// Function calls should account for a relatively larger portion of statements.
|
// Function calls should account for a relatively larger portion of statements.
|
||||||
if let Stmt::FnCall(x, _) = stmt {
|
if let Stmt::FnCall(x, ..) = stmt {
|
||||||
#[cfg(not(feature = "unchecked"))]
|
#[cfg(not(feature = "unchecked"))]
|
||||||
self.inc_operations(&mut global.num_operations, stmt.position())?;
|
self.inc_operations(&mut global.num_operations, stmt.position())?;
|
||||||
|
|
||||||
@ -288,19 +288,19 @@ impl Engine {
|
|||||||
// Must be either `var[index] op= val` or `var.prop op= val`
|
// Must be either `var[index] op= val` or `var.prop op= val`
|
||||||
match lhs {
|
match lhs {
|
||||||
// name op= rhs (handled above)
|
// name op= rhs (handled above)
|
||||||
Expr::Variable(_, _, _) => {
|
Expr::Variable(..) => {
|
||||||
unreachable!("Expr::Variable case is already handled")
|
unreachable!("Expr::Variable case is already handled")
|
||||||
}
|
}
|
||||||
// idx_lhs[idx_expr] op= rhs
|
// idx_lhs[idx_expr] op= rhs
|
||||||
#[cfg(not(feature = "no_index"))]
|
#[cfg(not(feature = "no_index"))]
|
||||||
Expr::Index(_, _, _) => self
|
Expr::Index(..) => self
|
||||||
.eval_dot_index_chain(
|
.eval_dot_index_chain(
|
||||||
scope, global, state, lib, this_ptr, lhs, level, _new_val,
|
scope, global, state, lib, this_ptr, lhs, level, _new_val,
|
||||||
)
|
)
|
||||||
.map(|_| Dynamic::UNIT),
|
.map(|_| Dynamic::UNIT),
|
||||||
// dot_lhs.dot_rhs op= rhs
|
// dot_lhs.dot_rhs op= rhs
|
||||||
#[cfg(not(feature = "no_object"))]
|
#[cfg(not(feature = "no_object"))]
|
||||||
Expr::Dot(_, _, _) => self
|
Expr::Dot(..) => self
|
||||||
.eval_dot_index_chain(
|
.eval_dot_index_chain(
|
||||||
scope, global, state, lib, this_ptr, lhs, level, _new_val,
|
scope, global, state, lib, this_ptr, lhs, level, _new_val,
|
||||||
)
|
)
|
||||||
@ -331,13 +331,13 @@ impl Engine {
|
|||||||
.map(Dynamic::flatten),
|
.map(Dynamic::flatten),
|
||||||
|
|
||||||
// Block scope
|
// Block scope
|
||||||
Stmt::Block(statements, _) if statements.is_empty() => Ok(Dynamic::UNIT),
|
Stmt::Block(statements, ..) if statements.is_empty() => Ok(Dynamic::UNIT),
|
||||||
Stmt::Block(statements, _) => {
|
Stmt::Block(statements, ..) => {
|
||||||
self.eval_stmt_block(scope, global, state, lib, this_ptr, statements, true, level)
|
self.eval_stmt_block(scope, global, state, lib, this_ptr, statements, true, level)
|
||||||
}
|
}
|
||||||
|
|
||||||
// If statement
|
// If statement
|
||||||
Stmt::If(expr, x, _) => {
|
Stmt::If(expr, x, ..) => {
|
||||||
let guard_val = self
|
let guard_val = self
|
||||||
.eval_expr(scope, global, state, lib, this_ptr, expr, level)
|
.eval_expr(scope, global, state, lib, this_ptr, expr, level)
|
||||||
.and_then(|v| {
|
.and_then(|v| {
|
||||||
@ -370,7 +370,7 @@ impl Engine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Switch statement
|
// Switch statement
|
||||||
Stmt::Switch(match_expr, x, _) => {
|
Stmt::Switch(match_expr, x, ..) => {
|
||||||
let SwitchCases {
|
let SwitchCases {
|
||||||
cases,
|
cases,
|
||||||
def_case,
|
def_case,
|
||||||
@ -414,8 +414,8 @@ impl Engine {
|
|||||||
let value = value.as_int().expect("`INT`");
|
let value = value.as_int().expect("`INT`");
|
||||||
let mut result = Ok(None);
|
let mut result = Ok(None);
|
||||||
|
|
||||||
for (_, _, _, block) in
|
for (.., block) in
|
||||||
ranges.iter().filter(|&&(start, end, inclusive, _)| {
|
ranges.iter().filter(|&&(start, end, inclusive, ..)| {
|
||||||
(!inclusive && (start..end).contains(&value))
|
(!inclusive && (start..end).contains(&value))
|
||||||
|| (inclusive && (start..=end).contains(&value))
|
|| (inclusive && (start..=end).contains(&value))
|
||||||
})
|
})
|
||||||
@ -483,15 +483,15 @@ impl Engine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Loop
|
// Loop
|
||||||
Stmt::While(Expr::Unit(_), body, _) => loop {
|
Stmt::While(Expr::Unit(_), body, ..) => loop {
|
||||||
if !body.is_empty() {
|
if !body.is_empty() {
|
||||||
match self
|
match self
|
||||||
.eval_stmt_block(scope, global, state, lib, this_ptr, body, true, level)
|
.eval_stmt_block(scope, global, state, lib, this_ptr, body, true, level)
|
||||||
{
|
{
|
||||||
Ok(_) => (),
|
Ok(_) => (),
|
||||||
Err(err) => match *err {
|
Err(err) => match *err {
|
||||||
ERR::LoopBreak(false, _) => (),
|
ERR::LoopBreak(false, ..) => (),
|
||||||
ERR::LoopBreak(true, _) => break Ok(Dynamic::UNIT),
|
ERR::LoopBreak(true, ..) => break Ok(Dynamic::UNIT),
|
||||||
_ => break Err(err),
|
_ => break Err(err),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -502,7 +502,7 @@ impl Engine {
|
|||||||
},
|
},
|
||||||
|
|
||||||
// While loop
|
// While loop
|
||||||
Stmt::While(expr, body, _) => loop {
|
Stmt::While(expr, body, ..) => loop {
|
||||||
let condition = self
|
let condition = self
|
||||||
.eval_expr(scope, global, state, lib, this_ptr, expr, level)
|
.eval_expr(scope, global, state, lib, this_ptr, expr, level)
|
||||||
.and_then(|v| {
|
.and_then(|v| {
|
||||||
@ -520,8 +520,8 @@ impl Engine {
|
|||||||
{
|
{
|
||||||
Ok(_) => (),
|
Ok(_) => (),
|
||||||
Err(err) => match *err {
|
Err(err) => match *err {
|
||||||
ERR::LoopBreak(false, _) => (),
|
ERR::LoopBreak(false, ..) => (),
|
||||||
ERR::LoopBreak(true, _) => break Ok(Dynamic::UNIT),
|
ERR::LoopBreak(true, ..) => break Ok(Dynamic::UNIT),
|
||||||
_ => break Err(err),
|
_ => break Err(err),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -531,7 +531,7 @@ impl Engine {
|
|||||||
},
|
},
|
||||||
|
|
||||||
// Do loop
|
// Do loop
|
||||||
Stmt::Do(body, expr, options, _) => loop {
|
Stmt::Do(body, expr, options, ..) => loop {
|
||||||
let is_while = !options.contains(AST_OPTION_NEGATED);
|
let is_while = !options.contains(AST_OPTION_NEGATED);
|
||||||
|
|
||||||
if !body.is_empty() {
|
if !body.is_empty() {
|
||||||
@ -540,8 +540,8 @@ impl Engine {
|
|||||||
{
|
{
|
||||||
Ok(_) => (),
|
Ok(_) => (),
|
||||||
Err(err) => match *err {
|
Err(err) => match *err {
|
||||||
ERR::LoopBreak(false, _) => continue,
|
ERR::LoopBreak(false, ..) => continue,
|
||||||
ERR::LoopBreak(true, _) => break Ok(Dynamic::UNIT),
|
ERR::LoopBreak(true, ..) => break Ok(Dynamic::UNIT),
|
||||||
_ => break Err(err),
|
_ => break Err(err),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -563,7 +563,7 @@ impl Engine {
|
|||||||
},
|
},
|
||||||
|
|
||||||
// For loop
|
// For loop
|
||||||
Stmt::For(expr, x, _) => {
|
Stmt::For(expr, x, ..) => {
|
||||||
let (Ident { name: var_name, .. }, counter, statements) = x.as_ref();
|
let (Ident { name: var_name, .. }, counter, statements) = x.as_ref();
|
||||||
|
|
||||||
let iter_result = self
|
let iter_result = self
|
||||||
@ -672,8 +672,8 @@ impl Engine {
|
|||||||
match result {
|
match result {
|
||||||
Ok(_) => (),
|
Ok(_) => (),
|
||||||
Err(err) => match *err {
|
Err(err) => match *err {
|
||||||
ERR::LoopBreak(false, _) => (),
|
ERR::LoopBreak(false, ..) => (),
|
||||||
ERR::LoopBreak(true, _) => break,
|
ERR::LoopBreak(true, ..) => break,
|
||||||
_ => {
|
_ => {
|
||||||
loop_result = Err(err);
|
loop_result = Err(err);
|
||||||
break;
|
break;
|
||||||
@ -699,7 +699,7 @@ impl Engine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Try/Catch statement
|
// Try/Catch statement
|
||||||
Stmt::TryCatch(x, _) => {
|
Stmt::TryCatch(x, ..) => {
|
||||||
let TryCatchBlock {
|
let TryCatchBlock {
|
||||||
try_block,
|
try_block,
|
||||||
catch_var,
|
catch_var,
|
||||||
@ -716,7 +716,7 @@ impl Engine {
|
|||||||
Err(err) if !err.is_catchable() => Err(err),
|
Err(err) if !err.is_catchable() => Err(err),
|
||||||
Err(mut err) => {
|
Err(mut err) => {
|
||||||
let err_value = match *err {
|
let err_value = match *err {
|
||||||
ERR::ErrorRuntime(ref x, _) => x.clone(),
|
ERR::ErrorRuntime(ref x, ..) => x.clone(),
|
||||||
|
|
||||||
#[cfg(feature = "no_object")]
|
#[cfg(feature = "no_object")]
|
||||||
_ => {
|
_ => {
|
||||||
@ -773,7 +773,7 @@ impl Engine {
|
|||||||
Ok(_) => Ok(Dynamic::UNIT),
|
Ok(_) => Ok(Dynamic::UNIT),
|
||||||
Err(result_err) => match *result_err {
|
Err(result_err) => match *result_err {
|
||||||
// Re-throw exception
|
// Re-throw exception
|
||||||
ERR::ErrorRuntime(Dynamic(Union::Unit(_, _, _)), pos) => {
|
ERR::ErrorRuntime(Dynamic(Union::Unit(..)), pos) => {
|
||||||
err.set_position(pos);
|
err.set_position(pos);
|
||||||
Err(err)
|
Err(err)
|
||||||
}
|
}
|
||||||
@ -795,15 +795,15 @@ impl Engine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Return value
|
// Return value
|
||||||
Stmt::Return(_, Some(expr), pos) => self
|
Stmt::Return(.., Some(expr), pos) => self
|
||||||
.eval_expr(scope, global, state, lib, this_ptr, expr, level)
|
.eval_expr(scope, global, state, lib, this_ptr, expr, level)
|
||||||
.and_then(|v| Err(ERR::Return(v.flatten(), *pos).into())),
|
.and_then(|v| Err(ERR::Return(v.flatten(), *pos).into())),
|
||||||
|
|
||||||
// Empty return
|
// Empty return
|
||||||
Stmt::Return(_, None, pos) => Err(ERR::Return(Dynamic::UNIT, *pos).into()),
|
Stmt::Return(.., None, pos) => Err(ERR::Return(Dynamic::UNIT, *pos).into()),
|
||||||
|
|
||||||
// Let/const statement - shadowing disallowed
|
// Let/const statement - shadowing disallowed
|
||||||
Stmt::Var(_, x, _, pos) if !self.allow_shadowing() && scope.contains(&x.name) => {
|
Stmt::Var(.., x, _, pos) if !self.allow_shadowing() && scope.contains(&x.name) => {
|
||||||
Err(ERR::ErrorVariableExists(x.name.to_string(), *pos).into())
|
Err(ERR::ErrorVariableExists(x.name.to_string(), *pos).into())
|
||||||
}
|
}
|
||||||
// Let/const statement
|
// Let/const statement
|
||||||
@ -924,7 +924,7 @@ impl Engine {
|
|||||||
let module_result = resolver
|
let module_result = resolver
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.and_then(|r| match r.resolve_raw(self, global, &path, path_pos) {
|
.and_then(|r| match r.resolve_raw(self, global, &path, path_pos) {
|
||||||
Err(err) if matches!(*err, ERR::ErrorModuleNotFound(_, _)) => None,
|
Err(err) if matches!(*err, ERR::ErrorModuleNotFound(..)) => None,
|
||||||
result => Some(result),
|
result => Some(result),
|
||||||
})
|
})
|
||||||
.or_else(|| {
|
.or_else(|| {
|
||||||
@ -961,10 +961,10 @@ impl Engine {
|
|||||||
|
|
||||||
// Export statement
|
// Export statement
|
||||||
#[cfg(not(feature = "no_module"))]
|
#[cfg(not(feature = "no_module"))]
|
||||||
Stmt::Export(x, _) => {
|
Stmt::Export(x, ..) => {
|
||||||
let (Ident { name, pos, .. }, Ident { name: alias, .. }) = x.as_ref();
|
let (Ident { name, pos, .. }, Ident { name: alias, .. }) = x.as_ref();
|
||||||
// Mark scope variables as public
|
// Mark scope variables as public
|
||||||
if let Some((index, _)) = scope.get_index(name) {
|
if let Some((index, ..)) = scope.get_index(name) {
|
||||||
scope.add_entry_alias(
|
scope.add_entry_alias(
|
||||||
index,
|
index,
|
||||||
if alias.is_empty() { name } else { alias }.clone(),
|
if alias.is_empty() { name } else { alias }.clone(),
|
||||||
@ -978,7 +978,7 @@ impl Engine {
|
|||||||
// Share statement
|
// Share statement
|
||||||
#[cfg(not(feature = "no_closure"))]
|
#[cfg(not(feature = "no_closure"))]
|
||||||
Stmt::Share(name) => {
|
Stmt::Share(name) => {
|
||||||
if let Some((index, _)) = scope.get_index(name) {
|
if let Some((index, ..)) = scope.get_index(name) {
|
||||||
let val = scope.get_mut_by_index(index);
|
let val = scope.get_mut_by_index(index);
|
||||||
|
|
||||||
if !val.is_shared() {
|
if !val.is_shared() {
|
||||||
|
@ -109,11 +109,11 @@ pub fn ensure_no_data_race(
|
|||||||
args: &FnCallArgs,
|
args: &FnCallArgs,
|
||||||
is_method_call: bool,
|
is_method_call: bool,
|
||||||
) -> RhaiResultOf<()> {
|
) -> RhaiResultOf<()> {
|
||||||
if let Some((n, _)) = args
|
if let Some((n, ..)) = args
|
||||||
.iter()
|
.iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.skip(if is_method_call { 1 } else { 0 })
|
.skip(if is_method_call { 1 } else { 0 })
|
||||||
.find(|(_, a)| a.is_locked())
|
.find(|(.., a)| a.is_locked())
|
||||||
{
|
{
|
||||||
return Err(ERR::ErrorDataRace(
|
return Err(ERR::ErrorDataRace(
|
||||||
format!("argument #{} of function '{}'", n + 1, fn_name),
|
format!("argument #{} of function '{}'", n + 1, fn_name),
|
||||||
@ -392,7 +392,7 @@ impl Engine {
|
|||||||
|
|
||||||
let source = match (source.as_str(), parent_source.as_str()) {
|
let source = match (source.as_str(), parent_source.as_str()) {
|
||||||
("", "") => None,
|
("", "") => None,
|
||||||
("", s) | (s, _) => Some(s),
|
("", s) | (s, ..) => Some(s),
|
||||||
};
|
};
|
||||||
|
|
||||||
#[cfg(feature = "debugging")]
|
#[cfg(feature = "debugging")]
|
||||||
@ -430,7 +430,7 @@ impl Engine {
|
|||||||
{
|
{
|
||||||
let trigger = match global.debugger.status {
|
let trigger = match global.debugger.status {
|
||||||
crate::eval::DebuggerStatus::FunctionExit(n) => n >= level,
|
crate::eval::DebuggerStatus::FunctionExit(n) => n >= level,
|
||||||
crate::eval::DebuggerStatus::Next(_, true) => true,
|
crate::eval::DebuggerStatus::Next(.., true) => true,
|
||||||
_ => false,
|
_ => false,
|
||||||
};
|
};
|
||||||
if trigger {
|
if trigger {
|
||||||
@ -774,8 +774,8 @@ impl Engine {
|
|||||||
scope, global, state, lib, &mut None, statements, false, level,
|
scope, global, state, lib, &mut None, statements, false, level,
|
||||||
)
|
)
|
||||||
.or_else(|err| match *err {
|
.or_else(|err| match *err {
|
||||||
ERR::Return(out, _) => Ok(out),
|
ERR::Return(out, ..) => Ok(out),
|
||||||
ERR::LoopBreak(_, _) => {
|
ERR::LoopBreak(..) => {
|
||||||
unreachable!("no outer loop scope to break out of")
|
unreachable!("no outer loop scope to break out of")
|
||||||
}
|
}
|
||||||
_ => Err(err),
|
_ => Err(err),
|
||||||
@ -958,7 +958,7 @@ impl Engine {
|
|||||||
level: usize,
|
level: usize,
|
||||||
) -> RhaiResultOf<(Dynamic, Position)> {
|
) -> RhaiResultOf<(Dynamic, Position)> {
|
||||||
Ok((
|
Ok((
|
||||||
if let Expr::Stack(slot, _) = arg_expr {
|
if let Expr::Stack(slot, ..) = arg_expr {
|
||||||
#[cfg(feature = "debugging")]
|
#[cfg(feature = "debugging")]
|
||||||
self.run_debugger(scope, global, state, lib, this_ptr, arg_expr, level)?;
|
self.run_debugger(scope, global, state, lib, this_ptr, arg_expr, level)?;
|
||||||
constants[*slot].clone()
|
constants[*slot].clone()
|
||||||
@ -1081,7 +1081,7 @@ impl Engine {
|
|||||||
a_expr
|
a_expr
|
||||||
.iter()
|
.iter()
|
||||||
.try_fold(fn_curry, |mut curried, expr| -> RhaiResultOf<_> {
|
.try_fold(fn_curry, |mut curried, expr| -> RhaiResultOf<_> {
|
||||||
let (value, _) = self.get_arg_value(
|
let (value, ..) = self.get_arg_value(
|
||||||
scope, global, state, lib, this_ptr, expr, constants, level,
|
scope, global, state, lib, this_ptr, expr, constants, level,
|
||||||
)?;
|
)?;
|
||||||
curried.push(value);
|
curried.push(value);
|
||||||
@ -1095,7 +1095,7 @@ impl Engine {
|
|||||||
#[cfg(not(feature = "no_closure"))]
|
#[cfg(not(feature = "no_closure"))]
|
||||||
crate::engine::KEYWORD_IS_SHARED if total_args == 1 => {
|
crate::engine::KEYWORD_IS_SHARED if total_args == 1 => {
|
||||||
let arg = first_arg.unwrap();
|
let arg = first_arg.unwrap();
|
||||||
let (arg_value, _) =
|
let (arg_value, ..) =
|
||||||
self.get_arg_value(scope, global, state, lib, this_ptr, arg, constants, level)?;
|
self.get_arg_value(scope, global, state, lib, this_ptr, arg, constants, level)?;
|
||||||
return Ok(arg_value.is_shared().into());
|
return Ok(arg_value.is_shared().into());
|
||||||
}
|
}
|
||||||
@ -1195,7 +1195,7 @@ impl Engine {
|
|||||||
.chain(a_expr.iter())
|
.chain(a_expr.iter())
|
||||||
.try_for_each(|expr| {
|
.try_for_each(|expr| {
|
||||||
self.get_arg_value(scope, global, state, lib, this_ptr, expr, constants, level)
|
self.get_arg_value(scope, global, state, lib, this_ptr, expr, constants, level)
|
||||||
.map(|(value, _)| arg_values.push(value.flatten()))
|
.map(|(value, ..)| arg_values.push(value.flatten()))
|
||||||
})?;
|
})?;
|
||||||
args.extend(curry.iter_mut());
|
args.extend(curry.iter_mut());
|
||||||
args.extend(arg_values.iter_mut());
|
args.extend(arg_values.iter_mut());
|
||||||
@ -1208,7 +1208,7 @@ impl Engine {
|
|||||||
scope, global, state, lib, name, hashes, &mut args, is_ref_mut, false, pos,
|
scope, global, state, lib, name, hashes, &mut args, is_ref_mut, false, pos,
|
||||||
level,
|
level,
|
||||||
)
|
)
|
||||||
.map(|(v, _)| v);
|
.map(|(v, ..)| v);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Call with blank scope
|
// Call with blank scope
|
||||||
@ -1227,7 +1227,7 @@ impl Engine {
|
|||||||
// func(x, ...) -> x.func(...)
|
// func(x, ...) -> x.func(...)
|
||||||
a_expr.iter().try_for_each(|expr| {
|
a_expr.iter().try_for_each(|expr| {
|
||||||
self.get_arg_value(scope, global, state, lib, this_ptr, expr, constants, level)
|
self.get_arg_value(scope, global, state, lib, this_ptr, expr, constants, level)
|
||||||
.map(|(value, _)| arg_values.push(value.flatten()))
|
.map(|(value, ..)| arg_values.push(value.flatten()))
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
let (mut target, _pos) =
|
let (mut target, _pos) =
|
||||||
@ -1264,7 +1264,7 @@ impl Engine {
|
|||||||
self.get_arg_value(
|
self.get_arg_value(
|
||||||
scope, global, state, lib, this_ptr, expr, constants, level,
|
scope, global, state, lib, this_ptr, expr, constants, level,
|
||||||
)
|
)
|
||||||
.map(|(value, _)| arg_values.push(value.flatten()))
|
.map(|(value, ..)| arg_values.push(value.flatten()))
|
||||||
})?;
|
})?;
|
||||||
args.extend(curry.iter_mut());
|
args.extend(curry.iter_mut());
|
||||||
args.extend(arg_values.iter_mut());
|
args.extend(arg_values.iter_mut());
|
||||||
@ -1274,7 +1274,7 @@ impl Engine {
|
|||||||
self.exec_fn_call(
|
self.exec_fn_call(
|
||||||
None, global, state, lib, name, hashes, &mut args, is_ref_mut, false, pos, level,
|
None, global, state, lib, name, hashes, &mut args, is_ref_mut, false, pos, level,
|
||||||
)
|
)
|
||||||
.map(|(v, _)| v)
|
.map(|(v, ..)| v)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Call a namespace-qualified function in normal function-call style.
|
/// Call a namespace-qualified function in normal function-call style.
|
||||||
@ -1313,7 +1313,7 @@ impl Engine {
|
|||||||
|
|
||||||
args_expr.iter().skip(1).try_for_each(|expr| {
|
args_expr.iter().skip(1).try_for_each(|expr| {
|
||||||
self.get_arg_value(scope, global, state, lib, this_ptr, expr, constants, level)
|
self.get_arg_value(scope, global, state, lib, this_ptr, expr, constants, level)
|
||||||
.map(|(value, _)| arg_values.push(value.flatten()))
|
.map(|(value, ..)| arg_values.push(value.flatten()))
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
// Get target reference to first argument
|
// Get target reference to first argument
|
||||||
@ -1344,7 +1344,7 @@ impl Engine {
|
|||||||
// func(..., ...) or func(mod::x, ...)
|
// func(..., ...) or func(mod::x, ...)
|
||||||
args_expr.iter().try_for_each(|expr| {
|
args_expr.iter().try_for_each(|expr| {
|
||||||
self.get_arg_value(scope, global, state, lib, this_ptr, expr, constants, level)
|
self.get_arg_value(scope, global, state, lib, this_ptr, expr, constants, level)
|
||||||
.map(|(value, _)| arg_values.push(value.flatten()))
|
.map(|(value, ..)| arg_values.push(value.flatten()))
|
||||||
})?;
|
})?;
|
||||||
args.extend(arg_values.iter_mut());
|
args.extend(arg_values.iter_mut());
|
||||||
}
|
}
|
||||||
|
@ -333,7 +333,7 @@ impl<'a> NativeCallContext<'a> {
|
|||||||
Position::NONE,
|
Position::NONE,
|
||||||
self.level + 1,
|
self.level + 1,
|
||||||
)
|
)
|
||||||
.map(|(r, _)| r)
|
.map(|(r, ..)| r)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -103,7 +103,7 @@ impl Engine {
|
|||||||
scope
|
scope
|
||||||
.iter()
|
.iter()
|
||||||
.skip(orig_scope_len)
|
.skip(orig_scope_len)
|
||||||
.map(|(_, _, v)| v.clone())
|
.map(|(.., v)| v.clone())
|
||||||
.collect(),
|
.collect(),
|
||||||
global.source.clone(),
|
global.source.clone(),
|
||||||
pos,
|
pos,
|
||||||
@ -161,9 +161,9 @@ impl Engine {
|
|||||||
)
|
)
|
||||||
.or_else(|err| match *err {
|
.or_else(|err| match *err {
|
||||||
// Convert return statement to return value
|
// Convert return statement to return value
|
||||||
ERR::Return(x, _) => Ok(x),
|
ERR::Return(x, ..) => Ok(x),
|
||||||
// Error in sub function call
|
// Error in sub function call
|
||||||
ERR::ErrorInFunctionCall(name, src, err, _) => {
|
ERR::ErrorInFunctionCall(name, src, err, ..) => {
|
||||||
let fn_name = if src.is_empty() {
|
let fn_name = if src.is_empty() {
|
||||||
format!("{} < {}", name, fn_def.name)
|
format!("{} < {}", name, fn_def.name)
|
||||||
} else {
|
} else {
|
||||||
@ -185,7 +185,7 @@ impl Engine {
|
|||||||
{
|
{
|
||||||
let trigger = match global.debugger.status {
|
let trigger = match global.debugger.status {
|
||||||
crate::eval::DebuggerStatus::FunctionExit(n) => n >= level,
|
crate::eval::DebuggerStatus::FunctionExit(n) => n >= level,
|
||||||
crate::eval::DebuggerStatus::Next(_, true) => true,
|
crate::eval::DebuggerStatus::Next(.., true) => true,
|
||||||
_ => false,
|
_ => false,
|
||||||
};
|
};
|
||||||
if trigger {
|
if trigger {
|
||||||
|
@ -1402,7 +1402,7 @@ impl Module {
|
|||||||
/// Sub-modules are flattened onto the root [`Module`], with higher level overriding lower level.
|
/// Sub-modules are flattened onto the root [`Module`], with higher level overriding lower level.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn combine_flatten(&mut self, other: Self) -> &mut Self {
|
pub fn combine_flatten(&mut self, other: Self) -> &mut Self {
|
||||||
for (_, m) in other.modules.into_iter() {
|
for (.., m) in other.modules.into_iter() {
|
||||||
self.combine_flatten(shared_take_or_clone(m));
|
self.combine_flatten(shared_take_or_clone(m));
|
||||||
}
|
}
|
||||||
self.variables.extend(other.variables.into_iter());
|
self.variables.extend(other.variables.into_iter());
|
||||||
@ -1471,7 +1471,7 @@ impl Module {
|
|||||||
other
|
other
|
||||||
.functions
|
.functions
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|&(_, f)| {
|
.filter(|&(.., f)| {
|
||||||
_filter(
|
_filter(
|
||||||
f.metadata.namespace,
|
f.metadata.namespace,
|
||||||
f.metadata.access,
|
f.metadata.access,
|
||||||
@ -1502,7 +1502,7 @@ impl Module {
|
|||||||
) -> &mut Self {
|
) -> &mut Self {
|
||||||
self.functions = std::mem::take(&mut self.functions)
|
self.functions = std::mem::take(&mut self.functions)
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.filter(|(_, f)| {
|
.filter(|(.., f)| {
|
||||||
if f.func.is_script() {
|
if f.func.is_script() {
|
||||||
filter(
|
filter(
|
||||||
f.metadata.namespace,
|
f.metadata.namespace,
|
||||||
@ -1717,7 +1717,7 @@ impl Module {
|
|||||||
result?;
|
result?;
|
||||||
|
|
||||||
// Variables with an alias left in the scope become module variables
|
// Variables with an alias left in the scope become module variables
|
||||||
for (_, value, mut aliases) in scope {
|
for (.., value, mut aliases) in scope {
|
||||||
match aliases.len() {
|
match aliases.len() {
|
||||||
0 => (),
|
0 => (),
|
||||||
1 => {
|
1 => {
|
||||||
|
@ -128,7 +128,7 @@ impl ModuleResolver for ModuleResolversCollection {
|
|||||||
match resolver.resolve(engine, source_path, path, pos) {
|
match resolver.resolve(engine, source_path, path, pos) {
|
||||||
Ok(module) => return Ok(module),
|
Ok(module) => return Ok(module),
|
||||||
Err(err) => match *err {
|
Err(err) => match *err {
|
||||||
ERR::ErrorModuleNotFound(_, _) => continue,
|
ERR::ErrorModuleNotFound(..) => continue,
|
||||||
ERR::ErrorInModule(_, err, _) => return Err(err),
|
ERR::ErrorInModule(_, err, _) => return Err(err),
|
||||||
_ => panic!("ModuleResolver::resolve returns error that is not ErrorModuleNotFound or ErrorInModule"),
|
_ => panic!("ModuleResolver::resolve returns error that is not ErrorModuleNotFound or ErrorInModule"),
|
||||||
},
|
},
|
||||||
|
@ -230,7 +230,7 @@ impl FileModuleResolver {
|
|||||||
|
|
||||||
locked_write(&self.cache)
|
locked_write(&self.cache)
|
||||||
.remove_entry(&file_path)
|
.remove_entry(&file_path)
|
||||||
.map(|(_, v)| v)
|
.map(|(.., v)| v)
|
||||||
}
|
}
|
||||||
/// Construct a full file path.
|
/// Construct a full file path.
|
||||||
#[must_use]
|
#[must_use]
|
||||||
@ -288,7 +288,7 @@ impl FileModuleResolver {
|
|||||||
let mut ast = engine
|
let mut ast = engine
|
||||||
.compile_file(file_path.clone())
|
.compile_file(file_path.clone())
|
||||||
.map_err(|err| match *err {
|
.map_err(|err| match *err {
|
||||||
ERR::ErrorSystem(_, err) if err.is::<IoError>() => {
|
ERR::ErrorSystem(.., err) if err.is::<IoError>() => {
|
||||||
Box::new(ERR::ErrorModuleNotFound(path.to_string(), pos))
|
Box::new(ERR::ErrorModuleNotFound(path.to_string(), pos))
|
||||||
}
|
}
|
||||||
_ => Box::new(ERR::ErrorInModule(path.to_string(), err, pos)),
|
_ => Box::new(ERR::ErrorInModule(path.to_string(), err, pos)),
|
||||||
@ -356,7 +356,7 @@ impl ModuleResolver for FileModuleResolver {
|
|||||||
ast
|
ast
|
||||||
})
|
})
|
||||||
.map_err(|err| match *err {
|
.map_err(|err| match *err {
|
||||||
ERR::ErrorSystem(_, err) if err.is::<IoError>() => {
|
ERR::ErrorSystem(.., err) if err.is::<IoError>() => {
|
||||||
ERR::ErrorModuleNotFound(path.to_string(), pos).into()
|
ERR::ErrorModuleNotFound(path.to_string(), pos).into()
|
||||||
}
|
}
|
||||||
_ => ERR::ErrorInModule(path.to_string(), err, pos).into(),
|
_ => ERR::ErrorInModule(path.to_string(), err, pos).into(),
|
||||||
|
168
src/optimizer.rs
168
src/optimizer.rs
@ -150,7 +150,7 @@ impl<'a> OptimizerState<'a> {
|
|||||||
0,
|
0,
|
||||||
)
|
)
|
||||||
.ok()
|
.ok()
|
||||||
.map(|(v, _)| v)
|
.map(|(v, ..)| v)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -205,13 +205,13 @@ fn optimize_stmt_block(
|
|||||||
// Flatten blocks
|
// Flatten blocks
|
||||||
loop {
|
loop {
|
||||||
if let Some(n) = statements.iter().enumerate().find_map(|(i, s)| match s {
|
if let Some(n) = statements.iter().enumerate().find_map(|(i, s)| match s {
|
||||||
Stmt::Block(block, _) if !block.iter().any(Stmt::is_block_dependent) => Some(i),
|
Stmt::Block(block, ..) if !block.iter().any(Stmt::is_block_dependent) => Some(i),
|
||||||
_ => None,
|
_ => None,
|
||||||
}) {
|
}) {
|
||||||
let (first, second) = statements.split_at_mut(n);
|
let (first, second) = statements.split_at_mut(n);
|
||||||
let stmt = mem::take(&mut second[0]);
|
let stmt = mem::take(&mut second[0]);
|
||||||
let mut stmts = match stmt {
|
let mut stmts = match stmt {
|
||||||
Stmt::Block(block, _) => block,
|
Stmt::Block(block, ..) => block,
|
||||||
stmt => unreachable!("Stmt::Block expected but gets {:?}", stmt),
|
stmt => unreachable!("Stmt::Block expected but gets {:?}", stmt),
|
||||||
};
|
};
|
||||||
statements = first
|
statements = first
|
||||||
@ -252,7 +252,7 @@ fn optimize_stmt_block(
|
|||||||
// Optimize each statement in the block
|
// Optimize each statement in the block
|
||||||
for stmt in statements.iter_mut() {
|
for stmt in statements.iter_mut() {
|
||||||
match stmt {
|
match stmt {
|
||||||
Stmt::Var(value_expr, x, options, _) => {
|
Stmt::Var(value_expr, x, options, ..) => {
|
||||||
if options.contains(AST_OPTION_CONSTANT) {
|
if options.contains(AST_OPTION_CONSTANT) {
|
||||||
// Add constant literals into the state
|
// Add constant literals into the state
|
||||||
optimize_expr(value_expr, state, false);
|
optimize_expr(value_expr, state, false);
|
||||||
@ -284,10 +284,10 @@ fn optimize_stmt_block(
|
|||||||
.find_map(|(i, stmt)| match stmt {
|
.find_map(|(i, stmt)| match stmt {
|
||||||
stmt if !is_pure(stmt) => Some(i),
|
stmt if !is_pure(stmt) => Some(i),
|
||||||
|
|
||||||
Stmt::Var(e, _, _, _) | Stmt::Expr(e) if !e.is_constant() => Some(i),
|
Stmt::Var(e, _, ..) | Stmt::Expr(e) if !e.is_constant() => Some(i),
|
||||||
|
|
||||||
#[cfg(not(feature = "no_module"))]
|
#[cfg(not(feature = "no_module"))]
|
||||||
Stmt::Import(e, _, _) if !e.is_constant() => Some(i),
|
Stmt::Import(e, ..) if !e.is_constant() => Some(i),
|
||||||
|
|
||||||
_ => None,
|
_ => None,
|
||||||
})
|
})
|
||||||
@ -320,7 +320,7 @@ fn optimize_stmt_block(
|
|||||||
loop {
|
loop {
|
||||||
match statements[..] {
|
match statements[..] {
|
||||||
// { return; } -> {}
|
// { return; } -> {}
|
||||||
[Stmt::Return(options, None, _)]
|
[Stmt::Return(options, None, ..)]
|
||||||
if reduce_return && !options.contains(AST_OPTION_BREAK) =>
|
if reduce_return && !options.contains(AST_OPTION_BREAK) =>
|
||||||
{
|
{
|
||||||
state.set_dirty();
|
state.set_dirty();
|
||||||
@ -331,7 +331,7 @@ fn optimize_stmt_block(
|
|||||||
statements.clear();
|
statements.clear();
|
||||||
}
|
}
|
||||||
// { ...; return; } -> { ... }
|
// { ...; return; } -> { ... }
|
||||||
[.., ref last_stmt, Stmt::Return(options, None, _)]
|
[.., ref last_stmt, Stmt::Return(options, None, ..)]
|
||||||
if reduce_return
|
if reduce_return
|
||||||
&& !options.contains(AST_OPTION_BREAK)
|
&& !options.contains(AST_OPTION_BREAK)
|
||||||
&& !last_stmt.returns_value() =>
|
&& !last_stmt.returns_value() =>
|
||||||
@ -377,14 +377,14 @@ fn optimize_stmt_block(
|
|||||||
statements.clear();
|
statements.clear();
|
||||||
}
|
}
|
||||||
// { ...; return; } -> { ... }
|
// { ...; return; } -> { ... }
|
||||||
[.., Stmt::Return(options, None, _)]
|
[.., Stmt::Return(options, None, ..)]
|
||||||
if reduce_return && !options.contains(AST_OPTION_BREAK) =>
|
if reduce_return && !options.contains(AST_OPTION_BREAK) =>
|
||||||
{
|
{
|
||||||
state.set_dirty();
|
state.set_dirty();
|
||||||
statements.pop().unwrap();
|
statements.pop().unwrap();
|
||||||
}
|
}
|
||||||
// { ...; return pure_val; } -> { ... }
|
// { ...; return pure_val; } -> { ... }
|
||||||
[.., Stmt::Return(options, Some(ref expr), _)]
|
[.., Stmt::Return(options, Some(ref expr), ..)]
|
||||||
if reduce_return
|
if reduce_return
|
||||||
&& !options.contains(AST_OPTION_BREAK)
|
&& !options.contains(AST_OPTION_BREAK)
|
||||||
&& expr.is_pure() =>
|
&& expr.is_pure() =>
|
||||||
@ -424,17 +424,17 @@ fn optimize_stmt_block(
|
|||||||
fn optimize_stmt(stmt: &mut Stmt, state: &mut OptimizerState, preserve_result: bool) {
|
fn optimize_stmt(stmt: &mut Stmt, state: &mut OptimizerState, preserve_result: bool) {
|
||||||
match stmt {
|
match stmt {
|
||||||
// var = var op expr => var op= expr
|
// var = var op expr => var op= expr
|
||||||
Stmt::Assignment(x, _)
|
Stmt::Assignment(x, ..)
|
||||||
if x.0.is_none()
|
if x.0.is_none()
|
||||||
&& x.1.lhs.is_variable_access(true)
|
&& x.1.lhs.is_variable_access(true)
|
||||||
&& matches!(&x.1.rhs, Expr::FnCall(x2, _)
|
&& matches!(&x.1.rhs, Expr::FnCall(x2, ..)
|
||||||
if Token::lookup_from_syntax(&x2.name).map(|t| t.has_op_assignment()).unwrap_or(false)
|
if Token::lookup_from_syntax(&x2.name).map(|t| t.has_op_assignment()).unwrap_or(false)
|
||||||
&& x2.args.len() == 2
|
&& x2.args.len() == 2
|
||||||
&& x2.args[0].get_variable_name(true) == x.1.lhs.get_variable_name(true)
|
&& x2.args[0].get_variable_name(true) == x.1.lhs.get_variable_name(true)
|
||||||
) =>
|
) =>
|
||||||
{
|
{
|
||||||
match x.1.rhs {
|
match x.1.rhs {
|
||||||
Expr::FnCall(ref mut x2, _) => {
|
Expr::FnCall(ref mut x2, ..) => {
|
||||||
state.set_dirty();
|
state.set_dirty();
|
||||||
x.0 = Some(OpAssignment::new_from_base(&x2.name));
|
x.0 = Some(OpAssignment::new_from_base(&x2.name));
|
||||||
|
|
||||||
@ -452,7 +452,7 @@ fn optimize_stmt(stmt: &mut Stmt, state: &mut OptimizerState, preserve_result: b
|
|||||||
}
|
}
|
||||||
|
|
||||||
// expr op= expr
|
// expr op= expr
|
||||||
Stmt::Assignment(x, _) => {
|
Stmt::Assignment(x, ..) => {
|
||||||
if !x.1.lhs.is_variable_access(false) {
|
if !x.1.lhs.is_variable_access(false) {
|
||||||
optimize_expr(&mut x.1.lhs, state, false);
|
optimize_expr(&mut x.1.lhs, state, false);
|
||||||
}
|
}
|
||||||
@ -460,7 +460,7 @@ fn optimize_stmt(stmt: &mut Stmt, state: &mut OptimizerState, preserve_result: b
|
|||||||
}
|
}
|
||||||
|
|
||||||
// if expr {}
|
// if expr {}
|
||||||
Stmt::If(condition, x, _) if x.0.is_empty() && x.1.is_empty() => {
|
Stmt::If(condition, x, ..) if x.0.is_empty() && x.1.is_empty() => {
|
||||||
state.set_dirty();
|
state.set_dirty();
|
||||||
|
|
||||||
let pos = condition.start_position();
|
let pos = condition.start_position();
|
||||||
@ -479,12 +479,12 @@ fn optimize_stmt(stmt: &mut Stmt, state: &mut OptimizerState, preserve_result: b
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
// if false { if_block } -> Noop
|
// if false { if_block } -> Noop
|
||||||
Stmt::If(Expr::BoolConstant(false, pos), x, _) if x.1.is_empty() => {
|
Stmt::If(Expr::BoolConstant(false, pos), x, ..) if x.1.is_empty() => {
|
||||||
state.set_dirty();
|
state.set_dirty();
|
||||||
*stmt = Stmt::Noop(*pos);
|
*stmt = Stmt::Noop(*pos);
|
||||||
}
|
}
|
||||||
// if false { if_block } else { else_block } -> else_block
|
// if false { if_block } else { else_block } -> else_block
|
||||||
Stmt::If(Expr::BoolConstant(false, _), x, _) => {
|
Stmt::If(Expr::BoolConstant(false, ..), x, ..) => {
|
||||||
state.set_dirty();
|
state.set_dirty();
|
||||||
*stmt =
|
*stmt =
|
||||||
match optimize_stmt_block(mem::take(&mut *x.1), state, preserve_result, true, false)
|
match optimize_stmt_block(mem::take(&mut *x.1), state, preserve_result, true, false)
|
||||||
@ -494,7 +494,7 @@ fn optimize_stmt(stmt: &mut Stmt, state: &mut OptimizerState, preserve_result: b
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// if true { if_block } else { else_block } -> if_block
|
// if true { if_block } else { else_block } -> if_block
|
||||||
Stmt::If(Expr::BoolConstant(true, _), x, _) => {
|
Stmt::If(Expr::BoolConstant(true, ..), x, ..) => {
|
||||||
state.set_dirty();
|
state.set_dirty();
|
||||||
*stmt =
|
*stmt =
|
||||||
match optimize_stmt_block(mem::take(&mut *x.0), state, preserve_result, true, false)
|
match optimize_stmt_block(mem::take(&mut *x.0), state, preserve_result, true, false)
|
||||||
@ -504,7 +504,7 @@ fn optimize_stmt(stmt: &mut Stmt, state: &mut OptimizerState, preserve_result: b
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// if expr { if_block } else { else_block }
|
// if expr { if_block } else { else_block }
|
||||||
Stmt::If(condition, x, _) => {
|
Stmt::If(condition, x, ..) => {
|
||||||
optimize_expr(condition, state, false);
|
optimize_expr(condition, state, false);
|
||||||
*x.0 = optimize_stmt_block(mem::take(&mut *x.0), state, preserve_result, true, false);
|
*x.0 = optimize_stmt_block(mem::take(&mut *x.0), state, preserve_result, true, false);
|
||||||
*x.1 = optimize_stmt_block(mem::take(&mut *x.1), state, preserve_result, true, false);
|
*x.1 = optimize_stmt_block(mem::take(&mut *x.1), state, preserve_result, true, false);
|
||||||
@ -564,11 +564,11 @@ fn optimize_stmt(stmt: &mut Stmt, state: &mut OptimizerState, preserve_result: b
|
|||||||
let value = value.as_int().expect("`INT`");
|
let value = value.as_int().expect("`INT`");
|
||||||
|
|
||||||
// Only one range or all ranges without conditions
|
// Only one range or all ranges without conditions
|
||||||
if ranges.len() == 1 || ranges.iter().all(|(_, _, _, c)| !c.has_condition()) {
|
if ranges.len() == 1 || ranges.iter().all(|(.., c)| !c.has_condition()) {
|
||||||
for (_, _, _, block) in
|
for (.., block) in
|
||||||
ranges
|
ranges
|
||||||
.iter_mut()
|
.iter_mut()
|
||||||
.filter(|&&mut (start, end, inclusive, _)| {
|
.filter(|&&mut (start, end, inclusive, ..)| {
|
||||||
(!inclusive && (start..end).contains(&value))
|
(!inclusive && (start..end).contains(&value))
|
||||||
|| (inclusive && (start..=end).contains(&value))
|
|| (inclusive && (start..=end).contains(&value))
|
||||||
})
|
})
|
||||||
@ -619,7 +619,7 @@ fn optimize_stmt(stmt: &mut Stmt, state: &mut OptimizerState, preserve_result: b
|
|||||||
|
|
||||||
let old_ranges_len = ranges.len();
|
let old_ranges_len = ranges.len();
|
||||||
|
|
||||||
ranges.retain(|&mut (start, end, inclusive, _)| {
|
ranges.retain(|&mut (start, end, inclusive, ..)| {
|
||||||
(!inclusive && (start..end).contains(&value))
|
(!inclusive && (start..end).contains(&value))
|
||||||
|| (inclusive && (start..=end).contains(&value))
|
|| (inclusive && (start..=end).contains(&value))
|
||||||
});
|
});
|
||||||
@ -628,7 +628,7 @@ fn optimize_stmt(stmt: &mut Stmt, state: &mut OptimizerState, preserve_result: b
|
|||||||
state.set_dirty();
|
state.set_dirty();
|
||||||
}
|
}
|
||||||
|
|
||||||
for (_, _, _, block) in ranges.iter_mut() {
|
for (.., block) in ranges.iter_mut() {
|
||||||
let statements = mem::take(&mut *block.statements);
|
let statements = mem::take(&mut *block.statements);
|
||||||
*block.statements =
|
*block.statements =
|
||||||
optimize_stmt_block(statements, state, preserve_result, true, false);
|
optimize_stmt_block(statements, state, preserve_result, true, false);
|
||||||
@ -636,7 +636,7 @@ fn optimize_stmt(stmt: &mut Stmt, state: &mut OptimizerState, preserve_result: b
|
|||||||
if let Some(mut condition) = mem::take(&mut block.condition) {
|
if let Some(mut condition) = mem::take(&mut block.condition) {
|
||||||
optimize_expr(&mut condition, state, false);
|
optimize_expr(&mut condition, state, false);
|
||||||
match condition {
|
match condition {
|
||||||
Expr::Unit(_) | Expr::BoolConstant(true, _) => state.set_dirty(),
|
Expr::Unit(_) | Expr::BoolConstant(true, ..) => state.set_dirty(),
|
||||||
_ => block.condition = Some(condition),
|
_ => block.condition = Some(condition),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -655,7 +655,7 @@ fn optimize_stmt(stmt: &mut Stmt, state: &mut OptimizerState, preserve_result: b
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
// switch
|
// switch
|
||||||
Stmt::Switch(match_expr, x, _) => {
|
Stmt::Switch(match_expr, x, ..) => {
|
||||||
optimize_expr(match_expr, state, false);
|
optimize_expr(match_expr, state, false);
|
||||||
for block in x.cases.values_mut() {
|
for block in x.cases.values_mut() {
|
||||||
let statements = mem::take(&mut *block.statements);
|
let statements = mem::take(&mut *block.statements);
|
||||||
@ -665,15 +665,15 @@ fn optimize_stmt(stmt: &mut Stmt, state: &mut OptimizerState, preserve_result: b
|
|||||||
if let Some(mut condition) = mem::take(&mut block.condition) {
|
if let Some(mut condition) = mem::take(&mut block.condition) {
|
||||||
optimize_expr(&mut condition, state, false);
|
optimize_expr(&mut condition, state, false);
|
||||||
match condition {
|
match condition {
|
||||||
Expr::Unit(_) | Expr::BoolConstant(true, _) => state.set_dirty(),
|
Expr::Unit(_) | Expr::BoolConstant(true, ..) => state.set_dirty(),
|
||||||
_ => block.condition = Some(condition),
|
_ => block.condition = Some(condition),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove false cases
|
// Remove false cases
|
||||||
while let Some((&key, _)) = x.cases.iter().find(|(_, block)| match block.condition {
|
while let Some((&key, ..)) = x.cases.iter().find(|(.., block)| match block.condition {
|
||||||
Some(Expr::BoolConstant(false, _)) => true,
|
Some(Expr::BoolConstant(false, ..)) => true,
|
||||||
_ => false,
|
_ => false,
|
||||||
}) {
|
}) {
|
||||||
state.set_dirty();
|
state.set_dirty();
|
||||||
@ -685,12 +685,12 @@ fn optimize_stmt(stmt: &mut Stmt, state: &mut OptimizerState, preserve_result: b
|
|||||||
}
|
}
|
||||||
|
|
||||||
// while false { block } -> Noop
|
// while false { block } -> Noop
|
||||||
Stmt::While(Expr::BoolConstant(false, pos), _, _) => {
|
Stmt::While(Expr::BoolConstant(false, pos), ..) => {
|
||||||
state.set_dirty();
|
state.set_dirty();
|
||||||
*stmt = Stmt::Noop(*pos)
|
*stmt = Stmt::Noop(*pos)
|
||||||
}
|
}
|
||||||
// while expr { block }
|
// while expr { block }
|
||||||
Stmt::While(condition, body, _) => {
|
Stmt::While(condition, body, ..) => {
|
||||||
optimize_expr(condition, state, false);
|
optimize_expr(condition, state, false);
|
||||||
if let Expr::BoolConstant(true, pos) = condition {
|
if let Expr::BoolConstant(true, pos) = condition {
|
||||||
*condition = Expr::Unit(*pos);
|
*condition = Expr::Unit(*pos);
|
||||||
@ -719,7 +719,7 @@ fn optimize_stmt(stmt: &mut Stmt, state: &mut OptimizerState, preserve_result: b
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// do { block } while false | do { block } until true -> { block }
|
// do { block } while false | do { block } until true -> { block }
|
||||||
Stmt::Do(body, Expr::BoolConstant(x, _), options, _)
|
Stmt::Do(body, Expr::BoolConstant(x, ..), options, ..)
|
||||||
if *x == options.contains(AST_OPTION_NEGATED) =>
|
if *x == options.contains(AST_OPTION_NEGATED) =>
|
||||||
{
|
{
|
||||||
state.set_dirty();
|
state.set_dirty();
|
||||||
@ -730,22 +730,22 @@ fn optimize_stmt(stmt: &mut Stmt, state: &mut OptimizerState, preserve_result: b
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
// do { block } while|until expr
|
// do { block } while|until expr
|
||||||
Stmt::Do(body, condition, _, _) => {
|
Stmt::Do(body, condition, ..) => {
|
||||||
optimize_expr(condition, state, false);
|
optimize_expr(condition, state, false);
|
||||||
***body = optimize_stmt_block(mem::take(&mut **body), state, false, true, false);
|
***body = optimize_stmt_block(mem::take(&mut **body), state, false, true, false);
|
||||||
}
|
}
|
||||||
// for id in expr { block }
|
// for id in expr { block }
|
||||||
Stmt::For(iterable, x, _) => {
|
Stmt::For(iterable, x, ..) => {
|
||||||
optimize_expr(iterable, state, false);
|
optimize_expr(iterable, state, false);
|
||||||
*x.2 = optimize_stmt_block(mem::take(&mut *x.2), state, false, true, false);
|
*x.2 = optimize_stmt_block(mem::take(&mut *x.2), state, false, true, false);
|
||||||
}
|
}
|
||||||
// let id = expr;
|
// let id = expr;
|
||||||
Stmt::Var(expr, _, options, _) if !options.contains(AST_OPTION_CONSTANT) => {
|
Stmt::Var(expr, _, options, ..) if !options.contains(AST_OPTION_CONSTANT) => {
|
||||||
optimize_expr(expr, state, false)
|
optimize_expr(expr, state, false)
|
||||||
}
|
}
|
||||||
// import expr as var;
|
// import expr as var;
|
||||||
#[cfg(not(feature = "no_module"))]
|
#[cfg(not(feature = "no_module"))]
|
||||||
Stmt::Import(expr, _, _) => optimize_expr(expr, state, false),
|
Stmt::Import(expr, ..) => optimize_expr(expr, state, false),
|
||||||
// { block }
|
// { block }
|
||||||
Stmt::Block(statements, pos) => {
|
Stmt::Block(statements, pos) => {
|
||||||
let statements = mem::take(statements).into_vec().into();
|
let statements = mem::take(statements).into_vec().into();
|
||||||
@ -765,7 +765,7 @@ fn optimize_stmt(stmt: &mut Stmt, state: &mut OptimizerState, preserve_result: b
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// try { pure try_block } catch ( var ) { catch_block } -> try_block
|
// try { pure try_block } catch ( var ) { catch_block } -> try_block
|
||||||
Stmt::TryCatch(x, _) if x.try_block.iter().all(Stmt::is_pure) => {
|
Stmt::TryCatch(x, ..) if x.try_block.iter().all(Stmt::is_pure) => {
|
||||||
// If try block is pure, there will never be any exceptions
|
// If try block is pure, there will never be any exceptions
|
||||||
state.set_dirty();
|
state.set_dirty();
|
||||||
*stmt = Stmt::Block(
|
*stmt = Stmt::Block(
|
||||||
@ -775,14 +775,14 @@ fn optimize_stmt(stmt: &mut Stmt, state: &mut OptimizerState, preserve_result: b
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
// try { try_block } catch ( var ) { catch_block }
|
// try { try_block } catch ( var ) { catch_block }
|
||||||
Stmt::TryCatch(x, _) => {
|
Stmt::TryCatch(x, ..) => {
|
||||||
*x.try_block =
|
*x.try_block =
|
||||||
optimize_stmt_block(mem::take(&mut *x.try_block), state, false, true, false);
|
optimize_stmt_block(mem::take(&mut *x.try_block), state, false, true, false);
|
||||||
*x.catch_block =
|
*x.catch_block =
|
||||||
optimize_stmt_block(mem::take(&mut *x.catch_block), state, false, true, false);
|
optimize_stmt_block(mem::take(&mut *x.catch_block), state, false, true, false);
|
||||||
}
|
}
|
||||||
// func(...)
|
// func(...)
|
||||||
Stmt::Expr(expr @ Expr::FnCall(_, _)) => {
|
Stmt::Expr(expr @ Expr::FnCall(..)) => {
|
||||||
optimize_expr(expr, state, false);
|
optimize_expr(expr, state, false);
|
||||||
match expr {
|
match expr {
|
||||||
Expr::FnCall(x, pos) => {
|
Expr::FnCall(x, pos) => {
|
||||||
@ -838,31 +838,31 @@ fn optimize_expr(expr: &mut Expr, state: &mut OptimizerState, chaining: bool) {
|
|||||||
}
|
}
|
||||||
// lhs.rhs
|
// lhs.rhs
|
||||||
#[cfg(not(feature = "no_object"))]
|
#[cfg(not(feature = "no_object"))]
|
||||||
Expr::Dot(x,_, _) if !_chaining => match (&mut x.lhs, &mut x.rhs) {
|
Expr::Dot(x,_, ..) if !_chaining => match (&mut x.lhs, &mut x.rhs) {
|
||||||
// map.string
|
// map.string
|
||||||
(Expr::Map(m, pos), Expr::Property(p, _)) if m.0.iter().all(|(_, x)| x.is_pure()) => {
|
(Expr::Map(m, pos), Expr::Property(p, ..)) if m.0.iter().all(|(.., x)| x.is_pure()) => {
|
||||||
let prop = p.2.as_str();
|
let prop = p.2.as_str();
|
||||||
// Map literal where everything is pure - promote the indexed item.
|
// Map literal where everything is pure - promote the indexed item.
|
||||||
// All other items can be thrown away.
|
// All other items can be thrown away.
|
||||||
state.set_dirty();
|
state.set_dirty();
|
||||||
*expr = mem::take(&mut m.0).into_iter().find(|(x, _)| x.name == prop)
|
*expr = mem::take(&mut m.0).into_iter().find(|(x, ..)| x.name == prop)
|
||||||
.map(|(_, mut expr)| { expr.set_position(*pos); expr })
|
.map(|(.., mut expr)| { expr.set_position(*pos); expr })
|
||||||
.unwrap_or_else(|| Expr::Unit(*pos));
|
.unwrap_or_else(|| Expr::Unit(*pos));
|
||||||
}
|
}
|
||||||
// var.rhs
|
// var.rhs
|
||||||
(Expr::Variable(_, _, _), rhs) => optimize_expr(rhs, state, true),
|
(Expr::Variable(..), rhs) => optimize_expr(rhs, state, true),
|
||||||
// lhs.rhs
|
// lhs.rhs
|
||||||
(lhs, rhs) => { optimize_expr(lhs, state, false); optimize_expr(rhs, state, true); }
|
(lhs, rhs) => { optimize_expr(lhs, state, false); optimize_expr(rhs, state, true); }
|
||||||
}
|
}
|
||||||
// ....lhs.rhs
|
// ....lhs.rhs
|
||||||
#[cfg(not(feature = "no_object"))]
|
#[cfg(not(feature = "no_object"))]
|
||||||
Expr::Dot(x,_, _) => { optimize_expr(&mut x.lhs, state, false); optimize_expr(&mut x.rhs, state, _chaining); }
|
Expr::Dot(x,_, ..) => { optimize_expr(&mut x.lhs, state, false); optimize_expr(&mut x.rhs, state, _chaining); }
|
||||||
|
|
||||||
// lhs[rhs]
|
// lhs[rhs]
|
||||||
#[cfg(not(feature = "no_index"))]
|
#[cfg(not(feature = "no_index"))]
|
||||||
Expr::Index(x, _, _) if !_chaining => match (&mut x.lhs, &mut x.rhs) {
|
Expr::Index(x, ..) if !_chaining => match (&mut x.lhs, &mut x.rhs) {
|
||||||
// array[int]
|
// array[int]
|
||||||
(Expr::Array(a, pos), Expr::IntegerConstant(i, _)) if *i >= 0 && (*i as usize) < a.len() && a.iter().all(Expr::is_pure) => {
|
(Expr::Array(a, pos), Expr::IntegerConstant(i, ..)) if *i >= 0 && (*i as usize) < a.len() && a.iter().all(Expr::is_pure) => {
|
||||||
// Array literal where everything is pure - promote the indexed item.
|
// Array literal where everything is pure - promote the indexed item.
|
||||||
// All other items can be thrown away.
|
// All other items can be thrown away.
|
||||||
state.set_dirty();
|
state.set_dirty();
|
||||||
@ -871,7 +871,7 @@ fn optimize_expr(expr: &mut Expr, state: &mut OptimizerState, chaining: bool) {
|
|||||||
*expr = result;
|
*expr = result;
|
||||||
}
|
}
|
||||||
// array[-int]
|
// array[-int]
|
||||||
(Expr::Array(a, pos), Expr::IntegerConstant(i, _)) if *i < 0 && i.checked_abs().map(|n| n as usize <= a.len()).unwrap_or(false) && a.iter().all(Expr::is_pure) => {
|
(Expr::Array(a, pos), Expr::IntegerConstant(i, ..)) if *i < 0 && i.checked_abs().map(|n| n as usize <= a.len()).unwrap_or(false) && a.iter().all(Expr::is_pure) => {
|
||||||
// Array literal where everything is pure - promote the indexed item.
|
// Array literal where everything is pure - promote the indexed item.
|
||||||
// All other items can be thrown away.
|
// All other items can be thrown away.
|
||||||
state.set_dirty();
|
state.set_dirty();
|
||||||
@ -881,58 +881,58 @@ fn optimize_expr(expr: &mut Expr, state: &mut OptimizerState, chaining: bool) {
|
|||||||
*expr = result;
|
*expr = result;
|
||||||
}
|
}
|
||||||
// map[string]
|
// map[string]
|
||||||
(Expr::Map(m, pos), Expr::StringConstant(s, _)) if m.0.iter().all(|(_, x)| x.is_pure()) => {
|
(Expr::Map(m, pos), Expr::StringConstant(s, ..)) if m.0.iter().all(|(.., x)| x.is_pure()) => {
|
||||||
// Map literal where everything is pure - promote the indexed item.
|
// Map literal where everything is pure - promote the indexed item.
|
||||||
// All other items can be thrown away.
|
// All other items can be thrown away.
|
||||||
state.set_dirty();
|
state.set_dirty();
|
||||||
*expr = mem::take(&mut m.0).into_iter().find(|(x, _)| x.name.as_str() == s.as_str())
|
*expr = mem::take(&mut m.0).into_iter().find(|(x, ..)| x.name.as_str() == s.as_str())
|
||||||
.map(|(_, mut expr)| { expr.set_position(*pos); expr })
|
.map(|(.., mut expr)| { expr.set_position(*pos); expr })
|
||||||
.unwrap_or_else(|| Expr::Unit(*pos));
|
.unwrap_or_else(|| Expr::Unit(*pos));
|
||||||
}
|
}
|
||||||
// int[int]
|
// int[int]
|
||||||
(Expr::IntegerConstant(n, pos), Expr::IntegerConstant(i, _)) if *i >= 0 && (*i as usize) < (std::mem::size_of_val(n) * 8) => {
|
(Expr::IntegerConstant(n, pos), Expr::IntegerConstant(i, ..)) if *i >= 0 && (*i as usize) < (std::mem::size_of_val(n) * 8) => {
|
||||||
// Bit-field literal indexing - get the bit
|
// Bit-field literal indexing - get the bit
|
||||||
state.set_dirty();
|
state.set_dirty();
|
||||||
*expr = Expr::BoolConstant((*n & (1 << (*i as usize))) != 0, *pos);
|
*expr = Expr::BoolConstant((*n & (1 << (*i as usize))) != 0, *pos);
|
||||||
}
|
}
|
||||||
// int[-int]
|
// int[-int]
|
||||||
(Expr::IntegerConstant(n, pos), Expr::IntegerConstant(i, _)) if *i < 0 && i.checked_abs().map(|i| i as usize <= (std::mem::size_of_val(n) * 8)).unwrap_or(false) => {
|
(Expr::IntegerConstant(n, pos), Expr::IntegerConstant(i, ..)) if *i < 0 && i.checked_abs().map(|i| i as usize <= (std::mem::size_of_val(n) * 8)).unwrap_or(false) => {
|
||||||
// Bit-field literal indexing - get the bit
|
// Bit-field literal indexing - get the bit
|
||||||
state.set_dirty();
|
state.set_dirty();
|
||||||
*expr = Expr::BoolConstant((*n & (1 << (std::mem::size_of_val(n) * 8 - i.abs() as usize))) != 0, *pos);
|
*expr = Expr::BoolConstant((*n & (1 << (std::mem::size_of_val(n) * 8 - i.abs() as usize))) != 0, *pos);
|
||||||
}
|
}
|
||||||
// string[int]
|
// string[int]
|
||||||
(Expr::StringConstant(s, pos), Expr::IntegerConstant(i, _)) if *i >= 0 && (*i as usize) < s.chars().count() => {
|
(Expr::StringConstant(s, pos), Expr::IntegerConstant(i, ..)) if *i >= 0 && (*i as usize) < s.chars().count() => {
|
||||||
// String literal indexing - get the character
|
// String literal indexing - get the character
|
||||||
state.set_dirty();
|
state.set_dirty();
|
||||||
*expr = Expr::CharConstant(s.chars().nth(*i as usize).unwrap(), *pos);
|
*expr = Expr::CharConstant(s.chars().nth(*i as usize).unwrap(), *pos);
|
||||||
}
|
}
|
||||||
// string[-int]
|
// string[-int]
|
||||||
(Expr::StringConstant(s, pos), Expr::IntegerConstant(i, _)) if *i < 0 && i.checked_abs().map(|n| n as usize <= s.chars().count()).unwrap_or(false) => {
|
(Expr::StringConstant(s, pos), Expr::IntegerConstant(i, ..)) if *i < 0 && i.checked_abs().map(|n| n as usize <= s.chars().count()).unwrap_or(false) => {
|
||||||
// String literal indexing - get the character
|
// String literal indexing - get the character
|
||||||
state.set_dirty();
|
state.set_dirty();
|
||||||
*expr = Expr::CharConstant(s.chars().rev().nth(i.abs() as usize - 1).unwrap(), *pos);
|
*expr = Expr::CharConstant(s.chars().rev().nth(i.abs() as usize - 1).unwrap(), *pos);
|
||||||
}
|
}
|
||||||
// var[rhs]
|
// var[rhs]
|
||||||
(Expr::Variable(_, _, _), rhs) => optimize_expr(rhs, state, true),
|
(Expr::Variable(..), rhs) => optimize_expr(rhs, state, true),
|
||||||
// lhs[rhs]
|
// lhs[rhs]
|
||||||
(lhs, rhs) => { optimize_expr(lhs, state, false); optimize_expr(rhs, state, true); }
|
(lhs, rhs) => { optimize_expr(lhs, state, false); optimize_expr(rhs, state, true); }
|
||||||
},
|
},
|
||||||
// ...[lhs][rhs]
|
// ...[lhs][rhs]
|
||||||
#[cfg(not(feature = "no_index"))]
|
#[cfg(not(feature = "no_index"))]
|
||||||
Expr::Index(x, _, _) => { optimize_expr(&mut x.lhs, state, false); optimize_expr(&mut x.rhs, state, _chaining); }
|
Expr::Index(x, ..) => { optimize_expr(&mut x.lhs, state, false); optimize_expr(&mut x.rhs, state, _chaining); }
|
||||||
// ``
|
// ``
|
||||||
Expr::InterpolatedString(x, pos) if x.is_empty() => {
|
Expr::InterpolatedString(x, pos) if x.is_empty() => {
|
||||||
state.set_dirty();
|
state.set_dirty();
|
||||||
*expr = Expr::StringConstant(state.engine.const_empty_string(), *pos);
|
*expr = Expr::StringConstant(state.engine.const_empty_string(), *pos);
|
||||||
}
|
}
|
||||||
// `...`
|
// `...`
|
||||||
Expr::InterpolatedString(x, _) if x.len() == 1 && matches!(x[0], Expr::StringConstant(_, _)) => {
|
Expr::InterpolatedString(x, ..) if x.len() == 1 && matches!(x[0], Expr::StringConstant(..)) => {
|
||||||
state.set_dirty();
|
state.set_dirty();
|
||||||
*expr = mem::take(&mut x[0]);
|
*expr = mem::take(&mut x[0]);
|
||||||
}
|
}
|
||||||
// `... ${ ... } ...`
|
// `... ${ ... } ...`
|
||||||
Expr::InterpolatedString(x, _) => {
|
Expr::InterpolatedString(x, ..) => {
|
||||||
x.iter_mut().for_each(|expr| optimize_expr(expr, state, false));
|
x.iter_mut().for_each(|expr| optimize_expr(expr, state, false));
|
||||||
|
|
||||||
let mut n = 0;
|
let mut n = 0;
|
||||||
@ -940,11 +940,11 @@ fn optimize_expr(expr: &mut Expr, state: &mut OptimizerState, chaining: bool) {
|
|||||||
// Merge consecutive strings
|
// Merge consecutive strings
|
||||||
while n < x.len() - 1 {
|
while n < x.len() - 1 {
|
||||||
match (mem::take(&mut x[n]), mem::take(&mut x[n+1])) {
|
match (mem::take(&mut x[n]), mem::take(&mut x[n+1])) {
|
||||||
(Expr::StringConstant(mut s1, pos), Expr::StringConstant(s2, _)) => { s1 += s2; x[n] = Expr::StringConstant(s1, pos); x.remove(n+1); state.set_dirty(); }
|
(Expr::StringConstant(mut s1, pos), Expr::StringConstant(s2, ..)) => { s1 += s2; x[n] = Expr::StringConstant(s1, pos); x.remove(n+1); state.set_dirty(); }
|
||||||
(expr1, Expr::Unit(_)) => { x[n] = expr1; x.remove(n+1); state.set_dirty(); }
|
(expr1, Expr::Unit(_)) => { x[n] = expr1; x.remove(n+1); state.set_dirty(); }
|
||||||
(Expr::Unit(_), expr2) => { x[n+1] = expr2; x.remove(n); state.set_dirty(); }
|
(Expr::Unit(_), expr2) => { x[n+1] = expr2; x.remove(n); state.set_dirty(); }
|
||||||
(expr1, Expr::StringConstant(s, _)) if s.is_empty() => { x[n] = expr1; x.remove(n+1); state.set_dirty(); }
|
(expr1, Expr::StringConstant(s, ..)) if s.is_empty() => { x[n] = expr1; x.remove(n+1); state.set_dirty(); }
|
||||||
(Expr::StringConstant(s, _), expr2) if s.is_empty()=> { x[n+1] = expr2; x.remove(n); state.set_dirty(); }
|
(Expr::StringConstant(s, ..), expr2) if s.is_empty()=> { x[n+1] = expr2; x.remove(n); state.set_dirty(); }
|
||||||
(expr1, expr2) => { x[n] = expr1; x[n+1] = expr2; n += 1; }
|
(expr1, expr2) => { x[n] = expr1; x[n+1] = expr2; n += 1; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -953,47 +953,47 @@ fn optimize_expr(expr: &mut Expr, state: &mut OptimizerState, chaining: bool) {
|
|||||||
}
|
}
|
||||||
// [ constant .. ]
|
// [ constant .. ]
|
||||||
#[cfg(not(feature = "no_index"))]
|
#[cfg(not(feature = "no_index"))]
|
||||||
Expr::Array(_, _) if expr.is_constant() => {
|
Expr::Array(..) if expr.is_constant() => {
|
||||||
state.set_dirty();
|
state.set_dirty();
|
||||||
*expr = Expr::DynamicConstant(expr.get_literal_value().unwrap().into(), expr.position());
|
*expr = Expr::DynamicConstant(expr.get_literal_value().unwrap().into(), expr.position());
|
||||||
}
|
}
|
||||||
// [ items .. ]
|
// [ items .. ]
|
||||||
#[cfg(not(feature = "no_index"))]
|
#[cfg(not(feature = "no_index"))]
|
||||||
Expr::Array(x, _) => x.iter_mut().for_each(|expr| optimize_expr(expr, state, false)),
|
Expr::Array(x, ..) => x.iter_mut().for_each(|expr| optimize_expr(expr, state, false)),
|
||||||
// #{ key:constant, .. }
|
// #{ key:constant, .. }
|
||||||
#[cfg(not(feature = "no_object"))]
|
#[cfg(not(feature = "no_object"))]
|
||||||
Expr::Map(_, _) if expr.is_constant() => {
|
Expr::Map(..) if expr.is_constant() => {
|
||||||
state.set_dirty();
|
state.set_dirty();
|
||||||
*expr = Expr::DynamicConstant(expr.get_literal_value().unwrap().into(), expr.position());
|
*expr = Expr::DynamicConstant(expr.get_literal_value().unwrap().into(), expr.position());
|
||||||
}
|
}
|
||||||
// #{ key:value, .. }
|
// #{ key:value, .. }
|
||||||
#[cfg(not(feature = "no_object"))]
|
#[cfg(not(feature = "no_object"))]
|
||||||
Expr::Map(x, _) => x.0.iter_mut().for_each(|(_, expr)| optimize_expr(expr, state, false)),
|
Expr::Map(x, ..) => x.0.iter_mut().for_each(|(.., expr)| optimize_expr(expr, state, false)),
|
||||||
// lhs && rhs
|
// lhs && rhs
|
||||||
Expr::And(x, _) => match (&mut x.lhs, &mut x.rhs) {
|
Expr::And(x, ..) => match (&mut x.lhs, &mut x.rhs) {
|
||||||
// true && rhs -> rhs
|
// true && rhs -> rhs
|
||||||
(Expr::BoolConstant(true, _), rhs) => { state.set_dirty(); optimize_expr(rhs, state, false); *expr = mem::take(rhs); }
|
(Expr::BoolConstant(true, ..), rhs) => { state.set_dirty(); optimize_expr(rhs, state, false); *expr = mem::take(rhs); }
|
||||||
// false && rhs -> false
|
// false && rhs -> false
|
||||||
(Expr::BoolConstant(false, pos), _) => { state.set_dirty(); *expr = Expr::BoolConstant(false, *pos); }
|
(Expr::BoolConstant(false, pos), ..) => { state.set_dirty(); *expr = Expr::BoolConstant(false, *pos); }
|
||||||
// lhs && true -> lhs
|
// lhs && true -> lhs
|
||||||
(lhs, Expr::BoolConstant(true, _)) => { state.set_dirty(); optimize_expr(lhs, state, false); *expr = mem::take(lhs); }
|
(lhs, Expr::BoolConstant(true, ..)) => { state.set_dirty(); optimize_expr(lhs, state, false); *expr = mem::take(lhs); }
|
||||||
// lhs && rhs
|
// lhs && rhs
|
||||||
(lhs, rhs) => { optimize_expr(lhs, state, false); optimize_expr(rhs, state, false); }
|
(lhs, rhs) => { optimize_expr(lhs, state, false); optimize_expr(rhs, state, false); }
|
||||||
},
|
},
|
||||||
// lhs || rhs
|
// lhs || rhs
|
||||||
Expr::Or(ref mut x, _) => match (&mut x.lhs, &mut x.rhs) {
|
Expr::Or(ref mut x, ..) => match (&mut x.lhs, &mut x.rhs) {
|
||||||
// false || rhs -> rhs
|
// false || rhs -> rhs
|
||||||
(Expr::BoolConstant(false, _), rhs) => { state.set_dirty(); optimize_expr(rhs, state, false); *expr = mem::take(rhs); }
|
(Expr::BoolConstant(false, ..), rhs) => { state.set_dirty(); optimize_expr(rhs, state, false); *expr = mem::take(rhs); }
|
||||||
// true || rhs -> true
|
// true || rhs -> true
|
||||||
(Expr::BoolConstant(true, pos), _) => { state.set_dirty(); *expr = Expr::BoolConstant(true, *pos); }
|
(Expr::BoolConstant(true, pos), ..) => { state.set_dirty(); *expr = Expr::BoolConstant(true, *pos); }
|
||||||
// lhs || false
|
// lhs || false
|
||||||
(lhs, Expr::BoolConstant(false, _)) => { state.set_dirty(); optimize_expr(lhs, state, false); *expr = mem::take(lhs); }
|
(lhs, Expr::BoolConstant(false, ..)) => { state.set_dirty(); optimize_expr(lhs, state, false); *expr = mem::take(lhs); }
|
||||||
// lhs || rhs
|
// lhs || rhs
|
||||||
(lhs, rhs) => { optimize_expr(lhs, state, false); optimize_expr(rhs, state, false); }
|
(lhs, rhs) => { optimize_expr(lhs, state, false); optimize_expr(rhs, state, false); }
|
||||||
},
|
},
|
||||||
|
|
||||||
// eval!
|
// eval!
|
||||||
Expr::FnCall(x, _) if x.name == KEYWORD_EVAL => {
|
Expr::FnCall(x, ..) if x.name == KEYWORD_EVAL => {
|
||||||
state.propagate_constants = false;
|
state.propagate_constants = false;
|
||||||
}
|
}
|
||||||
// Fn
|
// Fn
|
||||||
@ -1005,8 +1005,8 @@ fn optimize_expr(expr: &mut Expr, state: &mut OptimizerState, chaining: bool) {
|
|||||||
&& x.args[0].is_constant()
|
&& x.args[0].is_constant()
|
||||||
=> {
|
=> {
|
||||||
let fn_name = match x.args[0] {
|
let fn_name = match x.args[0] {
|
||||||
Expr::Stack(slot, _) => x.constants[slot].clone(),
|
Expr::Stack(slot, ..) => x.constants[slot].clone(),
|
||||||
Expr::StringConstant(ref s, _) => s.clone().into(),
|
Expr::StringConstant(ref s, ..) => s.clone().into(),
|
||||||
_ => Dynamic::UNIT
|
_ => Dynamic::UNIT
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1019,7 +1019,7 @@ fn optimize_expr(expr: &mut Expr, state: &mut OptimizerState, chaining: bool) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Do not call some special keywords
|
// Do not call some special keywords
|
||||||
Expr::FnCall(x, _) if DONT_EVAL_KEYWORDS.contains(&x.name.as_ref()) => {
|
Expr::FnCall(x, ..) if DONT_EVAL_KEYWORDS.contains(&x.name.as_ref()) => {
|
||||||
x.args.iter_mut().for_each(|a| optimize_expr(a, state, false));
|
x.args.iter_mut().for_each(|a| optimize_expr(a, state, false));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1031,7 +1031,7 @@ fn optimize_expr(expr: &mut Expr, state: &mut OptimizerState, chaining: bool) {
|
|||||||
//&& !is_valid_identifier(x.name.chars()) // cannot be scripted
|
//&& !is_valid_identifier(x.name.chars()) // cannot be scripted
|
||||||
=> {
|
=> {
|
||||||
let arg_values = &mut x.args.iter().map(|e| match e {
|
let arg_values = &mut x.args.iter().map(|e| match e {
|
||||||
Expr::Stack(slot, _) => x.constants[*slot].clone(),
|
Expr::Stack(slot, ..) => x.constants[*slot].clone(),
|
||||||
_ => e.get_literal_value().unwrap()
|
_ => e.get_literal_value().unwrap()
|
||||||
}).collect::<StaticVec<_>>();
|
}).collect::<StaticVec<_>>();
|
||||||
|
|
||||||
@ -1097,7 +1097,7 @@ fn optimize_expr(expr: &mut Expr, state: &mut OptimizerState, chaining: bool) {
|
|||||||
|
|
||||||
if !has_script_fn {
|
if !has_script_fn {
|
||||||
let arg_values = &mut x.args.iter().map(|e| match e {
|
let arg_values = &mut x.args.iter().map(|e| match e {
|
||||||
Expr::Stack(slot, _) => x.constants[*slot].clone(),
|
Expr::Stack(slot, ..) => x.constants[*slot].clone(),
|
||||||
_ => e.get_literal_value().unwrap()
|
_ => e.get_literal_value().unwrap()
|
||||||
}).collect::<StaticVec<_>>();
|
}).collect::<StaticVec<_>>();
|
||||||
|
|
||||||
@ -1119,7 +1119,7 @@ fn optimize_expr(expr: &mut Expr, state: &mut OptimizerState, chaining: bool) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// id(args ..) -> optimize function call arguments
|
// id(args ..) -> optimize function call arguments
|
||||||
Expr::FnCall(x, _) => for arg in x.args.iter_mut() {
|
Expr::FnCall(x, ..) => for arg in x.args.iter_mut() {
|
||||||
optimize_expr(arg, state, false);
|
optimize_expr(arg, state, false);
|
||||||
|
|
||||||
// Move constant arguments
|
// Move constant arguments
|
||||||
@ -1132,15 +1132,15 @@ fn optimize_expr(expr: &mut Expr, state: &mut OptimizerState, chaining: bool) {
|
|||||||
|
|
||||||
// constant-name
|
// constant-name
|
||||||
#[cfg(not(feature = "no_module"))]
|
#[cfg(not(feature = "no_module"))]
|
||||||
Expr::Variable(_, _, x) if x.1.is_some() => (),
|
Expr::Variable(.., x) if x.1.is_some() => (),
|
||||||
Expr::Variable(_, pos, x) if state.find_constant(&x.2).is_some() => {
|
Expr::Variable(.., pos, x) if state.find_constant(&x.2).is_some() => {
|
||||||
// Replace constant with value
|
// Replace constant with value
|
||||||
*expr = Expr::from_dynamic(state.find_constant(&x.2).unwrap().clone(), *pos);
|
*expr = Expr::from_dynamic(state.find_constant(&x.2).unwrap().clone(), *pos);
|
||||||
state.set_dirty();
|
state.set_dirty();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Custom syntax
|
// Custom syntax
|
||||||
Expr::Custom(x, _) => {
|
Expr::Custom(x, ..) => {
|
||||||
if x.scope_may_be_changed {
|
if x.scope_may_be_changed {
|
||||||
state.propagate_constants = false;
|
state.propagate_constants = false;
|
||||||
}
|
}
|
||||||
|
@ -52,7 +52,7 @@ pub mod array_functions {
|
|||||||
return Dynamic::UNIT;
|
return Dynamic::UNIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
let (index, _) = calc_offset_len(array.len(), index, 0);
|
let (index, ..) = calc_offset_len(array.len(), index, 0);
|
||||||
|
|
||||||
if index >= array.len() {
|
if index >= array.len() {
|
||||||
Dynamic::UNIT
|
Dynamic::UNIT
|
||||||
@ -88,7 +88,7 @@ pub mod array_functions {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let (index, _) = calc_offset_len(array.len(), index, 0);
|
let (index, ..) = calc_offset_len(array.len(), index, 0);
|
||||||
|
|
||||||
if index < array.len() {
|
if index < array.len() {
|
||||||
array[index] = value;
|
array[index] = value;
|
||||||
@ -182,7 +182,7 @@ pub mod array_functions {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let (index, _) = calc_offset_len(array.len(), index, 0);
|
let (index, ..) = calc_offset_len(array.len(), index, 0);
|
||||||
|
|
||||||
if index >= array.len() {
|
if index >= array.len() {
|
||||||
array.push(item);
|
array.push(item);
|
||||||
@ -231,10 +231,11 @@ pub mod array_functions {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let check_sizes = match item.0 {
|
let check_sizes = match item.0 {
|
||||||
crate::types::dynamic::Union::Array(_, _, _)
|
crate::types::dynamic::Union::Array(..) | crate::types::dynamic::Union::Str(..) => {
|
||||||
| crate::types::dynamic::Union::Str(_, _, _) => true,
|
true
|
||||||
|
}
|
||||||
#[cfg(not(feature = "no_object"))]
|
#[cfg(not(feature = "no_object"))]
|
||||||
crate::types::dynamic::Union::Map(_, _, _) => true,
|
crate::types::dynamic::Union::Map(..) => true,
|
||||||
_ => false,
|
_ => false,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -651,7 +652,7 @@ pub mod array_functions {
|
|||||||
mapper
|
mapper
|
||||||
.call_raw(&ctx, None, [item.clone()])
|
.call_raw(&ctx, None, [item.clone()])
|
||||||
.or_else(|err| match *err {
|
.or_else(|err| match *err {
|
||||||
ERR::ErrorFunctionNotFound(fn_sig, _)
|
ERR::ErrorFunctionNotFound(fn_sig, ..)
|
||||||
if fn_sig.starts_with(mapper.fn_name()) =>
|
if fn_sig.starts_with(mapper.fn_name()) =>
|
||||||
{
|
{
|
||||||
mapper.call_raw(&ctx, None, [item.clone(), (i as INT).into()])
|
mapper.call_raw(&ctx, None, [item.clone(), (i as INT).into()])
|
||||||
@ -740,7 +741,7 @@ pub mod array_functions {
|
|||||||
if filter
|
if filter
|
||||||
.call_raw(&ctx, None, [item.clone()])
|
.call_raw(&ctx, None, [item.clone()])
|
||||||
.or_else(|err| match *err {
|
.or_else(|err| match *err {
|
||||||
ERR::ErrorFunctionNotFound(fn_sig, _)
|
ERR::ErrorFunctionNotFound(fn_sig, ..)
|
||||||
if fn_sig.starts_with(filter.fn_name()) =>
|
if fn_sig.starts_with(filter.fn_name()) =>
|
||||||
{
|
{
|
||||||
filter.call_raw(&ctx, None, [item.clone(), (i as INT).into()])
|
filter.call_raw(&ctx, None, [item.clone(), (i as INT).into()])
|
||||||
@ -828,7 +829,7 @@ pub mod array_functions {
|
|||||||
if ctx
|
if ctx
|
||||||
.call_fn_raw(OP_EQUALS, true, false, &mut [item, &mut value.clone()])
|
.call_fn_raw(OP_EQUALS, true, false, &mut [item, &mut value.clone()])
|
||||||
.or_else(|err| match *err {
|
.or_else(|err| match *err {
|
||||||
ERR::ErrorFunctionNotFound(ref fn_sig, _) if fn_sig.starts_with(OP_EQUALS) => {
|
ERR::ErrorFunctionNotFound(ref fn_sig, ..) if fn_sig.starts_with(OP_EQUALS) => {
|
||||||
if item.type_id() == value.type_id() {
|
if item.type_id() == value.type_id() {
|
||||||
// No default when comparing same type
|
// No default when comparing same type
|
||||||
Err(err)
|
Err(err)
|
||||||
@ -914,13 +915,13 @@ pub mod array_functions {
|
|||||||
return Ok(-1);
|
return Ok(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
let (start, _) = calc_offset_len(array.len(), start, 0);
|
let (start, ..) = calc_offset_len(array.len(), start, 0);
|
||||||
|
|
||||||
for (i, item) in array.iter_mut().enumerate().skip(start) {
|
for (i, item) in array.iter_mut().enumerate().skip(start) {
|
||||||
if ctx
|
if ctx
|
||||||
.call_fn_raw(OP_EQUALS, true, false, &mut [item, &mut value.clone()])
|
.call_fn_raw(OP_EQUALS, true, false, &mut [item, &mut value.clone()])
|
||||||
.or_else(|err| match *err {
|
.or_else(|err| match *err {
|
||||||
ERR::ErrorFunctionNotFound(ref fn_sig, _) if fn_sig.starts_with(OP_EQUALS) => {
|
ERR::ErrorFunctionNotFound(ref fn_sig, ..) if fn_sig.starts_with(OP_EQUALS) => {
|
||||||
if item.type_id() == value.type_id() {
|
if item.type_id() == value.type_id() {
|
||||||
// No default when comparing same type
|
// No default when comparing same type
|
||||||
Err(err)
|
Err(err)
|
||||||
@ -1044,13 +1045,13 @@ pub mod array_functions {
|
|||||||
return Ok(-1);
|
return Ok(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
let (start, _) = calc_offset_len(array.len(), start, 0);
|
let (start, ..) = calc_offset_len(array.len(), start, 0);
|
||||||
|
|
||||||
for (i, item) in array.iter().enumerate().skip(start) {
|
for (i, item) in array.iter().enumerate().skip(start) {
|
||||||
if filter
|
if filter
|
||||||
.call_raw(&ctx, None, [item.clone()])
|
.call_raw(&ctx, None, [item.clone()])
|
||||||
.or_else(|err| match *err {
|
.or_else(|err| match *err {
|
||||||
ERR::ErrorFunctionNotFound(fn_sig, _)
|
ERR::ErrorFunctionNotFound(fn_sig, ..)
|
||||||
if fn_sig.starts_with(filter.fn_name()) =>
|
if fn_sig.starts_with(filter.fn_name()) =>
|
||||||
{
|
{
|
||||||
filter.call_raw(&ctx, None, [item.clone(), (i as INT).into()])
|
filter.call_raw(&ctx, None, [item.clone(), (i as INT).into()])
|
||||||
@ -1149,7 +1150,7 @@ pub mod array_functions {
|
|||||||
if filter
|
if filter
|
||||||
.call_raw(&ctx, None, [item.clone()])
|
.call_raw(&ctx, None, [item.clone()])
|
||||||
.or_else(|err| match *err {
|
.or_else(|err| match *err {
|
||||||
ERR::ErrorFunctionNotFound(fn_sig, _)
|
ERR::ErrorFunctionNotFound(fn_sig, ..)
|
||||||
if fn_sig.starts_with(filter.fn_name()) =>
|
if fn_sig.starts_with(filter.fn_name()) =>
|
||||||
{
|
{
|
||||||
filter.call_raw(&ctx, None, [item.clone(), (i as INT).into()])
|
filter.call_raw(&ctx, None, [item.clone(), (i as INT).into()])
|
||||||
@ -1236,7 +1237,7 @@ pub mod array_functions {
|
|||||||
if !filter
|
if !filter
|
||||||
.call_raw(&ctx, None, [item.clone()])
|
.call_raw(&ctx, None, [item.clone()])
|
||||||
.or_else(|err| match *err {
|
.or_else(|err| match *err {
|
||||||
ERR::ErrorFunctionNotFound(fn_sig, _)
|
ERR::ErrorFunctionNotFound(fn_sig, ..)
|
||||||
if fn_sig.starts_with(filter.fn_name()) =>
|
if fn_sig.starts_with(filter.fn_name()) =>
|
||||||
{
|
{
|
||||||
filter.call_raw(&ctx, None, [item.clone(), (i as INT).into()])
|
filter.call_raw(&ctx, None, [item.clone(), (i as INT).into()])
|
||||||
@ -1486,7 +1487,7 @@ pub mod array_functions {
|
|||||||
result = reducer
|
result = reducer
|
||||||
.call_raw(&ctx, None, [result.clone(), item.clone()])
|
.call_raw(&ctx, None, [result.clone(), item.clone()])
|
||||||
.or_else(|err| match *err {
|
.or_else(|err| match *err {
|
||||||
ERR::ErrorFunctionNotFound(fn_sig, _)
|
ERR::ErrorFunctionNotFound(fn_sig, ..)
|
||||||
if fn_sig.starts_with(reducer.fn_name()) =>
|
if fn_sig.starts_with(reducer.fn_name()) =>
|
||||||
{
|
{
|
||||||
reducer.call_raw(&ctx, None, [result, item, (i as INT).into()])
|
reducer.call_raw(&ctx, None, [result, item, (i as INT).into()])
|
||||||
@ -1648,7 +1649,7 @@ pub mod array_functions {
|
|||||||
result = reducer
|
result = reducer
|
||||||
.call_raw(&ctx, None, [result.clone(), item.clone()])
|
.call_raw(&ctx, None, [result.clone(), item.clone()])
|
||||||
.or_else(|err| match *err {
|
.or_else(|err| match *err {
|
||||||
ERR::ErrorFunctionNotFound(fn_sig, _)
|
ERR::ErrorFunctionNotFound(fn_sig, ..)
|
||||||
if fn_sig.starts_with(reducer.fn_name()) =>
|
if fn_sig.starts_with(reducer.fn_name()) =>
|
||||||
{
|
{
|
||||||
reducer.call_raw(&ctx, None, [result, item, ((len - 1 - i) as INT).into()])
|
reducer.call_raw(&ctx, None, [result, item, ((len - 1 - i) as INT).into()])
|
||||||
@ -1925,7 +1926,7 @@ pub mod array_functions {
|
|||||||
if filter
|
if filter
|
||||||
.call_raw(&ctx, None, [array[x].clone()])
|
.call_raw(&ctx, None, [array[x].clone()])
|
||||||
.or_else(|err| match *err {
|
.or_else(|err| match *err {
|
||||||
ERR::ErrorFunctionNotFound(fn_sig, _)
|
ERR::ErrorFunctionNotFound(fn_sig, ..)
|
||||||
if fn_sig.starts_with(filter.fn_name()) =>
|
if fn_sig.starts_with(filter.fn_name()) =>
|
||||||
{
|
{
|
||||||
filter.call_raw(&ctx, None, [array[x].clone(), (i as INT).into()])
|
filter.call_raw(&ctx, None, [array[x].clone(), (i as INT).into()])
|
||||||
@ -2121,7 +2122,7 @@ pub mod array_functions {
|
|||||||
if !filter
|
if !filter
|
||||||
.call_raw(&ctx, None, [array[x].clone()])
|
.call_raw(&ctx, None, [array[x].clone()])
|
||||||
.or_else(|err| match *err {
|
.or_else(|err| match *err {
|
||||||
ERR::ErrorFunctionNotFound(fn_sig, _)
|
ERR::ErrorFunctionNotFound(fn_sig, ..)
|
||||||
if fn_sig.starts_with(filter.fn_name()) =>
|
if fn_sig.starts_with(filter.fn_name()) =>
|
||||||
{
|
{
|
||||||
filter.call_raw(&ctx, None, [array[x].clone(), (i as INT).into()])
|
filter.call_raw(&ctx, None, [array[x].clone(), (i as INT).into()])
|
||||||
@ -2311,7 +2312,7 @@ pub mod array_functions {
|
|||||||
if !ctx
|
if !ctx
|
||||||
.call_fn_raw(OP_EQUALS, true, false, &mut [a1, a2])
|
.call_fn_raw(OP_EQUALS, true, false, &mut [a1, a2])
|
||||||
.or_else(|err| match *err {
|
.or_else(|err| match *err {
|
||||||
ERR::ErrorFunctionNotFound(ref fn_sig, _) if fn_sig.starts_with(OP_EQUALS) => {
|
ERR::ErrorFunctionNotFound(ref fn_sig, ..) if fn_sig.starts_with(OP_EQUALS) => {
|
||||||
if a1.type_id() == a2.type_id() {
|
if a1.type_id() == a2.type_id() {
|
||||||
// No default when comparing same type
|
// No default when comparing same type
|
||||||
Err(err)
|
Err(err)
|
||||||
|
@ -124,7 +124,7 @@ pub mod blob_functions {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
let (index, _) = calc_offset_len(blob.len(), index, 0);
|
let (index, ..) = calc_offset_len(blob.len(), index, 0);
|
||||||
|
|
||||||
if index >= blob.len() {
|
if index >= blob.len() {
|
||||||
0
|
0
|
||||||
@ -162,7 +162,7 @@ pub mod blob_functions {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let (index, _) = calc_offset_len(blob.len(), index, 0);
|
let (index, ..) = calc_offset_len(blob.len(), index, 0);
|
||||||
|
|
||||||
if index < blob.len() {
|
if index < blob.len() {
|
||||||
blob[index] = (value & 0x000000ff) as u8;
|
blob[index] = (value & 0x000000ff) as u8;
|
||||||
@ -256,7 +256,7 @@ pub mod blob_functions {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let (index, _) = calc_offset_len(blob.len(), index, 0);
|
let (index, ..) = calc_offset_len(blob.len(), index, 0);
|
||||||
|
|
||||||
if index >= blob.len() {
|
if index >= blob.len() {
|
||||||
blob.push(value);
|
blob.push(value);
|
||||||
|
@ -152,7 +152,7 @@ fn collect_fn_metadata(
|
|||||||
ctx.iter_namespaces()
|
ctx.iter_namespaces()
|
||||||
.flat_map(Module::iter_script_fn)
|
.flat_map(Module::iter_script_fn)
|
||||||
.filter(|(s, a, n, p, f)| filter(*s, *a, n, *p, f))
|
.filter(|(s, a, n, p, f)| filter(*s, *a, n, *p, f))
|
||||||
.for_each(|(_, _, _, _, f)| {
|
.for_each(|(.., f)| {
|
||||||
list.push(
|
list.push(
|
||||||
make_metadata(
|
make_metadata(
|
||||||
&dict,
|
&dict,
|
||||||
@ -169,7 +169,7 @@ fn collect_fn_metadata(
|
|||||||
.iter()
|
.iter()
|
||||||
.flat_map(|m| m.iter_script_fn())
|
.flat_map(|m| m.iter_script_fn())
|
||||||
.filter(|(ns, a, n, p, f)| filter(*ns, *a, n, *p, f))
|
.filter(|(ns, a, n, p, f)| filter(*ns, *a, n, *p, f))
|
||||||
.for_each(|(_, _, _, _, f)| {
|
.for_each(|(.., f)| {
|
||||||
list.push(
|
list.push(
|
||||||
make_metadata(
|
make_metadata(
|
||||||
&dict,
|
&dict,
|
||||||
@ -187,7 +187,7 @@ fn collect_fn_metadata(
|
|||||||
.values()
|
.values()
|
||||||
.flat_map(|m| m.iter_script_fn())
|
.flat_map(|m| m.iter_script_fn())
|
||||||
.filter(|(ns, a, n, p, f)| filter(*ns, *a, n, *p, f))
|
.filter(|(ns, a, n, p, f)| filter(*ns, *a, n, *p, f))
|
||||||
.for_each(|(_, _, _, _, f)| {
|
.for_each(|(.., f)| {
|
||||||
list.push(
|
list.push(
|
||||||
make_metadata(
|
make_metadata(
|
||||||
&dict,
|
&dict,
|
||||||
@ -219,7 +219,7 @@ fn collect_fn_metadata(
|
|||||||
module
|
module
|
||||||
.iter_script_fn()
|
.iter_script_fn()
|
||||||
.filter(|(s, a, n, p, f)| filter(*s, *a, n, *p, f))
|
.filter(|(s, a, n, p, f)| filter(*s, *a, n, *p, f))
|
||||||
.for_each(|(_, _, _, _, f)| {
|
.for_each(|(.., f)| {
|
||||||
list.push(make_metadata(dict, Some(namespace.clone()), f).into())
|
list.push(make_metadata(dict, Some(namespace.clone()), f).into())
|
||||||
});
|
});
|
||||||
for (ns, m) in module.iter_sub_modules() {
|
for (ns, m) in module.iter_sub_modules() {
|
||||||
|
362
src/parser.rs
362
src/parser.rs
File diff suppressed because it is too large
Load Diff
@ -118,55 +118,55 @@ impl<'de> Deserializer<'de> for &mut DynamicDeserializer<'de> {
|
|||||||
|
|
||||||
fn deserialize_any<V: Visitor<'de>>(self, visitor: V) -> RhaiResultOf<V::Value> {
|
fn deserialize_any<V: Visitor<'de>>(self, visitor: V) -> RhaiResultOf<V::Value> {
|
||||||
match self.value.0 {
|
match self.value.0 {
|
||||||
Union::Unit(_, _, _) => self.deserialize_unit(visitor),
|
Union::Unit(..) => self.deserialize_unit(visitor),
|
||||||
Union::Bool(_, _, _) => self.deserialize_bool(visitor),
|
Union::Bool(..) => self.deserialize_bool(visitor),
|
||||||
Union::Str(_, _, _) => self.deserialize_str(visitor),
|
Union::Str(..) => self.deserialize_str(visitor),
|
||||||
Union::Char(_, _, _) => self.deserialize_char(visitor),
|
Union::Char(..) => self.deserialize_char(visitor),
|
||||||
|
|
||||||
#[cfg(not(feature = "only_i32"))]
|
#[cfg(not(feature = "only_i32"))]
|
||||||
Union::Int(_, _, _) => self.deserialize_i64(visitor),
|
Union::Int(..) => self.deserialize_i64(visitor),
|
||||||
#[cfg(feature = "only_i32")]
|
#[cfg(feature = "only_i32")]
|
||||||
Union::Int(_, _, _) => self.deserialize_i32(visitor),
|
Union::Int(..) => self.deserialize_i32(visitor),
|
||||||
|
|
||||||
#[cfg(not(feature = "no_float"))]
|
#[cfg(not(feature = "no_float"))]
|
||||||
#[cfg(not(feature = "f32_float"))]
|
#[cfg(not(feature = "f32_float"))]
|
||||||
Union::Float(_, _, _) => self.deserialize_f64(visitor),
|
Union::Float(..) => self.deserialize_f64(visitor),
|
||||||
#[cfg(not(feature = "no_float"))]
|
#[cfg(not(feature = "no_float"))]
|
||||||
#[cfg(feature = "f32_float")]
|
#[cfg(feature = "f32_float")]
|
||||||
Union::Float(_, _, _) => self.deserialize_f32(visitor),
|
Union::Float(..) => self.deserialize_f32(visitor),
|
||||||
|
|
||||||
#[cfg(feature = "decimal")]
|
#[cfg(feature = "decimal")]
|
||||||
#[cfg(not(feature = "f32_float"))]
|
#[cfg(not(feature = "f32_float"))]
|
||||||
Union::Decimal(_, _, _) => self.deserialize_f64(visitor),
|
Union::Decimal(..) => self.deserialize_f64(visitor),
|
||||||
#[cfg(feature = "decimal")]
|
#[cfg(feature = "decimal")]
|
||||||
#[cfg(feature = "f32_float")]
|
#[cfg(feature = "f32_float")]
|
||||||
Union::Decimal(_, _, _) => self.deserialize_f32(visitor),
|
Union::Decimal(..) => self.deserialize_f32(visitor),
|
||||||
|
|
||||||
#[cfg(not(feature = "no_index"))]
|
#[cfg(not(feature = "no_index"))]
|
||||||
Union::Array(_, _, _) => self.deserialize_seq(visitor),
|
Union::Array(..) => self.deserialize_seq(visitor),
|
||||||
#[cfg(not(feature = "no_index"))]
|
#[cfg(not(feature = "no_index"))]
|
||||||
Union::Blob(_, _, _) => self.deserialize_bytes(visitor),
|
Union::Blob(..) => self.deserialize_bytes(visitor),
|
||||||
#[cfg(not(feature = "no_object"))]
|
#[cfg(not(feature = "no_object"))]
|
||||||
Union::Map(_, _, _) => self.deserialize_map(visitor),
|
Union::Map(..) => self.deserialize_map(visitor),
|
||||||
Union::FnPtr(_, _, _) => self.type_error(),
|
Union::FnPtr(..) => self.type_error(),
|
||||||
#[cfg(not(feature = "no_std"))]
|
#[cfg(not(feature = "no_std"))]
|
||||||
Union::TimeStamp(_, _, _) => self.type_error(),
|
Union::TimeStamp(..) => self.type_error(),
|
||||||
|
|
||||||
Union::Variant(ref value, _, _) if value.is::<i8>() => self.deserialize_i8(visitor),
|
Union::Variant(ref value, ..) if value.is::<i8>() => self.deserialize_i8(visitor),
|
||||||
Union::Variant(ref value, _, _) if value.is::<i16>() => self.deserialize_i16(visitor),
|
Union::Variant(ref value, ..) if value.is::<i16>() => self.deserialize_i16(visitor),
|
||||||
Union::Variant(ref value, _, _) if value.is::<i32>() => self.deserialize_i32(visitor),
|
Union::Variant(ref value, ..) if value.is::<i32>() => self.deserialize_i32(visitor),
|
||||||
Union::Variant(ref value, _, _) if value.is::<i64>() => self.deserialize_i64(visitor),
|
Union::Variant(ref value, ..) if value.is::<i64>() => self.deserialize_i64(visitor),
|
||||||
Union::Variant(ref value, _, _) if value.is::<i128>() => self.deserialize_i128(visitor),
|
Union::Variant(ref value, ..) if value.is::<i128>() => self.deserialize_i128(visitor),
|
||||||
Union::Variant(ref value, _, _) if value.is::<u8>() => self.deserialize_u8(visitor),
|
Union::Variant(ref value, ..) if value.is::<u8>() => self.deserialize_u8(visitor),
|
||||||
Union::Variant(ref value, _, _) if value.is::<u16>() => self.deserialize_u16(visitor),
|
Union::Variant(ref value, ..) if value.is::<u16>() => self.deserialize_u16(visitor),
|
||||||
Union::Variant(ref value, _, _) if value.is::<u32>() => self.deserialize_u32(visitor),
|
Union::Variant(ref value, ..) if value.is::<u32>() => self.deserialize_u32(visitor),
|
||||||
Union::Variant(ref value, _, _) if value.is::<u64>() => self.deserialize_u64(visitor),
|
Union::Variant(ref value, ..) if value.is::<u64>() => self.deserialize_u64(visitor),
|
||||||
Union::Variant(ref value, _, _) if value.is::<u128>() => self.deserialize_u128(visitor),
|
Union::Variant(ref value, ..) if value.is::<u128>() => self.deserialize_u128(visitor),
|
||||||
|
|
||||||
Union::Variant(_, _, _) => self.type_error(),
|
Union::Variant(..) => self.type_error(),
|
||||||
|
|
||||||
#[cfg(not(feature = "no_closure"))]
|
#[cfg(not(feature = "no_closure"))]
|
||||||
Union::Shared(_, _, _) => self.type_error(),
|
Union::Shared(..) => self.type_error(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,26 +15,26 @@ use crate::types::dynamic::Variant;
|
|||||||
impl Serialize for Dynamic {
|
impl Serialize for Dynamic {
|
||||||
fn serialize<S: Serializer>(&self, ser: S) -> Result<S::Ok, S::Error> {
|
fn serialize<S: Serializer>(&self, ser: S) -> Result<S::Ok, S::Error> {
|
||||||
match self.0 {
|
match self.0 {
|
||||||
Union::Unit(_, _, _) => ser.serialize_unit(),
|
Union::Unit(..) => ser.serialize_unit(),
|
||||||
Union::Bool(x, _, _) => ser.serialize_bool(x),
|
Union::Bool(x, ..) => ser.serialize_bool(x),
|
||||||
Union::Str(ref s, _, _) => ser.serialize_str(s.as_str()),
|
Union::Str(ref s, ..) => ser.serialize_str(s.as_str()),
|
||||||
Union::Char(c, _, _) => ser.serialize_str(&c.to_string()),
|
Union::Char(c, ..) => ser.serialize_str(&c.to_string()),
|
||||||
|
|
||||||
#[cfg(not(feature = "only_i32"))]
|
#[cfg(not(feature = "only_i32"))]
|
||||||
Union::Int(x, _, _) => ser.serialize_i64(x),
|
Union::Int(x, ..) => ser.serialize_i64(x),
|
||||||
#[cfg(feature = "only_i32")]
|
#[cfg(feature = "only_i32")]
|
||||||
Union::Int(x, _, _) => ser.serialize_i32(x),
|
Union::Int(x, ..) => ser.serialize_i32(x),
|
||||||
|
|
||||||
#[cfg(not(feature = "no_float"))]
|
#[cfg(not(feature = "no_float"))]
|
||||||
#[cfg(not(feature = "f32_float"))]
|
#[cfg(not(feature = "f32_float"))]
|
||||||
Union::Float(x, _, _) => ser.serialize_f64(*x),
|
Union::Float(x, ..) => ser.serialize_f64(*x),
|
||||||
#[cfg(not(feature = "no_float"))]
|
#[cfg(not(feature = "no_float"))]
|
||||||
#[cfg(feature = "f32_float")]
|
#[cfg(feature = "f32_float")]
|
||||||
Union::Float(x, _, _) => ser.serialize_f32(*x),
|
Union::Float(x, ..) => ser.serialize_f32(*x),
|
||||||
|
|
||||||
#[cfg(feature = "decimal")]
|
#[cfg(feature = "decimal")]
|
||||||
#[cfg(not(feature = "f32_float"))]
|
#[cfg(not(feature = "f32_float"))]
|
||||||
Union::Decimal(ref x, _, _) => {
|
Union::Decimal(ref x, ..) => {
|
||||||
use rust_decimal::prelude::ToPrimitive;
|
use rust_decimal::prelude::ToPrimitive;
|
||||||
|
|
||||||
if let Some(v) = x.to_f64() {
|
if let Some(v) = x.to_f64() {
|
||||||
@ -45,7 +45,7 @@ impl Serialize for Dynamic {
|
|||||||
}
|
}
|
||||||
#[cfg(feature = "decimal")]
|
#[cfg(feature = "decimal")]
|
||||||
#[cfg(feature = "f32_float")]
|
#[cfg(feature = "f32_float")]
|
||||||
Union::Decimal(ref x, _, _) => {
|
Union::Decimal(ref x, ..) => {
|
||||||
use rust_decimal::prelude::ToPrimitive;
|
use rust_decimal::prelude::ToPrimitive;
|
||||||
|
|
||||||
if let Some(v) = x.to_f32() {
|
if let Some(v) = x.to_f32() {
|
||||||
@ -56,28 +56,28 @@ impl Serialize for Dynamic {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(feature = "no_index"))]
|
#[cfg(not(feature = "no_index"))]
|
||||||
Union::Array(ref a, _, _) => (**a).serialize(ser),
|
Union::Array(ref a, ..) => (**a).serialize(ser),
|
||||||
#[cfg(not(feature = "no_index"))]
|
#[cfg(not(feature = "no_index"))]
|
||||||
Union::Blob(ref a, _, _) => (**a).serialize(ser),
|
Union::Blob(ref a, ..) => (**a).serialize(ser),
|
||||||
#[cfg(not(feature = "no_object"))]
|
#[cfg(not(feature = "no_object"))]
|
||||||
Union::Map(ref m, _, _) => {
|
Union::Map(ref m, ..) => {
|
||||||
let mut map = ser.serialize_map(Some(m.len()))?;
|
let mut map = ser.serialize_map(Some(m.len()))?;
|
||||||
m.iter()
|
m.iter()
|
||||||
.try_for_each(|(k, v)| map.serialize_entry(k.as_str(), v))?;
|
.try_for_each(|(k, v)| map.serialize_entry(k.as_str(), v))?;
|
||||||
map.end()
|
map.end()
|
||||||
}
|
}
|
||||||
Union::FnPtr(ref f, _, _) => ser.serialize_str(f.fn_name()),
|
Union::FnPtr(ref f, ..) => ser.serialize_str(f.fn_name()),
|
||||||
#[cfg(not(feature = "no_std"))]
|
#[cfg(not(feature = "no_std"))]
|
||||||
Union::TimeStamp(ref x, _, _) => ser.serialize_str(x.as_ref().type_name()),
|
Union::TimeStamp(ref x, ..) => ser.serialize_str(x.as_ref().type_name()),
|
||||||
|
|
||||||
Union::Variant(ref v, _, _) => ser.serialize_str((***v).type_name()),
|
Union::Variant(ref v, ..) => ser.serialize_str((***v).type_name()),
|
||||||
|
|
||||||
#[cfg(not(feature = "no_closure"))]
|
#[cfg(not(feature = "no_closure"))]
|
||||||
#[cfg(not(feature = "sync"))]
|
#[cfg(not(feature = "sync"))]
|
||||||
Union::Shared(ref cell, _, _) => cell.borrow().serialize(ser),
|
Union::Shared(ref cell, ..) => cell.borrow().serialize(ser),
|
||||||
#[cfg(not(feature = "no_closure"))]
|
#[cfg(not(feature = "no_closure"))]
|
||||||
#[cfg(feature = "sync")]
|
#[cfg(feature = "sync")]
|
||||||
Union::Shared(ref cell, _, _) => cell.read().unwrap().serialize(ser),
|
Union::Shared(ref cell, ..) => cell.read().unwrap().serialize(ser),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1332,7 +1332,7 @@ pub fn get_next_token(
|
|||||||
let result = get_next_token_inner(stream, state, pos);
|
let result = get_next_token_inner(stream, state, pos);
|
||||||
|
|
||||||
// Save the last token's state
|
// Save the last token's state
|
||||||
if let Some((ref token, _)) = result {
|
if let Some((ref token, ..)) = result {
|
||||||
state.next_token_cannot_be_unary = !token.is_next_unary();
|
state.next_token_cannot_be_unary = !token.is_next_unary();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1420,10 +1420,10 @@ fn get_next_token_inner(
|
|||||||
|
|
||||||
match (c, stream.peek_next().unwrap_or('\0')) {
|
match (c, stream.peek_next().unwrap_or('\0')) {
|
||||||
// \n
|
// \n
|
||||||
('\n', _) => pos.new_line(),
|
('\n', ..) => pos.new_line(),
|
||||||
|
|
||||||
// digit ...
|
// digit ...
|
||||||
('0'..='9', _) => {
|
('0'..='9', ..) => {
|
||||||
let mut result = smallvec::SmallVec::<[char; 16]>::new();
|
let mut result = smallvec::SmallVec::<[char; 16]>::new();
|
||||||
let mut radix_base: Option<u32> = None;
|
let mut radix_base: Option<u32> = None;
|
||||||
let mut valid: fn(char) -> bool = is_numeric_digit;
|
let mut valid: fn(char) -> bool = is_numeric_digit;
|
||||||
@ -1573,24 +1573,24 @@ fn get_next_token_inner(
|
|||||||
|
|
||||||
// letter or underscore ...
|
// letter or underscore ...
|
||||||
#[cfg(not(feature = "unicode-xid-ident"))]
|
#[cfg(not(feature = "unicode-xid-ident"))]
|
||||||
('a'..='z', _) | ('_', _) | ('A'..='Z', _) => {
|
('a'..='z', ..) | ('_', ..) | ('A'..='Z', ..) => {
|
||||||
return get_identifier(stream, pos, start_pos, c);
|
return get_identifier(stream, pos, start_pos, c);
|
||||||
}
|
}
|
||||||
#[cfg(feature = "unicode-xid-ident")]
|
#[cfg(feature = "unicode-xid-ident")]
|
||||||
(ch, _) if unicode_xid::UnicodeXID::is_xid_start(ch) || ch == '_' => {
|
(ch, ..) if unicode_xid::UnicodeXID::is_xid_start(ch) || ch == '_' => {
|
||||||
return get_identifier(stream, pos, start_pos, c);
|
return get_identifier(stream, pos, start_pos, c);
|
||||||
}
|
}
|
||||||
|
|
||||||
// " - string literal
|
// " - string literal
|
||||||
('"', _) => {
|
('"', ..) => {
|
||||||
return parse_string_literal(stream, state, pos, c, false, true, false)
|
return parse_string_literal(stream, state, pos, c, false, true, false)
|
||||||
.map_or_else(
|
.map_or_else(
|
||||||
|(err, err_pos)| Some((Token::LexError(err), err_pos)),
|
|(err, err_pos)| Some((Token::LexError(err), err_pos)),
|
||||||
|(result, _)| Some((Token::StringConstant(result), start_pos)),
|
|(result, ..)| Some((Token::StringConstant(result), start_pos)),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
// ` - string literal
|
// ` - string literal
|
||||||
('`', _) => {
|
('`', ..) => {
|
||||||
// Start from the next line if at the end of line
|
// Start from the next line if at the end of line
|
||||||
match stream.peek_next() {
|
match stream.peek_next() {
|
||||||
// `\r - start from next line
|
// `\r - start from next line
|
||||||
@ -1629,11 +1629,11 @@ fn get_next_token_inner(
|
|||||||
start_pos,
|
start_pos,
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
('\'', _) => {
|
('\'', ..) => {
|
||||||
return Some(
|
return Some(
|
||||||
parse_string_literal(stream, state, pos, c, false, false, false).map_or_else(
|
parse_string_literal(stream, state, pos, c, false, false, false).map_or_else(
|
||||||
|(err, err_pos)| (Token::LexError(err), err_pos),
|
|(err, err_pos)| (Token::LexError(err), err_pos),
|
||||||
|(result, _)| {
|
|(result, ..)| {
|
||||||
let mut chars = result.chars();
|
let mut chars = result.chars();
|
||||||
let first = chars.next().unwrap();
|
let first = chars.next().unwrap();
|
||||||
|
|
||||||
@ -1651,20 +1651,20 @@ fn get_next_token_inner(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Braces
|
// Braces
|
||||||
('{', _) => return Some((Token::LeftBrace, start_pos)),
|
('{', ..) => return Some((Token::LeftBrace, start_pos)),
|
||||||
('}', _) => return Some((Token::RightBrace, start_pos)),
|
('}', ..) => return Some((Token::RightBrace, start_pos)),
|
||||||
|
|
||||||
// Parentheses
|
// Parentheses
|
||||||
('(', '*') => {
|
('(', '*') => {
|
||||||
eat_next(stream, pos);
|
eat_next(stream, pos);
|
||||||
return Some((Token::Reserved("(*".into()), start_pos));
|
return Some((Token::Reserved("(*".into()), start_pos));
|
||||||
}
|
}
|
||||||
('(', _) => return Some((Token::LeftParen, start_pos)),
|
('(', ..) => return Some((Token::LeftParen, start_pos)),
|
||||||
(')', _) => return Some((Token::RightParen, start_pos)),
|
(')', ..) => return Some((Token::RightParen, start_pos)),
|
||||||
|
|
||||||
// Indexing
|
// Indexing
|
||||||
('[', _) => return Some((Token::LeftBracket, start_pos)),
|
('[', ..) => return Some((Token::LeftBracket, start_pos)),
|
||||||
(']', _) => return Some((Token::RightBracket, start_pos)),
|
(']', ..) => return Some((Token::RightBracket, start_pos)),
|
||||||
|
|
||||||
// Map literal
|
// Map literal
|
||||||
#[cfg(not(feature = "no_object"))]
|
#[cfg(not(feature = "no_object"))]
|
||||||
@ -1686,7 +1686,7 @@ fn get_next_token_inner(
|
|||||||
return Some((Token::Reserved(token.into()), start_pos));
|
return Some((Token::Reserved(token.into()), start_pos));
|
||||||
}
|
}
|
||||||
|
|
||||||
('#', _) => return Some((Token::Reserved("#".into()), start_pos)),
|
('#', ..) => return Some((Token::Reserved("#".into()), start_pos)),
|
||||||
|
|
||||||
// Operators
|
// Operators
|
||||||
('+', '=') => {
|
('+', '=') => {
|
||||||
@ -1697,10 +1697,10 @@ fn get_next_token_inner(
|
|||||||
eat_next(stream, pos);
|
eat_next(stream, pos);
|
||||||
return Some((Token::Reserved("++".into()), start_pos));
|
return Some((Token::Reserved("++".into()), start_pos));
|
||||||
}
|
}
|
||||||
('+', _) if !state.next_token_cannot_be_unary => {
|
('+', ..) if !state.next_token_cannot_be_unary => {
|
||||||
return Some((Token::UnaryPlus, start_pos))
|
return Some((Token::UnaryPlus, start_pos))
|
||||||
}
|
}
|
||||||
('+', _) => return Some((Token::Plus, start_pos)),
|
('+', ..) => return Some((Token::Plus, start_pos)),
|
||||||
|
|
||||||
('-', '0'..='9') if !state.next_token_cannot_be_unary => negated = Some(start_pos),
|
('-', '0'..='9') if !state.next_token_cannot_be_unary => negated = Some(start_pos),
|
||||||
('-', '0'..='9') => return Some((Token::Minus, start_pos)),
|
('-', '0'..='9') => return Some((Token::Minus, start_pos)),
|
||||||
@ -1716,10 +1716,10 @@ fn get_next_token_inner(
|
|||||||
eat_next(stream, pos);
|
eat_next(stream, pos);
|
||||||
return Some((Token::Reserved("--".into()), start_pos));
|
return Some((Token::Reserved("--".into()), start_pos));
|
||||||
}
|
}
|
||||||
('-', _) if !state.next_token_cannot_be_unary => {
|
('-', ..) if !state.next_token_cannot_be_unary => {
|
||||||
return Some((Token::UnaryMinus, start_pos))
|
return Some((Token::UnaryMinus, start_pos))
|
||||||
}
|
}
|
||||||
('-', _) => return Some((Token::Minus, start_pos)),
|
('-', ..) => return Some((Token::Minus, start_pos)),
|
||||||
|
|
||||||
('*', ')') => {
|
('*', ')') => {
|
||||||
eat_next(stream, pos);
|
eat_next(stream, pos);
|
||||||
@ -1742,7 +1742,7 @@ fn get_next_token_inner(
|
|||||||
start_pos,
|
start_pos,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
('*', _) => return Some((Token::Multiply, start_pos)),
|
('*', ..) => return Some((Token::Multiply, start_pos)),
|
||||||
|
|
||||||
// Comments
|
// Comments
|
||||||
('/', '/') => {
|
('/', '/') => {
|
||||||
@ -1819,10 +1819,10 @@ fn get_next_token_inner(
|
|||||||
eat_next(stream, pos);
|
eat_next(stream, pos);
|
||||||
return Some((Token::DivideAssign, start_pos));
|
return Some((Token::DivideAssign, start_pos));
|
||||||
}
|
}
|
||||||
('/', _) => return Some((Token::Divide, start_pos)),
|
('/', ..) => return Some((Token::Divide, start_pos)),
|
||||||
|
|
||||||
(';', _) => return Some((Token::SemiColon, start_pos)),
|
(';', ..) => return Some((Token::SemiColon, start_pos)),
|
||||||
(',', _) => return Some((Token::Comma, start_pos)),
|
(',', ..) => return Some((Token::Comma, start_pos)),
|
||||||
|
|
||||||
('.', '.') => {
|
('.', '.') => {
|
||||||
eat_next(stream, pos);
|
eat_next(stream, pos);
|
||||||
@ -1841,7 +1841,7 @@ fn get_next_token_inner(
|
|||||||
start_pos,
|
start_pos,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
('.', _) => return Some((Token::Period, start_pos)),
|
('.', ..) => return Some((Token::Period, start_pos)),
|
||||||
|
|
||||||
('=', '=') => {
|
('=', '=') => {
|
||||||
eat_next(stream, pos);
|
eat_next(stream, pos);
|
||||||
@ -1857,7 +1857,7 @@ fn get_next_token_inner(
|
|||||||
eat_next(stream, pos);
|
eat_next(stream, pos);
|
||||||
return Some((Token::DoubleArrow, start_pos));
|
return Some((Token::DoubleArrow, start_pos));
|
||||||
}
|
}
|
||||||
('=', _) => return Some((Token::Equals, start_pos)),
|
('=', ..) => return Some((Token::Equals, start_pos)),
|
||||||
|
|
||||||
#[cfg(not(feature = "no_module"))]
|
#[cfg(not(feature = "no_module"))]
|
||||||
(':', ':') => {
|
(':', ':') => {
|
||||||
@ -1878,7 +1878,7 @@ fn get_next_token_inner(
|
|||||||
eat_next(stream, pos);
|
eat_next(stream, pos);
|
||||||
return Some((Token::Reserved(":;".into()), start_pos));
|
return Some((Token::Reserved(":;".into()), start_pos));
|
||||||
}
|
}
|
||||||
(':', _) => return Some((Token::Colon, start_pos)),
|
(':', ..) => return Some((Token::Colon, start_pos)),
|
||||||
|
|
||||||
('<', '=') => {
|
('<', '=') => {
|
||||||
eat_next(stream, pos);
|
eat_next(stream, pos);
|
||||||
@ -1901,7 +1901,7 @@ fn get_next_token_inner(
|
|||||||
start_pos,
|
start_pos,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
('<', _) => return Some((Token::LessThan, start_pos)),
|
('<', ..) => return Some((Token::LessThan, start_pos)),
|
||||||
|
|
||||||
('>', '=') => {
|
('>', '=') => {
|
||||||
eat_next(stream, pos);
|
eat_next(stream, pos);
|
||||||
@ -1920,7 +1920,7 @@ fn get_next_token_inner(
|
|||||||
start_pos,
|
start_pos,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
('>', _) => return Some((Token::GreaterThan, start_pos)),
|
('>', ..) => return Some((Token::GreaterThan, start_pos)),
|
||||||
|
|
||||||
('!', '=') => {
|
('!', '=') => {
|
||||||
eat_next(stream, pos);
|
eat_next(stream, pos);
|
||||||
@ -1932,7 +1932,7 @@ fn get_next_token_inner(
|
|||||||
|
|
||||||
return Some((Token::NotEqualsTo, start_pos));
|
return Some((Token::NotEqualsTo, start_pos));
|
||||||
}
|
}
|
||||||
('!', _) => return Some((Token::Bang, start_pos)),
|
('!', ..) => return Some((Token::Bang, start_pos)),
|
||||||
|
|
||||||
('|', '|') => {
|
('|', '|') => {
|
||||||
eat_next(stream, pos);
|
eat_next(stream, pos);
|
||||||
@ -1942,7 +1942,7 @@ fn get_next_token_inner(
|
|||||||
eat_next(stream, pos);
|
eat_next(stream, pos);
|
||||||
return Some((Token::OrAssign, start_pos));
|
return Some((Token::OrAssign, start_pos));
|
||||||
}
|
}
|
||||||
('|', _) => return Some((Token::Pipe, start_pos)),
|
('|', ..) => return Some((Token::Pipe, start_pos)),
|
||||||
|
|
||||||
('&', '&') => {
|
('&', '&') => {
|
||||||
eat_next(stream, pos);
|
eat_next(stream, pos);
|
||||||
@ -1952,29 +1952,29 @@ fn get_next_token_inner(
|
|||||||
eat_next(stream, pos);
|
eat_next(stream, pos);
|
||||||
return Some((Token::AndAssign, start_pos));
|
return Some((Token::AndAssign, start_pos));
|
||||||
}
|
}
|
||||||
('&', _) => return Some((Token::Ampersand, start_pos)),
|
('&', ..) => return Some((Token::Ampersand, start_pos)),
|
||||||
|
|
||||||
('^', '=') => {
|
('^', '=') => {
|
||||||
eat_next(stream, pos);
|
eat_next(stream, pos);
|
||||||
return Some((Token::XOrAssign, start_pos));
|
return Some((Token::XOrAssign, start_pos));
|
||||||
}
|
}
|
||||||
('^', _) => return Some((Token::XOr, start_pos)),
|
('^', ..) => return Some((Token::XOr, start_pos)),
|
||||||
|
|
||||||
('~', _) => return Some((Token::Reserved("~".into()), start_pos)),
|
('~', ..) => return Some((Token::Reserved("~".into()), start_pos)),
|
||||||
|
|
||||||
('%', '=') => {
|
('%', '=') => {
|
||||||
eat_next(stream, pos);
|
eat_next(stream, pos);
|
||||||
return Some((Token::ModuloAssign, start_pos));
|
return Some((Token::ModuloAssign, start_pos));
|
||||||
}
|
}
|
||||||
('%', _) => return Some((Token::Modulo, start_pos)),
|
('%', ..) => return Some((Token::Modulo, start_pos)),
|
||||||
|
|
||||||
('@', _) => return Some((Token::Reserved("@".into()), start_pos)),
|
('@', ..) => return Some((Token::Reserved("@".into()), start_pos)),
|
||||||
|
|
||||||
('$', _) => return Some((Token::Reserved("$".into()), start_pos)),
|
('$', ..) => return Some((Token::Reserved("$".into()), start_pos)),
|
||||||
|
|
||||||
(ch, _) if ch.is_whitespace() => (),
|
(ch, ..) if ch.is_whitespace() => (),
|
||||||
|
|
||||||
(ch, _) => {
|
(ch, ..) => {
|
||||||
return Some((
|
return Some((
|
||||||
Token::LexError(LERR::UnexpectedInput(ch.to_string())),
|
Token::LexError(LERR::UnexpectedInput(ch.to_string())),
|
||||||
start_pos,
|
start_pos,
|
||||||
@ -2232,14 +2232,14 @@ impl<'a> Iterator for TokenIterator<'a> {
|
|||||||
"'#' is not a valid symbol. Should it be '#{'?".to_string(),
|
"'#' is not a valid symbol. Should it be '#{'?".to_string(),
|
||||||
)),
|
)),
|
||||||
// Reserved keyword/operator that is custom.
|
// Reserved keyword/operator that is custom.
|
||||||
(_, true) => Token::Custom(s),
|
(.., true) => Token::Custom(s),
|
||||||
// Reserved keyword that is not custom and disabled.
|
// Reserved keyword that is not custom and disabled.
|
||||||
(token, false) if self.engine.disabled_symbols.contains(token) => {
|
(token, false) if self.engine.disabled_symbols.contains(token) => {
|
||||||
let msg = format!("reserved {} '{}' is disabled", if is_valid_identifier(token.chars()) { "keyword"} else {"symbol"}, token);
|
let msg = format!("reserved {} '{}' is disabled", if is_valid_identifier(token.chars()) { "keyword"} else {"symbol"}, token);
|
||||||
Token::LexError(LERR::ImproperSymbol(s.to_string(), msg))
|
Token::LexError(LERR::ImproperSymbol(s.to_string(), msg))
|
||||||
},
|
},
|
||||||
// Reserved keyword/operator that is not custom.
|
// Reserved keyword/operator that is not custom.
|
||||||
(_, false) => Token::Reserved(s),
|
(.., false) => Token::Reserved(s),
|
||||||
}, pos),
|
}, pos),
|
||||||
// Custom keyword
|
// Custom keyword
|
||||||
Some((Token::Identifier(s), pos)) if self.engine.custom_keywords.contains_key(&*s) => {
|
Some((Token::Identifier(s), pos)) if self.engine.custom_keywords.contains_key(&*s) => {
|
||||||
|
@ -344,7 +344,7 @@ impl Dynamic {
|
|||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub const fn is_variant(&self) -> bool {
|
pub const fn is_variant(&self) -> bool {
|
||||||
matches!(self.0, Union::Variant(_, _, _))
|
matches!(self.0, Union::Variant(..))
|
||||||
}
|
}
|
||||||
/// Is the value held by this [`Dynamic`] shared?
|
/// Is the value held by this [`Dynamic`] shared?
|
||||||
///
|
///
|
||||||
@ -354,7 +354,7 @@ impl Dynamic {
|
|||||||
#[must_use]
|
#[must_use]
|
||||||
pub const fn is_shared(&self) -> bool {
|
pub const fn is_shared(&self) -> bool {
|
||||||
#[cfg(not(feature = "no_closure"))]
|
#[cfg(not(feature = "no_closure"))]
|
||||||
return matches!(self.0, Union::Shared(_, _, _));
|
return matches!(self.0, Union::Shared(..));
|
||||||
#[cfg(feature = "no_closure")]
|
#[cfg(feature = "no_closure")]
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -380,34 +380,34 @@ impl Dynamic {
|
|||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn type_id(&self) -> TypeId {
|
pub fn type_id(&self) -> TypeId {
|
||||||
match self.0 {
|
match self.0 {
|
||||||
Union::Unit(_, _, _) => TypeId::of::<()>(),
|
Union::Unit(..) => TypeId::of::<()>(),
|
||||||
Union::Bool(_, _, _) => TypeId::of::<bool>(),
|
Union::Bool(..) => TypeId::of::<bool>(),
|
||||||
Union::Str(_, _, _) => TypeId::of::<ImmutableString>(),
|
Union::Str(..) => TypeId::of::<ImmutableString>(),
|
||||||
Union::Char(_, _, _) => TypeId::of::<char>(),
|
Union::Char(..) => TypeId::of::<char>(),
|
||||||
Union::Int(_, _, _) => TypeId::of::<INT>(),
|
Union::Int(..) => TypeId::of::<INT>(),
|
||||||
#[cfg(not(feature = "no_float"))]
|
#[cfg(not(feature = "no_float"))]
|
||||||
Union::Float(_, _, _) => TypeId::of::<crate::FLOAT>(),
|
Union::Float(..) => TypeId::of::<crate::FLOAT>(),
|
||||||
#[cfg(feature = "decimal")]
|
#[cfg(feature = "decimal")]
|
||||||
Union::Decimal(_, _, _) => TypeId::of::<rust_decimal::Decimal>(),
|
Union::Decimal(..) => TypeId::of::<rust_decimal::Decimal>(),
|
||||||
#[cfg(not(feature = "no_index"))]
|
#[cfg(not(feature = "no_index"))]
|
||||||
Union::Array(_, _, _) => TypeId::of::<crate::Array>(),
|
Union::Array(..) => TypeId::of::<crate::Array>(),
|
||||||
#[cfg(not(feature = "no_index"))]
|
#[cfg(not(feature = "no_index"))]
|
||||||
Union::Blob(_, _, _) => TypeId::of::<crate::Blob>(),
|
Union::Blob(..) => TypeId::of::<crate::Blob>(),
|
||||||
#[cfg(not(feature = "no_object"))]
|
#[cfg(not(feature = "no_object"))]
|
||||||
Union::Map(_, _, _) => TypeId::of::<crate::Map>(),
|
Union::Map(..) => TypeId::of::<crate::Map>(),
|
||||||
Union::FnPtr(_, _, _) => TypeId::of::<FnPtr>(),
|
Union::FnPtr(..) => TypeId::of::<FnPtr>(),
|
||||||
#[cfg(not(feature = "no_std"))]
|
#[cfg(not(feature = "no_std"))]
|
||||||
Union::TimeStamp(_, _, _) => TypeId::of::<Instant>(),
|
Union::TimeStamp(..) => TypeId::of::<Instant>(),
|
||||||
|
|
||||||
Union::Variant(ref v, _, _) => (***v).type_id(),
|
Union::Variant(ref v, _, ..) => (***v).type_id(),
|
||||||
|
|
||||||
#[cfg(not(feature = "no_closure"))]
|
#[cfg(not(feature = "no_closure"))]
|
||||||
#[cfg(not(feature = "sync"))]
|
#[cfg(not(feature = "sync"))]
|
||||||
Union::Shared(ref cell, _, _) => (*cell.borrow()).type_id(),
|
Union::Shared(ref cell, _, ..) => (*cell.borrow()).type_id(),
|
||||||
|
|
||||||
#[cfg(not(feature = "no_closure"))]
|
#[cfg(not(feature = "no_closure"))]
|
||||||
#[cfg(feature = "sync")]
|
#[cfg(feature = "sync")]
|
||||||
Union::Shared(ref cell, _, _) => (*cell.read().unwrap()).type_id(),
|
Union::Shared(ref cell, _, ..) => (*cell.read().unwrap()).type_id(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/// Get the name of the type of the value held by this [`Dynamic`].
|
/// Get the name of the type of the value held by this [`Dynamic`].
|
||||||
@ -419,36 +419,36 @@ impl Dynamic {
|
|||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn type_name(&self) -> &'static str {
|
pub fn type_name(&self) -> &'static str {
|
||||||
match self.0 {
|
match self.0 {
|
||||||
Union::Unit(_, _, _) => "()",
|
Union::Unit(..) => "()",
|
||||||
Union::Bool(_, _, _) => "bool",
|
Union::Bool(..) => "bool",
|
||||||
Union::Str(_, _, _) => "string",
|
Union::Str(..) => "string",
|
||||||
Union::Char(_, _, _) => "char",
|
Union::Char(..) => "char",
|
||||||
Union::Int(_, _, _) => type_name::<INT>(),
|
Union::Int(..) => type_name::<INT>(),
|
||||||
#[cfg(not(feature = "no_float"))]
|
#[cfg(not(feature = "no_float"))]
|
||||||
Union::Float(_, _, _) => type_name::<crate::FLOAT>(),
|
Union::Float(..) => type_name::<crate::FLOAT>(),
|
||||||
#[cfg(feature = "decimal")]
|
#[cfg(feature = "decimal")]
|
||||||
Union::Decimal(_, _, _) => "decimal",
|
Union::Decimal(..) => "decimal",
|
||||||
#[cfg(not(feature = "no_index"))]
|
#[cfg(not(feature = "no_index"))]
|
||||||
Union::Array(_, _, _) => "array",
|
Union::Array(..) => "array",
|
||||||
#[cfg(not(feature = "no_index"))]
|
#[cfg(not(feature = "no_index"))]
|
||||||
Union::Blob(_, _, _) => "blob",
|
Union::Blob(..) => "blob",
|
||||||
#[cfg(not(feature = "no_object"))]
|
#[cfg(not(feature = "no_object"))]
|
||||||
Union::Map(_, _, _) => "map",
|
Union::Map(..) => "map",
|
||||||
Union::FnPtr(_, _, _) => "Fn",
|
Union::FnPtr(..) => "Fn",
|
||||||
#[cfg(not(feature = "no_std"))]
|
#[cfg(not(feature = "no_std"))]
|
||||||
Union::TimeStamp(_, _, _) => "timestamp",
|
Union::TimeStamp(..) => "timestamp",
|
||||||
|
|
||||||
Union::Variant(ref v, _, _) => (***v).type_name(),
|
Union::Variant(ref v, _, ..) => (***v).type_name(),
|
||||||
|
|
||||||
#[cfg(not(feature = "no_closure"))]
|
#[cfg(not(feature = "no_closure"))]
|
||||||
#[cfg(not(feature = "sync"))]
|
#[cfg(not(feature = "sync"))]
|
||||||
Union::Shared(ref cell, _, _) => cell
|
Union::Shared(ref cell, _, ..) => cell
|
||||||
.try_borrow()
|
.try_borrow()
|
||||||
.map(|v| (*v).type_name())
|
.map(|v| (*v).type_name())
|
||||||
.unwrap_or("<shared>"),
|
.unwrap_or("<shared>"),
|
||||||
#[cfg(not(feature = "no_closure"))]
|
#[cfg(not(feature = "no_closure"))]
|
||||||
#[cfg(feature = "sync")]
|
#[cfg(feature = "sync")]
|
||||||
Union::Shared(ref cell, _, _) => (*cell.read().unwrap()).type_name(),
|
Union::Shared(ref cell, _, ..) => (*cell.read().unwrap()).type_name(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -463,32 +463,32 @@ impl Hash for Dynamic {
|
|||||||
mem::discriminant(&self.0).hash(state);
|
mem::discriminant(&self.0).hash(state);
|
||||||
|
|
||||||
match self.0 {
|
match self.0 {
|
||||||
Union::Unit(_, _, _) => ().hash(state),
|
Union::Unit(..) => ().hash(state),
|
||||||
Union::Bool(ref b, _, _) => b.hash(state),
|
Union::Bool(ref b, _, ..) => b.hash(state),
|
||||||
Union::Str(ref s, _, _) => s.hash(state),
|
Union::Str(ref s, _, ..) => s.hash(state),
|
||||||
Union::Char(ref c, _, _) => c.hash(state),
|
Union::Char(ref c, _, ..) => c.hash(state),
|
||||||
Union::Int(ref i, _, _) => i.hash(state),
|
Union::Int(ref i, _, ..) => i.hash(state),
|
||||||
#[cfg(not(feature = "no_float"))]
|
#[cfg(not(feature = "no_float"))]
|
||||||
Union::Float(ref f, _, _) => f.hash(state),
|
Union::Float(ref f, _, ..) => f.hash(state),
|
||||||
#[cfg(feature = "decimal")]
|
#[cfg(feature = "decimal")]
|
||||||
Union::Decimal(ref d, _, _) => d.hash(state),
|
Union::Decimal(ref d, _, ..) => d.hash(state),
|
||||||
#[cfg(not(feature = "no_index"))]
|
#[cfg(not(feature = "no_index"))]
|
||||||
Union::Array(ref a, _, _) => a.as_ref().hash(state),
|
Union::Array(ref a, _, ..) => a.as_ref().hash(state),
|
||||||
#[cfg(not(feature = "no_index"))]
|
#[cfg(not(feature = "no_index"))]
|
||||||
Union::Blob(ref a, _, _) => a.as_ref().hash(state),
|
Union::Blob(ref a, _, ..) => a.as_ref().hash(state),
|
||||||
#[cfg(not(feature = "no_object"))]
|
#[cfg(not(feature = "no_object"))]
|
||||||
Union::Map(ref m, _, _) => m.as_ref().hash(state),
|
Union::Map(ref m, _, ..) => m.as_ref().hash(state),
|
||||||
Union::FnPtr(ref f, _, _) => f.hash(state),
|
Union::FnPtr(ref f, _, ..) => f.hash(state),
|
||||||
|
|
||||||
#[cfg(not(feature = "no_closure"))]
|
#[cfg(not(feature = "no_closure"))]
|
||||||
#[cfg(not(feature = "sync"))]
|
#[cfg(not(feature = "sync"))]
|
||||||
Union::Shared(ref cell, _, _) => (*cell.borrow()).hash(state),
|
Union::Shared(ref cell, _, ..) => (*cell.borrow()).hash(state),
|
||||||
|
|
||||||
#[cfg(not(feature = "no_closure"))]
|
#[cfg(not(feature = "no_closure"))]
|
||||||
#[cfg(feature = "sync")]
|
#[cfg(feature = "sync")]
|
||||||
Union::Shared(ref cell, _, _) => (*cell.read().unwrap()).hash(state),
|
Union::Shared(ref cell, _, ..) => (*cell.read().unwrap()).hash(state),
|
||||||
|
|
||||||
Union::Variant(ref v, _, _) => {
|
Union::Variant(ref v, _, ..) => {
|
||||||
let _v = v;
|
let _v = v;
|
||||||
|
|
||||||
#[cfg(not(feature = "only_i32"))]
|
#[cfg(not(feature = "only_i32"))]
|
||||||
@ -537,7 +537,7 @@ impl Hash for Dynamic {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(feature = "no_std"))]
|
#[cfg(not(feature = "no_std"))]
|
||||||
Union::TimeStamp(_, _, _) => unimplemented!("{} cannot be hashed", self.type_name()),
|
Union::TimeStamp(..) => unimplemented!("{} cannot be hashed", self.type_name()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -545,26 +545,26 @@ impl Hash for Dynamic {
|
|||||||
impl fmt::Display for Dynamic {
|
impl fmt::Display for Dynamic {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
match self.0 {
|
match self.0 {
|
||||||
Union::Unit(_, _, _) => write!(f, ""),
|
Union::Unit(..) => write!(f, ""),
|
||||||
Union::Bool(ref v, _, _) => fmt::Display::fmt(v, f),
|
Union::Bool(ref v, _, ..) => fmt::Display::fmt(v, f),
|
||||||
Union::Str(ref v, _, _) => fmt::Display::fmt(v, f),
|
Union::Str(ref v, _, ..) => fmt::Display::fmt(v, f),
|
||||||
Union::Char(ref v, _, _) => fmt::Display::fmt(v, f),
|
Union::Char(ref v, _, ..) => fmt::Display::fmt(v, f),
|
||||||
Union::Int(ref v, _, _) => fmt::Display::fmt(v, f),
|
Union::Int(ref v, _, ..) => fmt::Display::fmt(v, f),
|
||||||
#[cfg(not(feature = "no_float"))]
|
#[cfg(not(feature = "no_float"))]
|
||||||
Union::Float(ref v, _, _) => fmt::Display::fmt(v, f),
|
Union::Float(ref v, _, ..) => fmt::Display::fmt(v, f),
|
||||||
#[cfg(feature = "decimal")]
|
#[cfg(feature = "decimal")]
|
||||||
Union::Decimal(ref v, _, _) => fmt::Display::fmt(v, f),
|
Union::Decimal(ref v, _, ..) => fmt::Display::fmt(v, f),
|
||||||
#[cfg(not(feature = "no_index"))]
|
#[cfg(not(feature = "no_index"))]
|
||||||
Union::Array(_, _, _) => fmt::Debug::fmt(self, f),
|
Union::Array(..) => fmt::Debug::fmt(self, f),
|
||||||
#[cfg(not(feature = "no_index"))]
|
#[cfg(not(feature = "no_index"))]
|
||||||
Union::Blob(_, _, _) => fmt::Debug::fmt(self, f),
|
Union::Blob(..) => fmt::Debug::fmt(self, f),
|
||||||
#[cfg(not(feature = "no_object"))]
|
#[cfg(not(feature = "no_object"))]
|
||||||
Union::Map(_, _, _) => fmt::Debug::fmt(self, f),
|
Union::Map(..) => fmt::Debug::fmt(self, f),
|
||||||
Union::FnPtr(ref v, _, _) => fmt::Display::fmt(v, f),
|
Union::FnPtr(ref v, _, ..) => fmt::Display::fmt(v, f),
|
||||||
#[cfg(not(feature = "no_std"))]
|
#[cfg(not(feature = "no_std"))]
|
||||||
Union::TimeStamp(_, _, _) => f.write_str("<timestamp>"),
|
Union::TimeStamp(..) => f.write_str("<timestamp>"),
|
||||||
|
|
||||||
Union::Variant(ref v, _, _) => {
|
Union::Variant(ref v, _, ..) => {
|
||||||
let _value_any = (***v).as_any();
|
let _value_any = (***v).as_any();
|
||||||
let _type_id = _value_any.type_id();
|
let _type_id = _value_any.type_id();
|
||||||
|
|
||||||
@ -621,7 +621,7 @@ impl fmt::Display for Dynamic {
|
|||||||
|
|
||||||
#[cfg(not(feature = "no_closure"))]
|
#[cfg(not(feature = "no_closure"))]
|
||||||
#[cfg(not(feature = "sync"))]
|
#[cfg(not(feature = "sync"))]
|
||||||
Union::Shared(ref cell, _, _) => {
|
Union::Shared(ref cell, _, ..) => {
|
||||||
if let Ok(v) = cell.try_borrow() {
|
if let Ok(v) = cell.try_borrow() {
|
||||||
fmt::Display::fmt(&*v, f)
|
fmt::Display::fmt(&*v, f)
|
||||||
} else {
|
} else {
|
||||||
@ -630,7 +630,7 @@ impl fmt::Display for Dynamic {
|
|||||||
}
|
}
|
||||||
#[cfg(not(feature = "no_closure"))]
|
#[cfg(not(feature = "no_closure"))]
|
||||||
#[cfg(feature = "sync")]
|
#[cfg(feature = "sync")]
|
||||||
Union::Shared(ref cell, _, _) => fmt::Display::fmt(&*cell.read().unwrap(), f),
|
Union::Shared(ref cell, _, ..) => fmt::Display::fmt(&*cell.read().unwrap(), f),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -638,19 +638,19 @@ impl fmt::Display for Dynamic {
|
|||||||
impl fmt::Debug for Dynamic {
|
impl fmt::Debug for Dynamic {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
match self.0 {
|
match self.0 {
|
||||||
Union::Unit(ref v, _, _) => fmt::Debug::fmt(v, f),
|
Union::Unit(ref v, _, ..) => fmt::Debug::fmt(v, f),
|
||||||
Union::Bool(ref v, _, _) => fmt::Debug::fmt(v, f),
|
Union::Bool(ref v, _, ..) => fmt::Debug::fmt(v, f),
|
||||||
Union::Str(ref v, _, _) => fmt::Debug::fmt(v, f),
|
Union::Str(ref v, _, ..) => fmt::Debug::fmt(v, f),
|
||||||
Union::Char(ref v, _, _) => fmt::Debug::fmt(v, f),
|
Union::Char(ref v, _, ..) => fmt::Debug::fmt(v, f),
|
||||||
Union::Int(ref v, _, _) => fmt::Debug::fmt(v, f),
|
Union::Int(ref v, _, ..) => fmt::Debug::fmt(v, f),
|
||||||
#[cfg(not(feature = "no_float"))]
|
#[cfg(not(feature = "no_float"))]
|
||||||
Union::Float(ref v, _, _) => fmt::Debug::fmt(v, f),
|
Union::Float(ref v, _, ..) => fmt::Debug::fmt(v, f),
|
||||||
#[cfg(feature = "decimal")]
|
#[cfg(feature = "decimal")]
|
||||||
Union::Decimal(ref v, _, _) => fmt::Debug::fmt(v, f),
|
Union::Decimal(ref v, _, ..) => fmt::Debug::fmt(v, f),
|
||||||
#[cfg(not(feature = "no_index"))]
|
#[cfg(not(feature = "no_index"))]
|
||||||
Union::Array(ref v, _, _) => fmt::Debug::fmt(v, f),
|
Union::Array(ref v, _, ..) => fmt::Debug::fmt(v, f),
|
||||||
#[cfg(not(feature = "no_index"))]
|
#[cfg(not(feature = "no_index"))]
|
||||||
Union::Blob(ref v, _, _) => {
|
Union::Blob(ref v, _, ..) => {
|
||||||
f.write_str("[")?;
|
f.write_str("[")?;
|
||||||
v.iter().enumerate().try_for_each(|(i, v)| {
|
v.iter().enumerate().try_for_each(|(i, v)| {
|
||||||
if i > 0 && i % 8 == 0 {
|
if i > 0 && i % 8 == 0 {
|
||||||
@ -661,15 +661,15 @@ impl fmt::Debug for Dynamic {
|
|||||||
f.write_str("]")
|
f.write_str("]")
|
||||||
}
|
}
|
||||||
#[cfg(not(feature = "no_object"))]
|
#[cfg(not(feature = "no_object"))]
|
||||||
Union::Map(ref v, _, _) => {
|
Union::Map(ref v, _, ..) => {
|
||||||
f.write_str("#")?;
|
f.write_str("#")?;
|
||||||
fmt::Debug::fmt(v, f)
|
fmt::Debug::fmt(v, f)
|
||||||
}
|
}
|
||||||
Union::FnPtr(ref v, _, _) => fmt::Debug::fmt(v, f),
|
Union::FnPtr(ref v, _, ..) => fmt::Debug::fmt(v, f),
|
||||||
#[cfg(not(feature = "no_std"))]
|
#[cfg(not(feature = "no_std"))]
|
||||||
Union::TimeStamp(_, _, _) => write!(f, "<timestamp>"),
|
Union::TimeStamp(..) => write!(f, "<timestamp>"),
|
||||||
|
|
||||||
Union::Variant(ref v, _, _) => {
|
Union::Variant(ref v, _, ..) => {
|
||||||
let _value_any = (***v).as_any();
|
let _value_any = (***v).as_any();
|
||||||
let _type_id = _value_any.type_id();
|
let _type_id = _value_any.type_id();
|
||||||
|
|
||||||
@ -726,7 +726,7 @@ impl fmt::Debug for Dynamic {
|
|||||||
|
|
||||||
#[cfg(not(feature = "no_closure"))]
|
#[cfg(not(feature = "no_closure"))]
|
||||||
#[cfg(not(feature = "sync"))]
|
#[cfg(not(feature = "sync"))]
|
||||||
Union::Shared(ref cell, _, _) => {
|
Union::Shared(ref cell, _, ..) => {
|
||||||
if let Ok(v) = cell.try_borrow() {
|
if let Ok(v) = cell.try_borrow() {
|
||||||
write!(f, "{:?} (shared)", *v)
|
write!(f, "{:?} (shared)", *v)
|
||||||
} else {
|
} else {
|
||||||
@ -735,7 +735,7 @@ impl fmt::Debug for Dynamic {
|
|||||||
}
|
}
|
||||||
#[cfg(not(feature = "no_closure"))]
|
#[cfg(not(feature = "no_closure"))]
|
||||||
#[cfg(feature = "sync")]
|
#[cfg(feature = "sync")]
|
||||||
Union::Shared(ref cell, _, _) => fmt::Debug::fmt(&*cell.read().unwrap(), f),
|
Union::Shared(ref cell, _, ..) => fmt::Debug::fmt(&*cell.read().unwrap(), f),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -750,33 +750,33 @@ impl Clone for Dynamic {
|
|||||||
/// The cloned copy is marked read-write even if the original is read-only.
|
/// The cloned copy is marked read-write even if the original is read-only.
|
||||||
fn clone(&self) -> Self {
|
fn clone(&self) -> Self {
|
||||||
match self.0 {
|
match self.0 {
|
||||||
Union::Unit(v, tag, _) => Self(Union::Unit(v, tag, ReadWrite)),
|
Union::Unit(v, tag, ..) => Self(Union::Unit(v, tag, ReadWrite)),
|
||||||
Union::Bool(v, tag, _) => Self(Union::Bool(v, tag, ReadWrite)),
|
Union::Bool(v, tag, ..) => Self(Union::Bool(v, tag, ReadWrite)),
|
||||||
Union::Str(ref v, tag, _) => Self(Union::Str(v.clone(), tag, ReadWrite)),
|
Union::Str(ref v, tag, ..) => Self(Union::Str(v.clone(), tag, ReadWrite)),
|
||||||
Union::Char(v, tag, _) => Self(Union::Char(v, tag, ReadWrite)),
|
Union::Char(v, tag, ..) => Self(Union::Char(v, tag, ReadWrite)),
|
||||||
Union::Int(v, tag, _) => Self(Union::Int(v, tag, ReadWrite)),
|
Union::Int(v, tag, ..) => Self(Union::Int(v, tag, ReadWrite)),
|
||||||
#[cfg(not(feature = "no_float"))]
|
#[cfg(not(feature = "no_float"))]
|
||||||
Union::Float(v, tag, _) => Self(Union::Float(v, tag, ReadWrite)),
|
Union::Float(v, tag, ..) => Self(Union::Float(v, tag, ReadWrite)),
|
||||||
#[cfg(feature = "decimal")]
|
#[cfg(feature = "decimal")]
|
||||||
Union::Decimal(ref v, tag, _) => Self(Union::Decimal(v.clone(), tag, ReadWrite)),
|
Union::Decimal(ref v, tag, ..) => Self(Union::Decimal(v.clone(), tag, ReadWrite)),
|
||||||
#[cfg(not(feature = "no_index"))]
|
#[cfg(not(feature = "no_index"))]
|
||||||
Union::Array(ref v, tag, _) => Self(Union::Array(v.clone(), tag, ReadWrite)),
|
Union::Array(ref v, tag, ..) => Self(Union::Array(v.clone(), tag, ReadWrite)),
|
||||||
#[cfg(not(feature = "no_index"))]
|
#[cfg(not(feature = "no_index"))]
|
||||||
Union::Blob(ref v, tag, _) => Self(Union::Blob(v.clone(), tag, ReadWrite)),
|
Union::Blob(ref v, tag, ..) => Self(Union::Blob(v.clone(), tag, ReadWrite)),
|
||||||
#[cfg(not(feature = "no_object"))]
|
#[cfg(not(feature = "no_object"))]
|
||||||
Union::Map(ref v, tag, _) => Self(Union::Map(v.clone(), tag, ReadWrite)),
|
Union::Map(ref v, tag, ..) => Self(Union::Map(v.clone(), tag, ReadWrite)),
|
||||||
Union::FnPtr(ref v, tag, _) => Self(Union::FnPtr(v.clone(), tag, ReadWrite)),
|
Union::FnPtr(ref v, tag, ..) => Self(Union::FnPtr(v.clone(), tag, ReadWrite)),
|
||||||
#[cfg(not(feature = "no_std"))]
|
#[cfg(not(feature = "no_std"))]
|
||||||
Union::TimeStamp(ref v, tag, _) => Self(Union::TimeStamp(v.clone(), tag, ReadWrite)),
|
Union::TimeStamp(ref v, tag, ..) => Self(Union::TimeStamp(v.clone(), tag, ReadWrite)),
|
||||||
|
|
||||||
Union::Variant(ref v, tag, _) => Self(Union::Variant(
|
Union::Variant(ref v, tag, ..) => Self(Union::Variant(
|
||||||
v.as_ref().as_ref().clone_object().into(),
|
v.as_ref().as_ref().clone_object().into(),
|
||||||
tag,
|
tag,
|
||||||
ReadWrite,
|
ReadWrite,
|
||||||
)),
|
)),
|
||||||
|
|
||||||
#[cfg(not(feature = "no_closure"))]
|
#[cfg(not(feature = "no_closure"))]
|
||||||
Union::Shared(ref cell, tag, _) => Self(Union::Shared(cell.clone(), tag, ReadWrite)),
|
Union::Shared(ref cell, tag, ..) => Self(Union::Shared(cell.clone(), tag, ReadWrite)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1010,43 +1010,43 @@ impl Dynamic {
|
|||||||
#[must_use]
|
#[must_use]
|
||||||
pub(crate) const fn access_mode(&self) -> AccessMode {
|
pub(crate) const fn access_mode(&self) -> AccessMode {
|
||||||
match self.0 {
|
match self.0 {
|
||||||
Union::Unit(_, _, access)
|
Union::Unit(.., _, access)
|
||||||
| Union::Bool(_, _, access)
|
| Union::Bool(.., _, access)
|
||||||
| Union::Str(_, _, access)
|
| Union::Str(.., _, access)
|
||||||
| Union::Char(_, _, access)
|
| Union::Char(.., _, access)
|
||||||
| Union::Int(_, _, access)
|
| Union::Int(.., _, access)
|
||||||
| Union::FnPtr(_, _, access)
|
| Union::FnPtr(.., _, access)
|
||||||
| Union::Variant(_, _, access) => access,
|
| Union::Variant(.., _, access) => access,
|
||||||
|
|
||||||
#[cfg(not(feature = "no_float"))]
|
#[cfg(not(feature = "no_float"))]
|
||||||
Union::Float(_, _, access) => access,
|
Union::Float(.., _, access) => access,
|
||||||
#[cfg(feature = "decimal")]
|
#[cfg(feature = "decimal")]
|
||||||
Union::Decimal(_, _, access) => access,
|
Union::Decimal(.., _, access) => access,
|
||||||
#[cfg(not(feature = "no_index"))]
|
#[cfg(not(feature = "no_index"))]
|
||||||
Union::Array(_, _, access) | Union::Blob(_, _, access) => access,
|
Union::Array(.., _, access) | Union::Blob(.., _, access) => access,
|
||||||
#[cfg(not(feature = "no_object"))]
|
#[cfg(not(feature = "no_object"))]
|
||||||
Union::Map(_, _, access) => access,
|
Union::Map(.., _, access) => access,
|
||||||
#[cfg(not(feature = "no_std"))]
|
#[cfg(not(feature = "no_std"))]
|
||||||
Union::TimeStamp(_, _, access) => access,
|
Union::TimeStamp(.., _, access) => access,
|
||||||
#[cfg(not(feature = "no_closure"))]
|
#[cfg(not(feature = "no_closure"))]
|
||||||
Union::Shared(_, _, access) => access,
|
Union::Shared(.., _, access) => access,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/// Set the [`AccessMode`] for this [`Dynamic`].
|
/// Set the [`AccessMode`] for this [`Dynamic`].
|
||||||
pub(crate) fn set_access_mode(&mut self, typ: AccessMode) -> &mut Self {
|
pub(crate) fn set_access_mode(&mut self, typ: AccessMode) -> &mut Self {
|
||||||
match self.0 {
|
match self.0 {
|
||||||
Union::Unit(_, _, ref mut access)
|
Union::Unit(.., _, ref mut access)
|
||||||
| Union::Bool(_, _, ref mut access)
|
| Union::Bool(.., _, ref mut access)
|
||||||
| Union::Str(_, _, ref mut access)
|
| Union::Str(.., _, ref mut access)
|
||||||
| Union::Char(_, _, ref mut access)
|
| Union::Char(.., _, ref mut access)
|
||||||
| Union::Int(_, _, ref mut access)
|
| Union::Int(.., _, ref mut access)
|
||||||
| Union::FnPtr(_, _, ref mut access)
|
| Union::FnPtr(.., _, ref mut access)
|
||||||
| Union::Variant(_, _, ref mut access) => *access = typ,
|
| Union::Variant(.., _, ref mut access) => *access = typ,
|
||||||
|
|
||||||
#[cfg(not(feature = "no_float"))]
|
#[cfg(not(feature = "no_float"))]
|
||||||
Union::Float(_, _, ref mut access) => *access = typ,
|
Union::Float(.., _, ref mut access) => *access = typ,
|
||||||
#[cfg(feature = "decimal")]
|
#[cfg(feature = "decimal")]
|
||||||
Union::Decimal(_, _, ref mut access) => *access = typ,
|
Union::Decimal(.., _, ref mut access) => *access = typ,
|
||||||
#[cfg(not(feature = "no_index"))]
|
#[cfg(not(feature = "no_index"))]
|
||||||
Union::Array(ref mut a, _, ref mut access) => {
|
Union::Array(ref mut a, _, ref mut access) => {
|
||||||
*access = typ;
|
*access = typ;
|
||||||
@ -1055,7 +1055,7 @@ impl Dynamic {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#[cfg(not(feature = "no_index"))]
|
#[cfg(not(feature = "no_index"))]
|
||||||
Union::Blob(_, _, ref mut access) => *access = typ,
|
Union::Blob(.., _, ref mut access) => *access = typ,
|
||||||
#[cfg(not(feature = "no_object"))]
|
#[cfg(not(feature = "no_object"))]
|
||||||
Union::Map(ref mut m, _, ref mut access) => {
|
Union::Map(ref mut m, _, ref mut access) => {
|
||||||
*access = typ;
|
*access = typ;
|
||||||
@ -1064,9 +1064,9 @@ impl Dynamic {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#[cfg(not(feature = "no_std"))]
|
#[cfg(not(feature = "no_std"))]
|
||||||
Union::TimeStamp(_, _, ref mut access) => *access = typ,
|
Union::TimeStamp(.., _, ref mut access) => *access = typ,
|
||||||
#[cfg(not(feature = "no_closure"))]
|
#[cfg(not(feature = "no_closure"))]
|
||||||
Union::Shared(_, _, ref mut access) => *access = typ,
|
Union::Shared(.., _, ref mut access) => *access = typ,
|
||||||
}
|
}
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
@ -1081,17 +1081,17 @@ impl Dynamic {
|
|||||||
pub fn is_read_only(&self) -> bool {
|
pub fn is_read_only(&self) -> bool {
|
||||||
#[cfg(not(feature = "no_closure"))]
|
#[cfg(not(feature = "no_closure"))]
|
||||||
match self.0 {
|
match self.0 {
|
||||||
Union::Shared(_, _, ReadOnly) => return true,
|
Union::Shared(.., _, ReadOnly) => return true,
|
||||||
|
|
||||||
#[cfg(not(feature = "sync"))]
|
#[cfg(not(feature = "sync"))]
|
||||||
Union::Shared(ref cell, _, _) => {
|
Union::Shared(ref cell, _, ..) => {
|
||||||
return match cell.borrow().access_mode() {
|
return match cell.borrow().access_mode() {
|
||||||
ReadWrite => false,
|
ReadWrite => false,
|
||||||
ReadOnly => true,
|
ReadOnly => true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#[cfg(feature = "sync")]
|
#[cfg(feature = "sync")]
|
||||||
Union::Shared(ref cell, _, _) => {
|
Union::Shared(ref cell, _, ..) => {
|
||||||
return match cell.read().unwrap().access_mode() {
|
return match cell.read().unwrap().access_mode() {
|
||||||
ReadWrite => false,
|
ReadWrite => false,
|
||||||
ReadOnly => true,
|
ReadOnly => true,
|
||||||
@ -1110,26 +1110,26 @@ impl Dynamic {
|
|||||||
#[must_use]
|
#[must_use]
|
||||||
pub(crate) fn is_hashable(&self) -> bool {
|
pub(crate) fn is_hashable(&self) -> bool {
|
||||||
match self.0 {
|
match self.0 {
|
||||||
Union::Unit(_, _, _)
|
Union::Unit(..)
|
||||||
| Union::Bool(_, _, _)
|
| Union::Bool(..)
|
||||||
| Union::Str(_, _, _)
|
| Union::Str(..)
|
||||||
| Union::Char(_, _, _)
|
| Union::Char(..)
|
||||||
| Union::Int(_, _, _) => true,
|
| Union::Int(..) => true,
|
||||||
|
|
||||||
#[cfg(not(feature = "no_float"))]
|
#[cfg(not(feature = "no_float"))]
|
||||||
Union::Float(_, _, _) => true,
|
Union::Float(..) => true,
|
||||||
#[cfg(not(feature = "no_index"))]
|
#[cfg(not(feature = "no_index"))]
|
||||||
Union::Array(_, _, _) => true,
|
Union::Array(..) => true,
|
||||||
#[cfg(not(feature = "no_object"))]
|
#[cfg(not(feature = "no_object"))]
|
||||||
Union::Map(_, _, _) => true,
|
Union::Map(..) => true,
|
||||||
|
|
||||||
#[cfg(not(feature = "no_closure"))]
|
#[cfg(not(feature = "no_closure"))]
|
||||||
#[cfg(not(feature = "sync"))]
|
#[cfg(not(feature = "sync"))]
|
||||||
Union::Shared(ref cell, _, _) => cell.borrow().is_hashable(),
|
Union::Shared(ref cell, _, ..) => cell.borrow().is_hashable(),
|
||||||
|
|
||||||
#[cfg(not(feature = "no_closure"))]
|
#[cfg(not(feature = "no_closure"))]
|
||||||
#[cfg(feature = "sync")]
|
#[cfg(feature = "sync")]
|
||||||
Union::Shared(ref cell, _, _) => cell.read().unwrap().is_hashable(),
|
Union::Shared(ref cell, _, ..) => cell.read().unwrap().is_hashable(),
|
||||||
|
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
@ -1229,7 +1229,7 @@ impl Dynamic {
|
|||||||
let _access = self.access_mode();
|
let _access = self.access_mode();
|
||||||
|
|
||||||
match self.0 {
|
match self.0 {
|
||||||
Union::Shared(_, _, _) => self,
|
Union::Shared(..) => self,
|
||||||
_ => Self(Union::Shared(
|
_ => Self(Union::Shared(
|
||||||
crate::Locked::new(self).into(),
|
crate::Locked::new(self).into(),
|
||||||
DEFAULT_TAG_VALUE,
|
DEFAULT_TAG_VALUE,
|
||||||
@ -1266,7 +1266,7 @@ impl Dynamic {
|
|||||||
// Coded this way in order to maximally leverage potentials for dead-code removal.
|
// Coded this way in order to maximally leverage potentials for dead-code removal.
|
||||||
|
|
||||||
#[cfg(not(feature = "no_closure"))]
|
#[cfg(not(feature = "no_closure"))]
|
||||||
if let Union::Shared(_, _, _) = self.0 {
|
if let Union::Shared(..) = self.0 {
|
||||||
return self.flatten().try_cast::<T>();
|
return self.flatten().try_cast::<T>();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1294,10 +1294,12 @@ impl Dynamic {
|
|||||||
Union::FnPtr(v, ..) => reify!(v, |v: Box<T>| Some(*v), || None),
|
Union::FnPtr(v, ..) => reify!(v, |v: Box<T>| Some(*v), || None),
|
||||||
#[cfg(not(feature = "no_std"))]
|
#[cfg(not(feature = "no_std"))]
|
||||||
Union::TimeStamp(v, ..) => reify!(v, |v: Box<T>| Some(*v), || None),
|
Union::TimeStamp(v, ..) => reify!(v, |v: Box<T>| Some(*v), || None),
|
||||||
Union::Unit(_, ..) => reify!((), |v: T| Some(v), || None),
|
Union::Unit(..) => reify!((), |v: T| Some(v), || None),
|
||||||
Union::Variant(v, _, _) => (*v).as_boxed_any().downcast().ok().map(|x| *x),
|
Union::Variant(v, _, ..) => (*v).as_boxed_any().downcast().ok().map(|x| *x),
|
||||||
#[cfg(not(feature = "no_closure"))]
|
#[cfg(not(feature = "no_closure"))]
|
||||||
Union::Shared(_, _, _) => unreachable!("Union::Shared case should be already handled"),
|
Union::Shared(..) => {
|
||||||
|
unreachable!("Union::Shared case should be already handled")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/// Convert the [`Dynamic`] value into a specific type.
|
/// Convert the [`Dynamic`] value into a specific type.
|
||||||
@ -1382,10 +1384,10 @@ impl Dynamic {
|
|||||||
match self.0 {
|
match self.0 {
|
||||||
#[cfg(not(feature = "no_closure"))]
|
#[cfg(not(feature = "no_closure"))]
|
||||||
#[cfg(not(feature = "sync"))]
|
#[cfg(not(feature = "sync"))]
|
||||||
Union::Shared(ref cell, _, _) => cell.borrow().clone(),
|
Union::Shared(ref cell, _, ..) => cell.borrow().clone(),
|
||||||
#[cfg(not(feature = "no_closure"))]
|
#[cfg(not(feature = "no_closure"))]
|
||||||
#[cfg(feature = "sync")]
|
#[cfg(feature = "sync")]
|
||||||
Union::Shared(ref cell, _, _) => cell.read().unwrap().clone(),
|
Union::Shared(ref cell, _, ..) => cell.read().unwrap().clone(),
|
||||||
_ => self.clone(),
|
_ => self.clone(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1400,7 +1402,7 @@ impl Dynamic {
|
|||||||
pub fn flatten(self) -> Self {
|
pub fn flatten(self) -> Self {
|
||||||
match self.0 {
|
match self.0 {
|
||||||
#[cfg(not(feature = "no_closure"))]
|
#[cfg(not(feature = "no_closure"))]
|
||||||
Union::Shared(cell, _, _) => crate::func::native::shared_try_take(cell).map_or_else(
|
Union::Shared(cell, _, ..) => crate::func::native::shared_try_take(cell).map_or_else(
|
||||||
#[cfg(not(feature = "sync"))]
|
#[cfg(not(feature = "sync"))]
|
||||||
|cell| cell.borrow().clone(),
|
|cell| cell.borrow().clone(),
|
||||||
#[cfg(feature = "sync")]
|
#[cfg(feature = "sync")]
|
||||||
@ -1423,7 +1425,7 @@ impl Dynamic {
|
|||||||
pub(crate) fn flatten_in_place(&mut self) -> &mut Self {
|
pub(crate) fn flatten_in_place(&mut self) -> &mut Self {
|
||||||
match self.0 {
|
match self.0 {
|
||||||
#[cfg(not(feature = "no_closure"))]
|
#[cfg(not(feature = "no_closure"))]
|
||||||
Union::Shared(ref mut cell, _, _) => {
|
Union::Shared(ref mut cell, _, ..) => {
|
||||||
let cell = mem::take(cell);
|
let cell = mem::take(cell);
|
||||||
*self = crate::func::native::shared_try_take(cell).map_or_else(
|
*self = crate::func::native::shared_try_take(cell).map_or_else(
|
||||||
#[cfg(not(feature = "sync"))]
|
#[cfg(not(feature = "sync"))]
|
||||||
@ -1455,7 +1457,7 @@ impl Dynamic {
|
|||||||
pub fn is_locked(&self) -> bool {
|
pub fn is_locked(&self) -> bool {
|
||||||
#[cfg(not(feature = "no_closure"))]
|
#[cfg(not(feature = "no_closure"))]
|
||||||
match self.0 {
|
match self.0 {
|
||||||
Union::Shared(ref _cell, _, _) => {
|
Union::Shared(ref _cell, _, ..) => {
|
||||||
#[cfg(not(feature = "sync"))]
|
#[cfg(not(feature = "sync"))]
|
||||||
return _cell.try_borrow().is_err();
|
return _cell.try_borrow().is_err();
|
||||||
#[cfg(feature = "sync")]
|
#[cfg(feature = "sync")]
|
||||||
@ -1480,7 +1482,7 @@ impl Dynamic {
|
|||||||
pub fn read_lock<T: Any + Clone>(&self) -> Option<DynamicReadLock<T>> {
|
pub fn read_lock<T: Any + Clone>(&self) -> Option<DynamicReadLock<T>> {
|
||||||
match self.0 {
|
match self.0 {
|
||||||
#[cfg(not(feature = "no_closure"))]
|
#[cfg(not(feature = "no_closure"))]
|
||||||
Union::Shared(ref cell, _, _) => {
|
Union::Shared(ref cell, _, ..) => {
|
||||||
#[cfg(not(feature = "sync"))]
|
#[cfg(not(feature = "sync"))]
|
||||||
let value = cell.borrow();
|
let value = cell.borrow();
|
||||||
#[cfg(feature = "sync")]
|
#[cfg(feature = "sync")]
|
||||||
@ -1515,7 +1517,7 @@ impl Dynamic {
|
|||||||
pub fn write_lock<T: Any + Clone>(&mut self) -> Option<DynamicWriteLock<T>> {
|
pub fn write_lock<T: Any + Clone>(&mut self) -> Option<DynamicWriteLock<T>> {
|
||||||
match self.0 {
|
match self.0 {
|
||||||
#[cfg(not(feature = "no_closure"))]
|
#[cfg(not(feature = "no_closure"))]
|
||||||
Union::Shared(ref cell, _, _) => {
|
Union::Shared(ref cell, _, ..) => {
|
||||||
let guard = crate::func::native::locked_write(cell);
|
let guard = crate::func::native::locked_write(cell);
|
||||||
|
|
||||||
if (*guard).type_id() != TypeId::of::<T>()
|
if (*guard).type_id() != TypeId::of::<T>()
|
||||||
@ -1544,79 +1546,79 @@ impl Dynamic {
|
|||||||
|
|
||||||
if TypeId::of::<T>() == TypeId::of::<INT>() {
|
if TypeId::of::<T>() == TypeId::of::<INT>() {
|
||||||
return match self.0 {
|
return match self.0 {
|
||||||
Union::Int(ref v, _, _) => v.as_any().downcast_ref::<T>(),
|
Union::Int(ref v, _, ..) => v.as_any().downcast_ref::<T>(),
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
#[cfg(not(feature = "no_float"))]
|
#[cfg(not(feature = "no_float"))]
|
||||||
if TypeId::of::<T>() == TypeId::of::<crate::FLOAT>() {
|
if TypeId::of::<T>() == TypeId::of::<crate::FLOAT>() {
|
||||||
return match self.0 {
|
return match self.0 {
|
||||||
Union::Float(ref v, _, _) => v.as_ref().as_any().downcast_ref::<T>(),
|
Union::Float(ref v, _, ..) => v.as_ref().as_any().downcast_ref::<T>(),
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
#[cfg(feature = "decimal")]
|
#[cfg(feature = "decimal")]
|
||||||
if TypeId::of::<T>() == TypeId::of::<rust_decimal::Decimal>() {
|
if TypeId::of::<T>() == TypeId::of::<rust_decimal::Decimal>() {
|
||||||
return match self.0 {
|
return match self.0 {
|
||||||
Union::Decimal(ref v, _, _) => v.as_ref().as_any().downcast_ref::<T>(),
|
Union::Decimal(ref v, _, ..) => v.as_ref().as_any().downcast_ref::<T>(),
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
if TypeId::of::<T>() == TypeId::of::<bool>() {
|
if TypeId::of::<T>() == TypeId::of::<bool>() {
|
||||||
return match self.0 {
|
return match self.0 {
|
||||||
Union::Bool(ref v, _, _) => v.as_any().downcast_ref::<T>(),
|
Union::Bool(ref v, _, ..) => v.as_any().downcast_ref::<T>(),
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
if TypeId::of::<T>() == TypeId::of::<ImmutableString>() {
|
if TypeId::of::<T>() == TypeId::of::<ImmutableString>() {
|
||||||
return match self.0 {
|
return match self.0 {
|
||||||
Union::Str(ref v, _, _) => v.as_any().downcast_ref::<T>(),
|
Union::Str(ref v, _, ..) => v.as_any().downcast_ref::<T>(),
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
if TypeId::of::<T>() == TypeId::of::<char>() {
|
if TypeId::of::<T>() == TypeId::of::<char>() {
|
||||||
return match self.0 {
|
return match self.0 {
|
||||||
Union::Char(ref v, _, _) => v.as_any().downcast_ref::<T>(),
|
Union::Char(ref v, _, ..) => v.as_any().downcast_ref::<T>(),
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
#[cfg(not(feature = "no_index"))]
|
#[cfg(not(feature = "no_index"))]
|
||||||
if TypeId::of::<T>() == TypeId::of::<crate::Array>() {
|
if TypeId::of::<T>() == TypeId::of::<crate::Array>() {
|
||||||
return match self.0 {
|
return match self.0 {
|
||||||
Union::Array(ref v, _, _) => v.as_ref().as_any().downcast_ref::<T>(),
|
Union::Array(ref v, _, ..) => v.as_ref().as_any().downcast_ref::<T>(),
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
#[cfg(not(feature = "no_index"))]
|
#[cfg(not(feature = "no_index"))]
|
||||||
if TypeId::of::<T>() == TypeId::of::<crate::Blob>() {
|
if TypeId::of::<T>() == TypeId::of::<crate::Blob>() {
|
||||||
return match self.0 {
|
return match self.0 {
|
||||||
Union::Blob(ref v, _, _) => v.as_ref().as_any().downcast_ref::<T>(),
|
Union::Blob(ref v, _, ..) => v.as_ref().as_any().downcast_ref::<T>(),
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
#[cfg(not(feature = "no_object"))]
|
#[cfg(not(feature = "no_object"))]
|
||||||
if TypeId::of::<T>() == TypeId::of::<crate::Map>() {
|
if TypeId::of::<T>() == TypeId::of::<crate::Map>() {
|
||||||
return match self.0 {
|
return match self.0 {
|
||||||
Union::Map(ref v, _, _) => v.as_ref().as_any().downcast_ref::<T>(),
|
Union::Map(ref v, _, ..) => v.as_ref().as_any().downcast_ref::<T>(),
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
if TypeId::of::<T>() == TypeId::of::<FnPtr>() {
|
if TypeId::of::<T>() == TypeId::of::<FnPtr>() {
|
||||||
return match self.0 {
|
return match self.0 {
|
||||||
Union::FnPtr(ref v, _, _) => v.as_ref().as_any().downcast_ref::<T>(),
|
Union::FnPtr(ref v, _, ..) => v.as_ref().as_any().downcast_ref::<T>(),
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
#[cfg(not(feature = "no_std"))]
|
#[cfg(not(feature = "no_std"))]
|
||||||
if TypeId::of::<T>() == TypeId::of::<Instant>() {
|
if TypeId::of::<T>() == TypeId::of::<Instant>() {
|
||||||
return match self.0 {
|
return match self.0 {
|
||||||
Union::TimeStamp(ref v, _, _) => v.as_ref().as_any().downcast_ref::<T>(),
|
Union::TimeStamp(ref v, _, ..) => v.as_ref().as_any().downcast_ref::<T>(),
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
if TypeId::of::<T>() == TypeId::of::<()>() {
|
if TypeId::of::<T>() == TypeId::of::<()>() {
|
||||||
return match self.0 {
|
return match self.0 {
|
||||||
Union::Unit(ref v, _, _) => v.as_any().downcast_ref::<T>(),
|
Union::Unit(ref v, _, ..) => v.as_any().downcast_ref::<T>(),
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -1625,9 +1627,9 @@ impl Dynamic {
|
|||||||
}
|
}
|
||||||
|
|
||||||
match self.0 {
|
match self.0 {
|
||||||
Union::Variant(ref v, _, _) => (***v).as_any().downcast_ref::<T>(),
|
Union::Variant(ref v, _, ..) => (***v).as_any().downcast_ref::<T>(),
|
||||||
#[cfg(not(feature = "no_closure"))]
|
#[cfg(not(feature = "no_closure"))]
|
||||||
Union::Shared(_, _, _) => None,
|
Union::Shared(..) => None,
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1642,79 +1644,79 @@ impl Dynamic {
|
|||||||
|
|
||||||
if TypeId::of::<T>() == TypeId::of::<INT>() {
|
if TypeId::of::<T>() == TypeId::of::<INT>() {
|
||||||
return match self.0 {
|
return match self.0 {
|
||||||
Union::Int(ref mut v, _, _) => v.as_any_mut().downcast_mut::<T>(),
|
Union::Int(ref mut v, _, ..) => v.as_any_mut().downcast_mut::<T>(),
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
#[cfg(not(feature = "no_float"))]
|
#[cfg(not(feature = "no_float"))]
|
||||||
if TypeId::of::<T>() == TypeId::of::<crate::FLOAT>() {
|
if TypeId::of::<T>() == TypeId::of::<crate::FLOAT>() {
|
||||||
return match self.0 {
|
return match self.0 {
|
||||||
Union::Float(ref mut v, _, _) => v.as_mut().as_any_mut().downcast_mut::<T>(),
|
Union::Float(ref mut v, _, ..) => v.as_mut().as_any_mut().downcast_mut::<T>(),
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
#[cfg(feature = "decimal")]
|
#[cfg(feature = "decimal")]
|
||||||
if TypeId::of::<T>() == TypeId::of::<rust_decimal::Decimal>() {
|
if TypeId::of::<T>() == TypeId::of::<rust_decimal::Decimal>() {
|
||||||
return match self.0 {
|
return match self.0 {
|
||||||
Union::Decimal(ref mut v, _, _) => v.as_mut().as_any_mut().downcast_mut::<T>(),
|
Union::Decimal(ref mut v, _, ..) => v.as_mut().as_any_mut().downcast_mut::<T>(),
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
if TypeId::of::<T>() == TypeId::of::<bool>() {
|
if TypeId::of::<T>() == TypeId::of::<bool>() {
|
||||||
return match self.0 {
|
return match self.0 {
|
||||||
Union::Bool(ref mut v, _, _) => v.as_any_mut().downcast_mut::<T>(),
|
Union::Bool(ref mut v, _, ..) => v.as_any_mut().downcast_mut::<T>(),
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
if TypeId::of::<T>() == TypeId::of::<ImmutableString>() {
|
if TypeId::of::<T>() == TypeId::of::<ImmutableString>() {
|
||||||
return match self.0 {
|
return match self.0 {
|
||||||
Union::Str(ref mut v, _, _) => v.as_any_mut().downcast_mut::<T>(),
|
Union::Str(ref mut v, _, ..) => v.as_any_mut().downcast_mut::<T>(),
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
if TypeId::of::<T>() == TypeId::of::<char>() {
|
if TypeId::of::<T>() == TypeId::of::<char>() {
|
||||||
return match self.0 {
|
return match self.0 {
|
||||||
Union::Char(ref mut v, _, _) => v.as_any_mut().downcast_mut::<T>(),
|
Union::Char(ref mut v, _, ..) => v.as_any_mut().downcast_mut::<T>(),
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
#[cfg(not(feature = "no_index"))]
|
#[cfg(not(feature = "no_index"))]
|
||||||
if TypeId::of::<T>() == TypeId::of::<crate::Array>() {
|
if TypeId::of::<T>() == TypeId::of::<crate::Array>() {
|
||||||
return match self.0 {
|
return match self.0 {
|
||||||
Union::Array(ref mut v, _, _) => v.as_mut().as_any_mut().downcast_mut::<T>(),
|
Union::Array(ref mut v, _, ..) => v.as_mut().as_any_mut().downcast_mut::<T>(),
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
#[cfg(not(feature = "no_index"))]
|
#[cfg(not(feature = "no_index"))]
|
||||||
if TypeId::of::<T>() == TypeId::of::<crate::Blob>() {
|
if TypeId::of::<T>() == TypeId::of::<crate::Blob>() {
|
||||||
return match self.0 {
|
return match self.0 {
|
||||||
Union::Blob(ref mut v, _, _) => v.as_mut().as_any_mut().downcast_mut::<T>(),
|
Union::Blob(ref mut v, _, ..) => v.as_mut().as_any_mut().downcast_mut::<T>(),
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
#[cfg(not(feature = "no_object"))]
|
#[cfg(not(feature = "no_object"))]
|
||||||
if TypeId::of::<T>() == TypeId::of::<crate::Map>() {
|
if TypeId::of::<T>() == TypeId::of::<crate::Map>() {
|
||||||
return match self.0 {
|
return match self.0 {
|
||||||
Union::Map(ref mut v, _, _) => v.as_mut().as_any_mut().downcast_mut::<T>(),
|
Union::Map(ref mut v, _, ..) => v.as_mut().as_any_mut().downcast_mut::<T>(),
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
if TypeId::of::<T>() == TypeId::of::<FnPtr>() {
|
if TypeId::of::<T>() == TypeId::of::<FnPtr>() {
|
||||||
return match self.0 {
|
return match self.0 {
|
||||||
Union::FnPtr(ref mut v, _, _) => v.as_mut().as_any_mut().downcast_mut::<T>(),
|
Union::FnPtr(ref mut v, _, ..) => v.as_mut().as_any_mut().downcast_mut::<T>(),
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
#[cfg(not(feature = "no_std"))]
|
#[cfg(not(feature = "no_std"))]
|
||||||
if TypeId::of::<T>() == TypeId::of::<Instant>() {
|
if TypeId::of::<T>() == TypeId::of::<Instant>() {
|
||||||
return match self.0 {
|
return match self.0 {
|
||||||
Union::TimeStamp(ref mut v, _, _) => v.as_mut().as_any_mut().downcast_mut::<T>(),
|
Union::TimeStamp(ref mut v, _, ..) => v.as_mut().as_any_mut().downcast_mut::<T>(),
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
if TypeId::of::<T>() == TypeId::of::<()>() {
|
if TypeId::of::<T>() == TypeId::of::<()>() {
|
||||||
return match self.0 {
|
return match self.0 {
|
||||||
Union::Unit(ref mut v, _, _) => v.as_any_mut().downcast_mut::<T>(),
|
Union::Unit(ref mut v, _, ..) => v.as_any_mut().downcast_mut::<T>(),
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -1723,9 +1725,9 @@ impl Dynamic {
|
|||||||
}
|
}
|
||||||
|
|
||||||
match self.0 {
|
match self.0 {
|
||||||
Union::Variant(ref mut v, _, _) => (***v).as_any_mut().downcast_mut::<T>(),
|
Union::Variant(ref mut v, _, ..) => (***v).as_any_mut().downcast_mut::<T>(),
|
||||||
#[cfg(not(feature = "no_closure"))]
|
#[cfg(not(feature = "no_closure"))]
|
||||||
Union::Shared(_, _, _) => None,
|
Union::Shared(..) => None,
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1734,9 +1736,9 @@ impl Dynamic {
|
|||||||
#[inline]
|
#[inline]
|
||||||
pub fn as_unit(&self) -> Result<(), &'static str> {
|
pub fn as_unit(&self) -> Result<(), &'static str> {
|
||||||
match self.0 {
|
match self.0 {
|
||||||
Union::Unit(v, _, _) => Ok(v),
|
Union::Unit(v, _, ..) => Ok(v),
|
||||||
#[cfg(not(feature = "no_closure"))]
|
#[cfg(not(feature = "no_closure"))]
|
||||||
Union::Shared(_, _, _) => self.read_lock().map(|v| *v).ok_or_else(|| self.type_name()),
|
Union::Shared(..) => self.read_lock().map(|v| *v).ok_or_else(|| self.type_name()),
|
||||||
_ => Err(self.type_name()),
|
_ => Err(self.type_name()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1745,9 +1747,9 @@ impl Dynamic {
|
|||||||
#[inline]
|
#[inline]
|
||||||
pub fn as_int(&self) -> Result<INT, &'static str> {
|
pub fn as_int(&self) -> Result<INT, &'static str> {
|
||||||
match self.0 {
|
match self.0 {
|
||||||
Union::Int(n, _, _) => Ok(n),
|
Union::Int(n, _, ..) => Ok(n),
|
||||||
#[cfg(not(feature = "no_closure"))]
|
#[cfg(not(feature = "no_closure"))]
|
||||||
Union::Shared(_, _, _) => self.read_lock().map(|v| *v).ok_or_else(|| self.type_name()),
|
Union::Shared(..) => self.read_lock().map(|v| *v).ok_or_else(|| self.type_name()),
|
||||||
_ => Err(self.type_name()),
|
_ => Err(self.type_name()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1759,9 +1761,9 @@ impl Dynamic {
|
|||||||
#[inline]
|
#[inline]
|
||||||
pub fn as_float(&self) -> Result<crate::FLOAT, &'static str> {
|
pub fn as_float(&self) -> Result<crate::FLOAT, &'static str> {
|
||||||
match self.0 {
|
match self.0 {
|
||||||
Union::Float(n, _, _) => Ok(*n),
|
Union::Float(n, _, ..) => Ok(*n),
|
||||||
#[cfg(not(feature = "no_closure"))]
|
#[cfg(not(feature = "no_closure"))]
|
||||||
Union::Shared(_, _, _) => self.read_lock().map(|v| *v).ok_or_else(|| self.type_name()),
|
Union::Shared(..) => self.read_lock().map(|v| *v).ok_or_else(|| self.type_name()),
|
||||||
_ => Err(self.type_name()),
|
_ => Err(self.type_name()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1773,9 +1775,9 @@ impl Dynamic {
|
|||||||
#[inline]
|
#[inline]
|
||||||
pub fn as_decimal(&self) -> Result<rust_decimal::Decimal, &'static str> {
|
pub fn as_decimal(&self) -> Result<rust_decimal::Decimal, &'static str> {
|
||||||
match self.0 {
|
match self.0 {
|
||||||
Union::Decimal(ref n, _, _) => Ok(**n),
|
Union::Decimal(ref n, _, ..) => Ok(**n),
|
||||||
#[cfg(not(feature = "no_closure"))]
|
#[cfg(not(feature = "no_closure"))]
|
||||||
Union::Shared(_, _, _) => self.read_lock().map(|v| *v).ok_or_else(|| self.type_name()),
|
Union::Shared(..) => self.read_lock().map(|v| *v).ok_or_else(|| self.type_name()),
|
||||||
_ => Err(self.type_name()),
|
_ => Err(self.type_name()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1784,9 +1786,9 @@ impl Dynamic {
|
|||||||
#[inline]
|
#[inline]
|
||||||
pub fn as_bool(&self) -> Result<bool, &'static str> {
|
pub fn as_bool(&self) -> Result<bool, &'static str> {
|
||||||
match self.0 {
|
match self.0 {
|
||||||
Union::Bool(b, _, _) => Ok(b),
|
Union::Bool(b, _, ..) => Ok(b),
|
||||||
#[cfg(not(feature = "no_closure"))]
|
#[cfg(not(feature = "no_closure"))]
|
||||||
Union::Shared(_, _, _) => self.read_lock().map(|v| *v).ok_or_else(|| self.type_name()),
|
Union::Shared(..) => self.read_lock().map(|v| *v).ok_or_else(|| self.type_name()),
|
||||||
_ => Err(self.type_name()),
|
_ => Err(self.type_name()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1795,9 +1797,9 @@ impl Dynamic {
|
|||||||
#[inline]
|
#[inline]
|
||||||
pub fn as_char(&self) -> Result<char, &'static str> {
|
pub fn as_char(&self) -> Result<char, &'static str> {
|
||||||
match self.0 {
|
match self.0 {
|
||||||
Union::Char(n, _, _) => Ok(n),
|
Union::Char(n, _, ..) => Ok(n),
|
||||||
#[cfg(not(feature = "no_closure"))]
|
#[cfg(not(feature = "no_closure"))]
|
||||||
Union::Shared(_, _, _) => self.read_lock().map(|v| *v).ok_or_else(|| self.type_name()),
|
Union::Shared(..) => self.read_lock().map(|v| *v).ok_or_else(|| self.type_name()),
|
||||||
_ => Err(self.type_name()),
|
_ => Err(self.type_name()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1810,9 +1812,9 @@ impl Dynamic {
|
|||||||
#[inline]
|
#[inline]
|
||||||
pub(crate) fn as_str_ref(&self) -> Result<&str, &'static str> {
|
pub(crate) fn as_str_ref(&self) -> Result<&str, &'static str> {
|
||||||
match self.0 {
|
match self.0 {
|
||||||
Union::Str(ref s, _, _) => Ok(s),
|
Union::Str(ref s, _, ..) => Ok(s),
|
||||||
#[cfg(not(feature = "no_closure"))]
|
#[cfg(not(feature = "no_closure"))]
|
||||||
Union::Shared(_, _, _) => panic!("as_str_ref() cannot be called on shared values"),
|
Union::Shared(..) => panic!("as_str_ref() cannot be called on shared values"),
|
||||||
_ => Err(self.type_name()),
|
_ => Err(self.type_name()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1829,16 +1831,16 @@ impl Dynamic {
|
|||||||
#[inline]
|
#[inline]
|
||||||
pub fn into_immutable_string(self) -> Result<ImmutableString, &'static str> {
|
pub fn into_immutable_string(self) -> Result<ImmutableString, &'static str> {
|
||||||
match self.0 {
|
match self.0 {
|
||||||
Union::Str(s, _, _) => Ok(s),
|
Union::Str(s, _, ..) => Ok(s),
|
||||||
#[cfg(not(feature = "no_closure"))]
|
#[cfg(not(feature = "no_closure"))]
|
||||||
Union::Shared(cell, _, _) => {
|
Union::Shared(cell, _, ..) => {
|
||||||
#[cfg(not(feature = "sync"))]
|
#[cfg(not(feature = "sync"))]
|
||||||
let value = cell.borrow();
|
let value = cell.borrow();
|
||||||
#[cfg(feature = "sync")]
|
#[cfg(feature = "sync")]
|
||||||
let value = cell.read().unwrap();
|
let value = cell.read().unwrap();
|
||||||
|
|
||||||
match value.0 {
|
match value.0 {
|
||||||
Union::Str(ref s, _, _) => Ok(s.clone()),
|
Union::Str(ref s, _, ..) => Ok(s.clone()),
|
||||||
_ => Err((*value).type_name()),
|
_ => Err((*value).type_name()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1851,16 +1853,16 @@ impl Dynamic {
|
|||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn into_array(self) -> Result<crate::Array, &'static str> {
|
pub fn into_array(self) -> Result<crate::Array, &'static str> {
|
||||||
match self.0 {
|
match self.0 {
|
||||||
Union::Array(a, _, _) => Ok(*a),
|
Union::Array(a, _, ..) => Ok(*a),
|
||||||
#[cfg(not(feature = "no_closure"))]
|
#[cfg(not(feature = "no_closure"))]
|
||||||
Union::Shared(cell, _, _) => {
|
Union::Shared(cell, _, ..) => {
|
||||||
#[cfg(not(feature = "sync"))]
|
#[cfg(not(feature = "sync"))]
|
||||||
let value = cell.borrow();
|
let value = cell.borrow();
|
||||||
#[cfg(feature = "sync")]
|
#[cfg(feature = "sync")]
|
||||||
let value = cell.read().unwrap();
|
let value = cell.read().unwrap();
|
||||||
|
|
||||||
match value.0 {
|
match value.0 {
|
||||||
Union::Array(ref a, _, _) => Ok(a.as_ref().clone()),
|
Union::Array(ref a, _, ..) => Ok(a.as_ref().clone()),
|
||||||
_ => Err((*value).type_name()),
|
_ => Err((*value).type_name()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1873,7 +1875,7 @@ impl Dynamic {
|
|||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn into_typed_array<T: Variant + Clone>(self) -> Result<Vec<T>, &'static str> {
|
pub fn into_typed_array<T: Variant + Clone>(self) -> Result<Vec<T>, &'static str> {
|
||||||
match self.0 {
|
match self.0 {
|
||||||
Union::Array(a, _, _) => a
|
Union::Array(a, _, ..) => a
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|v| {
|
.map(|v| {
|
||||||
#[cfg(not(feature = "no_closure"))]
|
#[cfg(not(feature = "no_closure"))]
|
||||||
@ -1889,18 +1891,16 @@ impl Dynamic {
|
|||||||
v.try_cast::<T>().ok_or_else(|| typ)
|
v.try_cast::<T>().ok_or_else(|| typ)
|
||||||
})
|
})
|
||||||
.collect(),
|
.collect(),
|
||||||
Union::Blob(_, _, _) if TypeId::of::<T>() == TypeId::of::<u8>() => {
|
Union::Blob(..) if TypeId::of::<T>() == TypeId::of::<u8>() => Ok(self.cast::<Vec<T>>()),
|
||||||
Ok(self.cast::<Vec<T>>())
|
|
||||||
}
|
|
||||||
#[cfg(not(feature = "no_closure"))]
|
#[cfg(not(feature = "no_closure"))]
|
||||||
Union::Shared(cell, _, _) => {
|
Union::Shared(cell, _, ..) => {
|
||||||
#[cfg(not(feature = "sync"))]
|
#[cfg(not(feature = "sync"))]
|
||||||
let value = cell.borrow();
|
let value = cell.borrow();
|
||||||
#[cfg(feature = "sync")]
|
#[cfg(feature = "sync")]
|
||||||
let value = cell.read().unwrap();
|
let value = cell.read().unwrap();
|
||||||
|
|
||||||
match value.0 {
|
match value.0 {
|
||||||
Union::Array(ref a, _, _) => {
|
Union::Array(ref a, _, ..) => {
|
||||||
a.iter()
|
a.iter()
|
||||||
.map(|v| {
|
.map(|v| {
|
||||||
#[cfg(not(feature = "no_closure"))]
|
#[cfg(not(feature = "no_closure"))]
|
||||||
@ -1917,7 +1917,7 @@ impl Dynamic {
|
|||||||
})
|
})
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
Union::Blob(_, _, _) if TypeId::of::<T>() == TypeId::of::<u8>() => {
|
Union::Blob(..) if TypeId::of::<T>() == TypeId::of::<u8>() => {
|
||||||
Ok((*value).clone().cast::<Vec<T>>())
|
Ok((*value).clone().cast::<Vec<T>>())
|
||||||
}
|
}
|
||||||
_ => Err((*value).type_name()),
|
_ => Err((*value).type_name()),
|
||||||
@ -1932,16 +1932,16 @@ impl Dynamic {
|
|||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn into_blob(self) -> Result<crate::Blob, &'static str> {
|
pub fn into_blob(self) -> Result<crate::Blob, &'static str> {
|
||||||
match self.0 {
|
match self.0 {
|
||||||
Union::Blob(a, _, _) => Ok(*a),
|
Union::Blob(a, _, ..) => Ok(*a),
|
||||||
#[cfg(not(feature = "no_closure"))]
|
#[cfg(not(feature = "no_closure"))]
|
||||||
Union::Shared(cell, _, _) => {
|
Union::Shared(cell, _, ..) => {
|
||||||
#[cfg(not(feature = "sync"))]
|
#[cfg(not(feature = "sync"))]
|
||||||
let value = cell.borrow();
|
let value = cell.borrow();
|
||||||
#[cfg(feature = "sync")]
|
#[cfg(feature = "sync")]
|
||||||
let value = cell.read().unwrap();
|
let value = cell.read().unwrap();
|
||||||
|
|
||||||
match value.0 {
|
match value.0 {
|
||||||
Union::Blob(ref a, _, _) => Ok(a.as_ref().clone()),
|
Union::Blob(ref a, _, ..) => Ok(a.as_ref().clone()),
|
||||||
_ => Err((*value).type_name()),
|
_ => Err((*value).type_name()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -120,77 +120,77 @@ impl fmt::Display for EvalAltResult {
|
|||||||
s => write!(f, "{}: {}", s, err),
|
s => write!(f, "{}: {}", s, err),
|
||||||
}?,
|
}?,
|
||||||
|
|
||||||
Self::ErrorParsing(p, _) => write!(f, "Syntax error: {}", p)?,
|
Self::ErrorParsing(p, ..) => write!(f, "Syntax error: {}", p)?,
|
||||||
|
|
||||||
#[cfg(not(feature = "no_function"))]
|
#[cfg(not(feature = "no_function"))]
|
||||||
Self::ErrorInFunctionCall(s, src, err, _) if crate::parser::is_anonymous_fn(s) => {
|
Self::ErrorInFunctionCall(s, src, err, ..) if crate::parser::is_anonymous_fn(s) => {
|
||||||
write!(f, "{} in call to closure", err)?;
|
write!(f, "{} in call to closure", err)?;
|
||||||
if !src.is_empty() {
|
if !src.is_empty() {
|
||||||
write!(f, " @ '{}'", src)?;
|
write!(f, " @ '{}'", src)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Self::ErrorInFunctionCall(s, src, err, _) => {
|
Self::ErrorInFunctionCall(s, src, err, ..) => {
|
||||||
write!(f, "{} in call to function {}", err, s)?;
|
write!(f, "{} in call to function {}", err, s)?;
|
||||||
if !src.is_empty() {
|
if !src.is_empty() {
|
||||||
write!(f, " @ '{}'", src)?;
|
write!(f, " @ '{}'", src)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Self::ErrorInModule(s, err, _) if s.is_empty() => {
|
Self::ErrorInModule(s, err, ..) if s.is_empty() => {
|
||||||
write!(f, "Error in module: {}", err)?
|
write!(f, "Error in module: {}", err)?
|
||||||
}
|
}
|
||||||
Self::ErrorInModule(s, err, _) => write!(f, "Error in module {}: {}", s, err)?,
|
Self::ErrorInModule(s, err, ..) => write!(f, "Error in module {}: {}", s, err)?,
|
||||||
|
|
||||||
Self::ErrorVariableExists(s, _) => write!(f, "Variable is already defined: {}", s)?,
|
Self::ErrorVariableExists(s, ..) => write!(f, "Variable is already defined: {}", s)?,
|
||||||
Self::ErrorVariableNotFound(s, _) => write!(f, "Variable not found: {}", s)?,
|
Self::ErrorVariableNotFound(s, ..) => write!(f, "Variable not found: {}", s)?,
|
||||||
Self::ErrorFunctionNotFound(s, _) => write!(f, "Function not found: {}", s)?,
|
Self::ErrorFunctionNotFound(s, ..) => write!(f, "Function not found: {}", s)?,
|
||||||
Self::ErrorModuleNotFound(s, _) => write!(f, "Module not found: {}", s)?,
|
Self::ErrorModuleNotFound(s, ..) => write!(f, "Module not found: {}", s)?,
|
||||||
Self::ErrorDataRace(s, _) => {
|
Self::ErrorDataRace(s, ..) => {
|
||||||
write!(f, "Data race detected when accessing variable: {}", s)?
|
write!(f, "Data race detected when accessing variable: {}", s)?
|
||||||
}
|
}
|
||||||
Self::ErrorDotExpr(s, _) => match s.as_str() {
|
Self::ErrorDotExpr(s, ..) => match s.as_str() {
|
||||||
"" => f.write_str("Malformed dot expression"),
|
"" => f.write_str("Malformed dot expression"),
|
||||||
s => f.write_str(s),
|
s => f.write_str(s),
|
||||||
}?,
|
}?,
|
||||||
Self::ErrorIndexingType(s, _) => write!(f, "Indexer not registered: {}", s)?,
|
Self::ErrorIndexingType(s, ..) => write!(f, "Indexer not registered: {}", s)?,
|
||||||
Self::ErrorUnboundThis(_) => f.write_str("'this' is not bound")?,
|
Self::ErrorUnboundThis(_) => f.write_str("'this' is not bound")?,
|
||||||
Self::ErrorFor(_) => f.write_str("For loop expects a type that is iterable")?,
|
Self::ErrorFor(_) => f.write_str("For loop expects a type that is iterable")?,
|
||||||
Self::ErrorTooManyOperations(_) => f.write_str("Too many operations")?,
|
Self::ErrorTooManyOperations(_) => f.write_str("Too many operations")?,
|
||||||
Self::ErrorTooManyModules(_) => f.write_str("Too many modules imported")?,
|
Self::ErrorTooManyModules(_) => f.write_str("Too many modules imported")?,
|
||||||
Self::ErrorStackOverflow(_) => f.write_str("Stack overflow")?,
|
Self::ErrorStackOverflow(_) => f.write_str("Stack overflow")?,
|
||||||
Self::ErrorTerminated(_, _) => f.write_str("Script terminated")?,
|
Self::ErrorTerminated(..) => f.write_str("Script terminated")?,
|
||||||
|
|
||||||
Self::ErrorRuntime(d, _) if d.is::<()>() => f.write_str("Runtime error")?,
|
Self::ErrorRuntime(d, ..) if d.is::<()>() => f.write_str("Runtime error")?,
|
||||||
Self::ErrorRuntime(d, _)
|
Self::ErrorRuntime(d, ..)
|
||||||
if d.read_lock::<ImmutableString>()
|
if d.read_lock::<ImmutableString>()
|
||||||
.map_or(false, |v| v.is_empty()) =>
|
.map_or(false, |v| v.is_empty()) =>
|
||||||
{
|
{
|
||||||
write!(f, "Runtime error")?
|
write!(f, "Runtime error")?
|
||||||
}
|
}
|
||||||
Self::ErrorRuntime(d, _) => write!(f, "Runtime error: {}", d)?,
|
Self::ErrorRuntime(d, ..) => write!(f, "Runtime error: {}", d)?,
|
||||||
|
|
||||||
Self::ErrorAssignmentToConstant(s, _) => write!(f, "Cannot modify constant: {}", s)?,
|
Self::ErrorAssignmentToConstant(s, ..) => write!(f, "Cannot modify constant: {}", s)?,
|
||||||
Self::ErrorMismatchOutputType(s, r, _) => match (r.as_str(), s.as_str()) {
|
Self::ErrorMismatchOutputType(s, r, ..) => match (r.as_str(), s.as_str()) {
|
||||||
("", s) => write!(f, "Output type is incorrect, expecting {}", s),
|
("", s) => write!(f, "Output type is incorrect, expecting {}", s),
|
||||||
(r, "") => write!(f, "Output type is incorrect: {}", r),
|
(r, "") => write!(f, "Output type is incorrect: {}", r),
|
||||||
(r, s) => write!(f, "Output type is incorrect: {} (expecting {})", r, s),
|
(r, s) => write!(f, "Output type is incorrect: {} (expecting {})", r, s),
|
||||||
}?,
|
}?,
|
||||||
Self::ErrorMismatchDataType(s, r, _) => match (r.as_str(), s.as_str()) {
|
Self::ErrorMismatchDataType(s, r, ..) => match (r.as_str(), s.as_str()) {
|
||||||
("", s) => write!(f, "Data type is incorrect, expecting {}", s),
|
("", s) => write!(f, "Data type is incorrect, expecting {}", s),
|
||||||
(r, "") => write!(f, "Data type is incorrect: {}", r),
|
(r, "") => write!(f, "Data type is incorrect: {}", r),
|
||||||
(r, s) => write!(f, "Data type is incorrect: {} (expecting {})", r, s),
|
(r, s) => write!(f, "Data type is incorrect: {} (expecting {})", r, s),
|
||||||
}?,
|
}?,
|
||||||
Self::ErrorArithmetic(s, _) => match s.as_str() {
|
Self::ErrorArithmetic(s, ..) => match s.as_str() {
|
||||||
"" => f.write_str("Arithmetic error"),
|
"" => f.write_str("Arithmetic error"),
|
||||||
s => f.write_str(s),
|
s => f.write_str(s),
|
||||||
}?,
|
}?,
|
||||||
|
|
||||||
Self::LoopBreak(true, _) => f.write_str("'break' not inside a loop")?,
|
Self::LoopBreak(true, ..) => f.write_str("'break' not inside a loop")?,
|
||||||
Self::LoopBreak(false, _) => f.write_str("'continue' not inside a loop")?,
|
Self::LoopBreak(false, ..) => f.write_str("'continue' not inside a loop")?,
|
||||||
|
|
||||||
Self::Return(_, _) => f.write_str("NOT AN ERROR - function returns value")?,
|
Self::Return(..) => f.write_str("NOT AN ERROR - function returns value")?,
|
||||||
|
|
||||||
Self::ErrorArrayBounds(max, index, _) => match max {
|
Self::ErrorArrayBounds(max, index, ..) => match max {
|
||||||
0 => write!(f, "Array index {} out of bounds: array is empty", index),
|
0 => write!(f, "Array index {} out of bounds: array is empty", index),
|
||||||
1 => write!(
|
1 => write!(
|
||||||
f,
|
f,
|
||||||
@ -203,7 +203,7 @@ impl fmt::Display for EvalAltResult {
|
|||||||
index, max
|
index, max
|
||||||
),
|
),
|
||||||
}?,
|
}?,
|
||||||
Self::ErrorStringBounds(max, index, _) => match max {
|
Self::ErrorStringBounds(max, index, ..) => match max {
|
||||||
0 => write!(f, "String index {} out of bounds: string is empty", index),
|
0 => write!(f, "String index {} out of bounds: string is empty", index),
|
||||||
1 => write!(
|
1 => write!(
|
||||||
f,
|
f,
|
||||||
@ -216,14 +216,14 @@ impl fmt::Display for EvalAltResult {
|
|||||||
index, max
|
index, max
|
||||||
),
|
),
|
||||||
}?,
|
}?,
|
||||||
Self::ErrorBitFieldBounds(max, index, _) => write!(
|
Self::ErrorBitFieldBounds(max, index, ..) => write!(
|
||||||
f,
|
f,
|
||||||
"Bit-field index {} out of bounds: only {} bits in the bit-field",
|
"Bit-field index {} out of bounds: only {} bits in the bit-field",
|
||||||
index, max
|
index, max
|
||||||
)?,
|
)?,
|
||||||
Self::ErrorDataTooLarge(typ, _) => write!(f, "{} exceeds maximum limit", typ)?,
|
Self::ErrorDataTooLarge(typ, ..) => write!(f, "{} exceeds maximum limit", typ)?,
|
||||||
|
|
||||||
Self::ErrorCustomSyntax(s, tokens, _) => write!(f, "{}: {}", s, tokens.join(" "))?,
|
Self::ErrorCustomSyntax(s, tokens, ..) => write!(f, "{}: {}", s, tokens.join(" "))?,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Do not write any position if None
|
// Do not write any position if None
|
||||||
@ -256,7 +256,7 @@ impl EvalAltResult {
|
|||||||
#[must_use]
|
#[must_use]
|
||||||
pub const fn is_pseudo_error(&self) -> bool {
|
pub const fn is_pseudo_error(&self) -> bool {
|
||||||
match self {
|
match self {
|
||||||
Self::LoopBreak(_, _) | Self::Return(_, _) => true,
|
Self::LoopBreak(..) | Self::Return(..) => true,
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -264,58 +264,58 @@ impl EvalAltResult {
|
|||||||
#[must_use]
|
#[must_use]
|
||||||
pub const fn is_catchable(&self) -> bool {
|
pub const fn is_catchable(&self) -> bool {
|
||||||
match self {
|
match self {
|
||||||
Self::ErrorSystem(_, _) => false,
|
Self::ErrorSystem(..) => false,
|
||||||
Self::ErrorParsing(_, _) => false,
|
Self::ErrorParsing(..) => false,
|
||||||
|
|
||||||
Self::ErrorFunctionNotFound(_, _)
|
Self::ErrorFunctionNotFound(..)
|
||||||
| Self::ErrorInFunctionCall(_, _, _, _)
|
| Self::ErrorInFunctionCall(..)
|
||||||
| Self::ErrorInModule(_, _, _)
|
| Self::ErrorInModule(..)
|
||||||
| Self::ErrorUnboundThis(_)
|
| Self::ErrorUnboundThis(_)
|
||||||
| Self::ErrorMismatchDataType(_, _, _)
|
| Self::ErrorMismatchDataType(..)
|
||||||
| Self::ErrorArrayBounds(_, _, _)
|
| Self::ErrorArrayBounds(..)
|
||||||
| Self::ErrorStringBounds(_, _, _)
|
| Self::ErrorStringBounds(..)
|
||||||
| Self::ErrorBitFieldBounds(_, _, _)
|
| Self::ErrorBitFieldBounds(..)
|
||||||
| Self::ErrorIndexingType(_, _)
|
| Self::ErrorIndexingType(..)
|
||||||
| Self::ErrorFor(_)
|
| Self::ErrorFor(_)
|
||||||
| Self::ErrorVariableExists(_, _)
|
| Self::ErrorVariableExists(..)
|
||||||
| Self::ErrorVariableNotFound(_, _)
|
| Self::ErrorVariableNotFound(..)
|
||||||
| Self::ErrorModuleNotFound(_, _)
|
| Self::ErrorModuleNotFound(..)
|
||||||
| Self::ErrorDataRace(_, _)
|
| Self::ErrorDataRace(..)
|
||||||
| Self::ErrorAssignmentToConstant(_, _)
|
| Self::ErrorAssignmentToConstant(..)
|
||||||
| Self::ErrorMismatchOutputType(_, _, _)
|
| Self::ErrorMismatchOutputType(..)
|
||||||
| Self::ErrorDotExpr(_, _)
|
| Self::ErrorDotExpr(..)
|
||||||
| Self::ErrorArithmetic(_, _)
|
| Self::ErrorArithmetic(..)
|
||||||
| Self::ErrorRuntime(_, _) => true,
|
| Self::ErrorRuntime(..) => true,
|
||||||
|
|
||||||
// Custom syntax raises errors only when they are compiled by one
|
// Custom syntax raises errors only when they are compiled by one
|
||||||
// [`Engine`][crate::Engine] and run by another, causing a mismatch.
|
// [`Engine`][crate::Engine] and run by another, causing a mismatch.
|
||||||
//
|
//
|
||||||
// Therefore, this error should not be catchable.
|
// Therefore, this error should not be catchable.
|
||||||
Self::ErrorCustomSyntax(_, _, _) => false,
|
Self::ErrorCustomSyntax(..) => false,
|
||||||
|
|
||||||
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(_, _) => false,
|
Self::LoopBreak(..) | Self::Return(..) => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/// Is this error a system exception?
|
/// Is this error a system exception?
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub const fn is_system_exception(&self) -> bool {
|
pub const fn is_system_exception(&self) -> bool {
|
||||||
match self {
|
match self {
|
||||||
Self::ErrorSystem(_, _) => true,
|
Self::ErrorSystem(..) => true,
|
||||||
Self::ErrorParsing(_, _) => true,
|
Self::ErrorParsing(..) => true,
|
||||||
|
|
||||||
Self::ErrorCustomSyntax(_, _, _)
|
Self::ErrorCustomSyntax(..)
|
||||||
| Self::ErrorTooManyOperations(_)
|
| Self::ErrorTooManyOperations(_)
|
||||||
| Self::ErrorTooManyModules(_)
|
| Self::ErrorTooManyModules(_)
|
||||||
| Self::ErrorStackOverflow(_)
|
| Self::ErrorStackOverflow(_)
|
||||||
| Self::ErrorDataTooLarge(_, _) => true,
|
| Self::ErrorDataTooLarge(..) => true,
|
||||||
|
|
||||||
Self::ErrorTerminated(_, _) => true,
|
Self::ErrorTerminated(..) => true,
|
||||||
|
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
@ -333,58 +333,58 @@ impl EvalAltResult {
|
|||||||
);
|
);
|
||||||
|
|
||||||
match self {
|
match self {
|
||||||
Self::LoopBreak(_, _) | Self::Return(_, _) => (),
|
Self::LoopBreak(..) | Self::Return(..) => (),
|
||||||
|
|
||||||
Self::ErrorSystem(_, _)
|
Self::ErrorSystem(..)
|
||||||
| Self::ErrorParsing(_, _)
|
| Self::ErrorParsing(..)
|
||||||
| Self::ErrorUnboundThis(_)
|
| Self::ErrorUnboundThis(_)
|
||||||
| Self::ErrorFor(_)
|
| Self::ErrorFor(_)
|
||||||
| Self::ErrorArithmetic(_, _)
|
| Self::ErrorArithmetic(..)
|
||||||
| Self::ErrorTooManyOperations(_)
|
| Self::ErrorTooManyOperations(_)
|
||||||
| Self::ErrorTooManyModules(_)
|
| Self::ErrorTooManyModules(_)
|
||||||
| Self::ErrorStackOverflow(_)
|
| Self::ErrorStackOverflow(_)
|
||||||
| Self::ErrorRuntime(_, _) => (),
|
| Self::ErrorRuntime(..) => (),
|
||||||
|
|
||||||
Self::ErrorFunctionNotFound(f, _) => {
|
Self::ErrorFunctionNotFound(f, ..) => {
|
||||||
map.insert("function".into(), f.into());
|
map.insert("function".into(), f.into());
|
||||||
}
|
}
|
||||||
Self::ErrorInFunctionCall(f, s, _, _) => {
|
Self::ErrorInFunctionCall(f, s, ..) => {
|
||||||
map.insert("function".into(), f.into());
|
map.insert("function".into(), f.into());
|
||||||
map.insert("source".into(), s.into());
|
map.insert("source".into(), s.into());
|
||||||
}
|
}
|
||||||
Self::ErrorInModule(m, _, _) => {
|
Self::ErrorInModule(m, ..) => {
|
||||||
map.insert("module".into(), m.into());
|
map.insert("module".into(), m.into());
|
||||||
}
|
}
|
||||||
Self::ErrorMismatchDataType(r, a, _) | Self::ErrorMismatchOutputType(r, a, _) => {
|
Self::ErrorMismatchDataType(r, a, ..) | Self::ErrorMismatchOutputType(r, a, ..) => {
|
||||||
map.insert("requested".into(), r.into());
|
map.insert("requested".into(), r.into());
|
||||||
map.insert("actual".into(), a.into());
|
map.insert("actual".into(), a.into());
|
||||||
}
|
}
|
||||||
Self::ErrorArrayBounds(n, i, _)
|
Self::ErrorArrayBounds(n, i, ..)
|
||||||
| Self::ErrorStringBounds(n, i, _)
|
| Self::ErrorStringBounds(n, i, ..)
|
||||||
| Self::ErrorBitFieldBounds(n, i, _) => {
|
| Self::ErrorBitFieldBounds(n, i, ..) => {
|
||||||
map.insert("length".into(), (*n as INT).into());
|
map.insert("length".into(), (*n as INT).into());
|
||||||
map.insert("index".into(), (*i as INT).into());
|
map.insert("index".into(), (*i as INT).into());
|
||||||
}
|
}
|
||||||
Self::ErrorIndexingType(t, _) => {
|
Self::ErrorIndexingType(t, ..) => {
|
||||||
map.insert("type".into(), t.into());
|
map.insert("type".into(), t.into());
|
||||||
}
|
}
|
||||||
Self::ErrorVariableExists(v, _)
|
Self::ErrorVariableExists(v, ..)
|
||||||
| Self::ErrorVariableNotFound(v, _)
|
| Self::ErrorVariableNotFound(v, ..)
|
||||||
| Self::ErrorDataRace(v, _)
|
| Self::ErrorDataRace(v, ..)
|
||||||
| Self::ErrorAssignmentToConstant(v, _) => {
|
| Self::ErrorAssignmentToConstant(v, ..) => {
|
||||||
map.insert("variable".into(), v.into());
|
map.insert("variable".into(), v.into());
|
||||||
}
|
}
|
||||||
Self::ErrorModuleNotFound(m, _) => {
|
Self::ErrorModuleNotFound(m, ..) => {
|
||||||
map.insert("module".into(), m.into());
|
map.insert("module".into(), m.into());
|
||||||
}
|
}
|
||||||
Self::ErrorDotExpr(p, _) => {
|
Self::ErrorDotExpr(p, ..) => {
|
||||||
map.insert("property".into(), p.into());
|
map.insert("property".into(), p.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
Self::ErrorDataTooLarge(t, _) => {
|
Self::ErrorDataTooLarge(t, ..) => {
|
||||||
map.insert("type".into(), t.into());
|
map.insert("type".into(), t.into());
|
||||||
}
|
}
|
||||||
Self::ErrorTerminated(t, _) => {
|
Self::ErrorTerminated(t, ..) => {
|
||||||
map.insert("token".into(), t.clone());
|
map.insert("token".into(), t.clone());
|
||||||
}
|
}
|
||||||
Self::ErrorCustomSyntax(_, tokens, _) => {
|
Self::ErrorCustomSyntax(_, tokens, _) => {
|
||||||
@ -407,36 +407,36 @@ impl EvalAltResult {
|
|||||||
#[must_use]
|
#[must_use]
|
||||||
pub const fn position(&self) -> Position {
|
pub const fn position(&self) -> Position {
|
||||||
match self {
|
match self {
|
||||||
Self::ErrorSystem(_, _) => Position::NONE,
|
Self::ErrorSystem(..) => Position::NONE,
|
||||||
|
|
||||||
Self::ErrorParsing(_, pos)
|
Self::ErrorParsing(.., pos)
|
||||||
| Self::ErrorFunctionNotFound(_, pos)
|
| Self::ErrorFunctionNotFound(.., pos)
|
||||||
| Self::ErrorInFunctionCall(_, _, _, pos)
|
| Self::ErrorInFunctionCall(.., pos)
|
||||||
| Self::ErrorInModule(_, _, pos)
|
| Self::ErrorInModule(.., pos)
|
||||||
| Self::ErrorUnboundThis(pos)
|
| Self::ErrorUnboundThis(pos)
|
||||||
| Self::ErrorMismatchDataType(_, _, pos)
|
| Self::ErrorMismatchDataType(.., pos)
|
||||||
| Self::ErrorArrayBounds(_, _, pos)
|
| Self::ErrorArrayBounds(.., pos)
|
||||||
| Self::ErrorStringBounds(_, _, pos)
|
| Self::ErrorStringBounds(.., pos)
|
||||||
| Self::ErrorBitFieldBounds(_, _, pos)
|
| Self::ErrorBitFieldBounds(.., pos)
|
||||||
| Self::ErrorIndexingType(_, pos)
|
| Self::ErrorIndexingType(.., pos)
|
||||||
| Self::ErrorFor(pos)
|
| Self::ErrorFor(pos)
|
||||||
| Self::ErrorVariableExists(_, pos)
|
| Self::ErrorVariableExists(.., pos)
|
||||||
| Self::ErrorVariableNotFound(_, pos)
|
| Self::ErrorVariableNotFound(.., pos)
|
||||||
| Self::ErrorModuleNotFound(_, pos)
|
| Self::ErrorModuleNotFound(.., pos)
|
||||||
| Self::ErrorDataRace(_, pos)
|
| Self::ErrorDataRace(.., pos)
|
||||||
| Self::ErrorAssignmentToConstant(_, pos)
|
| Self::ErrorAssignmentToConstant(.., pos)
|
||||||
| Self::ErrorMismatchOutputType(_, _, pos)
|
| Self::ErrorMismatchOutputType(.., pos)
|
||||||
| Self::ErrorDotExpr(_, pos)
|
| Self::ErrorDotExpr(.., pos)
|
||||||
| Self::ErrorArithmetic(_, pos)
|
| Self::ErrorArithmetic(.., pos)
|
||||||
| 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::ErrorCustomSyntax(_, _, pos)
|
| Self::ErrorCustomSyntax(.., pos)
|
||||||
| Self::ErrorRuntime(_, pos)
|
| Self::ErrorRuntime(.., pos)
|
||||||
| Self::LoopBreak(_, pos)
|
| Self::LoopBreak(.., pos)
|
||||||
| Self::Return(_, pos) => *pos,
|
| Self::Return(.., pos) => *pos,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/// Remove the [position][Position] information from this error.
|
/// Remove the [position][Position] information from this error.
|
||||||
@ -456,36 +456,36 @@ impl EvalAltResult {
|
|||||||
/// Override the [position][Position] of this error.
|
/// Override the [position][Position] of this error.
|
||||||
pub fn set_position(&mut self, new_position: Position) -> &mut Self {
|
pub fn set_position(&mut self, new_position: Position) -> &mut Self {
|
||||||
match self {
|
match self {
|
||||||
Self::ErrorSystem(_, _) => (),
|
Self::ErrorSystem(..) => (),
|
||||||
|
|
||||||
Self::ErrorParsing(_, pos)
|
Self::ErrorParsing(.., pos)
|
||||||
| Self::ErrorFunctionNotFound(_, pos)
|
| Self::ErrorFunctionNotFound(.., pos)
|
||||||
| Self::ErrorInFunctionCall(_, _, _, pos)
|
| Self::ErrorInFunctionCall(.., pos)
|
||||||
| Self::ErrorInModule(_, _, pos)
|
| Self::ErrorInModule(.., pos)
|
||||||
| Self::ErrorUnboundThis(pos)
|
| Self::ErrorUnboundThis(pos)
|
||||||
| Self::ErrorMismatchDataType(_, _, pos)
|
| Self::ErrorMismatchDataType(.., pos)
|
||||||
| Self::ErrorArrayBounds(_, _, pos)
|
| Self::ErrorArrayBounds(.., pos)
|
||||||
| Self::ErrorStringBounds(_, _, pos)
|
| Self::ErrorStringBounds(.., pos)
|
||||||
| Self::ErrorBitFieldBounds(_, _, pos)
|
| Self::ErrorBitFieldBounds(.., pos)
|
||||||
| Self::ErrorIndexingType(_, pos)
|
| Self::ErrorIndexingType(.., pos)
|
||||||
| Self::ErrorFor(pos)
|
| Self::ErrorFor(pos)
|
||||||
| Self::ErrorVariableExists(_, pos)
|
| Self::ErrorVariableExists(.., pos)
|
||||||
| Self::ErrorVariableNotFound(_, pos)
|
| Self::ErrorVariableNotFound(.., pos)
|
||||||
| Self::ErrorModuleNotFound(_, pos)
|
| Self::ErrorModuleNotFound(.., pos)
|
||||||
| Self::ErrorDataRace(_, pos)
|
| Self::ErrorDataRace(.., pos)
|
||||||
| Self::ErrorAssignmentToConstant(_, pos)
|
| Self::ErrorAssignmentToConstant(.., pos)
|
||||||
| Self::ErrorMismatchOutputType(_, _, pos)
|
| Self::ErrorMismatchOutputType(.., pos)
|
||||||
| Self::ErrorDotExpr(_, pos)
|
| Self::ErrorDotExpr(.., pos)
|
||||||
| Self::ErrorArithmetic(_, pos)
|
| Self::ErrorArithmetic(.., pos)
|
||||||
| 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::ErrorCustomSyntax(_, _, pos)
|
| Self::ErrorCustomSyntax(.., 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,
|
||||||
}
|
}
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
@ -52,7 +52,7 @@ impl fmt::Display for LexError {
|
|||||||
Self::ImproperSymbol(s, d) if d.is_empty() => {
|
Self::ImproperSymbol(s, d) if d.is_empty() => {
|
||||||
write!(f, "Invalid symbol encountered: '{}'", s)
|
write!(f, "Invalid symbol encountered: '{}'", s)
|
||||||
}
|
}
|
||||||
Self::ImproperSymbol(_, d) => f.write_str(d),
|
Self::ImproperSymbol(.., d) => f.write_str(d),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -310,7 +310,7 @@ impl Scope<'_> {
|
|||||||
#[inline]
|
#[inline]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn contains(&self, name: &str) -> bool {
|
pub fn contains(&self, name: &str) -> bool {
|
||||||
self.names.iter().any(|(key, _)| name == key)
|
self.names.iter().any(|(key, ..)| name == key)
|
||||||
}
|
}
|
||||||
/// Find an entry in the [`Scope`], starting from the last.
|
/// Find an entry in the [`Scope`], starting from the last.
|
||||||
#[inline]
|
#[inline]
|
||||||
@ -322,7 +322,7 @@ impl Scope<'_> {
|
|||||||
.iter()
|
.iter()
|
||||||
.rev() // Always search a Scope in reverse order
|
.rev() // Always search a Scope in reverse order
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.find_map(|(i, (key, _))| {
|
.find_map(|(i, (key, ..))| {
|
||||||
if name == key {
|
if name == key {
|
||||||
let index = len - 1 - i;
|
let index = len - 1 - i;
|
||||||
Some((index, self.values[index].access_mode()))
|
Some((index, self.values[index].access_mode()))
|
||||||
@ -352,8 +352,8 @@ impl Scope<'_> {
|
|||||||
.iter()
|
.iter()
|
||||||
.rev()
|
.rev()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.find(|(_, (key, _))| name == key)
|
.find(|(.., (key, ..))| name == key)
|
||||||
.and_then(|(index, _)| self.values[len - 1 - index].flatten_clone().try_cast())
|
.and_then(|(index, ..)| self.values[len - 1 - index].flatten_clone().try_cast())
|
||||||
}
|
}
|
||||||
/// Check if the named entry in the [`Scope`] is constant.
|
/// Check if the named entry in the [`Scope`] is constant.
|
||||||
///
|
///
|
||||||
@ -374,7 +374,7 @@ impl Scope<'_> {
|
|||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn is_constant(&self, name: &str) -> Option<bool> {
|
pub fn is_constant(&self, name: &str) -> Option<bool> {
|
||||||
self.get_index(name).and_then(|(_, access)| match access {
|
self.get_index(name).and_then(|(.., access)| match access {
|
||||||
AccessMode::ReadWrite => None,
|
AccessMode::ReadWrite => None,
|
||||||
AccessMode::ReadOnly => Some(true),
|
AccessMode::ReadOnly => Some(true),
|
||||||
})
|
})
|
||||||
@ -411,7 +411,7 @@ impl Scope<'_> {
|
|||||||
value: impl Variant + Clone,
|
value: impl Variant + Clone,
|
||||||
) -> &mut Self {
|
) -> &mut Self {
|
||||||
match self.get_index(name.as_ref()) {
|
match self.get_index(name.as_ref()) {
|
||||||
None | Some((_, AccessMode::ReadOnly)) => {
|
None | Some((.., AccessMode::ReadOnly)) => {
|
||||||
self.push(name, value);
|
self.push(name, value);
|
||||||
}
|
}
|
||||||
Some((index, AccessMode::ReadWrite)) => {
|
Some((index, AccessMode::ReadWrite)) => {
|
||||||
@ -453,7 +453,7 @@ impl Scope<'_> {
|
|||||||
None => {
|
None => {
|
||||||
self.push(name, value);
|
self.push(name, value);
|
||||||
}
|
}
|
||||||
Some((_, AccessMode::ReadOnly)) => panic!("variable {} is constant", name.as_ref()),
|
Some((.., AccessMode::ReadOnly)) => panic!("variable {} is constant", name.as_ref()),
|
||||||
Some((index, AccessMode::ReadWrite)) => {
|
Some((index, AccessMode::ReadWrite)) => {
|
||||||
let value_ref = self.values.get_mut(index).unwrap();
|
let value_ref = self.values.get_mut(index).unwrap();
|
||||||
*value_ref = Dynamic::from(value);
|
*value_ref = Dynamic::from(value);
|
||||||
@ -511,7 +511,7 @@ impl Scope<'_> {
|
|||||||
#[cfg(not(feature = "no_module"))]
|
#[cfg(not(feature = "no_module"))]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub(crate) fn add_entry_alias(&mut self, index: usize, alias: Identifier) -> &mut Self {
|
pub(crate) fn add_entry_alias(&mut self, index: usize, alias: Identifier) -> &mut Self {
|
||||||
let (_, aliases) = self.names.get_mut(index).unwrap();
|
let (.., aliases) = self.names.get_mut(index).unwrap();
|
||||||
match aliases {
|
match aliases {
|
||||||
None => {
|
None => {
|
||||||
let mut list = StaticVec::new_const();
|
let mut list = StaticVec::new_const();
|
||||||
@ -533,7 +533,7 @@ impl Scope<'_> {
|
|||||||
self.names.iter().rev().enumerate().fold(
|
self.names.iter().rev().enumerate().fold(
|
||||||
Self::new(),
|
Self::new(),
|
||||||
|mut entries, (index, (name, alias))| {
|
|mut entries, (index, (name, alias))| {
|
||||||
if !entries.names.iter().any(|(key, _)| key == name) {
|
if !entries.names.iter().any(|(key, ..)| key == name) {
|
||||||
let orig_value = &self.values[len - 1 - index];
|
let orig_value = &self.values[len - 1 - index];
|
||||||
let mut value = orig_value.clone();
|
let mut value = orig_value.clone();
|
||||||
value.set_access_mode(orig_value.access_mode());
|
value.set_access_mode(orig_value.access_mode());
|
||||||
@ -593,7 +593,7 @@ impl Scope<'_> {
|
|||||||
self.names
|
self.names
|
||||||
.iter()
|
.iter()
|
||||||
.zip(self.values.iter())
|
.zip(self.values.iter())
|
||||||
.map(|((name, _), value)| (name.as_ref(), value.is_read_only(), value))
|
.map(|((name, ..), value)| (name.as_ref(), value.is_read_only(), value))
|
||||||
}
|
}
|
||||||
/// Remove a range of entries within the [`Scope`].
|
/// Remove a range of entries within the [`Scope`].
|
||||||
///
|
///
|
||||||
|
@ -330,7 +330,7 @@ fn test_call_fn_events() -> Result<(), Box<EvalAltResult>> {
|
|||||||
"update" => engine
|
"update" => engine
|
||||||
.call_fn(scope, ast, "update", (event_data,))
|
.call_fn(scope, ast, "update", (event_data,))
|
||||||
.or_else(|err| match *err {
|
.or_else(|err| match *err {
|
||||||
EvalAltResult::ErrorFunctionNotFound(fn_name, _)
|
EvalAltResult::ErrorFunctionNotFound(fn_name, ..)
|
||||||
if fn_name.starts_with("update") =>
|
if fn_name.starts_with("update") =>
|
||||||
{
|
{
|
||||||
// Default implementation of 'update' event handler
|
// Default implementation of 'update' event handler
|
||||||
|
@ -251,7 +251,7 @@ fn test_closures_data_race() -> Result<(), Box<EvalAltResult>> {
|
|||||||
"
|
"
|
||||||
)
|
)
|
||||||
.expect_err("should error"),
|
.expect_err("should error"),
|
||||||
EvalAltResult::ErrorDataRace(_, _)
|
EvalAltResult::ErrorDataRace(..)
|
||||||
));
|
));
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -10,13 +10,13 @@ fn test_constant() -> Result<(), Box<EvalAltResult>> {
|
|||||||
*engine
|
*engine
|
||||||
.eval::<INT>("const x = 123; x = 42;")
|
.eval::<INT>("const x = 123; x = 42;")
|
||||||
.expect_err("expects error"),
|
.expect_err("expects error"),
|
||||||
EvalAltResult::ErrorParsing(ParseErrorType::AssignmentToConstant(x), _) if x == "x"
|
EvalAltResult::ErrorParsing(ParseErrorType::AssignmentToConstant(x), ..) if x == "x"
|
||||||
));
|
));
|
||||||
|
|
||||||
#[cfg(not(feature = "no_index"))]
|
#[cfg(not(feature = "no_index"))]
|
||||||
assert!(matches!(
|
assert!(matches!(
|
||||||
*engine.run("const x = [1, 2, 3, 4, 5]; x[2] = 42;").expect_err("expects error"),
|
*engine.run("const x = [1, 2, 3, 4, 5]; x[2] = 42;").expect_err("expects error"),
|
||||||
EvalAltResult::ErrorAssignmentToConstant(x, _) if x == "x"
|
EvalAltResult::ErrorAssignmentToConstant(x, ..) if x == "x"
|
||||||
));
|
));
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -31,7 +31,7 @@ fn test_constant_scope() -> Result<(), Box<EvalAltResult>> {
|
|||||||
|
|
||||||
assert!(matches!(
|
assert!(matches!(
|
||||||
*engine.run_with_scope(&mut scope, "x = 1").expect_err("expects error"),
|
*engine.run_with_scope(&mut scope, "x = 1").expect_err("expects error"),
|
||||||
EvalAltResult::ErrorAssignmentToConstant(x, _) if x == "x"
|
EvalAltResult::ErrorAssignmentToConstant(x, ..) if x == "x"
|
||||||
));
|
));
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -87,7 +87,7 @@ fn test_constant_mut() -> Result<(), Box<EvalAltResult>> {
|
|||||||
"
|
"
|
||||||
)
|
)
|
||||||
.expect_err("should error"),
|
.expect_err("should error"),
|
||||||
EvalAltResult::ErrorAssignmentToConstant(_, _)
|
EvalAltResult::ErrorAssignmentToConstant(..)
|
||||||
));
|
));
|
||||||
|
|
||||||
let mut scope = Scope::new();
|
let mut scope = Scope::new();
|
||||||
@ -120,7 +120,7 @@ fn test_constant_mut() -> Result<(), Box<EvalAltResult>> {
|
|||||||
*engine
|
*engine
|
||||||
.run_with_scope(&mut scope, "MY_NUMBER.value = 42;")
|
.run_with_scope(&mut scope, "MY_NUMBER.value = 42;")
|
||||||
.expect_err("should error"),
|
.expect_err("should error"),
|
||||||
EvalAltResult::ErrorAssignmentToConstant(_, _)
|
EvalAltResult::ErrorAssignmentToConstant(..)
|
||||||
));
|
));
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -81,7 +81,7 @@ fn test_custom_syntax() -> Result<(), Box<EvalAltResult>> {
|
|||||||
*engine
|
*engine
|
||||||
.run("let foo = (exec [x<<15] -> { x += 2 } while x < 42) * 10;")
|
.run("let foo = (exec [x<<15] -> { x += 2 } while x < 42) * 10;")
|
||||||
.expect_err("should error"),
|
.expect_err("should error"),
|
||||||
EvalAltResult::ErrorRuntime(_, _)
|
EvalAltResult::ErrorRuntime(..)
|
||||||
));
|
));
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
|
@ -38,7 +38,7 @@ fn test_max_string_size() -> Result<(), Box<EvalAltResult>> {
|
|||||||
"#
|
"#
|
||||||
)
|
)
|
||||||
.expect_err("should error"),
|
.expect_err("should error"),
|
||||||
EvalAltResult::ErrorDataTooLarge(_, _)
|
EvalAltResult::ErrorDataTooLarge(..)
|
||||||
));
|
));
|
||||||
|
|
||||||
#[cfg(not(feature = "no_object"))]
|
#[cfg(not(feature = "no_object"))]
|
||||||
@ -52,7 +52,7 @@ fn test_max_string_size() -> Result<(), Box<EvalAltResult>> {
|
|||||||
"#
|
"#
|
||||||
)
|
)
|
||||||
.expect_err("should error"),
|
.expect_err("should error"),
|
||||||
EvalAltResult::ErrorDataTooLarge(_, _)
|
EvalAltResult::ErrorDataTooLarge(..)
|
||||||
));
|
));
|
||||||
|
|
||||||
engine.set_max_string_size(0);
|
engine.set_max_string_size(0);
|
||||||
@ -98,7 +98,7 @@ fn test_max_array_size() -> Result<(), Box<EvalAltResult>> {
|
|||||||
"
|
"
|
||||||
)
|
)
|
||||||
.expect_err("should error"),
|
.expect_err("should error"),
|
||||||
EvalAltResult::ErrorDataTooLarge(_, _)
|
EvalAltResult::ErrorDataTooLarge(..)
|
||||||
));
|
));
|
||||||
|
|
||||||
#[cfg(not(feature = "no_closure"))]
|
#[cfg(not(feature = "no_closure"))]
|
||||||
@ -131,7 +131,7 @@ fn test_max_array_size() -> Result<(), Box<EvalAltResult>> {
|
|||||||
"
|
"
|
||||||
)
|
)
|
||||||
.expect_err("should error"),
|
.expect_err("should error"),
|
||||||
EvalAltResult::ErrorDataTooLarge(_, _)
|
EvalAltResult::ErrorDataTooLarge(..)
|
||||||
));
|
));
|
||||||
|
|
||||||
assert!(matches!(
|
assert!(matches!(
|
||||||
@ -143,7 +143,7 @@ fn test_max_array_size() -> Result<(), Box<EvalAltResult>> {
|
|||||||
"
|
"
|
||||||
)
|
)
|
||||||
.expect_err("should error"),
|
.expect_err("should error"),
|
||||||
EvalAltResult::ErrorDataTooLarge(_, _)
|
EvalAltResult::ErrorDataTooLarge(..)
|
||||||
));
|
));
|
||||||
|
|
||||||
#[cfg(not(feature = "no_object"))]
|
#[cfg(not(feature = "no_object"))]
|
||||||
@ -169,7 +169,7 @@ fn test_max_array_size() -> Result<(), Box<EvalAltResult>> {
|
|||||||
"
|
"
|
||||||
)
|
)
|
||||||
.expect_err("should error"),
|
.expect_err("should error"),
|
||||||
EvalAltResult::ErrorDataTooLarge(_, _)
|
EvalAltResult::ErrorDataTooLarge(..)
|
||||||
));
|
));
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
@ -191,7 +191,7 @@ fn test_max_array_size() -> Result<(), Box<EvalAltResult>> {
|
|||||||
"
|
"
|
||||||
)
|
)
|
||||||
.expect_err("should error"),
|
.expect_err("should error"),
|
||||||
EvalAltResult::ErrorDataTooLarge(_, _)
|
EvalAltResult::ErrorDataTooLarge(..)
|
||||||
));
|
));
|
||||||
|
|
||||||
#[cfg(not(feature = "no_object"))]
|
#[cfg(not(feature = "no_object"))]
|
||||||
@ -204,7 +204,7 @@ fn test_max_array_size() -> Result<(), Box<EvalAltResult>> {
|
|||||||
"
|
"
|
||||||
)
|
)
|
||||||
.expect_err("should error"),
|
.expect_err("should error"),
|
||||||
EvalAltResult::ErrorDataTooLarge(_, _)
|
EvalAltResult::ErrorDataTooLarge(..)
|
||||||
));
|
));
|
||||||
|
|
||||||
assert!(matches!(
|
assert!(matches!(
|
||||||
@ -218,7 +218,7 @@ fn test_max_array_size() -> Result<(), Box<EvalAltResult>> {
|
|||||||
"
|
"
|
||||||
)
|
)
|
||||||
.expect_err("should error"),
|
.expect_err("should error"),
|
||||||
EvalAltResult::ErrorDataTooLarge(_, _)
|
EvalAltResult::ErrorDataTooLarge(..)
|
||||||
));
|
));
|
||||||
|
|
||||||
engine.set_max_array_size(0);
|
engine.set_max_array_size(0);
|
||||||
@ -282,7 +282,7 @@ fn test_max_map_size() -> Result<(), Box<EvalAltResult>> {
|
|||||||
"
|
"
|
||||||
)
|
)
|
||||||
.expect_err("should error"),
|
.expect_err("should error"),
|
||||||
EvalAltResult::ErrorDataTooLarge(_, _)
|
EvalAltResult::ErrorDataTooLarge(..)
|
||||||
));
|
));
|
||||||
|
|
||||||
assert!(matches!(
|
assert!(matches!(
|
||||||
@ -295,7 +295,7 @@ fn test_max_map_size() -> Result<(), Box<EvalAltResult>> {
|
|||||||
"
|
"
|
||||||
)
|
)
|
||||||
.expect_err("should error"),
|
.expect_err("should error"),
|
||||||
EvalAltResult::ErrorDataTooLarge(_, _)
|
EvalAltResult::ErrorDataTooLarge(..)
|
||||||
));
|
));
|
||||||
|
|
||||||
assert!(matches!(
|
assert!(matches!(
|
||||||
@ -307,7 +307,7 @@ fn test_max_map_size() -> Result<(), Box<EvalAltResult>> {
|
|||||||
"
|
"
|
||||||
)
|
)
|
||||||
.expect_err("should error"),
|
.expect_err("should error"),
|
||||||
EvalAltResult::ErrorDataTooLarge(_, _)
|
EvalAltResult::ErrorDataTooLarge(..)
|
||||||
));
|
));
|
||||||
|
|
||||||
#[cfg(not(feature = "no_index"))]
|
#[cfg(not(feature = "no_index"))]
|
||||||
@ -320,7 +320,7 @@ fn test_max_map_size() -> Result<(), Box<EvalAltResult>> {
|
|||||||
"
|
"
|
||||||
)
|
)
|
||||||
.expect_err("should error"),
|
.expect_err("should error"),
|
||||||
EvalAltResult::ErrorDataTooLarge(_, _)
|
EvalAltResult::ErrorDataTooLarge(..)
|
||||||
));
|
));
|
||||||
|
|
||||||
engine.set_max_map_size(0);
|
engine.set_max_map_size(0);
|
||||||
|
@ -171,7 +171,7 @@ fn test_eval_disabled() -> Result<(), Box<EvalAltResult>> {
|
|||||||
.compile(r#"eval("40 + 2")"#)
|
.compile(r#"eval("40 + 2")"#)
|
||||||
.expect_err("should error")
|
.expect_err("should error")
|
||||||
.0,
|
.0,
|
||||||
ParseErrorType::BadInput(LexError::ImproperSymbol(err, _)) if err == "eval"
|
ParseErrorType::BadInput(LexError::ImproperSymbol(err, ..)) if err == "eval"
|
||||||
));
|
));
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -73,7 +73,7 @@ fn test_fn_ptr() -> Result<(), Box<EvalAltResult>> {
|
|||||||
"#
|
"#
|
||||||
)
|
)
|
||||||
.expect_err("should error"),
|
.expect_err("should error"),
|
||||||
EvalAltResult::ErrorInFunctionCall(fn_name, _, err, _)
|
EvalAltResult::ErrorInFunctionCall(fn_name, _, err, ..)
|
||||||
if fn_name == "foo" && matches!(*err, EvalAltResult::ErrorUnboundThis(_))
|
if fn_name == "foo" && matches!(*err, EvalAltResult::ErrorUnboundThis(_))
|
||||||
));
|
));
|
||||||
|
|
||||||
|
@ -92,8 +92,8 @@ fn test_functions_global_module() -> Result<(), Box<EvalAltResult>> {
|
|||||||
foo()
|
foo()
|
||||||
}
|
}
|
||||||
").expect_err("should error"),
|
").expect_err("should error"),
|
||||||
EvalAltResult::ErrorInFunctionCall(_, _, err, _)
|
EvalAltResult::ErrorInFunctionCall(.., err, _)
|
||||||
if matches!(&*err, EvalAltResult::ErrorVariableNotFound(v, _) if v == "global::ANSWER")
|
if matches!(&*err, EvalAltResult::ErrorVariableNotFound(v, ..) if v == "global::ANSWER")
|
||||||
));
|
));
|
||||||
|
|
||||||
engine.register_result_fn(
|
engine.register_result_fn(
|
||||||
@ -110,8 +110,8 @@ fn test_functions_global_module() -> Result<(), Box<EvalAltResult>> {
|
|||||||
global::LOCAL_VALUE
|
global::LOCAL_VALUE
|
||||||
});
|
});
|
||||||
").expect_err("should error"),
|
").expect_err("should error"),
|
||||||
EvalAltResult::ErrorInFunctionCall(_, _, err, _)
|
EvalAltResult::ErrorInFunctionCall(.., err, _)
|
||||||
if matches!(&*err, EvalAltResult::ErrorVariableNotFound(v, _) if v == "global::LOCAL_VALUE")
|
if matches!(&*err, EvalAltResult::ErrorVariableNotFound(v, ..) if v == "global::LOCAL_VALUE")
|
||||||
));
|
));
|
||||||
|
|
||||||
#[cfg(not(feature = "no_closure"))]
|
#[cfg(not(feature = "no_closure"))]
|
||||||
|
@ -170,7 +170,7 @@ fn test_function_pointers() -> Result<(), Box<EvalAltResult>> {
|
|||||||
#[cfg(not(feature = "no_object"))]
|
#[cfg(not(feature = "no_object"))]
|
||||||
assert!(matches!(
|
assert!(matches!(
|
||||||
*engine.eval::<INT>(r#"let f = Fn("abc"); f.call(0)"#).expect_err("should error"),
|
*engine.eval::<INT>(r#"let f = Fn("abc"); f.call(0)"#).expect_err("should error"),
|
||||||
EvalAltResult::ErrorFunctionNotFound(f, _) if f.starts_with("abc (")
|
EvalAltResult::ErrorFunctionNotFound(f, ..) if f.starts_with("abc (")
|
||||||
));
|
));
|
||||||
|
|
||||||
#[cfg(not(feature = "no_object"))]
|
#[cfg(not(feature = "no_object"))]
|
||||||
|
@ -53,7 +53,7 @@ b`: 1}; y["a\nb"]
|
|||||||
*engine
|
*engine
|
||||||
.eval::<INT>("let y = #{`a${1}`: 1}; y.a1")
|
.eval::<INT>("let y = #{`a${1}`: 1}; y.a1")
|
||||||
.expect_err("should error"),
|
.expect_err("should error"),
|
||||||
EvalAltResult::ErrorParsing(ParseErrorType::PropertyExpected, _)
|
EvalAltResult::ErrorParsing(ParseErrorType::PropertyExpected, ..)
|
||||||
));
|
));
|
||||||
|
|
||||||
assert!(engine.eval::<bool>(r#"let y = #{a: 1, b: 2, c: 3}; "c" in y"#)?);
|
assert!(engine.eval::<bool>(r#"let y = #{a: 1, b: 2, c: 3}; "c" in y"#)?);
|
||||||
@ -205,7 +205,7 @@ fn test_map_json() -> Result<(), Box<EvalAltResult>> {
|
|||||||
|
|
||||||
assert!(matches!(
|
assert!(matches!(
|
||||||
*engine.parse_json(" 123", true).expect_err("should error"),
|
*engine.parse_json(" 123", true).expect_err("should error"),
|
||||||
EvalAltResult::ErrorParsing(ParseErrorType::MissingToken(token, _), _)
|
EvalAltResult::ErrorParsing(ParseErrorType::MissingToken(token, ..), ..)
|
||||||
if token == "{"
|
if token == "{"
|
||||||
));
|
));
|
||||||
|
|
||||||
|
@ -37,37 +37,37 @@ fn test_math() -> Result<(), Box<EvalAltResult>> {
|
|||||||
*engine
|
*engine
|
||||||
.eval::<INT>("abs(-9223372036854775808)")
|
.eval::<INT>("abs(-9223372036854775808)")
|
||||||
.expect_err("expects negation overflow"),
|
.expect_err("expects negation overflow"),
|
||||||
EvalAltResult::ErrorArithmetic(_, _)
|
EvalAltResult::ErrorArithmetic(..)
|
||||||
));
|
));
|
||||||
assert!(matches!(
|
assert!(matches!(
|
||||||
*engine
|
*engine
|
||||||
.eval::<INT>("9223372036854775807 + 1")
|
.eval::<INT>("9223372036854775807 + 1")
|
||||||
.expect_err("expects overflow"),
|
.expect_err("expects overflow"),
|
||||||
EvalAltResult::ErrorArithmetic(_, _)
|
EvalAltResult::ErrorArithmetic(..)
|
||||||
));
|
));
|
||||||
assert!(matches!(
|
assert!(matches!(
|
||||||
*engine
|
*engine
|
||||||
.eval::<INT>("-9223372036854775808 - 1")
|
.eval::<INT>("-9223372036854775808 - 1")
|
||||||
.expect_err("expects underflow"),
|
.expect_err("expects underflow"),
|
||||||
EvalAltResult::ErrorArithmetic(_, _)
|
EvalAltResult::ErrorArithmetic(..)
|
||||||
));
|
));
|
||||||
assert!(matches!(
|
assert!(matches!(
|
||||||
*engine
|
*engine
|
||||||
.eval::<INT>("9223372036854775807 * 9223372036854775807")
|
.eval::<INT>("9223372036854775807 * 9223372036854775807")
|
||||||
.expect_err("expects overflow"),
|
.expect_err("expects overflow"),
|
||||||
EvalAltResult::ErrorArithmetic(_, _)
|
EvalAltResult::ErrorArithmetic(..)
|
||||||
));
|
));
|
||||||
assert!(matches!(
|
assert!(matches!(
|
||||||
*engine
|
*engine
|
||||||
.eval::<INT>("9223372036854775807 / 0")
|
.eval::<INT>("9223372036854775807 / 0")
|
||||||
.expect_err("expects division by zero"),
|
.expect_err("expects division by zero"),
|
||||||
EvalAltResult::ErrorArithmetic(_, _)
|
EvalAltResult::ErrorArithmetic(..)
|
||||||
));
|
));
|
||||||
assert!(matches!(
|
assert!(matches!(
|
||||||
*engine
|
*engine
|
||||||
.eval::<INT>("9223372036854775807 % 0")
|
.eval::<INT>("9223372036854775807 % 0")
|
||||||
.expect_err("expects division by zero"),
|
.expect_err("expects division by zero"),
|
||||||
EvalAltResult::ErrorArithmetic(_, _)
|
EvalAltResult::ErrorArithmetic(..)
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -77,31 +77,31 @@ fn test_math() -> Result<(), Box<EvalAltResult>> {
|
|||||||
*engine
|
*engine
|
||||||
.eval::<INT>("2147483647 + 1")
|
.eval::<INT>("2147483647 + 1")
|
||||||
.expect_err("expects overflow"),
|
.expect_err("expects overflow"),
|
||||||
EvalAltResult::ErrorArithmetic(_, _)
|
EvalAltResult::ErrorArithmetic(..)
|
||||||
));
|
));
|
||||||
assert!(matches!(
|
assert!(matches!(
|
||||||
*engine
|
*engine
|
||||||
.eval::<INT>("-2147483648 - 1")
|
.eval::<INT>("-2147483648 - 1")
|
||||||
.expect_err("expects underflow"),
|
.expect_err("expects underflow"),
|
||||||
EvalAltResult::ErrorArithmetic(_, _)
|
EvalAltResult::ErrorArithmetic(..)
|
||||||
));
|
));
|
||||||
assert!(matches!(
|
assert!(matches!(
|
||||||
*engine
|
*engine
|
||||||
.eval::<INT>("2147483647 * 2147483647")
|
.eval::<INT>("2147483647 * 2147483647")
|
||||||
.expect_err("expects overflow"),
|
.expect_err("expects overflow"),
|
||||||
EvalAltResult::ErrorArithmetic(_, _)
|
EvalAltResult::ErrorArithmetic(..)
|
||||||
));
|
));
|
||||||
assert!(matches!(
|
assert!(matches!(
|
||||||
*engine
|
*engine
|
||||||
.eval::<INT>("2147483647 / 0")
|
.eval::<INT>("2147483647 / 0")
|
||||||
.expect_err("expects division by zero"),
|
.expect_err("expects division by zero"),
|
||||||
EvalAltResult::ErrorArithmetic(_, _)
|
EvalAltResult::ErrorArithmetic(..)
|
||||||
));
|
));
|
||||||
assert!(matches!(
|
assert!(matches!(
|
||||||
*engine
|
*engine
|
||||||
.eval::<INT>("2147483647 % 0")
|
.eval::<INT>("2147483647 % 0")
|
||||||
.expect_err("expects division by zero"),
|
.expect_err("expects division by zero"),
|
||||||
EvalAltResult::ErrorArithmetic(_, _)
|
EvalAltResult::ErrorArithmetic(..)
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,7 @@ fn test_mismatched_op() {
|
|||||||
|
|
||||||
assert!(matches!(
|
assert!(matches!(
|
||||||
*engine.eval::<INT>(r#""hello, " + "world!""#).expect_err("expects error"),
|
*engine.eval::<INT>(r#""hello, " + "world!""#).expect_err("expects error"),
|
||||||
EvalAltResult::ErrorMismatchOutputType(need, actual, _) if need == std::any::type_name::<INT>() && actual == "string"
|
EvalAltResult::ErrorMismatchOutputType(need, actual, ..) if need == std::any::type_name::<INT>() && actual == "string"
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -35,18 +35,18 @@ fn test_mismatched_op_custom_type() -> Result<(), Box<EvalAltResult>> {
|
|||||||
let y = new_ts();
|
let y = new_ts();
|
||||||
x == y
|
x == y
|
||||||
").expect_err("should error"),
|
").expect_err("should error"),
|
||||||
EvalAltResult::ErrorFunctionNotFound(f, _) if f == "== (TestStruct, TestStruct)"));
|
EvalAltResult::ErrorFunctionNotFound(f, ..) if f == "== (TestStruct, TestStruct)"));
|
||||||
|
|
||||||
assert!(!engine.eval::<bool>("new_ts() == 42")?);
|
assert!(!engine.eval::<bool>("new_ts() == 42")?);
|
||||||
|
|
||||||
assert!(matches!(
|
assert!(matches!(
|
||||||
*engine.eval::<INT>("60 + new_ts()").expect_err("should error"),
|
*engine.eval::<INT>("60 + new_ts()").expect_err("should error"),
|
||||||
EvalAltResult::ErrorFunctionNotFound(f, _) if f == format!("+ ({}, TestStruct)", std::any::type_name::<INT>())
|
EvalAltResult::ErrorFunctionNotFound(f, ..) if f == format!("+ ({}, TestStruct)", std::any::type_name::<INT>())
|
||||||
));
|
));
|
||||||
|
|
||||||
assert!(matches!(
|
assert!(matches!(
|
||||||
*engine.eval::<TestStruct>("42").expect_err("should error"),
|
*engine.eval::<TestStruct>("42").expect_err("should error"),
|
||||||
EvalAltResult::ErrorMismatchOutputType(need, actual, _)
|
EvalAltResult::ErrorMismatchOutputType(need, actual, ..)
|
||||||
if need == "TestStruct" && actual == std::any::type_name::<INT>()
|
if need == "TestStruct" && actual == std::any::type_name::<INT>()
|
||||||
));
|
));
|
||||||
|
|
||||||
|
@ -237,7 +237,7 @@ fn test_module_resolver() -> Result<(), Box<EvalAltResult>> {
|
|||||||
"#
|
"#
|
||||||
)
|
)
|
||||||
.expect_err("should error"),
|
.expect_err("should error"),
|
||||||
EvalAltResult::ErrorInFunctionCall(fn_name, _, _, _) if fn_name == "foo"
|
EvalAltResult::ErrorInFunctionCall(fn_name, _, ..) if fn_name == "foo"
|
||||||
));
|
));
|
||||||
|
|
||||||
engine.set_max_modules(1000);
|
engine.set_max_modules(1000);
|
||||||
@ -369,7 +369,7 @@ fn test_module_from_ast() -> Result<(), Box<EvalAltResult>> {
|
|||||||
*engine
|
*engine
|
||||||
.run(r#"import "testing" as ttt; ttt::hidden()"#)
|
.run(r#"import "testing" as ttt; ttt::hidden()"#)
|
||||||
.expect_err("should error"),
|
.expect_err("should error"),
|
||||||
EvalAltResult::ErrorFunctionNotFound(fn_name, _) if fn_name == "ttt::hidden ()"
|
EvalAltResult::ErrorFunctionNotFound(fn_name, ..) if fn_name == "ttt::hidden ()"
|
||||||
));
|
));
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -381,13 +381,13 @@ fn test_module_export() -> Result<(), Box<EvalAltResult>> {
|
|||||||
|
|
||||||
assert!(matches!(
|
assert!(matches!(
|
||||||
engine.compile("let x = 10; { export x; }").expect_err("should error"),
|
engine.compile("let x = 10; { export x; }").expect_err("should error"),
|
||||||
ParseError(x, _) if *x == ParseErrorType::WrongExport
|
ParseError(x, ..) if *x == ParseErrorType::WrongExport
|
||||||
));
|
));
|
||||||
|
|
||||||
#[cfg(not(feature = "no_function"))]
|
#[cfg(not(feature = "no_function"))]
|
||||||
assert!(matches!(
|
assert!(matches!(
|
||||||
engine.compile("fn abc(x) { export x; }").expect_err("should error"),
|
engine.compile("fn abc(x) { export x; }").expect_err("should error"),
|
||||||
ParseError(x, _) if *x == ParseErrorType::WrongExport
|
ParseError(x, ..) if *x == ParseErrorType::WrongExport
|
||||||
));
|
));
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -138,7 +138,7 @@ fn test_max_operations_eval() -> Result<(), Box<EvalAltResult>> {
|
|||||||
"#
|
"#
|
||||||
)
|
)
|
||||||
.expect_err("should error"),
|
.expect_err("should error"),
|
||||||
EvalAltResult::ErrorInFunctionCall(_, _, err, _) if matches!(*err, EvalAltResult::ErrorTooManyOperations(_))
|
EvalAltResult::ErrorInFunctionCall(.., err, _) if matches!(*err, EvalAltResult::ErrorTooManyOperations(_))
|
||||||
));
|
));
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -163,7 +163,7 @@ fn test_max_operations_progress() -> Result<(), Box<EvalAltResult>> {
|
|||||||
*engine
|
*engine
|
||||||
.run("for x in 0..500 {}")
|
.run("for x in 0..500 {}")
|
||||||
.expect_err("should error"),
|
.expect_err("should error"),
|
||||||
EvalAltResult::ErrorTerminated(x, _) if x.as_int()? == 42
|
EvalAltResult::ErrorTerminated(x, ..) if x.as_int()? == 42
|
||||||
));
|
));
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -27,12 +27,12 @@ fn test_ops_other_number_types() -> Result<(), Box<EvalAltResult>> {
|
|||||||
|
|
||||||
assert!(matches!(
|
assert!(matches!(
|
||||||
*engine.eval_with_scope::<bool>(&mut scope, "x == 42").expect_err("should error"),
|
*engine.eval_with_scope::<bool>(&mut scope, "x == 42").expect_err("should error"),
|
||||||
EvalAltResult::ErrorFunctionNotFound(f, _) if f.starts_with("== (u16,")
|
EvalAltResult::ErrorFunctionNotFound(f, ..) if f.starts_with("== (u16,")
|
||||||
));
|
));
|
||||||
#[cfg(not(feature = "no_float"))]
|
#[cfg(not(feature = "no_float"))]
|
||||||
assert!(matches!(
|
assert!(matches!(
|
||||||
*engine.eval_with_scope::<bool>(&mut scope, "x == 42.0").expect_err("should error"),
|
*engine.eval_with_scope::<bool>(&mut scope, "x == 42.0").expect_err("should error"),
|
||||||
EvalAltResult::ErrorFunctionNotFound(f, _) if f.starts_with("== (u16,")
|
EvalAltResult::ErrorFunctionNotFound(f, ..) if f.starts_with("== (u16,")
|
||||||
));
|
));
|
||||||
|
|
||||||
assert!(!engine.eval_with_scope::<bool>(&mut scope, r#"x == "hello""#)?);
|
assert!(!engine.eval_with_scope::<bool>(&mut scope, r#"x == "hello""#)?);
|
||||||
|
@ -93,7 +93,7 @@ fn test_plugins_package() -> Result<(), Box<EvalAltResult>> {
|
|||||||
|
|
||||||
assert!(
|
assert!(
|
||||||
matches!(*engine.run("const A = [1, 2, 3]; A.test(42);").expect_err("should error"),
|
matches!(*engine.run("const A = [1, 2, 3]; A.test(42);").expect_err("should error"),
|
||||||
EvalAltResult::ErrorAssignmentToConstant(x, _) if x == "array")
|
EvalAltResult::ErrorAssignmentToConstant(x, ..) if x == "array")
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -117,7 +117,7 @@ fn test_string_mut() -> Result<(), Box<EvalAltResult>> {
|
|||||||
assert_eq!(engine.eval::<INT>(r#"bar("hello")"#)?, 5);
|
assert_eq!(engine.eval::<INT>(r#"bar("hello")"#)?, 5);
|
||||||
assert!(
|
assert!(
|
||||||
matches!(*engine.eval::<INT>(r#"baz("hello")"#).expect_err("should error"),
|
matches!(*engine.eval::<INT>(r#"baz("hello")"#).expect_err("should error"),
|
||||||
EvalAltResult::ErrorFunctionNotFound(f, _) if f == "baz (&str | ImmutableString | String)"
|
EvalAltResult::ErrorFunctionNotFound(f, ..) if f == "baz (&str | ImmutableString | String)"
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -6,12 +6,12 @@ fn test_throw() {
|
|||||||
|
|
||||||
assert!(matches!(
|
assert!(matches!(
|
||||||
*engine.run("if true { throw 42 }").expect_err("expects error"),
|
*engine.run("if true { throw 42 }").expect_err("expects error"),
|
||||||
EvalAltResult::ErrorRuntime(s, _) if s.as_int().unwrap() == 42
|
EvalAltResult::ErrorRuntime(s, ..) if s.as_int().unwrap() == 42
|
||||||
));
|
));
|
||||||
|
|
||||||
assert!(matches!(
|
assert!(matches!(
|
||||||
*engine.run(r#"throw"#).expect_err("expects error"),
|
*engine.run(r#"throw"#).expect_err("expects error"),
|
||||||
EvalAltResult::ErrorRuntime(s, _) if s.is::<()>()
|
EvalAltResult::ErrorRuntime(s, ..) if s.is::<()>()
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -96,7 +96,7 @@ fn test_try_catch() -> Result<(), Box<EvalAltResult>> {
|
|||||||
*engine
|
*engine
|
||||||
.run("try { 42/0; } catch { throw; }")
|
.run("try { 42/0; } catch { throw; }")
|
||||||
.expect_err("expects error"),
|
.expect_err("expects error"),
|
||||||
EvalAltResult::ErrorArithmetic(_, _)
|
EvalAltResult::ErrorArithmetic(..)
|
||||||
));
|
));
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -115,7 +115,7 @@ fn test_var_resolver() -> Result<(), Box<EvalAltResult>> {
|
|||||||
assert_eq!(engine.eval_with_scope::<INT>(&mut scope, "chameleon")?, 1);
|
assert_eq!(engine.eval_with_scope::<INT>(&mut scope, "chameleon")?, 1);
|
||||||
assert!(
|
assert!(
|
||||||
matches!(*engine.eval_with_scope::<INT>(&mut scope, "DO_NOT_USE").expect_err("should error"),
|
matches!(*engine.eval_with_scope::<INT>(&mut scope, "DO_NOT_USE").expect_err("should error"),
|
||||||
EvalAltResult::ErrorVariableNotFound(n, _) if n == "DO_NOT_USE")
|
EvalAltResult::ErrorVariableNotFound(n, ..) if n == "DO_NOT_USE")
|
||||||
);
|
);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
Loading…
Reference in New Issue
Block a user