diff --git a/Cargo.toml b/Cargo.toml index e93cc307..f0a66805 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -98,10 +98,10 @@ features = ["maths"] optional = true [target.'cfg(target_arch = "wasm32")'.dependencies] -instant = { version = "0.1" } # WASM implementation of std::time::Instant +instant = { version = "0.1.10" } # WASM implementation of std::time::Instant [target.'cfg(target_arch = "wasm64")'.dependencies] -instant = { version = "0.1" } # WASM implementation of std::time::Instant +instant = { version = "0.1.10" } # WASM implementation of std::time::Instant [package.metadata.docs.rs] features = ["metadata", "serde", "internals", "decimal"] # compiling for no-std diff --git a/no_std/no_std_repl/Cargo.toml b/no_std/no_std_repl/Cargo.toml deleted file mode 100644 index 36e9c2f0..00000000 --- a/no_std/no_std_repl/Cargo.toml +++ /dev/null @@ -1,38 +0,0 @@ -cargo-features = ["named-profiles"] - -[workspace] - -[package] -name = "no_std_repl" -version = "0.1.0" -edition = "2018" -authors = ["Stephen Chung"] -description = "no-std REPL application" -homepage = "https://github.com/rhaiscript/rhai/tree/no_std/no_std_repl" -repository = "https://github.com/rhaiscript/rhai" - -[dependencies] -rhai = { path = "../../", default_features = false, features = [ "no_std", "decimal", "metadata" ] } -wee_alloc = { version = "0.4.5", default_features = false } - -[profile.dev] -panic = "abort" - -[profile.release] -opt-level = "z" # optimize for size -debug = false -rpath = false -debug-assertions = false -codegen-units = 1 -panic = "abort" - -[profile.unix] -inherits = "release" -lto = true - -[profile.windows] -inherits = "release" - -[profile.macos] -inherits = "release" -lto = "fat" diff --git a/no_std/no_std_repl/README.md b/no_std/no_std_repl/README.md deleted file mode 100644 index c7ea3ce5..00000000 --- a/no_std/no_std_repl/README.md +++ /dev/null @@ -1,26 +0,0 @@ -`no-std` REPL Sample -==================== - -This sample application is the same version as the `rhai-repl` tool, compiled for `no-std`. - -[`wee_alloc`](https://crates.io/crates/wee_alloc) is used as the allocator. - - -To Build --------- - -The nightly compiler is required: - -```bash -cargo +nightly build --release -``` - -A specific profile can also be used: - -```bash -cargo +nightly build --profile unix -Z unstable-options -``` - -Three profiles are defined: `unix`, `windows` and `macos`. - -The release build is optimized for size. It can be changed to optimize on speed instead. diff --git a/no_std/no_std_repl/src/main.rs b/no_std/no_std_repl/src/main.rs deleted file mode 100644 index 9a4b5e7f..00000000 --- a/no_std/no_std_repl/src/main.rs +++ /dev/null @@ -1,214 +0,0 @@ -use rhai::{Dynamic, Engine, EvalAltResult, Scope, AST}; - -use std::{ - env, - io::{stdin, stdout, Write}, -}; - -/// Pretty-print error. -fn print_error(input: &str, mut err: EvalAltResult) { - let lines: Vec<_> = input.trim().split('\n').collect(); - let pos = err.take_position(); - - let line_no = if lines.len() > 1 { - if pos.is_none() { - "".to_string() - } else { - format!("{}: ", pos.line().unwrap()) - } - } else { - "".to_string() - }; - - // Print error position - if pos.is_none() { - // No position - println!("{}", err); - } else { - // Specific position - print line text - println!("{}{}", line_no, lines[pos.line().unwrap() - 1]); - - // Display position marker - println!( - "{0:>1$} {2}", - "^", - line_no.len() + pos.position().unwrap(), - err - ); - } -} - -/// Print help text. -fn print_help() { - println!("help => print this help"); - println!("quit, exit => quit"); - println!("scope => print all variables in the scope"); - println!("functions => print all functions defined"); - println!("json => output all functions in JSON format"); - println!("ast => print the last AST (optimized)"); - println!("astu => print the last raw, un-optimized AST"); - println!(r"end a line with '\' to continue to the next line."); - println!(); -} - -fn main() { - let title = format!("Rhai REPL tool (version {})", env!("CARGO_PKG_VERSION")); - println!("{}", title); - println!("{0:=<1$}", "", title.len()); - print_help(); - - // Initialize scripting engine - let mut engine = Engine::new(); - - // Setup Engine - #[cfg(not(feature = "no_optimize"))] - engine.set_optimization_level(rhai::OptimizationLevel::None); - - // Make Engine immutable - let engine = engine; - - // Create scope - let mut scope = Scope::new(); - - // REPL loop - let mut input = String::new(); - let mut main_ast: AST = Default::default(); - let mut ast_u: AST = Default::default(); - let mut ast: AST = Default::default(); - - 'main_loop: loop { - print!("rhai-repl> "); - stdout().flush().expect("couldn't flush stdout"); - - input.clear(); - - loop { - match stdin().read_line(&mut input) { - Ok(0) => break 'main_loop, - Ok(_) => (), - Err(err) => panic!("input error: {}", err), - } - - let line = input.as_str().trim_end(); - - // Allow line continuation - if line.ends_with('\\') { - let len = line.len(); - input.truncate(len - 1); - input.push('\n'); - } else { - break; - } - - print!("> "); - stdout().flush().expect("couldn't flush stdout"); - } - - let script = input.trim(); - - if script.is_empty() { - continue; - } - - // Implement standard commands - match script { - "help" => { - print_help(); - continue; - } - "exit" | "quit" => break, // quit - "scope" => { - scope - .iter_raw() - .enumerate() - .for_each(|(i, (name, constant, value))| { - #[cfg(not(feature = "no_closure"))] - let value_is_shared = if value.is_shared() { " (shared" } else { "" }; - #[cfg(feature = "no_closure")] - let value_is_shared = ""; - - println!( - "[{}] {}{}{} = {:?}", - i + 1, - if constant { "const " } else { "" }, - name, - value_is_shared, - *value.read_lock::().unwrap(), - ) - }); - println!(); - continue; - } - "astu" => { - // print the last un-optimized AST - println!("{:#?}\n", ast_u); - continue; - } - "ast" => { - // print the last AST - println!("{:#?}\n", ast); - continue; - } - "functions" => { - // print a list of all registered functions - engine - .gen_fn_signatures(false) - .into_iter() - .for_each(|f| println!("{}", f)); - - #[cfg(not(feature = "no_function"))] - main_ast.iter_functions().for_each(|f| println!("{}", f)); - - println!(); - continue; - } - "json" => { - println!( - "{}", - engine - .gen_fn_metadata_with_ast_to_json(&main_ast, true) - .unwrap() - ); - continue; - } - _ => (), - } - - match engine - .compile_with_scope(&scope, &script) - .map_err(Into::into) - .and_then(|r| { - ast_u = r.clone(); - - #[cfg(not(feature = "no_optimize"))] - { - ast = engine.optimize_ast(&scope, r, rhai::OptimizationLevel::Simple); - } - - #[cfg(feature = "no_optimize")] - { - ast = r; - } - - // Merge the AST into the main - main_ast += ast.clone(); - - // Evaluate - engine.eval_ast_with_scope::(&mut scope, &main_ast) - }) { - Ok(result) if !result.is::<()>() => { - println!("=> {:?}", result); - println!(); - } - Ok(_) => (), - Err(err) => { - println!(); - print_error(&input, *err); - println!(); - } - } - - // Throw away all the statements, leaving only the functions - main_ast.clear_statements(); - } -} diff --git a/src/ast.rs b/src/ast.rs index c9ce1d3f..16288c17 100644 --- a/src/ast.rs +++ b/src/ast.rs @@ -40,7 +40,7 @@ pub enum FnAccess { Private, } -/// _(INTERNALS)_ A type containing information on a scripted function. +/// _(internals)_ A type containing information on a scripted function. /// Exported under the `internals` feature only. /// /// # Volatile Data Structure @@ -68,7 +68,7 @@ pub struct ScriptFnDef { /// Not available under `no_closure`. #[cfg(not(feature = "no_closure"))] pub externals: std::collections::BTreeSet, - /// _(METADATA)_ Function doc-comments (if any). + /// _(metadata)_ Function doc-comments (if any). /// Exported under the `metadata` feature only. /// /// Not available under `no_function`. @@ -104,7 +104,7 @@ impl fmt::Display for ScriptFnDef { #[cfg(not(feature = "no_function"))] #[derive(Debug, Eq, PartialEq, Clone, Hash)] pub struct ScriptFnMetadata<'a> { - /// _(METADATA)_ Function doc-comments (if any). + /// _(metadata)_ Function doc-comments (if any). /// Exported under the `metadata` feature only. /// /// Not available under `no_function`. @@ -278,7 +278,7 @@ impl AST { pub(crate) fn statements(&self) -> &[Stmt] { &self.body.0 } - /// _(INTERNALS)_ Get the statements. + /// _(internals)_ Get the statements. /// Exported under the `internals` feature only. #[cfg(feature = "internals")] #[deprecated = "this method is volatile and may change"] @@ -303,7 +303,7 @@ impl AST { pub(crate) fn shared_lib(&self) -> Shared { self.functions.clone() } - /// _(INTERNALS)_ Get the internal shared [`Module`] containing all script-defined functions. + /// _(internals)_ Get the internal shared [`Module`] containing all script-defined functions. /// Exported under the `internals` feature only. /// /// Not available under `no_function` or `no_module`. @@ -323,7 +323,7 @@ impl AST { pub(crate) fn lib(&self) -> &Module { &self.functions } - /// _(INTERNALS)_ Get the internal [`Module`] containing all script-defined functions. + /// _(internals)_ Get the internal [`Module`] containing all script-defined functions. /// Exported under the `internals` feature only. /// /// Not available under `no_function`. @@ -344,7 +344,7 @@ impl AST { ) -> Option> { self.resolver.clone() } - /// _(INTERNALS)_ Get the embedded [module resolver][crate::ModuleResolver]. + /// _(internals)_ Get the embedded [module resolver][crate::ModuleResolver]. /// Exported under the `internals` feature only. /// /// Not available under `no_module`. @@ -762,7 +762,7 @@ impl AST { true } - /// _(INTERNALS)_ Recursively walk the [`AST`], including function bodies (if any). + /// _(internals)_ Recursively walk the [`AST`], including function bodies (if any). /// Return `false` from the callback to terminate the walk. /// Exported under the `internals` feature only. #[cfg(feature = "internals")] @@ -816,7 +816,7 @@ impl AsRef for AST { } } -/// _(INTERNALS)_ An identifier containing a name and a [position][Position]. +/// _(internals)_ An identifier containing a name and a [position][Position]. /// Exported under the `internals` feature only. /// /// # Volatile Data Structure @@ -837,7 +837,7 @@ impl fmt::Debug for Ident { } } -/// _(INTERNALS)_ A type encapsulating the mode of a `return`/`throw` statement. +/// _(internals)_ A type encapsulating the mode of a `return`/`throw` statement. /// Exported under the `internals` feature only. /// /// # Volatile Data Structure @@ -851,7 +851,7 @@ pub enum ReturnType { Exception, } -/// _(INTERNALS)_ An [`AST`] node, consisting of either an [`Expr`] or a [`Stmt`]. +/// _(internals)_ An [`AST`] node, consisting of either an [`Expr`] or a [`Stmt`]. /// Exported under the `internals` feature only. /// /// # Volatile Data Structure @@ -875,7 +875,7 @@ impl<'a> From<&'a Expr> for ASTNode<'a> { } } -/// _(INTERNALS)_ A statements block. +/// _(internals)_ A statements block. /// Exported under the `internals` feature only. /// /// # Volatile Data Structure @@ -950,7 +950,19 @@ impl From for Stmt { } } -/// _(INTERNALS)_ A statement. +/// _(internals)_ Type of variable declaration. +/// Exported under the `internals` feature only. +/// +/// # Volatile Data Structure +/// +/// This type is volatile and may change. +#[derive(Debug, Eq, PartialEq, Copy, Clone, Hash)] +pub enum VarDeclaration { + Let, + Const, +} + +/// _(internals)_ A statement. /// Exported under the `internals` feature only. /// /// # Volatile Data Structure @@ -974,10 +986,8 @@ pub enum Stmt { Do(Box, Expr, bool, Position), /// `for` `(` id `,` counter `)` `in` expr `{` stmt `}` For(Expr, Box<(Ident, Option, StmtBlock)>, Position), - /// \[`export`\] `let` id `=` expr - Let(Expr, Box, bool, Position), - /// \[`export`\] `const` id `=` expr - Const(Expr, Box, bool, Position), + /// \[`export`\] `let`/`const` id `=` expr + Var(Expr, Box, VarDeclaration, bool, Position), /// expr op`=` expr Assignment(Box<(Expr, Option>, Expr)>, Position), /// func `(` expr `,` ... `)` @@ -1058,8 +1068,7 @@ impl Stmt { | Self::Do(_, _, _, pos) | Self::For(_, _, pos) | Self::Return(_, _, pos) - | Self::Let(_, _, _, pos) - | Self::Const(_, _, _, pos) + | Self::Var(_, _, _, _, pos) | Self::TryCatch(_, pos) => *pos, Self::Expr(x) => x.position(), @@ -1088,8 +1097,7 @@ impl Stmt { | Self::Do(_, _, _, pos) | Self::For(_, _, pos) | Self::Return(_, _, pos) - | Self::Let(_, _, _, pos) - | Self::Const(_, _, _, pos) + | Self::Var(_, _, _, _, pos) | Self::TryCatch(_, pos) => *pos = new_pos, Self::Expr(x) => { @@ -1123,8 +1131,7 @@ impl Stmt { | Self::For(_, _, _) | Self::TryCatch(_, _) => false, - Self::Let(_, _, _, _) - | Self::Const(_, _, _, _) + Self::Var(_, _, _, _, _) | Self::Assignment(_, _) | Self::Continue(_) | Self::Break(_) @@ -1151,8 +1158,7 @@ impl Stmt { // A No-op requires a semicolon in order to know it is an empty statement! Self::Noop(_) => false, - Self::Let(_, _, _, _) - | Self::Const(_, _, _, _) + Self::Var(_, _, _, _, _) | Self::Assignment(_, _) | Self::FnCall(_, _) | Self::Expr(_) @@ -1193,10 +1199,7 @@ impl Stmt { condition.is_pure() && block.0.iter().all(Stmt::is_pure) } Self::For(iterable, x, _) => iterable.is_pure() && (x.2).0.iter().all(Stmt::is_pure), - Self::Let(_, _, _, _) - | Self::Const(_, _, _, _) - | Self::Assignment(_, _) - | Self::FnCall(_, _) => false, + Self::Var(_, _, _, _, _) | Self::Assignment(_, _) | Self::FnCall(_, _) => false, Self::Block(block, _) => block.iter().all(|stmt| stmt.is_pure()), Self::Continue(_) | Self::Break(_) | Self::Return(_, _, _) => false, Self::TryCatch(x, _) => { @@ -1222,7 +1225,7 @@ impl Stmt { #[must_use] pub fn is_internally_pure(&self) -> bool { match self { - Self::Let(expr, _, _, _) | Self::Const(expr, _, _, _) => expr.is_pure(), + Self::Var(expr, _, _, _, _) => expr.is_pure(), #[cfg(not(feature = "no_module"))] Self::Import(expr, _, _) => expr.is_pure(), @@ -1260,7 +1263,7 @@ impl Stmt { } match self { - Self::Let(e, _, _, _) | Self::Const(e, _, _, _) => { + Self::Var(e, _, _, _, _) => { if !e.walk(path, on_node) { return false; } @@ -1375,7 +1378,7 @@ impl Stmt { } } -/// _(INTERNALS)_ A custom syntax expression. +/// _(internals)_ A custom syntax expression. /// Exported under the `internals` feature only. /// /// # Volatile Data Structure @@ -1391,7 +1394,7 @@ pub struct CustomExpr { pub tokens: StaticVec, } -/// _(INTERNALS)_ A binary expression. +/// _(internals)_ A binary expression. /// Exported under the `internals` feature only. /// /// # Volatile Data Structure @@ -1405,7 +1408,7 @@ pub struct BinaryExpr { pub rhs: Expr, } -/// _(INTERNALS)_ An op-assignment operator. +/// _(internals)_ An op-assignment operator. /// Exported under the `internals` feature only. /// /// # Volatile Data Structure @@ -1443,7 +1446,7 @@ impl OpAssignment<'_> { } } -/// _(INTERNALS)_ An set of function call hashes. +/// _(internals)_ An set of function call hashes. /// Exported under the `internals` feature only. /// /// Two separate hashes are pre-calculated because of the following pattern: @@ -1530,7 +1533,7 @@ impl FnCallHashes { } } -/// _(INTERNALS)_ A function call. +/// _(internals)_ A function call. /// Exported under the `internals` feature only. /// /// # Volatile Data Structure @@ -1686,7 +1689,7 @@ impl FloatWrapper { } } -/// _(INTERNALS)_ An expression sub-tree. +/// _(internals)_ An expression sub-tree. /// Exported under the `internals` feature only. /// /// # Volatile Data Structure diff --git a/src/dynamic.rs b/src/dynamic.rs index 512e062d..8441a940 100644 --- a/src/dynamic.rs +++ b/src/dynamic.rs @@ -46,7 +46,7 @@ mod private { impl Sealed for T {} } -/// _(INTERNALS)_ Trait to represent any type. +/// _(internals)_ Trait to represent any type. /// Exported under the `internals` feature only. /// /// This trait is sealed and cannot be implemented. @@ -80,7 +80,7 @@ pub trait Variant: Any + private::Sealed { fn clone_into_dynamic(&self) -> Dynamic; } -/// _(INTERNALS)_ Trait to represent any type. +/// _(internals)_ Trait to represent any type. /// Exported under the `internals` feature only. /// /// This trait is sealed and cannot be implemented. @@ -189,7 +189,7 @@ pub enum Union { /// Not available under `no_float`. #[cfg(not(feature = "no_float"))] Float(FloatWrapper, Tag, AccessMode), - /// _(DECIMAL)_ A fixed-precision decimal value. + /// _(decimal)_ A fixed-precision decimal value. /// Exported under the `decimal` feature only. #[cfg(feature = "decimal")] Decimal(Box, Tag, AccessMode), @@ -222,7 +222,7 @@ pub enum Union { Shared(crate::Shared>, Tag, AccessMode), } -/// _(INTERNALS)_ Lock guard for reading a [`Dynamic`]. +/// _(internals)_ Lock guard for reading a [`Dynamic`]. /// Exported under the `internals` feature only. /// /// This type provides transparent interoperability between normal [`Dynamic`] and shared @@ -265,7 +265,7 @@ impl<'d, T: Any + Clone> Deref for DynamicReadLock<'d, T> { } } -/// _(INTERNALS)_ Lock guard for writing a [`Dynamic`]. +/// _(internals)_ Lock guard for writing a [`Dynamic`]. /// Exported under the `internals` feature only. /// /// This type provides transparent interoperability between normal [`Dynamic`] and shared @@ -1762,7 +1762,7 @@ impl Dynamic { _ => Err(self.type_name()), } } - /// _(DECIMAL)_ Cast the [`Dynamic`] as a [`Decimal`] and return it. + /// _(decimal)_ Cast the [`Dynamic`] as a [`Decimal`](https://docs.rs/rust_decimal) and return it. /// Returns the name of the actual type if the cast fails. /// /// Exported under the `decimal` feature only. diff --git a/src/engine.rs b/src/engine.rs index 75924308..8bd29996 100644 --- a/src/engine.rs +++ b/src/engine.rs @@ -1,6 +1,6 @@ //! Main module defining the script evaluation [`Engine`]. -use crate::ast::{Expr, FnCallExpr, Ident, OpAssignment, ReturnType, Stmt}; +use crate::ast::{Expr, FnCallExpr, Ident, OpAssignment, ReturnType, Stmt, VarDeclaration}; use crate::custom_syntax::CustomSyntax; use crate::dynamic::{map_std_type_name, AccessMode, Union, Variant}; use crate::fn_hash::get_hasher; @@ -40,7 +40,7 @@ use crate::ast::FnCallHashes; pub type Precedence = NonZeroU8; -/// _(INTERNALS)_ A stack of imported [modules][Module]. +/// _(internals)_ A stack of imported [modules][Module]. /// Exported under the `internals` feature only. /// /// # Volatile Data Structure @@ -620,7 +620,7 @@ impl> From for Target<'_> { } } -/// _(INTERNALS)_ An entry in a function resolution cache. +/// _(internals)_ An entry in a function resolution cache. /// Exported under the `internals` feature only. /// /// # Volatile Data Structure @@ -634,7 +634,7 @@ pub struct FnResolutionCacheEntry { pub source: Option, } -/// _(INTERNALS)_ A function resolution cache. +/// _(internals)_ A function resolution cache. /// Exported under the `internals` feature only. /// /// # Volatile Data Structure @@ -642,7 +642,7 @@ pub struct FnResolutionCacheEntry { /// This type is volatile and may change. pub type FnResolutionCache = BTreeMap>>; -/// _(INTERNALS)_ A type that holds all the current states of the [`Engine`]. +/// _(internals)_ A type that holds all the current states of the [`Engine`]. /// Exported under the `internals` feature only. /// /// # Volatile Data Structure @@ -653,19 +653,20 @@ pub struct EvalState { /// Source of the current context. pub source: Option, /// Normally, access to variables are parsed with a relative offset into the [`Scope`] to avoid a lookup. - /// In some situation, e.g. after running an `eval` statement, subsequent offsets may become mis-aligned. + /// In some situation, e.g. after running an `eval` statement, or after a custom syntax statement, + /// subsequent offsets may become mis-aligned. /// When that happens, this flag is turned on to force a [`Scope`] search by name. pub always_search_scope: bool, /// Level of the current scope. The global (root) level is zero, a new block (or function call) /// is one level higher, and so on. pub scope_level: usize, /// Number of operations performed. - pub operations: u64, + pub num_operations: u64, /// Number of modules loaded. - pub modules: usize, + pub num_modules: usize, /// Embedded module resolver. #[cfg(not(feature = "no_module"))] - pub resolver: Option>, + pub embedded_module_resolver: Option>, /// Stack of function resolution caches. fn_resolution_caches: Vec, } @@ -679,10 +680,10 @@ impl EvalState { source: None, always_search_scope: false, scope_level: 0, - operations: 0, - modules: 0, + num_operations: 0, + num_modules: 0, #[cfg(not(feature = "no_module"))] - resolver: None, + embedded_module_resolver: None, fn_resolution_caches: Vec::new(), } } @@ -723,7 +724,7 @@ impl EvalState { } } -/// _(INTERNALS)_ A type containing all the limits imposed by the [`Engine`]. +/// _(internals)_ A type containing all the limits imposed by the [`Engine`]. /// Exported under the `internals` feature only. /// /// # Volatile Data Structure @@ -833,7 +834,7 @@ impl<'x, 'px, 'pt> EvalContext<'_, 'x, 'px, '_, '_, '_, '_, 'pt> { pub fn iter_imports(&self) -> impl Iterator { self.mods.iter() } - /// _(INTERNALS)_ The current set of modules imported via `import` statements. + /// _(internals)_ The current set of modules imported via `import` statements. /// Exported under the `internals` feature only. #[cfg(feature = "internals")] #[cfg(not(feature = "no_module"))] @@ -847,7 +848,7 @@ impl<'x, 'px, 'pt> EvalContext<'_, 'x, 'px, '_, '_, '_, '_, 'pt> { pub fn iter_namespaces(&self) -> impl Iterator { self.lib.iter().cloned() } - /// _(INTERNALS)_ The current set of namespaces containing definitions of all script-defined functions. + /// _(internals)_ The current set of namespaces containing definitions of all script-defined functions. /// Exported under the `internals` feature only. #[cfg(feature = "internals")] #[inline(always)] @@ -2850,12 +2851,11 @@ impl Engine { } // Let/const statement - Stmt::Let(expr, x, export, _) | Stmt::Const(expr, x, export, _) => { + Stmt::Var(expr, x, var_type, export, _) => { let name = &x.name; - let entry_type = match stmt { - Stmt::Let(_, _, _, _) => AccessMode::ReadWrite, - Stmt::Const(_, _, _, _) => AccessMode::ReadOnly, - _ => unreachable!("should be Stmt::Let or Stmt::Const, but gets {:?}", stmt), + let entry_type = match var_type { + VarDeclaration::Let => AccessMode::ReadWrite, + VarDeclaration::Const => AccessMode::ReadOnly, }; let value = self @@ -2914,7 +2914,7 @@ impl Engine { Stmt::Import(expr, export, _pos) => { // Guard against too many modules #[cfg(not(feature = "unchecked"))] - if state.modules >= self.max_modules() { + if state.num_modules >= self.max_modules() { return EvalAltResult::ErrorTooManyModules(*_pos).into(); } @@ -2928,7 +2928,7 @@ impl Engine { let path_pos = expr.position(); let module = state - .resolver + .embedded_module_resolver .as_ref() .and_then(|r| match r.resolve(self, source, &path, path_pos) { Err(err) @@ -2958,7 +2958,7 @@ impl Engine { } } - state.modules += 1; + state.num_modules += 1; Ok(Dynamic::UNIT) } else { @@ -3130,16 +3130,16 @@ impl Engine { state: &mut EvalState, pos: Position, ) -> Result<(), Box> { - state.operations += 1; + state.num_operations += 1; // Guard against too many operations - if self.max_operations() > 0 && state.operations > self.max_operations() { + if self.max_operations() > 0 && state.num_operations > self.max_operations() { return EvalAltResult::ErrorTooManyOperations(pos).into(); } // Report progress - only in steps if let Some(ref progress) = self.progress { - if let Some(token) = progress(state.operations) { + if let Some(token) = progress(state.num_operations) { // Terminate script if progress returns a termination token return EvalAltResult::ErrorTerminated(token, pos).into(); } diff --git a/src/engine_api.rs b/src/engine_api.rs index d61c4074..99213283 100644 --- a/src/engine_api.rs +++ b/src/engine_api.rs @@ -1729,7 +1729,7 @@ impl Engine { state.source = ast.source_raw().cloned(); #[cfg(not(feature = "no_module"))] { - state.resolver = ast.resolver(); + state.embedded_module_resolver = ast.resolver(); } let statements = ast.statements(); @@ -1811,7 +1811,7 @@ impl Engine { state.source = ast.source_raw().cloned(); #[cfg(not(feature = "no_module"))] { - state.resolver = ast.resolver(); + state.embedded_module_resolver = ast.resolver(); } let statements = ast.statements(); @@ -2052,7 +2052,7 @@ impl Engine { let stmt = std::mem::take(ast.statements_mut()); crate::optimize::optimize_into_ast(self, scope, stmt.into_vec(), lib, optimization_level) } - /// _(METADATA)_ Generate a list of all registered functions. + /// _(metadata)_ Generate a list of all registered functions. /// Exported under the `metadata` feature only. /// /// Functions from the following sources are included, in order: diff --git a/src/error_parsing.rs b/src/error_parsing.rs index c65b9b07..396c7957 100644 --- a/src/error_parsing.rs +++ b/src/error_parsing.rs @@ -9,7 +9,7 @@ use std::fmt; #[cfg(feature = "no_std")] use std::prelude::v1::*; -/// _(INTERNALS)_ Error encountered when tokenizing the script text. +/// _(internals)_ Error encountered when tokenizing the script text. /// Exported under the `internals` feature only. /// /// # Volatile Data Structure diff --git a/src/fn_call.rs b/src/fn_call.rs index 23bc447a..e79e906a 100644 --- a/src/fn_call.rs +++ b/src/fn_call.rs @@ -840,12 +840,12 @@ impl Engine { // Evaluate the AST let mut new_state = EvalState::new(); new_state.source = state.source.clone(); - new_state.operations = state.operations; + new_state.num_operations = state.num_operations; let result = self.eval_global_statements(scope, mods, &mut new_state, statements, lib, level); - state.operations = new_state.operations; + state.num_operations = new_state.num_operations; result } diff --git a/src/fn_native.rs b/src/fn_native.rs index 9930fec4..c7d8cdbd 100644 --- a/src/fn_native.rs +++ b/src/fn_native.rs @@ -98,7 +98,7 @@ impl<'a> NativeCallContext<'a> { lib, } } - /// _(INTERNALS)_ Create a new [`NativeCallContext`]. + /// _(internals)_ Create a new [`NativeCallContext`]. /// Exported under the `internals` feature only. /// /// Not available under `no_module`. @@ -156,7 +156,7 @@ impl<'a> NativeCallContext<'a> { ) -> impl Iterator)> { self.mods.iter().flat_map(|&m| m.iter_raw()) } - /// _(INTERNALS)_ The current set of modules imported via `import` statements. + /// _(internals)_ The current set of modules imported via `import` statements. /// Exported under the `internals` feature only. /// /// Not available under `no_module`. @@ -172,7 +172,7 @@ impl<'a> NativeCallContext<'a> { pub fn iter_namespaces(&self) -> impl Iterator { self.lib.iter().cloned() } - /// _(INTERNALS)_ The current set of namespaces containing definitions of all script-defined functions. + /// _(internals)_ The current set of namespaces containing definitions of all script-defined functions. /// Exported under the `internals` feature only. #[cfg(feature = "internals")] #[inline(always)] diff --git a/src/fn_register.rs b/src/fn_register.rs index b74a93ce..cb90c62e 100644 --- a/src/fn_register.rs +++ b/src/fn_register.rs @@ -71,17 +71,17 @@ pub trait RegisterNativeFunction { /// Get the type ID's of this function's parameters. #[must_use] fn param_types() -> Box<[TypeId]>; - /// _(METADATA)_ Get the type names of this function's parameters. + /// _(metadata)_ Get the type names of this function's parameters. /// Exported under the `metadata` feature only. #[cfg(feature = "metadata")] #[must_use] fn param_names() -> Box<[&'static str]>; - /// _(METADATA)_ Get the type ID of this function's return value. + /// _(metadata)_ Get the type ID of this function's return value. /// Exported under the `metadata` feature only. #[cfg(feature = "metadata")] #[must_use] fn return_type() -> TypeId; - /// _(METADATA)_ Get the type name of this function's return value. + /// _(metadata)_ Get the type name of this function's return value. /// Exported under the `metadata` feature only. #[cfg(feature = "metadata")] #[must_use] diff --git a/src/lib.rs b/src/lib.rs index 6b13fac0..1d72720f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -228,7 +228,7 @@ pub use token::{InputStream, Token, TokenizeState, TokenizerControl, TokenizerCo #[deprecated = "this type is volatile and may change"] pub use ast::{ ASTNode, BinaryExpr, CustomExpr, Expr, FloatWrapper, FnCallExpr, FnCallHashes, Ident, - OpAssignment, ReturnType, ScriptFnDef, Stmt, StmtBlock, + OpAssignment, ReturnType, ScriptFnDef, Stmt, StmtBlock, VarDeclaration, }; #[cfg(feature = "internals")] @@ -278,7 +278,7 @@ pub use module::NamespaceRef; #[cfg(not(feature = "internals"))] type StaticVec = smallvec::SmallVec<[T; 4]>; -/// _(INTERNALS)_ Alias to [`smallvec`](https://crates.io/crates/smallvec), which is a specialized +/// _(internals)_ Alias to [`smallvec`](https://crates.io/crates/smallvec), which is a specialized /// [`Vec`] backed by a small, inline, fixed-size array when there are ≤ 4 items stored. /// Exported under the `internals` feature only. /// diff --git a/src/module/mod.rs b/src/module/mod.rs index 413fad22..c9d10706 100644 --- a/src/module/mod.rs +++ b/src/module/mod.rs @@ -81,18 +81,18 @@ impl FuncInfo { sig.push_str(") -> "); sig.push_str(&return_type); } else { - sig.push_str(")"); + sig.push(')'); } } else { for x in 0..self.params { - sig.push_str("_"); + sig.push('_'); if x < self.params - 1 { sig.push_str(", "); } } if self.func.is_script() { - sig.push_str(")"); + sig.push(')'); } else { sig.push_str(") -> ?"); } @@ -102,7 +102,7 @@ impl FuncInfo { } } -/// _(INTERNALS)_ Calculate a [`u64`] hash key from a namespace-qualified function name and +/// _(internals)_ Calculate a [`u64`] hash key from a namespace-qualified function name and /// parameter types. /// Exported under the `internals` feature only. /// @@ -366,7 +366,6 @@ impl Module { /// Exported under the `metadata` feature only. #[cfg(feature = "metadata")] #[inline(always)] - #[must_use] pub fn gen_fn_signatures(&self) -> impl Iterator + '_ { self.functions .values() @@ -630,9 +629,9 @@ impl Module { .map(|&name| self.identifiers.get(name)) .collect(); - self.functions - .get_mut(&hash_fn) - .map(|f| f.param_names = param_names); + if let Some(f) = self.functions.get_mut(&hash_fn) { + f.param_names = param_names; + } self } @@ -1364,7 +1363,7 @@ impl Module { .map(|f| (f.namespace, f.access, f.name.as_str(), f.params)) } - /// _(INTERNALS)_ Get an iterator over all script-defined functions in the [`Module`]. + /// _(internals)_ Get an iterator over all script-defined functions in the [`Module`]. /// Exported under the `internals` feature only. /// /// Function metadata includes: @@ -1372,7 +1371,7 @@ impl Module { /// 2) Access mode ([`FnAccess::Public`] or [`FnAccess::Private`]). /// 3) Function name (as string slice). /// 4) Number of parameters. - /// 5) _(INTERNALS)_ Shared reference to function definition [`ScriptFnDef`][crate::ast::ScriptFnDef]. + /// 5) _(internals)_ Shared reference to function definition [`ScriptFnDef`][crate::ast::ScriptFnDef]. #[cfg(not(feature = "no_function"))] #[cfg(feature = "internals")] #[inline(always)] @@ -1653,7 +1652,7 @@ impl Module { } } -/// _(INTERNALS)_ A chain of [module][Module] names to namespace-qualify a variable or function call. +/// _(internals)_ A chain of [module][Module] names to namespace-qualify a variable or function call. /// Exported under the `internals` feature only. /// /// A [`u64`] offset to the current [`Scope`][crate::Scope] is cached for quick search purposes. diff --git a/src/module/resolvers/stat.rs b/src/module/resolvers/stat.rs index 0b43bd28..0b555884 100644 --- a/src/module/resolvers/stat.rs +++ b/src/module/resolvers/stat.rs @@ -1,4 +1,6 @@ -use crate::{Engine, EvalAltResult, Identifier, Module, ModuleResolver, Position, Shared}; +use crate::{ + Engine, EvalAltResult, Identifier, Module, ModuleResolver, Position, Shared, SmartString, +}; #[cfg(feature = "no_std")] use std::prelude::v1::*; use std::{collections::BTreeMap, ops::AddAssign}; @@ -72,11 +74,6 @@ impl StaticModuleResolver { pub fn iter_mut(&mut self) -> impl Iterator)> { self.0.iter_mut().map(|(k, v)| (k.as_str(), v)) } - /// Get a mutable iterator of all the modules. - #[inline(always)] - pub fn into_iter(self) -> impl Iterator)> { - self.0.into_iter() - } /// Get an iterator of all the [module][Module] paths. #[inline(always)] pub fn paths(&self) -> impl Iterator { @@ -117,6 +114,15 @@ impl StaticModuleResolver { } } +impl IntoIterator for StaticModuleResolver { + type Item = (Identifier, Shared); + type IntoIter = std::collections::btree_map::IntoIter>; + + fn into_iter(self) -> Self::IntoIter { + self.0.into_iter() + } +} + impl ModuleResolver for StaticModuleResolver { #[inline(always)] fn resolve( diff --git a/src/optimize.rs b/src/optimize.rs index b5d25a9b..75fe9a83 100644 --- a/src/optimize.rs +++ b/src/optimize.rs @@ -1,6 +1,6 @@ //! Module implementing the [`AST`] optimizer. -use crate::ast::{Expr, OpAssignment, Stmt}; +use crate::ast::{Expr, OpAssignment, Stmt, VarDeclaration}; use crate::dynamic::AccessMode; use crate::engine::{KEYWORD_DEBUG, KEYWORD_EVAL, KEYWORD_FN_PTR, KEYWORD_PRINT, KEYWORD_TYPE_OF}; use crate::fn_builtin::get_builtin_binary_op_fn; @@ -202,7 +202,7 @@ fn optimize_stmt_block( statements.iter_mut().for_each(|stmt| { match stmt { // Add constant literals into the state - Stmt::Const(value_expr, x, _, _) => { + Stmt::Var(value_expr, x, VarDeclaration::Const, _, _) => { optimize_expr(value_expr, state, false); if value_expr.is_constant() { @@ -214,7 +214,7 @@ fn optimize_stmt_block( } } // Add variables into the state - Stmt::Let(value_expr, x, _, _) => { + Stmt::Var(value_expr, x, VarDeclaration::Let, _, _) => { optimize_expr(value_expr, state, false); state.push_var(&x.name, AccessMode::ReadWrite, None); } @@ -232,11 +232,7 @@ fn optimize_stmt_block( .find_map(|(i, stmt)| match stmt { stmt if !is_pure(stmt) => Some(i), - Stmt::Let(e, _, _, _) | Stmt::Const(e, _, _, _) | Stmt::Expr(e) - if !e.is_constant() => - { - Some(i) - } + Stmt::Var(e, _, _, _, _) | Stmt::Expr(e) if !e.is_constant() => Some(i), #[cfg(not(feature = "no_module"))] Stmt::Import(e, _, _) if !e.is_constant() => Some(i), @@ -609,7 +605,7 @@ fn optimize_stmt(stmt: &mut Stmt, state: &mut OptimizerState, preserve_result: b *x.2.statements_mut() = optimize_stmt_block(body, state, false, true, false).into(); } // let id = expr; - Stmt::Let(expr, _, _, _) => optimize_expr(expr, state, false), + Stmt::Var(expr, _, VarDeclaration::Let, _, _) => optimize_expr(expr, state, false), // import expr as var; #[cfg(not(feature = "no_module"))] Stmt::Import(expr, _, _) => optimize_expr(expr, state, false), diff --git a/src/parse.rs b/src/parse.rs index 073a222f..a87ed5c8 100644 --- a/src/parse.rs +++ b/src/parse.rs @@ -2,7 +2,7 @@ use crate::ast::{ BinaryExpr, CustomExpr, Expr, FnCallExpr, FnCallHashes, Ident, OpAssignment, ReturnType, - ScriptFnDef, Stmt, StmtBlock, + ScriptFnDef, Stmt, StmtBlock, VarDeclaration, }; use crate::custom_syntax::{ CustomSyntax, CUSTOM_SYNTAX_MARKER_BLOCK, CUSTOM_SYNTAX_MARKER_BOOL, CUSTOM_SYNTAX_MARKER_EXPR, @@ -2115,14 +2115,12 @@ fn parse_expr( match token { Token::Custom(key) | Token::Reserved(key) | Token::Identifier(key) => { - match state.engine.custom_syntax.get_key_value(key.as_str()) { - Some((key, syntax)) => { - input.next().expect(NEVER_ENDS); - return parse_custom_syntax( - input, state, lib, settings, key, syntax, token_pos, - ); - } - _ => (), + if let Some((key, syntax)) = state.engine.custom_syntax.get_key_value(key.as_str()) + { + input.next().expect(NEVER_ENDS); + return parse_custom_syntax( + input, state, lib, settings, key, syntax, token_pos, + ); } } _ => (), @@ -2385,9 +2383,21 @@ fn parse_let( match var_type { // let name = expr - AccessMode::ReadWrite => Ok(Stmt::Let(expr, var_def.into(), export, settings.pos)), + AccessMode::ReadWrite => Ok(Stmt::Var( + expr, + var_def.into(), + VarDeclaration::Let, + export, + settings.pos, + )), // const name = { expr:constant } - AccessMode::ReadOnly => Ok(Stmt::Const(expr, var_def.into(), export, settings.pos)), + AccessMode::ReadOnly => Ok(Stmt::Var( + expr, + var_def.into(), + VarDeclaration::Const, + export, + settings.pos, + )), } } diff --git a/src/serde/de.rs b/src/serde/de.rs index 48e7a15f..36c27e07 100644 --- a/src/serde/de.rs +++ b/src/serde/de.rs @@ -33,12 +33,10 @@ impl<'de> DynamicDeserializer<'de> { Self { value } } /// Shortcut for a type conversion error. - #[must_use] fn type_error(&self) -> Result> { self.type_error_str(type_name::()) } /// Shortcut for a type conversion error. - #[must_use] fn type_error_str(&self, error: &str) -> Result> { EvalAltResult::ErrorMismatchOutputType( error.into(), @@ -47,7 +45,6 @@ impl<'de> DynamicDeserializer<'de> { ) .into() } - #[must_use] fn deserialize_int>( &mut self, v: crate::INT, @@ -111,7 +108,6 @@ impl<'de> DynamicDeserializer<'de> { /// # Ok(()) /// # } /// ``` -#[must_use] pub fn from_dynamic<'de, T: Deserialize<'de>>( value: &'de Dynamic, ) -> Result> { diff --git a/src/serde/deserialize.rs b/src/serde/deserialize.rs index b3cf6098..78bc91b6 100644 --- a/src/serde/deserialize.rs +++ b/src/serde/deserialize.rs @@ -40,12 +40,14 @@ impl<'d> Visitor<'d> for DynamicVisitor { } fn visit_i64(self, v: i64) -> Result { #[cfg(not(feature = "only_i32"))] - return Ok(v.into()); + { + Ok(v.into()) + } #[cfg(feature = "only_i32")] if v > i32::MAX as i64 { - return Ok(Dynamic::from(v)); + Ok(Dynamic::from(v)) } else { - return self.visit_i32(v as i32); + self.visit_i32(v as i32) } } fn visit_u8(self, v: u8) -> Result { @@ -56,26 +58,28 @@ impl<'d> Visitor<'d> for DynamicVisitor { } fn visit_u32(self, v: u32) -> Result { #[cfg(not(feature = "only_i32"))] - return Ok(INT::from(v).into()); + { + Ok(INT::from(v).into()) + } #[cfg(feature = "only_i32")] if v > i32::MAX as u32 { - return Ok(Dynamic::from(v)); + Ok(Dynamic::from(v)) } else { - return self.visit_i32(v as i32); + self.visit_i32(v as i32) } } fn visit_u64(self, v: u64) -> Result { #[cfg(not(feature = "only_i32"))] if v > i64::MAX as u64 { - return Ok(Dynamic::from(v)); + Ok(Dynamic::from(v)) } else { - return self.visit_i64(v as i64); + self.visit_i64(v as i64) } #[cfg(feature = "only_i32")] if v > i32::MAX as u64 { - return Ok(Dynamic::from(v)); + Ok(Dynamic::from(v)) } else { - return self.visit_i32(v as i32); + self.visit_i32(v as i32) } } diff --git a/src/serde/metadata.rs b/src/serde/metadata.rs index 31e04aee..9c7655f3 100644 --- a/src/serde/metadata.rs +++ b/src/serde/metadata.rs @@ -43,7 +43,7 @@ impl From for FnAccess { } } -#[derive(Debug, Clone, Eq, PartialEq, Ord, Hash, Serialize, Deserialize)] +#[derive(Debug, Clone, Eq, PartialEq, Hash, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] struct FnParam { pub name: String, @@ -71,6 +71,15 @@ impl PartialOrd for FnParam { } } +impl Ord for FnParam { + fn cmp(&self, other: &Self) -> Ordering { + match self.name.cmp(&other.name) { + Ordering::Equal => self.typ.cmp(&other.typ), + cmp => cmp, + } + } +} + #[derive(Debug, Clone, Eq, PartialEq, Hash, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] struct FnMetadata { @@ -128,7 +137,7 @@ impl From<&crate::module::FuncInfo> for FnMetadata { let name = seg .next() .map(|s| s.trim().to_string()) - .unwrap_or("_".to_string()); + .unwrap_or_else(|| "_".to_string()); let typ = seg.next().map(|s| s.trim().to_string()); FnParam { name, typ } }) @@ -209,7 +218,7 @@ impl From<&crate::Module> for ModuleMetadata { #[cfg(feature = "metadata")] impl Engine { - /// _(METADATA)_ Generate a list of all functions (including those defined in an + /// _(metadata)_ Generate a list of all functions (including those defined in an /// [`AST`][crate::AST]) in JSON format. /// Exported under the `metadata` feature only. /// @@ -218,7 +227,6 @@ impl Engine { /// 2) Functions registered into the global namespace /// 3) Functions in static modules /// 4) Functions in global modules (optional) - #[must_use] pub fn gen_fn_metadata_with_ast_to_json( &self, ast: &AST, @@ -258,7 +266,6 @@ impl Engine { /// 1) Functions registered into the global namespace /// 2) Functions in static modules /// 3) Functions in global modules (optional) - #[must_use] pub fn gen_fn_metadata_to_json(&self, include_global: bool) -> serde_json::Result { self.gen_fn_metadata_with_ast_to_json(&Default::default(), include_global) } diff --git a/src/serde/mod.rs b/src/serde/mod.rs index a3819556..f391d694 100644 --- a/src/serde/mod.rs +++ b/src/serde/mod.rs @@ -1,4 +1,4 @@ -//! _(SERDE)_ Serialization and deserialization support for [`serde`](https://crates.io/crates/serde). +//! _(serde)_ Serialization and deserialization support for [`serde`](https://crates.io/crates/serde). //! Exported under the `serde` feature only. mod de; diff --git a/src/serde/ser.rs b/src/serde/ser.rs index 79483c06..c4b7d56f 100644 --- a/src/serde/ser.rs +++ b/src/serde/ser.rs @@ -82,7 +82,6 @@ impl DynamicSerializer { /// # Ok(()) /// # } /// ``` -#[must_use] pub fn to_dynamic(value: T) -> RhaiResult { let mut s = DynamicSerializer::new(Default::default()); value.serialize(&mut s) @@ -138,27 +137,29 @@ impl Serializer for &mut DynamicSerializer { fn serialize_i64(self, v: i64) -> Result> { #[cfg(not(feature = "only_i32"))] - return Ok(v.into()); + { + Ok(v.into()) + } #[cfg(feature = "only_i32")] if v > i32::MAX as i64 { - return Ok(Dynamic::from(v)); + Ok(Dynamic::from(v)) } else { - return self.serialize_i32(v as i32); + self.serialize_i32(v as i32) } } fn serialize_i128(self, v: i128) -> Result> { #[cfg(not(feature = "only_i32"))] if v > i64::MAX as i128 { - return Ok(Dynamic::from(v)); + Ok(Dynamic::from(v)) } else { - return self.serialize_i64(v as i64); + self.serialize_i64(v as i64) } #[cfg(feature = "only_i32")] if v > i32::MAX as i128 { - return Ok(Dynamic::from(v)); + Ok(Dynamic::from(v)) } else { - return self.serialize_i32(v as i32); + self.serialize_i32(v as i32) } } @@ -178,42 +179,44 @@ impl Serializer for &mut DynamicSerializer { fn serialize_u32(self, v: u32) -> Result> { #[cfg(not(feature = "only_i32"))] - return self.serialize_i64(i64::from(v)); + { + self.serialize_i64(i64::from(v)) + } #[cfg(feature = "only_i32")] if v > i32::MAX as u32 { - return Ok(Dynamic::from(v)); + Ok(Dynamic::from(v)) } else { - return self.serialize_i32(v as i32); + self.serialize_i32(v as i32) } } fn serialize_u64(self, v: u64) -> Result> { #[cfg(not(feature = "only_i32"))] if v > i64::MAX as u64 { - return Ok(Dynamic::from(v)); + Ok(Dynamic::from(v)) } else { - return self.serialize_i64(v as i64); + self.serialize_i64(v as i64) } #[cfg(feature = "only_i32")] if v > i32::MAX as u64 { - return Ok(Dynamic::from(v)); + Ok(Dynamic::from(v)) } else { - return self.serialize_i32(v as i32); + self.serialize_i32(v as i32) } } fn serialize_u128(self, v: u128) -> Result> { #[cfg(not(feature = "only_i32"))] if v > i64::MAX as u128 { - return Ok(Dynamic::from(v)); + Ok(Dynamic::from(v)) } else { - return self.serialize_i64(v as i64); + self.serialize_i64(v as i64) } #[cfg(feature = "only_i32")] if v > i32::MAX as u128 { - return Ok(Dynamic::from(v)); + Ok(Dynamic::from(v)) } else { - return self.serialize_i32(v as i32); + self.serialize_i32(v as i32) } } diff --git a/src/serde/str.rs b/src/serde/str.rs index 5a275d90..81e90f8b 100644 --- a/src/serde/str.rs +++ b/src/serde/str.rs @@ -18,7 +18,6 @@ impl<'a> StringSliceDeserializer<'a> { Self { value } } /// Shortcut for a type conversion error. - #[must_use] fn type_error(&self) -> Result> { EvalAltResult::ErrorMismatchOutputType( type_name::().into(), diff --git a/src/token.rs b/src/token.rs index 4dcaec9a..cc425efd 100644 --- a/src/token.rs +++ b/src/token.rs @@ -27,7 +27,7 @@ use rust_decimal::Decimal; #[cfg(not(feature = "no_function"))] use crate::engine::KEYWORD_IS_DEF_FN; -/// _(INTERNALS)_ A type containing commands to control the tokenizer. +/// _(internals)_ A type containing commands to control the tokenizer. #[derive(Debug, Clone, Eq, PartialEq, Hash, Copy, Default)] pub struct TokenizerControlBlock { /// Is the current tokenizer position within an interpolated text string? @@ -35,7 +35,7 @@ pub struct TokenizerControlBlock { pub is_within_text: bool, } -/// _(INTERNALS)_ A shared object that allows control of the tokenizer from outside. +/// _(internals)_ A shared object that allows control of the tokenizer from outside. pub type TokenizerControl = Rc>; type LERR = LexError; @@ -283,7 +283,7 @@ impl AddAssign for Position { } } -/// _(INTERNALS)_ A Rhai language token. +/// _(internals)_ A Rhai language token. /// Exported under the `internals` feature only. /// /// # Volatile Data Structure @@ -980,7 +980,7 @@ impl From for String { } } -/// _(INTERNALS)_ State of the tokenizer. +/// _(internals)_ State of the tokenizer. /// Exported under the `internals` feature only. /// /// # Volatile Data Structure @@ -1000,7 +1000,7 @@ pub struct TokenizeState { pub is_within_text_terminated_by: Option, } -/// _(INTERNALS)_ Trait that encapsulates a peekable character input stream. +/// _(internals)_ Trait that encapsulates a peekable character input stream. /// Exported under the `internals` feature only. /// /// # Volatile Data Structure @@ -1018,7 +1018,7 @@ pub trait InputStream { fn peek_next(&mut self) -> Option; } -/// _(INTERNALS)_ Parse a string literal ended by `termination_char`. +/// _(internals)_ Parse a string literal ended by `termination_char`. /// Exported under the `internals` feature only. /// /// Returns the parsed string and a boolean indicating whether the string is @@ -1281,22 +1281,22 @@ fn scan_block_comment( match c { '/' => { - stream.peek_next().filter(|&c2| c2 == '*').map(|c2| { + if let Some(c2) = stream.peek_next().filter(|&c2| c2 == '*') { eat_next(stream, pos); if let Some(comment) = comment.as_mut() { comment.push(c2); } level += 1; - }); + } } '*' => { - stream.peek_next().filter(|&c2| c2 == '/').map(|c2| { + if let Some(c2) = stream.peek_next().filter(|&c2| c2 == '/') { eat_next(stream, pos); if let Some(comment) = comment.as_mut() { comment.push(c2); } level -= 1; - }); + } } '\n' => pos.new_line(), _ => (), @@ -1310,7 +1310,7 @@ fn scan_block_comment( level } -/// _(INTERNALS)_ Get the next token from the `stream`. +/// _(internals)_ Get the next token from the `stream`. /// Exported under the `internals` feature only. /// /// # Volatile API @@ -2234,7 +2234,7 @@ impl<'a> Iterator for TokenIterator<'a> { impl FusedIterator for TokenIterator<'_> {} impl Engine { - /// _(INTERNALS)_ Tokenize an input text stream. + /// _(internals)_ Tokenize an input text stream. /// Exported under the `internals` feature only. #[cfg(feature = "internals")] #[inline(always)] @@ -2245,7 +2245,7 @@ impl Engine { ) -> (TokenIterator<'a>, TokenizerControl) { self.lex_raw(input, None) } - /// _(INTERNALS)_ Tokenize an input text stream with a mapping function. + /// _(internals)_ Tokenize an input text stream with a mapping function. /// Exported under the `internals` feature only. #[cfg(feature = "internals")] #[inline(always)] diff --git a/tests/optimizer.rs b/tests/optimizer.rs index ac2d5f7f..8f64d7a2 100644 --- a/tests/optimizer.rs +++ b/tests/optimizer.rs @@ -86,7 +86,7 @@ fn test_optimizer_parse() -> Result<(), Box> { assert_eq!( format!("{:?}", ast), - r#"AST { source: None, body: Block[Const(false @ 1:18, "DECISION" @ 1:7, false, 1:1), Expr(123 @ 1:51)], functions: Module, resolver: None }"# + r#"AST { source: None, body: Block[Var(false @ 1:18, "DECISION" @ 1:7, Const, false, 1:1), Expr(123 @ 1:51)], functions: Module, resolver: None }"# ); let ast = engine.compile("if 1 == 2 { 42 }")?;