Add no_object
feature to disable objects.
This commit is contained in:
parent
a8a4ed2967
commit
ef6c6ea6d2
@ -20,13 +20,14 @@ categories = [ "no-std", "embedded", "parser-implementations" ]
|
|||||||
num-traits = "0.2.11"
|
num-traits = "0.2.11"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
#default = ["no_function", "no_index", "no_float", "only_i32", "no_stdlib", "unchecked", "no_optimize"]
|
#default = ["no_function", "no_index", "no_object", "no_float", "only_i32", "no_stdlib", "unchecked", "no_optimize"]
|
||||||
default = []
|
default = []
|
||||||
unchecked = [] # unchecked arithmetic
|
unchecked = [] # unchecked arithmetic
|
||||||
no_stdlib = [] # no standard library of utility functions
|
no_stdlib = [] # no standard library of utility functions
|
||||||
no_index = [] # no arrays and indexing
|
no_index = [] # no arrays and indexing
|
||||||
no_float = [] # no floating-point
|
no_float = [] # no floating-point
|
||||||
no_function = [] # no script-defined functions
|
no_function = [] # no script-defined functions
|
||||||
|
no_object = [] # no custom objects
|
||||||
no_optimize = [] # no script optimizer
|
no_optimize = [] # no script optimizer
|
||||||
optimize_full = [] # set optimization level to Full (default is Simple) - this is a feature used only to simplify testing
|
optimize_full = [] # set optimization level to Full (default is Simple) - this is a feature used only to simplify testing
|
||||||
only_i32 = [] # set INT=i32 (useful for 32-bit systems)
|
only_i32 = [] # set INT=i32 (useful for 32-bit systems)
|
||||||
|
31
README.md
31
README.md
@ -62,6 +62,7 @@ Optional features
|
|||||||
| `unchecked` | Exclude arithmetic checking (such as overflows and division by zero). Beware that a bad script may panic the entire system! |
|
| `unchecked` | Exclude arithmetic checking (such as overflows and division by zero). Beware that a bad script may panic the entire system! |
|
||||||
| `no_function` | Disable script-defined functions if not needed. |
|
| `no_function` | Disable script-defined functions if not needed. |
|
||||||
| `no_index` | Disable arrays and indexing features if not needed. |
|
| `no_index` | Disable arrays and indexing features if not needed. |
|
||||||
|
| `no_object` | Disable support for custom types and objects. |
|
||||||
| `no_float` | Disable floating-point numbers and math if not needed. |
|
| `no_float` | Disable floating-point numbers and math if not needed. |
|
||||||
| `no_optimize` | Disable the script optimizer. |
|
| `no_optimize` | Disable the script optimizer. |
|
||||||
| `only_i32` | Set the system integer type to `i32` and disable all other integer types. `INT` is set to `i32`. |
|
| `only_i32` | Set the system integer type to `i32` and disable all other integer types. `INT` is set to `i32`. |
|
||||||
@ -76,6 +77,7 @@ Excluding unneeded functionalities can result in smaller, faster builds as well
|
|||||||
[`no_index`]: #optional-features
|
[`no_index`]: #optional-features
|
||||||
[`no_float`]: #optional-features
|
[`no_float`]: #optional-features
|
||||||
[`no_function`]: #optional-features
|
[`no_function`]: #optional-features
|
||||||
|
[`no_object`]: #optional-features
|
||||||
[`no_optimize`]: #optional-features
|
[`no_optimize`]: #optional-features
|
||||||
[`only_i32`]: #optional-features
|
[`only_i32`]: #optional-features
|
||||||
[`only_i64`]: #optional-features
|
[`only_i64`]: #optional-features
|
||||||
@ -294,7 +296,7 @@ type_of('c') == "char";
|
|||||||
type_of(42) == "i64";
|
type_of(42) == "i64";
|
||||||
|
|
||||||
let x = 123;
|
let x = 123;
|
||||||
x.type_of(); // error - 'type_of' cannot use postfix notation
|
x.type_of(); // error - 'type_of' cannot use method-call style
|
||||||
type_of(x) == "i64";
|
type_of(x) == "i64";
|
||||||
|
|
||||||
x = 99.999;
|
x = 99.999;
|
||||||
@ -496,6 +498,7 @@ fn main() -> Result<(), EvalAltResult>
|
|||||||
```
|
```
|
||||||
|
|
||||||
All custom types must implement `Clone`. This allows the [`Engine`] to pass by value.
|
All custom types must implement `Clone`. This allows the [`Engine`] to pass by value.
|
||||||
|
You can turn off support for custom types via the [`no_object`] feature.
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
@ -522,7 +525,8 @@ let mut engine = Engine::new();
|
|||||||
engine.register_type::<TestStruct>();
|
engine.register_type::<TestStruct>();
|
||||||
```
|
```
|
||||||
|
|
||||||
To use methods and functions with the [`Engine`], we need to register them. There are some convenience functions to help with this. Below I register update and new with the [`Engine`].
|
To use methods and functions with the [`Engine`], we need to register them. There are some convenience functions to help with this.
|
||||||
|
Below I register update and new with the [`Engine`].
|
||||||
|
|
||||||
*Note: [`Engine`] follows the convention that methods use a `&mut` first parameter so that invoking methods can update the value in memory.*
|
*Note: [`Engine`] follows the convention that methods use a `&mut` first parameter so that invoking methods can update the value in memory.*
|
||||||
|
|
||||||
@ -531,7 +535,8 @@ engine.register_fn("update", TestStruct::update); // registers 'update(&mut ts
|
|||||||
engine.register_fn("new_ts", TestStruct::new); // registers 'new'
|
engine.register_fn("new_ts", TestStruct::new); // registers 'new'
|
||||||
```
|
```
|
||||||
|
|
||||||
Finally, we call our script. The script can see the function and method we registered earlier. We need to get the result back out from script land just as before, this time casting to our custom struct type.
|
Finally, we call our script. The script can see the function and method we registered earlier.
|
||||||
|
We need to get the result back out from script land just as before, this time casting to our custom struct type.
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
let result = engine.eval::<TestStruct>("let x = new_ts(); x.update(); x")?;
|
let result = engine.eval::<TestStruct>("let x = new_ts(); x.update(); x")?;
|
||||||
@ -539,7 +544,8 @@ let result = engine.eval::<TestStruct>("let x = new_ts(); x.update(); x")?;
|
|||||||
println!("result: {}", result.field); // prints 42
|
println!("result: {}", result.field); // prints 42
|
||||||
```
|
```
|
||||||
|
|
||||||
In fact, any function with a first argument (either by copy or via a `&mut` reference) can be used as a method-call on that type because internally they are the same thing: methods on a type is implemented as a functions taking an first argument.
|
In fact, any function with a first argument (either by copy or via a `&mut` reference) can be used as a method-call on that type because internally they are the same thing:
|
||||||
|
methods on a type is implemented as a functions taking an first argument.
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
fn foo(ts: &mut TestStruct) -> i64 {
|
fn foo(ts: &mut TestStruct) -> i64 {
|
||||||
@ -553,7 +559,15 @@ let result = engine.eval::<i64>("let x = new_ts(); x.foo()")?;
|
|||||||
println!("result: {}", result); // prints 1
|
println!("result: {}", result); // prints 1
|
||||||
```
|
```
|
||||||
|
|
||||||
[`type_of()`] works fine with custom types and returns the name of the type. If `register_type_with_name` is used to register the custom type
|
If the [`no_object`] feature is turned on, however, the _method_ style of function calls (i.e. calling a function as an object-method) is no longer supported.
|
||||||
|
|
||||||
|
```rust
|
||||||
|
// Below is a syntax error under 'no_object' because 'len' cannot be called in method style.
|
||||||
|
let result = engine.eval::<i64>("let x = [1, 2, 3]; x.len()")?;
|
||||||
|
```
|
||||||
|
|
||||||
|
[`type_of()`] works fine with custom types and returns the name of the type.
|
||||||
|
If `register_type_with_name` is used to register the custom type
|
||||||
with a special "pretty-print" name, [`type_of()`] will return that name instead.
|
with a special "pretty-print" name, [`type_of()`] will return that name instead.
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
@ -605,6 +619,9 @@ let result = engine.eval::<i64>("let a = new_ts(); a.xyz = 42; a.xyz")?;
|
|||||||
println!("Answer: {}", result); // prints 42
|
println!("Answer: {}", result); // prints 42
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Needless to say, `register_type`, `register_type_with_name`, `register_get`, `register_set` and `register_get_set`
|
||||||
|
are not available when the [`no_object`] feature is turned on.
|
||||||
|
|
||||||
Initializing and maintaining state
|
Initializing and maintaining state
|
||||||
---------------------------------
|
---------------------------------
|
||||||
|
|
||||||
@ -1326,6 +1343,8 @@ a.update(); // method call
|
|||||||
update(a); // this works, but 'a' is unchanged because only a COPY of 'a' is passed to 'update' by VALUE
|
update(a); // this works, but 'a' is unchanged because only a COPY of 'a' is passed to 'update' by VALUE
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Custom types, properties and methods can be disabled via the [`no_object`] feature.
|
||||||
|
|
||||||
`print` and `debug`
|
`print` and `debug`
|
||||||
-------------------
|
-------------------
|
||||||
|
|
||||||
@ -1606,7 +1625,7 @@ eval("{ let z = y }"); // to keep a variable local, use a statement blo
|
|||||||
|
|
||||||
print("z = " + z); // error - variable 'z' not found
|
print("z = " + z); // error - variable 'z' not found
|
||||||
|
|
||||||
"print(42)".eval(); // nope - just like 'type_of' postfix notation doesn't work
|
"print(42)".eval(); // nope - just like 'type_of', method-call style doesn't work
|
||||||
```
|
```
|
||||||
|
|
||||||
Script segments passed to `eval` execute inside the current [`Scope`], so they can access and modify _everything_,
|
Script segments passed to `eval` execute inside the current [`Scope`], so they can access and modify _everything_,
|
||||||
|
@ -15,6 +15,8 @@ impl TestStruct {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(not(feature = "no_index"))]
|
||||||
|
#[cfg(not(feature = "no_object"))]
|
||||||
fn main() {
|
fn main() {
|
||||||
let mut engine = Engine::new();
|
let mut engine = Engine::new();
|
||||||
|
|
||||||
@ -32,3 +34,6 @@ fn main() {
|
|||||||
engine.eval::<TestStruct>("let x = [new_ts()]; x[0].update(); x[0]")
|
engine.eval::<TestStruct>("let x = [new_ts()]; x[0].update(); x[0]")
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(any(feature = "no_index", feature = "no_object"))]
|
||||||
|
fn main() {}
|
||||||
|
@ -15,6 +15,7 @@ impl TestStruct {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(not(feature = "no_object"))]
|
||||||
fn main() -> Result<(), EvalAltResult> {
|
fn main() -> Result<(), EvalAltResult> {
|
||||||
let mut engine = Engine::new();
|
let mut engine = Engine::new();
|
||||||
|
|
||||||
@ -29,3 +30,6 @@ fn main() -> Result<(), EvalAltResult> {
|
|||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "no_object")]
|
||||||
|
fn main() {}
|
||||||
|
@ -75,6 +75,7 @@ impl<'e> Engine<'e> {
|
|||||||
/// # Ok(())
|
/// # Ok(())
|
||||||
/// # }
|
/// # }
|
||||||
/// ```
|
/// ```
|
||||||
|
#[cfg(not(feature = "no_object"))]
|
||||||
pub fn register_type<T: Any + Clone>(&mut self) {
|
pub fn register_type<T: Any + Clone>(&mut self) {
|
||||||
self.register_type_with_name::<T>(type_name::<T>());
|
self.register_type_with_name::<T>(type_name::<T>());
|
||||||
}
|
}
|
||||||
@ -122,6 +123,7 @@ impl<'e> Engine<'e> {
|
|||||||
/// # Ok(())
|
/// # Ok(())
|
||||||
/// # }
|
/// # }
|
||||||
/// ```
|
/// ```
|
||||||
|
#[cfg(not(feature = "no_object"))]
|
||||||
pub fn register_type_with_name<T: Any + Clone>(&mut self, name: &str) {
|
pub fn register_type_with_name<T: Any + Clone>(&mut self, name: &str) {
|
||||||
// Add the pretty-print type name into the map
|
// Add the pretty-print type name into the map
|
||||||
self.type_names
|
self.type_names
|
||||||
@ -173,6 +175,7 @@ impl<'e> Engine<'e> {
|
|||||||
/// # Ok(())
|
/// # Ok(())
|
||||||
/// # }
|
/// # }
|
||||||
/// ```
|
/// ```
|
||||||
|
#[cfg(not(feature = "no_object"))]
|
||||||
pub fn register_get<T: Any + Clone, U: Any + Clone>(
|
pub fn register_get<T: Any + Clone, U: Any + Clone>(
|
||||||
&mut self,
|
&mut self,
|
||||||
name: &str,
|
name: &str,
|
||||||
@ -215,6 +218,7 @@ impl<'e> Engine<'e> {
|
|||||||
/// # Ok(())
|
/// # Ok(())
|
||||||
/// # }
|
/// # }
|
||||||
/// ```
|
/// ```
|
||||||
|
#[cfg(not(feature = "no_object"))]
|
||||||
pub fn register_set<T: Any + Clone, U: Any + Clone>(
|
pub fn register_set<T: Any + Clone, U: Any + Clone>(
|
||||||
&mut self,
|
&mut self,
|
||||||
name: &str,
|
name: &str,
|
||||||
@ -262,6 +266,7 @@ impl<'e> Engine<'e> {
|
|||||||
/// # Ok(())
|
/// # Ok(())
|
||||||
/// # }
|
/// # }
|
||||||
/// ```
|
/// ```
|
||||||
|
#[cfg(not(feature = "no_object"))]
|
||||||
pub fn register_get_set<T: Any + Clone, U: Any + Clone>(
|
pub fn register_get_set<T: Any + Clone, U: Any + Clone>(
|
||||||
&mut self,
|
&mut self,
|
||||||
name: &str,
|
name: &str,
|
||||||
@ -864,7 +869,7 @@ impl<'e> Engine<'e> {
|
|||||||
/// let mut engine = Engine::new();
|
/// let mut engine = Engine::new();
|
||||||
///
|
///
|
||||||
/// // Set 'retain_functions' in 'consume' to keep the function definitions
|
/// // Set 'retain_functions' in 'consume' to keep the function definitions
|
||||||
/// engine.consume(true, "fn add(x, y) { x.len() + y }")?;
|
/// engine.consume(true, "fn add(x, y) { len(x) + y }")?;
|
||||||
///
|
///
|
||||||
/// // Call the script-defined function
|
/// // Call the script-defined function
|
||||||
/// let result: i64 = engine.call_fn("add", (String::from("abc"), 123_i64))?;
|
/// let result: i64 = engine.call_fn("add", (String::from("abc"), 123_i64))?;
|
||||||
|
@ -344,6 +344,7 @@ impl Engine<'_> {
|
|||||||
///
|
///
|
||||||
/// Otherwise, if `src` is `Some`, then it holds a name and index into `scope`; using `get_mut` on
|
/// Otherwise, if `src` is `Some`, then it holds a name and index into `scope`; using `get_mut` on
|
||||||
/// `scope` can retrieve a mutable reference to the variable's value to use as `this`.
|
/// `scope` can retrieve a mutable reference to the variable's value to use as `this`.
|
||||||
|
#[cfg(not(feature = "no_object"))]
|
||||||
fn get_dot_val_helper(
|
fn get_dot_val_helper(
|
||||||
&mut self,
|
&mut self,
|
||||||
scope: &mut Scope,
|
scope: &mut Scope,
|
||||||
@ -487,6 +488,7 @@ impl Engine<'_> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Evaluate a dot chain getter
|
/// Evaluate a dot chain getter
|
||||||
|
#[cfg(not(feature = "no_object"))]
|
||||||
fn get_dot_val(
|
fn get_dot_val(
|
||||||
&mut self,
|
&mut self,
|
||||||
scope: &mut Scope,
|
scope: &mut Scope,
|
||||||
@ -741,6 +743,7 @@ impl Engine<'_> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Chain-evaluate a dot setter
|
/// Chain-evaluate a dot setter
|
||||||
|
#[cfg(not(feature = "no_object"))]
|
||||||
fn set_dot_val_helper(
|
fn set_dot_val_helper(
|
||||||
&mut self,
|
&mut self,
|
||||||
scope: &mut Scope,
|
scope: &mut Scope,
|
||||||
@ -858,6 +861,7 @@ impl Engine<'_> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Evaluate a dot chain setter
|
// Evaluate a dot chain setter
|
||||||
|
#[cfg(not(feature = "no_object"))]
|
||||||
fn set_dot_val(
|
fn set_dot_val(
|
||||||
&mut self,
|
&mut self,
|
||||||
scope: &mut Scope,
|
scope: &mut Scope,
|
||||||
@ -1021,6 +1025,7 @@ impl Engine<'_> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// dot_lhs.dot_rhs = rhs
|
// dot_lhs.dot_rhs = rhs
|
||||||
|
#[cfg(not(feature = "no_object"))]
|
||||||
Expr::Dot(dot_lhs, dot_rhs, _) => self.set_dot_val(
|
Expr::Dot(dot_lhs, dot_rhs, _) => self.set_dot_val(
|
||||||
scope,
|
scope,
|
||||||
dot_lhs,
|
dot_lhs,
|
||||||
@ -1041,6 +1046,7 @@ impl Engine<'_> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(not(feature = "no_object"))]
|
||||||
Expr::Dot(lhs, rhs, _) => self.get_dot_val(scope, lhs, rhs, level),
|
Expr::Dot(lhs, rhs, _) => self.get_dot_val(scope, lhs, rhs, level),
|
||||||
|
|
||||||
#[cfg(not(feature = "no_index"))]
|
#[cfg(not(feature = "no_index"))]
|
||||||
|
@ -334,6 +334,7 @@ fn optimize_expr<'a>(expr: Expr, state: &mut State<'a>) -> Expr {
|
|||||||
expr => Expr::Assignment(id, Box::new(optimize_expr(expr, state)), pos),
|
expr => Expr::Assignment(id, Box::new(optimize_expr(expr, state)), pos),
|
||||||
},
|
},
|
||||||
// lhs.rhs
|
// lhs.rhs
|
||||||
|
#[cfg(not(feature = "no_object"))]
|
||||||
Expr::Dot(lhs, rhs, pos) => Expr::Dot(
|
Expr::Dot(lhs, rhs, pos) => Expr::Dot(
|
||||||
Box::new(optimize_expr(*lhs, state)),
|
Box::new(optimize_expr(*lhs, state)),
|
||||||
Box::new(optimize_expr(*rhs, state)),
|
Box::new(optimize_expr(*rhs, state)),
|
||||||
|
@ -357,6 +357,7 @@ pub enum Expr {
|
|||||||
/// expr = expr
|
/// expr = expr
|
||||||
Assignment(Box<Expr>, Box<Expr>, Position),
|
Assignment(Box<Expr>, Box<Expr>, Position),
|
||||||
/// lhs.rhs
|
/// lhs.rhs
|
||||||
|
#[cfg(not(feature = "no_object"))]
|
||||||
Dot(Box<Expr>, Box<Expr>, Position),
|
Dot(Box<Expr>, Box<Expr>, Position),
|
||||||
/// expr[expr]
|
/// expr[expr]
|
||||||
#[cfg(not(feature = "no_index"))]
|
#[cfg(not(feature = "no_index"))]
|
||||||
@ -443,10 +444,12 @@ impl Expr {
|
|||||||
| Expr::False(pos)
|
| Expr::False(pos)
|
||||||
| Expr::Unit(pos) => *pos,
|
| Expr::Unit(pos) => *pos,
|
||||||
|
|
||||||
Expr::Assignment(expr, _, _)
|
Expr::Assignment(expr, _, _) | Expr::And(expr, _) | Expr::Or(expr, _) => {
|
||||||
| Expr::Dot(expr, _, _)
|
expr.position()
|
||||||
| Expr::And(expr, _)
|
}
|
||||||
| Expr::Or(expr, _) => expr.position(),
|
|
||||||
|
#[cfg(not(feature = "no_object"))]
|
||||||
|
Expr::Dot(expr, _, _) => expr.position(),
|
||||||
|
|
||||||
#[cfg(not(feature = "no_float"))]
|
#[cfg(not(feature = "no_float"))]
|
||||||
Expr::FloatConstant(_, pos) => *pos,
|
Expr::FloatConstant(_, pos) => *pos,
|
||||||
@ -1767,6 +1770,7 @@ fn parse_assignment(lhs: Expr, rhs: Expr, pos: Position) -> Result<Expr, ParseEr
|
|||||||
},
|
},
|
||||||
|
|
||||||
// dot_lhs.dot_rhs
|
// dot_lhs.dot_rhs
|
||||||
|
#[cfg(not(feature = "no_object"))]
|
||||||
Expr::Dot(dot_lhs, dot_rhs, _) => match dot_lhs.as_ref() {
|
Expr::Dot(dot_lhs, dot_rhs, _) => match dot_lhs.as_ref() {
|
||||||
// var.dot_rhs
|
// var.dot_rhs
|
||||||
Expr::Variable(_, _) if is_top => valid_assignment_chain(dot_rhs, false),
|
Expr::Variable(_, _) if is_top => valid_assignment_chain(dot_rhs, false),
|
||||||
@ -1875,6 +1879,7 @@ fn parse_binary_op<'a>(
|
|||||||
Token::PlusAssign => parse_op_assignment("+", current_lhs, rhs, pos)?,
|
Token::PlusAssign => parse_op_assignment("+", current_lhs, rhs, pos)?,
|
||||||
Token::MinusAssign => parse_op_assignment("-", current_lhs, rhs, pos)?,
|
Token::MinusAssign => parse_op_assignment("-", current_lhs, rhs, pos)?,
|
||||||
|
|
||||||
|
#[cfg(not(feature = "no_object"))]
|
||||||
Token::Period => {
|
Token::Period => {
|
||||||
fn change_var_to_property(expr: Expr) -> Expr {
|
fn change_var_to_property(expr: Expr) -> Expr {
|
||||||
match expr {
|
match expr {
|
||||||
|
@ -16,6 +16,7 @@ fn test_arrays() -> Result<(), EvalAltResult> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
#[cfg(not(feature = "no_object"))]
|
||||||
fn test_array_with_structs() -> Result<(), EvalAltResult> {
|
fn test_array_with_structs() -> Result<(), EvalAltResult> {
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
struct TestStruct {
|
struct TestStruct {
|
||||||
|
@ -27,6 +27,7 @@ fn test_expressions() -> Result<(), EvalAltResult> {
|
|||||||
|
|
||||||
/// This example taken from https://github.com/jonathandturner/rhai/issues/115
|
/// This example taken from https://github.com/jonathandturner/rhai/issues/115
|
||||||
#[test]
|
#[test]
|
||||||
|
#[cfg(not(feature = "no_object"))]
|
||||||
fn test_expressions_eval() -> Result<(), EvalAltResult> {
|
fn test_expressions_eval() -> Result<(), EvalAltResult> {
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
struct AGENT {
|
struct AGENT {
|
||||||
|
@ -21,6 +21,7 @@ fn test_float() -> Result<(), EvalAltResult> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
#[cfg(not(feature = "no_object"))]
|
||||||
fn struct_with_float() -> Result<(), EvalAltResult> {
|
fn struct_with_float() -> Result<(), EvalAltResult> {
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
struct TestStruct {
|
struct TestStruct {
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
#![cfg(not(feature = "no_object"))]
|
||||||
|
|
||||||
use rhai::{Engine, EvalAltResult, RegisterFn, INT};
|
use rhai::{Engine, EvalAltResult, RegisterFn, INT};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -12,12 +12,12 @@ fn test_math() -> Result<(), EvalAltResult> {
|
|||||||
|
|
||||||
#[cfg(not(feature = "only_i32"))]
|
#[cfg(not(feature = "only_i32"))]
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
engine.eval::<INT>("(-9223372036854775807).abs()")?,
|
engine.eval::<INT>("abs(-9223372036854775807)")?,
|
||||||
9_223_372_036_854_775_807
|
9_223_372_036_854_775_807
|
||||||
);
|
);
|
||||||
|
|
||||||
#[cfg(feature = "only_i32")]
|
#[cfg(feature = "only_i32")]
|
||||||
assert_eq!(engine.eval::<INT>("(-2147483647).abs()")?, 2147483647);
|
assert_eq!(engine.eval::<INT>("abs(-2147483647)")?, 2147483647);
|
||||||
|
|
||||||
// Overflow/underflow/division-by-zero errors
|
// Overflow/underflow/division-by-zero errors
|
||||||
#[cfg(not(feature = "unchecked"))]
|
#[cfg(not(feature = "unchecked"))]
|
||||||
@ -26,7 +26,7 @@ fn test_math() -> Result<(), EvalAltResult> {
|
|||||||
{
|
{
|
||||||
assert!(matches!(
|
assert!(matches!(
|
||||||
engine
|
engine
|
||||||
.eval::<INT>("(-9223372036854775808).abs()")
|
.eval::<INT>("abs(-9223372036854775808)")
|
||||||
.expect_err("expects negation overflow"),
|
.expect_err("expects negation overflow"),
|
||||||
EvalAltResult::ErrorArithmetic(_, _)
|
EvalAltResult::ErrorArithmetic(_, _)
|
||||||
));
|
));
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
#![cfg(not(feature = "no_object"))]
|
||||||
|
|
||||||
use rhai::{Engine, EvalAltResult, RegisterFn, INT};
|
use rhai::{Engine, EvalAltResult, RegisterFn, INT};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -12,6 +12,7 @@ fn test_mismatched_op() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
#[cfg(not(feature = "no_object"))]
|
||||||
fn test_mismatched_op_custom_type() {
|
fn test_mismatched_op_custom_type() {
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
struct TestStruct {
|
struct TestStruct {
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
#![cfg(not(feature = "no_object"))]
|
||||||
|
|
||||||
///! This test simulates an external command object that is driven by a script.
|
///! This test simulates an external command object that is driven by a script.
|
||||||
use rhai::{Engine, EvalAltResult, RegisterFn, Scope, INT};
|
use rhai::{Engine, EvalAltResult, RegisterFn, Scope, INT};
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
|
Loading…
Reference in New Issue
Block a user