From 1e4abd012c052a362fc2753a981e55c0ad90d3b2 Mon Sep 17 00:00:00 2001 From: Stephen Chung Date: Wed, 9 Mar 2022 09:25:55 +0800 Subject: [PATCH] Minor refactor. --- src/api/register.rs | 2 +- src/ast/flags.rs | 10 +++++----- src/ast/stmt.rs | 2 +- src/eval/chaining.rs | 28 ++++++++++++---------------- src/lib.rs | 16 ++++++++++++++++ src/optimizer.rs | 8 ++++---- src/packages/bit_field.rs | 33 ++++++++++++++++----------------- src/packages/blob_basic.rs | 9 ++------- src/packages/iter_basic.rs | 12 +++++------- src/packages/time_basic.rs | 10 ++++++++++ tests/blobs.rs | 30 ++++++++++++++---------------- 11 files changed, 86 insertions(+), 74 deletions(-) diff --git a/src/api/register.rs b/src/api/register.rs index acd35914..72720c7a 100644 --- a/src/api/register.rs +++ b/src/api/register.rs @@ -293,7 +293,7 @@ impl Engine { self } /// Register an type iterator for an iterable type with the [`Engine`]. - /// This is an advanced feature. + /// This is an advanced API. #[inline(always)] pub fn register_iterator(&mut self) -> &mut Self where diff --git a/src/ast/flags.rs b/src/ast/flags.rs index 264a6374..6d2506ba 100644 --- a/src/ast/flags.rs +++ b/src/ast/flags.rs @@ -18,14 +18,14 @@ bitflags! { /// Exported under the `internals` feature only. pub struct ASTFlags: u8 { /// No options for the [`AST`][crate::AST] node. - const NONE = 0b0000_0000; + const NONE = 0b_0000_0000; /// The [`AST`][crate::AST] node is read-only. - const CONSTANT = 0b0000_0001; + const CONSTANT = 0b_0000_0001; /// The [`AST`][crate::AST] node is exposed to the outside (i.e. public). - const EXPORTED = 0b0000_0010; + const EXPORTED = 0b_0000_0010; /// The [`AST`][crate::AST] node is negated (i.e. whatever information is the opposite). - const NEGATED = 0b0000_0100; + const NEGATED = 0b_0000_0100; /// The [`AST`][crate::AST] node breaks out of normal control flow. - const BREAK = 0b0000_1000; + const BREAK = 0b_0000_1000; } } diff --git a/src/ast/stmt.rs b/src/ast/stmt.rs index 9ef68e10..815c0f8b 100644 --- a/src/ast/stmt.rs +++ b/src/ast/stmt.rs @@ -621,7 +621,7 @@ impl Stmt { /// upper block. /// /// Currently only variable definitions (i.e. `let` and `const`), `import`/`export` statements, - /// and `eval` calls (which may in turn call define variables) fall under this category. + /// and `eval` calls (which may in turn define variables) fall under this category. #[inline] #[must_use] pub fn is_block_dependent(&self) -> bool { diff --git a/src/eval/chaining.rs b/src/eval/chaining.rs index ad055595..3cb2076a 100644 --- a/src/eval/chaining.rs +++ b/src/eval/chaining.rs @@ -922,22 +922,20 @@ impl Engine { if idx.is::() || idx.is::() => { // val_int[range] - const BITS: usize = std::mem::size_of::() * 8; - let (shift, mask) = if let Some(range) = idx.read_lock::() { let start = range.start; let end = range.end; - let start = super::calc_index(BITS, start, false, || { - ERR::ErrorBitFieldBounds(BITS, start, idx_pos).into() + let start = super::calc_index(crate::INT_BITS, start, false, || { + ERR::ErrorBitFieldBounds(crate::INT_BITS, start, idx_pos).into() })?; - let end = super::calc_index(BITS, end, false, || { - ERR::ErrorBitFieldBounds(BITS, end, idx_pos).into() + let end = super::calc_index(crate::INT_BITS, end, false, || { + ERR::ErrorBitFieldBounds(crate::INT_BITS, end, idx_pos).into() })?; if end <= start { (0, 0) - } else if end == BITS && start == 0 { + } else if end == crate::INT_BITS && start == 0 { // -1 = all bits set (0, -1) } else { @@ -953,16 +951,16 @@ impl Engine { let start = *range.start(); let end = *range.end(); - let start = super::calc_index(BITS, start, false, || { - ERR::ErrorBitFieldBounds(BITS, start, idx_pos).into() + let start = super::calc_index(crate::INT_BITS, start, false, || { + ERR::ErrorBitFieldBounds(crate::INT_BITS, start, idx_pos).into() })?; - let end = super::calc_index(BITS, end, false, || { - ERR::ErrorBitFieldBounds(BITS, end, idx_pos).into() + let end = super::calc_index(crate::INT_BITS, end, false, || { + ERR::ErrorBitFieldBounds(crate::INT_BITS, end, idx_pos).into() })?; if end < start { (0, 0) - } else if end == BITS - 1 && start == 0 { + } else if end == crate::INT_BITS - 1 && start == 0 { // -1 = all bits set (0, -1) } else { @@ -995,10 +993,8 @@ impl Engine { .as_int() .map_err(|typ| self.make_type_mismatch_err::(typ, idx_pos))?; - const BITS: usize = std::mem::size_of::() * 8; - - let bit = super::calc_index(BITS, index, true, || { - ERR::ErrorBitFieldBounds(BITS, index, idx_pos).into() + let bit = super::calc_index(crate::INT_BITS, index, true, || { + ERR::ErrorBitFieldBounds(crate::INT_BITS, index, idx_pos).into() })?; let bit_value = (*value & (1 << bit)) != 0; diff --git a/src/lib.rs b/src/lib.rs index 39a4fef5..5e6c444a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -121,6 +121,16 @@ type UNSIGNED_INT = u64; #[allow(non_camel_case_types)] type UNSIGNED_INT = u32; +/// Number of bits in [`INT`]. +/// +/// It is 64 unless the `only_i32` feature is enabled when it will be 32. +const INT_BITS: usize = std::mem::size_of::() * 8; + +/// Number of bytes that make up an [`INT`]. +/// +/// It is 8 unless the `only_i32` feature is enabled when it will be 4. +const INT_BYTES: usize = std::mem::size_of::(); + /// The system floating-point type. It is defined as [`f64`]. /// /// Not available under `no_float`. @@ -140,6 +150,12 @@ pub type FLOAT = f64; #[cfg(feature = "f32_float")] pub type FLOAT = f32; +/// Number of bytes that make up a [`FLOAT`]. +/// +/// It is 8 unless the `f32_float` feature is enabled when it will be 4. +#[cfg(not(feature = "no_float"))] +const FLOAT_BYTES: usize = std::mem::size_of::(); + /// An exclusive integer range. type ExclusiveRange = std::ops::Range; diff --git a/src/optimizer.rs b/src/optimizer.rs index 579b8eec..a8fa2e4c 100644 --- a/src/optimizer.rs +++ b/src/optimizer.rs @@ -10,7 +10,7 @@ use crate::tokenizer::{Span, Token}; use crate::types::dynamic::AccessMode; use crate::{ calc_fn_hash, calc_fn_params_hash, combine_hashes, Dynamic, Engine, FnPtr, Position, Scope, - StaticVec, AST, INT, + StaticVec, AST, INT, INT_BITS, }; #[cfg(feature = "no_std")] use std::prelude::v1::*; @@ -940,16 +940,16 @@ fn optimize_expr(expr: &mut Expr, state: &mut OptimizerState, chaining: bool) { .unwrap_or_else(|| Expr::Unit(*pos)); } // int[int] - (Expr::IntegerConstant(n, pos), Expr::IntegerConstant(i, ..)) if *i >= 0 && (*i as usize) < (std::mem::size_of_val(n) * 8) => { + (Expr::IntegerConstant(n, pos), Expr::IntegerConstant(i, ..)) if *i >= 0 && (*i as usize) < INT_BITS => { // Bit-field literal indexing - get the bit state.set_dirty(); *expr = Expr::BoolConstant((*n & (1 << (*i as usize))) != 0, *pos); } // int[-int] - (Expr::IntegerConstant(n, pos), Expr::IntegerConstant(i, ..)) if *i < 0 && i.checked_abs().map(|i| i as usize <= (std::mem::size_of_val(n) * 8)).unwrap_or(false) => { + (Expr::IntegerConstant(n, pos), Expr::IntegerConstant(i, ..)) if *i < 0 && i.checked_abs().map(|i| i as usize <= INT_BITS).unwrap_or(false) => { // Bit-field literal indexing - get the bit state.set_dirty(); - *expr = Expr::BoolConstant((*n & (1 << (std::mem::size_of_val(n) * 8 - i.abs() as usize))) != 0, *pos); + *expr = Expr::BoolConstant((*n & (1 << (INT_BITS - i.abs() as usize))) != 0, *pos); } // string[int] (Expr::StringConstant(s, pos), Expr::IntegerConstant(i, ..)) if *i >= 0 && (*i as usize) < s.chars().count() => { diff --git a/src/packages/bit_field.rs b/src/packages/bit_field.rs index 55b4ad40..5deb09ce 100644 --- a/src/packages/bit_field.rs +++ b/src/packages/bit_field.rs @@ -1,7 +1,8 @@ use crate::eval::calc_index; use crate::plugin::*; use crate::{ - def_package, ExclusiveRange, InclusiveRange, Position, RhaiResultOf, ERR, INT, UNSIGNED_INT, + def_package, ExclusiveRange, InclusiveRange, Position, RhaiResultOf, ERR, INT, INT_BITS, + UNSIGNED_INT, }; #[cfg(feature = "no_std")] use std::prelude::v1::*; @@ -17,8 +18,6 @@ def_package! { #[export_module] mod bit_field_functions { - const BITS: usize = std::mem::size_of::() * 8; - /// Return `true` if the specified `bit` in the number is set. /// /// If `bit` < 0, position counts from the MSB (Most Significant Bit). @@ -36,8 +35,8 @@ mod bit_field_functions { /// ``` #[rhai_fn(return_raw)] pub fn get_bit(value: INT, bit: INT) -> RhaiResultOf { - let bit = calc_index(BITS, bit, true, || { - ERR::ErrorBitFieldBounds(BITS, bit, Position::NONE).into() + let bit = calc_index(INT_BITS, bit, true, || { + ERR::ErrorBitFieldBounds(INT_BITS, bit, Position::NONE).into() })?; Ok((value & (1 << bit)) != 0) @@ -66,8 +65,8 @@ mod bit_field_functions { /// ``` #[rhai_fn(return_raw)] pub fn set_bit(value: &mut INT, bit: INT, new_value: bool) -> RhaiResultOf<()> { - let bit = calc_index(BITS, bit, true, || { - ERR::ErrorBitFieldBounds(BITS, bit, Position::NONE).into() + let bit = calc_index(INT_BITS, bit, true, || { + ERR::ErrorBitFieldBounds(INT_BITS, bit, Position::NONE).into() })?; let mask = 1 << bit; @@ -128,17 +127,17 @@ mod bit_field_functions { return Ok(0); } - let bit = calc_index(BITS, start, true, || { - ERR::ErrorBitFieldBounds(BITS, start, Position::NONE).into() + let bit = calc_index(INT_BITS, start, true, || { + ERR::ErrorBitFieldBounds(INT_BITS, start, Position::NONE).into() })?; - let bits = if bit + bits as usize > BITS { - BITS - bit + let bits = if bit + bits as usize > INT_BITS { + INT_BITS - bit } else { bits as usize }; - if bit == 0 && bits == BITS { + if bit == 0 && bits == INT_BITS { return Ok(value); } @@ -214,17 +213,17 @@ mod bit_field_functions { return Ok(()); } - let bit = calc_index(BITS, bit, true, || { - ERR::ErrorBitFieldBounds(BITS, bit, Position::NONE).into() + let bit = calc_index(INT_BITS, bit, true, || { + ERR::ErrorBitFieldBounds(INT_BITS, bit, Position::NONE).into() })?; - let bits = if bit + bits as usize > BITS { - BITS - bit + let bits = if bit + bits as usize > INT_BITS { + INT_BITS - bit } else { bits as usize }; - if bit == 0 && bits == BITS { + if bit == 0 && bits == INT_BITS { *value = new_value; return Ok(()); } diff --git a/src/packages/blob_basic.rs b/src/packages/blob_basic.rs index 2a21b0d2..92a5b684 100644 --- a/src/packages/blob_basic.rs +++ b/src/packages/blob_basic.rs @@ -4,19 +4,14 @@ use crate::eval::{calc_index, calc_offset_len}; use crate::plugin::*; use crate::{ def_package, Array, Blob, Dynamic, ExclusiveRange, InclusiveRange, NativeCallContext, Position, - RhaiResultOf, INT, + RhaiResultOf, INT, INT_BYTES, }; #[cfg(feature = "no_std")] use std::prelude::v1::*; use std::{any::TypeId, mem}; #[cfg(not(feature = "no_float"))] -use crate::FLOAT; - -const INT_BYTES: usize = mem::size_of::(); - -#[cfg(not(feature = "no_float"))] -const FLOAT_BYTES: usize = mem::size_of::(); +use crate::{FLOAT, FLOAT_BYTES}; def_package! { /// Package of basic BLOB utilities. diff --git a/src/packages/iter_basic.rs b/src/packages/iter_basic.rs index bcf50691..95ccdf7a 100644 --- a/src/packages/iter_basic.rs +++ b/src/packages/iter_basic.rs @@ -1,7 +1,7 @@ use crate::eval::calc_index; use crate::plugin::*; use crate::types::dynamic::Variant; -use crate::{def_package, ExclusiveRange, InclusiveRange, RhaiResultOf, INT}; +use crate::{def_package, ExclusiveRange, InclusiveRange, RhaiResultOf, INT, INT_BITS}; #[cfg(feature = "no_std")] use std::prelude::v1::*; use std::{ @@ -117,18 +117,16 @@ impl FusedIterator for StepRange where #[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)] struct BitRange(INT, INT, usize); -const BITS: usize = std::mem::size_of::() * 8; - impl BitRange { pub fn new(value: INT, from: INT, len: INT) -> RhaiResultOf { - let from = calc_index(BITS, from, true, || { - crate::ERR::ErrorBitFieldBounds(BITS, from, Position::NONE).into() + let from = calc_index(INT_BITS, from, true, || { + crate::ERR::ErrorBitFieldBounds(INT_BITS, from, Position::NONE).into() })?; let len = if len < 0 { 0 - } else if from + (len as usize) > BITS { - BITS - from + } else if from + (len as usize) > INT_BITS { + INT_BITS - from } else { len as usize }; diff --git a/src/packages/time_basic.rs b/src/packages/time_basic.rs index b631a59d..4f51f8fe 100644 --- a/src/packages/time_basic.rs +++ b/src/packages/time_basic.rs @@ -31,6 +31,16 @@ mod time_functions { } /// Return the number of seconds between the current system time and the timestamp. + /// + /// # Example + /// + /// ```rhai + /// let now = timestamp(); + /// + /// sleep(10.0); // sleep for 10 seconds + /// + /// print(now.elapsed); // prints 10.??? + /// ``` #[rhai_fn(name = "elapsed", get = "elapsed", return_raw)] pub fn elapsed(timestamp: Instant) -> RhaiResult { #[cfg(not(feature = "no_float"))] diff --git a/tests/blobs.rs b/tests/blobs.rs index 5653e1ef..d961563f 100644 --- a/tests/blobs.rs +++ b/tests/blobs.rs @@ -9,66 +9,64 @@ fn test_blobs() -> Result<(), Box> { a.push(3); let engine = Engine::new(); - let mut orig_scope = Scope::new(); - orig_scope.push("x", a); - - let mut scope = orig_scope.clone(); + let mut scope = Scope::new(); + scope.push("x", a); assert_eq!(engine.eval_with_scope::(&mut scope, "x[1]")?, 2); assert_eq!(engine.eval_with_scope::(&mut scope, "x[0]")?, 1); assert_eq!(engine.eval_with_scope::(&mut scope, "x[-1]")?, 3); assert_eq!(engine.eval_with_scope::(&mut scope, "x[-3]")?, 1); assert_eq!( - engine.eval_with_scope::(&mut scope, "x += 4; x[3]")?, + engine.eval_with_scope::(&mut scope.clone(), "x += 4; x[3]")?, 4 ); #[cfg(not(feature = "no_object"))] { assert_eq!( - engine.eval_with_scope::(&mut orig_scope.clone(), "x.push(4); x")?, + engine.eval_with_scope::(&mut scope.clone(), "x.push(4); x")?, [1, 2, 3, 4] ); assert_eq!( - engine.eval_with_scope::(&mut orig_scope.clone(), "x.insert(0, 4); x")?, + engine.eval_with_scope::(&mut scope.clone(), "x.insert(0, 4); x")?, [4, 1, 2, 3] ); assert_eq!( - engine.eval_with_scope::(&mut orig_scope.clone(), "x.insert(999, 4); x")?, + engine.eval_with_scope::(&mut scope.clone(), "x.insert(999, 4); x")?, [1, 2, 3, 4] ); assert_eq!( - engine.eval_with_scope::(&mut orig_scope.clone(), "x.insert(-2, 4); x")?, + engine.eval_with_scope::(&mut scope.clone(), "x.insert(-2, 4); x")?, [1, 4, 2, 3] ); assert_eq!( - engine.eval_with_scope::(&mut orig_scope.clone(), "x.insert(-999, 4); x")?, + engine.eval_with_scope::(&mut scope.clone(), "x.insert(-999, 4); x")?, [4, 1, 2, 3] ); assert_eq!( - engine.eval_with_scope::(&mut orig_scope.clone(), "let z = [42]; x[z.len]")?, + engine.eval_with_scope::(&mut scope.clone(), "let z = [42]; x[z.len]")?, 2 ); assert_eq!( - engine.eval_with_scope::(&mut orig_scope.clone(), "let z = [2]; x[z[0]]")?, + engine.eval_with_scope::(&mut scope.clone(), "let z = [2]; x[z[0]]")?, 3 ); } assert_eq!( - engine.eval_with_scope::(&mut orig_scope.clone(), "x += x; x")?, + engine.eval_with_scope::(&mut scope.clone(), "x += x; x")?, [1, 2, 3, 1, 2, 3] ); assert_eq!( - engine.eval_with_scope::(&mut orig_scope.clone(), "x + x")?, + engine.eval_with_scope::(&mut scope.clone(), "x + x")?, [1, 2, 3, 1, 2, 3] ); assert_eq!( - engine.eval_with_scope::(&mut orig_scope.clone(), "x += 999; x")?, + engine.eval_with_scope::(&mut scope.clone(), "x += 999; x")?, [1, 2, 3, 0xe7] ); assert_eq!( - engine.eval_with_scope::(&mut orig_scope.clone(), "x[2] = 999; x")?, + engine.eval_with_scope::(&mut scope.clone(), "x[2] = 999; x")?, [1, 2, 0xe7] );