Add type iterator docs.
This commit is contained in:
parent
ecc08271d9
commit
6f2fecb76b
@ -15,6 +15,7 @@ Bug fixes
|
||||
|
||||
* Constants are no longer propagated by the optimizer if shadowed by a non-constant variable.
|
||||
* Constants passed as the `this` parameter to Rhai functions now throws an error if assigned to.
|
||||
* Generic type parameter of `Engine::register_iterator` is `IntoIterator` instead of `Iterator`.
|
||||
|
||||
Breaking changes
|
||||
----------------
|
||||
|
@ -82,6 +82,7 @@ The Rhai Scripting Language
|
||||
11. [Do Loop](language/do.md)
|
||||
12. [Loop Statement](language/loop.md)
|
||||
13. [For Loop](language/for.md)
|
||||
1. [Iterators for Custom Types](language/iterator.md)
|
||||
14. [Return Values](language/return.md)
|
||||
15. [Throw Exception on Error](language/throw.md)
|
||||
16. [Catch Exceptions](language/try-catch.md)
|
||||
|
@ -44,8 +44,8 @@ It doesn't attempt to be a new language. For example:
|
||||
* **No formal language grammar** - Rhai uses a hand-coded lexer, a hand-coded top-down recursive-descent parser
|
||||
for statements, and a hand-coded Pratt parser for expressions.
|
||||
|
||||
This lack of formalism allows the _parser_ itself to be exposed as a service in order to support
|
||||
[disabling keywords/operators][disable keywords and operators], adding [custom operators],
|
||||
This lack of formalism allows the _tokenizer_ and _parser_ themselves to be exposed as services in order
|
||||
to support [disabling keywords/operators][disable keywords and operators], adding [custom operators],
|
||||
and defining [custom syntax].
|
||||
|
||||
|
||||
|
@ -4,8 +4,10 @@ Related Resources
|
||||
{{#include ../links.md}}
|
||||
|
||||
|
||||
Other Online Resources for Rhai
|
||||
------------------------------
|
||||
Online Resources for Rhai
|
||||
-------------------------
|
||||
|
||||
* [GitHub](https://github.com/jonathandturner/rhai) - Home repository
|
||||
|
||||
* [`crates.io`](https://crates.io/crates/rhai) - Rhai crate
|
||||
|
||||
|
@ -34,7 +34,10 @@ number ^= 0x00ff; // number = number ^ 0x00ff;
|
||||
The Flexible `+=`
|
||||
----------------
|
||||
|
||||
The `+=` operator can also be used to build [strings]:
|
||||
The the `+` and `+=` operators are often [overloaded][function overloading] to perform
|
||||
build-up operations for different data types.
|
||||
|
||||
For example, it is used to build [strings]:
|
||||
|
||||
```rust
|
||||
let my_str = "abc";
|
||||
@ -44,7 +47,7 @@ my_str += 12345;
|
||||
my_str == "abcABC12345"
|
||||
```
|
||||
|
||||
It may also be used to concatenate [arrays]:
|
||||
to concatenate [arrays]:
|
||||
|
||||
```rust
|
||||
let my_array = [1, 2, 3];
|
||||
@ -53,7 +56,7 @@ my_array += [4, 5];
|
||||
my_array == [1, 2, 3, 4, 5];
|
||||
```
|
||||
|
||||
or mix two [object maps] together:
|
||||
and mix two [object maps] together:
|
||||
|
||||
```rust
|
||||
let my_obj = #{a:1, b:2};
|
||||
@ -61,6 +64,3 @@ my_obj += #{c:3, d:4, e:5};
|
||||
|
||||
my_obj.len() == 5;
|
||||
```
|
||||
|
||||
In fact, the `+` and `+=` operators are usually [overloaded][function overloading] when
|
||||
something is to be _added_ to an existing type.
|
||||
|
@ -3,7 +3,7 @@
|
||||
|
||||
{{#include ../links.md}}
|
||||
|
||||
Iterating through a range or an [array], or any type with a registered _type iterator_,
|
||||
Iterating through a range or an [array], or any type with a registered [type iterator],
|
||||
is provided by the `for` ... `in` loop.
|
||||
|
||||
Like C, `continue` can be used to skip to the next iteration, by-passing all following statements;
|
||||
|
45
doc/src/language/iterator.md
Normal file
45
doc/src/language/iterator.md
Normal file
@ -0,0 +1,45 @@
|
||||
Iterators for Custom Types
|
||||
==========================
|
||||
|
||||
{{#include ../links.md}}
|
||||
|
||||
If a [custom type] is iterable, the [`for`](for.md) loop can be used to iterate through
|
||||
its items in sequence.
|
||||
|
||||
In order to use a [`for`](for.md) statement, a _type iterator_ must be registered for
|
||||
the [custom type] in question.
|
||||
|
||||
`Engine::register_iterator<T>` allows registration of a _type iterator_ for any type
|
||||
that implements `IntoIterator`:
|
||||
|
||||
```rust
|
||||
// Custom type
|
||||
#[derive(Debug, Clone)]
|
||||
struct TestStruct { ... }
|
||||
|
||||
// Implement 'IntoIterator' trait
|
||||
impl IntoIterator<Item = ...> for TestStruct {
|
||||
type Item = ...;
|
||||
type IntoIter = SomeIterType<Self::Item>;
|
||||
|
||||
fn into_iter(self) -> Self::IntoIter {
|
||||
...
|
||||
}
|
||||
}
|
||||
|
||||
engine
|
||||
.register_type_with_name::<TestStruct>("TestStruct")
|
||||
.register_fn("new_ts", || TestStruct { ... })
|
||||
.register_iterator::<TestStruct>(); // register type iterator
|
||||
```
|
||||
|
||||
With a type iterator registered, the [custom type] can be iterated through:
|
||||
|
||||
```rust
|
||||
let ts = new_ts();
|
||||
|
||||
// Use 'for' statement to loop through items in 'ts'
|
||||
for item in ts {
|
||||
...
|
||||
}
|
||||
```
|
@ -6,6 +6,15 @@ Logic Operators
|
||||
Comparison Operators
|
||||
-------------------
|
||||
|
||||
| Operator | Description |
|
||||
| :------: | ------------------------- |
|
||||
| `==` | equals to |
|
||||
| `!=` | not equals to |
|
||||
| `>` | greater than |
|
||||
| `>=` | greater than or equals to |
|
||||
| `<` | less than |
|
||||
| `<=` | less than or equals to |
|
||||
|
||||
Comparing most values of the same data type work out-of-the-box for all [standard types] supported by the system.
|
||||
|
||||
However, if using a [raw `Engine`] without loading any [packages], comparisons can only be made between a limited
|
||||
@ -43,15 +52,15 @@ ts != 42; // true - types cannot be compared
|
||||
Boolean operators
|
||||
-----------------
|
||||
|
||||
| Operator | Description |
|
||||
| ----------------- | ------------------------------------- |
|
||||
| `!` | boolean _Not_ |
|
||||
| `&&` | boolean _And_ (short-circuits) |
|
||||
| <code>\|\|</code> | boolean _Or_ (short-circuits) |
|
||||
| `&` | boolean _And_ (doesn't short-circuit) |
|
||||
| <code>\|</code> | boolean _Or_ (doesn't short-circuit) |
|
||||
| Operator | Description | Short-Circuits? |
|
||||
| :---------------: | ------------- | :-------------: |
|
||||
| `!` (prefix) | boolean _NOT_ | no |
|
||||
| `&&` | boolean _AND_ | yes |
|
||||
| `&` | boolean _AND_ | no |
|
||||
| <code>\|\|</code> | boolean _OR_ | yes |
|
||||
| <code>\|</code> | boolean _OR_ | no |
|
||||
|
||||
Double boolean operators `&&` and `||` _short-circuit_, meaning that the second operand will not be evaluated
|
||||
Double boolean operators `&&` and `||` _short-circuit_ - meaning that the second operand will not be evaluated
|
||||
if the first one already proves the condition wrong.
|
||||
|
||||
Single boolean operators `&` and `|` always evaluate both operands.
|
||||
@ -65,3 +74,5 @@ a() | b(); // both a() and b() are evaluated
|
||||
|
||||
a() & b(); // both a() and b() are evaluated
|
||||
```
|
||||
|
||||
All boolean operators are [built in][built-in operators] for the `bool` data type.
|
||||
|
@ -6,7 +6,7 @@ Modules
|
||||
Rhai allows organizing code (functions, both Rust-based or script-based, and variables) into _modules_.
|
||||
Modules can be disabled via the [`no_module`] feature.
|
||||
|
||||
A module is of the type `Module` and holds a collection of functions, variables, type iterators and sub-modules.
|
||||
A module is of the type `Module` and holds a collection of functions, variables, [type iterators] and sub-modules.
|
||||
It may be created entirely from Rust functions, or it may encapsulate a Rhai script together with the functions
|
||||
and variables defined by that script.
|
||||
|
||||
|
@ -91,7 +91,7 @@ Many script-oriented exceptions can be caught via `try` ... `catch`:
|
||||
| [Array]/[string] indexing out-of-bounds | error message [string] |
|
||||
| Indexing with an inappropriate data type | error message [string] |
|
||||
| Error in a dot expression | error message [string] |
|
||||
| `for` statement without an type iterator | error message [string] |
|
||||
| `for` statement without a [type iterator] | error message [string] |
|
||||
| Error in an `in` expression | error message [string] |
|
||||
| Data race detected | error message [string] |
|
||||
|
||||
|
@ -57,6 +57,8 @@
|
||||
[custom types]: {{rootUrl}}/rust/custom.md
|
||||
[getters/setters]: {{rootUrl}}/rust/getters-setters.md
|
||||
[indexers]: {{rootUrl}}/rust/indexers.md
|
||||
[type iterator]: {{rootUrl}}/language/iterator.md
|
||||
[type iterators]: {{rootUrl}}/language/iterator.md
|
||||
|
||||
[`instant::Instant`]: https://crates.io/crates/instant
|
||||
|
||||
|
@ -162,7 +162,7 @@ x == 43;
|
||||
```
|
||||
|
||||
All functions (usually _methods_) defined in the module and marked with `#[rhai_fn(global)]`,
|
||||
as well as all _type iterators_, are automatically exposed to the _global_ namespace, so
|
||||
as well as all [type iterators], are automatically exposed to the _global_ namespace, so
|
||||
[iteration]({{rootUrl}}/language/for.md), [getters/setters] and [indexers] for [custom types]
|
||||
can work as expected.
|
||||
|
||||
|
@ -75,7 +75,7 @@ engine.eval::<i64>("calc::inc(41)")? == 42; // refer to the 'Calc' module
|
||||
`Module::set_fn_XXX_mut` can expose functions (usually _methods_) in the module
|
||||
to the _global_ namespace, so [getters/setters] and [indexers] for [custom types] can work as expected.
|
||||
|
||||
Type iterators, because of their special nature, are always exposed to the _global_ namespace.
|
||||
[Type iterators], because of their special nature, are always exposed to the _global_ namespace.
|
||||
|
||||
```rust
|
||||
use rhai::{Engine, Module, FnNamespace};
|
||||
|
@ -6,7 +6,7 @@ Modules
|
||||
Rhai allows organizing code (functions, both Rust-based or script-based, and variables) into _modules_.
|
||||
Modules can be disabled via the [`no_module`] feature.
|
||||
|
||||
A module is of the type `Module` and holds a collection of functions, variables, type iterators and sub-modules.
|
||||
A module is of the type `Module` and holds a collection of functions, variables, [type iterators] and sub-modules.
|
||||
It may be created entirely from Rust functions, or it may encapsulate a Rhai script together with the functions
|
||||
and variables defined by that script.
|
||||
|
||||
|
@ -21,7 +21,8 @@ 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:
|
||||
so to track the latest features, enhancements and bug fixes, pull directly from
|
||||
[GitHub](https://github.com/jonathandturner/rhai):
|
||||
|
||||
```toml
|
||||
[dependencies]
|
||||
|
@ -158,13 +158,13 @@ impl Engine {
|
||||
self.type_names.insert(type_name::<T>().into(), name.into());
|
||||
self
|
||||
}
|
||||
/// Register an iterator adapter for an iterable type with the [`Engine`].
|
||||
/// Register an type iterator for an iterable type with the [`Engine`].
|
||||
/// This is an advanced feature.
|
||||
#[inline(always)]
|
||||
pub fn register_iterator<T>(&mut self) -> &mut Self
|
||||
where
|
||||
T: Variant + Clone + Iterator,
|
||||
<T as Iterator>::Item: Variant + Clone,
|
||||
T: Variant + Clone + IntoIterator,
|
||||
<T as IntoIterator>::Item: Variant + Clone,
|
||||
{
|
||||
self.global_namespace.set_iterable::<T>();
|
||||
self
|
||||
|
Loading…
Reference in New Issue
Block a user