Move HashableHashMap to utils.
This commit is contained in:
parent
d5891d4802
commit
3fbcefe0ed
60
src/ast.rs
60
src/ast.rs
@ -6,7 +6,6 @@ use crate::module::NamespaceRef;
|
|||||||
use crate::stdlib::{
|
use crate::stdlib::{
|
||||||
borrow::Cow,
|
borrow::Cow,
|
||||||
boxed::Box,
|
boxed::Box,
|
||||||
collections::HashMap,
|
|
||||||
fmt,
|
fmt,
|
||||||
hash::{Hash, Hasher},
|
hash::{Hash, Hasher},
|
||||||
num::{NonZeroU64, NonZeroUsize},
|
num::{NonZeroU64, NonZeroUsize},
|
||||||
@ -16,7 +15,7 @@ use crate::stdlib::{
|
|||||||
vec::Vec,
|
vec::Vec,
|
||||||
};
|
};
|
||||||
use crate::token::Token;
|
use crate::token::Token;
|
||||||
use crate::utils::StraightHasherBuilder;
|
use crate::utils::{HashableHashMap, StraightHasherBuilder};
|
||||||
use crate::{
|
use crate::{
|
||||||
Dynamic, FnNamespace, FnPtr, ImmutableString, Module, Position, Shared, StaticVec, INT,
|
Dynamic, FnNamespace, FnPtr, ImmutableString, Module, Position, Shared, StaticVec, INT,
|
||||||
};
|
};
|
||||||
@ -691,54 +690,6 @@ pub enum ReturnType {
|
|||||||
Exception,
|
Exception,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A type that wraps a [`HashMap`]`<u64, Stmt>` for the `switch` statement and implements [`Hash`].
|
|
||||||
#[derive(Clone)]
|
|
||||||
pub struct SwitchHashWrapper(HashMap<u64, Stmt, StraightHasherBuilder>);
|
|
||||||
|
|
||||||
impl From<HashMap<u64, Stmt, StraightHasherBuilder>> for SwitchHashWrapper {
|
|
||||||
fn from(value: HashMap<u64, Stmt, StraightHasherBuilder>) -> Self {
|
|
||||||
Self(value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl AsRef<HashMap<u64, Stmt, StraightHasherBuilder>> for SwitchHashWrapper {
|
|
||||||
fn as_ref(&self) -> &HashMap<u64, Stmt, StraightHasherBuilder> {
|
|
||||||
&self.0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl AsMut<HashMap<u64, Stmt, StraightHasherBuilder>> for SwitchHashWrapper {
|
|
||||||
fn as_mut(&mut self) -> &mut HashMap<u64, Stmt, StraightHasherBuilder> {
|
|
||||||
&mut self.0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl Deref for SwitchHashWrapper {
|
|
||||||
type Target = HashMap<u64, Stmt, StraightHasherBuilder>;
|
|
||||||
|
|
||||||
fn deref(&self) -> &Self::Target {
|
|
||||||
&self.0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl DerefMut for SwitchHashWrapper {
|
|
||||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
|
||||||
&mut self.0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl fmt::Debug for SwitchHashWrapper {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
||||||
self.0.fmt(f)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl Hash for SwitchHashWrapper {
|
|
||||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
|
||||||
let mut keys: Vec<_> = self.0.keys().collect();
|
|
||||||
keys.sort();
|
|
||||||
|
|
||||||
keys.into_iter().for_each(|key| {
|
|
||||||
key.hash(state);
|
|
||||||
self.0.get(&key).unwrap().hash(state);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// _(INTERNALS)_ A statement.
|
/// _(INTERNALS)_ A statement.
|
||||||
/// Exported under the `internals` feature only.
|
/// Exported under the `internals` feature only.
|
||||||
///
|
///
|
||||||
@ -752,7 +703,14 @@ pub enum Stmt {
|
|||||||
/// `if` expr `{` stmt `}` `else` `{` stmt `}`
|
/// `if` expr `{` stmt `}` `else` `{` stmt `}`
|
||||||
If(Expr, Box<(Stmt, Option<Stmt>)>, Position),
|
If(Expr, Box<(Stmt, Option<Stmt>)>, Position),
|
||||||
/// `switch` expr `{` literal or _ `=>` stmt `,` ... `}`
|
/// `switch` expr `{` literal or _ `=>` stmt `,` ... `}`
|
||||||
Switch(Expr, Box<(SwitchHashWrapper, Option<Stmt>)>, Position),
|
Switch(
|
||||||
|
Expr,
|
||||||
|
Box<(
|
||||||
|
HashableHashMap<u64, Stmt, StraightHasherBuilder>,
|
||||||
|
Option<Stmt>,
|
||||||
|
)>,
|
||||||
|
Position,
|
||||||
|
),
|
||||||
/// `while` expr `{` stmt `}`
|
/// `while` expr `{` stmt `}`
|
||||||
While(Expr, Box<Stmt>, Position),
|
While(Expr, Box<Stmt>, Position),
|
||||||
/// `do` `{` stmt `}` `while`|`until` expr
|
/// `do` `{` stmt `}` `while`|`until` expr
|
||||||
|
@ -184,8 +184,8 @@ pub use token::{get_next_token, parse_string_literal, InputStream, Token, Tokeni
|
|||||||
#[cfg(feature = "internals")]
|
#[cfg(feature = "internals")]
|
||||||
#[deprecated = "this type is volatile and may change"]
|
#[deprecated = "this type is volatile and may change"]
|
||||||
pub use ast::{
|
pub use ast::{
|
||||||
BinaryExpr, CustomExpr, Expr, FloatWrapper, FnCallExpr, Ident, ReturnType, ScriptFnDef, Stmt,
|
BinaryExpr, CustomExpr, Expr, FloatWrapper, FnCallExpr, HashableHashMap, Ident, ReturnType,
|
||||||
SwitchHashWrapper,
|
ScriptFnDef, Stmt,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[cfg(feature = "internals")]
|
#[cfg(feature = "internals")]
|
||||||
|
61
src/utils.rs
61
src/utils.rs
@ -6,11 +6,13 @@ use crate::stdlib::{
|
|||||||
borrow::Borrow,
|
borrow::Borrow,
|
||||||
boxed::Box,
|
boxed::Box,
|
||||||
cmp::Ordering,
|
cmp::Ordering,
|
||||||
|
collections::HashMap,
|
||||||
fmt,
|
fmt,
|
||||||
|
fmt::{Debug, Display},
|
||||||
hash::{BuildHasher, Hash, Hasher},
|
hash::{BuildHasher, Hash, Hasher},
|
||||||
iter::{empty, FromIterator},
|
iter::{empty, FromIterator},
|
||||||
num::NonZeroU64,
|
num::NonZeroU64,
|
||||||
ops::{Add, AddAssign, Deref},
|
ops::{Add, AddAssign, Deref, DerefMut},
|
||||||
str::FromStr,
|
str::FromStr,
|
||||||
string::{String, ToString},
|
string::{String, ToString},
|
||||||
};
|
};
|
||||||
@ -140,6 +142,55 @@ pub(crate) fn combine_hashes(a: NonZeroU64, b: NonZeroU64) -> NonZeroU64 {
|
|||||||
NonZeroU64::new(a.get() ^ b.get()).unwrap_or_else(|| NonZeroU64::new(42).unwrap())
|
NonZeroU64::new(a.get() ^ b.get()).unwrap_or_else(|| NonZeroU64::new(42).unwrap())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// _(INTERNALS)_ A type that wraps a [`HashMap`] and implements [`Hash`].
|
||||||
|
/// Exported under the `internals` feature only.
|
||||||
|
#[derive(Clone, Default)]
|
||||||
|
pub struct HashableHashMap<K, T, H: BuildHasher>(HashMap<K, T, H>);
|
||||||
|
|
||||||
|
impl<K, T, H: BuildHasher> From<HashMap<K, T, H>> for HashableHashMap<K, T, H> {
|
||||||
|
fn from(value: HashMap<K, T, H>) -> Self {
|
||||||
|
Self(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl<K, T, H: BuildHasher> AsRef<HashMap<K, T, H>> for HashableHashMap<K, T, H> {
|
||||||
|
fn as_ref(&self) -> &HashMap<K, T, H> {
|
||||||
|
&self.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl<K, T, H: BuildHasher> AsMut<HashMap<K, T, H>> for HashableHashMap<K, T, H> {
|
||||||
|
fn as_mut(&mut self) -> &mut HashMap<K, T, H> {
|
||||||
|
&mut self.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl<K, T, H: BuildHasher> Deref for HashableHashMap<K, T, H> {
|
||||||
|
type Target = HashMap<K, T, H>;
|
||||||
|
|
||||||
|
fn deref(&self) -> &Self::Target {
|
||||||
|
&self.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl<K, T, H: BuildHasher> DerefMut for HashableHashMap<K, T, H> {
|
||||||
|
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||||
|
&mut self.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl<K: Debug, T: Debug, H: BuildHasher> Debug for HashableHashMap<K, T, H> {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
self.0.fmt(f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl<K: Hash + Ord, T: Hash, H: BuildHasher> Hash for HashableHashMap<K, T, H> {
|
||||||
|
fn hash<B: Hasher>(&self, state: &mut B) {
|
||||||
|
let mut keys: Vec<_> = self.0.keys().collect();
|
||||||
|
keys.sort();
|
||||||
|
|
||||||
|
keys.into_iter().for_each(|key| {
|
||||||
|
key.hash(state);
|
||||||
|
self.0.get(&key).unwrap().hash(state);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// The system immutable string type.
|
/// The system immutable string type.
|
||||||
///
|
///
|
||||||
/// An [`ImmutableString`] wraps an [`Rc`][std::rc::Rc]`<`[`String`]`>`
|
/// An [`ImmutableString`] wraps an [`Rc`][std::rc::Rc]`<`[`String`]`>`
|
||||||
@ -276,17 +327,17 @@ impl<'a> FromIterator<String> for ImmutableString {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for ImmutableString {
|
impl Display for ImmutableString {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
fmt::Display::fmt(self.0.as_str(), f)
|
Display::fmt(self.0.as_str(), f)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Debug for ImmutableString {
|
impl Debug for ImmutableString {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
fmt::Debug::fmt(self.0.as_str(), f)
|
Debug::fmt(self.0.as_str(), f)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user