Add Rhai book.

This commit is contained in:
Stephen Chung
2020-06-20 12:06:17 +08:00
parent 7e80d62df5
commit c7f1e12d6a
101 changed files with 3827 additions and 0 deletions

7
doc/src/start/builds.md Normal file
View File

@@ -0,0 +1,7 @@
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

@@ -0,0 +1,40 @@
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
```
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 in as what a script requires cannot be predicted. If a language feature is not needed,
omitting them via special features is a prudent strategy to optimize the build for size.
Omitting arrays ([`no_index`]) yields the most code-size savings, followed by floating-point support
([`no_float`]), checked arithmetic/script resource limits ([`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`]) only when the feature is not needed because code size savings is minimal.
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 loading specific [packages] to minimize the footprint.
Packages are sharable (even across threads via the [`sync`] feature), so they only have to be created once.

View File

@@ -0,0 +1,9 @@
`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.

View File

@@ -0,0 +1,27 @@
Performance Build
=================
{{#include ../../links.md}}
Use Only One Integer Type
------------------------
Some features are for performance. For example, using [`only_i32`] or [`only_i64`] disables all other integer types (such as `u16`).
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, performance should improve.
Use Only 32-Bit Numbers
----------------------
If only 32-bit integers are needed - again, most of the time this is the case - using [`only_i32`] disables also `i64`.
On 64-bit targets this may not gain much, but on some 32-bit targets this improves performance due to 64-bit arithmetic
requiring more CPU cycles to complete.
Minimize Size of [`Dynamic`]
---------------------------
Turning on [`no_float`], and [`only_i32`] makes the key [`Dynamic`] data type only 8 bytes small on 32-bit targets
while normally it can be up to 16 bytes (e.g. on x86/x64 CPU's) in order to hold an `i64` or `f64`.
Making [`Dynamic`] small helps performance due to better cache efficiency.

View File

@@ -0,0 +1,18 @@
Building to WebAssembly (WASM)
=============================
{{#include ../../links.md}}
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. Why you would want to is another matter... as there is already
a nice, fast, complete scripting language for the the common WASM environment (i.e. a browser) - and it is called JavaScript.
But anyhow, do it because you _can_!
When building for WASM, certain features will not be available, such as the script file API's and loading modules
from external script files.
Also look into [minimal builds] to reduce generated WASM size. As of this version, a typical, full-featured
Rhai scripting engine compiles to a single WASM file less than 200KB gzipped. When excluding features that are
marginal in WASM environment, the gzipped payload can be further shrunk to 160KB.
In benchmark tests, a WASM build runs scripts roughly 1.7-2.2x slower than a native optimized release build.

View File

@@ -0,0 +1,7 @@
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

@@ -0,0 +1,31 @@
Rust Examples
============
{{#include ../../links.md}}
A number of examples can be found in the `examples` folder:
| Example | Description |
| ---------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------- |
| [`arrays_and_structs`](https://github.com/jonathandturner/rhai/tree/master/examples/arrays_and_structs.rs) | shows how to register a custom Rust type and using [arrays] on it |
| [`custom_types_and_methods`](https://github.com/jonathandturner/rhai/tree/master/examples/custom_types_and_methods.rs) | shows how to register a custom Rust type and methods for it |
| [`hello`](https://github.com/jonathandturner/rhai/tree/master/examples/hello.rs) | simple example that evaluates an expression and prints the result |
| [`no_std`](https://github.com/jonathandturner/rhai/tree/master/examples/no_std.rs) | example to test out `no-std` builds |
| [`reuse_scope`](https://github.com/jonathandturner/rhai/tree/master/examples/reuse_scope.rs) | evaluates two pieces of code in separate runs, but using a common [`Scope`] |
| [`rhai_runner`](https://github.com/jonathandturner/rhai/tree/master/examples/rhai_runner.rs) | runs each filename passed to it as a Rhai script |
| [`simple_fn`](https://github.com/jonathandturner/rhai/tree/master/examples/simple_fn.rs) | shows how to register a simple function |
| [`strings`](https://github.com/jonathandturner/rhai/tree/master/examples/strings.rs) | shows different ways to register functions taking string arguments |
| [`repl`](https://github.com/jonathandturner/rhai/tree/master/examples/repl.rs) | a simple REPL, interactively evaluate statements from stdin |
The `repl` example is a particularly good one as it allows one to interactively try out Rhai's
language features in a standard REPL (**R**ead-**E**val-**P**rint **L**oop).
Running Examples
----------------
Examples can be run with the following command:
```bash
cargo run --example {example_name}
```

View File

@@ -0,0 +1,51 @@
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` folder:
| Script | Description |
| -------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------- |
| [`array.rhai`](https://github.com/jonathandturner/rhai/tree/master/scripts/array.rhai) | [arrays] in Rhai |
| [`assignment.rhai`](https://github.com/jonathandturner/rhai/tree/master/scripts/assignment.rhai) | variable declarations |
| [`comments.rhai`](https://github.com/jonathandturner/rhai/tree/master/scripts/comments.rhai) | just comments |
| [`for1.rhai`](https://github.com/jonathandturner/rhai/tree/master/scripts/for1.rhai) | [`for`](#for-loop) loops |
| [`for2.rhai`](https://github.com/jonathandturner/rhai/tree/master/scripts/for2.rhai) | [`for`](#for-loop) loops on [arrays] |
| [`function_decl1.rhai`](https://github.com/jonathandturner/rhai/tree/master/scripts/function_decl1.rhai) | a [function] without parameters |
| [`function_decl2.rhai`](https://github.com/jonathandturner/rhai/tree/master/scripts/function_decl2.rhai) | a [function] with two parameters |
| [`function_decl3.rhai`](https://github.com/jonathandturner/rhai/tree/master/scripts/function_decl3.rhai) | a [function] with many parameters |
| [`if1.rhai`](https://github.com/jonathandturner/rhai/tree/master/scripts/if1.rhai) | [`if`](#if-statement) example |
| [`loop.rhai`](https://github.com/jonathandturner/rhai/tree/master/scripts/loop.rhai) | count-down [`loop`](#infinite-loop) in Rhai, emulating a `do` .. `while` loop |
| [`op1.rhai`](https://github.com/jonathandturner/rhai/tree/master/scripts/op1.rhai) | just simple addition |
| [`op2.rhai`](https://github.com/jonathandturner/rhai/tree/master/scripts/op2.rhai) | simple addition and multiplication |
| [`op3.rhai`](https://github.com/jonathandturner/rhai/tree/master/scripts/op3.rhai) | change evaluation order with parenthesis |
| [`string.rhai`](https://github.com/jonathandturner/rhai/tree/master/scripts/string.rhai) | [string] operations |
| [`strings_map.rhai`](https://github.com/jonathandturner/rhai/tree/master/scripts/strings_map.rhai) | [string] and [object map] operations |
| [`while.rhai`](https://github.com/jonathandturner/rhai/tree/master/scripts/while.rhai) | [`while`](#while-loop) loop |
Benchmark Scripts
----------------
The following scripts are for benchmarking the speed of Rhai:
| Scripts | Description |
| ------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------- |
| [`speed_test.rhai`](https://github.com/jonathandturner/rhai/tree/master/scripts/speed_test.rhai) | a simple program to measure the speed of Rhai's interpreter (1 million iterations) |
| [`primes.rhai`](https://github.com/jonathandturner/rhai/tree/master/scripts/primes.rhai) | use Sieve of Eratosthenes to find all primes smaller than a limit |
| [`fibonacci.rhai`](https://github.com/jonathandturner/rhai/tree/master/scripts/fibonacci.rhai) | calculate the n-th Fibonacci number using a really dumb algorithm |
| [`mat_mul.rhai`](https://github.com/jonathandturner/rhai/tree/master/scripts/mat_mul.rhai) | matrix multiplication test to measure the speed of multi-dimensional array access |
Running Example Scripts
----------------------
To run the scripts, either make a tiny program or use of the `rhai_runner` example:
```bash
cargo run --example rhai_runner scripts/any_script.rhai
```

48
doc/src/start/features.md Normal file
View File

@@ -0,0 +1,48 @@
Optional Features
================
{{#include ../links.md}}
By default, Rhai includes all the standard functionalities in a small, tight package.
Most features are here to opt-**out** of certain functionalities that are not needed.
Excluding unneeded functionalities can result in smaller, faster builds
as well as more control over what a script can (or cannot) do.
| Feature | Description |
| ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `unchecked` | Disable arithmetic checking (such as over-flows and division by zero), call stack depth limit, operations count limit and modules loading limit. Beware that a bad script may panic the entire system! |
| `sync` | Restrict all values types to those that are `Send + Sync`. Under this feature, all Rhai types, including [`Engine`], [`Scope`] and `AST`, are all `Send + Sync`. |
| `no_optimize` | Disable the script optimizer. |
| `no_float` | Disable floating-point numbers and math. |
| `only_i32` | Set the system integer type to `i32` and disable all other integer types. `INT` is set to `i32`. |
| `only_i64` | Set the system integer type to `i64` and disable all other integer types. `INT` is set to `i64`. |
| `no_index` | Disable [arrays] and indexing features. |
| `no_object` | Disable support for custom types and [object maps]. |
| `no_function` | Disable script-defined functions. |
| `no_module` | Disable loading external modules. |
| `no_std` | Build for `no-std`. Notice that additional dependencies will be pulled in to replace `std` features. |
Example
-------
The `Cargo.toml` configuration below turns on these six features:
* `sync` (everything `Send + Sync`)
* `unchecked` (no checked arithmetic - should not be used with untrusted user scripts)
* `only_i32` (only 32-bit signed integers)
* `no_float` (no floating point numbers)
* `no_module` (no loading external modules)
* `no_function` (no defining functions)
```toml
[dependencies]
rhai = { version = "0.15.2", features = [ "sync", "unchecked", "only_i32", "no_float", "no_module", "no_function" ] }
```
The resulting scripting engine supports only the `i32` integer numeral type (and no others like `u32` or `i16`),
no floating-point, is `Send + Sync` (so it can be safely used across threads), 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.

27
doc/src/start/install.md Normal file
View File

@@ -0,0 +1,27 @@
Install the Rhai Crate
=====================
{{#include ../links.md}}
Install the Rhai crate from [`crates.io`](https:/crates.io/crates/rhai/) by adding this line
under `dependencies` in `Cargo.toml`:
```toml
[dependencies]
rhai = "0.15.2"
```
Use the latest released crate version on [`crates.io`](https:/crates.io/crates/rhai/):
```toml
[dependencies]
rhai = "*"
```
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:
```toml
[dependencies]
rhai = { git = "https://github.com/jonathandturner/rhai" }
```