Remove no_stdlib feature in favor of Engine::new_raw().
This commit is contained in:
parent
e0bb2e5c97
commit
bcff6bfd71
@ -20,16 +20,14 @@ categories = [ "no-std", "embedded", "parser-implementations" ]
|
|||||||
num-traits = "*"
|
num-traits = "*"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
#default = ["no_function", "no_index", "no_object", "no_float", "only_i32", "no_stdlib", "unchecked", "no_optimize", "sync"]
|
#default = ["no_stdlib", "no_function", "no_index", "no_object", "no_float", "only_i32", "unchecked", "no_optimize", "sync"]
|
||||||
default = []
|
default = []
|
||||||
unchecked = [] # unchecked arithmetic
|
unchecked = [] # unchecked arithmetic
|
||||||
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_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
|
|
||||||
only_i32 = [] # set INT=i32 (useful for 32-bit systems)
|
only_i32 = [] # set INT=i32 (useful for 32-bit systems)
|
||||||
only_i64 = [] # set INT=i64 (default) and disable support for all other integer types
|
only_i64 = [] # set INT=i64 (default) and disable support for all other integer types
|
||||||
sync = [] # restrict to only types that implement Send + Sync
|
sync = [] # restrict to only types that implement Send + Sync
|
||||||
@ -37,6 +35,10 @@ sync = [] # restrict to only types that implement Send + Sync
|
|||||||
# compiling for no-std
|
# compiling for no-std
|
||||||
no_std = [ "num-traits/libm", "hashbrown", "core-error", "libm" ]
|
no_std = [ "num-traits/libm", "hashbrown", "core-error", "libm" ]
|
||||||
|
|
||||||
|
# other developer features
|
||||||
|
no_stdlib = [] # do not register the standard library
|
||||||
|
optimize_full = [] # set optimization level to Full (default is Simple) - this is a feature used only to simplify testing
|
||||||
|
|
||||||
[profile.release]
|
[profile.release]
|
||||||
lto = "fat"
|
lto = "fat"
|
||||||
codegen-units = 1
|
codegen-units = 1
|
||||||
|
47
README.md
47
README.md
@ -60,8 +60,7 @@ Optional features
|
|||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
| Feature | Description |
|
| Feature | Description |
|
||||||
| ------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
| ------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
|
||||||
| `no_stdlib` | Exclude the standard library of utility functions in the build, and only include the minimum necessary functionalities. Standard types are not affected. |
|
|
||||||
| `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. |
|
||||||
@ -78,7 +77,6 @@ Most features are here to opt-**out** of certain functionalities that are not ne
|
|||||||
Excluding unneeded functionalities can result in smaller, faster builds as well as less bugs due to a more restricted language.
|
Excluding unneeded functionalities can result in smaller, faster builds as well as less bugs due to a more restricted language.
|
||||||
|
|
||||||
[`unchecked`]: #optional-features
|
[`unchecked`]: #optional-features
|
||||||
[`no_stdlib`]: #optional-features
|
|
||||||
[`no_index`]: #optional-features
|
[`no_index`]: #optional-features
|
||||||
[`no_float`]: #optional-features
|
[`no_float`]: #optional-features
|
||||||
[`no_function`]: #optional-features
|
[`no_function`]: #optional-features
|
||||||
@ -160,7 +158,7 @@ Hello world
|
|||||||
|
|
||||||
[`Engine`]: #hello-world
|
[`Engine`]: #hello-world
|
||||||
|
|
||||||
To get going with Rhai, create an instance of the scripting engine and then call `eval`:
|
To get going with Rhai, create an instance of the scripting engine via `Engine::new` and then call the `eval` method:
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
use rhai::{Engine, EvalAltResult};
|
use rhai::{Engine, EvalAltResult};
|
||||||
@ -253,6 +251,27 @@ let result: i64 = engine.call_fn(&mut scope, &ast, "hello", () )?
|
|||||||
// ^^ unit = tuple of zero
|
// ^^ unit = tuple of zero
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Raw `Engine`
|
||||||
|
------------
|
||||||
|
|
||||||
|
[raw `Engine`]: #raw-engine
|
||||||
|
|
||||||
|
`Engine::new` creates a scripting [`Engine`] with common functionalities (e.g. printing to the console via `print`).
|
||||||
|
In many controlled embedded environments, however, these are not needed.
|
||||||
|
|
||||||
|
Use `Engine::new_raw` to create a _raw_ `Engine`, in which:
|
||||||
|
|
||||||
|
* the `print` and `debug` statements do nothing instead of displaying to the console (see [`print` and `debug`](#print-and-debug) below)
|
||||||
|
* the _standard library_ of utility functions is _not_ loaded by default (load it using the `register_stdlib` method).
|
||||||
|
|
||||||
|
```rust
|
||||||
|
let mut engine = Engine::new_raw(); // Create a 'raw' Engine
|
||||||
|
|
||||||
|
engine.register_stdlib(); // Register the standard library manually
|
||||||
|
|
||||||
|
engine.
|
||||||
|
```
|
||||||
|
|
||||||
Evaluate expressions only
|
Evaluate expressions only
|
||||||
-------------------------
|
-------------------------
|
||||||
|
|
||||||
@ -263,8 +282,8 @@ In these cases, use the `compile_expression` and `eval_expression` methods or th
|
|||||||
let result = engine.eval_expression::<i64>("2 + (10 + 10) * 2")?;
|
let result = engine.eval_expression::<i64>("2 + (10 + 10) * 2")?;
|
||||||
```
|
```
|
||||||
|
|
||||||
When evaluation _expressions_, no control-flow statement (e.g. `if`, `while`, `for`) is not supported and will be
|
When evaluation _expressions_, no full-blown statement (e.g. `if`, `while`, `for`) - not even variable assignments -
|
||||||
parse errors when encountered - not even variable assignments.
|
is supported and will be considered parse errors when encountered.
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
// The following are all syntax errors because the script is not an expression.
|
// The following are all syntax errors because the script is not an expression.
|
||||||
@ -955,7 +974,7 @@ number = -5 - +5;
|
|||||||
Numeric functions
|
Numeric functions
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
The following standard functions (defined in the standard library but excluded if [`no_stdlib`]) operate on
|
The following standard functions (defined in the standard library but excluded if using a [raw `Engine`]) operate on
|
||||||
`i8`, `i16`, `i32`, `i64`, `f32` and `f64` only:
|
`i8`, `i16`, `i32`, `i64`, `f32` and `f64` only:
|
||||||
|
|
||||||
| Function | Description |
|
| Function | Description |
|
||||||
@ -966,7 +985,7 @@ The following standard functions (defined in the standard library but excluded i
|
|||||||
Floating-point functions
|
Floating-point functions
|
||||||
------------------------
|
------------------------
|
||||||
|
|
||||||
The following standard functions (defined in the standard library but excluded if [`no_stdlib`]) operate on `f64` only:
|
The following standard functions (defined in the standard library but excluded if using a [raw `Engine`]) operate on `f64` only:
|
||||||
|
|
||||||
| Category | Functions |
|
| Category | Functions |
|
||||||
| ---------------- | ------------------------------------------------------------ |
|
| ---------------- | ------------------------------------------------------------ |
|
||||||
@ -996,7 +1015,7 @@ Individual characters within a Rhai string can also be replaced just as if the s
|
|||||||
In Rhai, there is also no separate concepts of `String` and `&str` as in Rust.
|
In Rhai, there is also no separate concepts of `String` and `&str` as in Rust.
|
||||||
|
|
||||||
Strings can be built up from other strings and types via the `+` operator (provided by the standard library but excluded
|
Strings can be built up from other strings and types via the `+` operator (provided by the standard library but excluded
|
||||||
if [`no_stdlib`]). This is particularly useful when printing output.
|
if using a [raw `Engine`]). This is particularly useful when printing output.
|
||||||
|
|
||||||
[`type_of()`] a string returns `"string"`.
|
[`type_of()`] a string returns `"string"`.
|
||||||
|
|
||||||
@ -1044,7 +1063,7 @@ record == "Bob X. Davis: age 42 ❤\n";
|
|||||||
'C' in record == false;
|
'C' in record == false;
|
||||||
```
|
```
|
||||||
|
|
||||||
The following standard functions (defined in the standard library but excluded if [`no_stdlib`]) operate on strings:
|
The following standard functions (defined in the standard library but excluded if using a [raw `Engine`]) operate on strings:
|
||||||
|
|
||||||
| Function | Description |
|
| Function | Description |
|
||||||
| ---------- | ------------------------------------------------------------------------ |
|
| ---------- | ------------------------------------------------------------------------ |
|
||||||
@ -1097,7 +1116,7 @@ The Rust type of a Rhai array is `rhai::Array`. [`type_of()`] an array returns `
|
|||||||
|
|
||||||
Arrays are disabled via the [`no_index`] feature.
|
Arrays are disabled via the [`no_index`] feature.
|
||||||
|
|
||||||
The following functions (defined in the standard library but excluded if [`no_stdlib`]) operate on arrays:
|
The following functions (defined in the standard library but excluded if using a [raw `Engine`]) operate on arrays:
|
||||||
|
|
||||||
| Function | Description |
|
| Function | Description |
|
||||||
| ------------ | ------------------------------------------------------------------------------------- |
|
| ------------ | ------------------------------------------------------------------------------------- |
|
||||||
@ -1193,7 +1212,7 @@ The Rust type of a Rhai object map is `rhai::Map`. [`type_of()`] an object map r
|
|||||||
|
|
||||||
Object maps are disabled via the [`no_object`] feature.
|
Object maps are disabled via the [`no_object`] feature.
|
||||||
|
|
||||||
The following functions (defined in the standard library but excluded if [`no_stdlib`]) operate on object maps:
|
The following functions (defined in the standard library but excluded if using a [raw `Engine`]) operate on object maps:
|
||||||
|
|
||||||
| Function | Description |
|
| Function | Description |
|
||||||
| ------------ | ---------------------------------------------------------------------------------------------------------------------------------------- |
|
| ------------ | ---------------------------------------------------------------------------------------------------------------------------------------- |
|
||||||
@ -1271,7 +1290,7 @@ Comparison operators
|
|||||||
|
|
||||||
Comparing most values of the same data type work out-of-the-box for standard types supported by the system.
|
Comparing most values of the same data type work out-of-the-box for standard types supported by the system.
|
||||||
|
|
||||||
However, if the [`no_stdlib`] feature is turned on, comparisons can only be made between restricted system types -
|
However, if using a [raw `Engine`], comparisons can only be made between restricted system types -
|
||||||
`INT` (`i64` or `i32` depending on [`only_i32`] and [`only_i64`]), `f64` (if not [`no_float`]), string, array, `bool`, `char`.
|
`INT` (`i64` or `i32` depending on [`only_i32`] and [`only_i64`]), `f64` (if not [`no_float`]), string, array, `bool`, `char`.
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
@ -1753,7 +1772,7 @@ An [`Engine`]'s optimization level is set via a call to `set_optimization_level`
|
|||||||
engine.set_optimization_level(rhai::OptimizationLevel::Full);
|
engine.set_optimization_level(rhai::OptimizationLevel::Full);
|
||||||
```
|
```
|
||||||
|
|
||||||
If it is ever needed to _re_-optimize an `AST`, use the `optimize_ast` method.
|
If it is ever needed to _re_-optimize an `AST`, use the `optimize_ast` method:
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
// Compile script to AST
|
// Compile script to AST
|
||||||
|
33
src/api.rs
33
src/api.rs
@ -387,8 +387,30 @@ impl<'e> Engine<'e> {
|
|||||||
/// # }
|
/// # }
|
||||||
/// ```
|
/// ```
|
||||||
pub fn compile_with_scope(&self, scope: &Scope, input: &str) -> Result<AST, ParseError> {
|
pub fn compile_with_scope(&self, scope: &Scope, input: &str) -> Result<AST, ParseError> {
|
||||||
|
self.compile_with_scope_and_optimization_level(
|
||||||
|
scope,
|
||||||
|
input,
|
||||||
|
#[cfg(not(feature = "no_optimize"))]
|
||||||
|
self.optimization_level,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Compile a string into an `AST` using own scope at a specific optimization level.
|
||||||
|
pub(crate) fn compile_with_scope_and_optimization_level(
|
||||||
|
&self,
|
||||||
|
scope: &Scope,
|
||||||
|
input: &str,
|
||||||
|
#[cfg(not(feature = "no_optimize"))] optimization_level: OptimizationLevel,
|
||||||
|
) -> Result<AST, ParseError> {
|
||||||
let tokens_stream = lex(input);
|
let tokens_stream = lex(input);
|
||||||
parse(&mut tokens_stream.peekable(), self, scope)
|
|
||||||
|
parse(
|
||||||
|
&mut tokens_stream.peekable(),
|
||||||
|
self,
|
||||||
|
scope,
|
||||||
|
#[cfg(not(feature = "no_optimize"))]
|
||||||
|
optimization_level,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Read the contents of a file into a string.
|
/// Read the contents of a file into a string.
|
||||||
@ -800,7 +822,13 @@ impl<'e> Engine<'e> {
|
|||||||
pub fn consume_with_scope(&self, scope: &mut Scope, input: &str) -> Result<(), EvalAltResult> {
|
pub fn consume_with_scope(&self, scope: &mut Scope, input: &str) -> Result<(), EvalAltResult> {
|
||||||
let tokens_stream = lex(input);
|
let tokens_stream = lex(input);
|
||||||
|
|
||||||
let ast = parse(&mut tokens_stream.peekable(), self, scope)
|
let ast = parse(
|
||||||
|
&mut tokens_stream.peekable(),
|
||||||
|
self,
|
||||||
|
scope,
|
||||||
|
#[cfg(not(feature = "no_optimize"))]
|
||||||
|
self.optimization_level,
|
||||||
|
)
|
||||||
.map_err(EvalAltResult::ErrorParsing)?;
|
.map_err(EvalAltResult::ErrorParsing)?;
|
||||||
|
|
||||||
self.consume_ast_with_scope(scope, &ast)
|
self.consume_ast_with_scope(scope, &ast)
|
||||||
@ -837,7 +865,6 @@ impl<'e> Engine<'e> {
|
|||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// # fn main() -> Result<(), rhai::EvalAltResult> {
|
/// # fn main() -> Result<(), rhai::EvalAltResult> {
|
||||||
/// # #[cfg(not(feature = "no_stdlib"))]
|
|
||||||
/// # #[cfg(not(feature = "no_function"))]
|
/// # #[cfg(not(feature = "no_function"))]
|
||||||
/// # {
|
/// # {
|
||||||
/// use rhai::{Engine, Scope};
|
/// use rhai::{Engine, Scope};
|
||||||
|
@ -757,8 +757,7 @@ macro_rules! reg_fn2y {
|
|||||||
|
|
||||||
/// Register the built-in library.
|
/// Register the built-in library.
|
||||||
impl Engine<'_> {
|
impl Engine<'_> {
|
||||||
#[cfg(not(feature = "no_stdlib"))]
|
pub fn register_stdlib(&mut self) {
|
||||||
pub(crate) fn register_stdlib(&mut self) {
|
|
||||||
#[cfg(not(feature = "no_float"))]
|
#[cfg(not(feature = "no_float"))]
|
||||||
{
|
{
|
||||||
// Advanced math functions
|
// Advanced math functions
|
||||||
|
@ -283,28 +283,25 @@ pub struct Engine<'e> {
|
|||||||
|
|
||||||
impl Default for Engine<'_> {
|
impl Default for Engine<'_> {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
// User-friendly names for built-in types
|
|
||||||
let type_names = [
|
|
||||||
#[cfg(not(feature = "no_index"))]
|
|
||||||
(type_name::<Array>(), "array"),
|
|
||||||
#[cfg(not(feature = "no_object"))]
|
|
||||||
(type_name::<Map>(), "map"),
|
|
||||||
(type_name::<String>(), "string"),
|
|
||||||
(type_name::<Dynamic>(), "dynamic"),
|
|
||||||
(type_name::<Variant>(), "variant"),
|
|
||||||
]
|
|
||||||
.iter()
|
|
||||||
.map(|(k, v)| (k.to_string(), v.to_string()))
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
// Create the new scripting Engine
|
// Create the new scripting Engine
|
||||||
let mut engine = Engine {
|
let mut engine = Engine {
|
||||||
functions: None,
|
functions: None,
|
||||||
type_iterators: None,
|
type_iterators: None,
|
||||||
type_names: Some(type_names),
|
type_names: None,
|
||||||
on_print: Some(Box::new(default_print)), // default print/debug implementations
|
|
||||||
|
// default print/debug implementations
|
||||||
|
#[cfg(not(feature = "no_std"))]
|
||||||
|
on_print: Some(Box::new(default_print)),
|
||||||
|
#[cfg(not(feature = "no_std"))]
|
||||||
on_debug: Some(Box::new(default_print)),
|
on_debug: Some(Box::new(default_print)),
|
||||||
|
|
||||||
|
// default print/debug implementations
|
||||||
|
#[cfg(feature = "no_std")]
|
||||||
|
on_print: None,
|
||||||
|
#[cfg(feature = "no_std")]
|
||||||
|
on_debug: None,
|
||||||
|
|
||||||
|
// optimization level
|
||||||
#[cfg(not(feature = "no_optimize"))]
|
#[cfg(not(feature = "no_optimize"))]
|
||||||
#[cfg(not(feature = "optimize_full"))]
|
#[cfg(not(feature = "optimize_full"))]
|
||||||
optimization_level: OptimizationLevel::Simple,
|
optimization_level: OptimizationLevel::Simple,
|
||||||
@ -316,10 +313,11 @@ impl Default for Engine<'_> {
|
|||||||
max_call_stack_depth: MAX_CALL_STACK_DEPTH,
|
max_call_stack_depth: MAX_CALL_STACK_DEPTH,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
engine.fill_type_names();
|
||||||
engine.register_core_lib();
|
engine.register_core_lib();
|
||||||
|
|
||||||
#[cfg(not(feature = "no_stdlib"))]
|
#[cfg(not(feature = "no_stdlib"))]
|
||||||
engine.register_stdlib(); // Register the standard library when no_stdlib is not set
|
engine.register_stdlib();
|
||||||
|
|
||||||
engine
|
engine
|
||||||
}
|
}
|
||||||
@ -354,6 +352,24 @@ fn extract_prop_from_setter(fn_name: &str) -> Option<&str> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Engine<'_> {
|
impl Engine<'_> {
|
||||||
|
fn fill_type_names(&mut self) {
|
||||||
|
// User-friendly names for built-in types
|
||||||
|
self.type_names = Some(
|
||||||
|
[
|
||||||
|
#[cfg(not(feature = "no_index"))]
|
||||||
|
(type_name::<Array>(), "array"),
|
||||||
|
#[cfg(not(feature = "no_object"))]
|
||||||
|
(type_name::<Map>(), "map"),
|
||||||
|
(type_name::<String>(), "string"),
|
||||||
|
(type_name::<Dynamic>(), "dynamic"),
|
||||||
|
(type_name::<Variant>(), "variant"),
|
||||||
|
]
|
||||||
|
.iter()
|
||||||
|
.map(|(k, v)| (k.to_string(), v.to_string()))
|
||||||
|
.collect(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/// Create a new `Engine`
|
/// Create a new `Engine`
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
// fn abc<F: Fn() + Send + Sync>(f: F) {
|
// fn abc<F: Fn() + Send + Sync>(f: F) {
|
||||||
@ -364,7 +380,7 @@ impl Engine<'_> {
|
|||||||
Default::default()
|
Default::default()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a new `Engine` with minimal configurations - i.e. without pretty-print type names etc.
|
/// Create a new `Engine` with minimal configurations without the standard library etc.
|
||||||
pub fn new_raw() -> Self {
|
pub fn new_raw() -> Self {
|
||||||
let mut engine = Engine {
|
let mut engine = Engine {
|
||||||
functions: None,
|
functions: None,
|
||||||
@ -384,11 +400,9 @@ impl Engine<'_> {
|
|||||||
max_call_stack_depth: MAX_CALL_STACK_DEPTH,
|
max_call_stack_depth: MAX_CALL_STACK_DEPTH,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
engine.fill_type_names();
|
||||||
engine.register_core_lib();
|
engine.register_core_lib();
|
||||||
|
|
||||||
#[cfg(not(feature = "no_stdlib"))]
|
|
||||||
engine.register_stdlib(); // Register the standard library when no_stdlib is not set
|
|
||||||
|
|
||||||
engine
|
engine
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1487,14 +1501,25 @@ impl Engine<'_> {
|
|||||||
})?;
|
})?;
|
||||||
|
|
||||||
// Compile the script text
|
// Compile the script text
|
||||||
let mut ast = self.compile(script).map_err(EvalAltResult::ErrorParsing)?;
|
// No optimizations because we only run it once
|
||||||
|
let mut ast = self
|
||||||
|
.compile_with_scope_and_optimization_level(
|
||||||
|
&Scope::new(),
|
||||||
|
script,
|
||||||
|
#[cfg(not(feature = "no_optimize"))]
|
||||||
|
OptimizationLevel::None,
|
||||||
|
)
|
||||||
|
.map_err(EvalAltResult::ErrorParsing)?;
|
||||||
|
|
||||||
// If new functions are defined within the eval string, it is an error
|
// If new functions are defined within the eval string, it is an error
|
||||||
|
#[cfg(not(feature = "no_function"))]
|
||||||
|
{
|
||||||
if ast.1.len() > 0 {
|
if ast.1.len() > 0 {
|
||||||
return Err(EvalAltResult::ErrorParsing(
|
return Err(EvalAltResult::ErrorParsing(
|
||||||
ParseErrorType::WrongFnDefinition.into_err(pos),
|
ParseErrorType::WrongFnDefinition.into_err(pos),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if let Some(lib) = fn_lib {
|
if let Some(lib) = fn_lib {
|
||||||
#[cfg(feature = "sync")]
|
#[cfg(feature = "sync")]
|
||||||
@ -1760,11 +1785,6 @@ impl Engine<'_> {
|
|||||||
|
|
||||||
/// Print/debug to stdout
|
/// Print/debug to stdout
|
||||||
#[cfg(not(feature = "no_std"))]
|
#[cfg(not(feature = "no_std"))]
|
||||||
#[cfg(not(feature = "no_stdlib"))]
|
|
||||||
fn default_print(s: &str) {
|
fn default_print(s: &str) {
|
||||||
println!("{}", s);
|
println!("{}", s);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// No-op
|
|
||||||
#[cfg(any(feature = "no_std", feature = "no_stdlib"))]
|
|
||||||
fn default_print(_: &str) {}
|
|
||||||
|
@ -40,7 +40,6 @@
|
|||||||
//!
|
//!
|
||||||
//! | Feature | Description |
|
//! | Feature | Description |
|
||||||
//! | ------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
//! | ------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||||
//! | `no_stdlib` | Exclude the standard library of utility functions in the build, and only include the minimum necessary functionalities. Standard types are not affected. |
|
|
||||||
//! | `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. |
|
||||||
|
@ -6,7 +6,7 @@ use crate::error::{LexError, ParseError, ParseErrorType};
|
|||||||
use crate::scope::{EntryType as ScopeEntryType, Scope};
|
use crate::scope::{EntryType as ScopeEntryType, Scope};
|
||||||
|
|
||||||
#[cfg(not(feature = "no_optimize"))]
|
#[cfg(not(feature = "no_optimize"))]
|
||||||
use crate::optimize::optimize_into_ast;
|
use crate::optimize::{optimize_into_ast, OptimizationLevel};
|
||||||
|
|
||||||
use crate::stdlib::{
|
use crate::stdlib::{
|
||||||
borrow::Cow,
|
borrow::Cow,
|
||||||
@ -2866,19 +2866,14 @@ pub fn parse<'a, 'e>(
|
|||||||
input: &mut Peekable<TokenIterator<'a>>,
|
input: &mut Peekable<TokenIterator<'a>>,
|
||||||
engine: &Engine<'e>,
|
engine: &Engine<'e>,
|
||||||
scope: &Scope,
|
scope: &Scope,
|
||||||
|
#[cfg(not(feature = "no_optimize"))] optimization_level: OptimizationLevel,
|
||||||
) -> Result<AST, ParseError> {
|
) -> Result<AST, ParseError> {
|
||||||
let (statements, functions) = parse_global_level(input)?;
|
let (statements, functions) = parse_global_level(input)?;
|
||||||
|
|
||||||
Ok(
|
Ok(
|
||||||
// Optimize AST
|
// Optimize AST
|
||||||
#[cfg(not(feature = "no_optimize"))]
|
#[cfg(not(feature = "no_optimize"))]
|
||||||
optimize_into_ast(
|
optimize_into_ast(engine, scope, statements, functions, optimization_level),
|
||||||
engine,
|
|
||||||
scope,
|
|
||||||
statements,
|
|
||||||
functions,
|
|
||||||
engine.optimization_level,
|
|
||||||
),
|
|
||||||
//
|
//
|
||||||
// Do not optimize AST if `no_optimize`
|
// Do not optimize AST if `no_optimize`
|
||||||
#[cfg(feature = "no_optimize")]
|
#[cfg(feature = "no_optimize")]
|
||||||
|
@ -13,8 +13,6 @@ fn test_arrays() -> Result<(), EvalAltResult> {
|
|||||||
);
|
);
|
||||||
assert!(engine.eval::<bool>("let y = [1, 2, 3]; 2 in y")?);
|
assert!(engine.eval::<bool>("let y = [1, 2, 3]; 2 in y")?);
|
||||||
|
|
||||||
#[cfg(not(feature = "no_stdlib"))]
|
|
||||||
{
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
engine.eval::<INT>(
|
engine.eval::<INT>(
|
||||||
r"
|
r"
|
||||||
@ -48,7 +46,6 @@ fn test_arrays() -> Result<(), EvalAltResult> {
|
|||||||
.len(),
|
.len(),
|
||||||
5
|
5
|
||||||
);
|
);
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -33,8 +33,6 @@ fn test_map_indexing() -> Result<(), EvalAltResult> {
|
|||||||
assert!(engine.eval::<bool>("let y = #{a: 1, b: 2, c: 3}; 'b' in y")?);
|
assert!(engine.eval::<bool>("let y = #{a: 1, b: 2, c: 3}; 'b' in y")?);
|
||||||
assert!(!engine.eval::<bool>(r#"let y = #{a: 1, b: 2, c: 3}; "z" in y"#)?);
|
assert!(!engine.eval::<bool>(r#"let y = #{a: 1, b: 2, c: 3}; "z" in y"#)?);
|
||||||
|
|
||||||
#[cfg(not(feature = "no_stdlib"))]
|
|
||||||
{
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
engine.eval::<INT>(
|
engine.eval::<INT>(
|
||||||
r"
|
r"
|
||||||
@ -68,7 +66,6 @@ fn test_map_indexing() -> Result<(), EvalAltResult> {
|
|||||||
.len(),
|
.len(),
|
||||||
4
|
4
|
||||||
);
|
);
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -1,12 +1,11 @@
|
|||||||
use rhai::{Engine, EvalAltResult, RegisterFn, INT};
|
use rhai::{Engine, EvalAltResult, RegisterFn, INT};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[cfg(not(feature = "no_stdlib"))]
|
|
||||||
fn test_mismatched_op() {
|
fn test_mismatched_op() {
|
||||||
let engine = Engine::new();
|
let engine = Engine::new();
|
||||||
|
|
||||||
assert!(
|
assert!(
|
||||||
matches!(engine.eval::<INT>(r#"60 + "hello""#).expect_err("expects error"),
|
matches!(engine.eval::<INT>(r#""hello, " + "world!""#).expect_err("expects error"),
|
||||||
EvalAltResult::ErrorMismatchOutputType(err, _) if err == "string")
|
EvalAltResult::ErrorMismatchOutputType(err, _) if err == "string")
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
#![cfg(not(feature = "no_function"))]
|
||||||
use rhai::{Engine, EvalAltResult};
|
use rhai::{Engine, EvalAltResult};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -22,12 +22,12 @@ fn test_string() -> Result<(), EvalAltResult> {
|
|||||||
#[cfg(not(feature = "no_stdlib"))]
|
#[cfg(not(feature = "no_stdlib"))]
|
||||||
assert_eq!(engine.eval::<String>(r#""foo" + 123"#)?, "foo123");
|
assert_eq!(engine.eval::<String>(r#""foo" + 123"#)?, "foo123");
|
||||||
|
|
||||||
|
#[cfg(not(feature = "no_stdlib"))]
|
||||||
|
assert_eq!(engine.eval::<String>("(42).to_string()")?, "42");
|
||||||
|
|
||||||
#[cfg(not(feature = "no_float"))]
|
#[cfg(not(feature = "no_float"))]
|
||||||
#[cfg(not(feature = "no_stdlib"))]
|
#[cfg(not(feature = "no_stdlib"))]
|
||||||
assert_eq!(engine.eval::<String>(r#""foo" + 123.4556"#)?, "foo123.4556");
|
assert_eq!(engine.eval::<String>(r#""foo" + 123.4556"#)?, "foo123.4556");
|
||||||
|
|
||||||
#[cfg(not(feature = "no_stdlib"))]
|
|
||||||
assert_eq!(engine.eval::<String>("(42).to_string()")?, "42");
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user