Merge branch 'master' into plugins
This commit is contained in:
commit
8e33cbfe34
11
.ci/build.sh
11
.ci/build.sh
@ -1,11 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
set -ex
|
|
||||||
|
|
||||||
cargo build --verbose
|
|
||||||
cargo test --verbose
|
|
||||||
|
|
||||||
if [[ $TRAVIS_RUST_VERSION == "nightly" ]]; then
|
|
||||||
cargo build --verbose --features no_std
|
|
||||||
cargo test --verbose --features no_std
|
|
||||||
fi
|
|
76
.github/workflows/build.yml
vendored
Normal file
76
.github/workflows/build.yml
vendored
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
name: Build
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- master
|
||||||
|
pull_request: {}
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
# typical build with various feature combinations
|
||||||
|
build:
|
||||||
|
name: Build
|
||||||
|
runs-on: ${{ matrix.os }}
|
||||||
|
continue-on-error: ${{ matrix.experimental }}
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
os: [ubuntu-latest]
|
||||||
|
flags:
|
||||||
|
- ""
|
||||||
|
- "--features serde"
|
||||||
|
- "--features plugins"
|
||||||
|
- "--features unchecked"
|
||||||
|
- "--features sync"
|
||||||
|
- "--features no_optimize"
|
||||||
|
- "--features no_float"
|
||||||
|
- "--features only_i32"
|
||||||
|
- "--features only_i64"
|
||||||
|
- "--features no_index"
|
||||||
|
- "--features no_object"
|
||||||
|
- "--features no_function"
|
||||||
|
- "--features no_module"
|
||||||
|
toolchain: [stable]
|
||||||
|
experimental: [false]
|
||||||
|
include:
|
||||||
|
# smoketests for future and experimental toolchains
|
||||||
|
- {toolchain: stable, os: windows-latest, experimental: false, flags: ""}
|
||||||
|
- {toolchain: stable, os: macos-latest, experimental: false, flags: ""}
|
||||||
|
- {toolchain: beta, os: ubuntu-latest, experimental: false, flags: ""}
|
||||||
|
- {toolchain: nightly, os: ubuntu-latest, experimental: true, flags: ""}
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
- name: Setup Toolchain
|
||||||
|
uses: actions-rs/toolchain@v1
|
||||||
|
with:
|
||||||
|
toolchain: ${{matrix.toolchain}}
|
||||||
|
override: true
|
||||||
|
- name: Test
|
||||||
|
uses: actions-rs/cargo@v1
|
||||||
|
with:
|
||||||
|
command: test
|
||||||
|
args: --all {{matrix.flags}}
|
||||||
|
# no-std builds are a bit more extensive to test
|
||||||
|
no_std_build:
|
||||||
|
name: NoStdBuild
|
||||||
|
runs-on: ${{matrix.os}}
|
||||||
|
continue-on-error: ${{matrix.experimental}}
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
include:
|
||||||
|
- {os: ubuntu-latest, flags: "--profile unix -Z unstable-options", experimental: false}
|
||||||
|
- {os: windows-latest, flags: "--profile windows -Z unstable-options", experimental: true}
|
||||||
|
- {os: macos-latest, flags: "--profile macos -Z unstable-options", experimental: false}
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
- name: Setup Toolchain
|
||||||
|
uses: actions-rs/toolchain@v1
|
||||||
|
with:
|
||||||
|
toolchain: nightly
|
||||||
|
override: true
|
||||||
|
- name: Build Project
|
||||||
|
uses: actions-rs/cargo@v1
|
||||||
|
with:
|
||||||
|
command: build
|
||||||
|
args: --manifest-path=no_std/no_std_test/Cargo.toml ${{matrix.flags}}
|
10
.travis.yml
10
.travis.yml
@ -1,10 +0,0 @@
|
|||||||
language: rust
|
|
||||||
rust:
|
|
||||||
- stable
|
|
||||||
- beta
|
|
||||||
- nightly
|
|
||||||
matrix:
|
|
||||||
allow_failures:
|
|
||||||
- rust: nightly
|
|
||||||
|
|
||||||
script: bash ./.ci/build.sh
|
|
@ -2,7 +2,7 @@ Rhai - Embedded Scripting for Rust
|
|||||||
=================================
|
=================================
|
||||||
|
|
||||||
![GitHub last commit](https://img.shields.io/github/last-commit/jonathandturner/rhai)
|
![GitHub last commit](https://img.shields.io/github/last-commit/jonathandturner/rhai)
|
||||||
[![Travis (.org)](https://img.shields.io/travis/jonathandturner/rhai)](http://travis-ci.org/jonathandturner/rhai)
|
[![Build Status](https://github.com/jonathandturner/rhai/workflows/Build/badge.svg)](https://github.com/jonathandturner/rhai/actions)
|
||||||
[![license](https://img.shields.io/github/license/jonathandturner/rhai)](https://github.com/license/jonathandturner/rhai)
|
[![license](https://img.shields.io/github/license/jonathandturner/rhai)](https://github.com/license/jonathandturner/rhai)
|
||||||
[![crates.io](https://img.shields.io/crates/v/rhai.svg)](https://crates.io/crates/rhai/)
|
[![crates.io](https://img.shields.io/crates/v/rhai.svg)](https://crates.io/crates/rhai/)
|
||||||
[![crates.io](https://img.shields.io/crates/d/rhai)](https://crates.io/crates/rhai/)
|
[![crates.io](https://img.shields.io/crates/d/rhai)](https://crates.io/crates/rhai/)
|
||||||
@ -73,7 +73,7 @@ Licensed under either:
|
|||||||
* [Apache License, Version 2.0](https://github.com/jonathandturner/rhai/blob/master/LICENSE-APACHE.txt), or
|
* [Apache License, Version 2.0](https://github.com/jonathandturner/rhai/blob/master/LICENSE-APACHE.txt), or
|
||||||
* [MIT license](https://github.com/jonathandturner/rhai/blob/master/LICENSE-MIT.txt)
|
* [MIT license](https://github.com/jonathandturner/rhai/blob/master/LICENSE-MIT.txt)
|
||||||
|
|
||||||
at your option.
|
at your choice.
|
||||||
|
|
||||||
Unless explicitly stated otherwise, any contribution intentionally submitted
|
Unless explicitly stated otherwise, any contribution intentionally submitted
|
||||||
for inclusion in this crate, as defined in the Apache-2.0 license, shall
|
for inclusion in this crate, as defined in the Apache-2.0 license, shall
|
||||||
|
@ -5,8 +5,9 @@ The Rhai Scripting Language
|
|||||||
1. [Features](about/features.md)
|
1. [Features](about/features.md)
|
||||||
2. [Supported Targets and Builds](about/targets.md)
|
2. [Supported Targets and Builds](about/targets.md)
|
||||||
3. [What Rhai Isn't](about/non-design.md)
|
3. [What Rhai Isn't](about/non-design.md)
|
||||||
4. [Related Resources](about/related.md)
|
4. [Licensing](about/license.md)
|
||||||
3. [Getting Started](start/index.md)
|
5. [Related Resources](about/related.md)
|
||||||
|
2. [Getting Started](start/index.md)
|
||||||
1. [Online Playground](start/playground.md)
|
1. [Online Playground](start/playground.md)
|
||||||
2. [Install the Rhai Crate](start/install.md)
|
2. [Install the Rhai Crate](start/install.md)
|
||||||
3. [Optional Features](start/features.md)
|
3. [Optional Features](start/features.md)
|
||||||
@ -18,14 +19,14 @@ The Rhai Scripting Language
|
|||||||
5. [Examples](start/examples/index.md)
|
5. [Examples](start/examples/index.md)
|
||||||
1. [Rust](start/examples/rust.md)
|
1. [Rust](start/examples/rust.md)
|
||||||
2. [Scripts](start/examples/scripts.md)
|
2. [Scripts](start/examples/scripts.md)
|
||||||
4. [Using the `Engine`](engine/index.md)
|
3. [Using the `Engine`](engine/index.md)
|
||||||
1. [Hello World in Rhai - Evaluate a Script](engine/hello-world.md)
|
1. [Hello World in Rhai - Evaluate a Script](engine/hello-world.md)
|
||||||
2. [Compile a Script to AST for Repeated Evaluations](engine/compile.md)
|
2. [Compile to AST for Repeated Evaluations](engine/compile.md)
|
||||||
3. [Call a Rhai Function from Rust](engine/call-fn.md)
|
3. [Call a Rhai Function from Rust](engine/call-fn.md)
|
||||||
4. [Create a Rust Anonymous Function from a Rhai Function](engine/func.md)
|
4. [Create a Rust Anonymous Function from a Rhai Function](engine/func.md)
|
||||||
5. [Evaluate Expressions Only](engine/expressions.md)
|
5. [Evaluate Expressions Only](engine/expressions.md)
|
||||||
6. [Raw Engine](engine/raw.md)
|
6. [Raw Engine](engine/raw.md)
|
||||||
5. [Extend Rhai with Rust](rust/index.md)
|
4. [Extend Rhai with Rust](rust/index.md)
|
||||||
1. [Traits](rust/traits.md)
|
1. [Traits](rust/traits.md)
|
||||||
2. [Register a Rust Function](rust/functions.md)
|
2. [Register a Rust Function](rust/functions.md)
|
||||||
1. [String Parameters in Rust Functions](rust/strings.md)
|
1. [String Parameters in Rust Functions](rust/strings.md)
|
||||||
@ -43,7 +44,7 @@ The Rhai Scripting Language
|
|||||||
4. [Printing Custom Types](rust/print-custom.md)
|
4. [Printing Custom Types](rust/print-custom.md)
|
||||||
9. [Scope - Initializing and Maintaining State](rust/scope.md)
|
9. [Scope - Initializing and Maintaining State](rust/scope.md)
|
||||||
10. [Engine Configuration Options](rust/options.md)
|
10. [Engine Configuration Options](rust/options.md)
|
||||||
6. [Rhai Language Reference](language/index.md)
|
5. [Rhai Language Reference](language/index.md)
|
||||||
1. [Comments](language/comments.md)
|
1. [Comments](language/comments.md)
|
||||||
2. [Values and Types](language/values-and-types.md)
|
2. [Values and Types](language/values-and-types.md)
|
||||||
1. [Dynamic Values](language/dynamic.md)
|
1. [Dynamic Values](language/dynamic.md)
|
||||||
@ -64,28 +65,29 @@ The Rhai Scripting Language
|
|||||||
5. [Variables](language/variables.md)
|
5. [Variables](language/variables.md)
|
||||||
6. [Constants](language/constants.md)
|
6. [Constants](language/constants.md)
|
||||||
7. [Logic Operators](language/logic.md)
|
7. [Logic Operators](language/logic.md)
|
||||||
8. [If Statement](language/if.md)
|
8. [Other Operators](language/other-op.md)
|
||||||
9. [While Loop](language/while.md)
|
9. [If Statement](language/if.md)
|
||||||
10. [Loop Statement](language/loop.md)
|
10. [While Loop](language/while.md)
|
||||||
11. [For Loop](language/for.md)
|
11. [Loop Statement](language/loop.md)
|
||||||
12. [Return Values](language/return.md)
|
12. [For Loop](language/for.md)
|
||||||
13. [Throw Exception on Error](language/throw.md)
|
13. [Return Values](language/return.md)
|
||||||
14. [Functions](language/functions.md)
|
14. [Throw Exception on Error](language/throw.md)
|
||||||
|
15. [Functions](language/functions.md)
|
||||||
1. [Call Method as Function](language/method.md)
|
1. [Call Method as Function](language/method.md)
|
||||||
2. [Overloading](language/overload.md)
|
2. [Overloading](language/overload.md)
|
||||||
3. [Namespaces](language/fn-namespaces.md)
|
3. [Namespaces](language/fn-namespaces.md)
|
||||||
4. [Function Pointers](language/fn-ptr.md)
|
4. [Function Pointers](language/fn-ptr.md)
|
||||||
5. [Anonymous Functions](language/fn-anon.md)
|
5. [Anonymous Functions](language/fn-anon.md)
|
||||||
6. [Currying](language/fn-curry.md)
|
6. [Currying](language/fn-curry.md)
|
||||||
15. [Print and Debug](language/print-debug.md)
|
16. [Print and Debug](language/print-debug.md)
|
||||||
16. [Modules](language/modules/index.md)
|
17. [Modules](language/modules/index.md)
|
||||||
1. [Export Variables, Functions and Sub-Modules](language/modules/export.md)
|
1. [Export Variables, Functions and Sub-Modules](language/modules/export.md)
|
||||||
2. [Import Modules](language/modules/import.md)
|
2. [Import Modules](language/modules/import.md)
|
||||||
3. [Create from Rust](rust/modules/index.md)
|
3. [Create from Rust](rust/modules/index.md)
|
||||||
4. [Create from AST](language/modules/ast.md)
|
4. [Create from AST](language/modules/ast.md)
|
||||||
5. [Module Resolvers](rust/modules/resolvers.md)
|
5. [Module Resolvers](rust/modules/resolvers.md)
|
||||||
1. [Custom Implementation](rust/modules/imp-resolver.md)
|
1. [Custom Implementation](rust/modules/imp-resolver.md)
|
||||||
7. [Safety and Protection](safety/index.md)
|
6. [Safety and Protection](safety/index.md)
|
||||||
1. [Checked Arithmetic](safety/checked.md)
|
1. [Checked Arithmetic](safety/checked.md)
|
||||||
2. [Sand-Boxing](safety/sandbox.md)
|
2. [Sand-Boxing](safety/sandbox.md)
|
||||||
3. [Maximum Length of Strings](safety/max-string-size.md)
|
3. [Maximum Length of Strings](safety/max-string-size.md)
|
||||||
@ -96,7 +98,7 @@ The Rhai Scripting Language
|
|||||||
7. [Maximum Number of Modules](safety/max-modules.md)
|
7. [Maximum Number of Modules](safety/max-modules.md)
|
||||||
8. [Maximum Call Stack Depth](safety/max-call-stack.md)
|
8. [Maximum Call Stack Depth](safety/max-call-stack.md)
|
||||||
9. [Maximum Statement Depth](safety/max-stmt-depth.md)
|
9. [Maximum Statement Depth](safety/max-stmt-depth.md)
|
||||||
8. [Advanced Topics](advanced.md)
|
7. [Advanced Topics](advanced.md)
|
||||||
1. [Object-Oriented Programming (OOP)](language/oop.md)
|
1. [Object-Oriented Programming (OOP)](language/oop.md)
|
||||||
2. [Serialization/Deserialization of `Dynamic` with `serde`](rust/serde.md)
|
2. [Serialization/Deserialization of `Dynamic` with `serde`](rust/serde.md)
|
||||||
3. [Script Optimization](engine/optimize/index.md)
|
3. [Script Optimization](engine/optimize/index.md)
|
||||||
@ -112,7 +114,7 @@ The Rhai Scripting Language
|
|||||||
2. [Custom Operators](engine/custom-op.md)
|
2. [Custom Operators](engine/custom-op.md)
|
||||||
3. [Extending with Custom Syntax](engine/custom-syntax.md)
|
3. [Extending with Custom Syntax](engine/custom-syntax.md)
|
||||||
6. [Eval Statement](language/eval.md)
|
6. [Eval Statement](language/eval.md)
|
||||||
9. [Appendix](appendix/index.md)
|
8. [Appendix](appendix/index.md)
|
||||||
1. [Keywords](appendix/keywords.md)
|
1. [Keywords](appendix/keywords.md)
|
||||||
2. [Operators and Symbols](appendix/operators.md)
|
2. [Operators and Symbols](appendix/operators.md)
|
||||||
3. [Literals](appendix/literals.md)
|
3. [Literals](appendix/literals.md)
|
||||||
|
@ -7,6 +7,9 @@ Rhai is an embedded scripting language and evaluation engine for Rust that gives
|
|||||||
to add scripting to any application.
|
to add scripting to any application.
|
||||||
|
|
||||||
|
|
||||||
This Book is for version {{version}} of Rhai.
|
Versions
|
||||||
|
--------
|
||||||
|
|
||||||
|
This Book is for version **{{version}}** of Rhai.
|
||||||
|
|
||||||
For the latest development version, see [here]({{rootUrl}}/vnext/).
|
For the latest development version, see [here]({{rootUrl}}/vnext/).
|
||||||
|
16
doc/src/about/license.md
Normal file
16
doc/src/about/license.md
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
Licensing
|
||||||
|
=========
|
||||||
|
|
||||||
|
{{#include ../links.md}}
|
||||||
|
|
||||||
|
Rhai is licensed under either:
|
||||||
|
|
||||||
|
* [Apache License, Version 2.0]({{repoHome}}/LICENSE-APACHE.txt), or
|
||||||
|
|
||||||
|
* [MIT license]({{repoHome}}/LICENSE-MIT.txt)
|
||||||
|
|
||||||
|
at your choice.
|
||||||
|
|
||||||
|
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.
|
@ -18,21 +18,38 @@ It doesn't attempt to be a new language. For example:
|
|||||||
|
|
||||||
* No first-class functions - Code your functions in Rust instead, and register them with Rhai.
|
* No first-class functions - Code your functions in Rust instead, and register them with Rhai.
|
||||||
|
|
||||||
There is, however, support for simple [function pointers] allowing runtime dispatch by function name.
|
There is, however, support for simple [function pointers] to allow runtime dispatch by function name.
|
||||||
|
|
||||||
* No garbage collection - this should be expected, so...
|
* No garbage collection - this should be expected, so...
|
||||||
|
|
||||||
* No closures - do your closure magic in Rust instead; [turn a Rhai scripted function into a Rust closure]({{rootUrl}}/engine/call-fn.md).
|
* No closures - do your closure magic in Rust instead; [turn a Rhai scripted function into a Rust closure]({{rootUrl}}/engine/call-fn.md).
|
||||||
|
|
||||||
|
But you can [curry][currying] a [function pointer] with arguments to simulate it somewhat.
|
||||||
|
|
||||||
* No byte-codes/JIT - Rhai has an AST-walking interpreter which will not win any speed races. The purpose of Rhai is not
|
* No byte-codes/JIT - Rhai has an AST-walking interpreter which will not win any speed races. The purpose of Rhai is not
|
||||||
to be extremely _fast_, but to make it as easy as possible to integrate with native Rust applications.
|
to be extremely _fast_, but to make it as easy as possible to integrate with native Rust applications.
|
||||||
|
|
||||||
|
|
||||||
|
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
|
Due to this intended usage, Rhai deliberately keeps the language simple and small by omitting advanced language features
|
||||||
such as classes, inheritance, first-class functions, closures, concurrency, byte-codes, JIT etc.
|
such as classes, inheritance, first-class functions, closures, concurrency, byte-codes, JIT etc.
|
||||||
|
|
||||||
Avoid the temptation to write full-fledge application logic entirely in Rhai - that use case is best fulfilled by
|
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.
|
more complete languages such as JavaScript or Lua.
|
||||||
|
|
||||||
Therefore, in actual practice, it is usually best to expose a Rust API into Rhai for scripts to call.
|
|
||||||
All your core functionalities should be in Rust.
|
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.
|
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.
|
||||||
|
@ -5,7 +5,7 @@ Advanced Topics
|
|||||||
|
|
||||||
This section covers advanced features such as:
|
This section covers advanced features such as:
|
||||||
|
|
||||||
* Simulated [Object Oriented Programming][OOP].
|
* Simulated [Object Oriented Programming (OOP)][OOP].
|
||||||
|
|
||||||
* [`serde`] integration.
|
* [`serde`] integration.
|
||||||
|
|
||||||
@ -13,4 +13,6 @@ This section covers advanced features such as:
|
|||||||
|
|
||||||
* [Domain-Specific Languages][DSL].
|
* [Domain-Specific Languages][DSL].
|
||||||
|
|
||||||
|
* Low-level [function registration API]({{rootUrl}}/rust/register-raw.md)
|
||||||
|
|
||||||
* The dreaded (or beloved for those with twisted tastes) [`eval`] statement.
|
* The dreaded (or beloved for those with twisted tastes) [`eval`] statement.
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
{
|
{
|
||||||
"version": "0.18.0",
|
"version": "0.18.0",
|
||||||
|
"repoHome": "https://github.com/jonathandturner/rhai/blob/master",
|
||||||
|
"repoTree": "https://github.com/jonathandturner/rhai/tree/master",
|
||||||
"rootUrl": "",
|
"rootUrl": "",
|
||||||
"rootUrlX": "/rhai",
|
"rootUrlX": "/rhai",
|
||||||
"rootUrlXX": "/rhai/vnext"
|
"rootUrlXX": "/rhai/vnext"
|
||||||
|
@ -22,19 +22,31 @@ fn main() -> Result<(), Box<EvalAltResult>>
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
`rhai::EvalAltResult` is a Rust `enum` containing all errors encountered during the parsing or evaluation process.
|
Evaluate a script file directly:
|
||||||
|
|
||||||
|
```rust
|
||||||
|
// 'eval_file' takes a 'PathBuf'
|
||||||
|
let result = engine.eval_file::<i64>("hello_world.rhai".into())?;
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
Evaluate a Script
|
Error Type
|
||||||
----------------
|
----------
|
||||||
|
|
||||||
The type parameter is used to specify the type of the return value, which _must_ match the actual type or an error is returned.
|
`rhai::EvalAltResult` is the standard Rhai error type, which is a Rust `enum` containing all errors encountered
|
||||||
Rhai is very strict here.
|
during the parsing or evaluation process.
|
||||||
|
|
||||||
Use [`Dynamic`] for uncertain return types.
|
|
||||||
|
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.
|
There are two ways to specify the return type - _turbofish_ notation, or type inference.
|
||||||
|
|
||||||
|
Use [`Dynamic`] for uncertain return types.
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
let result = engine.eval::<i64>("40 + 2")?; // return type is i64, specified using 'turbofish' notation
|
let result = engine.eval::<i64>("40 + 2")?; // return type is i64, specified using 'turbofish' notation
|
||||||
|
|
||||||
@ -46,9 +58,3 @@ let result: Dynamic = engine.eval("boo()")?; // use 'Dynamic' if you're not s
|
|||||||
|
|
||||||
let result = engine.eval::<String>("40 + 2")?; // returns an error because the actual return type is i64, not String
|
let result = engine.eval::<String>("40 + 2")?; // returns an error because the actual return type is i64, not String
|
||||||
```
|
```
|
||||||
|
|
||||||
Evaluate a script file directly:
|
|
||||||
|
|
||||||
```rust
|
|
||||||
let result = engine.eval_file::<i64>("hello_world.rhai".into())?; // 'eval_file' takes a 'PathBuf'
|
|
||||||
```
|
|
||||||
|
@ -10,7 +10,10 @@ In many controlled embedded environments, however, these may not be needed and u
|
|||||||
application code storage space.
|
application code storage space.
|
||||||
|
|
||||||
Use `Engine::new_raw` to create a _raw_ `Engine`, in which only a minimal set of
|
Use `Engine::new_raw` to create a _raw_ `Engine`, in which only a minimal set of
|
||||||
basic arithmetic and logical operators are supported.
|
basic arithmetic and logical operators are supported (see below).
|
||||||
|
|
||||||
|
To add more functionalities to a _raw_ `Engine`, load [packages] into it.
|
||||||
|
|
||||||
|
|
||||||
Built-in Operators
|
Built-in Operators
|
||||||
------------------
|
------------------
|
||||||
@ -20,7 +23,7 @@ Built-in Operators
|
|||||||
| `+`, | `+=` | `INT`, `FLOAT` (if not [`no_float`]), `ImmutableString` |
|
| `+`, | `+=` | `INT`, `FLOAT` (if not [`no_float`]), `ImmutableString` |
|
||||||
| `-`, `*`, `/`, `%`, `~`, | `-=`, `*=`, `/=`, `%=`, `~=` | `INT`, `FLOAT` (if not [`no_float`]) |
|
| `-`, `*`, `/`, `%`, `~`, | `-=`, `*=`, `/=`, `%=`, `~=` | `INT`, `FLOAT` (if not [`no_float`]) |
|
||||||
| `<<`, `>>`, `^`, | `<<=`, `>>=`, `^=` | `INT` |
|
| `<<`, `>>`, `^`, | `<<=`, `>>=`, `^=` | `INT` |
|
||||||
| `&`, `|`, | `&=`, `|=` | `INT`, `bool` |
|
| `&`, <code>\|</code>, | `&=`, <code>\|=</code> | `INT`, `bool` |
|
||||||
| `&&`, `||` | | `bool` |
|
| `&&`, <code>\|\|</code> | | `bool` |
|
||||||
| `==`, `!=` | | `INT`, `FLOAT` (if not [`no_float`]), `bool`, `char`, `()`, `ImmutableString` |
|
| `==`, `!=` | | `INT`, `FLOAT` (if not [`no_float`]), `bool`, `char`, `()`, `ImmutableString` |
|
||||||
| `>`, `>=`, `<`, `<=` | | `INT`, `FLOAT` (if not [`no_float`]), `char`, `()`, `ImmutableString` |
|
| `>`, `>=`, `<`, `<=` | | `INT`, `FLOAT` (if not [`no_float`]), `char`, `()`, `ImmutableString` |
|
||||||
|
@ -3,7 +3,8 @@
|
|||||||
|
|
||||||
{{#include ../links.md}}
|
{{#include ../links.md}}
|
||||||
|
|
||||||
Iterating through a range or an [array] is provided by the `for` ... `in` loop.
|
Iterating through a range or an [array], or any type with a registered _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;
|
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.
|
`break` can be used to break out of the loop unconditionally.
|
||||||
|
@ -19,6 +19,9 @@ if foo(x) {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Braces Are Mandatory
|
||||||
|
--------------------
|
||||||
|
|
||||||
Unlike C, the condition expression does _not_ need to be enclosed in parentheses '`(`' .. '`)`', but
|
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 '`{`' .. '`}`',
|
all branches of the `if` statement must be enclosed within braces '`{`' .. '`}`',
|
||||||
even when there is only one statement inside the branch.
|
even when there is only one statement inside the branch.
|
||||||
|
@ -65,42 +65,3 @@ a() | b(); // both a() and b() are evaluated
|
|||||||
|
|
||||||
a() & b(); // both a() and b() are evaluated
|
a() & b(); // both a() and b() are evaluated
|
||||||
```
|
```
|
||||||
|
|
||||||
Compound Assignment Operators
|
|
||||||
----------------------------
|
|
||||||
|
|
||||||
```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 `+=` operator can also be used to build [strings]:
|
|
||||||
|
|
||||||
```rust
|
|
||||||
let my_str = "abc";
|
|
||||||
my_str += "ABC";
|
|
||||||
my_str += 12345;
|
|
||||||
|
|
||||||
my_str == "abcABC12345"
|
|
||||||
```
|
|
||||||
|
@ -4,8 +4,8 @@ Call Method as Function
|
|||||||
{{#include ../links.md}}
|
{{#include ../links.md}}
|
||||||
|
|
||||||
|
|
||||||
First `&mut` Reference Parameter
|
First `&mut` Parameter
|
||||||
-------------------------------
|
----------------------
|
||||||
|
|
||||||
Property [getters/setters] and [methods][custom types] in a Rust custom type registered with the [`Engine`] can be called
|
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
|
just like a regular function. In fact, like Rust, property getters/setters and object methods
|
||||||
@ -37,19 +37,20 @@ array[0].update(); // <- call in method-call style will update 'a'
|
|||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
Encouraged Usage
|
`&mut` is Efficient
|
||||||
----------------
|
------------------
|
||||||
|
|
||||||
Using a `&mut` first parameter is highly encouraged when using types that are expensive to clone,
|
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 the intention is not to mutate that argument, because it avoids cloning that argument value.
|
||||||
|
|
||||||
For primary types that are cheap to clone, including `ImmutableString`, this is not necessary.
|
For primary types that are cheap to clone (e.g. those that implement `Copy`),
|
||||||
|
including `ImmutableString`, this is not necessary.
|
||||||
|
|
||||||
|
|
||||||
Avoid `&mut ImmutableString`
|
Avoid `&mut ImmutableString`
|
||||||
---------------------------
|
---------------------------
|
||||||
|
|
||||||
`ImmutableString`, Rhai internal [string] type, is an exception.
|
`ImmutableString`, Rhai's internal [string] type, is an exception.
|
||||||
|
|
||||||
`ImmutableString` is cheap to clone, but expensive to take a mutable reference (because the underlying
|
`ImmutableString` is cheap to clone, but expensive to take a mutable reference (because the underlying
|
||||||
string must be cloned to make a private copy).
|
string must be cloned to make a private copy).
|
||||||
|
66
doc/src/language/other-op.md
Normal file
66
doc/src/language/other-op.md
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
Other Operators
|
||||||
|
===============
|
||||||
|
|
||||||
|
{{#include ../links.md}}
|
||||||
|
|
||||||
|
|
||||||
|
Compound Assignment Operators
|
||||||
|
----------------------------
|
||||||
|
|
||||||
|
```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 `+=` operator can also be used to build [strings]:
|
||||||
|
|
||||||
|
```rust
|
||||||
|
let my_str = "abc";
|
||||||
|
my_str += "ABC";
|
||||||
|
my_str += 12345;
|
||||||
|
|
||||||
|
my_str == "abcABC12345"
|
||||||
|
```
|
||||||
|
|
||||||
|
It may also be used to concatenate [arrays]:
|
||||||
|
|
||||||
|
```rust
|
||||||
|
let my_array = [1, 2, 3];
|
||||||
|
my_array += [4, 5];
|
||||||
|
|
||||||
|
my_array == [1, 2, 3, 4, 5];
|
||||||
|
```
|
||||||
|
|
||||||
|
or 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;
|
||||||
|
```
|
@ -66,8 +66,8 @@ let mut engine = Engine::new();
|
|||||||
engine.register_type::<TestStruct>();
|
engine.register_type::<TestStruct>();
|
||||||
```
|
```
|
||||||
|
|
||||||
Methods on Custom Type
|
Methods on The Custom Type
|
||||||
---------------------
|
-------------------------
|
||||||
|
|
||||||
To use native custom types, methods and functions in Rhai scripts, simply register them
|
To use native custom types, methods and functions in Rhai scripts, simply register them
|
||||||
using one of the `Engine::register_XXX` API.
|
using one of the `Engine::register_XXX` API.
|
||||||
|
@ -11,8 +11,8 @@ see [fallible functions]({{rootUrl}}/rust/fallible.md)).
|
|||||||
|
|
||||||
```rust
|
```rust
|
||||||
use rhai::{Dynamic, Engine, EvalAltResult, ImmutableString};
|
use rhai::{Dynamic, Engine, EvalAltResult, ImmutableString};
|
||||||
use rhai::RegisterFn; // use 'RegisterFn' trait for 'register_fn'
|
use rhai::RegisterFn; // use 'RegisterFn' trait for 'register_fn'
|
||||||
use rhai::RegisterResultFn; // use 'RegisterResultFn' trait for 'register_result_fn'
|
use rhai::RegisterResultFn; // use 'RegisterResultFn' trait for 'register_result_fn'
|
||||||
|
|
||||||
// Normal function that returns a standard type
|
// Normal function that returns a standard type
|
||||||
// Remember to use 'ImmutableString' and not 'String'
|
// Remember to use 'ImmutableString' and not 'String'
|
||||||
@ -26,7 +26,7 @@ fn add_len_str(x: i64, s: &str) -> i64 {
|
|||||||
|
|
||||||
// Function that returns a 'Dynamic' value - must return a 'Result'
|
// Function that returns a 'Dynamic' value - must return a 'Result'
|
||||||
fn get_any_value() -> Result<Dynamic, Box<EvalAltResult>> {
|
fn get_any_value() -> Result<Dynamic, Box<EvalAltResult>> {
|
||||||
Ok((42_i64).into()) // standard types can use 'into()'
|
Ok((42_i64).into()) // standard types can use 'into()'
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut engine = Engine::new();
|
let mut engine = Engine::new();
|
||||||
|
@ -30,7 +30,7 @@ impl ModuleResolver for MyModuleResolver {
|
|||||||
&self,
|
&self,
|
||||||
engine: &Engine, // reference to the current 'Engine'
|
engine: &Engine, // reference to the current 'Engine'
|
||||||
path: &str, // the module path
|
path: &str, // the module path
|
||||||
pos: Position, // location of the 'import' statement
|
pos: Position, // position of the 'import' statement
|
||||||
) -> Result<Module, Box<EvalAltResult>> {
|
) -> Result<Module, Box<EvalAltResult>> {
|
||||||
// Check module path.
|
// Check module path.
|
||||||
if is_valid_module_path(path) {
|
if is_valid_module_path(path) {
|
||||||
|
@ -12,7 +12,9 @@ fn to_int(num) {
|
|||||||
print("Ha! Gotcha! " + num);
|
print("Ha! Gotcha! " + num);
|
||||||
}
|
}
|
||||||
|
|
||||||
print(to_int(123)); // what happens?
|
let x = (123).to_int();
|
||||||
|
|
||||||
|
print(x); // what happens?
|
||||||
```
|
```
|
||||||
|
|
||||||
A registered native Rust function, in turn, overrides any built-in function of the
|
A registered native Rust function, in turn, overrides any built-in function of the
|
||||||
|
@ -37,8 +37,8 @@ Use `ImmutableString`
|
|||||||
Internally, Rhai uses _immutable_ [strings] instead of the Rust `String` type. This is mainly to avoid excessive
|
Internally, Rhai uses _immutable_ [strings] instead of the Rust `String` type. This is mainly to avoid excessive
|
||||||
cloning when passing function arguments.
|
cloning when passing function arguments.
|
||||||
|
|
||||||
The encapsulated immutable string type is `ImmutableString`. It is cheap to clone (just an `Rc` or `Arc` reference
|
Rhai's internal string type is `ImmutableString` (basically `Rc<String>` or `Arc<String>` depending on the [`sync`] feature).
|
||||||
count increment 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` (which maps to `ImmutableString`)
|
Therefore, functions taking `String` parameters should use `ImmutableString` or `&str` (which maps to `ImmutableString`)
|
||||||
for the best performance with Rhai.
|
for the best performance with Rhai.
|
||||||
|
@ -5,17 +5,17 @@ Rust Examples
|
|||||||
|
|
||||||
A number of examples can be found in the `examples` directory:
|
A number of examples can be found in the `examples` directory:
|
||||||
|
|
||||||
| Example | Description |
|
| Example | Description |
|
||||||
| ---------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- |
|
| ------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||||
| [`arrays_and_structs`](https://github.com/jonathandturner/rhai/tree/master/examples/arrays_and_structs.rs) | Shows how to register a custom Rust type and using [arrays] on it. |
|
| [`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`](https://github.com/jonathandturner/rhai/tree/master/examples/custom_types_and_methods.rs) | Shows how to register a custom Rust type and methods for it. |
|
| [`custom_types_and_methods`]({{repoTree}}/examples/custom_types_and_methods.rs) | Shows how to register a custom Rust type and methods for it. |
|
||||||
| [`hello`](https://github.com/jonathandturner/rhai/tree/master/examples/hello.rs) | Simple example that evaluates an expression and prints the result. |
|
| [`hello`]({{repoTree}}/examples/hello.rs) | Simple example that evaluates an expression and prints the result. |
|
||||||
| [`reuse_scope`](https://github.com/jonathandturner/rhai/tree/master/examples/reuse_scope.rs) | Evaluates two pieces of code in separate runs, but using a common [`Scope`]. |
|
| [`reuse_scope`]({{repoTree}}/examples/reuse_scope.rs) | Evaluates two pieces of code in separate runs, but using a common [`Scope`]. |
|
||||||
| [`rhai_runner`](https://github.com/jonathandturner/rhai/tree/master/examples/rhai_runner.rs) | Runs each filename passed to it as a Rhai script. |
|
| [`rhai_runner`]({{repoTree}}/examples/rhai_runner.rs) | Runs each filename passed to it as a Rhai script. |
|
||||||
| [`serde`](https://github.com/jonathandturner/rhai/tree/master/examples/serde.rs) | Example to serialize and deserialize Rust types with [`serde`](https://crates.io/crates/serde).<br/>The [`serde`] feature is required to run. |
|
| [`serde`]({{repoTree}}/examples/serde.rs) | Example to serialize and deserialize Rust types with [`serde`](https://crates.io/crates/serde).<br/>The [`serde`] feature is required to run. |
|
||||||
| [`simple_fn`](https://github.com/jonathandturner/rhai/tree/master/examples/simple_fn.rs) | Shows how to register a simple function. |
|
| [`simple_fn`]({{repoTree}}/examples/simple_fn.rs) | Shows how to register a simple function. |
|
||||||
| [`strings`](https://github.com/jonathandturner/rhai/tree/master/examples/strings.rs) | Shows different ways to register functions taking string arguments. |
|
| [`strings`]({{repoTree}}/examples/strings.rs) | Shows different ways to register functions taking string arguments. |
|
||||||
| [`repl`](https://github.com/jonathandturner/rhai/tree/master/examples/repl.rs) | A simple REPL, interactively evaluate statements from stdin. |
|
| [`repl`]({{repoTree}}/examples/repl.rs) | A simple REPL, interactively evaluate statements from stdin. |
|
||||||
|
|
||||||
The `repl` example is a particularly good one as it allows one to interactively try out Rhai's
|
The `repl` example is a particularly good one as it allows one to interactively try out Rhai's
|
||||||
language features in a standard REPL (**R**ead-**E**val-**P**rint **L**oop).
|
language features in a standard REPL (**R**ead-**E**val-**P**rint **L**oop).
|
||||||
@ -35,9 +35,9 @@ cargo run --example {example_name}
|
|||||||
|
|
||||||
To illustrate `no-std` builds, a number of sample applications are available under the `no_std` directory:
|
To illustrate `no-std` builds, a number of sample applications are available under the `no_std` directory:
|
||||||
|
|
||||||
| Sample | Description | Optimization | Allocator | Panics |
|
| Sample | Description | Optimization | Allocator | Panics |
|
||||||
| --------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------- | :----------: | :-----------------------------------------------: | :----: |
|
| ------------------------------------------------ | ----------------------------------------------------------------------------------------------------- | :----------: | :-----------------------------------------------: | :----: |
|
||||||
| [`no_std_test`](https://github.com/jonathandturner/rhai/tree/master/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 |
|
| [`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:
|
`cargo run` cannot be used to run a `no-std` sample. It must first be built:
|
||||||
|
|
||||||
|
@ -8,25 +8,25 @@ Language Feature Scripts
|
|||||||
|
|
||||||
There are also a number of examples scripts that showcase Rhai's features, all in the `scripts` directory:
|
There are also a number of examples scripts that showcase Rhai's features, all in the `scripts` directory:
|
||||||
|
|
||||||
| Script | Description |
|
| Script | Description |
|
||||||
| -------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------- |
|
| ----------------------------------------------------------------- | ------------------------------------------------------------------------------------------- |
|
||||||
| [`array.rhai`](https://github.com/jonathandturner/rhai/tree/master/scripts/array.rhai) | [Arrays] |
|
| [`array.rhai`]({{repoTree}}/scripts/array.rhai) | [Arrays] |
|
||||||
| [`assignment.rhai`](https://github.com/jonathandturner/rhai/tree/master/scripts/assignment.rhai) | Variable declarations |
|
| [`assignment.rhai`]({{repoTree}}/scripts/assignment.rhai) | Variable declarations |
|
||||||
| [`comments.rhai`](https://github.com/jonathandturner/rhai/tree/master/scripts/comments.rhai) | Just comments |
|
| [`comments.rhai`]({{repoTree}}/scripts/comments.rhai) | Just comments |
|
||||||
| [`for1.rhai`](https://github.com/jonathandturner/rhai/tree/master/scripts/for1.rhai) | [`for`]({{rootUrl}}/language/for.md) loops |
|
| [`for1.rhai`]({{repoTree}}/scripts/for1.rhai) | [`for`]({{rootUrl}}/language/for.md) loops |
|
||||||
| [`for2.rhai`](https://github.com/jonathandturner/rhai/tree/master/scripts/for2.rhai) | [`for`]({{rootUrl}}/language/for.md) loops on [arrays] |
|
| [`for2.rhai`]({{repoTree}}/scripts/for2.rhai) | [`for`]({{rootUrl}}/language/for.md) loops on [arrays] |
|
||||||
| [`function_decl1.rhai`](https://github.com/jonathandturner/rhai/tree/master/scripts/function_decl1.rhai) | A [function] without parameters |
|
| [`function_decl1.rhai`]({{repoTree}}/scripts/function_decl1.rhai) | A [function] without parameters |
|
||||||
| [`function_decl2.rhai`](https://github.com/jonathandturner/rhai/tree/master/scripts/function_decl2.rhai) | A [function] with two parameters |
|
| [`function_decl2.rhai`]({{repoTree}}/scripts/function_decl2.rhai) | A [function] with two parameters |
|
||||||
| [`function_decl3.rhai`](https://github.com/jonathandturner/rhai/tree/master/scripts/function_decl3.rhai) | A [function] with many parameters |
|
| [`function_decl3.rhai`]({{repoTree}}/scripts/function_decl3.rhai) | A [function] with many parameters |
|
||||||
| [`if1.rhai`](https://github.com/jonathandturner/rhai/tree/master/scripts/if1.rhai) | [`if`]({{rootUrl}}/language/if.md) example |
|
| [`if1.rhai`]({{repoTree}}/scripts/if1.rhai) | [`if`]({{rootUrl}}/language/if.md) example |
|
||||||
| [`loop.rhai`](https://github.com/jonathandturner/rhai/tree/master/scripts/loop.rhai) | Count-down [`loop`]({{rootUrl}}/language/loop.md) in Rhai, emulating a `do` .. `while` loop |
|
| [`loop.rhai`]({{repoTree}}/scripts/loop.rhai) | Count-down [`loop`]({{rootUrl}}/language/loop.md) in Rhai, emulating a `do` .. `while` loop |
|
||||||
| [`oop.rhai`](https://github.com/jonathandturner/rhai/tree/master/scripts/oop.rhai) | Simulate [object-oriented programming (OOP)][OOP] |
|
| [`oop.rhai`]({{repoTree}}/scripts/oop.rhai) | Simulate [object-oriented programming (OOP)][OOP] |
|
||||||
| [`op1.rhai`](https://github.com/jonathandturner/rhai/tree/master/scripts/op1.rhai) | Just simple addition |
|
| [`op1.rhai`]({{repoTree}}/scripts/op1.rhai) | Just simple addition |
|
||||||
| [`op2.rhai`](https://github.com/jonathandturner/rhai/tree/master/scripts/op2.rhai) | Simple addition and multiplication |
|
| [`op2.rhai`]({{repoTree}}/scripts/op2.rhai) | Simple addition and multiplication |
|
||||||
| [`op3.rhai`](https://github.com/jonathandturner/rhai/tree/master/scripts/op3.rhai) | Change evaluation order with parenthesis |
|
| [`op3.rhai`]({{repoTree}}/scripts/op3.rhai) | Change evaluation order with parenthesis |
|
||||||
| [`string.rhai`](https://github.com/jonathandturner/rhai/tree/master/scripts/string.rhai) | [String] operations |
|
| [`string.rhai`]({{repoTree}}/scripts/string.rhai) | [String] operations |
|
||||||
| [`strings_map.rhai`](https://github.com/jonathandturner/rhai/tree/master/scripts/strings_map.rhai) | [String] and [object map] operations |
|
| [`strings_map.rhai`]({{repoTree}}/scripts/strings_map.rhai) | [String] and [object map] operations |
|
||||||
| [`while.rhai`](https://github.com/jonathandturner/rhai/tree/master/scripts/while.rhai) | [`while`]({{rootUrl}}/language/while.md) loop |
|
| [`while.rhai`]({{repoTree}}/scripts/while.rhai) | [`while`]({{rootUrl}}/language/while.md) loop |
|
||||||
|
|
||||||
|
|
||||||
Benchmark Scripts
|
Benchmark Scripts
|
||||||
@ -34,12 +34,12 @@ Benchmark Scripts
|
|||||||
|
|
||||||
The following scripts are for benchmarking the speed of Rhai:
|
The following scripts are for benchmarking the speed of Rhai:
|
||||||
|
|
||||||
| Scripts | Description |
|
| Scripts | Description |
|
||||||
| ------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------- |
|
| --------------------------------------------------------- | --------------------------------------------------------------------------------------- |
|
||||||
| [`speed_test.rhai`](https://github.com/jonathandturner/rhai/tree/master/scripts/speed_test.rhai) | A simple application to measure the speed of Rhai's interpreter (1 million iterations). |
|
| [`speed_test.rhai`]({{repoTree}}/scripts/speed_test.rhai) | A simple application to measure the speed of Rhai's interpreter (1 million iterations). |
|
||||||
| [`primes.rhai`](https://github.com/jonathandturner/rhai/tree/master/scripts/primes.rhai) | Use Sieve of Eratosthenes to find all primes smaller than a limit. |
|
| [`primes.rhai`]({{repoTree}}/scripts/primes.rhai) | Use Sieve of Eratosthenes to find all primes smaller than a limit. |
|
||||||
| [`fibonacci.rhai`](https://github.com/jonathandturner/rhai/tree/master/scripts/fibonacci.rhai) | Calculate the n-th Fibonacci number using a really dumb algorithm. |
|
| [`fibonacci.rhai`]({{repoTree}}/scripts/fibonacci.rhai) | Calculate the n-th Fibonacci number using a really dumb algorithm. |
|
||||||
| [`mat_mul.rhai`](https://github.com/jonathandturner/rhai/tree/master/scripts/mat_mul.rhai) | Matrix multiplication test to measure the speed of multi-dimensional array access. |
|
| [`mat_mul.rhai`]({{repoTree}}/scripts/mat_mul.rhai) | Matrix multiplication test to measure the speed of multi-dimensional array access. |
|
||||||
|
|
||||||
|
|
||||||
Running Example Scripts
|
Running Example Scripts
|
||||||
|
@ -25,7 +25,7 @@ more control over what a script can (or cannot) do.
|
|||||||
| `no_module` | Disable loading external [modules]. |
|
| `no_module` | Disable loading external [modules]. |
|
||||||
| `no_std` | Build for `no-std`. Notice that additional dependencies will be pulled in to replace `std` features. |
|
| `no_std` | Build for `no-std`. Notice that additional dependencies will be pulled in to replace `std` features. |
|
||||||
| `serde` | Enable serialization/deserialization via [`serde`]. Notice that the [`serde`](https://crates.io/crates/serde) crate will be pulled in together with its dependencies. |
|
| `serde` | Enable serialization/deserialization via [`serde`]. Notice that the [`serde`](https://crates.io/crates/serde) crate will be pulled in together with its dependencies. |
|
||||||
| `internals` | Expose internal data structures (e.g. [`AST`] nodes) and enable defining [custom syntax]. Beware that Rhai internals are volatile and may change from version to version. |
|
| `internals` | Expose internal data structures (e.g. [`AST`] nodes). Beware that Rhai internals are volatile and may change from version to version. |
|
||||||
|
|
||||||
|
|
||||||
Example
|
Example
|
||||||
@ -46,7 +46,7 @@ rhai = { version = "{{version}}", features = [ "sync", "unchecked", "only_i32",
|
|||||||
```
|
```
|
||||||
|
|
||||||
The resulting scripting engine supports only the `i32` integer numeral type (and no others like `u32`, `i16` or `i64`),
|
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), does not support defining [functions]
|
no floating-point, is `Send + Sync` (so it can be safely used across threads), and does not support defining [functions]
|
||||||
nor loading external [modules].
|
nor loading external [modules].
|
||||||
|
|
||||||
This configuration is perfect for an expression parser in a 32-bit embedded system without floating-point hardware.
|
This configuration is perfect for an expression parser in a 32-bit embedded system without floating-point hardware.
|
||||||
|
@ -1,10 +1,12 @@
|
|||||||
|
cargo-features = ["named-profiles"]
|
||||||
|
|
||||||
[package]
|
[package]
|
||||||
name = "no_std_test"
|
name = "no_std_test"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
authors = ["Stephen Chung"]
|
authors = ["Stephen Chung"]
|
||||||
description = "no-std test application"
|
description = "no-std test application"
|
||||||
homepage = "https://github.com/jonathandturner/rhai/tree/master/no_std/no_std_test"
|
homepage = "https://github.com/jonathandturner/rhai/tree/no_std/no_std_test"
|
||||||
repository = "https://github.com/jonathandturner/rhai"
|
repository = "https://github.com/jonathandturner/rhai"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
@ -18,7 +20,17 @@ panic = "abort"
|
|||||||
opt-level = "z" # optimize for size
|
opt-level = "z" # optimize for size
|
||||||
debug = false
|
debug = false
|
||||||
rpath = false
|
rpath = false
|
||||||
lto = "fat"
|
|
||||||
debug-assertions = false
|
debug-assertions = false
|
||||||
codegen-units = 1
|
codegen-units = 1
|
||||||
panic = "abort"
|
panic = "abort"
|
||||||
|
|
||||||
|
[profile.unix]
|
||||||
|
inherits = "release"
|
||||||
|
lto = true
|
||||||
|
|
||||||
|
[profile.windows]
|
||||||
|
inherits = "release"
|
||||||
|
|
||||||
|
[profile.macos]
|
||||||
|
inherits = "release"
|
||||||
|
lto = "fat"
|
||||||
|
@ -12,7 +12,9 @@ To Compile
|
|||||||
The nightly compiler is required:
|
The nightly compiler is required:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cargo +nightly build --release
|
cargo +nightly build --release --profile unix -Z unstable-features
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Available profiles are: `unix`, `windows` and `macos`.
|
||||||
|
|
||||||
The release build is optimized for size. It can be changed to optimize on speed instead.
|
The release build is optimized for size. It can be changed to optimize on speed instead.
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
//! a simple expression and uses the result as the return value.
|
//! a simple expression and uses the result as the return value.
|
||||||
|
|
||||||
#![no_std]
|
#![no_std]
|
||||||
#![feature(alloc_error_handler, start, core_intrinsics, lang_items)]
|
#![feature(alloc_error_handler, start, core_intrinsics, lang_items, link_cfg)]
|
||||||
|
|
||||||
extern crate alloc;
|
extern crate alloc;
|
||||||
extern crate wee_alloc;
|
extern crate wee_alloc;
|
||||||
@ -10,6 +10,12 @@ extern crate wee_alloc;
|
|||||||
#[global_allocator]
|
#[global_allocator]
|
||||||
static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT;
|
static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT;
|
||||||
|
|
||||||
|
// NB: Rust needs a CRT runtime on Windows MSVC.
|
||||||
|
#[cfg(all(windows, target_env = "msvc"))]
|
||||||
|
#[link(name = "msvcrt")]
|
||||||
|
#[link(name = "libcmt")]
|
||||||
|
extern {}
|
||||||
|
|
||||||
use rhai::{Engine, INT};
|
use rhai::{Engine, INT};
|
||||||
|
|
||||||
#[start]
|
#[start]
|
||||||
|
@ -639,9 +639,7 @@ impl Engine {
|
|||||||
)
|
)
|
||||||
.or_else(|err| match *err {
|
.or_else(|err| match *err {
|
||||||
// If there is no index setter, no need to set it back because the indexer is read-only
|
// If there is no index setter, no need to set it back because the indexer is read-only
|
||||||
EvalAltResult::ErrorFunctionNotFound(s, _)
|
EvalAltResult::ErrorFunctionNotFound(_, _) => {
|
||||||
if s == FN_IDX_SET =>
|
|
||||||
{
|
|
||||||
Ok(Default::default())
|
Ok(Default::default())
|
||||||
}
|
}
|
||||||
_ => Err(err),
|
_ => Err(err),
|
||||||
|
@ -865,10 +865,22 @@ impl Engine {
|
|||||||
EvalAltResult::ErrorFunctionNotFound(_, _) if def_val.is_some() => {
|
EvalAltResult::ErrorFunctionNotFound(_, _) if def_val.is_some() => {
|
||||||
Ok(def_val.unwrap().into())
|
Ok(def_val.unwrap().into())
|
||||||
}
|
}
|
||||||
EvalAltResult::ErrorFunctionNotFound(_, _) => {
|
EvalAltResult::ErrorFunctionNotFound(_, pos) => {
|
||||||
Err(Box::new(EvalAltResult::ErrorFunctionNotFound(
|
Err(Box::new(EvalAltResult::ErrorFunctionNotFound(
|
||||||
format!("{}{}", modules, name),
|
format!(
|
||||||
Position::none(),
|
"{}{} ({})",
|
||||||
|
modules,
|
||||||
|
name,
|
||||||
|
args.iter()
|
||||||
|
.map(|a| if a.is::<ImmutableString>() {
|
||||||
|
"&str | ImmutableString | String"
|
||||||
|
} else {
|
||||||
|
self.map_type_name((*a).type_name())
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>()
|
||||||
|
.join(", ")
|
||||||
|
),
|
||||||
|
pos,
|
||||||
)))
|
)))
|
||||||
}
|
}
|
||||||
_ => Err(err),
|
_ => Err(err),
|
||||||
|
@ -10,9 +10,12 @@ use crate::token::{is_valid_identifier, Position};
|
|||||||
use crate::utils::{ImmutableString, StaticVec};
|
use crate::utils::{ImmutableString, StaticVec};
|
||||||
use crate::Scope;
|
use crate::Scope;
|
||||||
|
|
||||||
use crate::stdlib::{
|
use crate::stdlib::{boxed::Box, convert::TryFrom, fmt, mem, string::String, vec::Vec};
|
||||||
boxed::Box, convert::TryFrom, fmt, mem, rc::Rc, string::String, sync::Arc, vec::Vec,
|
|
||||||
};
|
#[cfg(not(feature = "sync"))]
|
||||||
|
use crate::stdlib::rc::Rc;
|
||||||
|
#[cfg(feature = "sync")]
|
||||||
|
use crate::stdlib::sync::Arc;
|
||||||
|
|
||||||
/// Trait that maps to `Send + Sync` only under the `sync` feature.
|
/// Trait that maps to `Send + Sync` only under the `sync` feature.
|
||||||
#[cfg(feature = "sync")]
|
#[cfg(feature = "sync")]
|
||||||
|
@ -20,9 +20,12 @@ use crate::stdlib::{
|
|||||||
boxed::Box,
|
boxed::Box,
|
||||||
fmt::Display,
|
fmt::Display,
|
||||||
format,
|
format,
|
||||||
ops::{Add, BitAnd, BitOr, BitXor, Div, Mul, Neg, Rem, Shl, Shr, Sub},
|
ops::{Add, BitAnd, BitOr, BitXor, Div, Mul, Neg, Rem, Sub},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#[cfg(feature = "unchecked")]
|
||||||
|
use crate::stdlib::ops::{Shl, Shr};
|
||||||
|
|
||||||
// Checked add
|
// Checked add
|
||||||
pub(crate) fn add<T: Display + CheckedAdd>(x: T, y: T) -> FuncReturn<T> {
|
pub(crate) fn add<T: Display + CheckedAdd>(x: T, y: T) -> FuncReturn<T> {
|
||||||
x.checked_add(&y).ok_or_else(|| {
|
x.checked_add(&y).ok_or_else(|| {
|
||||||
@ -171,10 +174,12 @@ pub(crate) fn shr<T: Display + CheckedShr>(x: T, y: INT) -> FuncReturn<T> {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
// Unchecked left-shift - may panic if shifting by a negative number of bits
|
// Unchecked left-shift - may panic if shifting by a negative number of bits
|
||||||
|
#[cfg(feature = "unchecked")]
|
||||||
pub(crate) fn shl_u<T: Shl<T>>(x: T, y: T) -> FuncReturn<<T as Shl<T>>::Output> {
|
pub(crate) fn shl_u<T: Shl<T>>(x: T, y: T) -> FuncReturn<<T as Shl<T>>::Output> {
|
||||||
Ok(x.shl(y))
|
Ok(x.shl(y))
|
||||||
}
|
}
|
||||||
// Unchecked right-shift - may panic if shifting by a negative number of bits
|
// Unchecked right-shift - may panic if shifting by a negative number of bits
|
||||||
|
#[cfg(feature = "unchecked")]
|
||||||
pub(crate) fn shr_u<T: Shr<T>>(x: T, y: T) -> FuncReturn<<T as Shr<T>>::Output> {
|
pub(crate) fn shr_u<T: Shr<T>>(x: T, y: T) -> FuncReturn<<T as Shr<T>>::Output> {
|
||||||
Ok(x.shr(y))
|
Ok(x.shr(y))
|
||||||
}
|
}
|
||||||
@ -229,6 +234,7 @@ pub(crate) fn pow_i_i(x: INT, y: INT) -> FuncReturn<INT> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Unchecked integer power - may panic on overflow or if the power index is too high (> u32::MAX)
|
// Unchecked integer power - may panic on overflow or if the power index is too high (> u32::MAX)
|
||||||
|
#[cfg(feature = "unchecked")]
|
||||||
pub(crate) fn pow_i_i_u(x: INT, y: INT) -> FuncReturn<INT> {
|
pub(crate) fn pow_i_i_u(x: INT, y: INT) -> FuncReturn<INT> {
|
||||||
Ok(x.pow(y as u32))
|
Ok(x.pow(y as u32))
|
||||||
}
|
}
|
||||||
|
@ -74,6 +74,7 @@ impl PackagesCollection {
|
|||||||
.flatten()
|
.flatten()
|
||||||
}
|
}
|
||||||
/// Does the specified TypeId iterator exist in the `PackagesCollection`?
|
/// Does the specified TypeId iterator exist in the `PackagesCollection`?
|
||||||
|
#[allow(dead_code)]
|
||||||
pub fn contains_iter(&self, id: TypeId) -> bool {
|
pub fn contains_iter(&self, id: TypeId) -> bool {
|
||||||
self.0.iter().any(|p| p.contains_iter(id))
|
self.0.iter().any(|p| p.contains_iter(id))
|
||||||
}
|
}
|
||||||
|
@ -1,12 +1,17 @@
|
|||||||
#![cfg(not(feature = "no_std"))]
|
#![cfg(not(feature = "no_std"))]
|
||||||
use super::logic::{eq, gt, gte, lt, lte, ne};
|
use super::logic::{eq, gt, gte, lt, lte, ne};
|
||||||
|
|
||||||
|
#[cfg(feature = "no_float")]
|
||||||
use super::math_basic::MAX_INT;
|
use super::math_basic::MAX_INT;
|
||||||
|
|
||||||
use crate::def_package;
|
use crate::def_package;
|
||||||
use crate::module::FuncReturn;
|
|
||||||
use crate::parser::INT;
|
|
||||||
use crate::result::EvalAltResult;
|
use crate::result::EvalAltResult;
|
||||||
use crate::token::Position;
|
|
||||||
|
#[cfg(not(feature = "no_float"))]
|
||||||
|
use crate::parser::FLOAT;
|
||||||
|
|
||||||
|
#[cfg(feature = "no_float")]
|
||||||
|
use crate::{module::FuncReturn, parser::INT, token::Position};
|
||||||
|
|
||||||
#[cfg(not(target_arch = "wasm32"))]
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
use crate::stdlib::time::Instant;
|
use crate::stdlib::time::Instant;
|
||||||
@ -14,9 +19,6 @@ use crate::stdlib::time::Instant;
|
|||||||
#[cfg(target_arch = "wasm32")]
|
#[cfg(target_arch = "wasm32")]
|
||||||
use instant::Instant;
|
use instant::Instant;
|
||||||
|
|
||||||
#[cfg(not(feature = "no_float"))]
|
|
||||||
use crate::parser::FLOAT;
|
|
||||||
|
|
||||||
def_package!(crate:BasicTimePackage:"Basic timing utilities.", lib, {
|
def_package!(crate:BasicTimePackage:"Basic timing utilities.", lib, {
|
||||||
// Register date/time functions
|
// Register date/time functions
|
||||||
lib.set_fn_0("timestamp", || Ok(Instant::now()));
|
lib.set_fn_0("timestamp", || Ok(Instant::now()));
|
||||||
|
@ -14,11 +14,14 @@ use crate::utils::StaticVec;
|
|||||||
use crate::stdlib::{
|
use crate::stdlib::{
|
||||||
boxed::Box,
|
boxed::Box,
|
||||||
fmt, format,
|
fmt, format,
|
||||||
rc::Rc,
|
|
||||||
string::{String, ToString},
|
string::{String, ToString},
|
||||||
sync::Arc,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#[cfg(not(feature = "sync"))]
|
||||||
|
use crate::stdlib::rc::Rc;
|
||||||
|
#[cfg(feature = "sync")]
|
||||||
|
use crate::stdlib::sync::Arc;
|
||||||
|
|
||||||
/// A general expression evaluation trait object.
|
/// A general expression evaluation trait object.
|
||||||
#[cfg(not(feature = "sync"))]
|
#[cfg(not(feature = "sync"))]
|
||||||
pub type FnCustomSyntaxEval = dyn Fn(
|
pub type FnCustomSyntaxEval = dyn Fn(
|
||||||
|
Loading…
Reference in New Issue
Block a user