commit
a0e272750a
@ -11,6 +11,8 @@ Bug fixes
|
|||||||
|
|
||||||
* `switch` cases with conditions that evaluate to constant `()` no longer optimize to `false` (should raise a type error during runtime).
|
* `switch` cases with conditions that evaluate to constant `()` no longer optimize to `false` (should raise a type error during runtime).
|
||||||
* Fixes concatenation of BLOB's and strings, where the BLOB's should be interpreted as UTF-8 encoded strings.
|
* Fixes concatenation of BLOB's and strings, where the BLOB's should be interpreted as UTF-8 encoded strings.
|
||||||
|
* Capturing an unknown variable in a closure no longer panics.
|
||||||
|
* Fixes panic in interpolated strings with constant expressions.
|
||||||
|
|
||||||
New features
|
New features
|
||||||
------------
|
------------
|
||||||
@ -47,6 +49,7 @@ Enhancements
|
|||||||
* `Iterator<Item=T>` type for functions metadata is simplified to `Iterator<T>`.
|
* `Iterator<Item=T>` type for functions metadata is simplified to `Iterator<T>`.
|
||||||
* `Scope::remove` is added to remove a variable from a `Scope`, returning its value.
|
* `Scope::remove` is added to remove a variable from a `Scope`, returning its value.
|
||||||
* The code base is cleaner by running it through Clippy.
|
* The code base is cleaner by running it through Clippy.
|
||||||
|
* `ParseError::err_type` and `ParseError::position` are added for convenience.
|
||||||
|
|
||||||
|
|
||||||
Version 1.8.0
|
Version 1.8.0
|
||||||
|
@ -64,10 +64,11 @@ fn one_fn_and_const_module_test() -> Result<(), Box<EvalAltResult>> {
|
|||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
engine.eval::<FLOAT>(
|
engine.eval::<FLOAT>(
|
||||||
r#"
|
"
|
||||||
let m = Math::Advanced::MYSTIC_NUMBER;
|
let m = Math::Advanced::MYSTIC_NUMBER;
|
||||||
let x = Math::Advanced::euclidean_distance(0.0, 1.0, 0.0, m);
|
let x = Math::Advanced::euclidean_distance(0.0, 1.0, 0.0, m);
|
||||||
x"#
|
x
|
||||||
|
"
|
||||||
)?,
|
)?,
|
||||||
41.0
|
41.0
|
||||||
);
|
);
|
||||||
@ -146,12 +147,13 @@ fn mut_opaque_ref_test() -> Result<(), Box<EvalAltResult>> {
|
|||||||
assert_eq!(
|
assert_eq!(
|
||||||
engine.eval::<bool>(
|
engine.eval::<bool>(
|
||||||
r#"
|
r#"
|
||||||
let success = "it worked";
|
let success = "it worked";
|
||||||
let message1 = Host::Msg::new_message(true, success);
|
let message1 = Host::Msg::new_message(true, success);
|
||||||
let ok1 = Host::Msg::write_out_message(message1);
|
let ok1 = Host::Msg::write_out_message(message1);
|
||||||
let message2 = Host::Msg::new_os_message(true, 0);
|
let message2 = Host::Msg::new_os_message(true, 0);
|
||||||
let ok2 = Host::Msg::write_out_message(message2);
|
let ok2 = Host::Msg::write_out_message(message2);
|
||||||
ok1 && ok2"#
|
ok1 && ok2
|
||||||
|
"#
|
||||||
)?,
|
)?,
|
||||||
true
|
true
|
||||||
);
|
);
|
||||||
@ -184,13 +186,13 @@ fn duplicate_fn_rename_test() -> Result<(), Box<EvalAltResult>> {
|
|||||||
engine.register_static_module("Math::Advanced", m.into());
|
engine.register_static_module("Math::Advanced", m.into());
|
||||||
|
|
||||||
let output_array = engine.eval::<Array>(
|
let output_array = engine.eval::<Array>(
|
||||||
r#"
|
"
|
||||||
let fx = get_mystic_number();
|
let fx = get_mystic_number();
|
||||||
let fy = Math::Advanced::add(fx, 1.0);
|
let fy = Math::Advanced::add(fx, 1.0);
|
||||||
let ix = 42;
|
let ix = 42;
|
||||||
let iy = Math::Advanced::add(ix, 1);
|
let iy = Math::Advanced::add(ix, 1);
|
||||||
[fy, iy]
|
[fy, iy]
|
||||||
"#,
|
",
|
||||||
)?;
|
)?;
|
||||||
assert_eq!(&output_array[0].as_float().unwrap(), &43.0);
|
assert_eq!(&output_array[0].as_float().unwrap(), &43.0);
|
||||||
assert_eq!(&output_array[1].as_int().unwrap(), &43);
|
assert_eq!(&output_array[1].as_int().unwrap(), &43);
|
||||||
@ -235,21 +237,21 @@ fn multiple_fn_rename_test() -> Result<(), Box<EvalAltResult>> {
|
|||||||
engine.register_global_module(m.into());
|
engine.register_global_module(m.into());
|
||||||
|
|
||||||
let output_array = engine.eval::<Array>(
|
let output_array = engine.eval::<Array>(
|
||||||
r#"
|
"
|
||||||
let fx = get_mystic_number();
|
let fx = get_mystic_number();
|
||||||
let fy1 = add(fx, 1.0);
|
let fy1 = add(fx, 1.0);
|
||||||
let fy2 = add_together(fx, 1.0);
|
let fy2 = add_together(fx, 1.0);
|
||||||
let fy3 = fx + 1.0;
|
let fy3 = fx + 1.0;
|
||||||
let p1 = fx.prop;
|
let p1 = fx.prop;
|
||||||
let p2 = prop(fx);
|
let p2 = prop(fx);
|
||||||
let idx1 = fx[1];
|
let idx1 = fx[1];
|
||||||
let idx2 = idx(fx, 1);
|
let idx2 = idx(fx, 1);
|
||||||
let ix = 42;
|
let ix = 42;
|
||||||
let iy1 = add(ix, 1);
|
let iy1 = add(ix, 1);
|
||||||
let iy2 = add_together(ix, 1);
|
let iy2 = add_together(ix, 1);
|
||||||
let iy3 = ix + 1;
|
let iy3 = ix + 1;
|
||||||
[fy1, fy2, fy3, iy1, iy2, iy3, p1, p2, idx1, idx2]
|
[fy1, fy2, fy3, iy1, iy2, iy3, p1, p2, idx1, idx2]
|
||||||
"#,
|
",
|
||||||
)?;
|
)?;
|
||||||
assert_eq!(&output_array[0].as_float().unwrap(), &44.0);
|
assert_eq!(&output_array[0].as_float().unwrap(), &44.0);
|
||||||
assert_eq!(&output_array[1].as_float().unwrap(), &44.0);
|
assert_eq!(&output_array[1].as_float().unwrap(), &44.0);
|
||||||
@ -307,15 +309,15 @@ fn export_by_prefix_test() -> Result<(), Box<EvalAltResult>> {
|
|||||||
engine.register_static_module("Math::Advanced", m.into());
|
engine.register_static_module("Math::Advanced", m.into());
|
||||||
|
|
||||||
let output_array = engine.eval::<Array>(
|
let output_array = engine.eval::<Array>(
|
||||||
r#"
|
"
|
||||||
let ex = 41.0;
|
let ex = 41.0;
|
||||||
let fx = Math::Advanced::foo_add_f(ex, 1.0);
|
let fx = Math::Advanced::foo_add_f(ex, 1.0);
|
||||||
let gx = Math::Advanced::foo_m(41.0, 1.0);
|
let gx = Math::Advanced::foo_m(41.0, 1.0);
|
||||||
let ei = 41;
|
let ei = 41;
|
||||||
let fi = Math::Advanced::bar_add_i(ei, 1);
|
let fi = Math::Advanced::bar_add_i(ei, 1);
|
||||||
let gi = Math::Advanced::foo_n(41, 1);
|
let gi = Math::Advanced::foo_n(41, 1);
|
||||||
[fx, gx, fi, gi]
|
[fx, gx, fi, gi]
|
||||||
"#,
|
",
|
||||||
)?;
|
)?;
|
||||||
assert_eq!(&output_array[0].as_float().unwrap(), &42.0);
|
assert_eq!(&output_array[0].as_float().unwrap(), &42.0);
|
||||||
assert_eq!(&output_array[1].as_float().unwrap(), &42.0);
|
assert_eq!(&output_array[1].as_float().unwrap(), &42.0);
|
||||||
@ -323,24 +325,22 @@ fn export_by_prefix_test() -> Result<(), Box<EvalAltResult>> {
|
|||||||
assert_eq!(&output_array[3].as_int().unwrap(), &42);
|
assert_eq!(&output_array[3].as_int().unwrap(), &42);
|
||||||
|
|
||||||
assert!(matches!(*engine.eval::<FLOAT>(
|
assert!(matches!(*engine.eval::<FLOAT>(
|
||||||
r#"
|
"
|
||||||
let ex = 41.0;
|
let ex = 41.0;
|
||||||
let fx = Math::Advanced::foo_add_float2(ex, 1.0);
|
let fx = Math::Advanced::foo_add_float2(ex, 1.0);
|
||||||
fx
|
fx
|
||||||
"#).unwrap_err(),
|
").unwrap_err(),
|
||||||
EvalAltResult::ErrorFunctionNotFound(s, p)
|
EvalAltResult::ErrorFunctionNotFound(s, p)
|
||||||
if s == "Math::Advanced::foo_add_float2 (f64, f64)"
|
if s == "Math::Advanced::foo_add_float2 (f64, f64)"));
|
||||||
&& p == rhai::Position::new(3, 34)));
|
|
||||||
|
|
||||||
assert!(matches!(*engine.eval::<FLOAT>(
|
assert!(matches!(*engine.eval::<FLOAT>(
|
||||||
r#"
|
"
|
||||||
let ex = 41.0;
|
let ex = 41.0;
|
||||||
let fx = Math::Advanced::bar_m(ex, 1.0);
|
let fx = Math::Advanced::bar_m(ex, 1.0);
|
||||||
fx
|
fx
|
||||||
"#).unwrap_err(),
|
").unwrap_err(),
|
||||||
EvalAltResult::ErrorFunctionNotFound(s, p)
|
EvalAltResult::ErrorFunctionNotFound(s, p)
|
||||||
if s == "Math::Advanced::bar_m (f64, f64)"
|
if s == "Math::Advanced::bar_m (f64, f64)"));
|
||||||
&& p == rhai::Position::new(3, 34)));
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -389,15 +389,15 @@ fn export_all_test() -> Result<(), Box<EvalAltResult>> {
|
|||||||
engine.register_static_module("Math::Advanced", m.into());
|
engine.register_static_module("Math::Advanced", m.into());
|
||||||
|
|
||||||
let output_array = engine.eval::<Array>(
|
let output_array = engine.eval::<Array>(
|
||||||
r#"
|
"
|
||||||
let ex = 41.0;
|
let ex = 41.0;
|
||||||
let fx = Math::Advanced::foo_add_f(ex, 1.0);
|
let fx = Math::Advanced::foo_add_f(ex, 1.0);
|
||||||
let gx = Math::Advanced::foo_m(41.0, 1.0);
|
let gx = Math::Advanced::foo_m(41.0, 1.0);
|
||||||
let ei = 41;
|
let ei = 41;
|
||||||
let fi = Math::Advanced::foo_add_i(ei, 1);
|
let fi = Math::Advanced::foo_add_i(ei, 1);
|
||||||
let gi = Math::Advanced::foo_n(41, 1);
|
let gi = Math::Advanced::foo_n(41, 1);
|
||||||
[fx, gx, fi, gi]
|
[fx, gx, fi, gi]
|
||||||
"#,
|
",
|
||||||
)?;
|
)?;
|
||||||
assert_eq!(&output_array[0].as_float().unwrap(), &42.0);
|
assert_eq!(&output_array[0].as_float().unwrap(), &42.0);
|
||||||
assert_eq!(&output_array[1].as_float().unwrap(), &42.0);
|
assert_eq!(&output_array[1].as_float().unwrap(), &42.0);
|
||||||
@ -405,14 +405,13 @@ fn export_all_test() -> Result<(), Box<EvalAltResult>> {
|
|||||||
assert_eq!(&output_array[3].as_int().unwrap(), &42);
|
assert_eq!(&output_array[3].as_int().unwrap(), &42);
|
||||||
|
|
||||||
assert!(matches!(*engine.eval::<INT>(
|
assert!(matches!(*engine.eval::<INT>(
|
||||||
r#"
|
"
|
||||||
let ex = 41;
|
let ex = 41;
|
||||||
let fx = Math::Advanced::foo_p(ex, 1);
|
let fx = Math::Advanced::foo_p(ex, 1);
|
||||||
fx
|
fx
|
||||||
"#).unwrap_err(),
|
").unwrap_err(),
|
||||||
EvalAltResult::ErrorFunctionNotFound(s, p)
|
EvalAltResult::ErrorFunctionNotFound(s, p)
|
||||||
if s == "Math::Advanced::foo_p (i64, i64)"
|
if s == "Math::Advanced::foo_p (i64, i64)"));
|
||||||
&& p == rhai::Position::new(3, 34)));
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -52,7 +52,12 @@ fn one_fn_sub_module_nested_attr_test() -> Result<(), Box<EvalAltResult>> {
|
|||||||
engine.register_static_module("Math::Advanced", m.into());
|
engine.register_static_module("Math::Advanced", m.into());
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
engine.eval::<FLOAT>(r#"let m = Math::Advanced::constants::get_mystic_number(); m"#)?,
|
engine.eval::<FLOAT>(
|
||||||
|
"
|
||||||
|
let m = Math::Advanced::constants::get_mystic_number();
|
||||||
|
m
|
||||||
|
"
|
||||||
|
)?,
|
||||||
42.0
|
42.0
|
||||||
);
|
);
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -121,21 +126,21 @@ fn export_nested_by_prefix_test() -> Result<(), Box<EvalAltResult>> {
|
|||||||
engine.register_static_module("Math::Advanced", m.into());
|
engine.register_static_module("Math::Advanced", m.into());
|
||||||
|
|
||||||
let output_array = engine.eval::<Array>(
|
let output_array = engine.eval::<Array>(
|
||||||
r#"
|
"
|
||||||
let ex = 41.0;
|
let ex = 41.0;
|
||||||
let fx = Math::Advanced::foo_first_adders::add_float(ex, 1.0);
|
let fx = Math::Advanced::foo_first_adders::add_float(ex, 1.0);
|
||||||
|
|
||||||
let ei = 41;
|
let ei = 41;
|
||||||
let fi = Math::Advanced::foo_first_adders::add_int(ei, 1);
|
let fi = Math::Advanced::foo_first_adders::add_int(ei, 1);
|
||||||
|
|
||||||
let gx = 41.0;
|
let gx = 41.0;
|
||||||
let hx = Math::Advanced::foo_second_adders::add_float(gx, 1.0);
|
let hx = Math::Advanced::foo_second_adders::add_float(gx, 1.0);
|
||||||
|
|
||||||
let gi = 41;
|
let gi = 41;
|
||||||
let hi = Math::Advanced::foo_second_adders::add_int(gi, 1);
|
let hi = Math::Advanced::foo_second_adders::add_int(gi, 1);
|
||||||
|
|
||||||
[fx, hx, fi, hi]
|
[fx, hx, fi, hi]
|
||||||
"#,
|
",
|
||||||
)?;
|
)?;
|
||||||
assert_eq!(&output_array[0].as_float().unwrap(), &42.0);
|
assert_eq!(&output_array[0].as_float().unwrap(), &42.0);
|
||||||
assert_eq!(&output_array[1].as_float().unwrap(), &42.0);
|
assert_eq!(&output_array[1].as_float().unwrap(), &42.0);
|
||||||
@ -143,44 +148,40 @@ fn export_nested_by_prefix_test() -> Result<(), Box<EvalAltResult>> {
|
|||||||
assert_eq!(&output_array[3].as_int().unwrap(), &42);
|
assert_eq!(&output_array[3].as_int().unwrap(), &42);
|
||||||
|
|
||||||
assert!(matches!(*engine.eval::<FLOAT>(
|
assert!(matches!(*engine.eval::<FLOAT>(
|
||||||
r#"
|
"
|
||||||
let ex = 41.0;
|
let ex = 41.0;
|
||||||
let fx = Math::Advanced::foo_third_adders::add_float(ex, 1.0);
|
let fx = Math::Advanced::foo_third_adders::add_float(ex, 1.0);
|
||||||
fx
|
fx
|
||||||
"#).unwrap_err(),
|
").unwrap_err(),
|
||||||
EvalAltResult::ErrorFunctionNotFound(s, p)
|
EvalAltResult::ErrorFunctionNotFound(s, p)
|
||||||
if s == "Math::Advanced::foo_third_adders::add_float (f64, f64)"
|
if s == "Math::Advanced::foo_third_adders::add_float (f64, f64)"));
|
||||||
&& p == rhai::Position::new(3, 52)));
|
|
||||||
|
|
||||||
assert!(matches!(*engine.eval::<FLOAT>(
|
assert!(matches!(*engine.eval::<FLOAT>(
|
||||||
r#"
|
"
|
||||||
let ex = 41;
|
let ex = 41;
|
||||||
let fx = Math::Advanced::foo_third_adders::add_int(ex, 1);
|
let fx = Math::Advanced::foo_third_adders::add_int(ex, 1);
|
||||||
fx
|
fx
|
||||||
"#).unwrap_err(),
|
").unwrap_err(),
|
||||||
EvalAltResult::ErrorFunctionNotFound(s, p)
|
EvalAltResult::ErrorFunctionNotFound(s, p)
|
||||||
if s == "Math::Advanced::foo_third_adders::add_int (i64, i64)"
|
if s == "Math::Advanced::foo_third_adders::add_int (i64, i64)"));
|
||||||
&& p == rhai::Position::new(3, 52)));
|
|
||||||
|
|
||||||
assert!(matches!(*engine.eval::<FLOAT>(
|
assert!(matches!(*engine.eval::<FLOAT>(
|
||||||
r#"
|
"
|
||||||
let ex = 41;
|
let ex = 41;
|
||||||
let fx = Math::Advanced::bar_fourth_adders::add_int(ex, 1);
|
let fx = Math::Advanced::bar_fourth_adders::add_int(ex, 1);
|
||||||
fx
|
fx
|
||||||
"#).unwrap_err(),
|
").unwrap_err(),
|
||||||
EvalAltResult::ErrorFunctionNotFound(s, p)
|
EvalAltResult::ErrorFunctionNotFound(s, p)
|
||||||
if s == "Math::Advanced::bar_fourth_adders::add_int (i64, i64)"
|
if s == "Math::Advanced::bar_fourth_adders::add_int (i64, i64)"));
|
||||||
&& p == rhai::Position::new(3, 53)));
|
|
||||||
|
|
||||||
assert!(matches!(*engine.eval::<FLOAT>(
|
assert!(matches!(*engine.eval::<FLOAT>(
|
||||||
r#"
|
"
|
||||||
let ex = 41.0;
|
let ex = 41.0;
|
||||||
let fx = Math::Advanced::bar_fourth_adders::add_float(ex, 1.0);
|
let fx = Math::Advanced::bar_fourth_adders::add_float(ex, 1.0);
|
||||||
fx
|
fx
|
||||||
"#).unwrap_err(),
|
").unwrap_err(),
|
||||||
EvalAltResult::ErrorFunctionNotFound(s, p)
|
EvalAltResult::ErrorFunctionNotFound(s, p)
|
||||||
if s == "Math::Advanced::bar_fourth_adders::add_float (f64, f64)"
|
if s == "Math::Advanced::bar_fourth_adders::add_float (f64, f64)"));
|
||||||
&& p == rhai::Position::new(3, 53)));
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -5,12 +5,16 @@ use crate::engine::{KEYWORD_FN_PTR, OP_EXCLUSIVE_RANGE, OP_INCLUSIVE_RANGE};
|
|||||||
use crate::func::hashing::ALT_ZERO_HASH;
|
use crate::func::hashing::ALT_ZERO_HASH;
|
||||||
use crate::tokenizer::Token;
|
use crate::tokenizer::Token;
|
||||||
use crate::types::dynamic::Union;
|
use crate::types::dynamic::Union;
|
||||||
use crate::{calc_fn_hash, Dynamic, FnPtr, Identifier, ImmutableString, Position, StaticVec, INT};
|
use crate::{
|
||||||
|
calc_fn_hash, Dynamic, FnPtr, Identifier, ImmutableString, Position, SmartString, StaticVec,
|
||||||
|
INT,
|
||||||
|
};
|
||||||
#[cfg(feature = "no_std")]
|
#[cfg(feature = "no_std")]
|
||||||
use std::prelude::v1::*;
|
use std::prelude::v1::*;
|
||||||
use std::{
|
use std::{
|
||||||
collections::BTreeMap,
|
collections::BTreeMap,
|
||||||
fmt,
|
fmt,
|
||||||
|
fmt::Write,
|
||||||
hash::Hash,
|
hash::Hash,
|
||||||
iter::once,
|
iter::once,
|
||||||
num::{NonZeroU8, NonZeroUsize},
|
num::{NonZeroU8, NonZeroUsize},
|
||||||
@ -576,6 +580,16 @@ impl Expr {
|
|||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Interpolated string
|
||||||
|
Self::InterpolatedString(x, ..) if self.is_constant() => {
|
||||||
|
let mut s = SmartString::new_const();
|
||||||
|
for segment in x.iter() {
|
||||||
|
let v = segment.get_literal_value().unwrap();
|
||||||
|
write!(&mut s, "{}", v).unwrap();
|
||||||
|
}
|
||||||
|
s.into()
|
||||||
|
}
|
||||||
|
|
||||||
// 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 =>
|
||||||
|
@ -1016,7 +1016,7 @@ impl Engine {
|
|||||||
|
|
||||||
// Share statement
|
// Share statement
|
||||||
#[cfg(not(feature = "no_closure"))]
|
#[cfg(not(feature = "no_closure"))]
|
||||||
Stmt::Share(name, ..) => {
|
Stmt::Share(name, pos) => {
|
||||||
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);
|
||||||
|
|
||||||
@ -1024,10 +1024,10 @@ impl Engine {
|
|||||||
// Replace the variable with a shared value.
|
// Replace the variable with a shared value.
|
||||||
*val = std::mem::take(val).into_shared();
|
*val = std::mem::take(val).into_shared();
|
||||||
}
|
}
|
||||||
|
Ok(Dynamic::UNIT)
|
||||||
} else {
|
} else {
|
||||||
unreachable!("variable {} not found for sharing", name);
|
Err(ERR::ErrorVariableNotFound(name.to_string(), *pos).into())
|
||||||
}
|
}
|
||||||
Ok(Dynamic::UNIT)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_ => unreachable!("statement cannot be evaluated: {:?}", stmt),
|
_ => unreachable!("statement cannot be evaluated: {:?}", stmt),
|
||||||
|
@ -12,7 +12,7 @@ use crate::tokenizer::{Span, Token};
|
|||||||
use crate::types::dynamic::AccessMode;
|
use crate::types::dynamic::AccessMode;
|
||||||
use crate::{
|
use crate::{
|
||||||
calc_fn_hash, calc_fn_params_hash, combine_hashes, Dynamic, Engine, FnPtr, Identifier,
|
calc_fn_hash, calc_fn_params_hash, combine_hashes, Dynamic, Engine, FnPtr, Identifier,
|
||||||
Position, Scope, StaticVec, AST, INT,
|
ImmutableString, Position, Scope, StaticVec, AST, INT,
|
||||||
};
|
};
|
||||||
#[cfg(feature = "no_std")]
|
#[cfg(feature = "no_std")]
|
||||||
use std::prelude::v1::*;
|
use std::prelude::v1::*;
|
||||||
@ -1052,10 +1052,10 @@ fn optimize_expr(expr: &mut Expr, state: &mut OptimizerState, _chaining: bool) {
|
|||||||
state.set_dirty();
|
state.set_dirty();
|
||||||
*expr = Expr::StringConstant(state.engine.const_empty_string(), *pos);
|
*expr = Expr::StringConstant(state.engine.const_empty_string(), *pos);
|
||||||
}
|
}
|
||||||
// `...`
|
// `... ${const} ...`
|
||||||
Expr::InterpolatedString(x, ..) if x.len() == 1 && matches!(x[0], Expr::StringConstant(..)) => {
|
Expr::InterpolatedString(..) if expr.is_constant() => {
|
||||||
state.set_dirty();
|
state.set_dirty();
|
||||||
*expr = mem::take(&mut x[0]);
|
*expr = Expr::StringConstant(expr.get_literal_value().unwrap().cast::<ImmutableString>(), expr.position());
|
||||||
}
|
}
|
||||||
// `... ${ ... } ...`
|
// `... ${ ... } ...`
|
||||||
Expr::InterpolatedString(x, ..) => {
|
Expr::InterpolatedString(x, ..) => {
|
||||||
|
@ -299,6 +299,21 @@ impl fmt::Display for ParseError {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl ParseError {
|
||||||
|
/// Get the [type][ParseErrorType] of this parse error.
|
||||||
|
#[inline(always)]
|
||||||
|
#[must_use]
|
||||||
|
pub fn err_type(&self) -> &ParseErrorType {
|
||||||
|
&self.0
|
||||||
|
}
|
||||||
|
/// Get the [position][Position] of this parse error.
|
||||||
|
#[inline(always)]
|
||||||
|
#[must_use]
|
||||||
|
pub fn position(&self) -> Position {
|
||||||
|
self.1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl From<ParseErrorType> for RhaiError {
|
impl From<ParseErrorType> for RhaiError {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn from(err: ParseErrorType) -> Self {
|
fn from(err: ParseErrorType) -> Self {
|
||||||
|
@ -179,40 +179,43 @@ fn test_array_index_types() -> Result<(), Box<EvalAltResult>> {
|
|||||||
engine.compile("[1, 2, 3][0]['x']")?;
|
engine.compile("[1, 2, 3][0]['x']")?;
|
||||||
|
|
||||||
assert!(matches!(
|
assert!(matches!(
|
||||||
*engine
|
engine
|
||||||
.compile("[1, 2, 3]['x']")
|
.compile("[1, 2, 3]['x']")
|
||||||
.expect_err("should error")
|
.expect_err("should error")
|
||||||
.0,
|
.err_type(),
|
||||||
ParseErrorType::MalformedIndexExpr(..)
|
ParseErrorType::MalformedIndexExpr(..)
|
||||||
));
|
));
|
||||||
|
|
||||||
#[cfg(not(feature = "no_float"))]
|
#[cfg(not(feature = "no_float"))]
|
||||||
assert!(matches!(
|
assert!(matches!(
|
||||||
*engine
|
engine
|
||||||
.compile("[1, 2, 3][123.456]")
|
.compile("[1, 2, 3][123.456]")
|
||||||
.expect_err("should error")
|
.expect_err("should error")
|
||||||
.0,
|
.err_type(),
|
||||||
ParseErrorType::MalformedIndexExpr(..)
|
ParseErrorType::MalformedIndexExpr(..)
|
||||||
));
|
));
|
||||||
|
|
||||||
assert!(matches!(
|
assert!(matches!(
|
||||||
*engine.compile("[1, 2, 3][()]").expect_err("should error").0,
|
engine
|
||||||
|
.compile("[1, 2, 3][()]")
|
||||||
|
.expect_err("should error")
|
||||||
|
.err_type(),
|
||||||
ParseErrorType::MalformedIndexExpr(..)
|
ParseErrorType::MalformedIndexExpr(..)
|
||||||
));
|
));
|
||||||
|
|
||||||
assert!(matches!(
|
assert!(matches!(
|
||||||
*engine
|
engine
|
||||||
.compile(r#"[1, 2, 3]["hello"]"#)
|
.compile(r#"[1, 2, 3]["hello"]"#)
|
||||||
.expect_err("should error")
|
.expect_err("should error")
|
||||||
.0,
|
.err_type(),
|
||||||
ParseErrorType::MalformedIndexExpr(..)
|
ParseErrorType::MalformedIndexExpr(..)
|
||||||
));
|
));
|
||||||
|
|
||||||
assert!(matches!(
|
assert!(matches!(
|
||||||
*engine
|
engine
|
||||||
.compile("[1, 2, 3][true && false]")
|
.compile("[1, 2, 3][true && false]")
|
||||||
.expect_err("should error")
|
.expect_err("should error")
|
||||||
.0,
|
.err_type(),
|
||||||
ParseErrorType::MalformedIndexExpr(..)
|
ParseErrorType::MalformedIndexExpr(..)
|
||||||
));
|
));
|
||||||
|
|
||||||
|
@ -21,40 +21,55 @@ fn test_assignments_bad_lhs() -> Result<(), Box<EvalAltResult>> {
|
|||||||
let engine = Engine::new();
|
let engine = Engine::new();
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
*engine.compile("(x+y) = 42;").expect_err("should error").0,
|
*engine
|
||||||
|
.compile("(x+y) = 42;")
|
||||||
|
.expect_err("should error")
|
||||||
|
.err_type(),
|
||||||
ParseErrorType::AssignmentToInvalidLHS("".to_string())
|
ParseErrorType::AssignmentToInvalidLHS("".to_string())
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
*engine.compile("foo(x) = 42;").expect_err("should error").0,
|
*engine
|
||||||
|
.compile("foo(x) = 42;")
|
||||||
|
.expect_err("should error")
|
||||||
|
.err_type(),
|
||||||
ParseErrorType::AssignmentToInvalidLHS("".to_string())
|
ParseErrorType::AssignmentToInvalidLHS("".to_string())
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
*engine.compile("true = 42;").expect_err("should error").0,
|
*engine
|
||||||
|
.compile("true = 42;")
|
||||||
|
.expect_err("should error")
|
||||||
|
.err_type(),
|
||||||
ParseErrorType::AssignmentToConstant("".to_string())
|
ParseErrorType::AssignmentToConstant("".to_string())
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
*engine.compile("123 = 42;").expect_err("should error").0,
|
*engine
|
||||||
|
.compile("123 = 42;")
|
||||||
|
.expect_err("should error")
|
||||||
|
.err_type(),
|
||||||
ParseErrorType::AssignmentToConstant("".to_string())
|
ParseErrorType::AssignmentToConstant("".to_string())
|
||||||
);
|
);
|
||||||
|
|
||||||
#[cfg(not(feature = "no_object"))]
|
#[cfg(not(feature = "no_object"))]
|
||||||
{
|
{
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
*engine.compile("x.foo() = 42;").expect_err("should error").0,
|
*engine
|
||||||
|
.compile("x.foo() = 42;")
|
||||||
|
.expect_err("should error")
|
||||||
|
.err_type(),
|
||||||
ParseErrorType::AssignmentToInvalidLHS("".to_string())
|
ParseErrorType::AssignmentToInvalidLHS("".to_string())
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
*engine
|
*engine
|
||||||
.compile("x.foo().x.y = 42;")
|
.compile("x.foo().x.y = 42;")
|
||||||
.expect_err("should error")
|
.expect_err("should error")
|
||||||
.0,
|
.err_type(),
|
||||||
ParseErrorType::AssignmentToInvalidLHS("".to_string())
|
ParseErrorType::AssignmentToInvalidLHS("".to_string())
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
*engine
|
*engine
|
||||||
.compile("x.y.z.foo() = 42;")
|
.compile("x.y.z.foo() = 42;")
|
||||||
.expect_err("should error")
|
.expect_err("should error")
|
||||||
.0,
|
.err_type(),
|
||||||
ParseErrorType::AssignmentToInvalidLHS("".to_string())
|
ParseErrorType::AssignmentToInvalidLHS("".to_string())
|
||||||
);
|
);
|
||||||
#[cfg(not(feature = "no_index"))]
|
#[cfg(not(feature = "no_index"))]
|
||||||
@ -62,7 +77,7 @@ fn test_assignments_bad_lhs() -> Result<(), Box<EvalAltResult>> {
|
|||||||
*engine
|
*engine
|
||||||
.compile("x.foo()[0] = 42;")
|
.compile("x.foo()[0] = 42;")
|
||||||
.expect_err("should error")
|
.expect_err("should error")
|
||||||
.0,
|
.err_type(),
|
||||||
ParseErrorType::AssignmentToInvalidLHS("".to_string())
|
ParseErrorType::AssignmentToInvalidLHS("".to_string())
|
||||||
);
|
);
|
||||||
#[cfg(not(feature = "no_index"))]
|
#[cfg(not(feature = "no_index"))]
|
||||||
@ -70,7 +85,7 @@ fn test_assignments_bad_lhs() -> Result<(), Box<EvalAltResult>> {
|
|||||||
*engine
|
*engine
|
||||||
.compile("x[y].z.foo() = 42;")
|
.compile("x[y].z.foo() = 42;")
|
||||||
.expect_err("should error")
|
.expect_err("should error")
|
||||||
.0,
|
.err_type(),
|
||||||
ParseErrorType::AssignmentToInvalidLHS("".to_string())
|
ParseErrorType::AssignmentToInvalidLHS("".to_string())
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -42,15 +42,29 @@ fn test_fn_ptr_curry_call() -> Result<(), Box<EvalAltResult>> {
|
|||||||
#[cfg(not(feature = "no_object"))]
|
#[cfg(not(feature = "no_object"))]
|
||||||
fn test_closures() -> Result<(), Box<EvalAltResult>> {
|
fn test_closures() -> Result<(), Box<EvalAltResult>> {
|
||||||
let mut engine = Engine::new();
|
let mut engine = Engine::new();
|
||||||
|
let mut scope = Scope::new();
|
||||||
|
|
||||||
|
scope.push("x", 42 as INT);
|
||||||
|
|
||||||
assert!(matches!(
|
assert!(matches!(
|
||||||
*engine
|
engine
|
||||||
.compile_expression("let f = |x| {};")
|
.compile_expression("|x| {}")
|
||||||
.expect_err("should error")
|
.expect_err("should error")
|
||||||
.0,
|
.err_type(),
|
||||||
ParseErrorType::BadInput(..)
|
ParseErrorType::BadInput(..)
|
||||||
));
|
));
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
engine.eval_with_scope::<INT>(
|
||||||
|
&mut scope,
|
||||||
|
"
|
||||||
|
let f = || { x };
|
||||||
|
f.call()
|
||||||
|
",
|
||||||
|
)?,
|
||||||
|
42
|
||||||
|
);
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
engine.eval::<INT>(
|
engine.eval::<INT>(
|
||||||
"
|
"
|
||||||
|
@ -13,11 +13,11 @@ fn test_custom_syntax() -> Result<(), Box<EvalAltResult>> {
|
|||||||
// Disable 'while' and make sure it still works with custom syntax
|
// Disable 'while' and make sure it still works with custom syntax
|
||||||
engine.disable_symbol("while");
|
engine.disable_symbol("while");
|
||||||
assert!(matches!(
|
assert!(matches!(
|
||||||
*engine.compile("while false {}").expect_err("should error").0,
|
engine.compile("while false {}").expect_err("should error").err_type(),
|
||||||
ParseErrorType::Reserved(err) if err == "while"
|
ParseErrorType::Reserved(err) if err == "while"
|
||||||
));
|
));
|
||||||
assert!(matches!(
|
assert!(matches!(
|
||||||
*engine.compile("let while = 0").expect_err("should error").0,
|
engine.compile("let while = 0").expect_err("should error").err_type(),
|
||||||
ParseErrorType::Reserved(err) if err == "while"
|
ParseErrorType::Reserved(err) if err == "while"
|
||||||
));
|
));
|
||||||
|
|
||||||
@ -157,7 +157,7 @@ fn test_custom_syntax() -> Result<(), Box<EvalAltResult>> {
|
|||||||
*engine
|
*engine
|
||||||
.register_custom_syntax(&["!"], false, |_, _| Ok(Dynamic::UNIT))
|
.register_custom_syntax(&["!"], false, |_, _| Ok(Dynamic::UNIT))
|
||||||
.expect_err("should error")
|
.expect_err("should error")
|
||||||
.0,
|
.err_type(),
|
||||||
ParseErrorType::BadInput(LexError::ImproperSymbol(
|
ParseErrorType::BadInput(LexError::ImproperSymbol(
|
||||||
"!".to_string(),
|
"!".to_string(),
|
||||||
"Improper symbol for custom syntax at position #1: '!'".to_string()
|
"Improper symbol for custom syntax at position #1: '!'".to_string()
|
||||||
@ -261,7 +261,10 @@ fn test_custom_syntax_raw() -> Result<(), Box<EvalAltResult>> {
|
|||||||
);
|
);
|
||||||
assert_eq!(engine.eval::<INT>("(hello kitty) + foo")?, 1041);
|
assert_eq!(engine.eval::<INT>("(hello kitty) + foo")?, 1041);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
*engine.compile("hello hey").expect_err("should error").0,
|
*engine
|
||||||
|
.compile("hello hey")
|
||||||
|
.expect_err("should error")
|
||||||
|
.err_type(),
|
||||||
ParseErrorType::BadInput(LexError::ImproperSymbol("hey".to_string(), "".to_string()))
|
ParseErrorType::BadInput(LexError::ImproperSymbol("hey".to_string(), "".to_string()))
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@ fn test_max_string_size() -> Result<(), Box<EvalAltResult>> {
|
|||||||
*engine
|
*engine
|
||||||
.compile(r#"let x = "hello, world!";"#)
|
.compile(r#"let x = "hello, world!";"#)
|
||||||
.expect_err("should error")
|
.expect_err("should error")
|
||||||
.0,
|
.err_type(),
|
||||||
ParseErrorType::LiteralTooLarge("Length of string literal".to_string(), 10)
|
ParseErrorType::LiteralTooLarge("Length of string literal".to_string(), 10)
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -24,7 +24,7 @@ fn test_max_string_size() -> Result<(), Box<EvalAltResult>> {
|
|||||||
*engine
|
*engine
|
||||||
.compile(r#"let x = "朝に紅顔、暮に白骨";"#)
|
.compile(r#"let x = "朝に紅顔、暮に白骨";"#)
|
||||||
.expect_err("should error")
|
.expect_err("should error")
|
||||||
.0,
|
.err_type(),
|
||||||
ParseErrorType::LiteralTooLarge("Length of string literal".to_string(), 10)
|
ParseErrorType::LiteralTooLarge("Length of string literal".to_string(), 10)
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -84,7 +84,7 @@ fn test_max_array_size() -> Result<(), Box<EvalAltResult>> {
|
|||||||
*engine
|
*engine
|
||||||
.compile("let x = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15];")
|
.compile("let x = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15];")
|
||||||
.expect_err("should error")
|
.expect_err("should error")
|
||||||
.0,
|
.err_type(),
|
||||||
ParseErrorType::LiteralTooLarge("Size of array literal".to_string(), 10)
|
ParseErrorType::LiteralTooLarge("Size of array literal".to_string(), 10)
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -266,7 +266,7 @@ fn test_max_map_size() -> Result<(), Box<EvalAltResult>> {
|
|||||||
"let x = #{a:1,b:2,c:3,d:4,e:5,f:6,g:7,h:8,i:9,j:10,k:11,l:12,m:13,n:14,o:15};"
|
"let x = #{a:1,b:2,c:3,d:4,e:5,f:6,g:7,h:8,i:9,j:10,k:11,l:12,m:13,n:14,o:15};"
|
||||||
)
|
)
|
||||||
.expect_err("should error")
|
.expect_err("should error")
|
||||||
.0,
|
.err_type(),
|
||||||
ParseErrorType::LiteralTooLarge(
|
ParseErrorType::LiteralTooLarge(
|
||||||
"Number of properties in object map literal".to_string(),
|
"Number of properties in object map literal".to_string(),
|
||||||
10
|
10
|
||||||
|
@ -167,10 +167,10 @@ fn test_eval_disabled() -> Result<(), Box<EvalAltResult>> {
|
|||||||
engine.disable_symbol("eval");
|
engine.disable_symbol("eval");
|
||||||
|
|
||||||
assert!(matches!(
|
assert!(matches!(
|
||||||
*engine
|
engine
|
||||||
.compile(r#"eval("40 + 2")"#)
|
.compile(r#"eval("40 + 2")"#)
|
||||||
.expect_err("should error")
|
.expect_err("should error")
|
||||||
.0,
|
.err_type(),
|
||||||
ParseErrorType::BadInput(LexError::ImproperSymbol(err, ..)) if err == "eval"
|
ParseErrorType::BadInput(LexError::ImproperSymbol(err, ..)) if err == "eval"
|
||||||
));
|
));
|
||||||
|
|
||||||
|
@ -65,12 +65,12 @@ fn test_fn_ptr() -> Result<(), Box<EvalAltResult>> {
|
|||||||
*engine
|
*engine
|
||||||
.eval::<INT>(
|
.eval::<INT>(
|
||||||
r#"
|
r#"
|
||||||
fn foo(x) { this += x; }
|
fn foo(x) { this += x; }
|
||||||
|
|
||||||
let f = Fn("foo");
|
let f = Fn("foo");
|
||||||
call(f, 2);
|
call(f, 2);
|
||||||
x
|
x
|
||||||
"#
|
"#
|
||||||
)
|
)
|
||||||
.expect_err("should error"),
|
.expect_err("should error"),
|
||||||
EvalAltResult::ErrorInFunctionCall(fn_name, _, err, ..)
|
EvalAltResult::ErrorInFunctionCall(fn_name, _, err, ..)
|
||||||
|
@ -84,7 +84,8 @@ fn test_functions_global_module() -> Result<(), Box<EvalAltResult>> {
|
|||||||
42
|
42
|
||||||
);
|
);
|
||||||
|
|
||||||
assert!(matches!(*engine.run("
|
assert!(matches!(*engine.run(
|
||||||
|
"
|
||||||
fn foo() { global::ANSWER }
|
fn foo() { global::ANSWER }
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -104,7 +105,8 @@ fn test_functions_global_module() -> Result<(), Box<EvalAltResult>> {
|
|||||||
);
|
);
|
||||||
|
|
||||||
#[cfg(not(feature = "no_closure"))]
|
#[cfg(not(feature = "no_closure"))]
|
||||||
assert!(matches!(*engine.run("
|
assert!(matches!(*engine.run(
|
||||||
|
"
|
||||||
do_stuff(|| {
|
do_stuff(|| {
|
||||||
const LOCAL_VALUE = 42;
|
const LOCAL_VALUE = 42;
|
||||||
global::LOCAL_VALUE
|
global::LOCAL_VALUE
|
||||||
|
@ -110,7 +110,7 @@ fn test_internal_fn_overloading() -> Result<(), Box<EvalAltResult>> {
|
|||||||
"
|
"
|
||||||
)
|
)
|
||||||
.expect_err("should error")
|
.expect_err("should error")
|
||||||
.0,
|
.err_type(),
|
||||||
ParseErrorType::FnDuplicatedDefinition("abc".to_string(), 1)
|
ParseErrorType::FnDuplicatedDefinition("abc".to_string(), 1)
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -125,8 +125,8 @@ fn test_internal_fn_params() -> Result<(), Box<EvalAltResult>> {
|
|||||||
assert_eq!(
|
assert_eq!(
|
||||||
*engine
|
*engine
|
||||||
.compile("fn hello(x, x) { x }")
|
.compile("fn hello(x, x) { x }")
|
||||||
.expect_err("should be error")
|
.expect_err("should error")
|
||||||
.0,
|
.err_type(),
|
||||||
ParseErrorType::FnDuplicatedParam("hello".to_string(), "x".to_string())
|
ParseErrorType::FnDuplicatedParam("hello".to_string(), "x".to_string())
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -236,7 +236,7 @@ fn test_internal_fn_bang() -> Result<(), Box<EvalAltResult>> {
|
|||||||
|
|
||||||
#[cfg(not(feature = "no_object"))]
|
#[cfg(not(feature = "no_object"))]
|
||||||
assert!(matches!(
|
assert!(matches!(
|
||||||
*engine
|
engine
|
||||||
.compile(
|
.compile(
|
||||||
"
|
"
|
||||||
fn foo() { this += x; }
|
fn foo() { this += x; }
|
||||||
@ -248,7 +248,7 @@ fn test_internal_fn_bang() -> Result<(), Box<EvalAltResult>> {
|
|||||||
"
|
"
|
||||||
)
|
)
|
||||||
.expect_err("should error")
|
.expect_err("should error")
|
||||||
.0,
|
.err_type(),
|
||||||
ParseErrorType::MalformedCapture(..)
|
ParseErrorType::MalformedCapture(..)
|
||||||
));
|
));
|
||||||
|
|
||||||
|
@ -30,7 +30,7 @@ fn test_loop() -> Result<(), Box<EvalAltResult>> {
|
|||||||
*engine
|
*engine
|
||||||
.compile("let x = 0; break;")
|
.compile("let x = 0; break;")
|
||||||
.expect_err("should error")
|
.expect_err("should error")
|
||||||
.0,
|
.err_type(),
|
||||||
ParseErrorType::LoopBreak
|
ParseErrorType::LoopBreak
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -38,7 +38,7 @@ fn test_loop() -> Result<(), Box<EvalAltResult>> {
|
|||||||
*engine
|
*engine
|
||||||
.compile("let x = 0; if x > 0 { continue; }")
|
.compile("let x = 0; if x > 0 { continue; }")
|
||||||
.expect_err("should error")
|
.expect_err("should error")
|
||||||
.0,
|
.err_type(),
|
||||||
ParseErrorType::LoopBreak
|
ParseErrorType::LoopBreak
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -132,43 +132,43 @@ fn test_map_index_types() -> Result<(), Box<EvalAltResult>> {
|
|||||||
engine.compile(r#"#{a:1, b:2, c:3}["a"]['x']"#)?;
|
engine.compile(r#"#{a:1, b:2, c:3}["a"]['x']"#)?;
|
||||||
|
|
||||||
assert!(matches!(
|
assert!(matches!(
|
||||||
*engine
|
engine
|
||||||
.compile("#{a:1, b:2, c:3}['x']")
|
.compile("#{a:1, b:2, c:3}['x']")
|
||||||
.expect_err("should error")
|
.expect_err("should error")
|
||||||
.0,
|
.err_type(),
|
||||||
ParseErrorType::MalformedIndexExpr(..)
|
ParseErrorType::MalformedIndexExpr(..)
|
||||||
));
|
));
|
||||||
|
|
||||||
assert!(matches!(
|
assert!(matches!(
|
||||||
*engine
|
engine
|
||||||
.compile("#{a:1, b:2, c:3}[1]")
|
.compile("#{a:1, b:2, c:3}[1]")
|
||||||
.expect_err("should error")
|
.expect_err("should error")
|
||||||
.0,
|
.err_type(),
|
||||||
ParseErrorType::MalformedIndexExpr(..)
|
ParseErrorType::MalformedIndexExpr(..)
|
||||||
));
|
));
|
||||||
|
|
||||||
#[cfg(not(feature = "no_float"))]
|
#[cfg(not(feature = "no_float"))]
|
||||||
assert!(matches!(
|
assert!(matches!(
|
||||||
*engine
|
engine
|
||||||
.compile("#{a:1, b:2, c:3}[123.456]")
|
.compile("#{a:1, b:2, c:3}[123.456]")
|
||||||
.expect_err("should error")
|
.expect_err("should error")
|
||||||
.0,
|
.err_type(),
|
||||||
ParseErrorType::MalformedIndexExpr(..)
|
ParseErrorType::MalformedIndexExpr(..)
|
||||||
));
|
));
|
||||||
|
|
||||||
assert!(matches!(
|
assert!(matches!(
|
||||||
*engine
|
engine
|
||||||
.compile("#{a:1, b:2, c:3}[()]")
|
.compile("#{a:1, b:2, c:3}[()]")
|
||||||
.expect_err("should error")
|
.expect_err("should error")
|
||||||
.0,
|
.err_type(),
|
||||||
ParseErrorType::MalformedIndexExpr(..)
|
ParseErrorType::MalformedIndexExpr(..)
|
||||||
));
|
));
|
||||||
|
|
||||||
assert!(matches!(
|
assert!(matches!(
|
||||||
*engine
|
engine
|
||||||
.compile("#{a:1, b:2, c:3}[true && false]")
|
.compile("#{a:1, b:2, c:3}[true && false]")
|
||||||
.expect_err("should error")
|
.expect_err("should error")
|
||||||
.0,
|
.err_type(),
|
||||||
ParseErrorType::MalformedIndexExpr(..)
|
ParseErrorType::MalformedIndexExpr(..)
|
||||||
));
|
));
|
||||||
|
|
||||||
|
@ -30,7 +30,8 @@ fn test_mismatched_op_custom_type() -> Result<(), Box<EvalAltResult>> {
|
|||||||
.register_type_with_name::<TestStruct>("TestStruct")
|
.register_type_with_name::<TestStruct>("TestStruct")
|
||||||
.register_fn("new_ts", TestStruct::new);
|
.register_fn("new_ts", TestStruct::new);
|
||||||
|
|
||||||
assert!(matches!(*engine.eval::<bool>("
|
assert!(matches!(*engine.eval::<bool>(
|
||||||
|
"
|
||||||
let x = new_ts();
|
let x = new_ts();
|
||||||
let y = new_ts();
|
let y = new_ts();
|
||||||
x == y
|
x == y
|
||||||
|
File diff suppressed because one or more lines are too long
@ -334,6 +334,8 @@ fn test_string_split() -> Result<(), Box<EvalAltResult>> {
|
|||||||
fn test_string_interpolated() -> Result<(), Box<EvalAltResult>> {
|
fn test_string_interpolated() -> Result<(), Box<EvalAltResult>> {
|
||||||
let engine = Engine::new();
|
let engine = Engine::new();
|
||||||
|
|
||||||
|
assert_eq!(engine.eval::<String>("`${}`")?, "");
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
engine.eval::<String>(
|
engine.eval::<String>(
|
||||||
"
|
"
|
||||||
|
@ -115,10 +115,10 @@ fn test_switch_errors() -> Result<(), Box<EvalAltResult>> {
|
|||||||
let engine = Engine::new();
|
let engine = Engine::new();
|
||||||
|
|
||||||
assert!(matches!(
|
assert!(matches!(
|
||||||
*engine
|
engine
|
||||||
.compile("switch x { _ => 123, 1 => 42 }")
|
.compile("switch x { _ => 123, 1 => 42 }")
|
||||||
.expect_err("should error")
|
.expect_err("should error")
|
||||||
.0,
|
.err_type(),
|
||||||
ParseErrorType::WrongSwitchDefaultCase
|
ParseErrorType::WrongSwitchDefaultCase
|
||||||
));
|
));
|
||||||
|
|
||||||
@ -179,10 +179,10 @@ fn test_switch_condition() -> Result<(), Box<EvalAltResult>> {
|
|||||||
);
|
);
|
||||||
|
|
||||||
assert!(matches!(
|
assert!(matches!(
|
||||||
*engine
|
engine
|
||||||
.compile("switch x { 1 => 123, _ if true => 42 }")
|
.compile("switch x { 1 => 123, _ if true => 42 }")
|
||||||
.expect_err("should error")
|
.expect_err("should error")
|
||||||
.0,
|
.err_type(),
|
||||||
ParseErrorType::WrongSwitchCaseCondition
|
ParseErrorType::WrongSwitchCaseCondition
|
||||||
));
|
));
|
||||||
|
|
||||||
@ -274,8 +274,9 @@ fn test_switch_ranges() -> Result<(), Box<EvalAltResult>> {
|
|||||||
'x'
|
'x'
|
||||||
);
|
);
|
||||||
assert!(matches!(
|
assert!(matches!(
|
||||||
*engine.compile("switch x { 10..20 => (), 20..=42 => 'a', 25..45 => 'z', 42 => 'x', 30..100 => true }")
|
engine.compile(
|
||||||
.expect_err("should error").0,
|
"switch x { 10..20 => (), 20..=42 => 'a', 25..45 => 'z', 42 => 'x', 30..100 => true }"
|
||||||
|
).expect_err("should error").err_type(),
|
||||||
ParseErrorType::WrongSwitchIntegerCase
|
ParseErrorType::WrongSwitchIntegerCase
|
||||||
));
|
));
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
|
@ -7,10 +7,10 @@ fn test_tokens_disabled() {
|
|||||||
engine.disable_symbol("if"); // disable the 'if' keyword
|
engine.disable_symbol("if"); // disable the 'if' keyword
|
||||||
|
|
||||||
assert!(matches!(
|
assert!(matches!(
|
||||||
*engine
|
engine
|
||||||
.compile("let x = if true { 42 } else { 0 };")
|
.compile("let x = if true { 42 } else { 0 };")
|
||||||
.expect_err("should error")
|
.expect_err("should error")
|
||||||
.0,
|
.err_type(),
|
||||||
ParseErrorType::Reserved(err) if err == "if"
|
ParseErrorType::Reserved(err) if err == "if"
|
||||||
));
|
));
|
||||||
|
|
||||||
@ -20,12 +20,12 @@ fn test_tokens_disabled() {
|
|||||||
*engine
|
*engine
|
||||||
.compile("let x = 40 + 2; x += 1;")
|
.compile("let x = 40 + 2; x += 1;")
|
||||||
.expect_err("should error")
|
.expect_err("should error")
|
||||||
.0,
|
.err_type(),
|
||||||
ParseErrorType::UnknownOperator("+=".to_string())
|
ParseErrorType::UnknownOperator("+=".to_string())
|
||||||
);
|
);
|
||||||
|
|
||||||
assert!(matches!(
|
assert!(matches!(
|
||||||
*engine.compile("let x = += 0;").expect_err("should error").0,
|
engine.compile("let x = += 0;").expect_err("should error").err_type(),
|
||||||
ParseErrorType::Reserved(err) if err == "+="
|
ParseErrorType::Reserved(err) if err == "+="
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
@ -233,7 +233,7 @@ fn test_var_def_filter() -> Result<(), Box<EvalAltResult>> {
|
|||||||
);
|
);
|
||||||
|
|
||||||
assert!(matches!(
|
assert!(matches!(
|
||||||
*engine.compile("let x = 42;").expect_err("should error").0,
|
engine.compile("let x = 42;").expect_err("should error").err_type(),
|
||||||
ParseErrorType::ForbiddenVariable(s) if s == "x"
|
ParseErrorType::ForbiddenVariable(s) if s == "x"
|
||||||
));
|
));
|
||||||
assert!(matches!(
|
assert!(matches!(
|
||||||
|
Loading…
Reference in New Issue
Block a user