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 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.
|
* 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
|
Breaking changes
|
||||||
----------------
|
----------------
|
||||||
|
@ -82,6 +82,7 @@ The Rhai Scripting Language
|
|||||||
11. [Do Loop](language/do.md)
|
11. [Do Loop](language/do.md)
|
||||||
12. [Loop Statement](language/loop.md)
|
12. [Loop Statement](language/loop.md)
|
||||||
13. [For Loop](language/for.md)
|
13. [For Loop](language/for.md)
|
||||||
|
1. [Iterators for Custom Types](language/iterator.md)
|
||||||
14. [Return Values](language/return.md)
|
14. [Return Values](language/return.md)
|
||||||
15. [Throw Exception on Error](language/throw.md)
|
15. [Throw Exception on Error](language/throw.md)
|
||||||
16. [Catch Exceptions](language/try-catch.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
|
* **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.
|
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
|
This lack of formalism allows the _tokenizer_ and _parser_ themselves to be exposed as services in order
|
||||||
[disabling keywords/operators][disable keywords and operators], adding [custom operators],
|
to support [disabling keywords/operators][disable keywords and operators], adding [custom operators],
|
||||||
and defining [custom syntax].
|
and defining [custom syntax].
|
||||||
|
|
||||||
|
|
||||||
|
@ -4,8 +4,10 @@ Related Resources
|
|||||||
{{#include ../links.md}}
|
{{#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
|
* [`crates.io`](https://crates.io/crates/rhai) - Rhai crate
|
||||||
|
|
||||||
|
@ -34,7 +34,10 @@ number ^= 0x00ff; // number = number ^ 0x00ff;
|
|||||||
The Flexible `+=`
|
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
|
```rust
|
||||||
let my_str = "abc";
|
let my_str = "abc";
|
||||||
@ -44,7 +47,7 @@ my_str += 12345;
|
|||||||
my_str == "abcABC12345"
|
my_str == "abcABC12345"
|
||||||
```
|
```
|
||||||
|
|
||||||
It may also be used to concatenate [arrays]:
|
to concatenate [arrays]:
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
let my_array = [1, 2, 3];
|
let my_array = [1, 2, 3];
|
||||||
@ -53,7 +56,7 @@ my_array += [4, 5];
|
|||||||
my_array == [1, 2, 3, 4, 5];
|
my_array == [1, 2, 3, 4, 5];
|
||||||
```
|
```
|
||||||
|
|
||||||
or mix two [object maps] together:
|
and mix two [object maps] together:
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
let my_obj = #{a:1, b:2};
|
let my_obj = #{a:1, b:2};
|
||||||
@ -61,6 +64,3 @@ my_obj += #{c:3, d:4, e:5};
|
|||||||
|
|
||||||
my_obj.len() == 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}}
|
{{#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.
|
is provided by the `for` ... `in` loop.
|
||||||
|
|
||||||
Like C, `continue` can be used to skip to the next iteration, by-passing all following statements;
|
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
|
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.
|
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
|
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
|
Boolean operators
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
| Operator | Description |
|
| Operator | Description | Short-Circuits? |
|
||||||
| ----------------- | ------------------------------------- |
|
| :---------------: | ------------- | :-------------: |
|
||||||
| `!` | boolean _Not_ |
|
| `!` (prefix) | boolean _NOT_ | no |
|
||||||
| `&&` | boolean _And_ (short-circuits) |
|
| `&&` | boolean _AND_ | yes |
|
||||||
| <code>\|\|</code> | boolean _Or_ (short-circuits) |
|
| `&` | boolean _AND_ | no |
|
||||||
| `&` | boolean _And_ (doesn't short-circuit) |
|
| <code>\|\|</code> | boolean _OR_ | yes |
|
||||||
| <code>\|</code> | boolean _Or_ (doesn't short-circuit) |
|
| <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.
|
if the first one already proves the condition wrong.
|
||||||
|
|
||||||
Single boolean operators `&` and `|` always evaluate both operands.
|
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
|
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_.
|
Rhai allows organizing code (functions, both Rust-based or script-based, and variables) into _modules_.
|
||||||
Modules can be disabled via the [`no_module`] feature.
|
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
|
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.
|
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] |
|
| [Array]/[string] indexing out-of-bounds | error message [string] |
|
||||||
| Indexing with an inappropriate data type | error message [string] |
|
| Indexing with an inappropriate data type | error message [string] |
|
||||||
| Error in a dot expression | 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] |
|
| Error in an `in` expression | error message [string] |
|
||||||
| Data race detected | error message [string] |
|
| Data race detected | error message [string] |
|
||||||
|
|
||||||
|
@ -57,6 +57,8 @@
|
|||||||
[custom types]: {{rootUrl}}/rust/custom.md
|
[custom types]: {{rootUrl}}/rust/custom.md
|
||||||
[getters/setters]: {{rootUrl}}/rust/getters-setters.md
|
[getters/setters]: {{rootUrl}}/rust/getters-setters.md
|
||||||
[indexers]: {{rootUrl}}/rust/indexers.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
|
[`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)]`,
|
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]
|
[iteration]({{rootUrl}}/language/for.md), [getters/setters] and [indexers] for [custom types]
|
||||||
can work as expected.
|
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
|
`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.
|
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
|
```rust
|
||||||
use rhai::{Engine, Module, FnNamespace};
|
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_.
|
Rhai allows organizing code (functions, both Rust-based or script-based, and variables) into _modules_.
|
||||||
Modules can be disabled via the [`no_module`] feature.
|
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
|
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.
|
and variables defined by that script.
|
||||||
|
|
||||||
|
@ -21,7 +21,8 @@ rhai = "*"
|
|||||||
```
|
```
|
||||||
|
|
||||||
Crate versions are released on [`crates.io`](https:/crates.io/crates/rhai/) infrequently,
|
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
|
```toml
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
@ -158,13 +158,13 @@ impl Engine {
|
|||||||
self.type_names.insert(type_name::<T>().into(), name.into());
|
self.type_names.insert(type_name::<T>().into(), name.into());
|
||||||
self
|
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.
|
/// This is an advanced feature.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn register_iterator<T>(&mut self) -> &mut Self
|
pub fn register_iterator<T>(&mut self) -> &mut Self
|
||||||
where
|
where
|
||||||
T: Variant + Clone + Iterator,
|
T: Variant + Clone + IntoIterator,
|
||||||
<T as Iterator>::Item: Variant + Clone,
|
<T as IntoIterator>::Item: Variant + Clone,
|
||||||
{
|
{
|
||||||
self.global_namespace.set_iterable::<T>();
|
self.global_namespace.set_iterable::<T>();
|
||||||
self
|
self
|
||||||
|
Loading…
Reference in New Issue
Block a user