diff --git a/CHANGELOG.md b/CHANGELOG.md index 5b4c3e67..2965b74e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -59,6 +59,8 @@ Enhancements Version 1.0.6 ============= +* `MultiInputsStream`, `ParseState`, `TokenIterator`, `IdentifierBuilder` and `AccessMode` are exported under the `internals` feature. + Version 1.0.5 ============= diff --git a/README.md b/README.md index f63abb9d..f3cef610 100644 --- a/README.md +++ b/README.md @@ -71,6 +71,47 @@ For those who actually want their own language * Extend the language with [custom syntax](https://rhai.rs/book/engine/custom-syntax.html). +Example +------- + +The [`scripts`](https://github.com/rhaiscript/rhai/tree/master/scripts) subdirectory contains sample Rhai scripts. + +Below is the standard _Fibonacci_ example for scripting languages: + +```js +// This Rhai script calculates the n-th Fibonacci number using a really dumb algorithm +// to test the speed of the scripting engine. + +const TARGET = 28; +const REPEAT = 5; + +fn fib(n) { + if n < 2 { + n + } else { + fib(n-1) + fib(n-2) + } +} + +print(`Running Fibonacci(${TARGET}) x ${REPEAT} times...`); +print("Ready... Go!"); + +let result; +let now = timestamp(); + +for n in range(0, REPEAT) { + result = fib(TARGET); +} + +print(`Finished. Run time = ${now.elapsed} seconds.`); + +print(`Fibonacci number #${TARGET} = ${result}`); + +if result != 317_811 { + print("The answer is WRONG! Should be 317,811!"); +} +``` + Project Site ------------ diff --git a/scripts/fibonacci.rhai b/scripts/fibonacci.rhai index fd3ba5c0..dac77d22 100644 --- a/scripts/fibonacci.rhai +++ b/scripts/fibonacci.rhai @@ -12,7 +12,7 @@ fn fib(n) { } } -print(`Running Fibonacci(28) x ${REPEAT} times...`); +print(`Running Fibonacci(${TARGET}) x ${REPEAT} times...`); print("Ready... Go!"); let result; diff --git a/src/dynamic.rs b/src/dynamic.rs index a71ecca6..075ddab9 100644 --- a/src/dynamic.rs +++ b/src/dynamic.rs @@ -148,7 +148,8 @@ impl dyn Variant { } } -/// Modes of access. +/// _(internals)_ Modes of access. +/// Exported under the `internals` feature only. #[derive(Debug, Eq, PartialEq, Hash, Copy, Clone)] pub enum AccessMode { /// Mutable. diff --git a/src/lib.rs b/src/lib.rs index 413af829..bb8e1ee9 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -214,7 +214,7 @@ pub use optimize::OptimizationLevel; #[cfg(feature = "internals")] #[deprecated = "this type is volatile and may change"] -pub use dynamic::{DynamicReadLock, DynamicWriteLock, Variant}; +pub use dynamic::{AccessMode, DynamicReadLock, DynamicWriteLock, Variant}; // Expose internal data structures. #[cfg(feature = "internals")] @@ -224,7 +224,14 @@ pub use token::{get_next_token, parse_string_literal}; // Expose internal data structures. #[cfg(feature = "internals")] #[deprecated = "this type is volatile and may change"] -pub use token::{InputStream, Token, TokenizeState, TokenizerControl, TokenizerControlBlock}; +pub use token::{ + InputStream, MultiInputsStream, Token, TokenIterator, TokenizeState, TokenizerControl, + TokenizerControlBlock, +}; + +#[cfg(feature = "internals")] +#[deprecated = "this type is volatile and may change"] +pub use parse::{IdentifierBuilder, ParseState}; #[cfg(feature = "internals")] #[deprecated = "this type is volatile and may change"] diff --git a/src/parse.rs b/src/parse.rs index 9507aabb..daa57566 100644 --- a/src/parse.rs +++ b/src/parse.rs @@ -42,7 +42,8 @@ const SCOPE_SEARCH_BARRIER_MARKER: &str = "$BARRIER$"; /// The message: `TokenStream` never ends const NEVER_ENDS: &str = "`TokenStream` never ends"; -/// A factory of identifiers from text strings. +/// _(internals)_ A factory of identifiers from text strings. +/// Exported under the `internals` feature only. /// /// When [`SmartString`](https://crates.io/crates/smartstring) is used as [`Identifier`], /// this just returns a copy because most identifiers in Rhai are short and ASCII-based. @@ -72,38 +73,39 @@ impl IdentifierBuilder { } } -/// A type that encapsulates the current state of the parser. +/// _(internals)_ A type that encapsulates the current state of the parser. +/// Exported under the `internals` feature only. #[derive(Debug)] pub struct ParseState<'e> { /// Reference to the scripting [`Engine`]. - engine: &'e Engine, + pub engine: &'e Engine, /// Input stream buffer containing the next character to read. - tokenizer_control: TokenizerControl, + pub tokenizer_control: TokenizerControl, /// Interned strings. - interned_strings: IdentifierBuilder, + pub interned_strings: IdentifierBuilder, /// Encapsulates a local stack with variable names to simulate an actual runtime scope. - stack: StaticVec<(Identifier, AccessMode)>, + pub stack: StaticVec<(Identifier, AccessMode)>, /// Size of the local variables stack upon entry of the current block scope. - entry_stack_len: usize, + pub entry_stack_len: usize, /// Tracks a list of external variables (variables that are not explicitly declared in the scope). #[cfg(not(feature = "no_closure"))] - external_vars: BTreeMap, + pub external_vars: BTreeMap, /// An indicator that disables variable capturing into externals one single time /// up until the nearest consumed Identifier token. /// If set to false the next call to [`access_var`][ParseState::access_var] will not capture the variable. /// All consequent calls to [`access_var`][ParseState::access_var] will not be affected #[cfg(not(feature = "no_closure"))] - allow_capture: bool, + pub allow_capture: bool, /// Encapsulates a local stack with imported [module][crate::Module] names. #[cfg(not(feature = "no_module"))] - modules: StaticVec, + pub modules: StaticVec, /// Maximum levels of expression nesting. #[cfg(not(feature = "unchecked"))] - max_expr_depth: Option, + pub max_expr_depth: Option, /// Maximum levels of expression nesting in functions. #[cfg(not(feature = "unchecked"))] #[cfg(not(feature = "no_function"))] - max_function_expr_depth: Option, + pub max_function_expr_depth: Option, } impl<'e> ParseState<'e> { diff --git a/src/token.rs b/src/token.rs index 98980ca5..00725d77 100644 --- a/src/token.rs +++ b/src/token.rs @@ -2054,15 +2054,17 @@ pub fn is_id_continue(x: char) -> bool { x.is_ascii_alphanumeric() || x == '_' } -/// A type that implements the [`InputStream`] trait. +/// _(internals)_ A type that implements the [`InputStream`] trait. +/// Exported under the `internals` feature only. +/// /// Multiple character streams are jointed together to form one single stream. pub struct MultiInputsStream<'a> { /// Buffered character, if any. - buf: Option, + pub buf: Option, /// The current stream index. - index: usize, + pub index: usize, /// The input character streams. - streams: StaticVec>>, + pub streams: StaticVec>>, } impl InputStream for MultiInputsStream<'_> { @@ -2112,20 +2114,21 @@ impl InputStream for MultiInputsStream<'_> { } } -/// An iterator on a [`Token`] stream. +/// _(internals)_ An iterator on a [`Token`] stream. +/// Exported under the `internals` feature only. pub struct TokenIterator<'a> { /// Reference to the scripting `Engine`. - engine: &'a Engine, + pub engine: &'a Engine, /// Current state. - state: TokenizeState, + pub state: TokenizeState, /// Current position. - pos: Position, + pub pos: Position, /// External buffer containing the next character to read, if any. - tokenizer_control: TokenizerControl, + pub tokenizer_control: TokenizerControl, /// Input character stream. - stream: MultiInputsStream<'a>, + pub stream: MultiInputsStream<'a>, /// A processor function that maps a token to another. - map: Option Token>, + pub map: Option Token>, } impl<'a> Iterator for TokenIterator<'a> {