diff --git a/doc/README.md b/doc/README.md
deleted file mode 100644
index bc521a4f..00000000
--- a/doc/README.md
+++ /dev/null
@@ -1,41 +0,0 @@
-The Rhai Book
-=============
-
-[_The Rhai Book_](https://rhaiscript.github.io/book) serves as Rhai's primary
-documentation and tutorial resource.
-
-
-How to Build from Source
-------------------------
-
-* Install [`mdbook`](https://github.com/rust-lang/mdBook):
-
-```bash
-cargo install mdbook
-```
-
-* Install [`mdbook-tera`](https://github.com/avitex/mdbook-tera) (for templating):
-
-```bash
-cargo install mdbook-tera
-```
-
-* Run build in source directory:
-
-```bash
-cd doc
-mdbook build
-```
-
-
-Configuration Settings
-----------------------
-
-Settings stored in `context.json`:
-
-| Setting | Description |
-| ---------- | -------------------------------------------------------------------------------------------- |
-| `version` | version of Rhai |
-| `repoHome` | points to the [root of the GitHub repo](https://github.com/rhaiscript/rhai/blob/master) |
-| `repoTree` | points to the [root of the GitHub repo tree](https://github.com/rhaiscript/rhai/tree/master) |
-| `rootUrl` | sub-directory for the root domain, e.g. `/rhai` |
diff --git a/doc/book.toml b/doc/book.toml
deleted file mode 100644
index d72fe611..00000000
--- a/doc/book.toml
+++ /dev/null
@@ -1,22 +0,0 @@
-[book]
-title = "Rhai - Embedded Scripting for Rust"
-authors = ["Jonathan Turner", "Stephen Chung"]
-description = "Tutorial and reference on the Rhai scripting engine and language."
-language = "en"
-
-[output.html]
-no-section-label = true
-git-repository-url = "https://github.com/rhaiscript/rhai"
-curly-quotes = true
-
-[output.html.fold]
-enable = true
-level = 4
-
-[outputX.linkcheck]
-follow-web-links = false
-traverse-parent-directories = false
-warning-policy = "ignore"
-
-[preprocessor.tera]
-command = "mdbook-tera --json ./src/context.json"
diff --git a/doc/src/SUMMARY.md b/doc/src/SUMMARY.md
deleted file mode 100644
index 0f16501f..00000000
--- a/doc/src/SUMMARY.md
+++ /dev/null
@@ -1,149 +0,0 @@
-The Rhai Scripting Language
-==========================
-
-1. [What is Rhai](about/index.md)
- 1. [Features](about/features.md)
- 2. [Supported Targets and Builds](about/targets.md)
- 3. [What Rhai Isn't](about/non-design.md)
- 4. [Licensing](about/license.md)
- 5. [Related Resources](about/related.md)
-2. [Getting Started](start/index.md)
- 1. [Online Playground](start/playground.md)
- 2. [Install the Rhai Crate](start/install.md)
- 3. [Optional Features](start/features.md)
- 4. [Special Builds](start/builds/index.md)
- 1. [Performance](start/builds/performance.md)
- 2. [Minimal](start/builds/minimal.md)
- 3. [no-std](start/builds/no-std.md)
- 4. [WebAssembly (WASM)](start/builds/wasm.md)
- 5. [Packaged Utilities](start/bin.md)
- 6. [Examples](start/examples/index.md)
- 1. [Rust](start/examples/rust.md)
- 2. [Scripts](start/examples/scripts.md)
-3. [Using the `Engine`](engine/index.md)
- 1. [Hello World in Rhai – Evaluate a Script](engine/hello-world.md)
- 2. [Compile to AST for Repeated Evaluations](engine/compile.md)
- 3. [Call a Rhai Function from Rust](engine/call-fn.md)
- 4. [Create a Rust Closure from a Rhai Function](engine/func.md)
- 5. [Evaluate Expressions Only](engine/expressions.md)
- 6. [Raw Engine](engine/raw.md)
- 7. [Scope – Initializing and Maintaining State](engine/scope.md)
- 8. [Engine Configuration Options](engine/options.md)
-4. [Extend Rhai with Rust](rust/index.md)
- 1. [Traits](rust/traits.md)
- 2. [Register a Rust Function](rust/functions.md)
- 1. [String Parameters in Rust Functions](rust/strings.md)
- 3. [Register a Generic Rust Function](rust/generic.md)
- 4. [Register a Fallible Rust Function](rust/fallible.md)
- 5. [Override a Built-in Function](rust/override.md)
- 6. [Operator Overloading](rust/operators.md)
- 7. [Register any Rust Type and its Methods](rust/custom.md)
- 1. [Property Getters and Setters](rust/getters-setters.md)
- 2. [Indexers](rust/indexers.md)
- 3. [Disable Custom Types](rust/disable-custom.md)
- 4. [Printing Custom Types](rust/print-custom.md)
- 8. [Modules](rust/modules/index.md)
- 1. [Create from Rust](rust/modules/create.md)
- 2. [Create from AST](rust/modules/ast.md)
- 3. [Module Resolvers](rust/modules/resolvers.md)
- 1. [Custom Module Resolvers](rust/modules/imp-resolver.md)
- 9. [Plugins](plugins/index.md)
- 1. [Export a Rust Module](plugins/module.md)
- 2. [Export a Rust Function](plugins/function.md)
- 10. [Packages](rust/packages/index.md)
- 1. [Built-in Packages](rust/packages/builtin.md)
- 2. [Custom Packages](rust/packages/create.md)
-5. [Rhai Language Reference](language/index.md)
- 1. [Comments](language/comments.md)
- 1. [Doc-Comments](language/doc-comments.md)
- 2. [Values and Types](language/values-and-types.md)
- 1. [Dynamic Values](language/dynamic.md)
- 2. [Serialization/Deserialization with `serde`](rust/serde.md)
- 3. [type_of()](language/type-of.md)
- 4. [Numbers](language/numbers.md)
- 1. [Operators](language/num-op.md)
- 2. [Functions](language/num-fn.md)
- 3. [Value Conversions](language/convert.md)
- 5. [Strings and Characters](language/strings-chars.md)
- 1. [Built-in Functions](language/string-fn.md)
- 6. [Arrays](language/arrays.md)
- 7. [Object Maps](language/object-maps.md)
- 1. [Parse from JSON](language/json.md)
- 2. [Special Support for OOP](language/object-maps-oop.md)
- 8. [Time-Stamps](language/timestamps.md)
- 3. [Keywords](language/keywords.md)
- 4. [Statements](language/statements.md)
- 5. [Variables](language/variables.md)
- 6. [Constants](language/constants.md)
- 7. [Logic Operators](language/logic.md)
- 8. [Assignment Operators](language/assignment-op.md)
- 9. [If Statement](language/if.md)
- 10. [Switch Expression](language/switch.md)
- 11. [While Loop](language/while.md)
- 12. [Do Loop](language/do.md)
- 13. [Loop Statement](language/loop.md)
- 14. [For Loop](language/for.md)
- 1. [Iterators for Custom Types](language/iterator.md)
- 15. [Return Values](language/return.md)
- 16. [Throw Exception on Error](language/throw.md)
- 17. [Catch Exceptions](language/try-catch.md)
- 18. [Functions](language/functions.md)
- 1. [Call Method as Function](language/method.md)
- 2. [Overloading](language/overload.md)
- 3. [Namespaces](language/fn-namespaces.md)
- 4. [Function Pointers](language/fn-ptr.md)
- 5. [Currying](language/fn-curry.md)
- 6. [Anonymous Functions](language/fn-anon.md)
- 7. [Closures](language/fn-closure.md)
- 19. [Print and Debug](language/print-debug.md)
- 20. [Modules](language/modules/index.md)
- 1. [Export Variables, Functions and Sub-Modules](language/modules/export.md)
- 2. [Import Modules](language/modules/import.md)
- 21. [Eval Function](language/eval.md)
-6. [Safety and Protection](safety/index.md)
- 1. [Checked Arithmetic](safety/checked.md)
- 2. [Sand-Boxing](safety/sandbox.md)
- 3. [Maximum Length of Strings](safety/max-string-size.md)
- 4. [Maximum Size of Arrays](safety/max-array-size.md)
- 5. [Maximum Size of Object Maps](safety/max-map-size.md)
- 6. [Maximum Number of Operations](safety/max-operations.md)
- 1. [Tracking Progress and Force-Termination](safety/progress.md)
- 7. [Maximum Number of Modules](safety/max-modules.md)
- 8. [Maximum Call Stack Depth](safety/max-call-stack.md)
- 9. [Maximum Statement Depth](safety/max-stmt-depth.md)
-7. [Script Optimization](engine/optimize/index.md)
- 1. [Optimization Levels](engine/optimize/optimize-levels.md)
- 2. [Re-Optimize an AST](engine/optimize/reoptimize.md)
- 3. [Eager Function Evaluation](engine/optimize/eager.md)
- 4. [Side-Effect Considerations](engine/optimize/side-effects.md)
- 5. [Volatility Considerations](engine/optimize/volatility.md)
- 6. [Subtle Semantic Changes](engine/optimize/semantics.md)
-8. [Usage Patterns](patterns/index.md)
- 1. [Object-Oriented Programming (OOP)](patterns/oop.md)
- 2. [Working With Rust Enums](patterns/enums.md)
- 3. [Loadable Configuration](patterns/config.md)
- 4. [Control Layer](patterns/control.md)
- 5. [Singleton Command](patterns/singleton.md)
- 6. [Multi-Layer Functions](patterns/multi-layer.md)
- 7. [One Engine Instance Per Call](patterns/parallel.md)
- 8. [Scriptable Event Handler with State](patterns/events.md)
- 9. [Dynamic Constants Provider](patterns/dynamic-const.md)
-9. [Advanced Topics](advanced.md)
- 1. [Capture Scope for Function Call](language/fn-capture.md)
- 2. [Low-Level API](rust/register-raw.md)
- 3. [Variable Resolver](engine/var.md)
- 4. [Use as DSL](engine/dsl.md)
- 1. [Disable Keywords and/or Operators](engine/disable.md)
- 2. [Custom Operators](engine/custom-op.md)
- 3. [Extending with Custom Syntax](engine/custom-syntax.md)
- 5. [Multiple Instantiation](patterns/multiple.md)
- 6. [Functions Metadata](engine/metadata/index.md)
- 1. [Generate Function Signatures](engine/metadata/gen_fn_sig.md)
- 2. [Export Metadata to JSON](engine/metadata/export_to_json.md)
-10. [External Tools](tools/index.md)
- 1. [Online Playground](tools/playground.md)
- 2. [`rhai-doc`](tools/rhai-doc.md)
-11. [Appendix](appendix/index.md)
- 1. [Keywords](appendix/keywords.md)
- 2. [Operators and Symbols](appendix/operators.md)
- 3. [Literals](appendix/literals.md)
diff --git a/doc/src/about/features.md b/doc/src/about/features.md
deleted file mode 100644
index 597f6677..00000000
--- a/doc/src/about/features.md
+++ /dev/null
@@ -1,79 +0,0 @@
-Features
-========
-
-{{#include ../links.md}}
-
-Easy
-----
-
-* Easy-to-use language similar to JavaScript+Rust with dynamic typing.
-
-* Tight integration with native Rust [functions] and [types][custom types] including [getters/setters],
- [methods][custom type] and [indexers].
-
-* Freely pass Rust variables/constants into a script via an external [`Scope`] – all clonable Rust types are supported seamlessly
- without the need to implement any special trait.
-
-* Easily [call a script-defined function]({{rootUrl}}/engine/call-fn.md) from Rust.
-
-* Very few additional dependencies – right now only [`smallvec`](https://crates.io/crates/smallvec/) plus crates for procedural macros;
- for [`no-std`] and `WASM` builds, a number of additional dependencies are pulled in to provide for missing functionalities.
-
-* [Plugins] system powered by procedural macros simplifies custom API development.
-
-Fast
-----
-
-* Fairly low compile-time overhead.
-
-* Fairly efficient evaluation (1 million iterations in 0.3 sec on a single core, 2.3 GHz Linux VM).
-
-* Scripts are [optimized][script optimization] (useful for template-based machine-generated scripts) for repeated evaluations.
-
-Dynamic
--------
-
-* [Function overloading]({{rootUrl}}/language/overload.md).
-
-* [Operator overloading]({{rootUrl}}/rust/operators.md).
-
-* Organize code base with dynamically-loadable [modules].
-
-* Dynamic dispatch via [function pointers] with additional support for [currying].
-
-* [Closures] that can capture shared variables.
-
-* Some support for [object-oriented programming (OOP)][OOP].
-
-* Hook into variables access via [variable resolver].
-
-Safe
-----
-
-* Relatively little `unsafe` code (yes there are some for performance reasons).
-
-* Sand-boxed – the scripting [`Engine`], if declared immutable, cannot mutate the containing environment unless
- [explicitly permitted]({{rootUrl}}/patterns/control.md).
-
-Rugged
-------
-
-* Protected against malicious attacks (such as [stack-overflow][maximum call stack depth], [over-sized data][maximum length of strings],
- and [runaway scripts][maximum number of operations] etc.) that may come from untrusted third-party user-land scripts.
-
-* Track script evaluation [progress] and manually terminate a script run.
-
-Flexible
---------
-
-* Re-entrant scripting [`Engine`] can be made `Send + Sync` (via the [`sync`] feature).
-
-* Serialization/deserialization support via [`serde`](https://crates.io/crates/serde).
-
-* Support for [minimal builds] by excluding unneeded language [features].
-
-* Supports [most build targets](targets.md) including `no-std` and [WASM].
-
-* Surgically [disable keywords and operators] to restrict the language.
-
-* Use as a [DSL] by defining [custom operators] and/or extending the language with [custom syntax].
diff --git a/doc/src/about/index.md b/doc/src/about/index.md
deleted file mode 100644
index f316698d..00000000
--- a/doc/src/about/index.md
+++ /dev/null
@@ -1,46 +0,0 @@
-What is Rhai
-============
-
-{{#include ../links.md}}
-
-![Rhai Logo]({{rootUrl}}/images/logo/rhai-banner-transparent-colour.svg)
-
-Rhai is an embedded scripting language and evaluation engine for Rust that gives a safe and easy way
-to add scripting to any application.
-
-
-Versions
---------
-
-This Book is for version **{{version}}** of Rhai.
-
-{% if rootUrl != "" and not rootUrl is ending_with("vnext") %}
-For the latest development version, see [here]({{rootUrl}}/vnext/).
-{% endif %}
-
-
-Etymology of the name "Rhai"
----------------------------
-
-### As per Rhai's author Johnathan Turner
-
-In the beginning there was [ChaiScript](http://chaiscript.com),
-which is an embedded scripting language for C++.
-Originally it was intended to be a scripting language similar to **JavaScript**.
-
-With java being a kind of hot beverage, the new language was named after
-another hot beverage – **Chai**, which is the word for "tea" in many world languages
-and, in particular, a popular kind of milk tea consumed in India.
-
-Later, when the novel implementation technique behind ChaiScript was ported from C++ to Rust,
-logically the `C` was changed to an `R` to make it "RhaiScript", or just "Rhai".
-
-### On the origin of the semi-official Rhai logo
-
-One of Rhai's maintainers, [Stephen Chung](https://github.com/schungx), was thinking about a logo when he accidentally
-came across a copy of _Catcher in the Rye_ in a restaurant, and drew the first version
-of the logo.
-
-Then [`@semirix`](https://github.com/semirix) refined it to the current version.
-
-The plan is to make the logo official together with a `1.0` release.
diff --git a/doc/src/about/license.md b/doc/src/about/license.md
deleted file mode 100644
index 8465ec4c..00000000
--- a/doc/src/about/license.md
+++ /dev/null
@@ -1,14 +0,0 @@
-Licensing
-=========
-
-{{#include ../links.md}}
-
-Rhai is licensed under either of the following, at your choice:
-
-* [Apache License, Version 2.0]({{repoHome}}/LICENSE-APACHE.txt), or
-
-* [MIT license]({{repoHome}}/LICENSE-MIT.txt).
-
-Unless explicitly stated otherwise, any contribution intentionally submitted for inclusion in this crate,
-as defined in the Apache-2.0 license, shall be dual-licensed as above,
-without any additional terms or conditions.
diff --git a/doc/src/about/non-design.md b/doc/src/about/non-design.md
deleted file mode 100644
index aa39f465..00000000
--- a/doc/src/about/non-design.md
+++ /dev/null
@@ -1,77 +0,0 @@
-What Rhai Isn't
-===============
-
-{{#include ../links.md}}
-
-Rhai's purpose is to provide a dynamic layer over Rust code, in the same spirit of _zero cost abstractions_.
-It doesn't attempt to be a new language. For example:
-
-* **No classes**. Well, Rust doesn't either. On the other hand...
-
-* **No traits**... so it is also not Rust. Do your Rusty stuff in Rust.
-
-* **No structures/records/tuples** – define your types in Rust instead; Rhai can seamlessly work with _any Rust type_.
-
- There is, however, a built-in [object map] type which is adequate for most uses.
- It is possible to simulate [object-oriented programming (OOP)][OOP] by storing [function pointers]
- or [closures] in [object map] properties, turning them into _methods_.
-
-* **No first-class functions** – Code your functions in Rust instead, and register them with Rhai.
-
- There is, however, support for simple [function pointers] to allow runtime dispatch by function name.
-
-* **No garbage collection** – this should be expected, so...
-
-* **No first-class closures** – do your closure magic in Rust instead: [turn a Rhai scripted function into a Rust closure]({{rootUrl}}/engine/call-fn.md).
-
- There is, however, support for simulated [closures] via [currying] a [function pointer] with
- captured shared variables.
-
-* **No byte-codes/JIT** – Rhai has an optimized AST-walking interpreter which is fast enough for most casual
- usage scenarios. Essential AST data structures are packed and kept together to maximize cache friendliness.
-
- Functions are dispatched based on pre-calculated hashes and accessing variables are mostly through pre-calculated
- offsets to the variables file (a [`Scope`]), so it is seldom necessary to look something up by text name.
-
- In addition, Rhai's design deliberately avoids maintaining a _scope chain_ so function scopes do not
- pay any speed penalty. This particular design also allows variables data to be kept together in a contiguous
- block, avoiding allocations and fragmentation while being cache-friendly. In a typical script evaluation run,
- no data is shared and nothing is locked.
-
- Still, the purpose of Rhai is not to be super _fast_, but to make it as easy and versatile as possible to
- integrate with native Rust applications.
-
-* **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 _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].
-
-
-Do Not Write The Next 4D VR Game in Rhai
----------------------------------------
-
-Due to this intended usage, Rhai deliberately keeps the language simple and small by omitting
-advanced language features such as classes, inheritance, interfaces, generics,
-first-class functions/closures, pattern matching, concurrency, byte-codes VM, JIT etc.
-Focus is on _flexibility_ and _ease of use_ instead of raw speed.
-
-Avoid the temptation to write full-fledge application logic entirely in Rhai -
-that use case is best fulfilled by more complete languages such as JavaScript or Lua.
-
-
-Thin Dynamic Wrapper Layer Over Rust Code
-----------------------------------------
-
-In actual practice, it is usually best to expose a Rust API into Rhai for scripts to call.
-
-All the core functionalities should be written in Rust, with Rhai being the dynamic _control_ layer.
-
-This is similar to some dynamic languages where most of the core functionalities reside in a C/C++
-standard library.
-
-Another similar scenario is a web front-end driving back-end services written in a systems language.
-In this case, JavaScript takes the role of Rhai while the back-end language, well... it can actually also be Rust.
-Except that Rhai integrates with Rust _much_ more tightly, removing the need for interfaces such
-as XHR calls and payload encoding such as JSON.
diff --git a/doc/src/about/related.md b/doc/src/about/related.md
deleted file mode 100644
index cc6e2503..00000000
--- a/doc/src/about/related.md
+++ /dev/null
@@ -1,36 +0,0 @@
-Related Resources
-=================
-
-{{#include ../links.md}}
-
-
-Online Resources for Rhai
--------------------------
-
-* [GitHub](https://github.com/rhaiscript/rhai) – Home repository
-
-* [`crates.io`](https://crates.io/crates/rhai) – Rhai crate
-
-* [`DOCS.RS`](https://docs.rs/rhai) – Rhai API documentation
-
-* [`LIB.RS`](https://lib.rs/crates/rhai) – Rhai library info
-
-* [Discord Chat](https://discord.gg/HquqbYFcZ9) – Rhai channel
-
-* [Reddit](https://www.reddit.com/r/Rhai) – Rhai community
-
-
-External Tools
---------------
-
-* [Online Playground][playground] – Run Rhai scripts directly from an editor in the browser
-
-* [`rhai-doc`] – Rhai script documentation tool
-
-
-Other Cool Projects
--------------------
-
-* [ChaiScript](http://chaiscript.com) – A strong inspiration for Rhai. An embedded scripting language for C++.
-
-* Check out the list of [scripting languages for Rust](https://github.com/rust-unofficial/awesome-rust#scripting) on [awesome-rust](https://github.com/rust-unofficial/awesome-rust)
diff --git a/doc/src/about/targets.md b/doc/src/about/targets.md
deleted file mode 100644
index a68430a0..00000000
--- a/doc/src/about/targets.md
+++ /dev/null
@@ -1,18 +0,0 @@
-Supported Targets and Builds
-===========================
-
-{{#include ../links.md}}
-
-The following targets and builds are support by Rhai:
-
-* All common CPU targets for Windows, Linux and MacOS.
-
-* WebAssembly ([WASM])
-
-* [`no-std`]
-
-
-Minimum Rust Version
---------------------
-
-The minimum version of Rust required to compile Rhai is `1.45.0`.
diff --git a/doc/src/advanced.md b/doc/src/advanced.md
deleted file mode 100644
index 87136de0..00000000
--- a/doc/src/advanced.md
+++ /dev/null
@@ -1,6 +0,0 @@
-Advanced Topics
-===============
-
-{{#include links.md}}
-
-This section covers advanced features of the Rhai [`Engine`].
diff --git a/doc/src/appendix/index.md b/doc/src/appendix/index.md
deleted file mode 100644
index bdb6cae9..00000000
--- a/doc/src/appendix/index.md
+++ /dev/null
@@ -1,6 +0,0 @@
-Appendix
-========
-
-{{#include ../links.md}}
-
-This section contains miscellaneous reference materials.
diff --git a/doc/src/appendix/keywords.md b/doc/src/appendix/keywords.md
deleted file mode 100644
index 2866cb5d..00000000
--- a/doc/src/appendix/keywords.md
+++ /dev/null
@@ -1,75 +0,0 @@
-Keywords List
-=============
-
-{{#include ../links.md}}
-
-| Keyword | Description | Inactive under | Is function? | Overloadable |
-| :-------------------: | ------------------------------------------- | :-------------: | :----------: | :----------: |
-| `true` | boolean true literal | | no | |
-| `false` | boolean false literal | | no | |
-| `let` | variable declaration | | no | |
-| `const` | constant declaration | | no | |
-| `if` | if statement | | no | |
-| `else` | else block of if statement | | no | |
-| `switch` | matching | | no | |
-| `do` | looping | | no | |
-| `while` | 1) while loop 2) condition for do loop | | no | |
-| `until` | do loop | | no | |
-| `loop` | infinite loop | | no | |
-| `for` | for loop | | no | |
-| `in` | 1) containment test 2) part of for loop | | no | |
-| `continue` | continue a loop at the next iteration | | no | |
-| `break` | break out of loop iteration | | no | |
-| `return` | return value | | no | |
-| `throw` | throw exception | | no | |
-| `try` | trap exception | | no | |
-| `catch` | catch exception | | no | |
-| `import` | import module | [`no_module`] | no | |
-| `export` | export variable | [`no_module`] | no | |
-| `as` | alias for variable export | [`no_module`] | no | |
-| `private` | mark function private | [`no_function`] | no | |
-| `fn` (lower-case `f`) | function definition | [`no_function`] | no | |
-| `Fn` (capital `F`) | create a [function pointer] | | yes | yes |
-| `call` | call a [function pointer] | | yes | no |
-| `curry` | curry a [function pointer] | | yes | no |
-| `this` | reference to base object for method call | [`no_function`] | no | |
-| `type_of` | get type name of value | | yes | yes |
-| `print` | print value | | yes | yes |
-| `debug` | print value in debug format | | yes | yes |
-| `eval` | evaluate script | | yes | yes |
-
-
-Reserved Keywords
------------------
-
-| Keyword | Potential usage |
-| --------- | --------------------- |
-| `var` | variable declaration |
-| `static` | variable declaration |
-| `begin` | block scope |
-| `end` | block scope |
-| `shared` | share value |
-| `each` | looping |
-| `then` | control flow |
-| `goto` | control flow |
-| `exit` | control flow |
-| `unless` | control flow |
-| `match` | matching |
-| `case` | matching |
-| `public` | function/field access |
-| `new` | constructor |
-| `use` | import namespace |
-| `with` | scope |
-| `module` | module |
-| `package` | package |
-| `thread` | threading |
-| `spawn` | threading |
-| `go` | threading |
-| `await` | async |
-| `async` | async |
-| `sync` | async |
-| `yield` | async |
-| `default` | special value |
-| `void` | special value |
-| `null` | special value |
-| `nil` | special value |
diff --git a/doc/src/appendix/literals.md b/doc/src/appendix/literals.md
deleted file mode 100644
index 3e5a5fdf..00000000
--- a/doc/src/appendix/literals.md
+++ /dev/null
@@ -1,16 +0,0 @@
-Literals Syntax
-===============
-
-{{#include ../links.md}}
-
-| Type | Literal syntax |
-| :--------------------------------: | :-----------------------------------------------------------------------------------------: |
-| `INT` | decimal: `42`, `-123`, `0` hex: `0x????..` binary: `0b????..` octal: `0o????..` |
-| `FLOAT` | `42.0`, `-123.456`, `0.0` |
-| [String] | `"... \x?? \u???? \U???????? ..."` |
-| [Character][string] | single: `'?'` ASCII hex: `'\x??'` Unicode: `'\u????'`, `'\U????????'` |
-| [`Array`] | `[ ???, ???, ??? ]` |
-| [Object map] | `#{ a: ???, b: ???, c: ???, "def": ??? }` |
-| Boolean true | `true` |
-| Boolean false | `false` |
-| `Nothing`/`null`/`nil`/`void`/Unit | `()` |
diff --git a/doc/src/appendix/operators.md b/doc/src/appendix/operators.md
deleted file mode 100644
index 71e94965..00000000
--- a/doc/src/appendix/operators.md
+++ /dev/null
@@ -1,74 +0,0 @@
-Operators and Symbols
-====================
-
-{{#include ../links.md}}
-
-
-Operators
----------
-
-| Operator | Description | Binary? | Binding direction |
-| :-----------------------------------------------------------------------------------------: | -------------------------------------- | :--------: | :---------------: |
-| `+` | add | yes | left |
-| `-` | 1) subtract 2) negative (prefix) | yes no | left right |
-| `*` | multiply | yes | left |
-| `/` | divide | yes | left |
-| `%` | modulo | yes | left |
-| `~` | power | yes | left |
-| `>>` | right bit-shift | yes | left |
-| `<<` | left bit-shift | yes | left |
-| `&` | 1) bit-wise _AND_ 2) boolean _AND_ | yes | left |
-| \|
| 1) bit-wise _OR_ 2) boolean _OR_ | yes | left |
-| `^` | 1) bit-wise _XOR_ 2) boolean _XOR_ | yes | left |
-| `=`, `+=`, `-=`, `*=`, `/=`, `~=`, `%=`, `<<=`, `>>=`, `&=`,\|=
, `^=` | assignments | yes | right |
-| `==` | equals to | yes | left |
-| `~=` | not equals to | yes | left |
-| `>` | greater than | yes | left |
-| `>=` | greater than or equals to | yes | left |
-| `<` | less than | yes | left |
-| `<=` | less than or equals to | yes | left |
-| `&&` | boolean _AND_ (short-circuits) | yes | left |
-| \|\|
| boolean _OR_ (short-circuits) | yes | left |
-| `!` | boolean _NOT_ | no | left |
-| `[` .. `]` | indexing | yes | right |
-| `.` | 1) property access 2) method call | yes | right |
-
-
-Symbols and Patterns
---------------------
-
-| Symbol | Name | Description |
-| ---------------------------------- | :------------------: | ------------------------------------- |
-| `_` | underscore | default `switch` case |
-| `;` | semicolon | statement separator |
-| `,` | comma | list separator |
-| `:` | colon | [object map] property value separator |
-| `::` | path | module path separator |
-| `#{` .. `}` | hash map | [object map] literal |
-| `"` .. `"` | double quote | [string] |
-| `'` .. `'` | single quote | [character][string] |
-| `\` | escape | escape character literal |
-| `(` .. `)` | parentheses | expression grouping |
-| `{` .. `}` | braces | block statement |
-| \|
.. \|
| pipes | closure |
-| `[` .. `]` | brackets | [array] literal |
-| `!` | bang | function call in calling scope |
-| `=>` | double arrow | `switch` expression case separator |
-| `//` | comment | line comment |
-| `/*` .. `*/` | comment | block comment |
-| `(*` .. `*)` | comment | _reserved_ |
-| `<` .. `>` | angular brackets | _reserved_ |
-| `++` | increment | _reserved_ |
-| `--` | decrement | _reserved_ |
-| `..` | range | _reserved_ |
-| `...` | range | _reserved_ |
-| `**` | exponentiation | _reserved_ |
-| `#` | hash | _reserved_ |
-| `@` | at | _reserved_ |
-| `$` | dollar | _reserved_ |
-| `->` | arrow | _reserved_ |
-| `<-` | left arrow | _reserved_ |
-| `===` | strict equals to | _reserved_ |
-| `!==` | strict not equals to | _reserved_ |
-| `:=` | assignment | _reserved_ |
-| `::<` .. `>` | turbofish | _reserved_ |
diff --git a/doc/src/context.json b/doc/src/context.json
deleted file mode 100644
index e3ba5b9b..00000000
--- a/doc/src/context.json
+++ /dev/null
@@ -1,8 +0,0 @@
-{
- "version": "0.19.10",
- "repoHome": "https://github.com/rhaiscript/rhai/blob/master",
- "repoTree": "https://github.com/rhaiscript/rhai/tree/master",
- "rootUrl": "",
- "rootUrlX": "/rhai",
- "rootUrlXX": "/rhai/vnext"
-}
\ No newline at end of file
diff --git a/doc/src/engine/call-fn.md b/doc/src/engine/call-fn.md
deleted file mode 100644
index 548b058a..00000000
--- a/doc/src/engine/call-fn.md
+++ /dev/null
@@ -1,95 +0,0 @@
-Calling Rhai Functions from Rust
-===============================
-
-{{#include ../links.md}}
-
-Rhai also allows working _backwards_ from the other direction – i.e. calling a Rhai-scripted function
-from Rust via `Engine::call_fn`.
-
-Functions declared with `private` are hidden and cannot be called from Rust (see also [modules]).
-
-```rust
-// Define functions in a script.
-let ast = engine.compile(true,
- r#"
- // a function with two parameters: string and i64
- fn hello(x, y) {
- x.len + y
- }
-
- // functions can be overloaded: this one takes only one parameter
- fn hello(x) {
- x * 2
- }
-
- // this one takes no parameters
- fn hello() {
- 42
- }
-
- // this one is private and cannot be called by 'call_fn'
- private hidden() {
- throw "you shouldn't see me!";
- }
- "#)?;
-
-// A custom scope can also contain any variables/constants available to the functions
-let mut scope = Scope::new();
-
-// Evaluate a function defined in the script, passing arguments into the script as a tuple.
-// Beware, arguments must be of the correct types because Rhai does not have built-in type conversions.
-// If arguments of the wrong types are passed, the Engine will not find the function.
-
-let result: i64 = engine.call_fn(&mut scope, &ast, "hello", ( String::from("abc"), 123_i64 ) )?;
-// ^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-// return type must be specified put arguments in a tuple
-
-let result: i64 = engine.call_fn(&mut scope, &ast, "hello", (123_i64,) )?;
-// ^^^^^^^^^^ tuple of one
-
-let result: i64 = engine.call_fn(&mut scope, &ast, "hello", () )?;
-// ^^ unit = tuple of zero
-
-// The following call will return a function-not-found error because
-// 'hidden' is declared with 'private'.
-let result: () = engine.call_fn(&mut scope, &ast, "hidden", ())?;
-```
-
-
-Low-Level API – `Engine::call_fn_dynamic`
-----------------------------------------------
-
-For more control, construct all arguments as `Dynamic` values and use `Engine::call_fn_dynamic`, passing it
-anything that implements `AsMut` (such as a simple array or a `Vec`):
-
-```rust
-let result = engine.call_fn_dynamic(
- &mut scope, // scope to use
- &ast, // AST containing the functions
- "hello", // function entry-point
- None, // 'this' pointer, if any
- [ String::from("abc").into(), 123_i64.into() ] // arguments
- )?;
-```
-
-
-Binding the `this` Pointer
--------------------------
-
-`Engine::call_fn_dynamic` can also bind a value to the `this` pointer of a script-defined function.
-
-```rust
-let ast = engine.compile("fn action(x) { this += x; }")?;
-
-let mut value: Dynamic = 1_i64.into();
-
-let result = engine.call_fn_dynamic(
- &mut scope,
- &ast,
- "action",
- Some(&mut value), // binding the 'this' pointer
- [ 41_i64.into() ]
- )?;
-
-assert_eq!(value.as_int()?, 42);
-```
diff --git a/doc/src/engine/compile.md b/doc/src/engine/compile.md
deleted file mode 100644
index 07c172c1..00000000
--- a/doc/src/engine/compile.md
+++ /dev/null
@@ -1,27 +0,0 @@
-Compile a Script (to AST)
-========================
-
-{{#include ../links.md}}
-
-To repeatedly evaluate a script, _compile_ it first with `Engine::compile` into an `AST`
-(abstract syntax tree) form.
-
-`Engine::eval_ast` evaluates a pre-compiled `AST`.
-
-```rust
-// Compile to an AST and store it for later evaluations
-let ast = engine.compile("40 + 2")?;
-
-for _ in 0..42 {
- let result: i64 = engine.eval_ast(&ast)?;
-
- println!("Answer #{}: {}", i, result); // prints 42
-}
-```
-
-Compiling a script file is also supported with `Engine::compile_file`
-(not available under [`no_std`] or in [WASM] builds):
-
-```rust
-let ast = engine.compile_file("hello_world.rhai".into())?;
-```
diff --git a/doc/src/engine/custom-op.md b/doc/src/engine/custom-op.md
deleted file mode 100644
index 3dacfa9d..00000000
--- a/doc/src/engine/custom-op.md
+++ /dev/null
@@ -1,115 +0,0 @@
-Custom Operators
-================
-
-{{#include ../links.md}}
-
-For use as a DSL (Domain-Specific Languages), it is sometimes more convenient to augment Rhai with
-customized operators performing specific logic.
-
-`Engine::register_custom_operator` registers a keyword as a custom operator, giving it a particular
-_precedence_ (which cannot be zero).
-
-
-Example
--------
-
-```rust
-use rhai::{Engine, RegisterFn};
-
-let mut engine = Engine::new();
-
-// Register a custom operator named 'foo' and give it a precedence of 160
-// (i.e. between +|- and *|/)
-// Also register the implementation of the customer operator as a function
-engine
- .register_custom_operator("foo", 160)?
- .register_fn("foo", |x: i64, y: i64| (x * y) - (x + y));
-
-// The custom operator can be used in expressions
-let result = engine.eval_expression::("1 + 2 * 3 foo 4 - 5 / 6")?;
-// ^ custom operator
-
-// The above is equivalent to: 1 + ((2 * 3) foo 4) - (5 / 6)
-result == 15;
-```
-
-
-Alternatives to a Custom Operator
---------------------------------
-
-Custom operators are merely _syntactic sugar_. They map directly to registered functions.
-
-Therefore, the following are equivalent (assuming `foo` has been registered as a custom operator):
-
-```rust
-1 + 2 * 3 foo 4 - 5 / 6 // use custom operator
-
-1 + foo(2 * 3, 4) - 5 / 6 // use function call
-```
-
-A script using custom operators can always be pre-processed, via a pre-processor application,
-into a syntax that uses the corresponding function calls.
-
-Using `Engine::register_custom_operator` merely enables a convenient shortcut.
-
-
-Must be a Valid Identifier or Reserved Symbol
---------------------------------------------
-
-All custom operators must be _identifiers_ that follow the same naming rules as [variables].
-
-Alternatively, they can also be [reserved symbols]({{rootUrl}}/appendix/operators.md#symbols),
-[disabled operators or keywords][disable keywords and operators].
-
-```rust
-engine.register_custom_operator("foo", 20); // 'foo' is a valid custom operator
-
-engine.register_custom_operator("#", 20); // the reserved symbol '#' is also
- // a valid custom operator
-
-engine.register_custom_operator("+", 30); // <- error: '+' is an active operator
-
-engine.register_custom_operator("=>", 30); // <- error: '=>' is an active symbol
-```
-
-
-Binary Operators Only
----------------------
-
-All custom operators must be _binary_ (i.e. they take two operands).
-_Unary_ custom operators are not supported.
-
-```rust
-engine
- .register_custom_operator("foo", 160)?
- .register_fn("foo", |x: i64| x * x);
-
-engine.eval::("1 + 2 * 3 foo 4 - 5 / 6")?; // error: function 'foo (i64, i64)' not found
-```
-
-
-Operator Precedence
--------------------
-
-All operators in Rhai has a _precedence_ indicating how tightly they bind.
-
-A higher precedence binds more tightly than a lower precedence, so `*` and `/` binds before `+` and `-` etc.
-
-When registering a custom operator, the operator's precedence must also be provided.
-
-The following _precedence table_ shows the built-in precedence of standard Rhai operators:
-
-| Category | Operators | Precedence (0-255) |
-| ------------------- | :-------------------------------------------------------------------------------------: | :----------------: |
-| Assignments | `=`, `+=`, `-=`, `*=`, `/=`, `~=`, `%=`, `<<=`, `>>=`, `&=`, \|=
, `^=` | 0 |
-| Logic and bit masks | \|\|
, \|
, `^` | 30 |
-| Logic and bit masks | `&&`, `&` | 60 |
-| Comparisons | `==`, `!=` | 90 |
-| | `in` | 110 |
-| Comparisons | `>`, `>=`, `<`, `<=` | 130 |
-| Arithmetic | `+`, `-` | 150 |
-| Arithmetic | `*`, `/`, `%` | 180 |
-| Arithmetic | `~` | 190 |
-| Bit-shifts | `<<`, `>>` | 210 |
-| Object | `.` _(binds to right)_ | 240 |
-| Unary operators | unary `+`, `-`, `!` _(binds to right)_ | 255 |
diff --git a/doc/src/engine/custom-syntax.md b/doc/src/engine/custom-syntax.md
deleted file mode 100644
index 5c27142a..00000000
--- a/doc/src/engine/custom-syntax.md
+++ /dev/null
@@ -1,404 +0,0 @@
-Extend Rhai with Custom Syntax
-=============================
-
-{{#include ../links.md}}
-
-
-For the ultimate adventurous, there is a built-in facility to _extend_ the Rhai language
-with custom-defined _syntax_.
-
-But before going off to define the next weird statement type, heed this warning:
-
-
-Don't Do It™
-------------
-
-Stick with standard language syntax as much as possible.
-
-Having to learn Rhai is bad enough, no sane user would ever want to learn _yet_ another
-obscure language syntax just to do something.
-
-Try to use [custom operators] first. Defining a custom syntax should be considered a _last resort_.
-
-
-Where This Might Be Useful
--------------------------
-
-* Where an operation is used a _LOT_ and a custom syntax saves a lot of typing.
-
-* Where a custom syntax _significantly_ simplifies the code and _significantly_ enhances understanding of the code's intent.
-
-* Where certain logic cannot be easily encapsulated inside a function.
-
-* Where you just want to confuse your user and make their lives miserable, because you can.
-
-
-Step One – Design The Syntax
----------------------------------
-
-A custom syntax is simply a list of symbols.
-
-These symbol types can be used:
-
-* Standard [keywords]({{rootUrl}}/appendix/keywords.md)
-
-* Standard [operators]({{rootUrl}}/appendix/operators.md#operators).
-
-* Reserved [symbols]({{rootUrl}}/appendix/operators.md#symbols).
-
-* Identifiers following the [variable] naming rules.
-
-* `$expr$` – any valid expression, statement or statement block.
-
-* `$block$` – any valid statement block (i.e. must be enclosed by `'{'` .. `'}'`).
-
-* `$ident$` – any [variable] name.
-
-### The First Symbol Must be an Identifier
-
-There is no specific limit on the combination and sequencing of each symbol type,
-except the _first_ symbol which must be a custom keyword that follows the naming rules
-of [variables].
-
-The first symbol also cannot be a normal or reserved [keyword].
-In other words, any valid identifier that is not a [keyword] will work fine.
-
-### The First Symbol Must be Unique
-
-Rhai uses the _first_ symbol as a clue to parse custom syntax.
-
-Therefore, at any one time, there can only be _one_ custom syntax starting with each unique symbol.
-
-Any new custom syntax definition using the same first symbol simply _overwrites_ the previous one.
-
-### Example
-
-```rust
-exec $ident$ <- $expr$ : $block$
-```
-
-The above syntax is made up of a stream of symbols:
-
-| Position | Input | Symbol | Description |
-| :------: | :---: | :-------: | -------------------------------------------------------------------------------------------------------- |
-| 1 | | `exec` | custom keyword |
-| 2 | 1 | `$ident$` | a variable name |
-| 3 | | `<-` | the left-arrow symbol (which is a [reserved symbol]({{rootUrl}}/appendix/operators.md#symbols) in Rhai). |
-| 4 | 2 | `$expr$` | an expression, which may be enclosed with `{` .. `}`, or not. |
-| 5 | | `:` | the colon symbol |
-| 6 | 3 | `$block$` | a statement block, which must be enclosed with `{` .. `}`. |
-
-This syntax matches the following sample code and generates three inputs (one for each non-keyword):
-
-```rust
-// Assuming the 'exec' custom syntax implementation declares the variable 'hello':
-let x = exec hello <- foo(1, 2) : {
- hello += bar(hello);
- baz(hello);
- };
-
-print(x); // variable 'x' has a value returned by the custom syntax
-
-print(hello); // variable declared by a custom syntax persists!
-```
-
-
-Step Two – Implementation
-------------------------------
-
-Any custom syntax must include an _implementation_ of it.
-
-### Function Signature
-
-The function signature of an implementation is:
-
-> `Fn(context: &mut EvalContext, inputs: &[Expression]) -> Result>`
-
-where:
-
-| Parameter | Type | Description |
-| -------------------------- | :-------------------------------------: | ---------------------------------------------------------------------------------------------------------------------- |
-| `context` | `&mut EvalContext` | mutable reference to the current evaluation _context_ |
-| • `scope()` | `&Scope` | reference to the current [`Scope`] |
-| • `scope_mut()` | `&mut &mut Scope` | mutable reference to the current [`Scope`]; variables can be added to/removed from it |
-| • `engine()` | `&Engine` | reference to the current [`Engine`] |
-| • `source()` | `Option<&str>` | reference to the current source, if any |
-| • `iter_imports()` | `impl Iterator- ` | iterator of the current stack of [modules] imported via `import` statements |
-| • `imports()` | `&Imports` | reference to the current stack of [modules] imported via `import` statements; requires the [`internals`] feature |
-| • `iter_namespaces()` | `impl Iterator
- ` | iterator of the namespaces (as [modules]) containing all script-defined functions |
-| • `namespaces()` | `&[&Module]` | reference to the namespaces (as [modules]) containing all script-defined functions; requires the [`internals`] feature |
-| • `this_ptr()` | `Option<&Dynamic>` | reference to the current bound [`this`] pointer, if any |
-| • `call_level()` | `usize` | the current nesting level of function calls |
-| `inputs` | `&[Expression]` | a list of input expression trees |
-
-### Return Value
-
-Return value is the result of evaluating the custom syntax expression.
-
-### Access Arguments
-
-The most important argument is `inputs` where the matched identifiers (`$ident$`), expressions/statements (`$expr$`)
-and statement blocks (`$block$`) are provided.
-
-To access a particular argument, use the following patterns:
-
-| Argument type | Pattern (`n` = slot in `inputs`) | Result type | Description |
-| :-----------: | ---------------------------------------- | :----------: | ------------------ |
-| `$ident$` | `inputs[n].get_variable_name().unwrap()` | `&str` | name of a variable |
-| `$expr$` | `inputs.get(n).unwrap()` | `Expression` | an expression tree |
-| `$block$` | `inputs.get(n).unwrap()` | `Expression` | an expression tree |
-
-### Evaluate an Expression Tree
-
-Use the `EvalContext::eval_expression_tree` method to evaluate an arbitrary expression tree
-within the current evaluation context.
-
-```rust
-let expression = inputs.get(0).unwrap();
-let result = context.eval_expression_tree(expression)?;
-```
-
-### Declare Variables
-
-New variables maybe declared (usually with a variable name that is passed in via `$ident$).
-
-It can simply be pushed into the [`Scope`].
-
-However, beware that all new variables must be declared _prior_ to evaluating any expression tree.
-In other words, any [`Scope`] calls that change the list of must come _before_ any
-`EvalContext::eval_expression_tree` calls.
-
-```rust
-let var_name = inputs[0].get_variable_name().unwrap();
-let expression = inputs.get(1).unwrap();
-
-context.scope_mut().push(var_name, 0 as INT); // do this BEFORE 'context.eval_expression_tree'!
-
-let result = context.eval_expression_tree(expression)?;
-```
-
-
-Step Three – Register the Custom Syntax
---------------------------------------------
-
-Use `Engine::register_custom_syntax` to register a custom syntax.
-
-Again, beware that the _first_ symbol must be unique. If there already exists a custom syntax starting
-with that symbol, the previous syntax will be overwritten.
-
-The syntax is passed simply as a slice of `&str`.
-
-```rust
-// Custom syntax implementation
-fn implementation_func(
- context: &mut EvalContext,
- inputs: &[Expression]
-) -> Result
> {
- let var_name = inputs[0].get_variable_name().unwrap().to_string();
- let stmt = inputs.get(1).unwrap();
- let condition = inputs.get(2).unwrap();
-
- // Push one new variable into the scope BEFORE 'context.eval_expression_tree'
- context.scope_mut().push(var_name, 0 as INT);
-
- loop {
- // Evaluate the statement block
- context.eval_expression_tree(stmt)?;
-
- // Evaluate the condition expression
- let stop = !context.eval_expression_tree(condition)?
- .as_bool().map_err(|err| Box::new(
- EvalAltResult::ErrorMismatchDataType(
- "bool".to_string(),
- err.to_string(),
- condition.position(),
- )
- ))?;
-
- if stop {
- break;
- }
- }
-
- Ok(Dynamic::UNIT)
-}
-
-// Register the custom syntax (sample): exec |x| -> { x += 1 } while x < 0
-engine.register_custom_syntax(
- &[ "exec", "|", "$ident$", "|", "->", "$block$", "while", "$expr$" ], // the custom syntax
- 1, // the number of new variables declared within this custom syntax
- implementation_func
-)?;
-```
-
-Remember that a custom syntax acts as an _expression_, so it can show up practically anywhere:
-
-```rust
-// Use as an expression:
-let foo = (exec |x| -> { x += 1 } while x < 0) * 100;
-
-// Use as a function call argument:
-do_something(exec |x| -> { x += 1 } while x < 0, 24, true);
-
-// Use as a statement:
-exec |x| -> { x += 1 } while x < 0;
-// ^ terminate statement with ';'
-```
-
-
-Step Four – Disable Unneeded Statement Types
--------------------------------------------------
-
-When a DSL needs a custom syntax, most likely than not it is extremely specialized.
-Therefore, many statement types actually may not make sense under the same usage scenario.
-
-So, while at it, better [disable][disable keywords and operators] those built-in keywords
-and operators that should not be used by the user. The would leave only the bare minimum
-language surface exposed, together with the custom syntax that is tailor-designed for
-the scenario.
-
-A keyword or operator that is disabled can still be used in a custom syntax.
-
-In an extreme case, it is possible to disable _every_ keyword in the language, leaving only
-custom syntax (plus possibly expressions). But again, Don't Do It™ – unless you are certain
-of what you're doing.
-
-
-Step Five – Document
--------------------------
-
-For custom syntax, documentation is crucial.
-
-Make sure there are _lots_ of examples for users to follow.
-
-
-Step Six – Profit!
-------------------------
-
-
-Really Advanced – Custom Parsers
--------------------------------------
-
-Sometimes it is desirable to have multiple custom syntax starting with the
-same symbol. This is especially common for _command-style_ syntax where the
-second symbol calls a particular command:
-
-```rust
-// The following simulates a command-style syntax, all starting with 'perform'.
-perform hello world; // A fixed sequence of symbols
-perform action 42; // Perform a system action with a parameter
-perform update system; // Update the system
-perform check all; // Check all system settings
-perform cleanup; // Clean up the system
-perform add something; // Add something to the system
-perform remove something; // Delete something from the system
-```
-
-Alternatively, a custom syntax may have variable length, with a termination symbol:
-
-```rust
-// The following is a variable-length list terminated by '>'
-tags < "foo", "bar", 123, ... , x+y, true >
-```
-
-For even more flexibility in order to handle these advanced use cases, there is a
-_low level_ API for custom syntax that allows the registration of an entire mini-parser.
-
-Use `Engine::register_custom_syntax_raw` to register a custom syntax _parser_
-together with the implementation function.
-
-### How Custom Parsers Work
-
-A custom parser takes as input parameters two pieces of information:
-
-* The symbols parsed so far; `$ident$` is replaced with the actual identifier parsed,
- while `$expr$` and `$block$` stay as they were.
-
- The custom parser can inspect this symbols stream to determine the next symbol to parse.
-
-* The _look-ahead_ symbol, which is the symbol that will be parsed _next_.
-
- If the look-ahead is an expected symbol, the customer parser just returns it to continue parsing,
- or it can return `$ident$` to parse it as an identifier, or even `$expr$` to start parsing
- an expression.
-
- If the look-ahead is '`{`', then the custom parser may also return `$block$` to start parsing a
- statements block.
-
- If the look-ahead is unexpected, the custom parser should then return the symbol expected
- and Rhai will fail with a parse error containing information about the expected symbol.
-
-A custom parser always returns the _next_ symbol expected, which can also be `$ident$`,
-`$expr$` or `$block$`, or `None` if parsing should terminate (_without_ reading the
-look-ahead symbol).
-
-
-### Example
-
-```rust
-engine.register_custom_syntax_raw(
- "perform",
- // The custom parser implementation - always returns the next symbol expected
- // 'look_ahead' is the next symbol about to be read
- |symbols, look_ahead| match symbols.len() {
- // perform ...
- 1 => Ok(Some("$ident$".to_string())),
- // perform command ...
- 2 => match symbols[1].as_str() {
- "action" => Ok(Some("$expr$".into())),
- "hello" => Ok(Some("world".into())),
- "update" | "check" | "add" | "remove" => Ok(Some("$ident$".into())),
- "cleanup" => Ok(None),
- cmd => Err(ParseError(Box::new(ParseErrorType::BadInput(
- LexError::ImproperSymbol(format!("Improper command: {}", cmd))
- )), Position::NONE)),
- },
- // perform command arg ...
- 3 => match (symbols[1].as_str(), symbols[2].as_str()) {
- ("action", _) => Ok(None),
- ("hello", "world") => Ok(None),
- ("update", arg) if arg == "system" => Ok(None),
- ("update", arg) if arg == "client" => Ok(None),
- ("check", arg) => Ok(None),
- ("add", arg) => Ok(None),
- ("remove", arg) => Ok(None),
- (cmd, arg) => Err(ParseError(Box::new(ParseErrorType::BadInput(
- LexError::ImproperSymbol(
- format!("Invalid argument for command {}: {}", cmd, arg)
- )
- )), Position::NONE)),
- },
- _ => unreachable!(),
- },
- // Number of new variables declared by this custom syntax
- 0,
- // Implementation function
- implementation_func
-);
-```
-
-### Function Signature
-
-The custom syntax parser has the following signature:
-
-> `Fn(symbols: &[ImmutableString], look_ahead: &str) -> Result, ParseError>`
-
-where:
-
-| Parameter | Type | Description |
-| ------------ | :------------------: | ---------------------------------------------------------------------------------------------------------------------------------------------- |
-| `symbols` | `&[ImmutableString]` | a slice of symbols that have been parsed so far, possibly containing `$expr$` and/or `$block$`; `$ident$` is replaced by the actual identifier |
-| `look_ahead` | `&str` | a string slice containing the next symbol that is about to be read |
-
-Most strings are [`ImmutableString`][string]'s so it is usually more efficient to just `clone` the appropriate one
-(if any matches, or keep an internal cache for commonly-used symbols) as the return value.
-
-### Return Value
-
-The return value is `Result , ParseError>` where:
-
-| Value | Description |
-| ------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
-| `Ok(None)` | parsing complete and there are no more symbols to match |
-| `Ok(Some(symbol))` | the next symbol to match, which can also be `$expr$`, `$ident$` or `$block$` |
-| `Err(ParseError)` | error that is reflected back to the [`Engine`] – normally `ParseError(ParseErrorType::BadInput(LexError::ImproperSymbol(message)), Position::NONE)` to indicate that there is a syntax error, but it can be any `ParseError`. |
diff --git a/doc/src/engine/disable.md b/doc/src/engine/disable.md
deleted file mode 100644
index 28e35f70..00000000
--- a/doc/src/engine/disable.md
+++ /dev/null
@@ -1,28 +0,0 @@
-Disable Certain Keywords and/or Operators
-========================================
-
-{{#include ../links.md}}
-
-For certain embedded usage, it is sometimes necessary to restrict the language to a strict subset of Rhai
-to prevent usage of certain language features.
-
-Rhai supports surgically disabling a keyword or operator via the `Engine::disable_symbol` method.
-
-```rust
-use rhai::Engine;
-
-let mut engine = Engine::new();
-
-engine
- .disable_symbol("if") // disable the 'if' keyword
- .disable_symbol("+="); // disable the '+=' operator
-
-// The following all return parse errors.
-
-engine.compile("let x = if true { 42 } else { 0 };")?;
-// ^ 'if' is rejected as a reserved keyword
-
-engine.compile("let x = 40 + 2; x += 1;")?;
-// ^ '+=' is not recognized as an operator
-// ^ other operators are not affected
-```
diff --git a/doc/src/engine/dsl.md b/doc/src/engine/dsl.md
deleted file mode 100644
index efb9ac81..00000000
--- a/doc/src/engine/dsl.md
+++ /dev/null
@@ -1,92 +0,0 @@
-Use Rhai as a Domain-Specific Language (DSL)
-===========================================
-
-{{#include ../links.md}}
-
-Rhai can be successfully used as a domain-specific language (DSL).
-
-
-Expressions Only
-----------------
-
-In many DSL scenarios, only evaluation of expressions is needed.
-
-The [`Engine::eval_expression_XXX`][`eval_expression`] API can be used to restrict
-a script to expressions only.
-
-
-Unicode Standard Annex #31 Identifiers
--------------------------------------
-
-Variable names and other identifiers do not necessarily need to be ASCII-only.
-
-The [`unicode-xid-ident`] feature, when turned on, causes Rhai to allow variable names and identifiers
-that follow [Unicode Standard Annex #31](http://www.unicode.org/reports/tr31/).
-
-This is sometimes useful in a non-English DSL.
-
-
-Disable Keywords and/or Operators
---------------------------------
-
-In some DSL scenarios, it is necessary to further restrict the language to exclude certain
-language features that are not necessary or dangerous to the application.
-
-For example, a DSL may disable the `while` loop while keeping all other statement types intact.
-
-It is possible, in Rhai, to surgically [disable keywords and operators].
-
-
-Custom Operators
-----------------
-
-On the other hand, some DSL scenarios require special operators that make sense only for
-that specific environment. In such cases, it is possible to define [custom operators] in Rhai.
-
-For example:
-
-```rust
-let animal = "rabbit";
-let food = "carrot";
-
-animal eats food // custom operator 'eats'
-
-eats(animal, food) // <- the above really de-sugars to this
-```
-
-Although a [custom operator] always de-sugars to a simple function call,
-nevertheless it makes the DSL syntax much simpler and expressive.
-
-
-Custom Syntax
--------------
-
-For advanced DSL scenarios, it is possible to define entire expression [_syntax_][custom syntax] &ndash
-essentially custom statement types.
-
-For example, the following is a SQL-like syntax for some obscure DSL operation:
-
-```rust
-let table = [..., ..., ..., ...];
-
-// Syntax = calculate $ident$ ( $expr$ -> $ident$ ) => $ident$ : $expr$
-let total = calculate sum(table->price) => row : row.weight > 50;
-
-// Note: There is nothing special about those symbols; to make it look exactly like SQL:
-// Syntax = SELECT $ident$ ( $ident$ ) AS $ident$ FROM $expr$ WHERE $expr$
-let total = SELECT sum(price) AS row FROM table WHERE row.weight > 50;
-```
-
-After registering this custom syntax with Rhai, it can be used anywhere inside a script as
-a normal expression.
-
-For its evaluation, the callback function will receive the following list of inputs:
-
-* `inputs[0] = "sum"` - math operator
-* `inputs[1] = "price"` - field name
-* `inputs[2] = "row"` - loop variable name
-* `inputs[3] = Expression(table)` - data source
-* `inputs[4] = Expression(row.wright > 50)` - filter predicate
-
-Other identifiers, such as `"calculate"`, `"FROM"`, as well as symbols such as `->` and `:` etc.,
-are parsed in the order defined within the custom syntax.
diff --git a/doc/src/engine/expressions.md b/doc/src/engine/expressions.md
deleted file mode 100644
index cb3ea9b2..00000000
--- a/doc/src/engine/expressions.md
+++ /dev/null
@@ -1,27 +0,0 @@
-Evaluate Expressions Only
-========================
-
-{{#include ../links.md}}
-
-Sometimes a use case does not require a full-blown scripting _language_, but only needs to evaluate _expressions_.
-
-In these cases, use the `Engine::compile_expression` and `Engine::eval_expression` methods or their `_with_scope` variants.
-
-```rust
-let result = engine.eval_expression::("2 + (10 + 10) * 2")?;
-```
-
-When evaluating _expressions_, no full-blown statement (e.g. `if`, `while`, `for`, `fn`) – not even variable assignment –
-is supported and will be considered parse errors when encountered.
-
-[Closures] and [anonymous functions] are also not supported because in the background they compile to functions.
-
-```rust
-// The following are all syntax errors because the script is not an expression.
-
-engine.eval_expression::<()>("x = 42")?;
-
-let ast = engine.compile_expression("let x = 42")?;
-
-let result = engine.eval_expression_with_scope::(&mut scope, "if x { 42 } else { 123 }")?;
-```
diff --git a/doc/src/engine/func.md b/doc/src/engine/func.md
deleted file mode 100644
index d0ce6784..00000000
--- a/doc/src/engine/func.md
+++ /dev/null
@@ -1,43 +0,0 @@
-Create a Rust Closure from a Rhai Function
-=========================================
-
-{{#include ../links.md}}
-
-It is possible to further encapsulate a script in Rust such that it becomes a normal Rust function.
-
-Such a _closure_ is very useful as call-back functions.
-
-Creating them is accomplished via the `Func` trait which contains `create_from_script`
-(as well as its companion method `create_from_ast`):
-
-```rust
-use rhai::{Engine, Func}; // use 'Func' for 'create_from_script'
-
-let engine = Engine::new(); // create a new 'Engine' just for this
-
-let script = "fn calc(x, y) { x + y.len < 42 }";
-
-// Func takes two type parameters:
-// 1) a tuple made up of the types of the script function's parameters
-// 2) the return type of the script function
-//
-// 'func' will have type Box Result>> and is callable!
-let func = Func::<(i64, String), bool>::create_from_script(
-// ^^^^^^^^^^^^^ function parameter types in tuple
-
- engine, // the 'Engine' is consumed into the closure
- script, // the script, notice number of parameters must match
- "calc" // the entry-point function name
-)?;
-
-func(123, "hello".to_string())? == false; // call the closure
-
-schedule_callback(func); // pass it as a callback to another function
-
-// Although there is nothing you can't do by manually writing out the closure yourself...
-let engine = Engine::new();
-let ast = engine.compile(script)?;
-schedule_callback(Box::new(move |x: i64, y: String| -> Result> {
- engine.call_fn(&mut Scope::new(), &ast, "calc", (x, y))
-}));
-```
diff --git a/doc/src/engine/hello-world.md b/doc/src/engine/hello-world.md
deleted file mode 100644
index 241d282b..00000000
--- a/doc/src/engine/hello-world.md
+++ /dev/null
@@ -1,60 +0,0 @@
-Hello World in Rhai
-===================
-
-{{#include ../links.md}}
-
-To get going with Rhai is as simple as creating an instance of the scripting engine `rhai::Engine` via
-`Engine::new`, then calling the `eval` method:
-
-```rust
-use rhai::{Engine, EvalAltResult};
-
-fn main() -> Result<(), Box>
-{
- let engine = Engine::new();
-
- let result = engine.eval::("40 + 2")?;
- // ^^^^^^^ cast the result to an 'i64', this is required
-
- println!("Answer: {}", result); // prints 42
-
- Ok(())
-}
-```
-
-Evaluate a script file directly:
-
-```rust
-// 'eval_file' takes a 'PathBuf'
-let result = engine.eval_file::("hello_world.rhai".into())?;
-```
-
-
-Error Type
-----------
-
-`rhai::EvalAltResult` is the standard Rhai error type, which is a Rust `enum` containing all errors encountered
-during the parsing or evaluation process.
-
-
-Return Type
------------
-
-The type parameter for `Engine::eval` is used to specify the type of the return value,
-which _must_ match the actual type or an error is returned. Rhai is very strict here.
-
-There are two ways to specify the return type – _turbofish_ notation, or type inference.
-
-Use [`Dynamic`] for uncertain return types.
-
-```rust
-let result = engine.eval::("40 + 2")?; // return type is i64, specified using 'turbofish' notation
-
-let result: i64 = engine.eval("40 + 2")?; // return type is inferred to be i64
-
-result.is::() == true;
-
-let result: Dynamic = engine.eval("boo()")?; // use 'Dynamic' if you're not sure what type it'll be!
-
-let result = engine.eval::("40 + 2")?; // returns an error because the actual return type is i64, not String
-```
diff --git a/doc/src/engine/index.md b/doc/src/engine/index.md
deleted file mode 100644
index 8bf58504..00000000
--- a/doc/src/engine/index.md
+++ /dev/null
@@ -1,8 +0,0 @@
-Using the Engine
-================
-
-{{#include ../links.md}}
-
-Rhai's interpreter resides in the [`Engine`] type under the master `rhai` namespace.
-
-This section shows how to set up, configure and use this scripting engine.
diff --git a/doc/src/engine/metadata/export_to_json.md b/doc/src/engine/metadata/export_to_json.md
deleted file mode 100644
index 13d2da72..00000000
--- a/doc/src/engine/metadata/export_to_json.md
+++ /dev/null
@@ -1,107 +0,0 @@
-Export Functions Metadata to JSON
-================================
-
-{{#include ../../links.md}}
-
-
-`Engine::gen_fn_metadata_to_json` `Engine::gen_fn_metadata_with_ast_to_json`
-------------------------------------------------------------------------------
-
-As part of a _reflections_ API, `Engine::gen_fn_metadata_to_json` and the corresponding
-`Engine::gen_fn_metadata_with_ast_to_json` export the full list of [functions metadata]
-in JSON format.
-
-The [`metadata`] feature must be used to turn on this API, which requires
-the [`serde_json`](https://crates.io/crates/serde_json) crate.
-
-### Sources
-
-Functions from the following sources are included:
-
-1) Script-defined functions in an [`AST`] (for `Engine::gen_fn_metadata_with_ast_to_json`)
-2) Native Rust functions registered into the global namespace via the `Engine::register_XXX` API
-3) _Public_ (i.e. non-[`private`]) functions (native Rust or Rhai scripted) in static modules
- registered via `Engine::register_static_module`
-4) Native Rust functions in global modules registered via `Engine::register_global_module` (optional)
-
-Notice that if a function has been [overloaded][function overloading], only the overriding function's
-metadata is included.
-
-
-JSON Schema
------------
-
-The JSON schema used to hold functions metadata is very simple, containing a nested structure of
-`modules` and a list of `functions`.
-
-### Modules Schema
-
-```json
-{
- "modules":
- {
- "sub_module_1":
- {
- "modules":
- {
- "sub_sub_module_A":
- {
- "functions":
- [
- { ... function metadata ... },
- { ... function metadata ... },
- { ... function metadata ... },
- { ... function metadata ... },
- ...
- ]
- },
- "sub_sub_module_B":
- {
- ...
- }
- }
- },
- "sub_module_2":
- {
- ...
- },
- ...
- },
- "functions":
- [
- { ... function metadata ... },
- { ... function metadata ... },
- { ... function metadata ... },
- { ... function metadata ... },
- ...
- ]
-}
-```
-
-### Function Metadata Schema
-
-```json
-{
- "namespace": "internal" | "global",
- "access": "public" | "private",
- "name": "fn_name",
- "type": "native" | "script",
- "numParams": 42, /* number of parameters */
- "params": /* omitted if no parameters */
- [
- { "name": "param_1", "type": "type_1" },
- { "name": "param_2" }, /* no type info */
- { "name": "_", "type": "type_3" },
- ...
- ],
- "returnType": "ret_type", /* omitted if unknown */
- "signature": "[private] fn_name(param_1: type_1, param_2, _: type_3) -> ret_type",
- "docComments": /* omitted if none */
- [
- "/// doc-comment line 1",
- "/// doc-comment line 2",
- "/** doc-comment block */",
- ...
- ]
-}
-```
diff --git a/doc/src/engine/metadata/gen_fn_sig.md b/doc/src/engine/metadata/gen_fn_sig.md
deleted file mode 100644
index fe1df178..00000000
--- a/doc/src/engine/metadata/gen_fn_sig.md
+++ /dev/null
@@ -1,91 +0,0 @@
-Generate Function Signatures
-===========================
-
-{{#include ../../links.md}}
-
-
-`Engine::gen_fn_signatures`
---------------------------
-
-As part of a _reflections_ API, `Engine::gen_fn_signatures` returns a list of function _signatures_
-(as `Vec`), each corresponding to a particular function available to that [`Engine`] instance.
-
-> `fn_name ( param_1: type_1, param_2: type_2, ... , param_n : type_n ) -> return_type`
-
-### Sources
-
-Functions from the following sources are included, in order:
-
-1) Native Rust functions registered into the global namespace via the `Engine::register_XXX` API
-2) _Public_ (i.e. non-[`private`]) functions (native Rust or Rhai scripted) in global sub-modules
- registered via `Engine::register_static_module`.
-3) Native Rust functions in global modules registered via `Engine::register_global_module` (optional)
-
-
-Functions Metadata
-------------------
-
-Beware, however, that not all function signatures contain parameters and return value information.
-
-### `Engine::register_XXX`
-
-For instance, functions registered via `Engine::register_XXX` contain no information on
-the names of parameter and their actual types because Rust simply does not make such metadata
-available natively. The return type is also undetermined.
-
-A function registered under the name `foo` with three parameters and unknown return type:
-
-> `foo(_, _, _)`
-
-An operator function – again, unknown parameters and return type.
-Notice that function names do not need to be valid identifiers.
-
-> `+(_, _)`
-
-A [property setter][getters/setters] – again, unknown parameters and return type.
-Notice that function names do not need to be valid identifiers.
-In this case, the first parameter should be `&mut T` of the custom type and the return value is `()`:
-
-> `set$prop(_, _, _)`
-
-### Script-Defined Functions
-
-Script-defined [function] signatures contain parameter names. Since all parameters, as well as
-the return value, are [`Dynamic`] the types are simply not shown.
-
-A script-defined function always takes dynamic arguments, and the return type is also dynamic,
-so no type information is needed:
-
-> `foo(x, y, z)`
-
-probably defined as:
-
-```rust
-fn foo(x, y, z) {
- ...
-}
-```
-
-is the same as:
-
-> `foo(x: Dynamic, y: Dynamic, z: Dynamic) -> Result>`
-
-### Plugin Functions
-
-Functions defined in [plugin modules] are the best. They contain all the metadata
-describing the functions.
-
-For example, a plugin function `merge`:
-
-> `merge(list: &mut MyStruct, num: usize, name: &str) -> Option`
-
-Notice that function names do not need to be valid identifiers.
-
-For example, an operator defined as a [fallible function] in a [plugin module] via
-`#[rhai_fn(name="+=", return_raw)]` returns `Result>`:
-
-> `+=(list: &mut MyStruct, num: usize, name: &str) -> Result>`
-
-For example, a [property getter][getters/setters] defined in a [plugin module]:
-
-> `get$prop(obj: &mut MyStruct) -> String`
diff --git a/doc/src/engine/metadata/index.md b/doc/src/engine/metadata/index.md
deleted file mode 100644
index 227b1fcf..00000000
--- a/doc/src/engine/metadata/index.md
+++ /dev/null
@@ -1,28 +0,0 @@
-Functions Metadata
-==================
-
-{{#include ../../links.md}}
-
-The _metadata_ of a [function] means all relevant information related to a function's
-definition including:
-
-1. Its callable name
-
-2. Its access mode (public or [private][`private`])
-
-3. Its parameters and types (if any)
-
-4. Its return value and type (if any)
-
-5. Its nature (i.e. native Rust-based or Rhai script-based)
-
-6. Its [namespace][function namespace] (module or global)
-
-7. Its purpose, in the form of [doc-comments]
-
-8. Usage notes, warnings, etc., in the form of [doc-comments]
-
-A function's _signature_ encapsulates the first four pieces of information in a single
-concise line of definition:
-
-> `[private] fn_name ( param_1: type_1, param_2: type_2, ... , param_n : type_n ) -> return_type`
diff --git a/doc/src/engine/optimize/disable.md b/doc/src/engine/optimize/disable.md
deleted file mode 100644
index 8c02726c..00000000
--- a/doc/src/engine/optimize/disable.md
+++ /dev/null
@@ -1,24 +0,0 @@
-Turn Off Script Optimizations
-============================
-
-{{#include ../../links.md}}
-
-When scripts:
-
-* are known to be run only _once_,
-
-* are known to contain no dead code,
-
-* do not use constants in calculations
-
-the optimization pass may be a waste of time and resources. In that case, turn optimization off
-by setting the optimization level to [`OptimizationLevel::None`].
-
-Alternatively, turn off optimizations via the [`no_optimize`] feature.
-
-```rust
-let engine = rhai::Engine::new();
-
-// Turn off the optimizer
-engine.set_optimization_level(rhai::OptimizationLevel::None);
-```
diff --git a/doc/src/engine/optimize/eager.md b/doc/src/engine/optimize/eager.md
deleted file mode 100644
index 2071154b..00000000
--- a/doc/src/engine/optimize/eager.md
+++ /dev/null
@@ -1,26 +0,0 @@
-Eager Function Evaluation When Using Full Optimization Level
-==========================================================
-
-{{#include ../../links.md}}
-
-When the optimization level is [`OptimizationLevel::Full`], the [`Engine`] assumes all functions to be _pure_
-and will _eagerly_ evaluated all function calls with constant arguments, using the result to replace the call.
-
-This also applies to all operators (which are implemented as functions).
-
-For instance, the same example above:
-
-```rust
-// When compiling the following with OptimizationLevel::Full...
-
-const DECISION = 1;
- // this condition is now eliminated because 'sign(DECISION) > 0'
-if DECISION.sign() > 0 { // is a call to the 'sign' and '>' functions, and they return 'true'
- print("hello!"); // this block is promoted to the parent level
-} else {
- print("boo!"); // this block is eliminated because it is never reached
-}
-
-print("hello!"); // <- the above is equivalent to this
- // ('print' and 'debug' are handled specially)
-```
diff --git a/doc/src/engine/optimize/index.md b/doc/src/engine/optimize/index.md
deleted file mode 100644
index 6852604b..00000000
--- a/doc/src/engine/optimize/index.md
+++ /dev/null
@@ -1,146 +0,0 @@
-Script Optimization
-===================
-
-{{#include ../../links.md}}
-
-Rhai includes an _optimizer_ that tries to optimize a script after parsing.
-This can reduce resource utilization and increase execution speed.
-
-Script optimization can be turned off via the [`no_optimize`] feature.
-
-
-Dead Code Removal
-----------------
-
-For example, in the following:
-
-```rust
-{
- let x = 999; // NOT eliminated: variable may be used later on (perhaps even an 'eval')
- 123; // eliminated: no effect
- "hello"; // eliminated: no effect
- [1, 2, x, x*2, 5]; // eliminated: no effect
- foo(42); // NOT eliminated: the function 'foo' may have side-effects
- 666 // NOT eliminated: this is the return value of the block,
- // and the block is the last one so this is the return value of the whole script
-}
-```
-
-Rhai attempts to eliminate _dead code_ (i.e. code that does nothing, for example an expression by itself as a statement,
-which is allowed in Rhai).
-
-The above script optimizes to:
-
-```rust
-{
- let x = 999;
- foo(42);
- 666
-}
-```
-
-
-Constants Propagation
---------------------
-
-Constants propagation is used to remove dead code:
-
-```rust
-const ABC = true;
-
-if ABC || some_work() { print("done!"); } // 'ABC' is constant so it is replaced by 'true'...
-
-if true || some_work() { print("done!"); } // since '||' short-circuits, 'some_work' is never called
-
-if true { print("done!"); } // <- the line above is equivalent to this
-
-print("done!"); // <- the line above is further simplified to this
- // because the condition is always true
-```
-
-These are quite effective for template-based machine-generated scripts where certain constant values
-are spliced into the script text in order to turn on/off certain sections.
-
-For fixed script texts, the constant values can be provided in a user-defined [`Scope`] object
-to the [`Engine`] for use in compilation and evaluation.
-
-### Caveat
-
-If the [constants] are modified later on (yes, it is possible, via Rust functions),
-the modified values will not show up in the optimized script.
-Only the initialization values of [constants] are ever retained.
-
-This is almost never a problem because real-world scripts seldom modify a constant,
-but the possibility is always there.
-
-
-Eager Operator Evaluations
--------------------------
-
-Beware, however, that most operators are actually function calls, and those functions can be overridden,
-so whether they are optimized away depends on the situation:
-
-* If the operands are not _constant_ values, it is not optimized.
-
-* If the operator is [overloaded][operator overloading], it is not optimized because the overloading function may not be _pure_
- (i.e. may cause side-effects when called).
-
-* If the operator is not _binary_, it is not optimized. Only binary operators are built-in to Rhai.
-
-* If the operands are not of the same type, it is not optimized.
-
-* If the operator is not _built-in_ (see list of [built-in operators]), it is not optimized.
-
-* If the operator is a binary built-in operator for a [standard type][standard types], it is called and replaced by a constant result.
-
-Rhai guarantees that no external function will be run (in order not to trigger side-effects) during the
-optimization process (unless the optimization level is set to [`OptimizationLevel::Full`]).
-
-```rust
-// The following is most likely generated by machine.
-
-const DECISION = 1; // this is an integer, one of the standard types
-
-if DECISION == 1 { // this is optimized into 'true'
- :
-} else if DECISION == 2 { // this is optimized into 'false'
- :
-} else if DECISION == 3 { // this is optimized into 'false'
- :
-} else {
- :
-}
-```
-
-Because of the eager evaluation of operators for [standard types], many constant expressions will be evaluated
-and replaced by the result.
-
-```rust
-let x = (1+2) * 3-4 / 5%6; // will be replaced by 'let x = 9'
-
-let y = (1 > 2) || (3 < =4); // will be replaced by 'let y = true'
-```
-
-For operators that are not optimized away due to one of the above reasons, the function calls
-are simply left behind:
-
-```rust
-// Assume 'new_state' returns some custom type that is NOT one of the standard types.
-// Also assume that the '==; operator is defined for that custom type.
-const DECISION_1 = new_state(1);
-const DECISION_2 = new_state(2);
-const DECISION_3 = new_state(3);
-
-if DECISION == 1 { // NOT optimized away because the operator is not built-in
- : // and may cause side-effects if called!
- :
-} else if DECISION == 2 { // same here, NOT optimized away
- :
-} else if DECISION == 3 { // same here, NOT optimized away
- :
-} else {
- :
-}
-```
-
-Alternatively, turn the optimizer to [`OptimizationLevel::Full`].
diff --git a/doc/src/engine/optimize/optimize-levels.md b/doc/src/engine/optimize/optimize-levels.md
deleted file mode 100644
index c9e3015f..00000000
--- a/doc/src/engine/optimize/optimize-levels.md
+++ /dev/null
@@ -1,34 +0,0 @@
-Optimization Levels
-==================
-
-{{#include ../../links.md}}
-
-There are three levels of optimization: `None`, `Simple` and `Full`.
-
-* `None` is obvious – no optimization on the AST is performed.
-
-* `Simple` (default) performs only relatively _safe_ optimizations without causing side-effects
- (i.e. it only relies on static analysis and [built-in operators] for constant [standard types],
- and will not perform any external function calls).
-
- However, it is important to bear in mind that _constants propagation_ is performed with the
- caveat that, if [constants] are modified later on (yes, it is possible, via Rust functions),
- the modified values will not show up in the optimized script. Only the initialization values
- of [constants] are ever retained.
-
- Furthermore, overriding a [built-in operator][built-in operators] in the [`Engine`] afterwards
- has no effect after the optimizer replaces an expression with its calculated value.
-
-* `Full` is _much_ more aggressive, _including_ calling external functions on constant arguments to determine their result.
- One benefit to this is that many more optimization opportunities arise, especially with regards to comparison operators.
-
-
-Set Optimization Level
----------------------
-
-An [`Engine`]'s optimization level is set via a call to `Engine::set_optimization_level`:
-
-```rust
-// Turn on aggressive optimizations
-engine.set_optimization_level(rhai::OptimizationLevel::Full);
-```
diff --git a/doc/src/engine/optimize/reoptimize.md b/doc/src/engine/optimize/reoptimize.md
deleted file mode 100644
index 38726649..00000000
--- a/doc/src/engine/optimize/reoptimize.md
+++ /dev/null
@@ -1,38 +0,0 @@
-Re-Optimize an AST
-==================
-
-{{#include ../../links.md}}
-
-Sometimes it is more efficient to store one single, large script with delimited code blocks guarded by
-constant variables. This script is compiled once to an [`AST`].
-
-Then, depending on the execution environment, constants are passed into the [`Engine`] and the [`AST`]
-is _re_-optimized based on those constants via the `Engine::optimize_ast` method,
-effectively pruning out unused code sections.
-
-The final, optimized [`AST`] is then used for evaluations.
-
-```rust
-// Compile master script to AST
-let master_ast = engine.compile(
-r"
- if SCENARIO == 1 {
- do_work();
- } else if SCENARIO == 2 {
- do_something();
- } else if SCENARIO == 3 {
- do_something_else();
- } else {
- do_nothing();
- }
-")?;
-
-// Create a new 'Scope' - put constants in it to aid optimization
-let mut scope = Scope::new();
-scope.push_constant("SCENARIO", 1_i64);
-
-// Re-optimize the AST
-let new_ast = engine.optimize_ast(&scope, master_ast.clone(), OptimizationLevel::Simple);
-
-// 'new_ast' is essentially: 'do_work()'
-```
diff --git a/doc/src/engine/optimize/semantics.md b/doc/src/engine/optimize/semantics.md
deleted file mode 100644
index 86aa51b9..00000000
--- a/doc/src/engine/optimize/semantics.md
+++ /dev/null
@@ -1,43 +0,0 @@
-Subtle Semantic Changes After Optimization
-=========================================
-
-{{#include ../../links.md}}
-
-Some optimizations can alter subtle semantics of the script.
-
-For example:
-
-```rust
-if true { // condition always true
- 123.456; // eliminated
- hello; // eliminated, EVEN THOUGH the variable doesn't exist!
- foo(42) // promoted up-level
-}
-
-foo(42) // <- the above optimizes to this
-```
-
-If the original script were evaluated instead, it would have been an error – the variable `hello` does not exist,
-so the script would have been terminated at that point with an error return.
-
-In fact, any errors inside a statement that has been eliminated will silently _disappear_:
-
-```rust
-print("start!");
-if my_decision { /* do nothing... */ } // eliminated due to no effect
-print("end!");
-
-// The above optimizes to:
-
-print("start!");
-print("end!");
-```
-
-In the script above, if `my_decision` holds anything other than a boolean value,
-the script should have been terminated due to a type error.
-
-However, after optimization, the entire `if` statement is removed (because an access to `my_decision` produces
-no side-effects), thus the script silently runs to completion without errors.
-
-It is usually a _Very Bad Idea™_ to depend on a script failing or such kind of subtleties, but if it turns out to be necessary
-(why? I would never guess), turn script optimization off by setting the optimization level to [`OptimizationLevel::None`].
diff --git a/doc/src/engine/optimize/side-effects.md b/doc/src/engine/optimize/side-effects.md
deleted file mode 100644
index fbacea0b..00000000
--- a/doc/src/engine/optimize/side-effects.md
+++ /dev/null
@@ -1,22 +0,0 @@
-Side-Effect Considerations for Full Optimization Level
-====================================================
-
-{{#include ../../links.md}}
-
-All of Rhai's built-in functions (and operators which are implemented as functions) are _pure_
-(i.e. they do not mutate state nor cause any side-effects, with the exception of `print` and `debug`
-which are handled specially) so using [`OptimizationLevel::Full`] is usually quite safe _unless_
-custom types and functions are registered.
-
-If custom functions are registered, they _may_ be called (or maybe not, if the calls happen to lie
-within a pruned code block).
-
-If custom functions are registered to overload built-in operators, they will also be called when
-the operators are used (in an `if` statement, for example) causing side-effects.
-
-Therefore, the rule-of-thumb is:
-
-* _Always_ register custom types and functions _after_ compiling scripts if [`OptimizationLevel::Full`] is used.
-
-* _DO NOT_ depend on knowledge that the functions have no side-effects, because those functions can change later on and,
- when that happens, existing scripts may break in subtle ways.
diff --git a/doc/src/engine/optimize/volatility.md b/doc/src/engine/optimize/volatility.md
deleted file mode 100644
index dcd1f487..00000000
--- a/doc/src/engine/optimize/volatility.md
+++ /dev/null
@@ -1,16 +0,0 @@
-Volatility Considerations for Full Optimization Level
-===================================================
-
-{{#include ../../links.md}}
-
-Even if a custom function does not mutate state nor cause side-effects, it may still be _volatile_,
-i.e. it _depends_ on the external environment and is not _pure_.
-
-A perfect example is a function that gets the current time – obviously each run will return a different value!
-
-The optimizer, when using [`OptimizationLevel::Full`], will _merrily assume_ that all functions are _pure_,
-so when it finds constant arguments (or none) it eagerly executes the function call and replaces it with the result.
-
-This causes the script to behave differently from the intended semantics.
-
-Therefore, **avoid using [`OptimizationLevel::Full`]** if non-_pure_ custom types and/or functions are involved.
diff --git a/doc/src/engine/options.md b/doc/src/engine/options.md
deleted file mode 100644
index 345a4b4c..00000000
--- a/doc/src/engine/options.md
+++ /dev/null
@@ -1,19 +0,0 @@
-Engine Configuration Options
-===========================
-
-{{#include ../links.md}}
-
-A number of other configuration options are available from the `Engine` to fine-tune behavior and safeguards.
-
-| Method | Not available under | Description |
-| ------------------------ | ---------------------------- | ---------------------------------------------------------------------------------------------------------------------- |
-| `set_doc_comments` | | enables/disables [doc-comments] |
-| `set_optimization_level` | [`no_optimize`] | sets the amount of script _optimizations_ performedSee [script optimization] |
-| `set_max_expr_depths` | [`unchecked`] | sets the maximum nesting levels of an expression/statementSee [maximum statement depth] |
-| `set_max_call_levels` | [`unchecked`] | sets the maximum number of function call levels (default 50) to avoid infinite recursionSee [maximum call stack depth] |
-| `set_max_operations` | [`unchecked`] | sets the maximum number of _operations_ that a script is allowed to consumeSee [maximum number of operations] |
-| `set_max_modules` | [`unchecked`] | sets the maximum number of [modules] that a script is allowed to loadSee [maximum number of modules] |
-| `set_max_string_size` | [`unchecked`] | sets the maximum length (in UTF-8 bytes) for [strings]See [maximum length of strings] |
-| `set_max_array_size` | [`unchecked`], [`no_index`] | sets the maximum size for [arrays]See [maximum size of arrays] |
-| `set_max_map_size` | [`unchecked`], [`no_object`] | sets the maximum number of properties for [object maps]See [maximum size of object maps] |
-| `disable_symbol` | | disables a certain keyword or operatorSee [disable keywords and operators] |
diff --git a/doc/src/engine/raw.md b/doc/src/engine/raw.md
deleted file mode 100644
index 017814a5..00000000
--- a/doc/src/engine/raw.md
+++ /dev/null
@@ -1,28 +0,0 @@
-Raw `Engine`
-===========
-
-{{#include ../links.md}}
-
-`Engine::new` creates a scripting [`Engine`] with common functionalities (e.g. printing to the console via `print`).
-
-In many controlled embedded environments, however, these may not be needed and unnecessarily occupy
-application code storage space.
-
-Use `Engine::new_raw` to create a _raw_ `Engine`, in which only a minimal set of
-basic arithmetic and logical operators are supported (see below).
-
-To add more functionalities to a _raw_ `Engine`, load [packages] into it.
-
-
-Built-in Operators
-------------------
-
-| Operators | Assignment operators | Supported for types (see [standard types]) |
-| ------------------------- | ---------------------------- | ----------------------------------------------------------------------------- |
-| `+`, | `+=` | `INT`, `FLOAT` (if not [`no_float`]), `char`, `ImmutableString` |
-| `-`, `*`, `/`, `%`, `~`, | `-=`, `*=`, `/=`, `%=`, `~=` | `INT`, `FLOAT` (if not [`no_float`]) |
-| `<<`, `>>` | `<<=`, `>>=` | `INT` |
-| `&`, \|
, `^` | `&=`, \|=
, `^=` | `INT`, `bool` |
-| `&&`, \|\|
| | `bool` |
-| `==`, `!=` | | `INT`, `FLOAT` (if not [`no_float`]), `bool`, `char`, `()`, `ImmutableString` |
-| `>`, `>=`, `<`, `<=` | | `INT`, `FLOAT` (if not [`no_float`]), `char`, `()`, `ImmutableString` |
diff --git a/doc/src/engine/scope.md b/doc/src/engine/scope.md
deleted file mode 100644
index 067fe077..00000000
--- a/doc/src/engine/scope.md
+++ /dev/null
@@ -1,55 +0,0 @@
-`Scope` – Initializing and Maintaining State
-=================================================
-
-{{#include ../links.md}}
-
-By default, Rhai treats each [`Engine`] invocation as a fresh one, persisting only the functions that have been defined
-but no global state. This gives each evaluation a clean starting slate.
-
-In order to continue using the same global state from one invocation to the next,
-such a state must be manually created and passed in.
-
-All `Scope` variables are [`Dynamic`], meaning they can store values of any type.
-
-Under [`sync`], however, only types that are `Send + Sync` are supported, and the entire `Scope` itself
-will also be `Send + Sync`. This is extremely useful in multi-threaded applications.
-
-In this example, a global state object (a `Scope`) is created with a few initialized variables,
-then the same state is threaded through multiple invocations:
-
-```rust
-use rhai::{Engine, Scope, EvalAltResult};
-
-let engine = Engine::new();
-
-// First create the state
-let mut scope = Scope::new();
-
-// Then push (i.e. add) some initialized variables into the state.
-// Remember the system number types in Rhai are i64 (i32 if 'only_i32') ond f64.
-// Better stick to them or it gets hard working with the script.
-scope
- .push("y", 42_i64)
- .push("z", 999_i64)
- .push_constant("MY_NUMBER", 123_i64) // constants can also be added
- .set_value("s", "hello, world!".to_string()); //'set_value' adds a variable when one doesn't exist
- // remember to use 'String', not '&str'
-
-// First invocation
-engine.eval_with_scope::<()>(&mut scope, r"
- let x = 4 + 5 – y + z + MY_NUMBER + s.len;
- y = 1;
-")?;
-
-// Second invocation using the same state
-let result = engine.eval_with_scope::(&mut scope, "x")?;
-
-println!("result: {}", result); // prints 1102
-
-// Variable y is changed in the script – read it with 'get_value'
-assert_eq!(scope.get_value::("y").expect("variable y should exist"), 1);
-
-// We can modify scope variables directly with 'set_value'
-scope.set_value("y", 42_i64);
-assert_eq!(scope.get_value::("y").expect("variable y should exist"), 42);
-```
diff --git a/doc/src/engine/var.md b/doc/src/engine/var.md
deleted file mode 100644
index c0fb5579..00000000
--- a/doc/src/engine/var.md
+++ /dev/null
@@ -1,93 +0,0 @@
-Variable Resolver
-=================
-
-{{#include ../links.md}}
-
-By default, Rhai looks up access to variables from the enclosing block scope,
-working its way outwards until it reaches the top (global) level, then it
-searches the [`Scope`] that is passed into the `Engine::eval` call.
-
-There is a built-in facility for advanced users to _hook_ into the variable
-resolution service and to override its default behavior.
-
-To do so, provide a closure to the [`Engine`] via the `Engine::on_var` method:
-
-```rust
-let mut engine = Engine::new();
-
-// Register a variable resolver.
-engine.on_var(|name, index, context| {
- match name {
- "MYSTIC_NUMBER" => Ok(Some((42 as INT).into())),
- // Override a variable - make it not found even if it exists!
- "DO_NOT_USE" => Err(Box::new(
- EvalAltResult::ErrorVariableNotFound(name.to_string(), Position::NONE)
- )),
- // Silently maps 'chameleon' into 'innocent'.
- "chameleon" => context.scope().get_value("innocent").map(Some).ok_or_else(|| Box::new(
- EvalAltResult::ErrorVariableNotFound(name.to_string(), Position::NONE)
- )),
- // Return Ok(None) to continue with the normal variable resolution process.
- _ => Ok(None)
- }
-});
-```
-
-
-Returned Values are Constants
-----------------------------
-
-Variable values, if any returned, are treated as _constants_ by the script and cannot be assigned to.
-This is to avoid needing a mutable reference to the underlying data provider which may not be possible to obtain.
-
-In order to change these variables, it is best to push them into a custom [`Scope`] instead of using
-a variable resolver. Then these variables can be assigned to and their updated values read back after
-the script is evaluated.
-
-
-Benefits of Using a Variable Resolver
-------------------------------------
-
-1. Avoid having to maintain a custom [`Scope`] with all variables regardless of need (because a script may not use them all).
-
-2. _Short-circuit_ variable access, essentially overriding standard behavior.
-
-3. _Lazy-load_ variables when they are accessed, not up-front. This benefits when the number of variables is very large, when they are timing-dependent, or when they are expensive to load.
-
-4. Rename system variables on a script-by-script basis without having to construct different [`Scope`]'s.
-
-
-Function Signature
-------------------
-
-The function signature passed to `Engine::on_var` takes the following form:
-
-> `Fn(name: &str, index: usize, context: &EvalContext)`
-> `-> Result, Box> + 'static`
-
-where:
-
-| Parameter | Type | Description |
-| -------------------------- | :-------------------------------------: | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
-| `name` | `&str` | variable name |
-| `index` | `usize` | an offset from the bottom of the current [`Scope`] that the variable is supposed to reside. Offsets start from 1, with 1 meaning the last variable in the current [`Scope`]. Essentially the correct variable is at position `scope.len() - index`. If `index` is zero, then there is no pre-calculated offset position and a search through the current [`Scope`] must be performed. |
-| `context` | `&EvalContext` | reference to the current evaluation _context_ |
-| • `scope()` | `&Scope` | reference to the current [`Scope`] |
-| • `engine()` | `&Engine` | reference to the current [`Engine`] |
-| • `source()` | `Option<&str>` | reference to the current source, if any |
-| • `iter_imports()` | `impl Iterator- ` | iterator of the current stack of [modules] imported via `import` statements |
-| • `imports()` | `&Imports` | reference to the current stack of [modules] imported via `import` statements; requires the [`internals`] feature |
-| • `iter_namespaces()` | `impl Iterator
- ` | iterator of the namespaces (as [modules]) containing all script-defined functions |
-| • `namespaces()` | `&[&Module]` | reference to the namespaces (as [modules]) containing all script-defined functions; requires the [`internals`] feature |
-| • `this_ptr()` | `Option<&Dynamic>` | reference to the current bound [`this`] pointer, if any |
-| • `call_level()` | `usize` | the current nesting level of function calls |
-
-### Return Value
-
-The return value is `Result
, Box>` where:
-
-| Value | Description |
-| ------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
-| `Ok(None)` | normal variable resolution process should continue, i.e. continue searching through the [`Scope`] |
-| `Ok(Some(Dynamic))` | value of the variable, treated as a constant |
-| `Err(Box)` | error that is reflected back to the [`Engine`]. Normally this is `EvalAltResult::ErrorVariableNotFound(var_name, Position::NONE)` to indicate that the variable does not exist, but it can be any `EvalAltResult`. |
diff --git a/doc/src/images/logo/favicon.png b/doc/src/images/logo/favicon.png
deleted file mode 100644
index f5cf9cac..00000000
Binary files a/doc/src/images/logo/favicon.png and /dev/null differ
diff --git a/doc/src/images/logo/favicon.svg b/doc/src/images/logo/favicon.svg
deleted file mode 100644
index 16aeb468..00000000
--- a/doc/src/images/logo/favicon.svg
+++ /dev/null
@@ -1,15 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/doc/src/images/logo/rhai-banner-transparent-colour.png b/doc/src/images/logo/rhai-banner-transparent-colour.png
deleted file mode 100644
index 8d478bdc..00000000
Binary files a/doc/src/images/logo/rhai-banner-transparent-colour.png and /dev/null differ
diff --git a/doc/src/images/logo/rhai-banner-transparent-colour.svg b/doc/src/images/logo/rhai-banner-transparent-colour.svg
deleted file mode 100644
index 57ee1693..00000000
--- a/doc/src/images/logo/rhai-banner-transparent-colour.svg
+++ /dev/null
@@ -1,31 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/doc/src/images/logo/rhai-colour-black.png b/doc/src/images/logo/rhai-colour-black.png
deleted file mode 100644
index b874a27e..00000000
Binary files a/doc/src/images/logo/rhai-colour-black.png and /dev/null differ
diff --git a/doc/src/images/logo/rhai-colour-black.svg b/doc/src/images/logo/rhai-colour-black.svg
deleted file mode 100644
index 2a2469f1..00000000
--- a/doc/src/images/logo/rhai-colour-black.svg
+++ /dev/null
@@ -1,39 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/doc/src/images/logo/rhai-colour-white.png b/doc/src/images/logo/rhai-colour-white.png
deleted file mode 100644
index db83cee0..00000000
Binary files a/doc/src/images/logo/rhai-colour-white.png and /dev/null differ
diff --git a/doc/src/images/logo/rhai-colour-white.svg b/doc/src/images/logo/rhai-colour-white.svg
deleted file mode 100644
index 9008b4dd..00000000
--- a/doc/src/images/logo/rhai-colour-white.svg
+++ /dev/null
@@ -1,34 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/doc/src/images/logo/rhai-icon-colour-black.png b/doc/src/images/logo/rhai-icon-colour-black.png
deleted file mode 100644
index 55c7d714..00000000
Binary files a/doc/src/images/logo/rhai-icon-colour-black.png and /dev/null differ
diff --git a/doc/src/images/logo/rhai-icon-colour-black.svg b/doc/src/images/logo/rhai-icon-colour-black.svg
deleted file mode 100644
index 05db75f0..00000000
--- a/doc/src/images/logo/rhai-icon-colour-black.svg
+++ /dev/null
@@ -1,23 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/doc/src/images/logo/rhai-icon-colour-white.png b/doc/src/images/logo/rhai-icon-colour-white.png
deleted file mode 100644
index 4af8351f..00000000
Binary files a/doc/src/images/logo/rhai-icon-colour-white.png and /dev/null differ
diff --git a/doc/src/images/logo/rhai-icon-colour-white.svg b/doc/src/images/logo/rhai-icon-colour-white.svg
deleted file mode 100644
index fde472a9..00000000
--- a/doc/src/images/logo/rhai-icon-colour-white.svg
+++ /dev/null
@@ -1,23 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/doc/src/images/logo/rhai-icon-transparent-black.png b/doc/src/images/logo/rhai-icon-transparent-black.png
deleted file mode 100644
index c1d0c712..00000000
Binary files a/doc/src/images/logo/rhai-icon-transparent-black.png and /dev/null differ
diff --git a/doc/src/images/logo/rhai-icon-transparent-black.svg b/doc/src/images/logo/rhai-icon-transparent-black.svg
deleted file mode 100644
index f02f7a47..00000000
--- a/doc/src/images/logo/rhai-icon-transparent-black.svg
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
diff --git a/doc/src/images/logo/rhai-icon-transparent-colour.png b/doc/src/images/logo/rhai-icon-transparent-colour.png
deleted file mode 100644
index c7a54fc4..00000000
Binary files a/doc/src/images/logo/rhai-icon-transparent-colour.png and /dev/null differ
diff --git a/doc/src/images/logo/rhai-icon-transparent-colour.svg b/doc/src/images/logo/rhai-icon-transparent-colour.svg
deleted file mode 100644
index a8408964..00000000
--- a/doc/src/images/logo/rhai-icon-transparent-colour.svg
+++ /dev/null
@@ -1,14 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/doc/src/images/logo/rhai-icon-transparent-white.png b/doc/src/images/logo/rhai-icon-transparent-white.png
deleted file mode 100644
index cd63ff1e..00000000
Binary files a/doc/src/images/logo/rhai-icon-transparent-white.png and /dev/null differ
diff --git a/doc/src/images/logo/rhai-icon-transparent-white.svg b/doc/src/images/logo/rhai-icon-transparent-white.svg
deleted file mode 100644
index 6648a7ae..00000000
--- a/doc/src/images/logo/rhai-icon-transparent-white.svg
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
diff --git a/doc/src/images/logo/rhai-logo-transparent-colour-black.png b/doc/src/images/logo/rhai-logo-transparent-colour-black.png
deleted file mode 100644
index 9d2f9efb..00000000
Binary files a/doc/src/images/logo/rhai-logo-transparent-colour-black.png and /dev/null differ
diff --git a/doc/src/images/logo/rhai-logo-transparent-colour-black.svg b/doc/src/images/logo/rhai-logo-transparent-colour-black.svg
deleted file mode 100644
index f7e36f24..00000000
--- a/doc/src/images/logo/rhai-logo-transparent-colour-black.svg
+++ /dev/null
@@ -1,28 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/doc/src/images/logo/rhai-logo-transparent-colour-white.png b/doc/src/images/logo/rhai-logo-transparent-colour-white.png
deleted file mode 100644
index 028f6ad6..00000000
Binary files a/doc/src/images/logo/rhai-logo-transparent-colour-white.png and /dev/null differ
diff --git a/doc/src/images/logo/rhai-logo-transparent-colour-white.svg b/doc/src/images/logo/rhai-logo-transparent-colour-white.svg
deleted file mode 100644
index 3055938d..00000000
--- a/doc/src/images/logo/rhai-logo-transparent-colour-white.svg
+++ /dev/null
@@ -1,28 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/doc/src/images/logo/rhai-logo-transparent-sil-black.png b/doc/src/images/logo/rhai-logo-transparent-sil-black.png
deleted file mode 100644
index 97b7d122..00000000
Binary files a/doc/src/images/logo/rhai-logo-transparent-sil-black.png and /dev/null differ
diff --git a/doc/src/images/logo/rhai-logo-transparent-sil-black.svg b/doc/src/images/logo/rhai-logo-transparent-sil-black.svg
deleted file mode 100644
index 565c24ba..00000000
--- a/doc/src/images/logo/rhai-logo-transparent-sil-black.svg
+++ /dev/null
@@ -1,25 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/doc/src/images/logo/rhai-logo-transparent-sil-white.png b/doc/src/images/logo/rhai-logo-transparent-sil-white.png
deleted file mode 100644
index 99049d18..00000000
Binary files a/doc/src/images/logo/rhai-logo-transparent-sil-white.png and /dev/null differ
diff --git a/doc/src/images/logo/rhai-logo-transparent-sil-white.svg b/doc/src/images/logo/rhai-logo-transparent-sil-white.svg
deleted file mode 100644
index 9eabc0d7..00000000
--- a/doc/src/images/logo/rhai-logo-transparent-sil-white.svg
+++ /dev/null
@@ -1,25 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/doc/src/images/logo/rhai-sil-black.png b/doc/src/images/logo/rhai-sil-black.png
deleted file mode 100644
index 92b0b7e6..00000000
Binary files a/doc/src/images/logo/rhai-sil-black.png and /dev/null differ
diff --git a/doc/src/images/logo/rhai-sil-black.svg b/doc/src/images/logo/rhai-sil-black.svg
deleted file mode 100644
index 8d4c9b32..00000000
--- a/doc/src/images/logo/rhai-sil-black.svg
+++ /dev/null
@@ -1,36 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/doc/src/images/logo/rhai-sil-white.png b/doc/src/images/logo/rhai-sil-white.png
deleted file mode 100644
index c1466588..00000000
Binary files a/doc/src/images/logo/rhai-sil-white.png and /dev/null differ
diff --git a/doc/src/images/logo/rhai-sil-white.svg b/doc/src/images/logo/rhai-sil-white.svg
deleted file mode 100644
index bdb09519..00000000
--- a/doc/src/images/logo/rhai-sil-white.svg
+++ /dev/null
@@ -1,29 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/doc/src/language/arrays.md b/doc/src/language/arrays.md
deleted file mode 100644
index 492800b9..00000000
--- a/doc/src/language/arrays.md
+++ /dev/null
@@ -1,218 +0,0 @@
-Arrays
-======
-
-{{#include ../links.md}}
-
-Arrays are first-class citizens in Rhai. Like C, arrays are accessed with zero-based, non-negative integer indices:
-
-> _array_ `[` _index_ `]`
-
-Array literals are built within square brackets '`[`' ... '`]`' and separated by commas '`,`':
-
-> `[` _value_ `,` _value_ `,` `...` `,` _value_ `]`
->
-> `[` _value_ `,` _value_ `,` `...` `,` _value_ `,` `]` `// trailing comma is OK`
-
-All elements stored in an array are [`Dynamic`], and the array can freely grow or shrink with elements added or removed.
-
-The Rust type of a Rhai array is `rhai::Array`.
-
-[`type_of()`] an array returns `"array"`.
-
-Arrays are disabled via the [`no_index`] feature.
-
-The maximum allowed size of an array can be controlled via `Engine::set_max_array_size`
-(see [maximum size of arrays].
-
-
-Built-in Functions
------------------
-
-The following methods (mostly defined in the [`BasicArrayPackage`][packages] but excluded if using a [raw `Engine`]) operate on arrays:
-
-| Function | Parameter(s) | Description |
-| ------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
-| `push` | element to insert | inserts an element at the end |
-| `append` | array to append | concatenates the second array to the end of the first |
-| `+=` operator | 1) array 2) element to insert (not another array) | inserts an element at the end |
-| `+=` operator | 1) array 2) array to append | concatenates the second array to the end of the first |
-| `+` operator | 1) first array 2) second array | concatenates the first array with the second |
-| `==` operator | 1) first array 2) second array | are the two arrays the same (elements compared with the `==` operator, if defined)? |
-| `!=` operator | 1) first array 2) second array | are the two arrays different (elements compared with the `==` operator, if defined)? |
-| `in` operator | item to find | does the array contain the item (compared with the `==` operator, if defined)? |
-| `insert` | 1) element to insert 2) position, beginning if < 0, end if > length | inserts an element at a certain index |
-| `pop` | _none_ | removes the last element and returns it ([`()`] if empty) |
-| `shift` | _none_ | removes the first element and returns it ([`()`] if empty) |
-| `extract` | 1) start position, beginning if < 0, end if > length 2) _(optional)_ number of items to extract, none if < 0 | extracts a portion of the array into a new array |
-| `remove` | index | removes an element at a particular index and returns it ([`()`] if the index is not valid) |
-| `reverse` | _none_ | reverses the array |
-| `len` method and property | _none_ | returns the number of elements |
-| `pad` | 1) target length 2) element to pad | pads the array with an element to at least a specified length |
-| `clear` | _none_ | empties the array |
-| `truncate` | target length | cuts off the array at exactly a specified length (discarding all subsequent elements) |
-| `chop` | target length | cuts off the head of the array, leaving the tail at exactly a specified length |
-| `drain` | 1) [function pointer] to predicate (usually a [closure]) 2) _(optional)_ [function pointer] to function (usually a [closure]) that provides the initial value | removes all items (returning them) that return `true` when called with the predicate function: 1st parameter: array item 2nd parameter: _(optional)_ offset index |
-| `drain` | 1) start position, beginning if < 0, end if > length 2) number of items to remove, none if < 0 | removes a portion of the array, returning the removed items (not in original order) |
-| `retain` | 1) [function pointer] to predicate (usually a [closure]) 2) _(optional)_ [function pointer] to function (usually a [closure]) that provides the initial value | removes all items (returning them) that do not return `true` when called with the predicate function: 1st parameter: array item 2nd parameter: _(optional)_ offset index |
-| `retain` | 1) start position, beginning if < 0, end if > length 2) number of items to retain, none if < 0 | retains a portion of the array, removes all other items and returning them (not in original order) |
-| `splice` | 1) start position, beginning if < 0, end if > length 2) number of items to remove, none if < 0 3) array to insert | replaces a portion of the array with another (not necessarily of the same length as the replaced portion) |
-| `filter` | [function pointer] to predicate (usually a [closure]) | constructs a new array with all items that return `true` when called with the predicate function: 1st parameter: array item 2nd parameter: _(optional)_ offset index |
-| `index_of` | [function pointer] to predicate (usually a [closure]) | returns the index of the first item in the array that returns `true` when called with the predicate function, or -1 if not found: 1st parameter: array item 2nd parameter: _(optional)_ offset index |
-| `map` | [function pointer] to conversion function (usually a [closure]) | constructs a new array with all items mapped to the result of applying the conversion function: 1st parameter: array item 2nd parameter: _(optional)_ offset index |
-| `reduce` | 1) [function pointer] to accumulator function (usually a [closure]) 2) _(optional)_ [function pointer] to function (usually a [closure]) that provides the initial value | reduces the array into a single value via the accumulator function: 1st parameter: accumulated value ([`()`] initially) 2nd parameter: array item 3rd parameter: _(optional)_ offset index |
-| `reduce_rev` | 1) [function pointer] to accumulator function (usually a [closure]) 2) _(optional)_ [function pointer] to function (usually a [closure]) that provides the initial value | reduces the array (in reverse order) into a single value via the accumulator function: 1st parameter: accumulated value ([`()`] initially) 2nd parameter: array item 3rd parameter: _(optional)_ offset index |
-| `some` | [function pointer] to predicate (usually a [closure]) | returns `true` if any item returns `true` when called with the predicate function: 1st parameter: array item 2nd parameter: _(optional)_ offset index |
-| `all` | [function pointer] to predicate (usually a [closure]) | returns `true` if all items return `true` when called with the predicate function: 1st parameter: array item 2nd parameter: _(optional)_ offset index |
-| `sort` | [function pointer] to a comparison function (usually a [closure]) | sorts the array with a comparison function: 1st parameter: first item 2nd parameter: second item return value: `INT` < 0 if first < second, > 0 if first > second, 0 if first == second |
-
-
-Use Custom Types With Arrays
----------------------------
-
-To use a [custom type] with arrays, a number of array functions need to be manually implemented,
-in particular `push`, `insert`, `pad` and the `+=` operator. In addition, the `==` operator must be
-implemented for the [custom type] in order to support the `in` operator which uses `==` to
-compare elements.
-
-See the section on [custom types] for more details.
-
-
-Examples
---------
-
-```rust
-let y = [2, 3]; // y == [2, 3]
-
-let y = [2, 3,]; // y == [2, 3]
-
-y.insert(0, 1); // y == [1, 2, 3]
-
-y.insert(999, 4); // y == [1, 2, 3, 4]
-
-y.len == 4;
-
-y[0] == 1;
-y[1] == 2;
-y[2] == 3;
-y[3] == 4;
-
-(1 in y) == true; // use 'in' to test if an item exists in the array
-(42 in y) == false; // 'in' uses the '==' operator (which users can override)
- // to check if the target item exists in the array
-
-y[1] = 42; // y == [1, 42, 3, 4]
-
-(42 in y) == true;
-
-y.remove(2) == 3; // y == [1, 42, 4]
-
-y.len == 3;
-
-y[2] == 4; // elements after the removed element are shifted
-
-ts.list = y; // arrays can be assigned completely (by value copy)
-
-ts.list[1] == 42;
-
-[1, 2, 3][0] == 1; // indexing on array literal
-
-fn abc() {
- [42, 43, 44] // a function returning an array
-}
-
-abc()[0] == 42;
-
-y.push(4); // y == [1, 42, 4, 4]
-
-y += 5; // y == [1, 42, 4, 4, 5]
-
-y.len == 5;
-
-y.shift() == 1; // y == [42, 4, 4, 5]
-
-y.chop(3); // y == [4, 4, 5]
-
-y.len == 3;
-
-y.pop() == 5; // y == [4, 4]
-
-y.len == 2;
-
-for item in y { // arrays can be iterated with a 'for' statement
- print(item);
-}
-
-y.pad(6, "hello"); // y == [4, 4, "hello", "hello", "hello", "hello"]
-
-y.len == 6;
-
-y.truncate(4); // y == [4, 4, "hello", "hello"]
-
-y.len == 4;
-
-y.clear(); // y == []
-
-y.len == 0;
-
-let a = [42, 123, 99];
-
-a.map(|v| v + 1); // returns [43, 124, 100]
-
-a.map(|v, i| v + i); // returns [42, 124, 101]
-
-a.filter(|v| v > 50); // returns [123, 99]
-
-a.filter(|v, i| i == 1); // returns [123]
-
-// Use a closure to provide the initial value
-a.reduce(|sum, v| sum + v, || 0) == 264;
-
-// Detect the initial value of '()'
-a.reduce(
- |sum, v| if sum.type_of() == "()" { v } else { sum + v }
-) == 264;
-
-// Detect the initial value via index
-a.reduce(|sum, v, i|
- if i == 0 { v } else { sum + v }
-) == 264;
-
-// Use a closure to provide the initial value
-a.reduce_rev(|sum, v| sum + v, || 0) == 264;
-
-// Detect the initial value of '()'
-a.reduce_rev(
- |sum, v| if sum.type_of() == "()" { v } else { sum + v }
-) == 264;
-
-// Detect the initial value via index
-a.reduce_rev(|sum, v, i|
- if i == 2 { v } else { sum + v }
-) == 264;
-
-a.some(|v| v > 50); // returns true
-
-a.some(|v, i| v < i); // returns false
-
-a.none(|v| v != 0); // returns false
-
-a.none(|v, i| v == i); // returns true
-
-a.all(|v| v > 50); // returns false
-
-a.all(|v, i| v > i); // returns true
-
-a.splice(1, 1, [1, 3, 2]); // a == [42, 1, 3, 2, 99]
-
-a.extract(1, 3); // returns [1, 3, 2]
-
-a.sort(|x, y| x - y); // a == [1, 2, 3, 42, 99]
-
-a.drain(|v| v <= 1); // a == [2, 3, 42, 99]
-
-a.drain(|v, i| i >= 3); // a == [2, 3, 42]
-
-a.retain(|v| v > 10); // a == [42]
-
-a.retain(|v, i| i > 0); // a == []
-```
diff --git a/doc/src/language/assignment-op.md b/doc/src/language/assignment-op.md
deleted file mode 100644
index 5cfd73c5..00000000
--- a/doc/src/language/assignment-op.md
+++ /dev/null
@@ -1,66 +0,0 @@
-Compound Assignment Operators
-=============================
-
-{{#include ../links.md}}
-
-
-```rust
-let number = 9;
-
-number += 8; // number = number + 8
-
-number -= 7; // number = number - 7
-
-number *= 6; // number = number * 6
-
-number /= 5; // number = number / 5
-
-number %= 4; // number = number % 4
-
-number ~= 3; // number = number ~ 3
-
-number <<= 2; // number = number << 2
-
-number >>= 1; // number = number >> 1
-
-number &= 0x00ff; // number = number & 0x00ff;
-
-number |= 0x00ff; // number = number | 0x00ff;
-
-number ^= 0x00ff; // number = number ^ 0x00ff;
-```
-
-
-The Flexible `+=`
-----------------
-
-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";
-my_str += "ABC";
-my_str += 12345;
-
-my_str == "abcABC12345"
-```
-
-to concatenate [arrays]:
-
-```rust
-let my_array = [1, 2, 3];
-my_array += [4, 5];
-
-my_array == [1, 2, 3, 4, 5];
-```
-
-and mix two [object maps] together:
-
-```rust
-let my_obj = #{a:1, b:2};
-my_obj += #{c:3, d:4, e:5};
-
-my_obj.len() == 5;
-```
diff --git a/doc/src/language/comments.md b/doc/src/language/comments.md
deleted file mode 100644
index 111e370c..00000000
--- a/doc/src/language/comments.md
+++ /dev/null
@@ -1,24 +0,0 @@
-Comments
-========
-
-{{#include ../links.md}}
-
-Comments are C-style, including '`/*` ... `*/`' pairs for block comments
-and '`//`' for comments to the end of the line.
-
-Comments can be nested.
-
-```rust
-let /* intruder comment */ name = "Bob";
-
-// This is a very important one-line comment
-
-/* This comment spans
- multiple lines, so it
- only makes sense that
- it is even more important */
-
-/* Fear not, Rhai satisfies all nesting needs with nested comments:
- /*/*/*/*/**/*/*/*/*/
-*/
-```
diff --git a/doc/src/language/constants.md b/doc/src/language/constants.md
deleted file mode 100644
index 31398f42..00000000
--- a/doc/src/language/constants.md
+++ /dev/null
@@ -1,97 +0,0 @@
-Constants
-=========
-
-{{#include ../links.md}}
-
-Constants can be defined using the `const` keyword and are immutable.
-
-Constants follow the same naming rules as [variables].
-
-```rust
-const x = 42;
-
-print(x * 2); // prints 84
-
-x = 123; // <- syntax error: cannot assign to constant
-```
-
-```rust
-const x; // 'x' is a constant '()'
-
-const x = 40 + 2; // 'x' is a constant 42
-```
-
-
-Manually Add Constant into Custom Scope
---------------------------------------
-
-It is possible to add a constant into a custom [`Scope`] so it'll be available to scripts
-running with that [`Scope`].
-
-When added to a custom [`Scope`], a constant can hold any value, not just a literal value.
-
-It is very useful to have a constant value hold a [custom type], which essentially acts
-as a [_singleton_](../patterns/singleton.md).
-
-```rust
-use rhai::{Engine, Scope, RegisterFn};
-
-#[derive(Debug, Clone)]
-struct TestStruct(i64); // custom type
-
-let mut engine = Engine::new();
-
-engine
- .register_type_with_name::("TestStruct") // register custom type
- .register_get("value", |obj: &mut TestStruct| obj.0), // property getter
- .register_fn("update_value",
- |obj: &mut TestStruct, value: i64| obj.0 = value // mutating method
- );
-
-let mut scope = Scope::new(); // create custom scope
-
-scope.push_constant("MY_NUMBER", TestStruct(123_i64)); // add constant variable
-
-// Beware: constant objects can still be modified via a method call!
-engine.consume_with_scope(&mut scope,
-r"
- MY_NUMBER.update_value(42);
- print(MY_NUMBER.value); // prints 42
-")?;
-```
-
-
-Caveat – Constants Can be Modified via Rust
-------------------------------------------------
-
-A custom type stored as a constant cannot be modified via script, but _can_ be modified via
-a registered Rust function that takes a first `&mut` parameter – because there is no way for
-Rhai to know whether the Rust function modifies its argument!
-
-```rust
-const x = 42; // a constant
-
-x.increment(); // call 'increment' defined in Rust with '&mut' first parameter
-
-x == 43; // value of 'x' is changed!
-
-fn double() {
- this *= 2; // function doubles 'this'
-}
-
-let y = 1; // 'y' is not constant and mutable
-
-y.double(); // double it...
-
-y == 2; // value of 'y' is changed as expected
-
-x.double(); // <- error: cannot modify constant 'this'
-
-x == 43; // value of 'x' is unchanged by script
-```
-
-This is important to keep in mind because the script [optimizer][script optimization]
-by default does _constant propagation_ as a operation.
-
-If a constant is eventually modified by a Rust function, the optimizer will not see
-the updated value and will propagate the original initialization value instead.
diff --git a/doc/src/language/convert.md b/doc/src/language/convert.md
deleted file mode 100644
index a14feed3..00000000
--- a/doc/src/language/convert.md
+++ /dev/null
@@ -1,56 +0,0 @@
-Value Conversions
-=================
-
-{{#include ../links.md}}
-
-
-Convert Between Integer and Floating-Point
------------------------------------------
-
-The `to_float` function converts a supported number to `FLOAT` (defaults to `f64`).
-
-The `to_int` function converts a supported number to `INT` (`i32` or `i64` depending on [`only_i32`]).
-
-That's it; for other conversions, register custom conversion functions.
-
-```rust
-let x = 42;
-
-let y = x * 100.0; // <- error: cannot multiply i64 with f64
-
-let y = x.to_float() * 100.0; // works
-
-let z = y.to_int() + x; // works
-
-let c = 'X'; // character
-
-print("c is '" + c + "' and its code is " + c.to_int()); // prints "c is 'X' and its code is 88"
-```
-
-
-Parse String into Number
-------------------------
-
-The `parse_float` function converts a [string] into a `FLOAT` (defaults to `f64`).
-
-The `parse_int` function converts a [string] into an `INT` (`i32` or `i64` depending on [`only_i32`]).
-An optional radix (2-36) can be provided to parse the [string] into a number of the specified radix.
-
-```rust
-let x = parse_float("123.4"); // parse as floating-point
-x == 123.4;
-type_of(x) == "f64";
-
-let dec = parse_int("42"); // parse as decimal
-let dec = parse_int("42", 10); // radix = 10 is the default
-dec == 42;
-type_of(dec) == "i64";
-
-let bin = parse_int("110", 2); // parse as binary (radix = 2)
-bin == 0b110;
-type_of(bin) == "i64";
-
-let hex = parse_int("ab", 16); // parse as hex (radix = 16)
-hex == 0xab;
-type_of(hex) == "i64";
-```
diff --git a/doc/src/language/do.md b/doc/src/language/do.md
deleted file mode 100644
index c1129944..00000000
--- a/doc/src/language/do.md
+++ /dev/null
@@ -1,28 +0,0 @@
-`do` Loop
-=========
-
-{{#include ../links.md}}
-
-`do` loops have two opposite variants: `do` ... `while` and `do` ... `until`.
-
-Like the `while` loop, `continue` can be used to skip to the next iteration, by-passing all following statements;
-`break` can be used to break out of the loop unconditionally.
-
-```rust
-let x = 10;
-
-do {
- x -= 1;
- if x < 6 { continue; } // skip to the next iteration
- print(x);
- if x == 5 { break; } // break out of do loop
-} while x > 0;
-
-
-do {
- x -= 1;
- if x < 6 { continue; } // skip to the next iteration
- print(x);
- if x == 5 { break; } // break out of do loop
-} until x == 0;
-```
diff --git a/doc/src/language/doc-comments.md b/doc/src/language/doc-comments.md
deleted file mode 100644
index a3fdcf91..00000000
--- a/doc/src/language/doc-comments.md
+++ /dev/null
@@ -1,77 +0,0 @@
-Doc-Comments
-============
-
-{{#include ../links.md}}
-
-Similar to Rust, comments starting with `///` (three slashes) or `/**` (two asterisks) are
-_doc-comments_.
-
-Doc-comments can only appear in front of [function] definitions, not any other elements:
-
-```rust
-/// This is a valid one-line doc-comment
-fn foo() {}
-
-/** This is a
- ** valid block
- ** doc-comment
- **/
-fn bar(x) {
- /// Syntax error - this doc-comment is invalid
- x + 1
-}
-
-/** Syntax error - this doc-comment is invalid */
-let x = 42;
-
-/// Syntax error - this doc-comment is also invalid
-{
- let x = 42;
-}
-```
-
-
-Special Cases
--------------
-
-Long streams of `//////...` and `/*****...` do _NOT_ form doc-comments.
-This is consistent with popular comment block styles for C-like languages.
-
-```rust
-/////////////////////////////// <- this is not a doc-comment
-// This is not a doc-comment // <- this is a normal comment
-/////////////////////////////// <- this is not a doc-comment
-
-// However, watch out for comment lines starting with '///'
-
-////////////////////////////////////////// <- this is not a doc-comment
-/// This, however, IS a doc-comment!!! /// <- this starts with '///'
-////////////////////////////////////////// <- this is not a doc-comment
-
-/****************************************
- * *
- * This is also not a doc-comment block *
- * so we don't have to put this in *
- * front of a function. *
- * *
- ****************************************/
-```
-
-
-Using Doc-Comments
-------------------
-
-Doc-comments are stored within the script's [`AST`] after compilation.
-
-The `AST::iter_functions` method provides a `ScriptFnMetadata` instance
-for each function defined within the script, which includes doc-comments.
-
-Doc-comments never affect the evaluation of a script nor do they incur
-significant performance overhead. However, third party tools can take advantage
-of this information to auto-generate documentation for Rhai script functions.
-
-
-Disabling Doc-Comments
-----------------------
-
-Doc-comments can be disabled via the `Engine::set_doc_comments` method.
diff --git a/doc/src/language/dynamic.md b/doc/src/language/dynamic.md
deleted file mode 100644
index 8c10d9f8..00000000
--- a/doc/src/language/dynamic.md
+++ /dev/null
@@ -1,100 +0,0 @@
-Dynamic Values
-==============
-
-{{#include ../links.md}}
-
-A `Dynamic` value can be _any_ type. However, under [`sync`], all types must be `Send + Sync`.
-
-
-Use `type_of()` to Get Value Type
---------------------------------
-
-Because [`type_of()`] a `Dynamic` value returns the type of the actual value,
-it is usually used to perform type-specific actions based on the actual value's type.
-
-```c
-let mystery = get_some_dynamic_value();
-
-switch type_of(mystery) {
- "i64" => print("Hey, I got an integer here!"),
- "f64" => print("Hey, I got a float here!"),
- "string" => print("Hey, I got a string here!"),
- "bool" => print("Hey, I got a boolean here!"),
- "array" => print("Hey, I got an array here!"),
- "map" => print("Hey, I got an object map here!"),
- "Fn" => print("Hey, I got a function pointer here!"),
- "TestStruct" => print("Hey, I got the TestStruct custom type here!"),
- _ => print("I don't know what this is: " + type_of(mystery))
-}
-```
-
-
-Functions Returning `Dynamic`
-----------------------------
-
-In Rust, sometimes a `Dynamic` forms part of a returned value – a good example is an [array]
-which contains `Dynamic` elements, or an [object map] which contains `Dynamic` property values.
-
-To get the _real_ values, the actual value types _must_ be known in advance.
-There is no easy way for Rust to decide, at run-time, what type the `Dynamic` value is
-(short of using the `type_name` function and match against the name).
-
-
-Type Checking and Casting
-------------------------
-
-A `Dynamic` value's actual type can be checked via the `is` method.
-
-The `cast` method then converts the value into a specific, known type.
-
-Alternatively, use the `try_cast` method which does not panic but returns `None` when the cast fails.
-
-```rust
-let list: Array = engine.eval("...")?; // return type is 'Array'
-let item = list[0]; // an element in an 'Array' is 'Dynamic'
-
-item.is::() == true; // 'is' returns whether a 'Dynamic' value is of a particular type
-
-let value = item.cast::(); // if the element is 'i64', this succeeds; otherwise it panics
-let value: i64 = item.cast(); // type can also be inferred
-
-let value = item.try_cast::()?; // 'try_cast' does not panic when the cast fails, but returns 'None'
-```
-
-Type Name
----------
-
-The `type_name` method gets the name of the actual type as a static string slice,
-which can be `match`-ed against.
-
-```rust
-let list: Array = engine.eval("...")?; // return type is 'Array'
-let item = list[0]; // an element in an 'Array' is 'Dynamic'
-
-match item.type_name() { // 'type_name' returns the name of the actual Rust type
- "i64" => ...
- "alloc::string::String" => ...
- "bool" => ...
- "crate::path::to::module::TestStruct" => ...
-}
-```
-
-**Note:** `type_name` always returns the _full_ Rust path name of the type, even when the type
-has been registered with a friendly name via `Engine::register_type_with_name`. This behavior
-is different from that of the [`type_of`][`type_of()`] function in Rhai.
-
-
-Conversion Traits
-----------------
-
-The following conversion traits are implemented for `Dynamic`:
-
-* `From` (`i32` if [`only_i32`])
-* `From` (if not [`no_float`])
-* `From`
-* `From`
-* `From`
-* `From`
-* `From>` (into an [array])
-* `From>` (into an [object map])
-* `From` (into a [timestamp] if not [`no_std`])
diff --git a/doc/src/language/eval.md b/doc/src/language/eval.md
deleted file mode 100644
index 7e9bdd4d..00000000
--- a/doc/src/language/eval.md
+++ /dev/null
@@ -1,83 +0,0 @@
-`eval` Function
-===============
-
-{{#include ../links.md}}
-
-Or "How to Shoot Yourself in the Foot even Easier"
-------------------------------------------------
-
-Saving the best for last, there is the ever-dreaded... `eval` function!
-
-```rust
-let x = 10;
-
-fn foo(x) { x += 12; x }
-
-let script = "let y = x;"; // build a script
-script += "y += foo(y);";
-script += "x + y";
-
-let result = eval(script); // <- look, JavaScript, we can also do this!
-
-result == 42;
-
-x == 10; // prints 10: functions call arguments are passed by value
-y == 32; // prints 32: variables defined in 'eval' persist!
-
-eval("{ let z = y }"); // to keep a variable local, use a statement block
-
-print(z); // <- error: variable 'z' not found
-
-"print(42)".eval(); // <- nope... method-call style doesn't work with 'eval'
-```
-
-Script segments passed to `eval` execute inside the current [`Scope`], so they can access and modify _everything_,
-including all variables that are visible at that position in code! It is almost as if the script segments were
-physically pasted in at the position of the `eval` call.
-
-
-Cannot Define New Functions
---------------------------
-
-New functions cannot be defined within an `eval` call, since functions can only be defined at the _global_ level,
-not inside another function call!
-
-```rust
-let script = "x += 32";
-let x = 10;
-eval(script); // variable 'x' in the current scope is visible!
-print(x); // prints 42
-
-// The above is equivalent to:
-let script = "x += 32";
-let x = 10;
-x += 32;
-print(x);
-```
-
-
-`eval` is Evil
---------------
-
-For those who subscribe to the (very sensible) motto of ["`eval` is evil"](http://linterrors.com/js/eval-is-evil),
-disable `eval` using [`Engine::disable_symbol`][disable keywords and operators]:
-
-```rust
-engine.disable_symbol("eval"); // disable usage of 'eval'
-```
-
-`eval` can also be disabled by overloading it, probably with something that throws:
-
-```rust
-fn eval(script) { throw "eval is evil! I refuse to run " + script }
-
-let x = eval("40 + 2"); // throws "eval is evil! I refuse to run 40 + 2"
-```
-
-Or overload it from Rust:
-
-```rust
-engine.register_result_fn("eval", |script: String| -> Result<(), Box> {
- Err(format!("eval is evil! I refuse to run {}", script).into())
-});
-```
diff --git a/doc/src/language/fn-anon.md b/doc/src/language/fn-anon.md
deleted file mode 100644
index a2e45706..00000000
--- a/doc/src/language/fn-anon.md
+++ /dev/null
@@ -1,60 +0,0 @@
-Anonymous Functions
-===================
-
-{{#include ../links.md}}
-
-Sometimes it gets tedious to define separate functions only to dispatch them via single [function pointers].
-This scenario is especially common when simulating object-oriented programming ([OOP]).
-
-```rust
-// Define object
-let obj = #{
- data: 42,
- increment: Fn("inc_obj"), // use function pointers to
- decrement: Fn("dec_obj"), // refer to method functions
- print: Fn("print_obj")
-};
-
-// Define method functions one-by-one
-fn inc_obj(x) { this.data += x; }
-fn dec_obj(x) { this.data -= x; }
-fn print_obj() { print(this.data); }
-```
-
-The above can be replaced by using _anonymous functions_ which have the same syntax as Rust's closures
-(but they are **NOT** real closures, merely syntactic sugar):
-
-```rust
-let obj = #{
- data: 42,
- increment: |x| this.data += x, // one-liner
- decrement: |x| this.data -= x,
- print_obj: || { print(this.data); } // full function body
-};
-```
-
-The anonymous functions will be hoisted into separate functions in the global namespace.
-The above is equivalent to:
-
-```rust
-let obj = #{
- data: 42,
- increment: Fn("anon_fn_1000"),
- decrement: Fn("anon_fn_1001"),
- print: Fn("anon_fn_1002")
-};
-
-fn anon_fn_1000(x) { this.data += x; }
-fn anon_fn_1001(x) { this.data -= x; }
-fn anon_fn_1002() { print this.data; }
-```
-
-
-WARNING – NOT Real Closures
---------------------------------
-
-Remember: anonymous functions, though having the same syntax as Rust _closures_, are themselves
-**not** real closures.
-
-In particular, they capture their execution environment via [automatic currying]
-(disabled via [`no_closure`]).
diff --git a/doc/src/language/fn-capture.md b/doc/src/language/fn-capture.md
deleted file mode 100644
index 599b211d..00000000
--- a/doc/src/language/fn-capture.md
+++ /dev/null
@@ -1,71 +0,0 @@
-Capture The Calling Scope for Function Call
-==========================================
-
-{{#include ../links.md}}
-
-
-Peeking Out of The Pure Box
----------------------------
-
-Rhai functions are _pure_, meaning that they depend on on their arguments and have no
-access to the calling environment.
-
-When a function accesses a variable that is not defined within that function's scope,
-it raises an evaluation error.
-
-It is possible, through a special syntax, to capture the calling scope – i.e. the scope
-that makes the function call – and access variables defined there.
-
-```rust
-fn foo(y) { // function accesses 'x' and 'y', but 'x' is not defined
- x += y; // 'x' is modified in this function
- x
-}
-
-let x = 1;
-
-foo(41); // error: variable 'x' not found
-
-// Calling a function with a '!' causes it to capture the calling scope
-
-foo!(41) == 42; // the function can access the value of 'x', but cannot change it
-
-x == 1; // 'x' is still the original value
-
-x.method!(); // <- syntax error: capturing is not allowed in method-call style
-
-// Capturing also works for function pointers
-
-let f = Fn("foo");
-
-call!(f, 41) == 42; // must use function-call style
-
-f.call!(41); // <- syntax error: capturing is not allowed in method-call style
-
-// Capturing is not available for module functions
-
-import "hello" as h;
-
-h::greet!(); // <- syntax error: capturing is not allowed in namespace-qualified calls
-```
-
-
-No Mutations
-------------
-
-Variables in the calling scope are captured as cloned copies.
-Changes to them do **not** reflect back to the calling scope.
-
-Rhai functions remain _pure_ in the sense that they can never mutate their environment.
-
-
-Caveat Emptor
--------------
-
-Functions relying on the calling scope is often a _Very Bad Idea™_ because it makes code
-almost impossible to reason and maintain, as their behaviors are volatile and unpredictable.
-
-They behave more like macros that are expanded inline than actual function calls, thus the
-syntax is also similar to Rust's macro invocations.
-
-This usage should be at the last resort. YOU HAVE BEEN WARNED.
diff --git a/doc/src/language/fn-closure.md b/doc/src/language/fn-closure.md
deleted file mode 100644
index 985a67f3..00000000
--- a/doc/src/language/fn-closure.md
+++ /dev/null
@@ -1,192 +0,0 @@
-Simulating Closures
-===================
-
-{{#include ../links.md}}
-
-Capture External Variables via Automatic Currying
-------------------------------------------------
-
-Since [anonymous functions] de-sugar to standard function definitions, they retain all the behaviors of
-Rhai functions, including being _pure_, having no access to external variables.
-
-The anonymous function syntax, however, automatically _captures_ variables that are not defined within
-the current scope, but are defined in the external scope – i.e. the scope where the anonymous function
-is created.
-
-Variables that are accessible during the time the [anonymous function] is created can be captured,
-as long as they are not shadowed by local variables defined within the function's scope.
-
-The captured variables are automatically converted into **reference-counted shared values**
-(`Rc>` in normal builds, `Arc>` in [`sync`] builds).
-
-Therefore, similar to closures in many languages, these captured shared values persist through
-reference counting, and may be read or modified even after the variables that hold them
-go out of scope and no longer exist.
-
-Use the `Dynamic::is_shared` function to check whether a particular value is a shared value.
-
-Automatic currying can be turned off via the [`no_closure`] feature.
-
-
-Examples
---------
-
-```rust
-let x = 1; // a normal variable
-
-x.is_shared() == false;
-
-let f = |y| x + y; // variable 'x' is auto-curried (captured) into 'f'
-
-x.is_shared() == true; // 'x' is now a shared value!
-
-f.call(2) == 3; // 1 + 2 == 3
-
-x = 40; // changing 'x'...
-
-f.call(2) == 42; // the value of 'x' is 40 because 'x' is shared
-
-// The above de-sugars into this:
-fn anon$1001(x, y) { x + y } // parameter 'x' is inserted
-
-$make_shared(x); // convert variable 'x' into a shared value
-
-let f = Fn("anon$1001").curry(x); // shared 'x' is curried
-
-f.call(2) == 42;
-```
-
-
-Beware: Captured Variables are Truly Shared
-------------------------------------------
-
-The example below is a typical tutorial sample for many languages to illustrate the traps
-that may accompany capturing external scope variables in closures.
-
-It prints `9`, `9`, `9`, ... `9`, `9`, not `0`, `1`, `2`, ... `8`, `9`, because there is
-ever only _one_ captured variable, and all ten closures capture the _same_ variable.
-
-```rust
-let funcs = [];
-
-for i in range(0, 10) {
- funcs.push(|| print(i)); // the for loop variable 'i' is captured
-}
-
-funcs.len() == 10; // 10 closures stored in the array
-
-funcs[0].type_of() == "Fn"; // make sure these are closures
-
-for f in funcs {
- f.call(); // all references to 'i' are the same variable!
-}
-```
-
-
-Therefore – Be Careful to Prevent Data Races
--------------------------------------------------
-
-Rust does not have data races, but that doesn't mean Rhai doesn't.
-
-Avoid performing a method call on a captured shared variable (which essentially takes a
-mutable reference to the shared object) while using that same variable as a parameter
-in the method call – this is a sure-fire way to generate a data race error.
-
-If a shared value is used as the `this` pointer in a method call to a closure function,
-then the same shared value _must not_ be captured inside that function, or a data race
-will occur and the script will terminate with an error.
-
-```rust
-let x = 20;
-
-x.is_shared() == false; // 'x' is not shared, so no data race is possible
-
-let f = |a| this += x + a; // 'x' is captured in this closure
-
-x.is_shared() == true; // now 'x' is shared
-
-x.call(f, 2); // <- error: data race detected on 'x'
-```
-
-
-Data Races in `sync` Builds Can Become Deadlocks
------------------------------------------------
-
-Under the [`sync`] feature, shared values are guarded with a `RwLock`, meaning that data race
-conditions no longer raise an error.
-
-Instead, they wait endlessly for the `RwLock` to be freed, and thus can become deadlocks.
-
-On the other hand, since the same thread (i.e. the [`Engine`] thread) that is holding the lock
-is attempting to read it again, this may also [panic](https://doc.rust-lang.org/std/sync/struct.RwLock.html#panics-1)
-depending on the O/S.
-
-```rust
-let x = 20;
-
-let f = |a| this += x + a; // 'x' is captured in this closure
-
-// Under `sync`, the following may wait forever, or may panic,
-// because 'x' is locked as the `this` pointer but also accessed
-// via a captured shared value.
-x.call(f, 2);
-```
-
-
-TL;DR
------
-
-### Q: How is it actually implemented?
-
-The actual implementation of closures de-sugars to:
-
-1. Keeping track of what variables are accessed inside the anonymous function,
-
-2. If a variable is not defined within the anonymous function's scope, it is looked up _outside_ the function and
- in the current execution scope – where the anonymous function is created.
-
-3. The variable is added to the parameters list of the anonymous function, at the front.
-
-4. The variable is then converted into a **reference-counted shared value**.
-
- An [anonymous function] which captures an external variable is the only way to create a reference-counted shared value in Rhai.
-
-5. The shared value is then [curried][currying] into the [function pointer] itself, essentially carrying a reference to that shared value
- and inserting it into future calls of the function.
-
- This process is called _Automatic Currying_, and is the mechanism through which Rhai simulates normal closures.
-
-### Q: Why are closures implemented as automatic currying?
-
-In concept, a closure _closes_ over captured variables from the outer scope – that's why
-they are called _closures_. When this happen, a typical language implementation hoists
-those variables that are captured away from the stack frame and into heap-allocated storage.
-This is because those variables may be needed after the stack frame goes away.
-
-These heap-allocated captured variables only go away when all the closures that need them
-are finished with them. A garbage collector makes this trivial to implement – they are
-automatically collected as soon as all closures needing them are destroyed.
-
-In Rust, this can be done by reference counting instead, with the potential pitfall of creating
-reference loops that will prevent those variables from being deallocated forever.
-Rhai avoids this by clone-copying most data values, so reference loops are hard to create.
-
-Rhai does the hoisting of captured variables into the heap by converting those values
-into reference-counted locked values, also allocated on the heap. The process is identical.
-
-Closures are usually implemented as a data structure containing two items:
-
-1) A function pointer to the function body of the closure,
-2) A data structure containing references to the captured shared variables on the heap.
-
-Usually a language implementation passes the structure containing references to captured
-shared variables into the function pointer, the function body taking this data structure
-as an additional parameter.
-
-This is essentially what Rhai does, except that Rhai passes each variable individually
-as separate parameters to the function, instead of creating a structure and passing that
-structure as a single parameter. This is the only difference.
-
-Therefore, in most languages, essentially all closures are implemented as automatic currying of
-shared variables hoisted into the heap, automatically passing those variables as parameters into
-the function. Rhai just brings this directly up to the front.
diff --git a/doc/src/language/fn-curry.md b/doc/src/language/fn-curry.md
deleted file mode 100644
index c223d8cd..00000000
--- a/doc/src/language/fn-curry.md
+++ /dev/null
@@ -1,39 +0,0 @@
-Function Pointer Currying
-========================
-
-{{#include ../links.md}}
-
-It is possible to _curry_ a [function pointer] by providing partial (or all) arguments.
-
-Currying is done via the `curry` keyword and produces a new [function pointer] which carries
-the curried arguments.
-
-When the curried [function pointer] is called, the curried arguments are inserted starting from the left.
-The actual call arguments should be reduced by the number of curried arguments.
-
-```rust
-fn mul(x, y) { // function with two parameters
- x * y
-}
-
-let func = Fn("mul");
-
-func.call(21, 2) == 42; // two arguments are required for 'mul'
-
-let curried = func.curry(21); // currying produces a new function pointer which
- // carries 21 as the first argument
-
-let curried = curry(func, 21); // function-call style also works
-
-curried.call(2) == 42; // <- de-sugars to 'func.call(21, 2)'
- // only one argument is now required
-```
-
-
-Automatic Currying
-------------------
-
-[Anonymous functions] defined via a closure syntax _capture_ external variables
-that are not shadowed inside the function's scope.
-
-This is accomplished via [automatic currying].
diff --git a/doc/src/language/fn-namespaces.md b/doc/src/language/fn-namespaces.md
deleted file mode 100644
index 47489acf..00000000
--- a/doc/src/language/fn-namespaces.md
+++ /dev/null
@@ -1,119 +0,0 @@
-Function Namespaces
-==================
-
-{{#include ../links.md}}
-
-Each Function is a Separate Compilation Unit
--------------------------------------------
-
-[Functions] in Rhai are _pure_ and they form individual _compilation units_.
-This means that individual functions can be separated, exported, re-grouped, imported,
-and generally mix-'n-match-ed with other completely unrelated scripts.
-
-For example, the `AST::merge` and `AST::combine` methods (or the equivalent `+` and `+=` operators)
-allow combining all functions in one [`AST`] into another, forming a new, unified, group of functions.
-
-In general, there are two types of _namespaces_ where functions are looked up:
-
-| Namespace | How Many | Source | Lookup | Sub-modules? | Variables? |
-| --------- | :------: | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------ | :----------: | :--------: |
-| Global | One | 1) [`AST`] being evaluated 2) `Engine::register_XXX` API 3) global [modules] registered via `Engine::register_global_module` 4) functions in static [modules] registered via `Engine::register_static_module` and marked _global_ | simple name | ignored | ignored |
-| Module | Many | 1) [Module] registered via `Engine::register_static_module` 2) [Module] loaded via [`import`] statement | namespace-qualified name | yes | yes |
-
-
-Module Namespaces
------------------
-
-There can be multiple module namespaces at any time during a script evaluation, usually loaded via the
-[`import`] statement.
-
-_Static_ module namespaces can also be registered into an [`Engine`] via `Engine::register_static_module`.
-
-Functions and variables in module namespaces are isolated and encapsulated within their own environments.
-
-They must be called or accessed in a _namespace-qualified_ manner.
-
-```rust
-import "my_module" as m; // new module namespace 'm' created via 'import'
-
-let x = m::calc_result(); // namespace-qualified function call
-
-let y = m::MY_NUMBER; // namespace-qualified variable (constant) access
-
-let x = calc_result(); // <- error: function 'calc_result' not found
- // in global namespace!
-```
-
-
-Global Namespace
-----------------
-
-There is one _global_ namespace for every [`Engine`], which includes (in the following search order):
-
-* All functions defined in the [`AST`] currently being evaluated.
-
-* All native Rust functions and iterators registered via the `Engine::register_XXX` API.
-
-* All functions and iterators defined in global [modules] that are registered into the [`Engine`] via
- `Engine::register_global_module`.
-
-* Functions defined in [modules] registered via `Engine::register_static_module` that are specifically
- marked for exposure to the global namespace (e.g. via the `#[rhai(global)]` attribute in a [plugin module]).
-
-Anywhere in a Rhai script, when a function call is made, the function is searched within the
-global namespace, in the above search order.
-
-Therefore, function calls in Rhai are _late_ bound – meaning that the function called cannot be
-determined or guaranteed and there is no way to _lock down_ the function being called.
-This aspect is very similar to JavaScript before ES6 modules.
-
-```rust
-// Compile a script into AST
-let ast1 = engine.compile(
- r#"
- fn get_message() {
- "Hello!" // greeting message
- }
-
- fn say_hello() {
- print(get_message()); // prints message
- }
-
- say_hello();
- "#
-)?;
-
-// Compile another script with an overriding function
-let ast2 = engine.compile(r#"fn get_message() { "Boo!" }"#)?;
-
-// Combine the two AST's
-ast1 += ast2; // 'message' will be overwritten
-
-engine.consume_ast(&ast1)?; // prints 'Boo!'
-```
-
-Therefore, care must be taken when _cross-calling_ functions to make sure that the correct
-functions are called.
-
-The only practical way to ensure that a function is a correct one is to use [modules] -
-i.e. define the function in a separate module and then [`import`] it:
-
-```rust
-----------------
-| message.rhai |
-----------------
-
-fn get_message() { "Hello!" }
-
-
----------------
-| script.rhai |
----------------
-
-import "message" as msg;
-
-fn say_hello() {
- print(msg::get_message());
-}
-say_hello();
-```
diff --git a/doc/src/language/fn-ptr.md b/doc/src/language/fn-ptr.md
deleted file mode 100644
index 4717504a..00000000
--- a/doc/src/language/fn-ptr.md
+++ /dev/null
@@ -1,271 +0,0 @@
-Function Pointers
-=================
-
-{{#include ../links.md}}
-
-It is possible to store a _function pointer_ in a variable just like a normal value.
-In fact, internally a function pointer simply stores the _name_ of the function as a string.
-
-A function pointer is created via the `Fn` function, which takes a [string] parameter.
-
-Call a function pointer using the `call` method.
-
-
-Built-in methods
-----------------
-
-The following standard methods (mostly defined in the [`BasicFnPackage`][packages] but excluded if
-using a [raw `Engine`]) operate on function pointers:
-
-| Function | Parameter(s) | Description |
-| ---------------------------------- | ------------ | ------------------------------------------------------------------------------------------------ |
-| `name` method and property | _none_ | returns the name of the function encapsulated by the function pointer |
-| `is_anonymous` method and property | _none_ | does the function pointer refer to an [anonymous function]? Not available under [`no_function`]. |
-| `call` | _arguments_ | calls the function matching the function pointer's name with the _arguments_ |
-
-
-Examples
---------
-
-```rust
-fn foo(x) { 41 + x }
-
-let func = Fn("foo"); // use the 'Fn' function to create a function pointer
-
-print(func); // prints 'Fn(foo)'
-
-let func = fn_name.Fn(); // <- error: 'Fn' cannot be called in method-call style
-
-func.type_of() == "Fn"; // type_of() as function pointer is 'Fn'
-
-func.name == "foo";
-
-func.call(1) == 42; // call a function pointer with the 'call' method
-
-foo(1) == 42; // <- the above de-sugars to this
-
-call(func, 1); // normal function call style also works for 'call'
-
-let len = Fn("len"); // 'Fn' also works with registered native Rust functions
-
-len.call("hello") == 5;
-
-let add = Fn("+"); // 'Fn' works with built-in operators also
-
-add.call(40, 2) == 42;
-
-let fn_name = "hello"; // the function name does not have to exist yet
-
-let hello = Fn(fn_name + "_world");
-
-hello.call(0); // error: function not found - 'hello_world (i64)'
-```
-
-
-Global Namespace Only
---------------------
-
-Because of their dynamic nature, function pointers cannot refer to functions in [`import`]-ed [modules].
-They can only refer to functions within the global [namespace][function namespace].
-See _[Function Namespaces]_ for more details.
-
-```rust
-import "foo" as f; // assume there is 'f::do_work()'
-
-f::do_work(); // works!
-
-let p = Fn("f::do_work"); // error: invalid function name
-
-fn do_work_now() { // call it from a local function
- f::do_work();
-}
-
-let p = Fn("do_work_now");
-
-p.call(); // works!
-```
-
-
-Dynamic Dispatch
-----------------
-
-The purpose of function pointers is to enable rudimentary _dynamic dispatch_, meaning to determine,
-at runtime, which function to call among a group.
-
-Although it is possible to simulate dynamic dispatch via a number and a large `if-then-else-if` statement,
-using function pointers significantly simplifies the code.
-
-```rust
-let x = some_calculation();
-
-// These are the functions to call depending on the value of 'x'
-fn method1(x) { ... }
-fn method2(x) { ... }
-fn method3(x) { ... }
-
-// Traditional - using decision variable
-let func = sign(x);
-
-// Dispatch with if-statement
-if func == -1 {
- method1(42);
-} else if func == 0 {
- method2(42);
-} else if func == 1 {
- method3(42);
-}
-
-// Using pure function pointer
-let func = if x < 0 {
- Fn("method1")
-} else if x == 0 {
- Fn("method2")
-} else if x > 0 {
- Fn("method3")
-}
-
-// Dynamic dispatch
-func.call(42);
-
-// Using functions map
-let map = [ Fn("method1"), Fn("method2"), Fn("method3") ];
-
-let func = sign(x) + 1;
-
-// Dynamic dispatch
-map[func].call(42);
-```
-
-
-Bind the `this` Pointer
-----------------------
-
-When `call` is called as a _method_ but not on a function pointer, it is possible to dynamically dispatch
-to a function call while binding the object in the method call to the `this` pointer of the function.
-
-To achieve this, pass the function pointer as the _first_ argument to `call`:
-
-```rust
-fn add(x) { // define function which uses 'this'
- this += x;
-}
-
-let func = Fn("add"); // function pointer to 'add'
-
-func.call(1); // error: 'this' pointer is not bound
-
-let x = 41;
-
-func.call(x, 1); // error: function 'add (i64, i64)' not found
-
-call(func, x, 1); // error: function 'add (i64, i64)' not found
-
-x.call(func, 1); // 'this' is bound to 'x', dispatched to 'func'
-
-x == 42;
-```
-
-Beware that this only works for _method-call_ style. Normal function-call style cannot bind
-the `this` pointer (for syntactic reasons).
-
-Therefore, obviously, binding the `this` pointer is unsupported under [`no_object`].
-
-
-Call a Function Pointer in Rust
-------------------------------
-
-It is completely normal to register a Rust function with an [`Engine`] that takes parameters
-whose types are function pointers. The Rust type in question is `rhai::FnPtr`.
-
-A function pointer in Rhai is essentially syntactic sugar wrapping the _name_ of a function
-to call in script. Therefore, the script's [`AST`] is required to call a function pointer,
-as well as the entire _execution context_ that the script is running in.
-
-For a rust function taking a function pointer as parameter, the [Low-Level API](../rust/register-raw.md)
-must be used to register the function.
-
-Essentially, use the low-level `Engine::register_raw_fn` method to register the function.
-`FnPtr::call_dynamic` is used to actually call the function pointer, passing to it the
-current _native call context_, the `this` pointer, and other necessary arguments.
-
-```rust
-use rhai::{Engine, Module, Dynamic, FnPtr, NativeCallContext};
-
-let mut engine = Engine::new();
-
-// Define Rust function in required low-level API signature
-fn call_fn_ptr_with_value(context: NativeCallContext, args: &mut [&mut Dynamic])
- -> Result>
-{
- // 'args' is guaranteed to contain enough arguments of the correct types
- let fp = std::mem::take(args[1]).cast::(); // 2nd argument - function pointer
- let value = args[2].clone(); // 3rd argument - function argument
- let this_ptr = args.get_mut(0).unwrap(); // 1st argument - this pointer
-
- // Use 'FnPtr::call_dynamic' to call the function pointer.
- // Beware, private script-defined functions will not be found.
- fp.call_dynamic(context, Some(this_ptr), [value])
-}
-
-// Register a Rust function using the low-level API
-engine.register_raw_fn("super_call",
- &[ // parameter types
- std::any::TypeId::of::(),
- std::any::TypeId::of::(),
- std::any::TypeId::of::()
- ],
- call_fn_ptr_with_value
-);
-```
-
-
-`NativeCallContext`
-------------------
-
-`FnPtr::call_dynamic` takes a parameter of type `NativeCallContext` which holds the _native call context_
-of the particular call to a registered Rust function. It is a type that exposes the following:
-
-| Field | Type | Description |
-| ------------------- | :-------------------------------------: | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
-| `engine()` | `&Engine` | the current [`Engine`], with all configurations and settings. This is sometimes useful for calling a script-defined function within the same evaluation context using [`Engine::call_fn`][`call_fn`], or calling a [function pointer]. |
-| `source()` | `Option<&str>` | reference to the current source, if any |
-| `iter_imports()` | `impl Iterator- ` | iterator of the current stack of [modules] imported via `import` statements |
-| `imports()` | `&Imports` | reference to the current stack of [modules] imported via `import` statements; requires the [`internals`] feature |
-| `iter_namespaces()` | `impl Iterator
- ` | iterator of the namespaces (as [modules]) containing all script-defined functions |
-| `namespaces()` | `&[&Module]` | reference to the namespaces (as [modules]) containing all script-defined functions; requires the [`internals`] feature |
-
-
-This type is normally provided by the [`Engine`] (e.g. when using [`Engine::register_fn_raw`](../rust/register-raw.md)).
-However, it may also be manually constructed from a tuple:
-
-```rust
-use rhai::{Engine, FnPtr, NativeCallContext};
-
-let engine = Engine::new();
-
-// Compile script to AST
-let mut ast = engine.compile(
- r#"
- let test = "hello";
- |x| test + x // this creates an closure
- "#,
-)?;
-
-// Save the closure together with captured variables
-let fn_ptr = engine.eval_ast::
(&ast)?;
-
-// Get rid of the script, retaining only functions
-ast.retain_functions(|_, _, _| true);
-
-// Create function namespace from the 'AST'
-let lib = [ast.as_ref()];
-
-// Create native call context
-let context = NativeCallContext::new(&engine, &lib);
-
-// 'f' captures: the engine, the AST, and the closure
-let f = move |x: i64| fn_ptr.call_dynamic(context, None, [x.into()]);
-
-// 'f' can be called like a normal function
-let result = f(42)?;
-```
diff --git a/doc/src/language/for.md b/doc/src/language/for.md
deleted file mode 100644
index 6af5a422..00000000
--- a/doc/src/language/for.md
+++ /dev/null
@@ -1,103 +0,0 @@
-`for` Loop
-==========
-
-{{#include ../links.md}}
-
-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;
-`break` can be used to break out of the loop unconditionally.
-
-To loop through a number sequence (with or without steps), use the `range` function to
-return a numeric iterator.
-
-
-Iterate Through Strings
------------------------
-
-Iterating through a [string] yields characters.
-
-```rust
-let s = "hello, world!";
-
-for ch in s {
- if ch > 'z' { continue; } // skip to the next iteration
-
- print(ch);
-
- if x == '@' { break; } // break out of for loop
-}
-```
-
-
-Iterate Through Arrays
-----------------------
-
-Iterating through an [array] yields cloned _copies_ of each element.
-
-```rust
-let array = [1, 3, 5, 7, 9, 42];
-
-for x in array {
- if x > 10 { continue; } // skip to the next iteration
-
- print(x);
-
- if x == 42 { break; } // break out of for loop
-}
-```
-
-
-Iterate Through Numeric Ranges
------------------------------
-
-The `range` function allows iterating through a range of numbers
-(not including the last number).
-
-```rust
-// Iterate starting from 0 and stopping at 49.
-for x in range(0, 50) {
- if x > 10 { continue; } // skip to the next iteration
-
- print(x);
-
- if x == 42 { break; } // break out of for loop
-}
-
-// The 'range' function also takes a step.
-for x in range(0, 50, 3) { // step by 3
- if x > 10 { continue; } // skip to the next iteration
-
- print(x);
-
- if x == 42 { break; } // break out of for loop
-}
-```
-
-
-Iterate Through Object Maps
---------------------------
-
-Two methods, `keys` and `values`, return [arrays] containing cloned _copies_
-of all property names and values of an [object map], respectively.
-
-These [arrays] can be iterated.
-
-```rust
-let map = #{a:1, b:3, c:5, d:7, e:9};
-
-// Property names are returned in unsorted, random order
-for x in map.keys() {
- if x > 10 { continue; } // skip to the next iteration
-
- print(x);
-
- if x == 42 { break; } // break out of for loop
-}
-
-// Property values are returned in unsorted, random order
-for val in map.values() {
- print(val);
-}
-```
diff --git a/doc/src/language/functions.md b/doc/src/language/functions.md
deleted file mode 100644
index d7f9917d..00000000
--- a/doc/src/language/functions.md
+++ /dev/null
@@ -1,190 +0,0 @@
-Functions
-=========
-
-{{#include ../links.md}}
-
-Rhai supports defining functions in script (unless disabled with [`no_function`]):
-
-```rust
-fn add(x, y) {
- return x + y;
-}
-
-fn sub(x, y,) { // trailing comma in parameters list is OK
- return x - y;
-}
-
-add(2, 3) == 5;
-
-sub(2, 3,) == -1; // trailing comma in arguments list is OK
-```
-
-
-Implicit Return
----------------
-
-Just like in Rust, an implicit return can be used. In fact, the last statement of a block is _always_ the block's return value
-regardless of whether it is terminated with a semicolon `';'`. This is different from Rust.
-
-```rust
-fn add(x, y) { // implicit return:
- x + y; // value of the last statement (no need for ending semicolon)
- // is used as the return value
-}
-
-fn add2(x) {
- return x + 2; // explicit return
-}
-
-add(2, 3) == 5;
-
-add2(42) == 44;
-```
-
-
-Global Definitions Only
-----------------------
-
-Functions can only be defined at the global level, never inside a block or another function.
-
-```rust
-// Global level is OK
-fn add(x, y) {
- x + y
-}
-
-// The following will not compile
-fn do_addition(x) {
- fn add_y(n) { // <- syntax error: functions cannot be defined inside another function
- n + y
- }
-
- add_y(x)
-}
-```
-
-
-No Access to External Scope
---------------------------
-
-Functions are not _closures_. They do not capture the calling environment
-and can only access their own parameters.
-They cannot access variables external to the function itself.
-
-```rust
-let x = 42;
-
-fn foo() { x } // <- syntax error: variable 'x' doesn't exist
-```
-
-
-But Can Call Other Functions
----------------------------
-
-All functions in the same [`AST`] can call each other.
-
-```rust
-fn foo(x) { x + 1 } // function defined in the global namespace
-
-fn bar(x) { foo(x) } // OK! function 'foo' can be called
-```
-
-
-Use Before Definition Allowed
-----------------------------
-
-Unlike C/C++, functions in Rhai can be defined _anywhere_ at global level.
-
-A function does not need to be defined prior to being used in a script;
-a statement in the script can freely call a function defined afterwards.
-
-This is similar to Rust and many other modern languages, such as JavaScript's `function` keyword.
-
-
-Arguments are Passed by Value
-----------------------------
-
-Functions defined in script always take [`Dynamic`] parameters (i.e. they can be of any types).
-Therefore, functions with the same name and same _number_ of parameters are equivalent.
-
-All arguments are passed by _value_, so all Rhai script-defined functions are _pure_
-(i.e. they never modify their arguments).
-
-Any update to an argument will **not** be reflected back to the caller.
-
-```rust
-fn change(s) { // 's' is passed by value
- s = 42; // only a COPY of 's' is changed
-}
-
-let x = 500;
-
-change(x);
-
-x == 500; // 'x' is NOT changed!
-```
-
-
-`this` – Simulating an Object Method
------------------------------------------
-
-Script-defined functions can also be called in method-call style.
-When this happens, the keyword '`this`' binds to the object in the method call and can be changed.
-
-```rust
-fn change() { // not that the object does not need a parameter
- this = 42; // 'this' binds to the object in method-call
-}
-
-let x = 500;
-
-x.change(); // call 'change' in method-call style, 'this' binds to 'x'
-
-x == 42; // 'x' is changed!
-
-change(); // <- error: `this` is unbound
-```
-
-
-`is_def_fn`
------------
-
-Use `is_def_fn` to detect if a Rhai function is defined (and therefore callable),
-based on its name and the number of parameters.
-
-```rust
-fn foo(x) { x + 1 }
-
-is_def_fn("foo", 1) == true;
-
-is_def_fn("foo", 0) == false;
-
-is_def_fn("foo", 2) == false;
-
-is_def_fn("bar", 1) == false;
-```
-
-
-Metadata
---------
-
-The function `get_fn_metadata_list` is a _reflection_ API that returns an array of the metadata
-of all script-defined functions in scope.
-
-Functions from the following sources are returned, in order:
-
-1) Encapsulated script environment (e.g. when loading a [module] from a script file),
-2) Current script,
-3) [Modules] imported via the [`import`] statement (latest imports first),
-4) [Modules] added via [`Engine::register_static_module`]({{rootUrl}}/rust/modules/create.md) (latest registrations first)
-
-The return value is an [array] of [object maps] (so `get_fn_metadata_list` is not available under
-[`no_index`] or [`no_object`]), containing the following fields:
-
-| Field | Type | Optional? | Description |
-| -------------- | :------------------: | :-------: | ---------------------------------------------------------------------- |
-| `namespace` | [string] | yes | the module _namespace_ if the function is defined within a module |
-| `access` | [string] | no | `"public"` if the function is public, `"private"` if it is private |
-| `name` | [string] | no | function name |
-| `params` | [array] of [strings] | no | parameter names |
-| `is_anonymous` | `bool` | no | is this function an anonymous function? |
diff --git a/doc/src/language/if.md b/doc/src/language/if.md
deleted file mode 100644
index b9c63dab..00000000
--- a/doc/src/language/if.md
+++ /dev/null
@@ -1,51 +0,0 @@
-`if` Statement
-==============
-
-{{#include ../links.md}}
-
-`if` statements follow C syntax:
-
-```rust
-if foo(x) {
- print("It's true!");
-} else if bar == baz {
- print("It's true again!");
-} else if baz.is_foo() {
- print("Yet again true.");
-} else if foo(bar - baz) {
- print("True again... this is getting boring.");
-} else {
- print("It's finally false!");
-}
-```
-
-Braces Are Mandatory
---------------------
-
-Unlike C, the condition expression does _not_ need to be enclosed in parentheses '`(`' .. '`)`', but
-all branches of the `if` statement must be enclosed within braces '`{`' .. '`}`',
-even when there is only one statement inside the branch.
-
-Like Rust, there is no ambiguity regarding which `if` clause a branch belongs to.
-
-```rust
-// Rhai is not C!
-if (decision) print("I've decided!");
-// ^ syntax error, expecting '{' in statement block
-```
-
-
-`if`-Expressions
----------------
-
-Like Rust, `if` statements can also be used as _expressions_, replacing the `? :` conditional operators
-in other C-like languages.
-
-```rust
-// The following is equivalent to C: int x = 1 + (decision ? 42 : 123) / 2;
-let x = 1 + if decision { 42 } else { 123 } / 2;
-x == 22;
-
-let x = if decision { 42 }; // no else branch defaults to '()'
-x == ();
-```
diff --git a/doc/src/language/index.md b/doc/src/language/index.md
deleted file mode 100644
index ac4e4fb6..00000000
--- a/doc/src/language/index.md
+++ /dev/null
@@ -1,7 +0,0 @@
-Rhai Language Reference
-======================
-
-{{#include ../links.md}}
-
-This section outlines the Rhai language.
-
diff --git a/doc/src/language/iterator.md b/doc/src/language/iterator.md
deleted file mode 100644
index e885efba..00000000
--- a/doc/src/language/iterator.md
+++ /dev/null
@@ -1,45 +0,0 @@
-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` 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- for TestStruct {
- type Item = ...;
- type IntoIter = SomeIterType
;
-
- fn into_iter(self) -> Self::IntoIter {
- ...
- }
-}
-
-engine
- .register_type_with_name::("TestStruct")
- .register_fn("new_ts", || TestStruct { ... })
- .register_iterator::(); // 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 {
- ...
-}
-```
diff --git a/doc/src/language/json.md b/doc/src/language/json.md
deleted file mode 100644
index 26e9f81f..00000000
--- a/doc/src/language/json.md
+++ /dev/null
@@ -1,95 +0,0 @@
-Parse an Object Map from JSON
-============================
-
-{{#include ../links.md}}
-
-The syntax for an [object map] is extremely similar to the JSON representation of a object hash,
-with the exception of `null` values which can technically be mapped to [`()`].
-
-A valid JSON string does not start with a hash character `#` while a Rhai [object map] does – that's the major difference!
-
-Use the `Engine::parse_json` method to parse a piece of JSON into an object map.
-The JSON text must represent a single object hash (i.e. must be wrapped within "`{ .. }`")
-otherwise it returns a syntax error.
-
-```rust
-// JSON string - notice that JSON property names are always quoted
-// notice also that comments are acceptable within the JSON string
-let json = r#"{
- "a": 1, // <- this is an integer number
- "b": true,
- "c": 123.0, // <- this is a floating-point number
- "$d e f!": "hello", // <- any text can be a property name
- "^^^!!!": [1,42,"999"], // <- value can be array or another hash
- "z": null // <- JSON 'null' value
- }
-"#;
-
-// Parse the JSON expression as an object map
-// Set the second boolean parameter to true in order to map 'null' to '()'
-let map = engine.parse_json(json, true)?;
-
-map.len() == 6; // 'map' contains all properties in the JSON string
-
-// Put the object map into a 'Scope'
-let mut scope = Scope::new();
-scope.push("map", map);
-
-let result = engine.eval_with_scope::(r#"map["^^^!!!"].len()"#)?;
-
-result == 3; // the object map is successfully used in the script
-```
-
-Representation of Numbers
-------------------------
-
-JSON numbers are all floating-point while Rhai supports integers (`INT`) and floating-point (`FLOAT`) if
-the [`no_float`] feature is not used.
-
-Most common generators of JSON data distinguish between integer and floating-point values by always
-serializing a floating-point number with a decimal point (i.e. `123.0` instead of `123` which is
-assumed to be an integer).
-
-This style can be used successfully with Rhai [object maps].
-
-
-Parse JSON with Sub-Objects
---------------------------
-
-`Engine::parse_json` depends on the fact that the [object map] literal syntax in Rhai is _almost_
-the same as a JSON object. However, it is _almost_ because the syntax for a sub-object in JSON
-(i.e. "`{ ... }`") is different from a Rhai [object map] literal (i.e. "`#{ ... }`").
-
-When `Engine::parse_json` encounters JSON with sub-objects, it fails with a syntax error.
-
-If it is certain that no text string in the JSON will ever contain the character '`{`',
-then it is possible to parse it by first replacing all occupance of '`{`' with "`#{`".
-
-A JSON object hash starting with `#{` is handled transparently by `Engine::parse_json`.
-
-```rust
-// JSON with sub-object 'b'.
-let json = r#"{"a":1, "b":{"x":true, "y":false}}"#;
-
-// Our JSON text does not contain the '{' character, so off we go!
-let new_json = json.replace("{", "#{");
-
-// The leading '{' will also be replaced to '#{', but 'parse_json' handles this just fine.
-let map = engine.parse_json(&new_json, false)?;
-
-map.len() == 2; // 'map' contains two properties: 'a' and 'b'
-```
-
-
-Use `serde` to Serialize/Deserialize to/from JSON
-------------------------------------------------
-
-Remember, `Engine::parse_json` is nothing more than a _cheap_ alternative to true JSON parsing.
-
-If correctness is needed, or for more configuration possibilities, turn on the [`serde`][features]
-feature to pull in the [`serde`](https://crates.io/crates/serde) crate which enables
-serialization and deserialization to/from multiple formats, including JSON.
-
-Beware, though... the [`serde`](https://crates.io/crates/serde) crate is quite heavy.
-
-See _[Serialization/Deserialization of `Dynamic` with `serde`][`serde`]_ for more details.
diff --git a/doc/src/language/keywords.md b/doc/src/language/keywords.md
deleted file mode 100644
index 53f3ca65..00000000
--- a/doc/src/language/keywords.md
+++ /dev/null
@@ -1,26 +0,0 @@
-Keywords
-========
-
-{{#include ../links.md}}
-
-The following are reserved keywords in Rhai:
-
-| Active keywords | Reserved keywords | Usage | Inactive under feature |
-| ---------------------------------------------------------------- | ---------------------------------------------------------- | ---------------------- | :--------------------: |
-| `true`, `false` | | constants | |
-| `let`, `const` | `var`, `static` | variables | |
-| | `begin`, `end` | block scopes | |
-| `is_shared` | | shared values | [`no_closure`] |
-| `if`, `else` | `then`, `unless`, `goto`, `exit` | control flow | |
-| `switch` | `match`, `case` | switching and matching | |
-| `do`, `while`, `loop`, `until`, `for`, `in`, `continue`, `break` | `each` | looping | |
-| `fn`, `private` | `public`, `new` | functions | [`no_function`] |
-| `return` | | return values | |
-| `throw`, `try`, `catch` | | throw/catch exceptions | |
-| `import`, `export`, `as` | `use`, `with`, `module`, `package` | modules/packages | [`no_module`] |
-| `Fn`, `call`, `curry` | | function pointers | |
-| | `spawn`, `thread`, `go`, `sync`, `async`, `await`, `yield` | threading/async | |
-| `type_of`, `print`, `debug`, `eval` | | special functions | |
-| | `default`, `void`, `null`, `nil` | special values | |
-
-Keywords cannot become the name of a [function] or [variable], even when they are disabled.
diff --git a/doc/src/language/logic.md b/doc/src/language/logic.md
deleted file mode 100644
index 9f6ebbcf..00000000
--- a/doc/src/language/logic.md
+++ /dev/null
@@ -1,78 +0,0 @@
-Logic Operators
-==============
-
-{{#include ../links.md}}
-
-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
-set of types (see [built-in operators]).
-
-```rust
-42 == 42; // true
-
-42 > 42; // false
-
-"hello" > "foo"; // true
-
-"42" == 42; // false
-```
-
-Comparing two values of _different_ data types, or of unknown data types, always results in `false`,
-except for '`!=`' (not equals) which results in `true`. This is in line with intuition.
-
-```rust
-42 == 42.0; // false - i64 cannot be compared with f64
-
-42 != 42.0; // true - i64 cannot be compared with f64
-
-42 > "42"; // false - i64 cannot be compared with string
-
-42 <= "42"; // false - i64 cannot be compared with string
-
-let ts = new_ts(); // custom type
-
-ts == 42; // false - types cannot be compared
-
-ts != 42; // true - types cannot be compared
-```
-
-Boolean operators
------------------
-
-| Operator | Description | Short-Circuits? |
-| :---------------: | ------------- | :-------------: |
-| `!` (prefix) | boolean _NOT_ | no |
-| `&&` | boolean _AND_ | yes |
-| `&` | boolean _AND_ | no |
-| \|\|
| boolean _OR_ | yes |
-| \|
| boolean _OR_ | no |
-
-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.
-
-```rust
-a() || b(); // b() is not evaluated if a() is true
-
-a() && b(); // b() is not evaluated if a() is false
-
-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.
diff --git a/doc/src/language/loop.md b/doc/src/language/loop.md
deleted file mode 100644
index 3fd9b5fb..00000000
--- a/doc/src/language/loop.md
+++ /dev/null
@@ -1,26 +0,0 @@
-Infinite `loop`
-===============
-
-{{#include ../links.md}}
-
-Infinite loops follow Rust syntax.
-
-Like Rust, `continue` can be used to skip to the next iteration, by-passing all following statements;
-`break` can be used to break out of the loop unconditionally.
-
-```rust
-let x = 10;
-
-loop {
- x -= 1;
-
- if x > 5 { continue; } // skip to the next iteration
-
- print(x);
-
- if x == 0 { break; } // break out of loop
-}
-```
-
-Beware: a `loop` statement without a `break` statement inside its loop block is infinite -
-there is no way for the loop to stop iterating.
diff --git a/doc/src/language/method.md b/doc/src/language/method.md
deleted file mode 100644
index 5843faef..00000000
--- a/doc/src/language/method.md
+++ /dev/null
@@ -1,95 +0,0 @@
-Call Method as Function
-======================
-
-{{#include ../links.md}}
-
-
-First `&mut` Parameter
-----------------------
-
-Property [getters/setters] and [methods][custom types] in a Rust custom type registered with the [`Engine`] can be called
-just like a regular function. In fact, like Rust, property getters/setters and object methods
-are registered as regular [functions] in Rhai that take a first `&mut` parameter.
-
-Unlike functions defined in script (for which all arguments are passed by _value_),
-native Rust functions may mutate the object (or the first argument if called in normal function call style).
-
-However, sometimes it is not as straight-forward, and methods called in function-call style may end up
-not muting the object – see the example below. Therefore, it is best to always use method-call style.
-
-Custom types, properties and methods can be disabled via the [`no_object`] feature.
-
-```rust
-let a = new_ts(); // constructor function
-a.field = 500; // property setter
-a.update(); // method call, 'a' can be modified
-
-update(a); // <- this de-sugars to 'a.update()' thus if 'a' is a simple variable
- // unlike scripted functions, 'a' can be modified and is not a copy
-
-let array = [ a ];
-
-update(array[0]); // <- 'array[0]' is an expression returning a calculated value,
- // a transient (i.e. a copy), so this statement has no effect
- // except waste a lot of time cloning
-
-array[0].update(); // <- call in method-call style will update 'a'
-```
-
-**IMPORTANT: Rhai does NOT support normal references (i.e. `&T`) as parameters.**
-
-
-Number of Parameters in Methods
-------------------------------
-
-Native Rust methods registered with an [`Engine`] take _one additional parameter_ more than
-an equivalent method coded in script, where the object is accessed via the `this` pointer instead.
-
-The following table illustrates the differences:
-
-| Function type | Parameters | Object reference | Function signature |
-| :-----------: | :--------: | :-----------------------: | :---------------------------: |
-| Native Rust | _N_ + 1 | first `&mut T` parameter | `Fn(obj: &mut T, x: U, y: V)` |
-| Rhai script | _N_ | `this` (of type `&mut T`) | `Fn(x: U, y: V)` |
-
-
-`&mut` is Efficient, Except for `&mut ImmutableString`
-----------------------------------------------------
-
-Using a `&mut` first parameter is highly encouraged when using types that are expensive to clone,
-even when the intention is not to mutate that argument, because it avoids cloning that argument value.
-
-Even when a function is never intended to be a method – for example an operator,
-it is still sometimes beneficial to make it method-like (i.e. with a first `&mut` parameter)
-if the first parameter is not modified.
-
-For types that are expensive to clone (remember, all function calls are passed cloned
-copies of argument values), this may result in a significant performance boost.
-
-For primary types that are cheap to clone (e.g. those that implement `Copy`), including `ImmutableString`,
-this is not necessary.
-
-```rust
-// This is a type that is very expensive to clone.
-#[derive(Debug, Clone)]
-struct VeryComplexType { ... }
-
-// Calculate some value by adding 'VeryComplexType' with an integer number.
-fn do_add(obj: &VeryComplexType, offset: i64) -> i64 {
- ...
-}
-
-engine
- .register_type::()
- .register_fn("+", add_pure /* or add_method*/);
-
-// Very expensive to call, as the 'VeryComplexType' is cloned before each call.
-fn add_pure(obj: VeryComplexType, offset: i64) -> i64 {
- do_add(obj, offset)
-}
-
-// Efficient to call, as only a reference to the 'VeryComplexType' is passed.
-fn add_method(obj: &mut VeryComplexType, offset: i64) -> i64 {
- do_add(obj, offset)
-}
-```
diff --git a/doc/src/language/modules/export.md b/doc/src/language/modules/export.md
deleted file mode 100644
index 362ca111..00000000
--- a/doc/src/language/modules/export.md
+++ /dev/null
@@ -1,98 +0,0 @@
-Export Variables, Functions and Sub-Modules in Module
-===================================================
-
-{{#include ../../links.md}}
-
-
-The easiest way to expose a collection of functions as a self-contained [module] is to do it via a Rhai script itself.
-
-See the section on [_Creating a Module from AST_]({{rootUrl}}/rust/modules/ast.md) for more details.
-
-The script text is evaluated, variables are then selectively exposed via the [`export`] statement.
-Functions defined by the script are automatically exported.
-
-Modules loaded within this module at the global level become _sub-modules_ and are also automatically exported.
-
-
-Export Global Variables
-----------------------
-
-The `export` statement, which can only be at global level, exposes selected variables as members of a module.
-
-Variables not exported are _private_ and hidden. They are merely used to initialize the module,
-but cannot be accessed from outside.
-
-Everything exported from a module is **constant** (i.e. read-only).
-
-```rust
-// This is a module script.
-
-let hidden = 123; // variable not exported - default hidden
-let x = 42; // this will be exported below
-
-export x; // the variable 'x' is exported under its own name
-
-export let x = 42; // convenient short-hand to declare a variable and export it
- // under its own name
-
-export x as answer; // the variable 'x' is exported under the alias 'answer'
- // another script can load this module and access 'x' as 'module::answer'
-
-{
- let inner = 0; // local variable - it disappears when the statement block ends,
- // therefore it is not 'global' and cannot be exported
-
- export inner; // <- syntax error: cannot export a local variable
-}
-```
-
-### Multiple Exports
-
-One `export` statement can export multiple variables, even under multiple names.
-
-```rust
-// The following exports three variables:
-// - 'x' (as 'x' and 'hello')
-// - 'y' (as 'foo' and 'bar')
-// - 'z' (as 'z')
-export x, x as hello, x as world, y as foo, y as bar, z;
-```
-
-
-Export Functions
-----------------
-
-All functions are automatically exported, _unless_ it is explicitly opt-out with the [`private`] prefix.
-
-Functions declared [`private`] are hidden to the outside.
-
-```rust
-// This is a module script.
-
-fn inc(x) { x + 1 } // script-defined function - default public
-
-private fn foo() {} // private function - hidden
-```
-
-[`private`] functions are commonly called to initialize the module.
-They cannot be called apart from this.
-
-
-Sub-Modules
------------
-
-All loaded modules are automatically exported as sub-modules.
-
-To prevent a module from being exported, load it inside a block statement so that it goes away at the
-end of the block.
-
-```rust
-// This is a module script.
-
-import "hello" as foo; // exported as sub-module 'foo'
-
-{
- import "world" as bar; // not exported - the module disappears at the end
- // of the statement block and is not 'global'
-}
-```
diff --git a/doc/src/language/modules/import.md b/doc/src/language/modules/import.md
deleted file mode 100644
index d335beeb..00000000
--- a/doc/src/language/modules/import.md
+++ /dev/null
@@ -1,113 +0,0 @@
-Import a Module
-===============
-
-{{#include ../../links.md}}
-
-
-Before a module can be used (via an `import` statement) in a script, there must be a [module resolver]
-registered into the [`Engine`], the default being the `FileModuleResolver`.
-
-See the section on [_Module Resolvers_][module resolver] for more details.
-
-
-`import` Statement
------------------
-
-A module can be _imported_ via the `import` statement, and be given a name.
-Its members can be accessed via '`::`' similar to C++.
-
-A module that is only `import`-ed but not under any module name is commonly used for initialization purposes,
-where the module script contains initialization statements that puts the functions registered with the
-[`Engine`] into a particular state.
-
-```rust
-import "crypto_init"; // run the script file 'crypto_init.rhai' without creating an imported module
-
-import "crypto" as lock; // run the script file 'crypto.rhai' and import it as a module named 'lock'
-
-const SECRET_NUMBER = 42;
-
-let mod_file = "crypto_" + SECRET_NUMBER;
-
-import mod_file as my_mod; // load the script file "crypto_42.rhai" and import it as a module named 'my_mod'
- // notice that module path names can be dynamically constructed!
- // any expression that evaluates to a string is acceptable after the 'import' keyword
-
-lock::encrypt(secret); // use functions defined under the module via '::'
-
-lock::hash::sha256(key); // sub-modules are also supported
-
-print(lock::status); // module variables are constants
-
-lock::status = "off"; // <- runtime error - cannot modify a constant
-```
-
-
-Scoped Imports
---------------
-
-`import` statements are _scoped_, meaning that they are only accessible inside the scope that they're imported.
-
-They can appear anywhere a normal statement can be, but in the vast majority of cases `import` statements are
-group at the beginning of a script. It is not advised to deviate from this common practice unless
-there is a _Very Good Reason™_.
-
-Especially, do not place an `import` statement within a loop; doing so will repeatedly re-load the same module
-during every iteration of the loop!
-
-```rust
-let mod = "crypto";
-
-if secured { // new block scope
- import mod as c; // import module (the path needs not be a constant string)
-
- c::encrypt(key); // use a function in the module
-} // the module disappears at the end of the block scope
-
-c::encrypt(others); // <- this causes a run-time error because the 'crypto' module
- // is no longer available!
-
-for x in range(0, 1000) {
- import "crypto" as c; // <- importing a module inside a loop is a Very Bad Idea™
-
- c.encrypt(something);
-}
-```
-
-
-Recursive Imports
-----------------
-
-Beware of _import cycles_ – i.e. recursively loading the same module. This is a sure-fire way to
-cause a stack overflow in the [`Engine`], unless stopped by setting a limit for [maximum number of modules].
-
-For instance, importing itself always causes an infinite recursion:
-
-```rust
---------------
-| hello.rhai |
---------------
-
-import "hello" as foo; // import itself - infinite recursion!
-
-foo::do_something();
-```
-
-Modules cross-referencing also cause infinite recursion:
-
-```rust
---------------
-| hello.rhai |
---------------
-
-import "world" as foo;
-foo::do_something();
-
-
---------------
-| world.rhai |
---------------
-
-import "hello" as bar;
-bar::do_something_else();
-```
diff --git a/doc/src/language/modules/index.md b/doc/src/language/modules/index.md
deleted file mode 100644
index dd8c928a..00000000
--- a/doc/src/language/modules/index.md
+++ /dev/null
@@ -1,14 +0,0 @@
-Modules
-=======
-
-{{#include ../../links.md}}
-
-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.
-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.
-
-Other scripts can then load this module and use the functions and variables exported
-as if they were defined inside the same script.
diff --git a/doc/src/language/num-fn.md b/doc/src/language/num-fn.md
deleted file mode 100644
index 599b03c1..00000000
--- a/doc/src/language/num-fn.md
+++ /dev/null
@@ -1,46 +0,0 @@
-Numeric Functions
-================
-
-{{#include ../links.md}}
-
-Integer Functions
-----------------
-
-The following standard functions (defined in the [`BasicMathPackage`][packages] but excluded if using a [raw `Engine`])
-operate on `i8`, `i16`, `i32`, `i64`, `f32` and `f64` only:
-
-| Function | No available under | Description |
-| -------- | :----------------: | ----------------------------------------------------------------------- |
-| `abs` | | absolute value |
-| `sign` | | returns -1 (`INT`) if the number is negative, +1 if positive, 0 if zero |
-
-
-Floating-Point Functions
------------------------
-
-The following standard functions (defined in the [`BasicMathPackage`][packages] but excluded if using a [raw `Engine`])
-operate on `f64` only:
-
-| Category | Functions |
-| ---------------- | --------------------------------------------------------------------- |
-| Trigonometry | `sin`, `cos`, `tan`, `sinh`, `cosh`, `tanh` in degrees |
-| Arc-trigonometry | `asin`, `acos`, `atan`, `asinh`, `acosh`, `atanh` in degrees |
-| Square root | `sqrt` |
-| Exponential | `exp` (base _e_) |
-| Logarithmic | `ln` (base _e_), `log10` (base 10), `log` (any base) |
-| Rounding | `floor`, `ceiling`, `round`, `int`, `fraction` methods and properties |
-| Conversion | [`to_int`] |
-| Testing | `is_nan`, `is_finite`, `is_infinite` methods and properties |
-
-
-Conversion Functions
--------------------
-
-The following standard functions (defined in the [`BasicMathPackage`][packages] but excluded if using a [raw `Engine`])
-parse numbers:
-
-| Function | No available under | Description |
-| --------------- | :----------------: | --------------------------------------------------- |
-| [`to_float`] | [`no_float`] | converts an integer type to `FLOAT` |
-| [`parse_int`] | | converts a [string] to `INT` with an optional radix |
-| [`parse_float`] | [`no_float`] | converts a [string] to `FLOAT` |
diff --git a/doc/src/language/num-op.md b/doc/src/language/num-op.md
deleted file mode 100644
index a897c7ae..00000000
--- a/doc/src/language/num-op.md
+++ /dev/null
@@ -1,51 +0,0 @@
-Numeric Operators
-=================
-
-{{#include ../links.md}}
-
-Numeric operators generally follow C styles.
-
-Unary Operators
----------------
-
-| Operator | Description |
-| -------- | ----------- |
-| `+` | positive |
-| `-` | negative |
-
-```rust
-let number = -5;
-
-number = -5 - +5;
-```
-
-Binary Operators
-----------------
-
-| Operator | Description | Integers only |
-| --------------- | ---------------------------------------------------- | :-----------: |
-| `+` | plus | |
-| `-` | minus | |
-| `*` | multiply | |
-| `/` | divide (integer division if acting on integer types) | |
-| `%` | modulo (remainder) | |
-| `~` | power | |
-| `&` | bit-wise _And_ | Yes |
-| \|
| bit-wise _Or_ | Yes |
-| `^` | bit-wise _Xor_ | Yes |
-| `<<` | left bit-shift | Yes |
-| `>>` | right bit-shift | Yes |
-
-```rust
-let x = (1 + 2) * (6 - 4) / 2; // arithmetic, with parentheses
-
-let reminder = 42 % 10; // modulo
-
-let power = 42 ~ 2; // power (i64 and f64 only)
-
-let left_shifted = 42 << 3; // left shift
-
-let right_shifted = 42 >> 3; // right shift
-
-let bit_op = 42 | 99; // bit masking
-```
diff --git a/doc/src/language/numbers.md b/doc/src/language/numbers.md
deleted file mode 100644
index 78a4f236..00000000
--- a/doc/src/language/numbers.md
+++ /dev/null
@@ -1,22 +0,0 @@
-Numbers
-=======
-
-{{#include ../links.md}}
-
-Integer numbers follow C-style format with support for decimal, binary ('`0b`'), octal ('`0o`') and hex ('`0x`') notations.
-
-The default system integer type (also aliased to `INT`) is `i64`. It can be turned into `i32` via the [`only_i32`] feature.
-
-Floating-point numbers are also supported if not disabled with [`no_float`]. The default system floating-point type is `i64`
-(also aliased to `FLOAT`). It can be turned into `f32` via the [`f32_float`] feature.
-
-'`_`' separators can be added freely and are ignored within a number – except at the very beginning or right after
-a decimal point ('`.`').
-
-| Format | Type |
-| --------------------- | ---------------- |
-| `123_345`, `-42` | `INT` in decimal |
-| `0o07_76` | `INT` in octal |
-| `0xabcd_ef` | `INT` in hex |
-| `0b0101_1001` | `INT` in binary |
-| `123_456.789`, `-42.` | `FLOAT` |
diff --git a/doc/src/language/object-maps-oop.md b/doc/src/language/object-maps-oop.md
deleted file mode 100644
index f96fda04..00000000
--- a/doc/src/language/object-maps-oop.md
+++ /dev/null
@@ -1,39 +0,0 @@
-Special Support for OOP via Object Maps
-======================================
-
-{{#include ../links.md}}
-
-[Object maps] can be used to simulate [object-oriented programming (OOP)][OOP] by storing data
-as properties and methods as properties holding [function pointers].
-
-If an [object map]'s property holds a [function pointer], the property can simply be called like
-a normal method in method-call syntax. This is a _short-hand_ to avoid the more verbose syntax
-of using the `call` function keyword.
-
-When a property holding a [function pointer] or a [closure] is called like a method,
-what happens next depends on whether the target function is a native Rust function or
-a script-defined function.
-
-* If it is a registered native Rust function, it is called directly in _method-call_ style with the [object map] inserted as the first argument.
-
-* If it is a script-defined function, the `this` variable within the function body is bound to the [object map] before the function is called.
-
-```rust
-let obj = #{
- data: 40,
- action: || this.data += x // 'action' holds a closure
- };
-
-obj.action(2); // calls the function pointer with `this` bound to 'obj'
-
-obj.call(obj.action, 2); // <- the above de-sugars to this
-
-obj.data == 42;
-
-// To achieve the above with normal function pointer call will fail.
-fn do_action(map, x) { map.data += x; } // 'map' is a copy
-
-obj.action = Fn("do_action");
-
-obj.action.call(obj, 2); // 'obj' is passed as a copy by value
-```
diff --git a/doc/src/language/object-maps.md b/doc/src/language/object-maps.md
deleted file mode 100644
index 8dcdbef5..00000000
--- a/doc/src/language/object-maps.md
+++ /dev/null
@@ -1,169 +0,0 @@
-Object Maps
-===========
-
-{{#include ../links.md}}
-
-Object maps are hash dictionaries. Properties are all [`Dynamic`] and can be freely added and retrieved.
-
-The Rust type of a Rhai object map is `rhai::Map`.
-
-[`type_of()`] an object map returns `"map"`.
-
-Object maps are disabled via the [`no_object`] feature.
-
-The maximum allowed size of an object map can be controlled via `Engine::set_max_map_size`
-(see [maximum size of object maps]).
-
-
-Object Map Literals
-------------------
-
-Object map literals are built within braces '`#{`' ... '`}`' (_name_ `:` _value_ syntax similar to Rust)
-and separated by commas '`,`':
-
-> `#{` _property_ `:` _value_ `,` `...` `,` _property_ `:` _value_ `}`
->
-> `#{` _property_ `:` _value_ `,` `...` `,` _property_ `:` _value_ `,` `}` `// trailing comma is OK`
-
-The property _name_ can be a simple variable name following the same
-naming rules as [variables], or an arbitrary [string] literal.
-
-
-Access Properties
------------------
-
-### Dot Notation
-
-The _dot notation_ allows only property names that follow the same naming rules as [variables].
-
-> _object_ `.` _property_
-
-### Index Notation
-
-The _index notation_ allows setting/getting properties of arbitrary names (even the empty [string]).
-
-> _object_ `[` _property_ `]`
-
-### Non-Existence
-
-Trying to read a non-existing property returns [`()`] instead of causing an error.
-
-This is similar to JavaScript where accessing a non-existing property returns `undefined`.
-
-
-Built-in Functions
------------------
-
-The following methods (defined in the [`BasicMapPackage`][packages] but excluded if using a [raw `Engine`])
-operate on object maps:
-
-| Function | Parameter(s) | Description |
-| ---------------------- | -------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
-| `has`, `in` operator | property name | does the object map contain a property of a particular name? |
-| `len` | _none_ | returns the number of properties |
-| `clear` | _none_ | empties the object map |
-| `remove` | property name | removes a certain property and returns it ([`()`] if the property does not exist) |
-| `+=` operator, `mixin` | second object map | mixes in all the properties of the second object map to the first (values of properties with the same names replace the existing values) |
-| `+` operator | 1) first object map 2) second object map | merges the first object map with the second |
-| `==` operator | 1) first object map 2) second object map | are the two object map the same (elements compared with the `==` operator, if defined)? |
-| `!=` operator | 1) first object map 2) second object map | are the two object map different (elements compared with the `==` operator, if defined)? |
-| `fill_with` | second object map | adds in all properties of the second object map that do not exist in the object map |
-| `keys` | _none_ | returns an [array] of all the property names (in random order), not available under [`no_index`] |
-| `values` | _none_ | returns an [array] of all the property values (in random order), not available under [`no_index`] |
-
-
-Examples
---------
-
-```rust
-let y = #{ // object map literal with 3 properties
- a: 1,
- bar: "hello",
- "baz!$@": 123.456, // like JavaScript, you can use any string as property names...
- "": false, // even the empty string!
-
- a: 42 // <- syntax error: duplicated property name
-};
-
-y.a = 42; // access via dot notation
-y.baz!$@ = 42; // <- syntax error: only proper variable names allowed in dot notation
-y."baz!$@" = 42; // <- syntax error: strings not allowed in dot notation
-
-y.a == 42;
-
-y["baz!$@"] == 123.456; // access via index notation
-
-"baz!$@" in y == true; // use 'in' to test if a property exists in the object map
-("z" in y) == false;
-
-ts.obj = y; // object maps can be assigned completely (by value copy)
-let foo = ts.list.a;
-foo == 42;
-
-let foo = #{ a:1,}; // trailing comma is OK
-
-let foo = #{ a:1, b:2, c:3 }["a"];
-foo == 1;
-
-fn abc() {
- ##{ a:1, b:2, c:3 } // a function returning an object map
-}
-
-let foo = abc().b;
-foo == 2;
-
-let foo = y["a"];
-foo == 42;
-
-y.has("a") == true;
-y.has("xyz") == false;
-
-y.xyz == (); // a non-existing property returns '()'
-y["xyz"] == ();
-
-y.len() == 3;
-
-y.remove("a") == 1; // remove property
-
-y.len() == 2;
-y.has("a") == false;
-
-for name in y.keys() { // get an array of all the property names via 'keys'
- print(name);
-}
-
-for val in y.values() { // get an array of all the property values via 'values'
- print(val);
-}
-
-y.clear(); // empty the object map
-
-y.len() == 0;
-```
-
-
-No Support for Property Getters
-------------------------------
-
-In order not to affect the speed of accessing properties in an object map, new property
-[getters][getters/setters] cannot be registered because they conflict with the syntax of
-property access.
-
-A property [getter][getters/setters] function registered via `Engine::register_get`, for example,
-for a `Map` will never be found – instead, the property will be looked up in the object map.
-
-Therefore, _method-call_ notation must be used for built-in properties:
-
-```rust
-map.len // access property 'len', returns '()' if not found
-
-map.len() // returns the number of properties
-
-map.keys // access property 'keys', returns '()' if not found
-
-map.keys() // returns array of all property names
-
-map.values // access property 'values', returns '()' if not found
-
-map.values() // returns array of all property values
-```
diff --git a/doc/src/language/overload.md b/doc/src/language/overload.md
deleted file mode 100644
index 2ec2fd4e..00000000
--- a/doc/src/language/overload.md
+++ /dev/null
@@ -1,29 +0,0 @@
-Function Overloading
-===================
-
-{{#include ../links.md}}
-
-[Functions] defined in script can be _overloaded_ by _arity_ (i.e. they are resolved purely upon the function's _name_
-and _number_ of parameters, but not parameter _types_ since all parameters are the same type – [`Dynamic`]).
-
-New definitions _overwrite_ previous definitions of the same name and number of parameters.
-
-```rust
-fn foo(x,y,z) { print("Three!!! " + x + "," + y + "," + z); }
-
-fn foo(x) { print("One! " + x); }
-
-fn foo(x,y) { print("Two! " + x + "," + y); }
-
-fn foo() { print("None."); }
-
-fn foo(x) { print("HA! NEW ONE! " + x); } // overwrites previous definition
-
-foo(1,2,3); // prints "Three!!! 1,2,3"
-
-foo(42); // prints "HA! NEW ONE! 42"
-
-foo(1,2); // prints "Two!! 1,2"
-
-foo(); // prints "None."
-```
diff --git a/doc/src/language/print-debug.md b/doc/src/language/print-debug.md
deleted file mode 100644
index 996e6aac..00000000
--- a/doc/src/language/print-debug.md
+++ /dev/null
@@ -1,72 +0,0 @@
-`print` and `debug`
-===================
-
-{{#include ../links.md}}
-
-The `print` and `debug` functions default to printing to `stdout`, with `debug` using standard debug formatting.
-
-```rust
-print("hello"); // prints hello to stdout
-
-print(1 + 2 + 3); // prints 6 to stdout
-
-print("hello" + 42); // prints hello42 to stdout
-
-debug("world!"); // prints "world!" to stdout using debug formatting
-```
-
-Override `print` and `debug` with Callback Functions
---------------------------------------------------
-
-When embedding Rhai into an application, it is usually necessary to trap `print` and `debug` output
-(for logging into a tracking log, for example) with the `Engine::on_print` and `Engine::on_debug` methods:
-
-```rust
-// Any function or closure that takes an '&str' argument can be used to override 'print'.
-engine.on_print(|x| println!("hello: {}", x));
-
-// Any function or closure that takes a '&str' and a 'Position' argument can be used to
-// override 'debug'.
-engine.on_debug(|x, src, pos| println!("DEBUG of {} at {:?}: {}", src.unwrap_or("unknown"), pos, x));
-
-// Example: quick-'n-dirty logging
-let logbook = Arc::new(RwLock::new(Vec::::new()));
-
-// Redirect print/debug output to 'log'
-let log = logbook.clone();
-engine.on_print(move |s| log.write().unwrap().push(format!("entry: {}", s)));
-
-let log = logbook.clone();
-engine.on_debug(move |s, src, pos| log.write().unwrap().push(
- format!("DEBUG of {} at {:?}: {}", src.unwrap_or("unknown"), pos, s)
- ));
-
-// Evaluate script
-engine.eval::<()>(script)?;
-
-// 'logbook' captures all the 'print' and 'debug' output
-for entry in logbook.read().unwrap().iter() {
- println!("{}", entry);
-}
-```
-
-
-`on_debug` Callback Signature
------------------------------
-
-The function signature passed to `Engine::on_debug` takes the following form:
-
-> `Fn(text: &str, source: Option<&str>, pos: Position) + 'static`
-
-where:
-
-| Parameter | Type | Description |
-| --------- | :------------: | --------------------------------------------------------------- |
-| `text` | `&str` | text to display |
-| `source` | `Option<&str>` | source of the current evaluation, if any |
-| `pos` | `Position` | position (line number and character offset) of the `debug` call |
-
-The _source_ of a script evaluation is any text string provided to an [`AST`] via the `AST::set_source` method.
-
-If a [module] is loaded via an [`import`] statement, then the _source_ of functions defined
-within the module will be the module's _path_.
diff --git a/doc/src/language/return.md b/doc/src/language/return.md
deleted file mode 100644
index 41c063f9..00000000
--- a/doc/src/language/return.md
+++ /dev/null
@@ -1,16 +0,0 @@
-Return Values
-=============
-
-{{#include ../links.md}}
-
-The `return` statement is used to immediately stop evaluation and exist the current context
-(typically a function call) yielding a _return value_.
-
-```rust
-return; // equivalent to return ();
-
-return 123 + 456; // returns 579
-```
-
-A `return` statement at _global_ level stop the entire script evaluation,
-the return value is taken as the result of the script evaluation.
diff --git a/doc/src/language/statements.md b/doc/src/language/statements.md
deleted file mode 100644
index a4fad876..00000000
--- a/doc/src/language/statements.md
+++ /dev/null
@@ -1,42 +0,0 @@
-Statements
-==========
-
-{{#include ../links.md}}
-
-Terminated by '`;`'
-------------------
-
-Statements are terminated by semicolons '`;`' and they are mandatory,
-except for the _last_ statement in a _block_ (enclosed by '`{`' .. '`}`' pairs) where it can be omitted.
-
-Semicolons can also be omitted if the statement ends with a block itself
-(e.g. the `if`, `while`, `for` and `loop` statements).
-
-```rust
-let a = 42; // normal assignment statement
-let a = foo(42); // normal function call statement
-foo < 42; // normal expression as statement
-
-let a = { 40 + 2 }; // 'a' is set to the value of the statement block, which is the value of the last statement
-// ^ the last statement does not require a terminating semicolon (although it also works with it)
-// ^ semicolon required here to terminate the assignment statement; it is a syntax error without it
-
-if foo { a = 42 }
-// ^ there is no need to terminate an if-statement with a semicolon
-
-4 * 10 + 2 // a statement which is just one expression - no ending semicolon is OK
- // because it is the last statement of the whole block
-```
-
-
-Statement Expression
---------------------
-
-A statement can be used anywhere where an expression is expected. These are called, for lack of a more
-creative name, "statement expressions."
-
-The _last_ statement of a statement block is _always_ the block's return value when used as a statement,
-_regardless_ of whether it is terminated by a semicolon or not. This is different from Rust where,
-if the last statement is terminated by a semicolon, the block's return value is taken to be `()`.
-
-If the last statement has no return value (e.g. variable definitions, assignments) then it is assumed to be [`()`].
diff --git a/doc/src/language/string-fn.md b/doc/src/language/string-fn.md
deleted file mode 100644
index db3d8b88..00000000
--- a/doc/src/language/string-fn.md
+++ /dev/null
@@ -1,65 +0,0 @@
-Built-in String Functions
-========================
-
-{{#include ../links.md}}
-
-The following standard methods (mostly defined in the [`MoreStringPackage`][packages] but excluded if
-using a [raw `Engine`]) operate on [strings]:
-
-| Function | Parameter(s) | Description |
-| ------------------------- | ------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------- |
-| `len` method and property | _none_ | returns the number of characters (not number of bytes) in the string |
-| `pad` | 1) target length 2) character/string to pad | pads the string with a character or a string to at least a specified length |
-| `+=` operator, `append` | character/string to append | Adds a character or a string to the end of another string |
-| `clear` | _none_ | empties the string |
-| `truncate` | target length | cuts off the string at exactly a specified number of characters |
-| `contains` | character/sub-string to search for | checks if a certain character or sub-string occurs in the string |
-| `index_of` | 1) character/sub-string to search for 2) _(optional)_ start index | returns the index that a certain character or sub-string occurs in the string, or -1 if not found |
-| `sub_string` | 1) start index 2) _(optional)_ number of characters to extract, none if < 0 | extracts a sub-string (to the end of the string if length is not specified) |
-| `split` | delimiter character/string | splits the string by the specified delimiter, returning an [array] of string segments; not available under [`no_index`] |
-| `crop` | 1) start index 2) _(optional)_ number of characters to retain, none if < 0 | retains only a portion of the string |
-| `replace` | 1) target character/sub-string 2) replacement character/string | replaces a sub-string with another |
-| `trim` | _none_ | trims the string of whitespace at the beginning and end |
-
-Examples
---------
-
-```rust
-let full_name == " Bob C. Davis ";
-full_name.len == 14;
-
-full_name.trim();
-full_name.len == 12;
-full_name == "Bob C. Davis";
-
-full_name.pad(15, '$');
-full_name.len == 15;
-full_name == "Bob C. Davis$$$";
-
-let n = full_name.index_of('$');
-n == 12;
-
-full_name.index_of("$$", n + 1) == 13;
-
-full_name.sub_string(n, 3) == "$$$";
-
-full_name.truncate(6);
-full_name.len == 6;
-full_name == "Bob C.";
-
-full_name.replace("Bob", "John");
-full_name.len == 7;
-full_name == "John C.";
-
-full_name.contains('C') == true;
-full_name.contains("John") == true;
-
-full_name.crop(5);
-full_name == "C.";
-
-full_name.crop(0, 1);
-full_name == "C";
-
-full_name.clear();
-full_name.len == 0;
-```
diff --git a/doc/src/language/strings-chars.md b/doc/src/language/strings-chars.md
deleted file mode 100644
index f814288e..00000000
--- a/doc/src/language/strings-chars.md
+++ /dev/null
@@ -1,133 +0,0 @@
-Strings and Characters
-=====================
-
-{{#include ../links.md}}
-
-String in Rhai contain any text sequence of valid Unicode characters.
-Internally strings are stored in UTF-8 encoding.
-
-Strings can be built up from other strings and types via the `+` operator
-(provided by the [`MoreStringPackage`][packages] but excluded if using a [raw `Engine`]).
-This is particularly useful when printing output.
-
-[`type_of()`] a string returns `"string"`.
-
-The maximum allowed length of a string can be controlled via `Engine::set_max_string_size`
-(see [maximum length of strings]).
-
-
-The `ImmutableString` Type
--------------------------
-
-All strings in Rhai are implemented as `ImmutableString` (see [standard types]).
-An `ImmutableString` does not change and can be shared.
-
-Modifying an `ImmutableString` causes it first to be cloned, and then the modification made to the copy.
-
-### **IMPORTANT** – Avoid `String` Parameters
-
-`ImmutableString` should be used in place of `String` for function parameters because using
-`String` is very inefficient (the `String` argument is cloned during every call).
-
-A alternative is to use `&str` which de-sugars to `ImmutableString`.
-
-```rust
-fn slow(s: String) -> i64 { ... } // string is cloned each call
-
-fn fast1(s: ImmutableString) -> i64 { ... } // cloning 'ImmutableString' is cheap
-
-fn fast2(s: &str) -> i64 { ... } // de-sugars to above
-```
-
-
-String and Character Literals
-----------------------------
-
-String and character literals follow C-style formatting, with support for Unicode ('`\u`_xxxx_' or '`\U`_xxxxxxxx_')
-and hex ('`\x`_xx_') escape sequences.
-
-Hex sequences map to ASCII characters, while '`\u`' maps to 16-bit common Unicode code points and '`\U`' maps the full,
-32-bit extended Unicode code points.
-
-Standard escape sequences:
-
-| Escape sequence | Meaning |
-| --------------- | -------------------------------- |
-| `\\` | back-slash `\` |
-| `\t` | tab |
-| `\r` | carriage-return `CR` |
-| `\n` | line-feed `LF` |
-| `\"` | double-quote `"` |
-| `\'` | single-quote `'` |
-| `\x`_xx_ | ASCII character in 2-digit hex |
-| `\u`_xxxx_ | Unicode character in 4-digit hex |
-| `\U`_xxxxxxxx_ | Unicode character in 8-digit hex |
-
-
-Differences from Rust Strings
-----------------------------
-
-Internally Rhai strings are stored as UTF-8 just like Rust (they _are_ Rust `String`'s!),
-but nevertheless there are major differences.
-
-In Rhai a string is the same as an array of Unicode characters and can be directly indexed (unlike Rust).
-
-This is similar to most other languages where strings are internally represented not as UTF-8 but as arrays of multi-byte
-Unicode characters.
-
-Individual characters within a Rhai string can also be replaced just as if the string is an array of Unicode characters.
-
-In Rhai, there are also no separate concepts of `String` and `&str` as in Rust.
-
-
-Examples
---------
-
-```rust
-let name = "Bob";
-let middle_initial = 'C';
-let last = "Davis";
-
-let full_name = name + " " + middle_initial + ". " + last;
-full_name == "Bob C. Davis";
-
-// String building with different types
-let age = 42;
-let record = full_name + ": age " + age;
-record == "Bob C. Davis: age 42";
-
-// Unlike Rust, Rhai strings can be indexed to get a character
-// (disabled with 'no_index')
-let c = record[4];
-c == 'C';
-
-ts.s = record; // custom type properties can take strings
-
-let c = ts.s[4];
-c == 'C';
-
-let c = "foo"[0]; // indexing also works on string literals...
-c == 'f';
-
-let c = ("foo" + "bar")[5]; // ... and expressions returning strings
-c == 'r';
-
-// Escape sequences in strings
-record += " \u2764\n"; // escape sequence of '❤' in Unicode
-record == "Bob C. Davis: age 42 ❤\n"; // '\n' = new-line
-
-// Unlike Rust, Rhai strings can be directly modified character-by-character
-// (disabled with 'no_index')
-record[4] = '\x58'; // 0x58 = 'X'
-record == "Bob X. Davis: age 42 ❤\n";
-
-// Use 'in' to test if a substring (or character) exists in a string
-"Davis" in record == true;
-'X' in record == true;
-'C' in record == false;
-
-// Strings can be iterated with a 'for' statement, yielding characters
-for ch in record {
- print(ch);
-}
-```
diff --git a/doc/src/language/switch.md b/doc/src/language/switch.md
deleted file mode 100644
index 08d380ee..00000000
--- a/doc/src/language/switch.md
+++ /dev/null
@@ -1,111 +0,0 @@
-`switch` Expression
-===================
-
-{{#include ../links.md}}
-
-The `switch` _expression_ allows matching on literal values, and it mostly follows Rust's
-`match` syntax:
-
-```c
-switch calc_secret_value(x) {
- 1 => print("It's one!"),
- 2 => {
- print("It's two!");
- print("Again!");
- }
- 3 => print("Go!"),
- // _ is the default when no cases match
- _ => print("Oops! Something's wrong: " + x)
-}
-```
-
-
-Expression, Not Statement
-------------------------
-
-`switch` is not a statement, but an expression. This means that a `switch` expression can
-appear anywhere a regular expression can, e.g. as function call arguments.
-
-```c
-let x = switch foo { 1 => true, _ => false };
-
-func(switch foo {
- "hello" => 42,
- "world" => 123,
- _ => 0
-});
-
-// The above is somewhat equivalent to:
-
-let x = if foo == 1 { true } else { false };
-
-if foo == "hello" {
- func(42);
-} else if foo == "world" {
- func(123);
-} else {
- func(0);
-}
-```
-
-
-Array and Object Map Literals Also Work
---------------------------------------
-
-The `switch` expression can match against any _literal_, including [array] and [object map] literals.
-
-```c
-// Match on arrays
-switch [foo, bar, baz] {
- ["hello", 42, true] => { ... }
- ["hello", 123, false] => { ... }
- ["world", 1, true] => { ... }
- _ => { ... }
-}
-
-// Match on object maps
-switch map {
- #{ a: 1, b: 2, c: true } => { ... }
- #{ a: 42, d: "hello" } => { ... }
- _ => { ... }
-}
-```
-
-Switching on [arrays] is very useful when working with Rust enums (see [this chapter]({{rootUrl}}/patterns/enums.md)
-for more details).
-
-
-Difference From `if`-`else if` Chain
------------------------------------
-
-Although a `switch` expression looks _almost_ the same as an `if`-`else if` chain,
-there are subtle differences between the two.
-
-### Look-up Table vs `x == y`
-
-A `switch` expression matches through _hashing_ via a look-up table.
-Therefore, matching is very fast. Walking down an `if`-`else if` chain
-is _much_ slower.
-
-On the other hand, operators can be [overloaded][operator overloading] in Rhai,
-meaning that it is possible to override the `==` operator for integers such
-that `x == y` returns a different result from the built-in default.
-
-`switch` expressions do _not_ use the `==` operator for comparison;
-instead, they _hash_ the data values and jump directly to the correct
-statements via a pre-compiled look-up table. This makes matching extremely
-efficient, but it also means that [overloading][operator overloading]
-the `==` operator will have no effect.
-
-Therefore, in environments where it is desirable to [overload][operator overloading]
-the `==` operator – though it is difficult to think of valid scenarios where you'd want
-`1 == 1` to return something other than `true` – avoid using the `switch` expression.
-
-### Efficiency
-
-Because the `switch` expression works through a look-up table, it is very efficient
-even for _large_ number of cases; in fact, switching is an O(1) operation regardless
-of the size of the data and number of cases to match.
-
-A long `if`-`else if` chain becomes increasingly slower with each additional case
-because essentially an O(n) _linear scan_ is performed.
diff --git a/doc/src/language/throw.md b/doc/src/language/throw.md
deleted file mode 100644
index a11a8074..00000000
--- a/doc/src/language/throw.md
+++ /dev/null
@@ -1,52 +0,0 @@
-Throw Exception on Error
-=======================
-
-{{#include ../links.md}}
-
-All of [`Engine`]'s evaluation/consuming methods return `Result>`
-with `EvalAltResult` holding error information.
-
-To deliberately return an error during an evaluation, use the `throw` keyword.
-
-```rust
-if some_bad_condition_has_happened {
- throw error; // 'throw' any value as the exception
-}
-
-throw; // defaults to '()'
-```
-
-Exceptions thrown via `throw` in the script can be captured in Rust by matching
-`Err(Box)` with the exception value
-captured by `value`.
-
-```rust
-let result = engine.eval::(r#"
- let x = 42;
-
- if x > 0 {
- throw x;
- }
-"#);
-
-println!("{}", result); // prints "Runtime error: 42 (line 5, position 15)"
-```
-
-
-Catch a Thrown Exception
-------------------------
-
-It is possible to _catch_ an exception instead of having it abort the evaluation
-of the entire script via the [`try` ... `catch`]({{rootUrl}}/language/try-catch.md)
-statement common to many C-like languages.
-
-```rust
-try
-{
- throw 42;
-}
-catch (err) // 'err' captures the thrown exception value
-{
- print(err); // prints 42
-}
-```
diff --git a/doc/src/language/timestamps.md b/doc/src/language/timestamps.md
deleted file mode 100644
index 0a8a0adc..00000000
--- a/doc/src/language/timestamps.md
+++ /dev/null
@@ -1,40 +0,0 @@
-`timestamp`
-===========
-
-{{#include ../links.md}}
-
-Timestamps are provided by the [`BasicTimePackage`][packages] (excluded if using a [raw `Engine`])
-via the `timestamp` function.
-
-Timestamps are not available under [`no_std`].
-
-The Rust type of a timestamp is `std::time::Instant` ([`instant::Instant`] in [WASM] builds).
-
-[`type_of()`] a timestamp returns `"timestamp"`.
-
-
-Built-in Functions
------------------
-
-The following methods (defined in the [`BasicTimePackage`][packages] but excluded if using a [raw `Engine`]) operate on timestamps:
-
-| Function | Parameter(s) | Description |
-| ----------------------------- | ------------------------------------------- | -------------------------------------------------------- |
-| `elapsed` method and property | _none_ | returns the number of seconds since the timestamp |
-| `-` operator | 1) later timestamp 2) earlier timestamp | returns the number of seconds between the two timestamps |
-| `+` operator | number of seconds to add | returns a new timestamp |
-| `-` operator | number of seconds to subtract | returns a new timestamp |
-
-
-Examples
---------
-
-```rust
-let now = timestamp();
-
-// Do some lengthy operation...
-
-if now.elapsed > 30.0 {
- print("takes too long (over 30 seconds)!")
-}
-```
diff --git a/doc/src/language/try-catch.md b/doc/src/language/try-catch.md
deleted file mode 100644
index a132fc61..00000000
--- a/doc/src/language/try-catch.md
+++ /dev/null
@@ -1,108 +0,0 @@
-Catch Exceptions
-================
-
-{{#include ../links.md}}
-
-
-When an [exception] is thrown via a [`throw`] statement, evaluation of the script halts
-and the [`Engine`] returns with `Err(Box)` containing the
-exception value that has been thrown.
-
-It is possible, via the `try` ... `catch` statement, to _catch_ exceptions, optionally
-with an _error variable_.
-
-```rust
-// Catch an exception and capturing its value
-try
-{
- throw 42;
-}
-catch (err) // 'err' captures the thrown exception value
-{
- print(err); // prints 42
-}
-
-// Catch an exception without capturing its value
-try
-{
- print(42/0); // deliberate divide-by-zero exception
-}
-catch // no error variable - exception value is discarded
-{
- print("Ouch!");
-}
-
-// Exception in the 'catch' block
-try
-{
- print(42/0); // throw divide-by-zero exception
-}
-catch
-{
- print("You seem to be dividing by zero here...");
-
- throw "die"; // a 'throw' statement inside a 'catch' block
- // throws a new exception
-}
-```
-
-
-Re-Throw Exception
-------------------
-
-Like the `try` ... `catch` syntax in most languages, it is possible to _re-throw_
-an exception within the `catch` block simply by another [`throw`] statement without
-a value.
-
-
-```rust
-try
-{
- // Call something that will throw an exception...
- do_something_bad_that_throws();
-}
-catch
-{
- print("Oooh! You've done something real bad!");
-
- throw; // 'throw' without a value within a 'catch' block
- // re-throws the original exception
-}
-
-```
-
-
-Catchable Exceptions
---------------------
-
-Many script-oriented exceptions can be caught via `try` ... `catch`:
-
-| Error type | Error value |
-| --------------------------------------------- | :------------------------: |
-| Runtime error thrown by a [`throw`] statement | value in `throw` statement |
-| Other runtime error | error message [string] |
-| Arithmetic error | error message [string] |
-| Variable not found | error message [string] |
-| [Function] not found | error message [string] |
-| [Module] not found | error message [string] |
-| Unbound [`this`] | error message [string] |
-| Data type mismatch | error message [string] |
-| Assignment to a calculated/constant value | error message [string] |
-| [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 a [type iterator] | error message [string] |
-| Error in an `in` expression | error message [string] |
-| Data race detected | error message [string] |
-
-
-Non-Catchable Exceptions
-------------------------
-
-Some exceptions _cannot_ be caught:
-
-* Syntax error during parsing
-* System error – e.g. script file not found
-* Script evaluation metrics over [safety limits]({{rootUrl}}/safety/index.md)
-* Function calls nesting exceeding [maximum call stack depth]
-* Script evaluation manually terminated
diff --git a/doc/src/language/type-of.md b/doc/src/language/type-of.md
deleted file mode 100644
index 45e3d0b0..00000000
--- a/doc/src/language/type-of.md
+++ /dev/null
@@ -1,47 +0,0 @@
-`type_of()`
-===========
-
-{{#include ../links.md}}
-
-The `type_of` function detects the actual type of a value.
-
-This is useful because all variables are [`Dynamic`] in nature.
-
-```rust
-// Use 'type_of()' to get the actual types of values
-type_of('c') == "char";
-type_of(42) == "i64";
-
-let x = 123;
-x.type_of() == "i64"; // method-call style is also OK
-type_of(x) == "i64";
-
-x = 99.999;
-type_of(x) == "f64";
-
-x = "hello";
-if type_of(x) == "string" {
- do_something_with_string(x);
-}
-```
-
-
-Custom Types
-------------
-
-`type_of()` a [custom type] returns:
-
-* if registered via `Engine::register_type_with_name` – the registered name
-
-* if registered via `Engine::register_type` – the full Rust path name
-
-```rust
-struct TestStruct1;
-struct TestStruct2;
-
-engine
- // type_of(struct1) == "crate::path::to::module::TestStruct1"
- .register_type::()
- // type_of(struct2) == "MyStruct"
- .register_type_with_name::("MyStruct");
-```
diff --git a/doc/src/language/values-and-types.md b/doc/src/language/values-and-types.md
deleted file mode 100644
index fbae2013..00000000
--- a/doc/src/language/values-and-types.md
+++ /dev/null
@@ -1,42 +0,0 @@
-Values and Types
-===============
-
-{{#include ../links.md}}
-
-The following primitive types are supported natively:
-
-| Category | Equivalent Rust types | [`type_of()`] | `to_string()` |
-| -------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------- | --------------------- | ----------------------- |
-| **Integer number** | `u8`, `i8`, `u16`, `i16`, `u32`, `i32` (default for [`only_i32`]), `u64`, `i64` _(default)_ | `"i32"`, `"u64"` etc. | `"42"`, `"123"` etc. |
-| **Floating-point number** (disabled with [`no_float`]) | `f32` (default for [`f32_float`]), `f64` _(default)_ | `"f32"` or `"f64"` | `"123.4567"` etc. |
-| **Boolean value** | `bool` | `"bool"` | `"true"` or `"false"` |
-| **Unicode character** | `char` | `"char"` | `"A"`, `"x"` etc. |
-| **Immutable Unicode [string]** | `rhai::ImmutableString` (implemented as `Rc` or `Arc`) | `"string"` | `"hello"` etc. |
-| **[`Array`]** (disabled with [`no_index`]) | `rhai::Array` | `"array"` | `"[ ?, ?, ? ]"` |
-| **[Object map]** (disabled with [`no_object`]) | `rhai::Map` | `"map"` | `"#{ "a": 1, "b": 2 }"` |
-| **[Timestamp]** (implemented in the [`BasicTimePackage`][packages], disabled with [`no_std`]) | `std::time::Instant` ([`instant::Instant`] if [WASM] build) | `"timestamp"` | `""` |
-| **[Function pointer]** | `rhai::FnPtr` | `Fn` | `"Fn(foo)"` |
-| **[`Dynamic`] value** (i.e. can be anything) | `rhai::Dynamic` | _the actual type_ | _actual value_ |
-| **Shared value** (a reference-counted, shared [`Dynamic`] value, created via [automatic currying], disabled with [`no_closure`]) | | _the actual type_ | _actual value_ |
-| **System integer** (current configuration) | `rhai::INT` (`i32` or `i64`) | `"i32"` or `"i64"` | `"42"`, `"123"` etc. |
-| **System floating-point** (current configuration, disabled with [`no_float`]) | `rhai::FLOAT` (`f32` or `f64`) | `"f32"` or `"f64"` | `"123.456"` etc. |
-| **Nothing/void/nil/null/Unit** (or whatever it is called) | `()` | `"()"` | `""` _(empty string)_ |
-
-All types are treated strictly separate by Rhai, meaning that `i32` and `i64` and `u32` are completely different -
-they even cannot be added together. This is very similar to Rust.
-
-The default integer type is `i64`. If other integer types are not needed, it is possible to exclude them and make a
-smaller build with the [`only_i64`] feature.
-
-If only 32-bit integers are needed, enabling the [`only_i32`] feature will remove support for all integer types other than `i32`, including `i64`.
-This is useful on some 32-bit targets where using 64-bit integers incur a performance penalty.
-
-If no floating-point is needed or supported, use the [`no_float`] feature to remove it.
-
-[Strings] in Rhai are _immutable_, meaning that they can be shared but not modified. In actual, the `ImmutableString` type
-is an alias to `Rc` or `Arc` (depending on the [`sync`] feature).
-Any modification done to a Rhai string will cause the string to be cloned and the modifications made to the copy.
-
-The `to_string` function converts a standard type into a [string] for display purposes.
-
-The `to_debug` function converts a standard type into a [string] in debug format.
diff --git a/doc/src/language/variables.md b/doc/src/language/variables.md
deleted file mode 100644
index d2582906..00000000
--- a/doc/src/language/variables.md
+++ /dev/null
@@ -1,68 +0,0 @@
-Variables
-=========
-
-{{#include ../links.md}}
-
-Valid Names
------------
-
-Variables in Rhai follow normal C naming rules – must contain only ASCII letters, digits and underscores '`_`',
-and cannot start with a digit.
-
-For example: '`_c3po`' and '`r2d2`' are valid variable names, but '`3abc`' is not.
-
-However, unlike Rust, a variable name must also contain at least one ASCII letter, and an ASCII letter must come before any digit.
-In other words, the first character that is not an underscore '`_`' must be an ASCII letter and not a digit.
-
-Therefore, some names acceptable to Rust, like '`_`', '`_42foo`', '`_1`' etc., are not valid in Rhai.
-This restriction is to reduce confusion because, for instance, '`_1`' can easily be misread (or mis-typed) as `-1`.
-
-Variable names are case _sensitive_.
-
-Variable names also cannot be the same as a [keyword].
-
-### Unicode Standard Annex #31 Identifiers
-
-The [`unicode-xid-ident`] feature expands the allowed characters for variable names to the set defined by
-[Unicode Standard Annex #31](http://www.unicode.org/reports/tr31/).
-
-
-Declare a Variable
-------------------
-
-Variables are declared using the `let` keyword.
-
-Variables do not have to be given an initial value.
-If none is provided, it defaults to [`()`].
-
-A variable defined within a statement block is _local_ to that block.
-
-Use `is_def_var` to detect if a variable is defined.
-
-```rust
-let x; // ok - value is '()'
-let x = 3; // ok
-let _x = 42; // ok
-let x_ = 42; // also ok
-let _x_ = 42; // still ok
-
-let _ = 123; // <- syntax error: illegal variable name
-let _9 = 9; // <- syntax error: illegal variable name
-
-let x = 42; // variable is 'x', lower case
-let X = 123; // variable is 'X', upper case
-x == 42;
-X == 123;
-
-{
- let x = 999; // local variable 'x' shadows the 'x' in parent block
- x == 999; // access to local 'x'
-}
-x == 42; // the parent block's 'x' is not changed
-
-is_def_var("x") == true;
-
-is_def_var("_x") == true;
-
-is_def_var("y") == false;
-```
diff --git a/doc/src/language/while.md b/doc/src/language/while.md
deleted file mode 100644
index 5b7a5ac8..00000000
--- a/doc/src/language/while.md
+++ /dev/null
@@ -1,20 +0,0 @@
-`while` Loop
-============
-
-{{#include ../links.md}}
-
-`while` loops follow C syntax.
-
-Like C, `continue` can be used to skip to the next iteration, by-passing all following statements;
-`break` can be used to break out of the loop unconditionally.
-
-```rust
-let x = 10;
-
-while x > 0 {
- x -= 1;
- if x < 6 { continue; } // skip to the next iteration
- print(x);
- if x == 5 { break; } // break out of while loop
-}
-```
diff --git a/doc/src/links.md b/doc/src/links.md
deleted file mode 100644
index c2681d79..00000000
--- a/doc/src/links.md
+++ /dev/null
@@ -1,147 +0,0 @@
-[features]: {{rootUrl}}/start/features.md
-[`unchecked`]: {{rootUrl}}/start/features.md
-[`sync`]: {{rootUrl}}/start/features.md
-[`no_optimize`]: {{rootUrl}}/start/features.md
-[`no_float`]: {{rootUrl}}/start/features.md
-[`f32_float`]: {{rootUrl}}/start/features.md
-[`only_i32`]: {{rootUrl}}/start/features.md
-[`only_i64`]: {{rootUrl}}/start/features.md
-[`no_index`]: {{rootUrl}}/start/features.md
-[`no_object`]: {{rootUrl}}/start/features.md
-[`no_function`]: {{rootUrl}}/start/features.md
-[`no_module`]: {{rootUrl}}/start/features.md
-[`no_closure`]: {{rootUrl}}/start/features.md
-[`no_std`]: {{rootUrl}}/start/features.md
-[`no-std`]: {{rootUrl}}/start/features.md
-[`metadata`]: {{rootUrl}}/start/features.md
-[`internals`]: {{rootUrl}}/start/features.md
-[`unicode-xid-ident`]: {{rootUrl}}/start/features.md
-
-[minimal builds]: {{rootUrl}}/start/builds/minimal.md
-[WASM]: {{rootUrl}}/start/builds/wasm.md
-[playground]: https://alvinhochun.github.io/rhai-demo
-
-[`Engine`]: {{rootUrl}}/engine/hello-world.md
-[traits]: {{rootUrl}}/rust/traits.md
-[`private`]: {{rootUrl}}/engine/call-fn.md
-[`call_fn`]: {{rootUrl}}/engine/call-fn.md
-[`Func`]: {{rootUrl}}/engine/func.md
-[`AST`]: {{rootUrl}}/engine/compile.md
-[`eval_expression`]: {{rootUrl}}/engine/expressions.md
-[`eval_expression_with_scope`]: {{rootUrl}}/engine/expressions.md
-[raw `Engine`]: {{rootUrl}}/engine/raw.md
-[built-in operators]: {{rootUrl}}/engine/raw.md#built-in-operators
-[package]: {{rootUrl}}/rust/packages/index.md
-[packages]: {{rootUrl}}/rust/packages/index.md
-[custom package]: {{rootUrl}}/rust/packages/create.md
-[custom packages]: {{rootUrl}}/rust/packages/create.md
-[plugin]: {{rootUrl}}/plugins/index.md
-[plugins]: {{rootUrl}}/plugins/index.md
-[plugin module]: {{rootUrl}}/plugins/module.md
-[plugin modules]: {{rootUrl}}/plugins/module.md
-[plugin function]: {{rootUrl}}/plugins/function.md
-[plugin functions]: {{rootUrl}}/plugins/function.md
-[functions metadata]: {{rootUrl}}/engine/metadata/index.md
-[`Scope`]: {{rootUrl}}/engine/scope.md
-[`serde`]: {{rootUrl}}/rust/serde.md
-
-[`type_of()`]: {{rootUrl}}/language/type-of.md
-[`to_string()`]: {{rootUrl}}/language/values-and-types.md
-[`()`]: {{rootUrl}}/language/values-and-types.md
-[standard types]: {{rootUrl}}/language/values-and-types.md
-[`Dynamic`]: {{rootUrl}}/language/dynamic.md
-[`to_int`]: {{rootUrl}}/language/convert.md
-[`to_float`]: {{rootUrl}}/language/convert.md
-[`parse_int`]: {{rootUrl}}/language/convert.md
-[`parse_float`]: {{rootUrl}}/language/convert.md
-
-[custom type]: {{rootUrl}}/rust/custom.md
-[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
-
-[`print`]: {{rootUrl}}/language/print-debug.md
-[`debug`]: {{rootUrl}}/language/print-debug.md
-
-[keywords]: {{rootUrl}}/appendix/keywords.md
-[keyword]: {{rootUrl}}/appendix/keywords.md
-
-[variable]: {{rootUrl}}/language/variables.md
-[variables]: {{rootUrl}}/language/variables.md
-[constant]: {{rootUrl}}/language/constants.md
-[constants]: {{rootUrl}}/language/constants.md
-
-[string]: {{rootUrl}}/language/strings-chars.md
-[strings]: {{rootUrl}}/language/strings-chars.md
-[char]: {{rootUrl}}/language/strings-chars.md
-
-[array]: {{rootUrl}}/language/arrays.md
-[arrays]: {{rootUrl}}/language/arrays.md
-[`Array`]: {{rootUrl}}/language/arrays.md
-
-[`Map`]: {{rootUrl}}/language/object-maps.md
-[object map]: {{rootUrl}}/language/object-maps.md
-[object maps]: {{rootUrl}}/language/object-maps.md
-
-[`timestamp`]: {{rootUrl}}/language/timestamps.md
-[timestamp]: {{rootUrl}}/language/timestamps.md
-[timestamps]: {{rootUrl}}/language/timestamps.md
-
-[doc-comments]: {{rootUrl}}/language/doc-comments.md
-[function]: {{rootUrl}}/language/functions.md
-[functions]: {{rootUrl}}/language/functions.md
-[function overloading]: {{rootUrl}}/rust/functions.md#function-overloading
-[fallible function]: {{rootUrl}}/rust/fallible.md
-[fallible functions]: {{rootUrl}}/rust/fallible.md
-[`throw`]: {{rootUrl}}/language/throw.md
-[exception]: {{rootUrl}}/language/throw.md
-[exceptions]: {{rootUrl}}/language/throw.md
-[function pointer]: {{rootUrl}}/language/fn-ptr.md
-[function pointers]: {{rootUrl}}/language/fn-ptr.md
-[currying]: {{rootUrl}}/language/fn-curry.md
-[capture]: {{rootUrl}}/language/fn-capture.md
-[automatic currying]: {{rootUrl}}/language/fn-closure.md
-[closure]: {{rootUrl}}/language/fn-closure.md
-[closures]: {{rootUrl}}/language/fn-closure.md
-[function namespace]: {{rootUrl}}/language/fn-namespaces.md
-[function namespaces]: {{rootUrl}}/language/fn-namespaces.md
-[anonymous function]: {{rootUrl}}/language/fn-anon.md
-[anonymous functions]: {{rootUrl}}/language/fn-anon.md
-[operator overloading]: {{rootUrl}}/rust/operators.md
-
-[`Module`]: {{rootUrl}}/rust/modules/index.md
-[module]: {{rootUrl}}/rust/modules/index.md
-[modules]: {{rootUrl}}/rust/modules/index.md
-[module resolver]: {{rootUrl}}/rust/modules/resolvers.md
-[variable resolver]: {{rootUrl}}/engine/var.md
-[`export`]: {{rootUrl}}/language/modules/export.md
-[`import`]: {{rootUrl}}/language/modules/import.md
-
-[`eval`]: {{rootUrl}}/language/eval.md
-
-[OOP]: {{rootUrl}}/patterns/oop.md
-[DSL]: {{rootUrl}}/engine/dsl.md
-
-[sand-boxed]: {{rootUrl}}/safety/sandbox.md
-[maximum statement depth]: {{rootUrl}}/safety/max-stmt-depth.md
-[maximum call stack depth]: {{rootUrl}}/safety/max-call-stack.md
-[maximum number of operations]: {{rootUrl}}/safety/max-operations.md
-[maximum number of modules]: {{rootUrl}}/safety/max-modules.md
-[maximum length of strings]: {{rootUrl}}/safety/max-string-size.md
-[maximum size of arrays]: {{rootUrl}}/safety/max-array-size.md
-[maximum size of object maps]: {{rootUrl}}/safety/max-map-size.md
-[progress]: {{rootUrl}}/safety/progress.md
-
-[script optimization]: {{rootUrl}}/engine/optimize/index.md
-[`OptimizationLevel::Full`]: {{rootUrl}}/engine/optimize/optimize-levels.md
-[`OptimizationLevel::Simple`]: {{rootUrl}}/engine/optimize/optimize-levels.md
-[`OptimizationLevel::None`]: {{rootUrl}}/engine/optimize/optimize-levels.md
-
-[disable keywords and operators]: {{rootUrl}}/engine/disable.md
-[custom operator]: {{rootUrl}}/engine/custom-op.md
-[custom operators]: {{rootUrl}}/engine/custom-op.md
-[custom syntax]: {{rootUrl}}/engine/custom-syntax.md
diff --git a/doc/src/patterns/config.md b/doc/src/patterns/config.md
deleted file mode 100644
index 6af3ae10..00000000
--- a/doc/src/patterns/config.md
+++ /dev/null
@@ -1,163 +0,0 @@
-Loadable Configuration
-======================
-
-{{#include ../links.md}}
-
-
-Usage Scenario
---------------
-
-* A system where settings and configurations are complex and logic-driven.
-
-* Where said system is too complex to configure via standard configuration file formats such as `JSON`, `TOML` or `YAML`.
-
-* The system is complex enough to require a full programming language to configure. Essentially _configuration by code_.
-
-* Yet the configuration must be flexible, late-bound and dynamically loadable, just like a configuration file.
-
-
-Key Concepts
-------------
-
-* Leverage the loadable [modules] of Rhai. The [`no_module`] feature must not be on.
-
-* Expose the configuration API. Use separate scripts to configure that API. Dynamically load scripts via the `import` statement.
-
-* Leverage [function overloading] to simplify the API design.
-
-* Since Rhai is _sand-boxed_, it cannot mutate the environment. To modify the external configuration object via an API, it must be wrapped in a `RefCell` (or `RwLock`/`Mutex` for [`sync`]) and shared to the [`Engine`].
-
-
-Implementation
---------------
-
-### Configuration Type
-
-```rust
-#[derive(Debug, Clone, Default)]
-struct Config {
- pub id: String;
- pub some_field: i64;
- pub some_list: Vec;
- pub some_map: HashMap;
-}
-```
-
-### Make Shared Object
-
-```rust
-pub type SharedConfig = Rc>;
-```
-
-Note: Use `Arc>` or `Arc>` when using the [`sync`] feature because the function
-must then be `Send + Sync`.
-
-```rust
-let config: SharedConfig = Rc::new(RefCell::new(Default::default()));
-```
-
-### Register Config API
-
-The trick to building a Config API is to clone the shared configuration object and
-move it into each function registration via a closure.
-
-Therefore, it is not possible to use a [plugin module] to achieve this, and each function must
-be registered one after another.
-
-```rust
-// Notice 'move' is used to move the shared configuration object into the closure.
-let cfg = config.clone();
-engine.register_fn("config_set_id", move |id: String| *cfg.borrow_mut().id = id);
-
-let cfg = config.clone();
-engine.register_fn("config_get_id", move || cfg.borrow().id.clone());
-
-let cfg = config.clone();
-engine.register_fn("config_set", move |value: i64| *cfg.borrow_mut().some_field = value);
-
-// Remember Rhai functions can be overloaded when designing the API.
-
-let cfg = config.clone();
-engine.register_fn("config_add", move |value: String|
- cfg.borrow_mut().some_list.push(value)
-);
-
-let cfg = config.clone();
-engine.register_fn("config_add", move |values: &mut Array|
- cfg.borrow_mut().some_list.extend(values.into_iter().map(|v| v.to_string()))
-);
-
-let cfg = config.clone();
-engine.register_fn("config_add", move |key: String, value: bool|
- cfg.borrow_mut().some_map.insert(key, value)
-);
-
-let cfg = config.clone();
-engine.register_fn("config_contains", move |value: String|
- cfg.borrow().some_list.contains(&value)
-);
-
-let cfg = config.clone();
-engine.register_fn("config_is_set", move |value: String|
- cfg.borrow().some_map.get(&value).cloned().unwrap_or(false)
-);
-```
-
-### Configuration Script
-
-```rust
-------------------
-| my_config.rhai |
-------------------
-
-config_set_id("hello");
-
-config_add("foo"); // add to list
-config_add("bar", true); // add to map
-
-if config_contains("hey") || config_is_set("hey") {
- config_add("baz", false); // add to map
-}
-```
-
-### Load the Configuration
-
-```rust
-import "my_config"; // run configuration script without creating a module
-
-let id = config_get_id();
-
-id == "hello";
-```
-
-
-Consider a Custom Syntax
-------------------------
-
-This is probably one of the few scenarios where a [custom syntax] can be recommended.
-
-A properly-designed [custom syntax] can make the configuration file clean, simple to write,
-easy to understand and quick to modify.
-
-For example, the above configuration example may be expressed by this custom syntax:
-
-```rust
-------------------
-| my_config.rhai |
-------------------
-
-// Configure ID
-id "hello";
-
-// Add to list
-list + "foo";
-
-// Add to map
-map "bar" => true;
-
-if config contains "hey" || config is_set "hey" {
- map "baz" => false;
-}
-```
-
-Notice that `contains` and `is_set` may be implemented as a [custom operator].
diff --git a/doc/src/patterns/control.md b/doc/src/patterns/control.md
deleted file mode 100644
index 25d73231..00000000
--- a/doc/src/patterns/control.md
+++ /dev/null
@@ -1,144 +0,0 @@
-Scriptable Control Layer
-========================
-
-{{#include ../links.md}}
-
-
-Usage Scenario
---------------
-
-* A system provides core functionalities, but no driving logic.
-
-* The driving logic must be dynamic and hot-loadable.
-
-* A script is used to drive the system and provide control intelligence.
-
-
-Key Concepts
-------------
-
-* Expose a Control API.
-
-* Leverage [function overloading] to simplify the API design.
-
-* Since Rhai is _[sand-boxed]_, it cannot mutate the environment. To perform external actions via an API, the actual system must be wrapped in a `RefCell` (or `RwLock`/`Mutex` for [`sync`]) and shared to the [`Engine`].
-
-
-Implementation
---------------
-
-There are two broad ways for Rhai to control an external system, both of which involve
-wrapping the system in a shared, interior-mutated object.
-
-This is one way which does not involve exposing the data structures of the external system,
-but only through exposing an abstract API primarily made up of functions.
-
-Use this when the API is relatively simple and clean, and the number of functions is small enough.
-
-For a complex API involving lots of functions, or an API that has a clear object structure,
-use the [Singleton Command Object]({{rootUrl}}/patterns/singleton.md) pattern instead.
-
-
-### Functional API
-
-Assume that a system provides the following functional API:
-
-```rust
-struct EnergizerBunny;
-
-impl EnergizerBunny {
- pub fn new () -> Self { ... }
- pub fn go (&mut self) { ... }
- pub fn stop (&mut self) { ... }
- pub fn is_going (&self) { ... }
- pub fn get_speed (&self) -> i64 { ... }
- pub fn set_speed (&mut self, speed: i64) { ... }
-}
-```
-
-### Wrap API in Shared Object
-
-```rust
-pub type SharedBunny = Rc>;
-```
-
-Note: Use `Arc>` or `Arc>` when using the [`sync`] feature because the function
-must then be `Send + Sync`.
-
-```rust
-let bunny: SharedBunny = Rc::new(RefCell::(EnergizerBunny::new()));
-```
-
-### Register Control API
-
-The trick to building a Control API is to clone the shared API object and
-move it into each function registration via a closure.
-
-Therefore, it is not possible to use a [plugin module] to achieve this, and each function must
-be registered one after another.
-
-```rust
-// Notice 'move' is used to move the shared API object into the closure.
-let b = bunny.clone();
-engine.register_fn("bunny_power", move |on: bool| {
- if on {
- if b.borrow().is_going() {
- println!("Still going...");
- } else {
- b.borrow_mut().go();
- }
- } else {
- if b.borrow().is_going() {
- b.borrow_mut().stop();
- } else {
- println!("Already out of battery!");
- }
- }
-});
-
-let b = bunny.clone();
-engine.register_fn("bunny_is_going", move || b.borrow().is_going());
-
-let b = bunny.clone();
-engine.register_fn("bunny_get_speed", move ||
- if b.borrow().is_going() { b.borrow().get_speed() } else { 0 }
-);
-
-let b = bunny.clone();
-engine.register_result_fn("bunny_set_speed", move |speed: i64|
- if speed <= 0 {
- return Err("Speed must be positive!".into());
- } else if speed > 100 {
- return Err("Bunny will be going too fast!".into());
- }
-
- if b.borrow().is_going() {
- b.borrow_mut().set_speed(speed)
- } else {
- return Err("Bunny is not yet going!".into());
- }
-
- Ok(Dynamic::UNIT)
-);
-```
-
-### Use the API
-
-```rust
-if !bunny_is_going() { bunny_power(true); }
-
-if bunny_get_speed() > 50 { bunny_set_speed(50); }
-```
-
-
-Caveat
-------
-
-Although this usage pattern appears a perfect fit for _game_ logic, avoid writing the
-_entire game_ in Rhai. Performance will not be acceptable.
-
-Implement as much functionalities of the game engine in Rust as possible.
-Rhai integrates well with Rust so this is usually not a hinderance.
-
-Lift as much out of Rhai as possible.
-Use Rhai only for the logic that _must_ be dynamic or hot-loadable.
diff --git a/doc/src/patterns/dynamic-const.md b/doc/src/patterns/dynamic-const.md
deleted file mode 100644
index e3fe7c06..00000000
--- a/doc/src/patterns/dynamic-const.md
+++ /dev/null
@@ -1,56 +0,0 @@
-Dynamic Constants Provider
-=========================
-
-{{#include ../links.md}}
-
-
-Usage Scenario
---------------
-
-* A system has a _large_ number of constants, but only a minor set will be used by any script.
-
-* The system constants are expensive to load.
-
-* The system constants set is too massive to push into a custom [`Scope`].
-
-* The values of system constants are volatile and call-dependent.
-
-
-Key Concepts
-------------
-
-* Use a [variable resolver] to intercept variable access.
-
-* Only load a variable when it is being used.
-
-* Perform a lookup based on variable name, and provide the correct data value.
-
-* May even perform back-end network access or look up the latest value from a database.
-
-
-Implementation
---------------
-
-```rust
-let mut engine = Engine::new();
-
-// Create shared data provider.
-// Assume that SystemValuesProvider::get(&str) -> Option gets a value.
-let provider = Arc::new(SystemValuesProvider::new());
-
-// Clone the shared provider
-let db = provider.clone();
-
-// Register a variable resolver.
-// Move the shared provider into the closure.
-engine.on_var(move |name, _, _, _| Ok(db.get(name).map(Dynamic::from)));
-```
-
-
-Values are Constants
---------------------
-
-All values provided by a [variable resolver] are _constants_ due to their dynamic nature.
-They cannot be assigned to.
-
-In order to change values in an external system, register a dedicated API for that purpose.
diff --git a/doc/src/patterns/enums.md b/doc/src/patterns/enums.md
deleted file mode 100644
index d76e62f9..00000000
--- a/doc/src/patterns/enums.md
+++ /dev/null
@@ -1,237 +0,0 @@
-Working With Rust Enums
-=======================
-
-{{#include ../links.md}}
-
-Enums in Rust are typically used with _pattern matching_. Rhai is dynamic, so although
-it integrates with Rust enum variants just fine (treated transparently as [custom types]),
-it is impossible (short of registering a complete API) to distinguish between individual
-enum variants or to extract internal data from them.
-
-
-Simulate an Enum API
---------------------
-
-A [plugin module] is extremely handy in creating an entire API for a custom enum type.
-
-```rust
-use rhai::{Engine, Dynamic, EvalAltResult};
-use rhai::plugin::*;
-
-#[derive(Debug, Clone, Eq, PartialEq, Hash)]
-enum MyEnum {
- Foo,
- Bar(i64),
- Baz(String, bool)
-}
-
-// Create a plugin module with functions constructing the 'MyEnum' variants
-#[export_module]
-mod MyEnumModule {
- // Constructors for 'MyEnum' variants
- pub const Foo: &MyEnum = MyEnum::Foo;
- pub fn Bar(value: i64) -> MyEnum {
- MyEnum::Bar(value)
- }
- pub fn Baz(val1: String, val2: bool) -> MyEnum {
- MyEnum::Baz(val1, val2)
- }
- // Access to fields
- #[rhai_fn(get = "enum_type")]
- pub fn get_type(a: &mut MyEnum) -> String {
- match a {
- MyEnum::Foo => "Foo".to_string(),
- MyEnum::Bar(_) => "Bar".to_string(),
- MyEnum::Baz(_, _) => "Baz".to_string()
- }
- }
- #[rhai_fn(get = "field_0")]
- pub fn get_field_0(a: &mut MyEnum) -> Dynamic {
- match a {
- MyEnum::Foo => Dynamic::UNIT,
- MyEnum::Bar(x) => Dynamic::from(x),
- MyEnum::Baz(x, _) => Dynamic::from(x)
- }
- }
- #[rhai_fn(get = "field_1")]
- pub fn get_field_1(a: &mut MyEnum) -> Dynamic {
- match a {
- MyEnum::Foo | MyEnum::Bar(_) => Dynamic::UNIT,
- MyEnum::Baz(_, x) => Dynamic::from(x)
- }
- }
- // Printing
- #[rhai(global, name = "to_string", name = "print", name = "to_debug", name = "debug")]
- pub fn to_string(a: &mut MyEnum) -> String {
- format!("{:?}", a))
- }
- #[rhai_fn(global, name = "+")]
- pub fn add_to_str(s: &str, a: MyEnum) -> String {
- format!("{}{:?}", s, a))
- }
- #[rhai_fn(global, name = "+")]
- pub fn add_str(a: &mut MyEnum, s: &str) -> String {
- format!("{:?}", a).push_str(s))
- }
- #[rhai_fn(global, name = "+=")]
- pub fn append_to_str(s: &mut ImmutableString, a: MyEnum) -> String {
- s += a.to_string())
- }
- // '==' and '!=' operators
- #[rhai_fn(global, name = "==")]
- pub fn eq(a: &mut MyEnum, b: MyEnum) -> bool {
- a == &b
- }
- #[rhai_fn(global, name = "!=")]
- pub fn neq(a: &mut MyEnum, b: MyEnum) -> bool {
- a != &b
- }
- // Array functions
- #[rhai_fn(global, name = "push")]
- pub fn append_to_array(list: &mut Array, item: MyEnum) {
- list.push(Dynamic::from(item)));
- }
- #[rhai_fn(global, name = "+=")]
- pub fn append_to_array_op(list: &mut Array, item: MyEnum) {
- list.push(Dynamic::from(item)));
- }
- #[rhai_fn(global, name = "insert")]
- pub fn insert_to_array(list: &mut Array, position: i64, item: MyEnum) {
- if position <= 0 {
- list.insert(0, Dynamic::from(item));
- } else if (position as usize) >= list.len() - 1 {
- list.push(item);
- } else {
- list.insert(position as usize, Dynamic::from(item));
- }
- }
- #[rhai_fn(global, name = "pad")]
- pub fn pad_array(list: &mut Array, len: i64, item: MyEnum) {
- if len as usize > list.len() { list.resize(len as usize, item); }
- }
-}
-
-let mut engine = Engine::new();
-
-// Load the module as the module namespace "MyEnum"
-engine
- .register_type_with_name::("MyEnum")
- .register_static_module("MyEnum", exported_module!(MyEnumModule).into());
-```
-
-With this API in place, working with enums feels almost the same as in Rust:
-
-```rust
-let x = MyEnum::Foo;
-
-let y = MyEnum::Bar(42);
-
-let z = MyEnum::Baz("hello", true);
-
-x == MyEnum::Foo;
-
-y != MyEnum::Bar(0);
-
-// Detect enum types
-
-x.enum_type == "Foo";
-
-y.enum_type == "Bar";
-
-z.enum_type == "Baz";
-
-// Extract enum fields
-
-y.field_0 == 42;
-
-y.field_1 == ();
-
-z.field_0 == "hello";
-
-z.field_1 == true;
-```
-
-Since enums are internally treated as [custom types], they are not _literals_ and cannot be
-used as a match case in `switch` expressions. This is quite a limitation because the equivalent
-`match` statement is commonly used in Rust to work with enums and bind variables to
-variant-internal data.
-
-It is possible, however, to `switch` through enum variants based on their types:
-
-```c
-switch x.enum_type {
- "Foo" => ...,
- "Bar" => {
- let value = foo.field_0;
- ...
- }
- "Baz" => {
- let val1 = foo.field_0;
- let val2 = foo.field_1;
- ...
- }
-}
-```
-
-
-Use `switch` Through Arrays
----------------------------
-
-Another way to work with Rust enums in a `switch` expression is through exposing the internal data
-(or at least those that act as effective _discriminants_) of each enum variant as a variable-length
-[array], usually with the name of the variant as the first item for convenience:
-
-```rust
-use rhai::Array;
-
-engine.register_get("enum_data", |x: &mut Enum| {
- match x {
- Enum::Foo => vec![ "Foo".into() ] as Array,
-
- // Say, skip the data field because it is not
- // used as a discriminant
- Enum::Bar(value) => vec![ "Bar".into() ] as Array,
-
- // Say, all fields act as discriminants
- Enum::Baz(val1, val2) => vec![
- "Baz".into(), val1.clone().into(), (*val2).into()
- ] as Array
- }
-});
-```
-
-Then it is a simple matter to match an enum via the `switch` expression:
-
-```c
-// Assume 'value' = 'MyEnum::Baz("hello", true)'
-// 'enum_data' creates a variable-length array with 'MyEnum' data
-let x = switch value.enum_data {
- ["Foo"] => 1,
- ["Bar"] => value.field_1,
- ["Baz", "hello", false] => 4,
- ["Baz", "hello", true] => 5,
- _ => 9
-};
-
-x == 5;
-
-// Which is essentially the same as:
-let x = switch [value.type, value.field_0, value.field_1] {
- ["Foo", (), ()] => 1,
- ["Bar", 42, ()] => 42,
- ["Bar", 123, ()] => 123,
- :
- ["Baz", "hello", false] => 4,
- ["Baz", "hello", true] => 5,
- _ => 9
-}
-```
-
-Usually, a helper method returns an array of values that can uniquely determine
-the switch case based on actual usage requirements – which means that it probably
-skips fields that contain data instead of discriminants.
-
-Then `switch` is used to very quickly match through a large number of array shapes
-and jump to the appropriate case implementation.
-
-Data fields can then be extracted from the enum independently.
diff --git a/doc/src/patterns/events.md b/doc/src/patterns/events.md
deleted file mode 100644
index 24574612..00000000
--- a/doc/src/patterns/events.md
+++ /dev/null
@@ -1,202 +0,0 @@
-Scriptable Event Handler with State
-==================================
-
-{{#include ../links.md}}
-
-
-Usage Scenario
---------------
-
-* A system sends _events_ that must be handled.
-
-* Flexibility in event handling must be provided, through user-side scripting.
-
-* State must be kept between invocations of event handlers.
-
-* Default implementations of event handlers can be provided.
-
-
-Key Concepts
-------------
-
-* An _event handler_ object is declared that holds the following items:
- * [`Engine`] with registered functions serving as an API,
- * [`AST`] of the user script,
- * a [`Scope`] containing state.
-
-* Upon an event, the appropriate event handler function in the script is called via [`Engine::call_fn`][`call_fn`].
-
-* Optionally, trap the `EvalAltResult::ErrorFunctionNotFound` error to provide a default implementation.
-
-
-Implementation
---------------
-
-### Declare Handler Object
-
-In most cases, it would be simpler to store an [`Engine`] instance together with the handler object
-because it only requires registering all API functions only once.
-
-In rare cases where handlers are created and destroyed in a tight loop, a new [`Engine`] instance
-can be created for each event. See [_One Engine Instance Per Call_](parallel.md) for more details.
-
-```rust
-use rhai::{Engine, Scope, AST, EvalAltResult};
-
-// Event handler
-struct Handler {
- // Scripting engine
- pub engine: Engine,
- // Use a custom 'Scope' to keep stored state
- pub scope: Scope<'static>,
- // Program script
- pub ast: AST
-}
-```
-
-### Register API for Any Custom Type
-
-[Custom types] are often used to hold state. The easiest way to register an entire API is via a [plugin module].
-
-```rust
-use rhai::plugin::*;
-
-// A custom type to a hold state value.
-#[derive(Debug, Clone, Eq, PartialEq, Hash, Default)]
-pub struct SomeType {
- data: i64;
-}
-
-#[export_module]
-mod SomeTypeAPI {
- #[rhai_fn(global)]
- pub func1(obj: &mut SomeType) -> bool { ... }
- #[rhai_fn(global)]
- pub func2(obj: &mut SomeType) -> bool { ... }
- pub process(data: i64) -> i64 { ... }
- #[rhai_fn(get = "value")]
- pub get_value(obj: &mut SomeType) -> i64 { obj.data }
- #[rhai_fn(set = "value")]
- pub set_value(obj: &mut SomeType, value: i64) { obj.data = value; }
-}
-```
-
-### Initialize Handler Object
-
-Steps to initialize the event handler:
-
-1. Register an API with the [`Engine`],
-2. Create a custom [`Scope`] to serve as the stored state,
-3. Add default state variables into the custom [`Scope`],
-4. Get the handler script and [compile][`AST`] it,
-5. Store the compiled [`AST`] for future evaluations,
-6. Run the [`AST`] to initialize event handler state variables.
-
-```rust
-impl Handler {
- pub new(path: impl Into) -> Self {
- let mut engine = Engine::new();
-
- // Register custom types and API's
- engine
- .register_type_with_name::("SomeType")
- .register_global_module(exported_module!(SomeTypeAPI));
-
- // Create a custom 'Scope' to hold state
- let mut scope = Scope::new();
-
- // Add initialized state into the custom 'Scope'
- scope.push("state1", false);
- scope.push("state2", SomeType::new(42));
-
- // Compile the handler script.
- // In a real application you'd be handling errors...
- let ast = engine.compile_file(path).unwrap();
-
- // Evaluate the script to initialize it and other state variables.
- // In a real application you'd again be handling errors...
- engine.consume_ast_with_scope(&mut scope, &ast).unwrap();
-
- // The event handler is essentially these three items:
- Handler { engine, scope, ast }
- }
-}
-```
-
-### Hook up events
-
-There is usually an interface or trait that gets called when an event comes from the system.
-
-Mapping an event from the system into a scripted handler is straight-forward:
-
-```rust
-impl Handler {
- // Say there are three events: 'start', 'end', 'update'.
- // In a real application you'd be handling errors...
- pub fn on_event(&mut self, event_name: &str, event_data: i64) -> Result<(), Error> {
- let engine = &self.engine;
- let scope = &mut self.scope;
- let ast = &self.ast;
-
- match event_name {
- // The 'start' event maps to function 'start'.
- // In a real application you'd be handling errors...
- "start" => engine.call_fn(scope, ast, "start", (event_data,))?,
-
- // The 'end' event maps to function 'end'.
- // In a real application you'd be handling errors...
- "end" => engine.call_fn(scope, ast, "end", (event_data,))?,
-
- // The 'update' event maps to function 'update'.
- // This event provides a default implementation when the scripted function
- // is not found.
- "update" =>
- engine.call_fn(scope, ast, "update", (event_data,))
- .or_else(|err| match *err {
- EvalAltResult::ErrorFunctionNotFound(fn_name, _) if fn_name == "update" => {
- // Default implementation of 'update' event handler
- self.scope.set_value("state2", SomeType::new(42));
- // Turn function-not-found into a success
- Ok(Dynamic::UNIT)
- }
- _ => Err(err.into())
- })?
- }
- }
-}
-```
-
-### Sample Handler Script
-
-Because the stored state is kept in a custom [`Scope`], it is possible for all functions defined
-in the handler script to access and modify these state variables.
-
-The API registered with the [`Engine`] can be also used throughout the script.
-
-```rust
-fn start(data) {
- if state1 {
- throw "Already started!";
- }
- if state2.func1() || state2.func2() {
- throw "Conditions not yet ready to start!";
- }
- state1 = true;
- state2.value = data;
-}
-
-fn end(data) {
- if !state1 {
- throw "Not yet started!";
- }
- if state2.func1() || state2.func2() {
- throw "Conditions not yet ready to start!";
- }
- state1 = false;
- state2.value = data;
-}
-
-fn update(data) {
- state2.value += process(data);
-}
-```
diff --git a/doc/src/patterns/index.md b/doc/src/patterns/index.md
deleted file mode 100644
index fb651ae8..00000000
--- a/doc/src/patterns/index.md
+++ /dev/null
@@ -1,7 +0,0 @@
-Usage Patterns
-==============
-
-{{#include ../links.md}}
-
-
-Leverage the full power and flexibility of Rhai in different scenarios.
diff --git a/doc/src/patterns/multi-layer.md b/doc/src/patterns/multi-layer.md
deleted file mode 100644
index 9092ca82..00000000
--- a/doc/src/patterns/multi-layer.md
+++ /dev/null
@@ -1,117 +0,0 @@
-Multi-Layer Functions
-=====================
-
-{{#include ../links.md}}
-
-
-Usage Scenario
---------------
-
-* A system is divided into separate _layers_, each providing logic in terms of scripted [functions].
-
-* A lower layer provides _default implementations_ of certain functions.
-
-* Higher layers each provide progressively more specific implementations of the same functions.
-
-* A more specific function, if defined in a higher layer, always overrides the implementation in a lower layer.
-
-* This is akin to object-oriented programming but with functions.
-
-* This type of system is extremely convenient for dynamic business rules configuration, setting corporate-wide
- policies, granting permissions for specific roles etc. where specific, local rules need to override
- corporate-wide defaults.
-
-
-Key Concepts
-------------
-
-* Each layer is a separate script.
-
-* The lowest layer script is compiled into a base [`AST`].
-
-* Higher layer scripts are also compiled into [`AST`] and _combined_ into the base using `AST::combine`
- (or the `+=` operator), overriding any existing functions.
-
-
-Examples
---------
-
-Assume the following four scripts:
-
-```rust
-----------------
-| default.rhai |
-----------------
-
-// Default implementation of 'foo'.
-fn foo(x) { x + 1 }
-
-// Default implementation of 'bar'.
-fn bar(x, y) { x + y }
-
-// Default implementation of 'no_touch'.
-fn no_touch() { throw "do not touch me!"; }
-
-
----------------
-| lowest.rhai |
----------------
-
-// Specific implementation of 'foo'.
-fn foo(x) { x * 2 }
-
-// New implementation for this layer.
-fn baz() { print("hello!"); }
-
-
----------------
-| middle.rhai |
----------------
-
-// Specific implementation of 'bar'.
-fn bar(x, y) { x - y }
-
-// Specific implementation of 'baz'.
-fn baz() { print("hey!"); }
-
-
-----------------
-| highest.rhai |
-----------------
-
-// Specific implementation of 'foo'.
-fn foo(x) { x + 42 }
-```
-
-Load and combine them sequentially:
-
-```rust
-let engine = Engine::new();
-
-// Compile the baseline default implementations.
-let mut ast = engine.compile_file("default.rhai".into())?;
-
-// Combine the first layer.
-let lowest = engine.compile_file("lowest.rhai".into())?;
-ast += lowest;
-
-// Combine the second layer.
-let middle = engine.compile_file("middle.rhai".into())?;
-ast += lowest;
-
-// Combine the third layer.
-let highest = engine.compile_file("highest.rhai".into())?;
-ast += lowest;
-
-// Now, 'ast' contains the following functions:
-//
-// fn no_touch() { // from 'default.rhai'
-// throw "do not touch me!";
-// }
-// fn foo(x) { x + 42 } // from 'highest.rhai'
-// fn bar(x, y) { x - y } // from 'middle.rhai'
-// fn baz() { print("hey!"); } // from 'middle.rhai'
-```
-
-Unfortunately, there is no `super` call that calls the base implementation
-(i.e. no way for a higher-layer function to call an equivalent lower-layer function).
diff --git a/doc/src/patterns/multiple.md b/doc/src/patterns/multiple.md
deleted file mode 100644
index dad53501..00000000
--- a/doc/src/patterns/multiple.md
+++ /dev/null
@@ -1,89 +0,0 @@
-Multiple Instantiation
-======================
-
-{{#include ../links.md}}
-
-
-Background
-----------
-
-Rhai's [features] are not strictly additive. This is easily deduced from the [`no_std`] feature
-which prepares the crate for `no-std` builds. Obviously, turning on this feature has a material
-impact on how Rhai behaves.
-
-Many crates resolve this by going the opposite direction: build for `no-std` in default,
-but add a `std` feature, included by default, which builds for the `stdlib`.
-
-
-Rhai Language Features Are Not Additive
---------------------------------------
-
-Rhai, however, is more complex. Language features cannot be easily made _additive_.
-
-That is because the _lack_ of a language feature is a feature by itself.
-
-For example, by including [`no_float`], a project sets the Rhai language to ignore floating-point math.
-Floating-point numbers do not even parse under this case and will generate syntax errors.
-Assume that the project expects this behavior (why? perhaps integers are all that make sense
-within the project domain).
-
-Now, assume that a dependent crate also depends on Rhai. Under such circumstances,
-unless _exact_ versioning is used and the dependent crate depends on a _different_ version
-of Rhai, Cargo automatically _merges_ both dependencies, with the [`no_float`] feature turned on
-because Cargo features are _additive_.
-
-This will break the dependent crate, which does not by itself specify [`no_float`]
-and expects floating-point numbers and math to work normally.
-
-There is no way out of this dilemma. Reversing the [features] set with a `float` feature
-causes the project to break because floating-point numbers are not rejected as expected.
-
-
-Multiple Instantiations of Rhai Within The Same Project
-------------------------------------------------------
-
-The trick is to differentiate between multiple identical copies of Rhai, each having
-a different [features] set, by their _sources_:
-
-* Different versions from [`crates.io`](https://crates.io/crates/rhai/) – The official crate.
-
-* Different releases from [`GitHub`](https://github.com/rhaiscript/rhai) – Crate source on GitHub.
-
-* Forked copy of [https://github.com/rhaiscript/rhai](https://github.com/rhaiscript/rhai) on GitHub.
-
-* Local copy of [https://github.com/rhaiscript/rhai](https://github.com/rhaiscript/rhai) downloaded form GitHub.
-
-Use the following configuration in `Cargo.toml` to pull in multiple copies of Rhai within the same project:
-
-```toml
-[dependencies]
-rhai = { version = "{{version}}", features = [ "no_float" ] }
-rhai_github = { git = "https://github.com/rhaiscript/rhai", features = [ "unchecked" ] }
-rhai_my_github = { git = "https://github.com/my_github/rhai", branch = "variation1", features = [ "serde", "no_closure" ] }
-rhai_local = { path = "../rhai_copy" }
-```
-
-The example above creates four different modules: `rhai`, `rhai_github`, `rhai_my_github` and
-`rhai_local`, each referring to a different Rhai copy with the appropriate [features] set.
-
-Only one crate of any particular version can be used from each source, because Cargo merges
-all candidate cases within the same source, adding all [features] together.
-
-If more than four different instantiations of Rhai is necessary (why?), create more local repositories
-or GitHub forks or branches.
-
-
-Caveat – No Way To Avoid Dependency Conflicts
---------------------------------------------------
-
-Unfortunately, pulling in Rhai from different sources do not resolve the problem of
-[features] conflict between dependencies. Even overriding `crates.io` via the `[patch]` manifest
-section doesn't work – all dependencies will eventually find the only one copy.
-
-What is necessary – multiple copies of Rhai, one for each dependent crate that requires it,
-together with their _unique_ [features] set intact. In other words, turning off Cargo's
-crate merging feature _just for Rhai_.
-
-Unfortunately, as of this writing, there is no known method to achieve it.
-
-Therefore, moral of the story: avoid pulling in multiple crates that depend on Rhai.
diff --git a/doc/src/patterns/oop.md b/doc/src/patterns/oop.md
deleted file mode 100644
index 7b225c8c..00000000
--- a/doc/src/patterns/oop.md
+++ /dev/null
@@ -1,109 +0,0 @@
-Object-Oriented Programming (OOP)
-================================
-
-{{#include ../links.md}}
-
-Rhai does not have _objects_ per se, but it is possible to _simulate_ object-oriented programming.
-
-
-Use Object Maps to Simulate OOP
-------------------------------
-
-Rhai's [object maps] has [special support for OOP]({{rootUrl}}/language/object-maps-oop.md).
-
-| Rhai concept | Maps to OOP |
-| ----------------------------------------------------- | :---------: |
-| [Object maps] | objects |
-| [Object map] properties holding values | properties |
-| [Object map] properties that hold [function pointers] | methods |
-
-When a property of an [object map] is called like a method function, and if it happens to hold
-a valid [function pointer] (perhaps defined via an [anonymous function] or more commonly as a [closure]),
-then the call will be dispatched to the actual function with `this` binding to the [object map] itself.
-
-
-Use Closures to Define Methods
------------------------------
-
-[Anonymous functions] or [closures] defined as values for [object map] properties take on
-a syntactic shape which resembles very closely that of class methods in an OOP language.
-
-Closures also _[capture][automatic currying]_ variables from the defining environment, which is a very
-common language feature. Capturing is accomplished via a feature called _[automatic currying]_ and
-can be turned off via the [`no_closure`] feature.
-
-
-Examples
---------
-
-```rust
-let factor = 1;
-
-// Define the object
-let obj = #{
- data: 0, // object field
- increment: |x| this.data += x, // 'this' binds to 'obj'
- update: |x| this.data = x * factor, // 'this' binds to 'obj', 'factor' is captured
- action: || print(this.data) // 'this' binds to 'obj'
- };
-
-// Use the object
-obj.increment(1);
-obj.action(); // prints 1
-
-obj.update(42);
-obj.action(); // prints 42
-
-factor = 2;
-
-obj.update(42);
-obj.action(); // prints 84
-```
-
-
-Simulating Inheritance With Mixin
---------------------------------
-
-The `fill_with` method of [object maps] can be conveniently used to _polyfill_ default
-method implementations from a _base class_, as per OOP lingo.
-
-Do not use the `mixin` method because it _overwrites_ existing fields.
-
-```rust
-// Define base class
-let BaseClass = #{
- factor: 1,
- data: 42,
-
- get_data: || this.data * 2,
- update: |x| this.data += x * this.factor
-};
-
-let obj = #{
- // Override base class field
- factor: 100,
-
- // Override base class method
- // Notice that the base class can also be accessed, if in scope
- get_data: || this.call(BaseClass.get_data) * 999,
-}
-
-// Polyfill missing fields/methods
-obj.fill_with(BaseClass);
-
-// By this point, 'obj' has the following:
-//
-// #{
-// factor: 100
-// data: 42,
-// get_data: || this.call(BaseClass.get_data) * 999,
-// update: |x| this.data += x * this.factor
-// }
-
-// obj.get_data() => (this.data (42) * 2) * 999
-obj.get_data() == 83916;
-
-obj.update(1);
-
-obj.data == 142
-```
diff --git a/doc/src/patterns/parallel.md b/doc/src/patterns/parallel.md
deleted file mode 100644
index 3db89b3f..00000000
--- a/doc/src/patterns/parallel.md
+++ /dev/null
@@ -1,75 +0,0 @@
-One Engine Instance Per Call
-===========================
-
-{{#include ../links.md}}
-
-
-Usage Scenario
---------------
-
-* A system where scripts are called a _lot_, in tight loops or in parallel.
-
-* Keeping a global [`Engine`] instance is sub-optimal due to contention and locking.
-
-* Scripts need to be executed independently from each other, perhaps concurrently.
-
-* Scripts are used to [create Rust closure][`Func`] that are stored and may be called at any time, perhaps concurrently.
- In this case, the [`Engine`] instance is usually moved into the closure itself.
-
-
-Key Concepts
-------------
-
-* Create a single instance of each standard [package] required.
- To duplicate `Engine::new`, create a [`StandardPackage`]({{rootUrl}}/rust/packages/builtin.md).
-
-* Gather up all common custom functions into a [custom package].
-
-* Store a global `AST` for use with all engines.
-
-* Always use `Engine::new_raw` to create a [raw `Engine`], instead of `Engine::new` which is _much_ more expensive.
- A [raw `Engine`] is _extremely_ cheap to create.
-
- Registering the [`StandardPackage`]({{rootUrl}}/rust/packages/builtin.md) into a [raw `Engine`] via
- `Engine::register_global_module` is essentially the same as `Engine::new`.
-
- However, because packages are shared, using existing package is _much cheaper_ than
- registering all the functions one by one.
-
-* Register the required packages with the [raw `Engine`] via `Engine::register_global_module`,
- using `Package::as_shared_module` to obtain a shared [module].
-
-
-Examples
---------
-
-```rust
-use rhai::packages::{Package, StandardPackage};
-
-let ast = /* ... some AST ... */;
-let std_pkg = StandardPackage::new();
-let custom_pkg = MyCustomPackage::new();
-
-let make_call = |x: i64| -> Result<(), Box> {
- // Create a raw Engine - extremely cheap
- let mut engine = Engine::new_raw();
-
- // Register packages as global modules - cheap
- engine.register_global_module(std_pkg.as_shared_module());
- engine.register_global_module(custom_pkg.as_shared_module());
-
- // Create custom scope - cheap
- let mut scope = Scope::new();
-
- // Push variable into scope - relatively cheap
- scope.push("x", x);
-
- // Evaluate script.
- engine.consume_ast_with_scope(&mut scope, &ast)
-};
-
-// The following loop creates 10,000 Engine instances!
-for x in 0..10_000 {
- make_call(x)?;
-}
-```
diff --git a/doc/src/patterns/singleton.md b/doc/src/patterns/singleton.md
deleted file mode 100644
index 97b7d221..00000000
--- a/doc/src/patterns/singleton.md
+++ /dev/null
@@ -1,175 +0,0 @@
-Singleton Command Object
-=======================
-
-{{#include ../links.md}}
-
-
-Usage Scenario
---------------
-
-* A system provides core functionalities, but no driving logic.
-
-* The driving logic must be dynamic and hot-loadable.
-
-* A script is used to drive the system and provide control intelligence.
-
-* The API is multiplexed, meaning that it can act on multiple system-provided entities, or
-
-* The API lends itself readily to an object-oriented (OO) representation.
-
-
-Key Concepts
-------------
-
-* Expose a Command type with an API. The [`no_object`] feature must not be on.
-
-* Leverage [function overloading] to simplify the API design.
-
-* Since Rhai is _[sand-boxed]_, it cannot mutate the environment. To perform external actions via an API, the command object type must be wrapped in a `RefCell` (or `RwLock`/`Mutex` for [`sync`]) and shared to the [`Engine`].
-
-* Load each command object into a custom [`Scope`] as constant variables.
-
-* Control each command object in script via the constants.
-
-
-Implementation
---------------
-
-There are two broad ways for Rhai to control an external system, both of which involve
-wrapping the system in a shared, interior-mutated object.
-
-This is the other way which involves directly exposing the data structures of the external system
-as a name singleton object in the scripting space.
-
-Use this when the API is complex but has a clear object structure.
-
-For a relatively simple API that is action-based and not object-based,
-use the [Control Layer]({{rootUrl}}/patterns/control.md) pattern instead.
-
-
-### Functional API
-
-Assume the following command object type:
-
-```rust
-struct EnergizerBunny { ... }
-
-impl EnergizerBunny {
- pub fn new () -> Self { ... }
- pub fn go (&mut self) { ... }
- pub fn stop (&mut self) { ... }
- pub fn is_going (&self) -> bol { ... }
- pub fn get_speed (&self) -> i64 { ... }
- pub fn set_speed (&mut self, speed: i64) { ... }
- pub fn turn (&mut self, left_turn: bool) { ... }
-}
-```
-
-### Wrap Command Object Type as Shared
-
-```rust
-pub type SharedBunny = Rc>;
-```
-
-Note: Use `Arc>` or `Arc>` when using the [`sync`] feature because the function
-must then be `Send + Sync`.
-
-### Register the Custom Type
-
-```rust
-engine.register_type_with_name::("EnergizerBunny");
-```
-
-### Develop a Plugin with Methods and Getters/Setters
-
-The easiest way to develop a complete set of API for a [custom type] is via a [plugin module].
-
-```rust
-use rhai::plugin::*;
-
-#[export_module]
-pub mod bunny_api {
- pub const MAX_SPEED: i64 = 100;
-
- #[rhai_fn(get = "power")]
- pub fn get_power(bunny: &mut SharedBunny) -> bool {
- bunny.borrow().is_going()
- }
- #[rhai_fn(set = "power")]
- pub fn set_power(bunny: &mut SharedBunny, on: bool) {
- if on {
- if bunny.borrow().is_going() {
- println!("Still going...");
- } else {
- bunny.borrow_mut().go();
- }
- } else {
- if bunny.borrow().is_going() {
- bunny.borrow_mut().stop();
- } else {
- println!("Already out of battery!");
- }
- }
- }
- #[rhai_fn(get = "speed")]
- pub fn get_speed(bunny: &mut SharedBunny) -> i64 {
- if bunny.borrow().is_going() {
- bunny.borrow().get_speed()
- } else {
- 0
- }
- }
- #[rhai_fn(set = "speed", return_raw)]
- pub fn set_speed(bunny: &mut SharedBunny, speed: i64)
- -> Result>
- {
- if speed <= 0 {
- Err("Speed must be positive!".into())
- } else if speed > MAX_SPEED {
- Err("Bunny will be going too fast!".into())
- } else if !bunny.borrow().is_going() {
- Err("Bunny is not yet going!".into())
- } else {
- b.borrow_mut().set_speed(speed);
- Ok(Dynamic::UNIT)
- }
- }
- pub fn turn_left(bunny: &mut SharedBunny) {
- if bunny.borrow().is_going() {
- bunny.borrow_mut().turn(true);
- }
- }
- pub fn turn_right(bunny: &mut SharedBunny) {
- if bunny.borrow().is_going() {
- bunny.borrow_mut().turn(false);
- }
- }
-}
-
-engine.register_global_module(exported_module!(bunny_api).into());
-```
-
-### Push Constant Command Object into Custom Scope
-
-```rust
-let bunny: SharedBunny = Rc::new(RefCell::(EnergizerBunny::new()));
-
-let mut scope = Scope::new();
-
-// Add the command object into a custom Scope.
-scope.push_constant("Bunny", bunny.clone());
-
-engine.consume_with_scope(&mut scope, script)?;
-```
-
-### Use the Command API in Script
-
-```rust
-// Access the command object via constant variable 'Bunny'.
-
-if !Bunny.power { Bunny.power = true; }
-
-if Bunny.speed > 50 { Bunny.speed = 50; }
-
-Bunny.turn_left();
-```
diff --git a/doc/src/plugins/function.md b/doc/src/plugins/function.md
deleted file mode 100644
index 8f7b3f46..00000000
--- a/doc/src/plugins/function.md
+++ /dev/null
@@ -1,156 +0,0 @@
-Export a Rust Function to Rhai
-=============================
-
-{{#include ../links.md}}
-
-
-Sometimes only a few ad hoc functions are required and it is simpler to register
-individual functions instead of a full-blown [plugin module].
-
-
-Macros
-------
-
-| Macro | Signature | Description |
-| ------------------------- | -------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------- |
-| `#[export_fn]` | apply to rust function defined in a Rust module | exports the function |
-| `register_exported_fn!` | `register_exported_fn!(&mut `_engine_`, "`_name_`", `_function_`)` | registers the function into an [`Engine`] under a specific name |
-| `set_exported_fn!` | `set_exported_fn!(&mut `_module_`, "`_name_`", `_function_`)` | registers the function into a [`Module`] under a specific name |
-| `set_exported_global_fn!` | `set_exported_global_fn!(&mut `_module_`, "`_name_`", `_function_`)` | registers the function into a [`Module`] under a specific name, exposing it to the global namespace |
-
-
-`#[export_fn]` and `register_exported_fn!`
------------------------------------------
-
-Apply `#[export_fn]` onto a function defined at _module level_ to convert it into a Rhai plugin function.
-
-The function cannot be nested inside another function – it can only be defined directly under a module.
-
-To register the plugin function, simply call `register_exported_fn!`. The name of the function can be
-any text string, so it is possible to register _overloaded_ functions as well as operators.
-
-```rust
-use rhai::plugin::*; // import macros
-
-#[export_fn]
-fn increment(num: &mut i64) {
- *num += 1;
-}
-
-fn main() {
- let mut engine = Engine::new();
-
- // 'register_exported_fn!' registers the function as 'inc' with the Engine.
- register_exported_fn!(engine, "inc", increment);
-}
-```
-
-
-Fallible Functions
-------------------
-
-To register [fallible functions] (i.e. functions that may return errors), apply the
-`#[rhai_fn(return_raw)]` attribute on plugin functions that return `Result>`.
-
-A syntax error is generated if the function with `#[rhai_fn(return_raw)]` does not
-have the appropriate return type.
-
-```rust
-use rhai::plugin::*; // a "prelude" import for macros
-
-#[export_fn]
-#[rhai_fn(return_raw)]
-pub fn double_and_divide(x: i64, y: i64) -> Result> {
- if y == 0 {
- Err("Division by zero!".into())
- } else {
- let result = (x * 2) / y;
- Ok(result.into())
- }
-}
-
-fn main() {
- let mut engine = Engine::new();
-
- // Overloads the operator '+' with the Engine.
- register_exported_fn!(engine, "+", double_and_divide);
-}
-```
-
-
-`NativeCallContext` Parameter
-----------------------------
-
-If the _first_ parameter of a function is of type `rhai::NativeCallContext`, then it is treated
-specially by the plugins system.
-
-`NativeCallContext` is a type that encapsulates the current _native call context_ and exposes the following:
-
-| Field | Type | Description |
-| ------------------- | :-------------------------------------: | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
-| `engine()` | `&Engine` | the current [`Engine`], with all configurations and settings. This is sometimes useful for calling a script-defined function within the same evaluation context using [`Engine::call_fn`][`call_fn`], or calling a [function pointer]. |
-| `source()` | `Option<&str>` | reference to the current source, if any |
-| `iter_imports()` | `impl Iterator- ` | iterator of the current stack of [modules] imported via `import` statements |
-| `imports()` | `&Imports` | reference to the current stack of [modules] imported via `import` statements; requires the [`internals`] feature |
-| `iter_namespaces()` | `impl Iterator
- ` | iterator of the namespaces (as [modules]) containing all script-defined functions |
-| `namespaces()` | `&[&Module]` | reference to the namespaces (as [modules]) containing all script-defined functions; requires the [`internals`] feature |
-
-This first parameter, if exists, will be stripped before all other processing. It is _virtual_.
-Most importantly, it does _not_ count as a parameter to the function and there is no need to provide
-this argument when calling the function in Rhai.
-
-The native call context can be used to call a [function pointer] or [closure] that has been passed
-as a parameter to the function, thereby implementing a _callback_:
-
-```rust
-use rhai::{Dynamic, FnPtr, NativeCallContext, EvalAltResult};
-use rhai::plugin::*; // a "prelude" import for macros
-
-#[export_fn]
-#[rhai_fn(return_raw)]
-pub fn greet(context: NativeCallContext, callback: FnPtr)
- -> Result
>
-{
- // Call the callback closure with the current context
- // to obtain the name to greet!
- let name = callback.call_dynamic(context, None, [])?;
- Ok(format!("hello, {}!", name).into())
-}
-```
-
-The native call context is also useful in another scenario: protecting a function from malicious scripts.
-
-```rust
-use rhai::{Dynamic, Array, NativeCallContext, EvalAltResult, Position};
-use rhai::plugin::*; // a "prelude" import for macros
-
-// This function builds an array of arbitrary size, but is protected
-// against attacks by first checking with the allowed limit set
-// into the 'Engine'.
-#[export_fn]
-#[rhai_fn(return_raw)]
-pub fn grow(context: NativeCallContext, size: i64)
- -> Result>
-{
- // Make sure the function does not generate a
- // data structure larger than the allowed limit
- // for the Engine!
- if size as usize > context.engine().max_array_size()
- {
- return EvalAltResult::ErrorDataTooLarge(
- "Size to grow".to_string(),
- context.engine().max_array_size(),
- size as usize,
- Position::NONE,
- ).into();
- }
-
- let array = Array::new();
-
- for x in 0..size {
- array.push(x.into());
- }
-
- OK(array.into())
-}
-```
diff --git a/doc/src/plugins/index.md b/doc/src/plugins/index.md
deleted file mode 100644
index 1e3f3cc9..00000000
--- a/doc/src/plugins/index.md
+++ /dev/null
@@ -1,13 +0,0 @@
-Plugins
-=======
-
-{{#include ../links.md}}
-
-Rhai contains a robust _plugin_ system that greatly simplifies registration of custom
-functionality.
-
-Instead of using the large `Engine::register_XXX` API or the parallel `Module::set_fn_XXX` API,
-a _plugin_ simplifies the work of creating and registering new functionality in an [`Engine`].
-
-Plugins are processed via a set of procedural macros under the `rhai::plugin` module. These
-allow registering Rust functions directly in the Engine, or adding Rust modules as packages.
diff --git a/doc/src/plugins/module.md b/doc/src/plugins/module.md
deleted file mode 100644
index c147809f..00000000
--- a/doc/src/plugins/module.md
+++ /dev/null
@@ -1,507 +0,0 @@
-Export a Rust Module to Rhai
-============================
-
-{{#include ../links.md}}
-
-
-Prelude
--------
-
-When using the plugins system, the entire `rhai::plugin` module must be imported as a prelude
-because code generated will need these imports.
-
-```rust
-use rhai::plugin::*;
-```
-
-
-`#[export_module]`
-------------------
-
-When applied to a Rust module, the `#[export_module]` attribute generates the necessary
-code and metadata to allow Rhai access to its public (i.e. marked `pub`) functions, constants
-and sub-modules.
-
-This code is exactly what would need to be written by hand to achieve the same goal,
-and is custom fit to each exported item.
-
-All `pub` functions become registered functions, all `pub` constants become [module] constant variables,
-and all sub-modules become Rhai sub-modules.
-
-This Rust module can then be registered into an [`Engine`] as a normal [module].
-This is done via the `exported_module!` macro.
-
-The macro `combine_with_exported_module!` can be used to _combine_ all the functions
-and variables into an existing [module], _flattening_ the namespace – i.e. all sub-modules
-are eliminated and their contents promoted to the top level. This is typical for
-developing [custom packages].
-
-```rust
-use rhai::plugin::*; // a "prelude" import for macros
-
-#[export_module]
-mod my_module {
- // This constant will be registered as the constant variable 'MY_NUMBER'.
- // Ignored when registered as a global module.
- pub const MY_NUMBER: i64 = 42;
-
- // This function will be registered as 'greet'.
- pub fn greet(name: &str) -> String {
- format!("hello, {}!", name)
- }
- // This function will be registered as 'get_num'.
- pub fn get_num() -> i64 {
- mystic_number()
- }
- // This function will be registered as 'increment'.
- // It will also be exposed to the global namespace since 'global' is set.
- #[rhai_fn(global)]
- pub fn increment(num: &mut i64) {
- *num += 1;
- }
- // This function is not 'pub', so NOT registered.
- fn mystic_number() -> i64 {
- 42
- }
-
- // Sub-modules are ignored when the module is registered globally.
- pub mod my_sub_module {
- // This function is ignored when registered globally.
- // Otherwise it is a valid registered function under a sub-module.
- pub fn get_info() -> String {
- "hello".to_string()
- }
- }
-
- // Sub-modules are commonly used to put feature gates on a group of
- // functions because feature gates cannot be put on function definitions.
- // This is currently a limitation of the plugin procedural macros.
- #[cfg(feature = "advanced_functions")]
- pub mod advanced {
- // This function is ignored when registered globally.
- // Otherwise it is a valid registered function under a sub-module
- // which only exists when the 'advanced_functions' feature is used.
- pub fn advanced_calc(input: i64) -> i64 {
- input * 2
- }
- }
-}
-```
-
-### Use `Engine::register_global_module`
-
-The simplest way to register this into an [`Engine`] is to first use the `exported_module!` macro
-to turn it into a normal Rhai [module], then use the `Engine::register_global_module` method on it:
-
-```rust
-fn main() {
- let mut engine = Engine::new();
-
- // The macro call creates a Rhai module from the plugin module.
- let module = exported_module!(my_module);
-
- // A module can simply be registered into the global namespace.
- engine.register_global_module(module.into());
-}
-```
-
-The functions contained within the module definition (i.e. `greet`, `get_num` and `increment`)
-are automatically registered into the [`Engine`] when `Engine::register_global_module` is called.
-
-```rust
-let x = greet("world");
-x == "hello, world!";
-
-let x = greet(get_num().to_string());
-x == "hello, 42!";
-
-let x = get_num();
-x == 42;
-
-increment(x);
-x == 43;
-```
-
-Notice that, when using a [module] as a [package], only functions registered at the _top level_
-can be accessed.
-
-Variables as well as sub-modules are **ignored**.
-
-### Use `Engine::register_static_module`
-
-Another simple way to register this into an [`Engine`] is, again, to use the `exported_module!` macro
-to turn it into a normal Rhai [module], then use the `Engine::register_static_module` method on it:
-
-```rust
-fn main() {
- let mut engine = Engine::new();
-
- // The macro call creates a Rhai module from the plugin module.
- let module = exported_module!(my_module);
-
- // A module can simply be registered as a static module namespace.
- engine.register_static_module("service", module.into());
-}
-```
-
-The functions contained within the module definition (i.e. `greet`, `get_num` and `increment`),
-plus the constant `MY_NUMBER`, are automatically registered under the module namespace `service`:
-
-```rust
-let x = service::greet("world");
-x == "hello, world!";
-
-service::MY_NUMBER == 42;
-
-let x = service::greet(service::get_num().to_string());
-x == "hello, 42!";
-
-let x = service::get_num();
-x == 42;
-
-service::increment(x);
-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
-[iteration]({{rootUrl}}/language/for.md), [getters/setters] and [indexers] for [custom types]
-can work as expected.
-
-In fact, the default for all [getters/setters] and [indexers] defined in a plugin module
-is `#[rhai_fn(global)]` unless specifically overridden by `#[rhai_fn(internal)]`.
-
-Therefore, in the example above, the `increment` method (defined with `#[rhai_fn(global)]`)
-works fine when called in method-call style:
-
-```rust
-let x = 42;
-x.increment();
-x == 43;
-```
-
-### Use Dynamically
-
-Using this directly as a dynamically-loadable Rhai [module] is almost the same, except that a
-[module resolver] must be used to serve the module, and the module is loaded via `import` statements.
-
-See the [module] section for more information.
-
-### Combine into Custom Package
-
-Finally the plugin module can also be used to develop a [custom package],
-using `combine_with_exported_module!`:
-
-```rust
-def_package!(rhai:MyPackage:"My own personal super package", module, {
- combine_with_exported_module!(module, "my_module_ID", my_module));
-});
-```
-
-`combine_with_exported_module!` automatically _flattens_ the module namespace so that all
-functions in sub-modules are promoted to the top level. This is convenient for [custom packages].
-
-
-Sub-Modules and Feature Gates
-----------------------------
-
-Sub-modules in a plugin module definition are turned into valid sub-modules in the resultant
-Rhai `Module`.
-
-They are also commonly used to put _feature gates_ or _compile-time gates_ on a group of functions,
-because currently attributes do not work on individual function definitions due to a limitation of
-the procedural macros system.
-
-This is especially convenient when using the `combine_with_exported_module!` macro to develop
-[custom packages] because selected groups of functions can easily be included or excluded based on
-different combinations of feature flags instead of having to manually include/exclude every
-single function.
-
-```rust
-#[export_module]
-mod my_module {
- // Always available
- pub fn func0() {}
-
- // The following sub-module is only available under 'feature1'
- #[cfg(feature = "feature1")]
- pub mod feature1 {
- fn func1() {}
- fn func2() {}
- fn func3() {}
- }
-
- // The following sub-module is only available under 'feature2'
- #[cfg(feature = "feature2")]
- pub mod feature2 {
- fn func4() {}
- fn func5() {}
- fn func6() {}
- }
-}
-
-// Registered functions:
-// func0 - always available
-// func1 - available under 'feature1'
-// func2 - available under 'feature1'
-// func3 - available under 'feature1'
-// func4 - available under 'feature2'
-// func5 - available under 'feature2'
-// func6 - available under 'feature2'
-combine_with_exported_module!(module, "my_module_ID", my_module);
-```
-
-
-Function Overloading and Operators
----------------------------------
-
-Operators and overloaded functions can be specified via applying the `#[rhai_fn(name = "...")]`
-attribute to individual functions.
-
-The text string given as the `name` parameter to `#[rhai_fn]` is used to register the function with
-the [`Engine`], disregarding the actual name of the function.
-
-With `#[rhai_fn(name = "...")]`, multiple functions may be registered under the same name in Rhai,
-so long as they have different parameters.
-
-Operators (which require function names that are not valid for Rust) can also be registered this way.
-
-Registering the same function name with the same parameter types will cause a parsing error.
-
-```rust
-use rhai::plugin::*; // a "prelude" import for macros
-
-#[export_module]
-mod my_module {
- // This is the '+' operator for 'TestStruct'.
- #[rhai_fn(name = "+")]
- pub fn add(obj: &mut TestStruct, value: i64) {
- obj.prop += value;
- }
- // This function is 'calc (i64)'.
- #[rhai_fn(name = "calc")]
- pub fn calc_with_default(num: i64) -> i64 {
- ...
- }
- // This function is 'calc (i64, bool)'.
- #[rhai_fn(name = "calc")]
- pub fn calc_with_option(num: i64, option: bool) -> i64 {
- ...
- }
-}
-```
-
-
-Getters, Setters and Indexers
------------------------------
-
-Functions can be marked as [getters/setters] and [indexers] for [custom types] via the `#[rhai_fn]`
-attribute, which is applied on a function level.
-
-```rust
-use rhai::plugin::*; // a "prelude" import for macros
-
-#[export_module]
-mod my_module {
- // This is a normal function 'greet'.
- pub fn greet(name: &str) -> String {
- format!("hello, {}!", name)
- }
- // This is a getter for 'TestStruct::prop'.
- #[rhai_fn(get = "prop")]
- pub fn get_prop(obj: &mut TestStruct) -> i64 {
- obj.prop
- }
- // This is a setter for 'TestStruct::prop'.
- #[rhai_fn(set = "prop")]
- pub fn set_prop(obj: &mut TestStruct, value: i64) {
- obj.prop = value;
- }
- // This is an index getter for 'TestStruct'.
- #[rhai_fn(index_get)]
- pub fn get_index(obj: &mut TestStruct, index: i64) -> bool {
- obj.list[index]
- }
- // This is an index setter for 'TestStruct'.
- #[rhai_fn(index_set)]
- pub fn get_index(obj: &mut TestStruct, index: i64, state: bool) {
- obj.list[index] = state;
- }
-}
-```
-
-
-Multiple Registrations
-----------------------
-
-Parameters to the `#[rhai_fn(...)]` attribute can be applied multiple times.
-
-This is especially useful for the `name = "..."`, `get = "..."` and `set = "..."` parameters
-to give multiple alternative names to the same function.
-
-```rust
-use rhai::plugin::*; // a "prelude" import for macros
-
-#[export_module]
-mod my_module {
- // This function can be called in five ways
- #[rhai_fn(name = "get_prop_value", name = "prop", name = "+", set = "prop", index_get)]
- pub fn prop_function(obj: &mut TestStruct, index: i64) -> i64 {
- obj.prop[index]
- }
-}
-```
-
-The above function can be called in five ways:
-
-| Parameter for `#[rhai_fn(...)]` | Type | Call style |
-| ------------------------------- | :-------------: | --------------------------------------------- |
-| `name = "get_prop_value"` | method function | `get_prop_value(x, 0)`, `x.get_prop_value(0)` |
-| `name = "prop"` | method function | `prop(x, 0)`, `x.prop(0)` |
-| `name = "+"` | operator | `x + 42` |
-| `set = "prop"` | setter | `x.prop = 42` |
-| `index_get` | index getter | `x[0]` |
-
-
-Fallible Functions
-------------------
-
-To register [fallible functions] (i.e. functions that may return errors), apply the
-`#[rhai_fn(return_raw)]` attribute on functions that return `Result>`.
-
-A syntax error is generated if the function with `#[rhai_fn(return_raw)]` does not
-have the appropriate return type.
-
-```rust
-use rhai::plugin::*; // a "prelude" import for macros
-
-#[export_module]
-mod my_module {
- // This overloads the '/' operator for i64.
- #[rhai_fn(name = "/", return_raw)]
- pub fn double_and_divide(x: i64, y: i64) -> Result> {
- if y == 0 {
- Err("Division by zero!".into())
- } else {
- let result = (x * 2) / y;
- Ok(result.into())
- }
- }
-}
-```
-
-
-`NativeCallContext` Parameter
-----------------------------
-
-If the _first_ parameter of a function is of type `rhai::NativeCallContext`, then it is treated
-specially by the plugins system.
-
-`NativeCallContext` is a type that encapsulates the current _native call context_ and exposes the following:
-
-| Field | Type | Description |
-| ------------------- | :-------------------------------------: | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
-| `engine()` | `&Engine` | the current [`Engine`], with all configurations and settings. This is sometimes useful for calling a script-defined function within the same evaluation context using [`Engine::call_fn`][`call_fn`], or calling a [function pointer]. |
-| `source()` | `Option<&str>` | reference to the current source, if any |
-| `iter_imports()` | `impl Iterator- ` | iterator of the current stack of [modules] imported via `import` statements |
-| `imports()` | `&Imports` | reference to the current stack of [modules] imported via `import` statements; requires the [`internals`] feature |
-| `iter_namespaces()` | `impl Iterator
- ` | iterator of the namespaces (as [modules]) containing all script-defined functions |
-| `namespaces()` | `&[&Module]` | reference to the namespaces (as [modules]) containing all script-defined functions; requires the [`internals`] feature |
-
-This first parameter, if exists, will be stripped before all other processing. It is _virtual_.
-Most importantly, it does _not_ count as a parameter to the function and there is no need to provide
-this argument when calling the function in Rhai.
-
-The native call context can be used to call a [function pointer] or [closure] that has been passed
-as a parameter to the function, thereby implementing a _callback_:
-
-```rust
-use rhai::{Dynamic, FnPtr, NativeCallContext, EvalAltResult};
-use rhai::plugin::*; // a "prelude" import for macros
-
-#[export_module]
-mod my_module {
- #[rhai_fn(return_raw)]
- pub fn greet(context: NativeCallContext, callback: FnPtr)
- -> Result
>
- {
- // Call the callback closure with the current context
- // to obtain the name to greet!
- let name = callback.call_dynamic(context, None, [])?;
- Ok(format!("hello, {}!", name).into())
- }
-}
-```
-
-The native call context is also useful in another scenario: protecting a function from malicious scripts.
-
-```rust
-use rhai::{Dynamic, Array, NativeCallContext, EvalAltResult, Position};
-use rhai::plugin::*; // a "prelude" import for macros
-
-#[export_module]
-mod my_module {
- // This function builds an array of arbitrary size, but is protected
- // against attacks by first checking with the allowed limit set
- // into the 'Engine'.
- #[rhai_fn(return_raw)]
- pub fn grow(context: NativeCallContext, size: i64)
- -> Result>
- {
- // Make sure the function does not generate a
- // data structure larger than the allowed limit
- // for the Engine!
- if size as usize > context.engine().max_array_size()
- {
- return EvalAltResult::ErrorDataTooLarge(
- "Size to grow".to_string(),
- context.engine().max_array_size(),
- size as usize,
- Position::NONE,
- ).into();
- }
-
- let array = Array::new();
-
- for x in 0..size {
- array.push(x.into());
- }
-
- OK(array.into())
- }
-}
-```
-
-
-`#[export_module]` Parameters
-----------------------------
-
-Parameters can be applied to the `#[export_module]` attribute to override its default behavior.
-
-| Parameter | Description |
-| ----------------------- | ------------------------------------------------------------------------------------------------------------------------------ |
-| _none_ | exports only public (i.e. `pub`) functions |
-| `export_all` | exports all functions (including private, non-`pub` functions); use `#[rhai_fn(skip)]` on individual functions to avoid export |
-| `export_prefix = "..."` | exports functions (including private, non-`pub` functions) with names starting with a specific prefix |
-
-
-Inner Attributes
-----------------
-
-Inner attributes can be applied to the inner items of a module to tweak the export process.
-
-`#[rhai_fn]` is applied to functions, while `#[rhai_mod]` is applied to sub-modules.
-
-Parameters should be set on inner attributes to specify the desired behavior.
-
-| Attribute Parameter | Use with | Apply to | Description |
-| ------------------- | --------------------------- | ----------------------------------------------------- | ------------------------------------------------------- |
-| `skip` | `#[rhai_fn]`, `#[rhai_mod]` | function or sub-module | do not export this function/sub-module |
-| `global` | `#[rhai_fn]` | function | expose this function to the global namespace |
-| `internal` | `#[rhai_fn]` | function | keep this function within the internal module namespace |
-| `name = "..."` | `#[rhai_fn]`, `#[rhai_mod]` | function or sub-module | registers function/sub-module under the specified name |
-| `get = "..."` | `#[rhai_fn]` | `pub fn (&mut Type) -> Value` | registers a getter for the named property |
-| `set = "..."` | `#[rhai_fn]` | `pub fn (&mut Type, Value)` | registers a setter for the named property |
-| `index_get` | `#[rhai_fn]` | `pub fn (&mut Type, INT) -> Value` | registers an index getter |
-| `index_set` | `#[rhai_fn]` | `pub fn (&mut Type, INT, Value)` | registers an index setter |
-| `return_raw` | `#[rhai_fn]` | `pub fn (...) -> Result>` | marks this as a [fallible function] |
diff --git a/doc/src/rust/custom.md b/doc/src/rust/custom.md
deleted file mode 100644
index 1b0bec44..00000000
--- a/doc/src/rust/custom.md
+++ /dev/null
@@ -1,200 +0,0 @@
-Register any Rust Type and its Methods
-=====================================
-
-{{#include ../links.md}}
-
-
-Free Typing
------------
-
-Rhai works seamlessly with _any_ Rust type. The type can be _anything_; it does not
-have any prerequisites other than being `Clone`. It does not need to implement
-any other trait or use any custom `#[derive]`.
-
-This allows Rhai to be integrated into an existing Rust code base with as little plumbing
-as possible, usually silently and seamlessly. External types that are not defined
-within the same crate (and thus cannot implement special Rhai traits or
-use special `#[derive]`) can also be used easily with Rhai.
-
-The reason why it is termed a _custom_ type throughout this documentation is that
-Rhai natively supports a number of data types with fast, internal treatment (see
-the list of [standard types]). Any type outside of this list is considered _custom_.
-
-Any type not supported natively by Rhai is stored as a Rust _trait object_, with no
-restrictions other than being `Clone` (plus `Send + Sync` under the [`sync`] feature).
-It runs slightly slower than natively-supported types as it does not have built-in,
-optimized implementations for commonly-used functions, but for all other purposes has
-no difference.
-
-Support for custom types can be turned off via the [`no_object`] feature.
-
-
-Register a Custom Type and its Methods
--------------------------------------
-
-Any custom type must implement the `Clone` trait as this allows the [`Engine`] to pass by value.
-
-If the [`sync`] feature is used, it must also be `Send + Sync`.
-
-Notice that the custom type needs to be _registered_ using `Engine::register_type`
-or `Engine::register_type_with_name`.
-
-To use native methods on custom types in Rhai scripts, it is common to register an API
-for the type using one of the `Engine::register_XXX` functions.
-
-```rust
-use rhai::{Engine, EvalAltResult};
-use rhai::RegisterFn; // remember 'RegisterFn' is needed
-
-#[derive(Clone)]
-struct TestStruct {
- field: i64
-}
-
-impl TestStruct {
- fn new() -> Self {
- Self { field: 1 }
- }
-
- fn update(&mut self, x: i64) { // methods take &mut as first parameter
- self.field += x;
- }
-}
-
-let mut engine = Engine::new();
-
-// Most Engine API's can be chained up.
-engine
- .register_type::() // register custom type
- .register_fn("new_ts", TestStruct::new)
- .register_fn("update", TestStruct::update);
-
-// Cast result back to custom type.
-let result = engine.eval::(
- r"
- let x = new_ts(); // calls 'TestStruct::new'
- x.update(41); // calls 'TestStruct::update'
- x // 'x' holds a 'TestStruct'
- "
-)?;
-
-println!("result: {}", result.field); // prints 42
-```
-
-Rhai follows the convention that methods of custom types take a `&mut` first parameter
-to that type, so that invoking methods can always update it.
-
-All other parameters in Rhai are passed by value (i.e. clones).
-
-**IMPORTANT: Rhai does NOT support normal references (i.e. `&T`) as parameters.**
-
-
-Method-Call Style vs. Function-Call Style
-----------------------------------------
-
-Any function with a first argument that is a `&mut` reference can be used
-as method calls because internally they are the same thing: methods on a type is
-implemented as a functions taking a `&mut` first argument.
-
-This design is similar to Rust.
-
-```rust
-impl TestStruct {
- fn foo(&mut self) -> i64 {
- self.field
- }
-}
-
-engine.register_fn("foo", TestStruct::foo);
-
-let result = engine.eval::(
- r"
- let x = new_ts();
- foo(x); // normal call to 'foo'
- x.foo() // 'foo' can also be called like a method on 'x'
- "
-)?;
-
-println!("result: {}", result); // prints 1
-```
-
-Under [`no_object`], however, the _method_ style of function calls
-(i.e. calling a function as an object-method) is no longer supported.
-
-```rust
-// Below is a syntax error under 'no_object'.
-let result = engine.eval("let x = [1, 2, 3]; x.clear();")?;
- // ^ cannot call in method style under 'no_object'
-```
-
-
-`type_of()` a Custom Type
--------------------------
-
-[`type_of()`] works fine with custom types and returns the name of the type.
-
-If `Engine::register_type_with_name` is used to register the custom type
-with a special "pretty-print" name, [`type_of()`] will return that name instead.
-
-```rust
-engine
- .register_type::()
- .register_fn("new_ts1", TestStruct1::new)
- .register_type_with_name::("TestStruct")
- .register_fn("new_ts2", TestStruct2::new);
-
-let ts1_type = engine.eval::(r#"let x = new_ts1(); x.type_of()"#)?;
-let ts2_type = engine.eval::(r#"let x = new_ts2(); x.type_of()"#)?;
-
-println!("{}", ts1_type); // prints 'path::to::TestStruct'
-println!("{}", ts1_type); // prints 'TestStruct'
-```
-
-
-Use the Custom Type With Arrays
-------------------------------
-
-The `push`, `insert`, `pad` functions, as well as the `+=` operator, for [arrays] are only
-defined for standard built-in types. For custom types, type-specific versions must be registered:
-
-```rust
-engine
- .register_fn("push", |list: &mut Array, item: TestStruct| {
- list.push(Dynamic::from(item));
- }).register_fn("+=", |list: &mut Array, item: TestStruct| {
- list.push(Dynamic::from(item));
- }).register_fn("insert", |list: &mut Array, position: i64, item: TestStruct| {
- if position <= 0 {
- list.insert(0, Dynamic::from(item));
- } else if (position as usize) >= list.len() - 1 {
- list.push(item);
- } else {
- list.insert(position as usize, Dynamic::from(item));
- }
- }).register_fn("pad", |list: &mut Array, len: i64, item: TestStruct| {
- if len as usize > list.len() {
- list.resize(len as usize, item);
- }
- });
-```
-
-In particular, in order to use the `in` operator with a custom type for an [array],
-the `==` operator must be registered for the custom type:
-
-```rust
-// Assume 'TestStruct' implements `PartialEq`
-engine.register_fn("==",
- |item1: &mut TestStruct, item2: TestStruct| item1 == &item2
-);
-
-// Then this works in Rhai:
-let item = new_ts(); // construct a new 'TestStruct'
-item in array; // 'in' operator uses '=='
-```
-
-
-Working With Enums
-------------------
-
-It is quite easy to use Rust enums with Rhai.
-See [this chapter]({{rootUrl}}/patterns/enums.md) for more details.
diff --git a/doc/src/rust/disable-custom.md b/doc/src/rust/disable-custom.md
deleted file mode 100644
index 912482e5..00000000
--- a/doc/src/rust/disable-custom.md
+++ /dev/null
@@ -1,18 +0,0 @@
-Disable Custom Types
-====================
-
-{{#include ../links.md}}
-
-
-`no_object` Feature
--------------------
-
-The custom types API `register_type`, `register_type_with_name`, `register_get`, `register_get_result`,
-`register_set`, `register_set_result` and `register_get_set` are not available under [`no_object`].
-
-
-`no_index` Feature
-------------------
-
-The indexers API `register_indexer_get`, `register_indexer_get_result`, `register_indexer_set`,
-`register_indexer_set_result`, and `register_indexer_get_set` are also not available under [`no_index`].
diff --git a/doc/src/rust/fallible.md b/doc/src/rust/fallible.md
deleted file mode 100644
index 86d15576..00000000
--- a/doc/src/rust/fallible.md
+++ /dev/null
@@ -1,41 +0,0 @@
-Register a Fallible Rust Function
-================================
-
-{{#include ../links.md}}
-
-If a function is _fallible_ (i.e. it returns a `Result<_, Error>`), it can be registered with `register_result_fn`
-(using the `RegisterResultFn` trait).
-
-The function must return `Result>`.
-
-```rust
-use rhai::{Engine, EvalAltResult, Position};
-use rhai::RegisterResultFn; // use 'RegisterResultFn' trait for 'register_result_fn'
-
-// Function that may fail - the result type must be 'Dynamic'
-fn safe_divide(x: i64, y: i64) -> Result> {
- if y == 0 {
- // Return an error if y is zero
- Err("Division by zero!".into()) // shortcut to create Box
- } else {
- Ok((x / y).into()) // convert result into 'Dynamic'
- }
-}
-
-let mut engine = Engine::new();
-
-// Fallible functions that return Result values must use register_result_fn()
-engine.register_result_fn("divide", safe_divide);
-
-if let Err(error) = engine.eval::("divide(40, 0)") {
- println!("Error: {:?}", *error); // prints ErrorRuntime("Division by zero detected!", (1, 1)")
-}
-```
-
-Create a `Box`
-----------------------------
-
-`Box` implements `From<&str>` and `From` etc.
-and the error text gets converted into `Box`.
-
-The error values are `Box`-ed in order to reduce memory footprint of the error path, which should be hit rarely.
diff --git a/doc/src/rust/functions.md b/doc/src/rust/functions.md
deleted file mode 100644
index 99e9a485..00000000
--- a/doc/src/rust/functions.md
+++ /dev/null
@@ -1,73 +0,0 @@
-Register a Rust Function
-========================
-
-{{#include ../links.md}}
-
-Rhai's scripting engine is very lightweight. It gets most of its abilities from functions.
-
-To call these functions, they need to be _registered_ with the [`Engine`] using `Engine::register_fn`
-(in the `RegisterFn` trait) and `Engine::register_result_fn` (in the `RegisterResultFn` trait,
-see [fallible functions]).
-
-```rust
-use rhai::{Dynamic, Engine, EvalAltResult, ImmutableString};
-use rhai::RegisterFn; // use 'RegisterFn' trait for 'register_fn'
-use rhai::RegisterResultFn; // use 'RegisterResultFn' trait for 'register_result_fn'
-
-// Normal function that returns a standard type
-// Remember to use 'ImmutableString' and not 'String'
-fn add_len(x: i64, s: ImmutableString) -> i64 {
- x + s.len()
-}
-// Alternatively, '&str' maps directly to 'ImmutableString'
-fn add_len_str(x: i64, s: &str) -> i64 {
- x + s.len()
-}
-
-// Function that returns a 'Dynamic' value - must return a 'Result'
-fn get_any_value() -> Result> {
- Ok((42_i64).into()) // standard types can use 'into()'
-}
-
-let mut engine = Engine::new();
-
-engine
- .register_fn("add", add_len)
- .register_fn("add_str", add_len_str);
-
-let result = engine.eval::(r#"add(40, "xx")"#)?;
-
-println!("Answer: {}", result); // prints 42
-
-let result = engine.eval::(r#"add_str(40, "xx")"#)?;
-
-println!("Answer: {}", result); // prints 42
-
-// Functions that return Dynamic values must use register_result_fn()
-engine.register_result_fn("get_any_value", get_any_value);
-
-let result = engine.eval::("get_any_value()")?;
-
-println!("Answer: {}", result); // prints 42
-```
-
-To create a [`Dynamic`] value, use the `Dynamic::from` method.
-[Standard types] in Rhai can also use `into()`.
-
-```rust
-use rhai::Dynamic;
-
-let x = (42_i64).into(); // 'into()' works for standard types
-
-let y = Dynamic::from("hello!".to_string()); // remember &str is not supported by Rhai
-```
-
-
-Function Overloading
---------------------
-
-Functions registered with the [`Engine`] can be _overloaded_ as long as the _signature_ is unique,
-i.e. different functions can have the same name as long as their parameters are of different types
-or different number.
-
-New definitions _overwrite_ previous definitions of the same name and same number/types of parameters.
diff --git a/doc/src/rust/generic.md b/doc/src/rust/generic.md
deleted file mode 100644
index d2bea789..00000000
--- a/doc/src/rust/generic.md
+++ /dev/null
@@ -1,30 +0,0 @@
-Register a Generic Rust Function
-===============================
-
-{{#include ../links.md}}
-
-Rust generic functions can be used in Rhai, but separate instances for each concrete type must be registered separately.
-
-This essentially _overloads_ the function with different parameter types as Rhai does not natively support generics
-but Rhai does support _function overloading_.
-
-```rust
-use std::fmt::Display;
-
-use rhai::{Engine, RegisterFn};
-
-fn show_it(x: &mut T) {
- println!("put up a good show: {}!", x)
-}
-
-let mut engine = Engine::new();
-
-engine
- .register_fn("print", show_it::)
- .register_fn("print", show_it::)
- .register_fn("print", show_it::);
-```
-
-The above example shows how to register multiple functions
-(or, in this case, multiple overloaded versions of the same function)
-under the same name.
diff --git a/doc/src/rust/getters-setters.md b/doc/src/rust/getters-setters.md
deleted file mode 100644
index 334c7438..00000000
--- a/doc/src/rust/getters-setters.md
+++ /dev/null
@@ -1,69 +0,0 @@
-Custom Type Property Getters and Setters
-=======================================
-
-{{#include ../links.md}}
-
-A [custom type] can also expose properties by registering `get` and/or `set` functions.
-
-Getters and setters each take a `&mut` reference to the first parameter.
-
-Getters and setters are disabled when the [`no_object`] feature is used.
-
-| `Engine` API | Function signature(s) (`T: Clone` = custom type, `V: Clone` = data type) | Can mutate `T`? |
-| --------------------- | -------------------------------------------------------------------------------- | :----------------------------: |
-| `register_get` | `Fn(&mut T) -> V` | yes, but not advised |
-| `register_set` | `Fn(&mut T, V)` | yes |
-| `register_get_set` | getter: `Fn(&mut T) -> V`setter: `Fn(&mut T, V)` | yes, but not advised in getter |
-| `register_get_result` | `Fn(&mut T) -> Result>` | yes, but not advised |
-| `register_set_result` | `Fn(&mut T, V) -> Result<(), Box>` | yes |
-
-By convention, property getters are not supposed to mutate the [custom type], although there is nothing
-that prevents this mutation.
-
-
-Cannot Override Object Maps
---------------------------
-
-Property getters and setters are mainly intended for [custom types].
-
-Any getter or setter function registered for [object maps] is simply _ignored_ because
-the get/set calls will be interpreted as properties on the [object maps].
-
-
-Examples
---------
-
-```rust
-#[derive(Clone)]
-struct TestStruct {
- field: String
-}
-
-impl TestStruct {
- // Remember &mut must be used even for getters
- fn get_field(&mut self) -> String {
- self.field.clone()
- }
-
- fn set_field(&mut self, new_val: &str) {
- self.field = new_val.to_string();
- }
-
- fn new() -> Self {
- Self { field: "hello" }
- }
-}
-
-let mut engine = Engine::new();
-
-engine
- .register_type::()
- .register_get_set("xyz", TestStruct::get_field, TestStruct::set_field)
- .register_fn("new_ts", TestStruct::new);
-
-let result = engine.eval::(r#"let a = new_ts(); a.xyz = "42"; a.xyz"#)?;
-
-println!("Answer: {}", result); // prints 42
-```
-
-**IMPORTANT: Rhai does NOT support normal references (i.e. `&T`) as parameters.**
diff --git a/doc/src/rust/index.md b/doc/src/rust/index.md
deleted file mode 100644
index 6a0ca08d..00000000
--- a/doc/src/rust/index.md
+++ /dev/null
@@ -1,9 +0,0 @@
-Extend Rhai with Rust
-====================
-
-{{#include ../links.md}}
-
-Most features and functionalities required by a Rhai script should actually be coded in Rust,
-which leverages the superior native run-time speed.
-
-This section discusses how to extend Rhai with functionalities written in Rust.
diff --git a/doc/src/rust/indexers.md b/doc/src/rust/indexers.md
deleted file mode 100644
index f7cff1af..00000000
--- a/doc/src/rust/indexers.md
+++ /dev/null
@@ -1,82 +0,0 @@
-Custom Type Indexers
-===================
-
-{{#include ../links.md}}
-
-A [custom type] can also expose an _indexer_ by registering an indexer function.
-
-A [custom type] with an indexer function defined can use the bracket notation to get a property value:
-
-> _object_ `[` _index_ `]`
-
-Like property [getters/setters], indexers take a `&mut` reference to the first parameter.
-
-They also take an additional parameter of any type that serves as the _index_ within brackets.
-
-Indexers are disabled when the [`no_index`] feature is used.
-
-| `Engine` API | Function signature(s) (`T: Clone` = custom type, `X: Clone` = index type, `V: Clone` = data type) | Can mutate `T`? |
-| ----------------------------- | ------------------------------------------------------------------------------------------------------------- | :----------------------------: |
-| `register_indexer_get` | `Fn(&mut T, X) -> V` | yes, but not advised |
-| `register_indexer_set` | `Fn(&mut T, X, V)` | yes |
-| `register_indexer_get_set` | getter: `Fn(&mut T, X) -> V` setter: `Fn(&mut T, X, V)` | yes, but not advised in getter |
-| `register_indexer_get_result` | `Fn(&mut T, X) -> Result>` | yes, but not advised |
-| `register_indexer_set_result` | `Fn(&mut T, X, V) -> Result<(), Box>` | yes |
-
-By convention, index getters are not supposed to mutate the [custom type], although there is nothing
-that prevents this mutation.
-
-**IMPORTANT: Rhai does NOT support normal references (i.e. `&T`) as parameters.**
-
-
-Cannot Override Arrays, Object Maps and Strings
-----------------------------------------------
-
-For efficiency reasons, indexers **cannot** be used to overload (i.e. override)
-built-in indexing operations for [arrays], [object maps] and [strings].
-
-Attempting to register indexers for an [array], [object map] or [string] panics.
-
-
-Examples
---------
-
-```rust
-#[derive(Clone)]
-struct TestStruct {
- fields: Vec
-}
-
-impl TestStruct {
- // Remember &mut must be used even for getters
- fn get_field(&mut self, index: String) -> i64 {
- self.fields[index.len()]
- }
- fn set_field(&mut self, index: String, value: i64) {
- self.fields[index.len()] = value
- }
-
- fn new() -> Self {
- Self { fields: vec![1, 2, 3, 4, 5] }
- }
-}
-
-let mut engine = Engine::new();
-
-engine
- .register_type::()
- .register_fn("new_ts", TestStruct::new)
- // Short-hand: .register_indexer_get_set(TestStruct::get_field, TestStruct::set_field);
- .register_indexer_get(TestStruct::get_field)
- .register_indexer_set(TestStruct::set_field);
-
-let result = engine.eval::(
- r#"
- let a = new_ts();
- a["xyz"] = 42; // these indexers use strings
- a["xyz"] // as the index type
- "#
-)?;
-
-println!("Answer: {}", result); // prints 42
-```
diff --git a/doc/src/rust/modules/ast.md b/doc/src/rust/modules/ast.md
deleted file mode 100644
index 0b2bb8b8..00000000
--- a/doc/src/rust/modules/ast.md
+++ /dev/null
@@ -1,80 +0,0 @@
-Create a Module from an AST
-==========================
-
-{{#include ../../links.md}}
-
-
-`Module::eval_ast_as_new`
-------------------------
-
-A [module] can be created from a single script (or pre-compiled [`AST`]) containing global variables,
-functions and sub-modules via the `Module::eval_ast_as_new` method.
-
-See the section on [_Exporting Variables, Functions and Sub-Modules_][`export`] for details on how to
-prepare a Rhai script for this purpose as well as to control which functions/variables to export.
-
-When given an [`AST`], it is first evaluated, then the following items are exposed as members of the
-new [module]:
-
-* Global variables – all variables exported via the `export` statement (those not exported remain hidden).
-
-* Functions not specifically marked `private`.
-
-* Global modules that remain in the [`Scope`] at the end of a script run (become sub-modules).
-
-`Module::eval_ast_as_new` encapsulates the entire `AST` into each function call, merging the
-module namespace with the global namespace. Therefore, functions defined within the same module
-script can cross-call each other.
-
-
-Examples
---------
-
-Don't forget the [`export`] statement, otherwise there will be no variables exposed by the module
-other than non-[`private`] functions (unless that's intentional).
-
-```rust
-use rhai::{Engine, Module};
-
-let engine = Engine::new();
-
-// Compile a script into an 'AST'
-let ast = engine.compile(r#"
- // Functions become module functions
- fn calc(x) {
- x + 1
- }
- fn add_len(x, y) {
- x + y.len
- }
-
- // Imported modules can become sub-modules
- import "another module" as extra;
-
- // Variables defined at global level can become module variables
- const x = 123;
- let foo = 41;
- let hello;
-
- // Variable values become constant module variable values
- foo = calc(foo);
- hello = "hello, " + foo + " worlds!";
-
- // Finally, export the variables and modules
- export
- x as abc, // aliased variable name
- foo,
- hello,
- extra as foobar; // export sub-module
-"#)?;
-
-// Convert the 'AST' into a module, using the 'Engine' to evaluate it first
-// A copy of the entire 'AST' is encapsulated into each function,
-// allowing functions in the module script to cross-call each other.
-let module = Module::eval_ast_as_new(Scope::new(), &ast, &engine)?;
-
-// 'module' now contains:
-// - sub-module: 'foobar' (renamed from 'extra')
-// - functions: 'calc', 'add_len'
-// - constants: 'abc' (renamed from 'x'), 'foo', 'hello'
-```
diff --git a/doc/src/rust/modules/create.md b/doc/src/rust/modules/create.md
deleted file mode 100644
index f5e10e97..00000000
--- a/doc/src/rust/modules/create.md
+++ /dev/null
@@ -1,158 +0,0 @@
-Create a Module from Rust
-========================
-
-{{#include ../../links.md}}
-
-
-Create via Plugin
------------------
-
-By far the simplest way to create a [module] is via a [plugin module]
-which converts a normal Rust module into a Rhai [module] via procedural macros.
-
-
-Create via `Module` API
------------------------
-
-Manually creating a [module] is possible via the `Module` API.
-
-For the complete `Module` API, refer to the [documentation](https://docs.rs/rhai/{{version}}/rhai/struct.Module.html) online.
-
-
-Use Case 1 – Make the `Module` Globally Available
-------------------------------------------------------
-
-`Engine::register_global_module` registers a shared [module] into the _global_ namespace.
-
-All [functions] and [type iterators] can be accessed without _namespace qualifiers_.
-Variables and sub-modules are **ignored**.
-
-This is by far the easiest way to expose a module's functionalities to Rhai.
-
-```rust
-use rhai::{Engine, Module};
-
-let mut module = Module::new(); // new module
-
-// Use the 'Module::set_fn_XXX' API to add functions.
-let hash = module.set_fn_1("inc", |x: i64| Ok(x + 1));
-
-// Remember to update the parameter names/types and return type metadata.
-// 'Module::set_fn_XXX' by default does not set function metadata.
-module.update_fn_metadata(hash, ["x: i64", "i64"]);
-
-// Register the module into the global namespace of the Engine.
-let mut engine = Engine::new();
-engine.register_global_module(module.into());
-
-engine.eval::("inc(41)")? == 42; // no need to import module
-```
-
-Registering a [module] via `Engine::register_global_module` is essentially the _same_
-as calling `Engine::register_fn` (or any of the `Engine::register_XXX` API) individually
-on each top-level function within that [module]. In fact, the actual implementation of
-`Engine::register_fn` etc. simply adds the function to an internal [module]!
-
-```rust
-// The above is essentially the same as:
-let mut engine = Engine::new();
-
-engine.register_fn("inc", |x: i64| x + 1);
-
-engine.eval::("inc(41)")? == 42; // no need to import module
-```
-
-Use Case 2 – Make the `Module` a Static Module
----------------------------------------------------
-
-`Engine::register_static_module` registers a [module] and under a specific module namespace.
-
-```rust
-use rhai::{Engine, Module};
-
-let mut module = Module::new(); // new module
-
-// Use the 'Module::set_fn_XXX' API to add functions.
-let hash = module.set_fn_1("inc", |x: i64| Ok(x + 1));
-
-// Remember to update the parameter names/types and return type metadata.
-// 'Module::set_fn_XXX' by default does not set function metadata.
-module.update_fn_metadata(hash, ["x: i64", "i64"]);
-
-// Register the module into the Engine as the static module namespace path
-// 'services::calc'
-let mut engine = Engine::new();
-engine.register_static_module("services::calc", module.into());
-
-// refer to the 'services::calc' module
-engine.eval::("services::calc::inc(41)")? == 42;
-```
-
-### Expose Functions to the Global Namespace
-
-The `Module::set_fn_XXX_mut` API methods can optionally expose functions in the [module]
-to the _global_ namespace by setting the `namespace` parameter to `FnNamespace::Global`,
-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.
-
-```rust
-use rhai::{Engine, Module, FnNamespace};
-
-let mut module = Module::new(); // new module
-
-// Expose method 'inc' to the global namespace (default is 'FnNamespace::Internal')
-let hash = module.set_fn_1_mut("inc", FnNamespace::Global, |x: &mut i64| Ok(x + 1));
-
-// Remember to update the parameter names/types and return type metadata.
-// 'Module::set_fn_XXX_mut' by default does not set function metadata.
-module.update_fn_metadata(hash, ["x: &mut i64", "i64"]);
-
-// Register the module into the Engine as a static module namespace 'calc'
-let mut engine = Engine::new();
-engine.register_static_module("calc", module.into());
-
-// 'inc' works when qualified by the namespace
-engine.eval::("calc::inc(41)")? == 42;
-
-// 'inc' also works without a namespace qualifier
-// because it is exposed to the global namespace
-engine.eval::("let x = 41; x.inc()")? == 42;
-engine.eval::("let x = 41; inc(x)")? == 42;
-```
-
-
-Use Case 3 – Make the `Module` Dynamically Loadable
---------------------------------------------------------
-
-In order to dynamically load a custom module, there must be a [module resolver] which serves
-the module when loaded via `import` statements.
-
-The easiest way is to use, for example, the [`StaticModuleResolver`][module resolver] to hold such
-a custom module.
-
-```rust
-use rhai::{Engine, Scope, Module};
-use rhai::module_resolvers::StaticModuleResolver;
-
-let mut module = Module::new(); // new module
-module.set_var("answer", 41_i64); // variable 'answer' under module
-module.set_fn_1("inc", |x: i64| Ok(x + 1)); // use the 'set_fn_XXX' API to add functions
-
-// Create the module resolver
-let mut resolver = StaticModuleResolver::new();
-
-// Add the module into the module resolver under the name 'question'
-// They module can then be accessed via: 'import "question" as q;'
-resolver.insert("question", module);
-
-// Set the module resolver into the 'Engine'
-let mut engine = Engine::new();
-engine.set_module_resolver(resolver);
-
-// Use namespace-qualified variables
-engine.eval::(r#"import "question" as q; q::answer + 1"#)? == 42;
-
-// Call namespace-qualified functions
-engine.eval::(r#"import "question" as q; q::inc(q::answer)"#)? == 42;
-```
diff --git a/doc/src/rust/modules/imp-resolver.md b/doc/src/rust/modules/imp-resolver.md
deleted file mode 100644
index 1094e208..00000000
--- a/doc/src/rust/modules/imp-resolver.md
+++ /dev/null
@@ -1,72 +0,0 @@
-Implement a Custom Module Resolver
-=================================
-
-{{#include ../../links.md}}
-
-For many applications in which Rhai is embedded, it is necessary to customize the way that modules
-are resolved. For instance, modules may need to be loaded from script texts stored in a database,
-not in the file system.
-
-A module resolver must implement the trait [`rhai::ModuleResolver`][traits],
-which contains only one function: `resolve`.
-
-When Rhai prepares to load a module, `ModuleResolver::resolve` is called with the name
-of the _module path_ (i.e. the path specified in the [`import`] statement).
-
-* Upon success, it should return an [`Rc`][module] (or [`Arc`][module] under [`sync`]).
-
- The module should call `Module::build_index` on the target module before returning.
- This method flattens the entire module tree and _indexes_ it for fast function name resolution.
- If the module is already indexed, calling this method has no effect.
-
-* If the path does not resolve to a valid module, return `EvalAltResult::ErrorModuleNotFound`.
-
-* If the module failed to load, return `EvalAltResult::ErrorInModule`.
-
-
-Example
--------
-
-```rust
-use rhai::{ModuleResolver, Module, Engine, EvalAltResult};
-
-// Define a custom module resolver.
-struct MyModuleResolver {}
-
-// Implement the 'ModuleResolver' trait.
-impl ModuleResolver for MyModuleResolver {
- // Only required function.
- fn resolve(
- &self,
- engine: &Engine, // reference to the current 'Engine'
- path: &str, // the module path
- pos: Position, // position of the 'import' statement
- ) -> Result, Box> {
- // Check module path.
- if is_valid_module_path(path) {
- let mut my_module =
- load_secret_module(path) // load the custom module
- .map_err(|err|
- // Return EvalAltResult::ErrorInModule upon loading error
- EvalAltResult::ErrorInModule(path.into(), Box::new(err), pos).into()
- )?;
- my_module.build_index(); // index it
- Rc::new(my_module) // make it shared
- } else {
- // Return EvalAltResult::ErrorModuleNotFound if the path is invalid
- Err(EvalAltResult::ErrorModuleNotFound(path.into(), pos).into())
- }
- }
-}
-
-let mut engine = Engine::new();
-
-// Set the custom module resolver into the 'Engine'.
-engine.set_module_resolver(MyModuleResolver {});
-
-engine.consume(r#"
- import "hello" as foo; // this 'import' statement will call
- // 'MyModuleResolver::resolve' with "hello" as 'path'
- foo:bar();
-"#)?;
-```
diff --git a/doc/src/rust/modules/index.md b/doc/src/rust/modules/index.md
deleted file mode 100644
index b42aa030..00000000
--- a/doc/src/rust/modules/index.md
+++ /dev/null
@@ -1,29 +0,0 @@
-Modules
-=======
-
-{{#include ../../links.md}}
-
-Rhai allows organizing functionalities (functions, both Rust-based or script-based, and variables)
-into independent _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.
-
-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.
-
-Other scripts can then load this module and use the functions and variables exported
-as if they were defined inside the same script.
-
-Alternatively, modules can be registered directly into an [`Engine`] and made available
-to scripts either globally or under individual static module [_namespaces_][function namespaces].
-
-
-Usage Patterns
---------------
-
-| Usage | API | Lookup | Sub-modules? | Variables? |
-| -------------- | :-------------------------------: | :----------------------: | :----------: | :--------: |
-| Global module | `Engine:: register_global_module` | simple name | ignored | ignored |
-| Static module | `Engine:: register_static_module` | namespace-qualified name | yes | yes |
-| Dynamic module | [`import`] statement | namespace-qualified name | yes | yes |
diff --git a/doc/src/rust/modules/resolvers.md b/doc/src/rust/modules/resolvers.md
deleted file mode 100644
index c7ba3196..00000000
--- a/doc/src/rust/modules/resolvers.md
+++ /dev/null
@@ -1,181 +0,0 @@
-Module Resolvers
-================
-
-{{#include ../../links.md}}
-
-When encountering an [`import`] statement, Rhai attempts to _resolve_ the module based on the path string.
-
-See the section on [_Importing Modules_][`import`] for more details.
-
-_Module Resolvers_ are service types that implement the [`ModuleResolver`][traits] trait.
-
-
-Built-In Module Resolvers
-------------------------
-
-There are a number of standard resolvers built into Rhai, the default being the `FileModuleResolver`
-which simply loads a script file based on the path (with `.rhai` extension attached)
-and execute it to form a module.
-
-Built-in module resolvers are grouped under the `rhai::module_resolvers` module namespace.
-
-
-`FileModuleResolver` (default)
------------------------------
-
-The _default_ module resolution service, not available for [`no_std`] or [WASM] builds.
-Loads a script file (based off the current directory) with `.rhai` extension.
-
-All functions in the _global_ namespace, plus all those defined in the same module,
-are _merged_ into a _unified_ namespace.
-
-All modules imported at _global_ level via [`import`] statements become sub-modules,
-which are also available to functions defined within the same script file.
-
-Modules are also _cached_ so a script file is only evaluated _once_, even when repeatedly imported.
-
-```rust
-------------------
-| my_module.rhai |
-------------------
-
-// This function overrides any in the main script.
-private fn inner_message() { "hello! from module!" }
-
-fn greet() {
- print(inner_message()); // call function in module script
-}
-
-fn greet_main() {
- print(main_message()); // call function not in module script
-}
-
--------------
-| main.rhai |
--------------
-
-// This function is overridden by the module script.
-fn inner_message() { "hi! from main!" }
-
-// This function is found by the module script.
-fn main_message() { "main here!" }
-
-import "my_module" as m;
-
-m::greet(); // prints "hello! from module!"
-
-m::greet_main(); // prints "main here!"
-```
-
-### Simulating virtual functions
-
-When calling a namespace-qualified function defined within a module, other functions defined within
-the same module script override any similar-named functions (with the same number of parameters)
-defined in the global namespace. This is to ensure that a module acts as a self-contained unit and
-functions defined in the calling script do not override module code.
-
-In some situations, however, it is actually beneficial to do it in reverse: have module code call functions
-defined in the calling script (i.e. in the global namespace) if they exist, and only call those defined
-in the module script if none are found.
-
-One such situation is the need to provide a _default implementation_ to a simulated _virtual_ function:
-
-```rust
-------------------
-| my_module.rhai |
-------------------
-
-// Do not do this (it will override the main script):
-// fn message() { "hello! from module!" }
-
-// This function acts as the default implementation.
-private fn default_message() { "hello! from module!" }
-
-// This function depends on a 'virtual' function 'message'
-// which is not defined in the module script.
-fn greet() {
- if is_def_fn("message", 0) { // 'is_def_fn' detects if 'message' is defined.
- print(message());
- } else {
- print(default_message());
- }
-}
-
--------------
-| main.rhai |
--------------
-
-// The main script defines 'message' which is needed by the module script.
-fn message() { "hi! from main!" }
-
-import "my_module" as m;
-
-m::greet(); // prints "hi! from main!"
-
---------------
-| main2.rhai |
---------------
-
-// The main script does not define 'message' which is needed by the module script.
-
-import "my_module" as m;
-
-m::greet(); // prints "hello! from module!"
-```
-
-### Changing the base directory
-
-The base directory can be changed via the `FileModuleResolver::new_with_path` constructor function.
-
-
-`StaticModuleResolver`
----------------------
-
-Loads modules that are statically added. This can be used under [`no_std`].
-
-Functions are searched in the _global_ namespace by default.
-
-```rust
-use rhai::{Module, module_resolvers::StaticModuleResolver};
-
-let module: Module = create_a_module();
-
-let mut resolver = StaticModuleResolver::new();
-resolver.insert("my_module", module);
-```
-
-
-`ModuleResolversCollection`
---------------------------
-
-A collection of module resolvers. Modules will be resolved from each resolver in sequential order.
-
-This is useful when multiple types of modules are needed simultaneously.
-
-
-`DummyResolversCollection`
--------------------------
-
-This module resolver acts as a _dummy_ and always fails all module resolution calls.
-
-
-Set into `Engine`
------------------
-
-An [`Engine`]'s module resolver is set via a call to `Engine::set_module_resolver`:
-
-```rust
-use rhai::module_resolvers::{DummyModuleResolver, StaticModuleResolver};
-
-// Create a module resolver
-let resolver = StaticModuleResolver::new();
-
-// Register functions into 'resolver'...
-
-// Use the module resolver
-engine.set_module_resolver(resolver);
-
-// Effectively disable 'import' statements by setting module resolver to
-// the 'DummyModuleResolver' which acts as... well... a dummy.
-engine.set_module_resolver(DummyModuleResolver::new());
-```
diff --git a/doc/src/rust/operators.md b/doc/src/rust/operators.md
deleted file mode 100644
index 83175bf8..00000000
--- a/doc/src/rust/operators.md
+++ /dev/null
@@ -1,74 +0,0 @@
-Operator Overloading
-===================
-
-{{#include ../links.md}}
-
-In Rhai, a lot of functionalities are actually implemented as functions, including basic operations
-such as arithmetic calculations.
-
-For example, in the expression "`a + b`", the `+` operator calls a function named "`+`"!
-
-```rust
-let x = a + b;
-
-let x = +(a, b); // <- the above is equivalent to this function call
-```
-
-Similarly, comparison operators including `==`, `!=` etc. are all implemented as functions,
-with the stark exception of `&&` and `||`.
-
-
-`&&` and `||` Cannot Be Overloaded
----------------------------------
-
-Because they [_short-circuit_]({{rootUrl}}/language/logic.md#boolean-operators), `&&` and `||` are
-handled specially and _not_ via a function; as a result, overriding them has no effect at all.
-
-
-Overload Operator via Rust Function
-----------------------------------
-
-Operator functions cannot be defined as a script function (because operators syntax are not valid function names).
-
-However, operator functions _can_ be registered to the [`Engine`] via the methods
-`Engine::register_fn`, `Engine::register_result_fn` etc.
-
-When a custom operator function is registered with the same name as an operator, it _overrides_ the built-in version.
-
-```rust
-use rhai::{Engine, EvalAltResult, RegisterFn};
-
-let mut engine = Engine::new();
-
-fn strange_add(a: i64, b: i64) -> i64 { (a + b) * 42 }
-
-engine.register_fn("+", strange_add); // overload '+' operator for two integers!
-
-let result: i64 = engine.eval("1 + 0"); // the overloading version is used
-
-result == 42;
-
-let result: f64 = engine.eval("1.0 + 0.0"); // '+' operator for two floats not overloaded
-
-result == 1.0;
-
-fn mixed_add(a: i64, b: f64) -> f64 { (a as f64) + b }
-
-engine.register_fn("+", mixed_add); // register '+' operator for an integer and a float
-
-let result: i64 = engine.eval("1 + 1.0"); // <- normally an error...
-
-result == 2.0; // ... but not now
-```
-
-
-Considerations
---------------
-
-Normally, use operator overloading for [custom types] only.
-
-Be very careful when overriding built-in operators because script authors expect standard operators to behave in a
-consistent and predictable manner, and will be annoyed if a calculation for '`+`' turns into a subtraction, for example.
-
-Operator overloading also impacts script optimization when using [`OptimizationLevel::Full`].
-See the [script-optimization] for more details.
diff --git a/doc/src/rust/override.md b/doc/src/rust/override.md
deleted file mode 100644
index 7620bfd5..00000000
--- a/doc/src/rust/override.md
+++ /dev/null
@@ -1,22 +0,0 @@
-Override a Built-in Function
-===========================
-
-{{#include ../links.md}}
-
-Any similarly-named function defined in a script _overrides_ any built-in or registered
-native Rust function of the same name and number of parameters.
-
-```rust
-// Override the built-in function 'to_float' when called as a method
-fn to_float() {
- print("Ha! Gotcha! " + this);
- 42.0
-}
-
-let x = 123.to_float();
-
-print(x); // what happens?
-```
-
-A registered native Rust function, in turn, overrides any built-in function of the
-same name, number and types of parameters.
diff --git a/doc/src/rust/packages/builtin.md b/doc/src/rust/packages/builtin.md
deleted file mode 100644
index a9b07b6c..00000000
--- a/doc/src/rust/packages/builtin.md
+++ /dev/null
@@ -1,40 +0,0 @@
-Built-In Packages
-================
-
-{{#include ../../links.md}}
-
-`Engine::new` creates an [`Engine`] with the `StandardPackage` loaded.
-
-`Engine::new_raw` creates an [`Engine`] with _no_ package loaded.
-
-| Package | Description | In `Core` | In `Standard` |
-| ---------------------- | ------------------------------------------------------------------------------------------------------ | :-------: | :-----------: |
-| `ArithmeticPackage` | arithmetic operators (e.g. `+`, `-`, `*`, `/`) for numeric types that are not built in (e.g. `u16`) | yes | yes |
-| `BasicIteratorPackage` | numeric ranges (e.g. `range(1, 10)`) | yes | yes |
-| `LogicPackage` | logical and comparison operators (e.g. `==`, `>`) for numeric types that are not built in (e.g. `u16`) | yes | yes |
-| `BasicStringPackage` | basic string functions (e.g. `print`, `debug`, `len`) that are not built in | yes | yes |
-| `BasicTimePackage` | basic time functions (e.g. [timestamps]) | yes | yes |
-| `MoreStringPackage` | additional string functions, including converting common types to string | no | yes |
-| `BasicMathPackage` | basic math functions (e.g. `sin`, `sqrt`) | no | yes |
-| `BasicArrayPackage` | basic [array] functions (not available under `no_index`) | no | yes |
-| `BasicMapPackage` | basic [object map] functions (not available under `no_object`) | no | yes |
-| `BasicFnPackage` | basic methods for [function pointers]. | yes | yes |
-| `CorePackage` | basic essentials | yes | yes |
-| `StandardPackage` | standard library (default for `Engine::new`) | no | yes |
-
-
-`CorePackage`
--------------
-
-If only minimal functionalities are required, register the `CorePackage` instead:
-
-```rust
-use rhai::Engine;
-use rhai::packages::{Package, CorePackage};
-
-let mut engine = Engine::new_raw();
-let package = CorePackage::new();
-
-// Register the package into the 'Engine' by converting it into a shared module.
-engine.register_global_module(package.as_shared_module());
-```
diff --git a/doc/src/rust/packages/create.md b/doc/src/rust/packages/create.md
deleted file mode 100644
index b02fe61d..00000000
--- a/doc/src/rust/packages/create.md
+++ /dev/null
@@ -1,130 +0,0 @@
-Create a Custom Package
-=======================
-
-{{#include ../../links.md}}
-
-
-The macro `def_package!` can be used to create a custom [package].
-
-A custom package can aggregate many other packages into a single self-contained unit.
-More functions can be added on top of others.
-
-
-`def_package!`
---------------
-
-> `def_package!(root:package_name:description, variable, block)`
-
-where:
-
-| Parameter | Description |
-| :------------: | ----------------------------------------------------------------------------------------------- |
-| `root` | root namespace, usually `rhai` |
-| `package_name` | name of the package, usually ending in `...Package` |
-| `description` | doc-comment for the package |
-| `variable` | a variable name holding a reference to the [module] (`&mut Module`) that is to form the package |
-| `block` | a code block that initializes the package |
-
-
-Examples
---------
-
-```rust
-// Import necessary types and traits.
-use rhai::{
- def_package, // 'def_package!' macro
- packages::Package, // 'Package' trait
- packages::{ // pre-defined packages
- ArithmeticPackage, BasicArrayPackage, BasicMapPackage, LogicPackage
- }
-};
-
-// Define the package 'MyPackage'.
-def_package!(rhai:MyPackage:"My own personal super package", module, {
- // Aggregate other packages simply by calling 'init' on each.
- ArithmeticPackage::init(module);
- LogicPackage::init(module);
- BasicArrayPackage::init(module);
- BasicMapPackage::init(module);
-
- // Register additional Rust functions using the standard 'set_fn_XXX' module API.
- let hash = module.set_fn_1("foo", |s: ImmutableString| {
- Ok(foo(s.into_owned()))
- });
-
- // Remember to update the parameter names/types and return type metadata.
- // 'set_fn_XXX' by default does not set function metadata.
- module.update_fn_metadata(hash, ["s: ImmutableString", "i64"]);
-});
-```
-
-
-Create a Custom Package from a Plugin Module
--------------------------------------------
-
-By far the easiest way to create a custom module is to call `plugin::combine_with_exported_module!`
-from within `def_package!` which simply merges in all the functions defined within a [plugin module].
-
-In fact, this exactly is how Rhai's built-in packages, such as `BasicMathPackage`, are implemented.
-
-Due to specific requirements of a [package], `plugin::combine_with_exported_module!`
-_flattens_ all sub-modules (i.e. all functions and [type iterators] defined within sub-modules
-are pulled up to the top level instead) and so there will not be any sub-modules added to the package.
-
-Variables in the [plugin module] are ignored.
-
-```rust
-// Import necessary types and traits.
-use rhai::{
- def_package,
- packages::Package,
- packages::{ArithmeticPackage, BasicArrayPackage, BasicMapPackage, LogicPackage}
-};
-use rhai::plugin::*;
-
-// Define plugin module.
-#[export_module]
-mod my_module {
- pub const MY_NUMBER: i64 = 42;
-
- pub fn greet(name: &str) -> String {
- format!("hello, {}!", name)
- }
- pub fn get_num() -> i64 {
- 42
- }
-
- // This is a sub-module, but if using combine_with_exported_module!, it will
- // be flattened and all functions registered at the top level.
- pub mod my_sub_module {
- pub fn get_sub_num() -> i64 {
- 0
- }
- }
-}
-
-// Define the package 'MyPackage'.
-def_package!(rhai:MyPackage:"My own personal super package", module, {
- // Aggregate other packages simply by calling 'init' on each.
- ArithmeticPackage::init(module);
- LogicPackage::init(module);
- BasicArrayPackage::init(module);
- BasicMapPackage::init(module);
-
- // Merge all registered functions and constants from the plugin module into the custom package.
- //
- // The sub-module 'my_sub_module' is flattened and its functions registered at the top level.
- //
- // The text string name in the second parameter can be anything and is reserved for future use;
- // it is recommended to be an ID string that uniquely identifies the plugin module.
- //
- // The constant variable, 'MY_NUMBER', is ignored.
- //
- // This call ends up registering three functions at the top level of the package:
- // 1) greet
- // 2) get_num
- // 3) get_sub_num (pulled up from 'my_sub_module')
- //
- combine_with_exported_module!(module, "my-functions", my_module));
-});
-```
diff --git a/doc/src/rust/packages/index.md b/doc/src/rust/packages/index.md
deleted file mode 100644
index afbba8cf..00000000
--- a/doc/src/rust/packages/index.md
+++ /dev/null
@@ -1,58 +0,0 @@
-Packages
-========
-
-{{#include ../../links.md}}
-
-The built-in library of Rhai is provided as various _packages_ that can be
-turned into _shared_ [modules], which in turn can be registered into the
-_global namespace_ of an [`Engine`] via `Engine::register_global_module`.
-
-Packages reside under `rhai::packages::*` and the trait `rhai::packages::Package`
-must be loaded in order for packages to be used.
-
-### Packages _are_ Modules
-
-Internally, a _package_ is a _newtype_ wrapping a pre-defined [module],
-with some conveniences to make it easier to define and use as a standard
-_library_ for an [`Engine`].
-
-Packages typically contain Rust functions that are callable within a Rhai script.
-All _top-level_ functions in a package are available under the _global namespace_
-(i.e. they're available without namespace qualifiers).
-
-Sub-modules and variables are ignored in packages.
-
-
-Share a Package Among Multiple `Engine`'s
-----------------------------------------
-
-`Engine::register_global_module` and `Engine::register_static_module` both require _shared_ [modules].
-
-Once a package is created (e.g. via `Package::new`), it can create _shared_ [modules]
-(via `Package::as_shared_module`) and register them into multiple instances of [`Engine`],
-even across threads (under the [`sync`] feature).
-
-Therefore, a package only has to be created _once_ and essentially shared among multiple
-[`Engine`] instances. This is particular useful when spawning large number of [raw `Engine`'s][raw `Engine`].
-
-```rust
-use rhai::Engine;
-use rhai::packages::Package // load the 'Package' trait to use packages
-use rhai::packages::CorePackage; // the 'core' package contains basic functionalities (e.g. arithmetic)
-
-// Create a package - can be shared among multiple 'Engine' instances
-let package = CorePackage::new();
-
-let mut engines_collection: Vec = Vec::new();
-
-// Create 100 'raw' Engines
-for _ in 0..100 {
- let mut engine = Engine::new_raw();
-
- // Register the package into the global namespace.
- // 'Package::as_shared_module' converts the package into a shared module.
- engine.register_global_module(package.as_shared_module());
-
- engines_collection.push(engine);
-}
-```
diff --git a/doc/src/rust/print-custom.md b/doc/src/rust/print-custom.md
deleted file mode 100644
index c013559b..00000000
--- a/doc/src/rust/print-custom.md
+++ /dev/null
@@ -1,18 +0,0 @@
-Printing for Custom Types
-========================
-
-{{#include ../links.md}}
-
-To use custom types for [`print`] and [`debug`], or convert its value into a [string],
-it is necessary that the following functions be registered (assuming the custom type
-is `T: Display + Debug`):
-
-| Function | Signature | Typical implementation | Usage |
-| ----------- | ---------------------------------------------- | ---------------------------- | -------------------------------------------------------------------- |
-| `to_string` | \|x: &mut T\| -> String
| `x.to_string()` | converts the custom type into a [string] |
-| `print` | \|x: &mut T\| -> String
| `x.to_string()` | converts the custom type into a [string] for the [`print`] statement |
-| `to_debug` | \|x: &mut T\| -> String
| `format!("{:?}", x)` | converts the custom type into a [string] in debug format |
-| `debug` | \|x: &mut T\| -> String
| `format!("{:?}", x)` | converts the custom type into a [string] for the [`debug`] statement |
-| `+` | \|s: &str, x: T\| -> String
| `format!("{}{}", s, x)` | concatenates the custom type with another [string] |
-| `+` | \|x: &mut T, s: &str\| -> String
| `x.to_string().push_str(s);` | concatenates another [string] with the custom type |
-| `+=` | \|s: &mut ImmutableString, x: T\|
| `s += x.to_string()` | appends the custom type to an existing [string] |
diff --git a/doc/src/rust/register-raw.md b/doc/src/rust/register-raw.md
deleted file mode 100644
index 7b7566f7..00000000
--- a/doc/src/rust/register-raw.md
+++ /dev/null
@@ -1,189 +0,0 @@
-Use the Low-Level API to Register a Rust Function
-================================================
-
-{{#include ../links.md}}
-
-When a native Rust function is registered with an `Engine` using the `Engine::register_XXX` API,
-Rhai transparently converts all function arguments from [`Dynamic`] into the correct types before
-calling the function.
-
-For more power and flexibility, there is a _low-level_ API to work directly with [`Dynamic`] values
-without the conversions.
-
-
-Raw Function Registration
--------------------------
-
-The `Engine::register_raw_fn` method is marked _volatile_, meaning that it may be changed without warning.
-
-If this is acceptable, then using this method to register a Rust function opens up more opportunities.
-
-In particular, a the current _native call context_ (in form of the `NativeCallContext` type) is passed as an argument.
-`NativeCallContext` exposes the current [`Engine`], among others, so the Rust function can also use [`Engine`] facilities
-(such as evaluating a script).
-
-```rust
-engine.register_raw_fn(
- "increment_by", // function name
- &[ // a slice containing parameter types
- std::any::TypeId::of::(), // type of first parameter
- std::any::TypeId::of::() // type of second parameter
- ],
- |context, args| { // fixed function signature
- // Arguments are guaranteed to be correct in number and of the correct types.
-
- // But remember this is Rust, so you can keep only one mutable reference at any one time!
- // Therefore, get a '&mut' reference to the first argument _last_.
- // Alternatively, use `args.split_first_mut()` etc. to split the slice first.
-
- let y = *args[1].read_lock::().unwrap(); // get a reference to the second argument
- // then copy it because it is a primary type
-
- let y = std::mem::take(args[1]).cast::(); // alternatively, directly 'consume' it
-
- let x = args[0].write_lock::().unwrap(); // get a '&mut' reference to the first argument
-
- *x += y; // perform the action
-
- Ok(Dynamic::UNIT) // must be 'Result>'
- }
-);
-
-// The above is the same as (in fact, internally they are equivalent):
-
-engine.register_fn("increment_by", |x: &mut i64, y: i64| *x += y);
-```
-
-
-Function Signature
-------------------
-
-The function signature passed to `Engine::register_raw_fn` takes the following form:
-
-> `Fn(context: NativeCallContext, args: &mut [&mut Dynamic])`
-> `-> Result> + 'static`
-
-where:
-
-| Parameter | Type | Description |
-| -------------------------- | :-------------------------------------: | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
-| `T` | `impl Clone` | return type of the function |
-| `context` | `NativeCallContext` | the current _native call context_ |
-| • `engine()` | `&Engine` | the current [`Engine`], with all configurations and settings. This is sometimes useful for calling a script-defined function within the same evaluation context using [`Engine::call_fn`][`call_fn`], or calling a [function pointer]. |
-| • `source()` | `Option<&str>` | reference to the current source, if any |
-| • `iter_imports()` | `impl Iterator- ` | iterator of the current stack of [modules] imported via `import` statements |
-| • `imports()` | `&Imports` | reference to the current stack of [modules] imported via `import` statements; requires the [`internals`] feature |
-| • `iter_namespaces()` | `impl Iterator
- ` | iterator of the namespaces (as [modules]) containing all script-defined functions |
-| • `namespaces()` | `&[&Module]` | reference to the namespaces (as [modules]) containing all script-defined functions; requires the [`internals`] feature |
-| `args` | `&mut [&mut Dynamic]` | a slice containing `&mut` references to [`Dynamic`] values.
The slice is guaranteed to contain enough arguments _of the correct types_. |
-
-### Return value
-
-The return value is the result of the function call.
-
-Remember, in Rhai, all arguments _except_ the _first_ one are always passed by _value_ (i.e. cloned).
-Therefore, it is unnecessary to ever mutate any argument except the first one, as all mutations
-will be on the cloned copy.
-
-
-Extract Arguments
------------------
-
-To extract an argument from the `args` parameter (`&mut [&mut Dynamic]`), use the following:
-
-| Argument type | Access (`n` = argument position) | Result |
-| ------------------------------ | ------------------------------------- | ----------------------------------------------------- |
-| [Primary type][standard types] | `args[n].clone().cast::()` | copy of value |
-| [Custom type] | `args[n].read_lock::().unwrap()` | immutable reference to value |
-| [Custom type] (consumed) | `std::mem::take(args[n]).cast::()` | the _consumed_ value; the original value becomes `()` |
-| `this` object | `args[0].write_lock::().unwrap()` | mutable reference to value |
-
-When there is a mutable reference to the `this` object (i.e. the first argument),
-there can be no other immutable references to `args`, otherwise the Rust borrow checker will complain.
-
-
-Example – Passing a Callback to a Rust Function
-----------------------------------------------------
-
-The low-level API is useful when there is a need to interact with the scripting [`Engine`]
-within a function.
-
-The following example registers a function that takes a [function pointer] as an argument,
-then calls it within the same [`Engine`]. This way, a _callback_ function can be provided
-to a native Rust function.
-
-```rust
-use rhai::{Engine, FnPtr};
-
-let mut engine = Engine::new();
-
-// Register a Rust function
-engine.register_raw_fn(
- "bar",
- &[
- std::any::TypeId::of::(), // parameter types
- std::any::TypeId::of::(),
- std::any::TypeId::of::(),
- ],
- |context, args| {
- // 'args' is guaranteed to contain enough arguments of the correct types
-
- let fp = std::mem::take(args[1]).cast::(); // 2nd argument - function pointer
- let value = args[2].clone(); // 3rd argument - function argument
- let this_ptr = args.get_mut(0).unwrap(); // 1st argument - this pointer
-
- // Use 'FnPtr::call_dynamic' to call the function pointer.
- // Beware, private script-defined functions will not be found.
- fp.call_dynamic(context, Some(this_ptr), [value])
- },
-);
-
-let result = engine.eval::(
- r#"
- fn foo(x) { this += x; } // script-defined function 'foo'
-
- let x = 41; // object
- x.bar(Fn("foo"), 1); // pass 'foo' as function pointer
- x
- "#)?;
-```
-
-
-TL;DR – Why `read_lock` and `write_lock`
----------------------------------------------
-
-The `Dynamic` API that casts it to a reference to a particular data type is `read_lock`
-(for an immutable reference) and `write_lock` (for a mutable reference).
-
-As the naming shows, something is _locked_ in order to allow this access, and that something
-is a _shared value_ created by [capturing][automatic currying] variables from [closures].
-
-Shared values are implemented as `Rc>` (`Arc>` under [`sync`]).
-
-If the value is _not_ a shared value, or if running under [`no_closure`] where there is
-no [capturing][automatic currying], this API de-sugars to a simple `Dynamic::downcast_ref` and
-`Dynamic::downcast_mut`. In other words, there is no locking and reference counting overhead
-for the vast majority of non-shared values.
-
-If the value is a shared value, then it is first locked and the returned lock guard
-then allows access to the underlying value in the specified type.
-
-
-Hold Multiple References
-------------------------
-
-In order to access a value argument that is expensive to clone _while_ holding a mutable reference
-to the first argument, either _consume_ that argument via `mem::take` as above, or use `args.split_first`
-to partition the slice:
-
-```rust
-// Partition the slice
-let (first, rest) = args.split_first_mut().unwrap();
-
-// Mutable reference to the first parameter
-let this_ptr = &mut *first.write_lock::().unwrap();
-
-// Immutable reference to the second value parameter
-// This can be mutable but there is no point because the parameter is passed by value
-let value_ref = &*rest[0].read_lock::().unwrap();
-```
diff --git a/doc/src/rust/serde.md b/doc/src/rust/serde.md
deleted file mode 100644
index 38ef690a..00000000
--- a/doc/src/rust/serde.md
+++ /dev/null
@@ -1,126 +0,0 @@
-Serialization and Deserialization of `Dynamic` with `serde`
-=========================================================
-
-{{#include ../links.md}}
-
-Rhai's [`Dynamic`] type supports serialization and deserialization by [`serde`](https://crates.io/crates/serde)
-via the [`serde`][features] feature.
-
-A [`Dynamic`] can be seamlessly converted to and from a type that implements
-[`serde::Serialize`](https://docs.serde.rs/serde/trait.Serialize.html) and/or
-[`serde::Deserialize`](https://docs.serde.rs/serde/trait.Deserialize.html).
-
-
-Serialization
--------------
-
-The function `rhai::serde::to_dynamic` automatically converts any Rust type that implements
-[`serde::Serialize`](https://docs.serde.rs/serde/trait.Serialize.html) into a [`Dynamic`].
-
-This is usually not necessary because using [`Dynamic::from`][`Dynamic`] is much easier and is essentially
-the same thing. The only difference is treatment for integer values. `Dynamic::from` will keep the different
-integer types intact, while `rhai::serde::to_dynamic` will convert them all into [`INT`][standard types]
-(i.e. the system integer type which is `i64` or `i32` depending on the [`only_i32`] feature).
-
-In particular, Rust `struct`'s (or any type that is marked as a `serde` map) are converted into [object maps]
-while Rust `Vec`'s (or any type that is marked as a `serde` sequence) are converted into [arrays].
-
-While it is also simple to serialize a Rust type to `JSON` via `serde`,
-then use [`Engine::parse_json`]({{rootUrl}}/language/json.md) to convert it into an [object map],
-`rhai::serde::to_dynamic` serializes it to [`Dynamic`] directly via `serde` without going through the `JSON` step.
-
-```rust
-use rhai::{Dynamic, Map};
-use rhai::serde::to_dynamic;
-
-#[derive(Debug, serde::Serialize)]
-struct Point {
- x: f64,
- y: f64
-}
-
-#[derive(Debug, serde::Serialize)]
-struct MyStruct {
- a: i64,
- b: Vec,
- c: bool,
- d: Point
-}
-
-let x = MyStruct {
- a: 42,
- b: vec![ "hello".into(), "world".into() ],
- c: true,
- d: Point { x: 123.456, y: 999.0 }
-};
-
-// Convert the 'MyStruct' into a 'Dynamic'
-let map: Dynamic = to_dynamic(x);
-
-map.is::() == true;
-```
-
-
-Deserialization
----------------
-
-The function `rhai::serde::from_dynamic` automatically converts a [`Dynamic`] value into any Rust type
-that implements [`serde::Deserialize`](https://docs.serde.rs/serde/trait.Deserialize.html).
-
-In particular, [object maps] are converted into Rust `struct`'s (or any type that is marked as
-a `serde` map) while [arrays] are converted into Rust `Vec`'s (or any type that is marked
-as a `serde` sequence).
-
-```rust
-use rhai::{Engine, Dynamic};
-use rhai::serde::from_dynamic;
-
-#[derive(Debug, serde::Deserialize)]
-struct Point {
- x: f64,
- y: f64
-}
-
-#[derive(Debug, serde::Deserialize)]
-struct MyStruct {
- a: i64,
- b: Vec,
- c: bool,
- d: Point
-}
-
-let engine = Engine::new();
-
-let result: Dynamic = engine.eval(r#"
- ##{
- a: 42,
- b: [ "hello", "world" ],
- c: true,
- d: #{ x: 123.456, y: 999.0 }
- }
- "#)?;
-
-// Convert the 'Dynamic' object map into 'MyStruct'
-let x: MyStruct = from_dynamic(&result)?;
-```
-
-
-Cannot Deserialize Shared Values
--------------------------------
-
-A [`Dynamic`] containing a _shared_ value cannot be deserialized – i.e. it will give a type error.
-
-Use `Dynamic::flatten` to obtain a cloned copy before deserialization
-(if the value is not shared, it is simply returned and not cloned).
-
-Shared values are turned off via the [`no_closure`] feature.
-
-
-Lighter Alternative
--------------------
-
-The [`serde`](https://crates.io/crates/serde) crate is quite heavy.
-
-If only _simple_ JSON parsing (i.e. only deserialization) of a hash object into a Rhai [object map] is required,
-the [`Engine::parse_json`]({{rootUrl}}/language/json.md}}) method is available as a _cheap_ alternative,
-but it does not provide the same level of correctness, nor are there any configurable options.
diff --git a/doc/src/rust/strings.md b/doc/src/rust/strings.md
deleted file mode 100644
index 737bb207..00000000
--- a/doc/src/rust/strings.md
+++ /dev/null
@@ -1,43 +0,0 @@
-`String` Parameters in Rust Functions
-====================================
-
-{{#include ../links.md}}
-
-
-Avoid `String`
---------------
-
-As must as possible, avoid using `String` parameters in functions.
-
-Each `String` argument is cloned during every single call to that function – and the copy
-immediately thrown away right after the call.
-
-Needless to say, it is _extremely_ inefficient to use `String` parameters.
-
-
-`&str` Maps to `ImmutableString`
--------------------------------
-
-Rust functions accepting parameters of `String` should use `&str` instead because it maps directly to
-[`ImmutableString`][string] which is the type that Rhai uses to represent [strings] internally.
-
-The parameter type `String` involves always converting an [`ImmutableString`][string] into a `String`
-which mandates cloning it.
-
-Using `ImmutableString` or `&str` is much more efficient.
-A common mistake made by novice Rhai users is to register functions with `String` parameters.
-
-```rust
-fn get_len1(s: String) -> i64 { s.len() as i64 } // <- Very inefficient!!!
-fn get_len2(s: &str) -> i64 { s.len() as i64 } // <- This is better
-fn get_len3(s: ImmutableString) -> i64 { s.len() as i64 } // <- the above is equivalent to this
-
-engine
- .register_fn("len1", get_len1)
- .register_fn("len2", get_len2)
- .register_fn("len3", get_len3);
-
-let len = engine.eval::("x.len1()")?; // 'x' is cloned, very inefficient!
-let len = engine.eval::("x.len2()")?; // 'x' is shared
-let len = engine.eval::("x.len3()")?; // 'x' is shared
-```
diff --git a/doc/src/rust/traits.md b/doc/src/rust/traits.md
deleted file mode 100644
index a9b1a297..00000000
--- a/doc/src/rust/traits.md
+++ /dev/null
@@ -1,14 +0,0 @@
-Traits
-======
-
-{{#include ../links.md}}
-
-A number of traits, under the `rhai::` module namespace, provide additional functionalities.
-
-| Trait | Description | Methods |
-| ------------------------ | ------------------------------------------------------------------ | --------------------------------------------------------------------- |
-| `RegisterFn` | trait for registering functions | `register_fn` |
-| `RegisterResultFn` | trait for registering [fallible functions] | `register_result_fn` |
-| `Func` | trait for creating Rust closures from script | `create_from_ast`, `create_from_script` |
-| `ModuleResolver` | trait implemented by [module resolution][module resolver] services | `resolve` |
-| `plugin::PluginFunction` | trait implemented by [plugin] functions | `call`, `is_method_call`, `is_variadic`, `clone_boxed`, `input_types` |
diff --git a/doc/src/safety/checked.md b/doc/src/safety/checked.md
deleted file mode 100644
index e16164b0..00000000
--- a/doc/src/safety/checked.md
+++ /dev/null
@@ -1,11 +0,0 @@
-Checked Arithmetic
-=================
-
-{{#include ../links.md}}
-
-By default, all arithmetic calculations in Rhai are _checked_, meaning that the script terminates
-with an error whenever it detects a numeric over-flow/under-flow condition or an invalid
-floating-point operation, instead of crashing the entire system.
-
-This checking can be turned off via the [`unchecked`] feature for higher performance
-(but higher risks as well).
diff --git a/doc/src/safety/index.md b/doc/src/safety/index.md
deleted file mode 100644
index 6e4e8c1c..00000000
--- a/doc/src/safety/index.md
+++ /dev/null
@@ -1,45 +0,0 @@
-Safety and Protection Against DoS Attacks
-========================================
-
-{{#include ../links.md}}
-
-For scripting systems open to untrusted user-land scripts, it is always best to limit the amount of
-resources used by a script so that it does not consume more resources that it is allowed to.
-
-The most important resources to watch out for are:
-
-* **Memory**: A malicious script may continuously grow a [string], an [array] or [object map] until all memory is consumed.
-
- It may also create a large [array] or [object map] literal that exhausts all memory during parsing.
-
-* **CPU**: A malicious script may run an infinite tight loop that consumes all CPU cycles.
-
-* **Time**: A malicious script may run indefinitely, thereby blocking the calling system which is waiting for a result.
-
-* **Stack**: A malicious script may attempt an infinite recursive call that exhausts the call stack.
-
- Alternatively, it may create a degenerated deep expression with so many levels that the parser exhausts the call stack
- when parsing the expression; or even deeply-nested statement blocks, if nested deep enough.
-
- Another way to cause a stack overflow is to load a [self-referencing module][`import`].
-
-* **Overflows**: A malicious script may deliberately cause numeric over-flows and/or under-flows, divide by zero, and/or
- create bad floating-point representations, in order to crash the system.
-
-* **Files**: A malicious script may continuously [`import`] an external module within an infinite loop,
- thereby putting heavy load on the file-system (or even the network if the file is not local).
-
- Even when modules are not created from files, they still typically consume a lot of resources to load.
-
-* **Data**: A malicious script may attempt to read from and/or write to data that it does not own. If this happens,
- it is a severe security breach and may put the entire system at risk.
-
-
-`unchecked`
------------
-
-All these safe-guards can be turned off via the [`unchecked`] feature, which disables all
-safety checks (even fatal errors such as arithmetic overflows and division-by-zero).
-
-This will increase script evaluation performance, at the expense of having an erroneous
-script able to panic the entire system.
diff --git a/doc/src/safety/max-array-size.md b/doc/src/safety/max-array-size.md
deleted file mode 100644
index a50a3745..00000000
--- a/doc/src/safety/max-array-size.md
+++ /dev/null
@@ -1,40 +0,0 @@
-Maximum Size of Arrays
-=====================
-
-{{#include ../links.md}}
-
-Limit How Large Arrays Can Grow
-------------------------------
-
-Rhai by default does not limit how large an [array] can be.
-
-This can be changed via the `Engine::set_max_array_size` method, with zero being unlimited (the default).
-
-A script attempting to create an array literal larger than the maximum will terminate with a parse error.
-
-Any script operation that produces an array larger than the maximum also terminates the script with an error result.
-
-This check can be disabled via the [`unchecked`] feature for higher performance (but higher risks as well).
-
-```rust
-let mut engine = Engine::new();
-
-engine.set_max_array_size(500); // allow arrays only up to 500 items
-
-engine.set_max_array_size(0); // allow unlimited arrays
-```
-
-
-Setting Maximum Size
--------------------
-
-Be conservative when setting a maximum limit and always consider the fact that a registered function may grow
-an array's size without Rhai noticing until the very end.
-
-For instance, the built-in '`+`' operator for arrays concatenates two arrays together to form one larger array;
-if both arrays are _slightly_ below the maximum size limit, the resultant array may be almost _twice_ the maximum size.
-
-As a malicious script may create a deeply-nested array which consumes huge amounts of memory while each individual
-array still stays under the maximum size limit, Rhai also recursively adds up the sizes of all [strings], [arrays]
-and [object maps] contained within each array to make sure that the _aggregate_ sizes of none of these data structures
-exceed their respective maximum size limits (if any).
diff --git a/doc/src/safety/max-call-stack.md b/doc/src/safety/max-call-stack.md
deleted file mode 100644
index 7efb3c9d..00000000
--- a/doc/src/safety/max-call-stack.md
+++ /dev/null
@@ -1,31 +0,0 @@
-Maximum Call Stack Depth
-=======================
-
-{{#include ../links.md}}
-
-Limit How Stack Usage by Scripts
--------------------------------
-
-Rhai by default limits function calls to a maximum depth of 128 levels (8 levels in debug build).
-
-This limit may be changed via the `Engine::set_max_call_levels` method.
-
-A script exceeding the maximum call stack depth will terminate with an error result.
-
-This check can be disabled via the [`unchecked`] feature for higher performance (but higher risks as well).
-
-```rust
-let mut engine = Engine::new();
-
-engine.set_max_call_levels(10); // allow only up to 10 levels of function calls
-
-engine.set_max_call_levels(0); // allow no function calls at all (max depth = zero)
-```
-
-
-Setting Maximum Stack Depth
---------------------------
-
-When setting this limit, care must be also taken to the evaluation depth of each _statement_
-within a function. It is entirely possible for a malicious script to embed a recursive call deep
-inside a nested expression or statement block (see [maximum statement depth]).
diff --git a/doc/src/safety/max-map-size.md b/doc/src/safety/max-map-size.md
deleted file mode 100644
index a980562b..00000000
--- a/doc/src/safety/max-map-size.md
+++ /dev/null
@@ -1,40 +0,0 @@
-Maximum Size of Object Maps
-==========================
-
-{{#include ../links.md}}
-
-Limit How Large Object Maps Can Grow
------------------------------------
-
-Rhai by default does not limit how large (i.e. the number of properties) an [object map] can be.
-
-This can be changed via the `Engine::set_max_map_size` method, with zero being unlimited (the default).
-
-A script attempting to create an object map literal with more properties than the maximum will terminate with a parse error.
-
-Any script operation that produces an object map with more properties than the maximum also terminates the script with an error result.
-
-This check can be disabled via the [`unchecked`] feature for higher performance (but higher risks as well).
-
-```rust
-let mut engine = Engine::new();
-
-engine.set_max_map_size(500); // allow object maps with only up to 500 properties
-
-engine.set_max_map_size(0); // allow unlimited object maps
-```
-
-
-Setting Maximum Size
--------------------
-
-Be conservative when setting a maximum limit and always consider the fact that a registered function may grow
-an object map's size without Rhai noticing until the very end.
-
-For instance, the built-in '`+`' operator for object maps concatenates two object maps together to form one larger object map;
-if both object maps are _slightly_ below the maximum size limit, the resultant object map may be almost _twice_ the maximum size.
-
-As a malicious script may create a deeply-nested object map which consumes huge amounts of memory while each individual
-object map still stays under the maximum size limit, Rhai also recursively adds up the sizes of all [strings], [arrays]
-and [object maps] contained within each object map to make sure that the _aggregate_ sizes of none of these data structures
-exceed their respective maximum size limits (if any).
diff --git a/doc/src/safety/max-modules.md b/doc/src/safety/max-modules.md
deleted file mode 100644
index adb1c133..00000000
--- a/doc/src/safety/max-modules.md
+++ /dev/null
@@ -1,26 +0,0 @@
-Maximum Number of Modules
-========================
-
-{{#include ../links.md}}
-
-Rhai by default does not limit how many [modules] can be loaded via [`import`] statements.
-
-This can be changed via the `Engine::set_max_modules` method. Notice that setting the maximum number
-of modules to zero does _not_ indicate unlimited modules, but disallows loading any module altogether.
-
-A script attempting to load more than the maximum number of modules will terminate with an error result.
-
-This limit can also be used to stop [`import`-loops][`import`] (i.e. cycles of modules referring to each other).
-
-This check can be disabled via the [`unchecked`] feature for higher performance
-(but higher risks as well).
-
-```rust
-let mut engine = Engine::new();
-
-engine.set_max_modules(5); // allow loading only up to 5 modules
-
-engine.set_max_modules(0); // disallow loading any module (maximum = zero)
-
-engine.set_max_modules(1000); // set to a large number for effectively unlimited modules
-```
diff --git a/doc/src/safety/max-operations.md b/doc/src/safety/max-operations.md
deleted file mode 100644
index 86d85fc1..00000000
--- a/doc/src/safety/max-operations.md
+++ /dev/null
@@ -1,44 +0,0 @@
-Maximum Number of Operations
-===========================
-
-{{#include ../links.md}}
-
-
-Limit How Long a Script Can Run
-------------------------------
-
-Rhai by default does not limit how much time or CPU a script consumes.
-
-This can be changed via the `Engine::set_max_operations` method, with zero being unlimited (the default).
-
-The _operations count_ is intended to be a very course-grained measurement of the amount of CPU that a script
-has consumed, allowing the system to impose a hard upper limit on computing resources.
-
-A script exceeding the maximum operations count terminates with an error result.
-This can be disabled via the [`unchecked`] feature for higher performance (but higher risks as well).
-
-```rust
-let mut engine = Engine::new();
-
-engine.set_max_operations(500); // allow only up to 500 operations for this script
-
-engine.set_max_operations(0); // allow unlimited operations
-```
-
-
-What Does One _Operation_ Mean
------------------------------
-
-The concept of one single _operation_ in Rhai is volatile – it roughly equals one expression node,
-loading one variable/constant, one operator call, one iteration of a loop, or one function call etc.
-with sub-expressions, statements and function calls executed inside these contexts accumulated on top.
-
-A good rule-of-thumb is that one simple non-trivial expression consumes on average 5-10 operations.
-
-One _operation_ can take an unspecified amount of time and real CPU cycles, depending on the particulars.
-For example, loading a constant consumes very few CPU cycles, while calling an external Rust function,
-though also counted as only one operation, may consume much more computing resources.
-
-To help visualize, think of an _operation_ as roughly equals to one _instruction_ of a hypothetical CPU
-which includes _specialized_ instructions, such as _function call_, _load module_ etc., each taking up
-one CPU cycle to execute.
diff --git a/doc/src/safety/max-stmt-depth.md b/doc/src/safety/max-stmt-depth.md
deleted file mode 100644
index e9749689..00000000
--- a/doc/src/safety/max-stmt-depth.md
+++ /dev/null
@@ -1,56 +0,0 @@
-Maximum Statement Depth
-======================
-
-{{#include ../links.md}}
-
-Limit How Deeply-Nested a Statement Can Be
------------------------------------------
-
-Rhai by default limits statements and expressions nesting to a maximum depth of 128
-(which should be plenty) when they are at _global_ level, but only a depth of 32
-when they are within function bodies.
-
-For debug builds, these limits are set further downwards to 32 and 16 respectively.
-
-That is because it is possible to overflow the [`Engine`]'s stack when it tries to
-recursively parse an extremely deeply-nested code stream.
-
-```rust
-// The following, if long enough, can easily cause stack overflow during parsing.
-let a = (1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(...)+1)))))))))));
-```
-
-This limit may be changed via the `Engine::set_max_expr_depths` method.
-
-There are two limits to set, one for the maximum depth at global level, and the other for function bodies.
-
-A script exceeding the maximum nesting depths will terminate with a parsing error.
-The malicious [`AST`] will not be able to get past parsing in the first place.
-
-This check can be disabled via the [`unchecked`] feature for higher performance (but higher risks as well).
-
-```rust
-let mut engine = Engine::new();
-
-engine.set_max_expr_depths(50, 5); // allow nesting up to 50 layers of expressions/statements
- // at global level, but only 5 inside functions
-```
-
-Beware that there may be multiple layers for a simple language construct, even though it may correspond
-to only one AST node. That is because the Rhai _parser_ internally runs a recursive chain of function calls
-and it is important that a malicious script does not panic the parser in the first place.
-
-
-Beware of Recursion
--------------------
-
-_Functions_ are placed under stricter limits because of the multiplicative effect of _recursion_.
-
-A script can effectively call itself while deep inside an expression chain within the function body,
-thereby overflowing the stack even when the level of recursion is within limit.
-
-In general, make sure that `C x ( 5 + F ) + S` layered calls do not cause a stack overflow, where:
-
-* `C` = maximum call stack depth,
-* `F` = maximum statement depth for functions,
-* `S` = maximum statement depth at global level.
diff --git a/doc/src/safety/max-string-size.md b/doc/src/safety/max-string-size.md
deleted file mode 100644
index c693af9c..00000000
--- a/doc/src/safety/max-string-size.md
+++ /dev/null
@@ -1,36 +0,0 @@
-Maximum Length of Strings
-========================
-
-{{#include ../links.md}}
-
-Limit How Long Strings Can Grow
-------------------------------
-
-Rhai by default does not limit how long a [string] can be.
-
-This can be changed via the `Engine::set_max_string_size` method, with zero being unlimited (the default).
-
-A script attempting to create a string literal longer than the maximum length will terminate with a parse error.
-
-Any script operation that produces a string longer than the maximum also terminates the script with an error result.
-
-This check can be disabled via the [`unchecked`] feature for higher performance (but higher risks as well).
-
-```rust
-let mut engine = Engine::new();
-
-engine.set_max_string_size(500); // allow strings only up to 500 bytes long (in UTF-8 format)
-
-engine.set_max_string_size(0); // allow unlimited string length
-```
-
-
-Setting Maximum Length
----------------------
-
-Be conservative when setting a maximum limit and always consider the fact that a registered function may grow
-a string's length without Rhai noticing until the very end.
-
-For instance, the built-in '`+`' operator for strings concatenates two strings together to form one longer string;
-if both strings are _slightly_ below the maximum length limit, the resultant string may be almost _twice_ the maximum length.
-
diff --git a/doc/src/safety/progress.md b/doc/src/safety/progress.md
deleted file mode 100644
index 749ac95b..00000000
--- a/doc/src/safety/progress.md
+++ /dev/null
@@ -1,52 +0,0 @@
-Track Progress and Force-Termination
-===================================
-
-{{#include ../links.md}}
-
-It is impossible to know when, or even whether, a script run will end
-(a.k.a. the [Halting Problem](http://en.wikipedia.org/wiki/Halting_problem)).
-
-When dealing with third-party untrusted scripts that may be malicious, to track evaluation progress and
-to force-terminate a script prematurely (for any reason), provide a closure to the [`Engine`] via
-the `Engine::on_progress` method:
-
-```rust
-let mut engine = Engine::new();
-
-engine.on_progress(|count| { // parameter is number of operations already performed
- if count % 1000 == 0 {
- println!("{}", count); // print out a progress log every 1,000 operations
- }
- None // return 'None' to continue running the script
- // return 'Some(token)' to immediately terminate the script
-});
-```
-
-The closure passed to `Engine::on_progress` will be called once for every operation.
-Return `Some(token)` to terminate the script immediately, with the provided value
-(any [`Dynamic`]) acting as a termination token.
-
-
-Termination Token
------------------
-
-The [`Dynamic`] value returned by the closure for `Engine::on_progress` is a _termination token_.
-A script that is manually terminated returns with `Err(EvalAltResult::ErrorTerminated)`
-wrapping this value.
-
-The termination token is commonly used to provide information on the _reason_ or _source_
-behind the termination decision.
-
-If the termination token is not needed, simply return `Some(Dynamic::UNIT)` to terminate the script
-run with [`()`] as the token.
-
-
-Operations Count vs. Progress Percentage
----------------------------------------
-
-Notice that the _operations count_ value passed into the closure does not indicate the _percentage_ of work
-already done by the script (and thus it is not real _progress_ tracking), because it is impossible to determine
-how long a script may run.
-
-It is possible, however, to calculate this percentage based on an estimated total number of operations
-for a typical run.
diff --git a/doc/src/safety/sandbox.md b/doc/src/safety/sandbox.md
deleted file mode 100644
index 798a73ac..00000000
--- a/doc/src/safety/sandbox.md
+++ /dev/null
@@ -1,39 +0,0 @@
-Sand-Boxing – Block Access to External Data
-================================================
-
-{{#include ../links.md}}
-
-Rhai is _sand-boxed_ so a script can never read from outside its own environment.
-
-Furthermore, an [`Engine`] created non-`mut` cannot mutate any state, including itself
-(and therefore it is also _re-entrant_).
-
-It is highly recommended that [`Engine`]'s be created immutable as much as possible.
-
-```rust
-let mut engine = Engine::new();
-
-// Use the fluent API to configure an 'Engine'
-engine.register_get("field", get_field)
- .register_set("field", set_field)
- .register_fn("do_work", action);
-
-// Then turn it into an immutable instance
-let engine = engine;
-
-// 'engine' is immutable...
-```
-
-
-Using Rhai to Control External Environment
------------------------------------------
-
-How does a _sand-boxed_, immutable [`Engine`] control the external environment?
-This is necessary in order to use Rhai as a _dynamic control layer_ over a Rust core system.
-
-There are two general patterns, both involving wrapping the external system
-in a shared, interior-mutated object (e.g. `Rc>`):
-
-* [Control Layer]({{rootUrl}}/patterns/control.md) pattern.
-
-* [Singleton Command Object]({{rootUrl}}/patterns/singleton.md) pattern.
diff --git a/doc/src/start/bin.md b/doc/src/start/bin.md
deleted file mode 100644
index a053315d..00000000
--- a/doc/src/start/bin.md
+++ /dev/null
@@ -1,59 +0,0 @@
-Packaged Utilities
-==================
-
-{{#include ../links.md}}
-
-A number of Rhai-driven utility programs can be found in the `src/bin` directory:
-
-| Utility program | Description |
-| :-----------------------------------------------: | ----------------------------------------------------------- |
-| [`rhai-repl`]({{repoTree}}/examples/rhai-repl.rs) | a simple REPL, interactively evaluate statements from stdin |
-| [`rhai-run`]({{repoTree}}/examples/rhai-run.rs) | runs each filename passed to it as a Rhai script |
-
-
-`rhai-repl` – The Rhai REPL Tool
--------------------------------------
-
-`rhai-repl` is a particularly useful utility program – 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 before the REPL starts.
-
-### 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.
-
-```bash
-rhai-repl init1.rhai init2.rhai init3.rhai
-```
-
-
-`rhai-run` – The Rhai Runner
----------------------------------
-
-Use `rhai-run` to run Rhai scripts.
-
-Filenames passed to it as command line arguments are run in sequence.
-
-### Example
-
-The following command runs the scripts `script1.rhai`, `script2.rhai` and `script3.rhai`
-in order.
-
-```bash
-rhai-run script1.rhai script2.rhai script3.rhai
-```
-
-
-Running a Utility Program
--------------------------
-
-Utilities can be run with the following command:
-
-```bash
-cargo run --bin {program_name}
-```
diff --git a/doc/src/start/builds/index.md b/doc/src/start/builds/index.md
deleted file mode 100644
index a3cdfbf3..00000000
--- a/doc/src/start/builds/index.md
+++ /dev/null
@@ -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.
diff --git a/doc/src/start/builds/minimal.md b/doc/src/start/builds/minimal.md
deleted file mode 100644
index c916baea..00000000
--- a/doc/src/start/builds/minimal.md
+++ /dev/null
@@ -1,54 +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.
-
-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`]) and possibly closures ([`no_closure`]) when the features are not needed.
-Both of these have some code size savings but not much.
-
-
-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]({{rootUrl}}/engine/raw.md#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.
diff --git a/doc/src/start/builds/no-std.md b/doc/src/start/builds/no-std.md
deleted file mode 100644
index ce30ddb0..00000000
--- a/doc/src/start/builds/no-std.md
+++ /dev/null
@@ -1,79 +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.
-
-
-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 {}
-
-// 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() {}
-
-#[start]
-fn main(_argc: isize, _argv: *const *const u8) -> isize {
- // ... main program ...
-}
-```
-
-
-Samples
--------
-
-Check out the [`no-std` sample applications](../examples/rust.md#no-std-samples)
-for different operating environments.
diff --git a/doc/src/start/builds/performance.md b/doc/src/start/builds/performance.md
deleted file mode 100644
index 859e1782..00000000
--- a/doc/src/start/builds/performance.md
+++ /dev/null
@@ -1,61 +0,0 @@
-Performance Build
-=================
-
-{{#include ../../links.md}}
-
-Some features are for performance. For example, using [`only_i32`] or [`only_i64`] disables all other integer types (such as `u16`).
-
-
-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 [`no_float`] or [`f32_float`] and [`only_i32`] on 32-bit targets makes the critical [`Dynamic`]
-data type only 8 bytes long.
-Normally [`Dynamic`] can be up to 12-16 bytes in order to hold an `i64` or `f64`.
-
-A small [`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` or `Arc` 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` (both map to `ImmutableString`)
-for the best performance with Rhai.
-
-
-Disable Closures
-----------------
-
-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.
-
-Use [`no_closure`] to disable closure and capturing support to optimize the hot path
-because there is no need to take locks for shared data.
diff --git a/doc/src/start/builds/wasm.md b/doc/src/start/builds/wasm.md
deleted file mode 100644
index 27b85e77..00000000
--- a/doc/src/start/builds/wasm.md
+++ /dev/null
@@ -1,55 +0,0 @@
-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.
-
-
-Size
-----
-
-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.
-
-
-Speed
------
-
-In benchmark tests, a WASM build runs scripts roughly 1.7-2.2x 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 |
-| :-----------: | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
-| [`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 – 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. |
-
-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. |
-| [`internals`] | WASM usually doesn't need to access Rhai internal data structures, unless you are walking the [`AST`]. |
diff --git a/doc/src/start/examples/index.md b/doc/src/start/examples/index.md
deleted file mode 100644
index 6af1495b..00000000
--- a/doc/src/start/examples/index.md
+++ /dev/null
@@ -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.
diff --git a/doc/src/start/examples/rust.md b/doc/src/start/examples/rust.md
deleted file mode 100644
index b46d7249..00000000
--- a/doc/src/start/examples/rust.md
+++ /dev/null
@@ -1,45 +0,0 @@
-Rust Examples
-============
-
-{{#include ../../links.md}}
-
-A number of examples can be found in the `examples` directory:
-
-| Example | Description |
-| ------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- |
-| [`arrays_and_structs`]({{repoTree}}/examples/arrays_and_structs.rs) | shows how to register a custom Rust type and using [arrays] on it |
-| [`custom_types_and_methods`]({{repoTree}}/examples/custom_types_and_methods.rs) | shows how to register a custom Rust type and methods for it |
-| [`hello`]({{repoTree}}/examples/hello.rs) | simple example that evaluates an expression and prints the result |
-| [`reuse_scope`]({{repoTree}}/examples/reuse_scope.rs) | evaluates two pieces of code in separate runs, but using a common [`Scope`] |
-| [`serde`]({{repoTree}}/examples/serde.rs) | example to serialize and deserialize Rust types with [`serde`](https://crates.io/crates/serde). The [`serde`] feature is required to run |
-| [`simple_fn`]({{repoTree}}/examples/simple_fn.rs) | shows how to register a simple function |
-| [`strings`]({{repoTree}}/examples/strings.rs) | shows different ways to register functions taking string arguments |
-
-
-Running Examples
-----------------
-
-Examples can be run with the following command:
-
-```bash
-cargo run --example {example_name}
-```
-
-`no-std` Samples
-----------------
-
-To illustrate `no-std` builds, a number of sample applications are available under the `no_std` directory:
-
-| Sample | Description | Optimization | Allocator | Panics |
-| ------------------------------------------------ | ---------------------------------------------------------------------------------------------------- | :----------: | :-----------------------------------------------: | :----: |
-| [`no_std_test`]({{repoTree}}/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 |
-
-`cargo run` cannot be used to run a `no-std` sample. It must first be built:
-
-```bash
-cd no_std/no_std_test
-
-cargo +nightly build --release
-
-./target/release/no_std_test
-```
diff --git a/doc/src/start/examples/scripts.md b/doc/src/start/examples/scripts.md
deleted file mode 100644
index 80fe4908..00000000
--- a/doc/src/start/examples/scripts.md
+++ /dev/null
@@ -1,53 +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`]({{repoTree}}/scripts/array.rhai) | [arrays] |
-| [`assignment.rhai`]({{repoTree}}/scripts/assignment.rhai) | variable declarations |
-| [`comments.rhai`]({{repoTree}}/scripts/comments.rhai) | just comments |
-| [`for1.rhai`]({{repoTree}}/scripts/for1.rhai) | [`for`]({{rootUrl}}/language/for.md) loops |
-| [`for2.rhai`]({{repoTree}}/scripts/for2.rhai) | [`for`]({{rootUrl}}/language/for.md) loops on [arrays] |
-| [`function_decl1.rhai`]({{repoTree}}/scripts/function_decl1.rhai) | a [function] without parameters |
-| [`function_decl2.rhai`]({{repoTree}}/scripts/function_decl2.rhai) | a [function] with two parameters |
-| [`function_decl3.rhai`]({{repoTree}}/scripts/function_decl3.rhai) | a [function] with many parameters |
-| [`if1.rhai`]({{repoTree}}/scripts/if1.rhai) | [`if`]({{rootUrl}}/language/if.md) example |
-| [`loop.rhai`]({{repoTree}}/scripts/loop.rhai) | count-down [`loop`]({{rootUrl}}/language/loop.md) in Rhai, emulating a `do` .. `while` loop |
-| [`module.rhai`]({{repoTree}}/scripts/module.rhai) | import a script file as a module |
-| [`oop.rhai`]({{repoTree}}/scripts/oop.rhai) | simulate [object-oriented programming (OOP)][OOP] with [closures] |
-| [`op1.rhai`]({{repoTree}}/scripts/op1.rhai) | just simple addition |
-| [`op2.rhai`]({{repoTree}}/scripts/op2.rhai) | simple addition and multiplication |
-| [`op3.rhai`]({{repoTree}}/scripts/op3.rhai) | change evaluation order with parenthesis |
-| [`string.rhai`]({{repoTree}}/scripts/string.rhai) | [string] operations |
-| [`strings_map.rhai`]({{repoTree}}/scripts/strings_map.rhai) | [string] and [object map] operations |
-| [`while.rhai`]({{repoTree}}/scripts/while.rhai) | [`while`]({{rootUrl}}/language/while.md) loop |
-
-
-Benchmark Scripts
-----------------
-
-The following scripts are for benchmarking the speed of Rhai:
-
-| Scripts | Description |
-| --------------------------------------------------------- | -------------------------------------------------------------------------------------- |
-| [`speed_test.rhai`]({{repoTree}}/scripts/speed_test.rhai) | a simple application to measure the speed of Rhai's interpreter (1 million iterations) |
-| [`primes.rhai`]({{repoTree}}/scripts/primes.rhai) | use Sieve of Eratosthenes to find all primes smaller than a limit |
-| [`fibonacci.rhai`]({{repoTree}}/scripts/fibonacci.rhai) | calculate the n-th Fibonacci number using a really dumb algorithm |
-| [`mat_mul.rhai`]({{repoTree}}/scripts/mat_mul.rhai) | matrix multiplication test to measure the speed of multi-dimensional array access |
-
-
-Running Example Scripts
-----------------------
-
-The [`rhai-run`](../bin.md) utility can be used to run Rhai scripts:
-
-```bash
-cargo run --bin rhai-run scripts/any_script.rhai
-```
diff --git a/doc/src/start/features.md b/doc/src/start/features.md
deleted file mode 100644
index d1db695b..00000000
--- a/doc/src/start/features.md
+++ /dev/null
@@ -1,68 +0,0 @@
-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.
-Notice that this deviates from Rust norm where features are _additive_.
-
-Excluding unneeded functionalities can result in smaller, faster builds as well as
-more control over what a script can (or cannot) do.
-
-| Feature | Additive? | Description |
-| ------------------- | :-------: | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
-| `unchecked` | no | disables 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` | 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` |
-| `no_optimize` | no | disables [script optimization] |
-| `no_float` | no | disables floating-point numbers and math |
-| `f32_float` | no | sets the system floating-point type to `f32` instead of `f64`. `FLOAT` is set to `f32` |
-| `only_i32` | no | sets the system integer type to `i32` and disable all other integer types. `INT` is set to `i32` |
-| `only_i64` | no | sets the system integer type to `i64` and disable all other integer types. `INT` is set to `i64` |
-| `no_index` | no | disables [arrays] and indexing features |
-| `no_object` | no | disables support for [custom types] and [object maps] |
-| `no_function` | no | disables script-defined [functions] (implies `no_closure`) |
-| `no_module` | no | disables loading external [modules] |
-| `no_closure` | no | disables [capturing][automatic currying] external variables in [anonymous functions] to simulate _closures_, or [capturing the calling scope]({{rootUrl}}/language/fn-capture.md) in function calls |
-| `no_std` | no | builds for `no-std` (implies `no_closure`). Notice that additional dependencies will be pulled in to replace `std` features |
-| `serde` | yes | enables serialization/deserialization via `serde` (requires the [`serde`](https://crates.io/crates/serde) crate) |
-| `unicode-xid-ident` | no | allows [Unicode Standard Annex #31](http://www.unicode.org/reports/tr31/) as identifiers |
-| `metadata` | yes | enables exporting [functions metadata] to [JSON format]({{rootUrl}}/engine/metadata/export_to_json.md) (implies `serde` and additionally requires the [`serde_json`](https://crates.io/crates/serde_json) crate) |
-| `internals` | yes | exposes internal data structures (e.g. [`AST`] nodes). Beware that Rhai internals are volatile and may change from version to version |
-
-
-Example
--------
-
-The `Cargo.toml` configuration below turns on these six features:
-
-* `sync` (everything `Send + Sync`)
-* `unchecked` (disable all checking – 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 = "{{version}}", 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`, `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.
-
-
-Caveat – 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 _remove_ functionalities.
-
-There is a reason for this design, because the _lack_ of a language feature by itself is a feature.
-
-See [here]({{rootUrl}}/patterns/multiple.md) for more details.
diff --git a/doc/src/start/index.md b/doc/src/start/index.md
deleted file mode 100644
index f89dfbd0..00000000
--- a/doc/src/start/index.md
+++ /dev/null
@@ -1,6 +0,0 @@
-Getting Started
-===============
-
-{{#include ../links.md}}
-
-This section shows how to install the Rhai crate into a Rust application.
diff --git a/doc/src/start/install.md b/doc/src/start/install.md
deleted file mode 100644
index 18b75223..00000000
--- a/doc/src/start/install.md
+++ /dev/null
@@ -1,30 +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.
-
-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
-```
-
-Or to automatically 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](https://github.com/rhaiscript/rhai):
-
-```toml
-[dependencies]
-rhai = { git = "https://github.com/rhaiscript/rhai" }
-```
diff --git a/doc/src/start/playground.md b/doc/src/start/playground.md
deleted file mode 100644
index 08809805..00000000
--- a/doc/src/start/playground.md
+++ /dev/null
@@ -1,10 +0,0 @@
-Online Playground
-=================
-
-{{#include ../links.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.
diff --git a/doc/src/tools/index.md b/doc/src/tools/index.md
deleted file mode 100644
index 9b9eff01..00000000
--- a/doc/src/tools/index.md
+++ /dev/null
@@ -1,6 +0,0 @@
-External Tools
-==============
-
-{{#include ../links.md}}
-
-External tools available to work with Rhai.
diff --git a/doc/src/tools/playground.md b/doc/src/tools/playground.md
deleted file mode 100644
index 91507a3d..00000000
--- a/doc/src/tools/playground.md
+++ /dev/null
@@ -1,15 +0,0 @@
-Online Playground
-=================
-
-{{#include ../links.md}}
-
-
-The Online Playground runs off a [WASM] build of Rhai and allows evaluating
-Rhai scripts directly within a browser editor window.
-
-
-Author : [`@alvinhochun`](https://github.com/alvinhochun)
-
-Repo : [On GitHub](https://github.com/alvinhochun/rhai-playground)
-
-URL : [Link to Online Playground][playground]
diff --git a/doc/src/tools/rhai-doc.md b/doc/src/tools/rhai-doc.md
deleted file mode 100644
index fd32be6a..00000000
--- a/doc/src/tools/rhai-doc.md
+++ /dev/null
@@ -1,6 +0,0 @@
-Rhai Script Documentation Tool
-=============================
-
-{{#include ../links.md}}
-
-<< TODO >>
\ No newline at end of file
diff --git a/doc/theme/favicon.png b/doc/theme/favicon.png
deleted file mode 100644
index f5cf9cac..00000000
Binary files a/doc/theme/favicon.png and /dev/null differ
diff --git a/doc/theme/favicon.svg b/doc/theme/favicon.svg
deleted file mode 100644
index 4d5eaf02..00000000
--- a/doc/theme/favicon.svg
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-