reorganize module

This commit is contained in:
Timur Gordon
2025-04-04 08:28:07 +02:00
parent 1ea37e2e7f
commit 939b6b4e57
375 changed files with 7580 additions and 191 deletions

View File

@@ -1,121 +0,0 @@
Packaged Utilities
==================
{{#include ../links.md}}
A number of Rhai-driven tools can be found in the `src/bin` directory:
```admonish tip.side "Tip: Domain-specific tools"
It is possible to turn these tools into [_Domain-Specific Tools_](../patterns/domain-tools.md).
```
| Tool | Required feature(s) | Description |
| :----------------------------------------------: | :-----------------: | ---------------------- |
| [`rhai-run`]({{repoHome}}/src/bin/rhai-run.rs) | | runs Rhai script files |
| [`rhai-repl`]({{repoHome}}/src/bin/rhai-repl.rs) | `rustyline` | a simple REPL tool |
| [`rhai-dbg`]({{repoHome}}/src/bin/rhai-dbg.rs) | [`debugging`] | the _Rhai Debugger_ |
~~~admonish tip "Tip: `bin-features`"
Some bin tools require certain [features] and will not be built by default without those [features] set.
For convenience, a feature named [`bin-features`][features] is available which is a combination of
the following:
| Feature | Description |
| :-----------: | ------------------------------------------- |
| [`decimal`] | support for [decimal][rust_decimal] numbers |
| [`metadata`] | access [functions metadata] |
| [`serde`] | export [functions metadata] to JSON |
| [`debugging`] | required by `rhai-dbg` |
| `rustyline` | required by `rhai-repl` |
~~~
Install Tools
-------------
To install all these tools (with full features), use the following command:
```sh
cargo install --path . --bins --features bin-features
```
or specifically:
```sh
cargo install --path . --bin sample_app_to_run --features bin-features
```
Run a Tool from Cargo
---------------------
Tools can also be run with the following `cargo` command:
```sh
cargo run --features bin-features --bin sample_app_to_run
```
Tools List
----------
~~~admonish example "`rhai-repl` – The Rhai REPL Tool"
`rhai-repl` is a particularly useful tool – it allows one to interactively try out
Rhai's language features in a standard REPL (**R**ead-**E**val-**P**rint **L**oop).
Filenames passed to it as command line arguments are run and loaded as Rhai scripts before the REPL starts.
### Test functions
The following test functions are pre-registered, via `Engine::register_fn`, into `rhai-repl`.
They are intended for testing purposes.
| Function | Description |
| ------------------------------------ | ------------------------------------------ |
| `test(x: i64, y: i64)` | returns a string with both numbers |
| `test(x: &mut i64, y: i64, z: &str)` | displays the parameters and add `y` to `x` |
### Example
The following command first runs three scripts – `init1.rhai`, `init2.rhai` and `init3.rhai` –
loading the functions defined in each script into the _global_ namespace.
Then it enters an REPL, which can call the above functions freely.
```sh
rhai-repl init1.rhai init2.rhai init3.rhai
```
~~~
~~~admonish danger "`rhai-run` – The Rhai Runner"
Use `rhai-run` to run Rhai scripts.
Filenames passed to it as command line arguments are run in sequence as Rhai scripts.
### Example
The following command runs the scripts `script1.rhai`, `script2.rhai` and `script3.rhai` in order.
```sh
rhai-run script1.rhai script2.rhai script3.rhai
```
~~~
~~~admonish bug "`rhai-dbg` – The Rhai Debugger"
Use `rhai-dbg` to debug a Rhai script.
Filename passed to it will be loaded as a Rhai script for debugging.
### Example
The following command debugs the script `my_script.rhai`.
```sh
rhai-dbg my_script.rhai
```
~~~

View File

@@ -1,7 +0,0 @@
Special Builds
==============
{{#include ../../links.md}}
It is possible to mix-and-match various [features] of the Rhai crate to make specialized builds with
specific characteristics and behaviors.

View File

@@ -1,67 +0,0 @@
Minimal Build
=============
{{#include ../../links.md}}
Configuration
-------------
In order to compile a _minimal_ build – i.e. a build optimized for size – perhaps for
`no-std` embedded targets or for compiling to [WASM], it is essential that the correct linker flags
are used in `Cargo.toml`:
```toml
[profile.release]
lto = "fat" # turn on Link-Time Optimizations
codegen-units = 1 # trade compile time with maximum optimization
opt-level = "z" # optimize for size
```
Use `i32` Only
--------------
For embedded systems that must optimize for code size, the architecture is commonly 32-bit.
Use [`only_i32`] to prune away large sections of code implementing functions for other numeric types
(including `i64`).
If, for some reason, 64-bit long integers must be supported, use [`only_i64`] instead of [`only_i32`].
Opt-Out of Features
-------------------
Opt out of as many features as possible, if they are not needed, to reduce code size because,
remember, by default all code is compiled into the final binary since what a script requires cannot
be predicted. If a language feature will never be needed, omitting it is a prudent strategy to
optimize the build for size.
Removing the script [optimizer][script optimization] ([`no_optimize`]) yields a sizable code saving,
at the expense of a less efficient script.
Omitting [arrays] ([`no_index`]) yields the most code-size savings, followed by floating-point support
([`no_float`]), safety checks ([`unchecked`]) and finally [object maps] and [custom types] ([`no_object`]).
Where the usage scenario does not call for loading externally-defined modules, use [`no_module`] to
save some bytes. Disable script-defined functions ([`no_function`]) and possibly closures
([`no_closure`]) when the features are not needed. Both of these have some code size savings but not much.
For embedded scripts that are not expected to cause errors, the [`no_position`] feature can be used
to disable position tracking during parsing. No line number/character position information is kept
for error reporting purposes. This may result in a slightly smaller build due to elimination of code
related to position tracking.
Use a Raw [`Engine`]
--------------------
[`Engine::new_raw`][raw `Engine`] creates a _raw_ engine. A _raw_ engine supports, out of the box,
only a very [restricted set][built-in operators] of basic arithmetic and logical operators.
Selectively include other necessary functionalities by picking specific [packages] to minimize the footprint.
Packages are shared (even across threads via the [`sync`] feature), so they only have to be created once.
In addition, a [`Engine::new_raw`][raw `Engine`] disables the _[strings interner]_, which might
actually increase memory usage if many strings are created in scripts. Therefore, selectively turn
on the [strings interner] via [`Engine::set_max_strings_interned`][options].

View File

@@ -1,80 +0,0 @@
`no-std` Build
==============
{{#include ../../links.md}}
The feature [`no_std`] automatically converts the scripting engine into a `no-std` build.
Usually, a `no-std` build goes hand-in-hand with [minimal builds] because typical embedded
hardware (the primary target for `no-std`) has limited storage.
```admonish warning "Nightly required"
Currently, [`no_std`] requires the nightly compiler due to the crates that it uses.
```
Implementation
--------------
Rhai allocates, so the first thing that must be included in any `no-std` project is
an allocator crate, such as [`wee_alloc`](https://crates.io/crates/wee_alloc).
Then there is the need to set up proper error/panic handlers.
The following example uses `panic = "abort"` and `wee_alloc` as the allocator.
```rust
// Set up for no-std.
#![no_std]
// The following no-std features are usually needed.
#![feature(alloc_error_handler, start, core_intrinsics, lang_items, link_cfg)]
// Set up the global allocator.
extern crate alloc;
extern crate wee_alloc;
#[global_allocator]
static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT;
// Rust needs a CRT runtime on Windows when compiled with MSVC.
#[cfg(all(windows, target_env = "msvc"))]
#[link(name = "msvcrt")]
#[link(name = "libcmt")]
extern "C" {}
// Set up panic and error handlers
#[alloc_error_handler]
fn err_handler(_: core::alloc::Layout) -> ! {
core::intrinsics::abort();
}
#[panic_handler]
#[lang = "panic_impl"]
extern "C" fn rust_begin_panic(_: &core::panic::PanicInfo) -> ! {
core::intrinsics::abort();
}
#[lang = "eh_personality"]
extern "C" fn eh_personality() {}
#[no_mangle]
extern "C" fn rust_eh_register_frames() {}
#[no_mangle]
extern "C" fn rust_eh_unregister_frames() {}
#[no_mangle]
extern "C" fn _Unwind_Resume() {}
#[start]
fn main(_argc: isize, _argv: *const *const u8) -> isize {
// ... main program ...
}
```
```admonish example.small "Samples"
Check out the [`no-std` sample applications]({{rootUrl}}/start/examples/rust.html#no-std-examples)
for different operating environments.
```

View File

@@ -1,204 +0,0 @@
Performance Build
=================
{{#include ../../links.md}}
Some features are for performance. In order to squeeze out the maximum performance from Rhai, the
following features should be considered:
| Feature | Description | Rationale |
| -------------------- | ------------------------------------------------------ | ------------------------ |
| [`only_i32`] | support only a single `i32` integer type | reduce data size |
| [`no_float`] | remove support for floating-point numbers | reduce code size |
| [`f32_float`] | set floating-point numbers (if not disabled) to 32-bit | reduce data size |
| [`no_closure`] | remove support for [variables] sharing | no need for data locking |
| [`unchecked`] | disable all safety [checks][checked] | remove checking code |
| [`no_module`] | disable loading external [modules] | reduce code size |
| [`no_position`] | disable position tracking during parsing | reduce data size |
| [`no_custom_syntax`] | disable [custom syntax] | reduce code size |
When the above feature flags are used, performance may increase by around 15-20%.
~~~admonish info.small "See also: Benchmarks"
See Rhai performance [benchmarks].
~~~
Unchecked Build
---------------
By default, Rhai provides a [_Don't Panic_](https://en.wikipedia.org/wiki/Phrases_from_The_Hitchhiker%27s_Guide_to_the_Galaxy#Don't_Panic)
guarantee and prevents malicious scripts from bringing down the host. Any panic can be considered a bug.
For maximum performance, however, these [safety] checks can be turned off via the [`unchecked`] feature.
Fast Operators Mode
-------------------
Make sure that [_Fast Operators_ Mode][options], which is enabled by default, is on. It ignores any
user [overloading][operator overloading] of [built-in operators].
For operator-heavy scripts, this may provide a substantial speed-up.
Use Only One Integer Type
-------------------------
If only a single integer type is needed in scripts – most of the time this is the case –
it is best to avoid registering lots of functions related to other integer types that will never be used.
As a result, [`Engine`] creation will be faster because fewer functions need to be loaded.
The [`only_i32`] and [`only_i64`] features disable all integer types except `i32` or `i64` respectively.
Use Only 32-Bit Numbers
-----------------------
If only 32-bit integers are needed – again, most of the time this is the case – turn on [`only_i32`].
Under this feature, only `i32` is supported as a built-in integer type and no others.
On 64-bit targets this may not gain much, but on certain 32-bit targets this improves performance
due to 64-bit arithmetic requiring more CPU cycles to complete.
Minimize Size of `Dynamic`
--------------------------
Turning on [`f32_float`] (or [`no_float`]) and [`only_i32`] on 32-bit targets makes the critical
[`Dynamic`] data type only 8 bytes long for 32-bit targets.
Normally [`Dynamic`] needs to be up 12-16 bytes long in order to hold an `i64` or `f64`.
A smaller [`Dynamic`] helps performance due to better cache efficiency.
Use `ImmutableString`
---------------------
Internally, Rhai uses _immutable_ [strings] instead of the Rust `String` type.
This is mainly to avoid excessive cloning when passing function arguments.
Rhai's internal string type is [`ImmutableString`] (basically `Rc<SmartString>` or
`Arc<SmartString>` depending on the [`sync`] feature). It is cheap to clone, but expensive to modify
(a new copy of the string must be made in order to change it).
Therefore, functions taking `String` parameters should use [`ImmutableString`] or `&str`
(maps to [`ImmutableString`]) for the best performance with Rhai.
Disable Capturing in Closures
-----------------------------
```admonish info.side "Anonymous functions still work"
[Anonymous functions] continue to work even under [`no_closure`].
Only capturing of external shared [variables] is disabled.
```
Support for [closures] that capture _shared_ [variables] adds material overhead to script evaluation.
This is because every data access must be checked whether it is a shared value and, if so,
take a read lock before reading it.
As the vast majority of [variables] are _not_ shared, needless to say this is a non-trivial
performance overhead.
Use [`no_closure`] to disable support for [closures] to optimize the hot path because it no longer
needs to take locks for shared data.
Disable Position
----------------
For embedded scripts that are not expected to cause errors, the [`no_position`] feature can be used
to disable position tracking during parsing.
No line number/character position information is kept for error reporting purposes.
This may result in a slightly fast build due to elimination of code related to position tracking.
Avoid Cloning
-------------
### Use `&mut` functions
Rhai values are typically _cloned_ when passed around, especially into [function] calls.
Large data structures may incur material cloning overhead.
Some functions accept the first parameter as a mutable reference (i.e. `&mut`), for example
_methods_ for [custom types], and may avoid potentially-costly cloning.
### Compound assignment
For example, the `+=` (append) compound assignment takes a mutable reference to the [variable] while
the corresponding `+` (add) assignment usually doesn't. The difference in performance can be huge:
```rust
let x = create_some_very_big_and_expensive_type();
x = x + 1;
// ^ 'x' is cloned here
// The above is equivalent to:
let temp_value = x.clone() + 1;
x = temp_value;
x += 1; // <- 'x' is NOT cloned
```
### Use `take`
Another example: use the `take` function to extract a value out of a variable (replacing it with
[`()`]) without cloning.
```rust
let x = create_some_very_big_and_expensive_type();
let y = x; // <- 'x' is cloned here
let y = x.take(); // <- 'x' is NOT cloned
```
```admonish tip "Tip: Simple variable references are already optimized"
Rhai's script [optimizer][script optimization] is usually smart enough to _rewrite_ function calls
into [_method-call_]({{rootUrl}}/rust/methods.md) style or [_compound assignment_]({{rootUrl}}/language/assignment-op.md)
style to take advantage of this.
However, there are limits to its intelligence, and only **simple variable references** are optimized.
~~~rust
x = x + 1; // <- this statement...
x += 1; // ... is rewritten as this
x[y] = x[y] + 1; // <- but this is not, so this is MUCH slower...
x[y] += 1; // ... than this
some_func(x, 1); // <- this statement...
x.some_func(1); // ... is rewritten as this
some_func(x[y], 1); // <- but this is not, so 'x[y]` is cloned
~~~
```
Short Variable Names for 32-Bit Systems
---------------------------------------
On 32-bit systems, [variable] and [constant] names longer than 11 ASCII characters incur additional
allocation overhead.
This is particularly true for local variables inside a hot loop, where they are created and destroyed
in rapid succession.
Therefore, avoid long [variable] and [constant] names that are over this limit.
On 64-bit systems, this limit is raised to 23 ASCII characters, which is almost always adequate.

View File

@@ -1,116 +0,0 @@
WebAssembly (WASM) Build
========================
{{#include ../../links.md}}
```admonish question.side.wide "But why?"
There is already a fast and powerful scripting language that integrates nicely with WASM &ndash; **JavaScript**.
Anyhow, do it because you _can_!
```
It is possible to use Rhai when compiling to WebAssembly (WASM).
This yields a scripting engine (and language) that can be run in a standard web browser,
among other places.
```admonish warning "Unavailable features"
When building for WASM, certain features will not be available,
such as the script file APIs and loading [modules] from external script files.
```
```admonish example "Sample"
Check out the [_Online Playground_]({{rootUrl}}/tools/playground.md) project which is driven
by a Rhai [`Engine`] compiled into WASM.
```
JavaScript Interop
------------------
Specify either of the [`wasm-bindgen`] or [`stdweb`] features when building for WASM that requires
interop with JavaScript. This selects the appropriate JavaScript interop layer to use.
It is still possible to compile for WASM without either [`wasm-bindgen`] or [`stdweb`],
but then the interop code must then be explicitly provided.
Target Environments
-------------------
~~~admonish abstract "WASI: `wasm32-wasi`"
There is no particular setting to tweak when building for WASI.
~~~
~~~admonish abstract "JavaScript: `wasm32-unknown-unknown` + `wasm-bindgen`/`stdweb`"
Rhai requires a system-provided source of random numbers (for hashing).
Such random number source is available from JavaScript (implied by `wasm-bindgen` or `stdweb`).
The `js` feature on the [`getrandom`](https://crates.io/crates/getrandom) crate is
enabled automatically to provide the random number source.
See also: <https://docs.rs/getrandom/latest/getrandom/#webassembly-support> for details.
~~~
~~~admonish warning "Raw: `wasm32-unknown-unknown`"
Rhai requires a system-provided source of random numbers (for hashing).
Non-JavaScript/non-browser environments may not have random numbers available, so it is necessary to
opt out of `default-features` in order to enable [static hashing] which uses fixed (non-random) keys.
```toml
[dependencies]
rhai = { version = "{{version}}", default-features = false, features = [ "std" ] }
```
~~~
Size
----
Also look into [minimal builds] to reduce generated WASM size.
A typical, full-featured Rhai scripting engine compiles to a single WASM32 file that is less than
400KB (non-gzipped).
When excluding features that are marginal in WASM environment, the gzipped payload can be shrunk further.
Standard [packages][built-in packages] can also be excluded to yield additional size savings.
Speed
-----
In benchmark tests, a WASM build runs scripts roughly 30% slower than a native optimized release build.
Common Features
---------------
Some Rhai functionalities are not necessary in a WASM environment, so the following features
are typically used for a WASM build:
| Feature | Description |
| :----------------------------: | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [`wasm-bindgen`] or [`stdweb`] | use [`wasm-bindgen`](https://crates.io/crates/wasm-bindgen) or [`stdweb`](https://crates.io/crates/stdweb) as the JavaScript interop layer, omit if using custom interop code |
| [`unchecked`] | when a WASM module panics, it doesn't crash the entire web app; however this also disables [maximum number of operations] and [progress] tracking so a script can still run indefinitely &ndash; the web app must terminate it itself |
| [`only_i32`] | WASM supports 32-bit and 64-bit integers, but most scripts will only need 32-bit |
| [`f32_float`] | WASM supports 32-bit single-precision and 64-bit double-precision floating-point numbers, but single-precision is usually fine for most uses |
| [`no_module`] | a WASM module cannot load modules from the file system, so usually this is not needed, but the savings are minimal; alternatively, a custom [module resolver] can be provided that loads other Rhai scripts |
| [`no_custom_syntax`] | if [custom syntax] is not used, this results in a small size saving |
The following features are typically _not_ used because they don't make sense in a WASM build:
| Feature | Why unnecessary |
| :-----------: | ----------------------------------------------------------------------------------------------------- |
| [`sync`] | WASM is single-threaded |
| [`no_std`] | `std` lib works fine with WASM |
| [`metadata`] | WASM usually doesn't need access to Rhai functions metadata |
| [`internals`] | WASM usually doesn't need to access Rhai internal data structures, unless you are walking the [`AST`] |
| [`debugging`] | unless debugging is needed |

View File

@@ -1,7 +0,0 @@
Examples
========
{{#include ../../links.md}}
Rhai comes with a number of examples showing how to integrate the scripting [`Engine`] within a Rust
application, as well as a number of sample scripts that showcase different Rhai language features.

View File

@@ -1,73 +0,0 @@
Rust Examples
=============
{{#include ../../links.md}}
Standard Examples
-----------------
A number of examples can be found under `examples`.
| Example | Description |
| ------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------- |
| [`arrays_and_structs`]({{repoHome}}/examples/arrays_and_structs.rs) | shows how to register a [Rust type][custom type] and using it with [arrays] |
| [`callback`]({{repoHome}}/examples/callback.rs) | shows how to store a Rhai [closure] and call it later within Rust |
| [`custom_types_and_methods`]({{repoHome}}/examples/custom_types_and_methods.rs) | shows how to register a [Rust type][custom type] and [methods]/[getters/setters] for it |
| [`custom_types`]({{repoHome}}/examples/custom_types.rs) | shows how to register a [Rust type][custom type] and [methods]/[getters/setters] using the [`CustomType`] trait. |
| [`definitions`]({{repoHome}}/examples/definitions) | shows how to generate definition files for use with the [Rhai Language Server][lsp] (requires the [`metadata`] feature) |
| [`hello`]({{repoHome}}/examples/hello.rs) | simple example that evaluates an expression and prints the result |
| [`pause_and_resume`]({{repoHome}}/pause_and_resume.rs) | shows how to pause/resume/stop an `Engine` running in a separate thread via an MPSC channel |
| [`reuse_scope`]({{repoHome}}/examples/reuse_scope.rs) | evaluates two pieces of code in separate runs, but using a common [`Scope`] |
| [`serde`]({{repoHome}}/examples/serde.rs) | example to serialize and deserialize Rust types with [`serde`](https://crates.io/crates/serde) (requires the [`serde`] feature) |
| [`simple_fn`]({{repoHome}}/examples/simple_fn.rs) | shows how to register a simple Rust function |
| [`strings`]({{repoHome}}/examples/strings.rs) | shows different ways to register Rust functions taking [string] arguments |
| [`threading`]({{repoHome}}/examples/threading.rs) | shows how to communicate in duplex with an [`Engine`] running in a separate thread via a pair of MPSC channels |
Scriptable Event Handler With State Examples
--------------------------------------------
Because of its popularity, the pattern [_Scriptable Event Handler With State_]({{rootUrl}}/patterns/events.md)
has sample implementations for different styles.
| Example | Handler Script | Description |
| ---------------------------------------------------------------- | ---------------------------------------------------------------------------------------- | :----------------------------------------------: |
| [`event_handler_main`]({{repoHome}}/examples/event_handler_main) | [`event_handler_main/script.rhai`]({{repoHome}}/examples/event_handler_main/script.rhai) | [_Main Style_]({{rootUrl}}/patterns/events-1.md) |
| [`event_handler_js`]({{repoHome}}/examples/event_handler_js) | [`event_handler_js/script.rhai`]({{repoHome}}/examples/event_handler_js/script.rhai) | [_JS Style_]({{rootUrl}}/patterns/events-2.md) |
| [`event_handler_map`]({{repoHome}}/examples/event_handler_map) | [`event_handler_map/script.rhai`]({{repoHome}}/examples/event_handler_map/script.rhai) | [_Map Style_]({{rootUrl}}/patterns/events-3.md) |
Running Examples
----------------
Examples can be run with the following command:
```sh
cargo run --example {example_name}
```
`no-std` Examples
-----------------
To illustrate `no-std` builds, a number of example applications are available under the `no_std` directory:
| Example | Description | Optimization | Allocator | Panics |
| ------------------------------------------------ | ---------------------------------------------------------------------------------------------------- | :----------: | :-----------------------------------------------: | :----: |
| [`no_std_test`]({{repoHome}}/no_std/no_std_test) | bare-bones test application that evaluates a Rhai expression and sets the result as the return value | size | [`wee_alloc`](https://crates.io/crates/wee_alloc) | abort |
### Building the `no-std` examples
```admonish warning "Nightly required"
Currently, the nightly compiler must be used to build for `no-std`.
```
```sh
cd no_std/no_std_test
cargo +nightly build --release
./target/release/no_std_test
```

View File

@@ -1,59 +0,0 @@
Example Scripts
===============
{{#include ../../links.md}}
Language Feature Scripts
------------------------
There are also a number of examples scripts that showcase Rhai's features, all in the `scripts` directory:
| Script | Description |
| ----------------------------------------------------------------- | --------------------------------------------------------------------------------------------- |
| [`array.rhai`]({{repoHome}}/scripts/array.rhai) | [arrays] example |
| [`assignment.rhai`]({{repoHome}}/scripts/assignment.rhai) | [variable] declarations |
| [`comments.rhai`]({{repoHome}}/scripts/comments.rhai) | just regular [comments] |
| [`doc-comments.rhai`]({{repoHome}}/scripts/doc-comments.rhai) | [doc-comments] example |
| [`for1.rhai`]({{repoHome}}/scripts/for1.rhai) | [`for`] loops |
| [`for2.rhai`]({{repoHome}}/scripts/for2.rhai) | [`for`] loops with [array] iterations |
| [`for3.rhai`]({{repoHome}}/scripts/for3.rhai) | [`for`] loops with [closures] |
| [`function_decl1.rhai`]({{repoHome}}/scripts/function_decl1.rhai) | a [function] without parameters |
| [`function_decl2.rhai`]({{repoHome}}/scripts/function_decl2.rhai) | a [function] with two parameters |
| [`function_decl3.rhai`]({{repoHome}}/scripts/function_decl3.rhai) | a [function] with many parameters |
| [`function_decl4.rhai`]({{repoHome}}/scripts/function_decl4.rhai) | a [function] acting as a [method]({{rootUrl}}/language/fn-method.md) |
| [`function_decl5.rhai`]({{repoHome}}/scripts/function_decl5.rhai) | multiple [functions] as [methods]({{rootUrl}}/language/fn-method.md) for different data types |
| [`if1.rhai`]({{repoHome}}/scripts/if1.rhai) | [`if`] example |
| [`if2.rhai`]({{repoHome}}/scripts/if2.rhai) | [`if`]-expression example |
| [`loop.rhai`]({{repoHome}}/scripts/loop.rhai) | count-down [`loop`] in Rhai, emulating a [`do`] ... `while` loop |
| [`module.rhai`]({{repoHome}}/scripts/module.rhai) | import a script file as a module |
| [`oop.rhai`]({{repoHome}}/scripts/oop.rhai) | simulate [object-oriented programming (OOP)][OOP] with [closures] |
| [`op1.rhai`]({{repoHome}}/scripts/op1.rhai) | just simple addition |
| [`op2.rhai`]({{repoHome}}/scripts/op2.rhai) | simple addition and multiplication |
| [`op3.rhai`]({{repoHome}}/scripts/op3.rhai) | change evaluation order with parenthesis |
| [`string.rhai`]({{repoHome}}/scripts/string.rhai) | [string] operations, including _interpolation_ |
| [`strings_map.rhai`]({{repoHome}}/scripts/strings_map.rhai) | [string] and [object map] operations |
| [`switch.rhai`]({{repoHome}}/scripts/switch.rhai) | [`switch`] example |
| [`while.rhai`]({{repoHome}}/scripts/while.rhai) | [`while`] loop |
Benchmark Scripts
-----------------
The following scripts are for benchmarking the speed of Rhai:
| Scripts | Description |
| --------------------------------------------------------- | -------------------------------------------------------------------------------------- |
| [`speed_test.rhai`]({{repoHome}}/scripts/speed_test.rhai) | a simple application to measure the speed of Rhai's interpreter (1 million iterations) |
| [`primes.rhai`]({{repoHome}}/scripts/primes.rhai) | use Sieve of Eratosthenes to find all primes smaller than a limit |
| [`fibonacci.rhai`]({{repoHome}}/scripts/fibonacci.rhai) | calculate the n-th Fibonacci number using a really dumb algorithm |
| [`mat_mul.rhai`]({{repoHome}}/scripts/mat_mul.rhai) | matrix multiplication test to measure the speed of multi-dimensional array access |
Run Example Scripts
-------------------
The [`rhai-run`]({{rootUrl}}/bin.md) utility can be used to run Rhai scripts:
```sh
cargo run --bin rhai-run scripts/any_script.rhai
```

View File

@@ -1,134 +0,0 @@
Optional Features
=================
{{#include ../links.md}}
By default, Rhai includes all the standard functionalities in a small, tight package.
```admonish warning "Features are not additive"
Most Rhai features are not strictly _additive_, i.e. they do not only add optional functionalities.
In fact, most features are _subtractive_, i.e. they opt-**out** of unneeded functionalities.
Notice that this deviates from Rust norm where features are _additive_.
Excluding functionalities result in smaller, faster builds as well as more control over
what scripts can (or cannot) do.
There is a reason for this design, because the _lack_ of a language feature by itself is a feature (that's deep...).
See [here]({{rootUrl}}/patterns/multiple.md) for more details.
```
Features that Enable Special Functionalities
--------------------------------------------
| Feature | Additive? | Description |
| ------------------- | :-------: | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `std` | **no** | standard features |
| `sync` | **no** | restricts all values types to those that are `Send + Sync`; under this feature, all Rhai types, including [`Engine`], [`Scope`] and [`AST`], are all `Send + Sync` |
| `decimal` | **no** | enables the [`Decimal`][rust_decimal] number type (pulls in the [`rust_decimal`][rust_decimal] crate) |
| `unicode-xid-ident` | **no** | allows [Unicode Standard Annex #31](http://www.unicode.org/reports/tr31/) as identifiers (pulls in the [`unicode-xid`](https://crates.io/crates/unicode-xid) crate) |
| `serde` | yes | enables serialization/deserialization via `serde` (pulls in the [`serde`](https://crates.io/crates/serde) crate) |
| `metadata` | yes | enables exporting [functions metadata]; implies `serde` and additionally pulls in [`serde_json`](https://crates.io/crates/serde_json) |
| `internals` | yes | exposes internal data structures (e.g. [`AST`] nodes);<br/><br/>**Safety Warnings**<ul><li>allowing access to internal types may enable external attack vectors</li><li>internal types and functions are volatile and may change from version to version</li></ul> |
| `debugging` | yes | enables the [debugging][debugger] interface; implies `internals` |
Features that Disable Certain Language Features
-----------------------------------------------
| Feature | Additive? | Description |
| ------------------ | :-------: | --------------------------------------------------------- |
| `no_float` | **no** | disables floating-point numbers and math |
| `no_index` | **no** | disables [arrays] and indexing features |
| `no_object` | **no** | disables support for [custom types] and [object maps] |
| `no_time` | **no** | disables [timestamps] |
| `no_function` | **no** | disables script-defined [functions]; implies `no_closure` |
| `no_module` | **no** | disables loading external [modules] |
| `no_closure` | **no** | disables capturing external variables in [closures] |
| `no_custom_syntax` | **no** | disables [custom syntax] and [custom operators] |
Features that Disable Certain Engine Features
---------------------------------------------
| Feature | Additive? | Description |
| ------------- | :-------: | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `unchecked` | **no** | disables [arithmetic checking][checked] (such as over-flows and division by zero), [call stack depth limit][maximum call stack depth], [operations count limit][maximum number of operations], [modules loading limit][maximum number of modules] and [data size limit][maximum length of strings].<br/>Beware that a bad script may panic the entire system! |
| `no_optimize` | **no** | disables [script optimization] |
| `no_position` | **no** | disables position tracking during parsing |
Features that Configure the Engine
----------------------------------
| Feature | Additive? | Description |
| ----------- | :-------: | --------------------------------------------------------------------------------------------------- |
| `f32_float` | **no** | sets the system floating-point type (`FLOAT`) to `f32` instead of `f64`; no effect under `no_float` |
| `only_i32` | **no** | sets the system integer type (`INT`) to `i32` and disable all other integer types |
| `only_i64` | **no** | sets the system integer type (`INT`) to `i64` and disable all other integer types |
Features for `no-std` Builds
----------------------------
The following features are provided exclusively for [`no-std`] targets.
Do not use them when not compiling for [`no-std`].
Specify `default-features = false` when compiling for [`no-std`], which will remove the default
`std` feature.
| Feature | Additive? | Description |
| -------- | :-------: | -------------------------------------------------------------------------------------------------------------- |
| `no_std` | **no** | builds for [`no-std`]; notice that additional dependencies will be pulled in to replace missing `std` features |
Features for WebAssembly (WASM) Builds
--------------------------------------
The following features are provided exclusively for [WASM] targets.
Do not use them for non-[WASM] targets.
| Feature | Additive? | Description |
| -------------- | :-------: | ---------------------------------------------------------------------------------- |
| `wasm-bindgen` | **no** | uses [`wasm-bindgen`](https://crates.io/crates/wasm-bindgen) to compile for [WASM] |
| `stdweb` | **no** | uses [`stdweb`](https://crates.io/crates/stdweb) to compile for [WASM] |
Features for Building Bin Tools
-------------------------------
The feature `bin-features` include all the features necessary for building the [bin tools](bin.md).
By default, it includes: `decimal`, `metadata`, `serde`, `debugging` and `rustyline`.
Example
-------
The `Cargo.toml` configuration below:
```toml
[dependencies]
rhai = { version = "{{version}}", features = [ "sync", "unchecked", "only_i32", "no_float", "no_module", "no_function" ] }
```
turns on these six features:
| Feature | Description |
| :-----------: | ------------------------------------------------------------------------------------ |
| `sync` | everything is `Send + Sync` |
| `unchecked` | disable all [safety checks][safety] (should not be used with untrusted user scripts) |
| `only_i32` | use only 32-bit signed integers and no others |
| `no_float` | no floating point numbers |
| `no_module` | no loading external [modules] |
| `no_function` | no defining [functions] |
The resulting scripting engine supports only the `i32` integer numeral type (and no others like
`u32`, `i16` or `i64`), no floating-point, is `Send + Sync` (so it can be safely used across
threads), and does not support defining [functions] nor loading external [modules].
This configuration is perfect for an expression parser in a 32-bit embedded system without
floating-point hardware.

View File

@@ -1,6 +0,0 @@
Getting Started
===============
{{#include ../links.md}}
This section shows how to install the Rhai crate into a Rust application.

View File

@@ -1,40 +0,0 @@
Install the Rhai Crate
======================
{{#include ../links.md}}
In order to use Rhai in a project, the Rhai crate must first be made a dependency.
~~~admonish info "Use specific version"
The easiest way is to install the Rhai crate from [`crates.io`](https://crates.io/crates/rhai/),
starting by looking up the latest version and adding this line under `dependencies` in the project's `Cargo.toml`:
```toml
[dependencies]
rhai = "{{version}}" # assuming {{version}} is the latest version
```
~~~
~~~admonish note "Use latest release version"
Automatically use the latest released crate version on [`crates.io`](https://crates.io/crates/rhai/):
```toml
[dependencies]
rhai = "*"
```
~~~
~~~admonish tip "Use latest development version"
Crate versions are released on [`crates.io`](https://crates.io/crates/rhai/) infrequently,
so to track the latest features, enhancements and bug fixes, pull directly from
[GitHub](https://github.com/rhaiscript/rhai):
```toml
[dependencies]
rhai = { git = "https://github.com/rhaiscript/rhai" }
```
~~~

View File

@@ -1,19 +0,0 @@
Online Playground
=================
{{#include ../links.md}}
```admonish info.side "See also"
For more details, see the section [here]({{rootUrl}}/tools/playground.md).
```
Rhai provides an [online playground][playground] to try out its language and engine features without
having to install anything.
The playground provides a syntax-highlighting script editor with example snippets.
Scripts can be evaluated directly from the editor.
[![Online Playground]({{rootUrl}}/images/playground.png)][playground]