Use ImmutableString.
This commit is contained in:
parent
839da9c7f0
commit
bed29da71a
@ -618,9 +618,9 @@ pub enum Stmt {
|
||||
/// `for` id `in` expr `{` stmt `}`
|
||||
For(Expr, Box<(String, Stmt)>, Position),
|
||||
/// \[`export`\] `let` id `=` expr
|
||||
Let(Box<Ident>, Option<Expr>, bool, Position),
|
||||
Let(Box<IdentX>, Option<Expr>, bool, Position),
|
||||
/// \[`export`\] `const` id `=` expr
|
||||
Const(Box<Ident>, Option<Expr>, bool, Position),
|
||||
Const(Box<IdentX>, Option<Expr>, bool, Position),
|
||||
/// expr op`=` expr
|
||||
Assignment(Box<(Expr, Cow<'static, str>, Expr)>, Position),
|
||||
/// `{` stmt`;` ... `}`
|
||||
|
@ -2302,9 +2302,9 @@ impl Engine {
|
||||
};
|
||||
let (var_name, _alias): (Cow<'_, str>, _) = if state.is_global() {
|
||||
(
|
||||
var_def.name.clone().into(),
|
||||
var_def.name.to_string().into(),
|
||||
if *export {
|
||||
Some(var_def.name.to_string())
|
||||
Some(var_def.name.clone())
|
||||
} else {
|
||||
None
|
||||
},
|
||||
@ -2371,7 +2371,7 @@ impl Engine {
|
||||
// Mark scope variables as public
|
||||
if let Some(index) = scope.get_index(name).map(|(i, _)| i) {
|
||||
let alias = rename.as_ref().map(|x| &x.name).unwrap_or_else(|| name);
|
||||
scope.add_entry_alias(index, alias.to_string());
|
||||
scope.add_entry_alias(index, alias.clone());
|
||||
} else {
|
||||
return EvalAltResult::ErrorVariableNotFound(name.to_string(), *id_pos)
|
||||
.into();
|
||||
|
@ -120,9 +120,9 @@ impl FuncInfo {
|
||||
#[derive(Clone)]
|
||||
pub struct Module {
|
||||
/// Sub-modules.
|
||||
modules: HashMap<String, Shared<Module>>,
|
||||
modules: HashMap<ImmutableString, Shared<Module>>,
|
||||
/// Module variables.
|
||||
variables: HashMap<String, Dynamic>,
|
||||
variables: HashMap<ImmutableString, Dynamic>,
|
||||
/// Flattened collection of all module variables, including those in sub-modules.
|
||||
all_variables: HashMap<u64, Dynamic, StraightHasherBuilder>,
|
||||
/// External Rust functions.
|
||||
@ -160,7 +160,7 @@ impl fmt::Debug for Module {
|
||||
"Module(\n modules: {}\n vars: {}\n functions: {}\n)",
|
||||
self.modules
|
||||
.keys()
|
||||
.map(String::as_str)
|
||||
.map(|m| m.as_str())
|
||||
.collect::<Vec<_>>()
|
||||
.join(", "),
|
||||
self.variables
|
||||
@ -331,7 +331,11 @@ impl Module {
|
||||
/// assert_eq!(module.get_var_value::<i64>("answer").unwrap(), 42);
|
||||
/// ```
|
||||
#[inline(always)]
|
||||
pub fn set_var(&mut self, name: impl Into<String>, value: impl Variant + Clone) -> &mut Self {
|
||||
pub fn set_var(
|
||||
&mut self,
|
||||
name: impl Into<ImmutableString>,
|
||||
value: impl Variant + Clone,
|
||||
) -> &mut Self {
|
||||
self.variables.insert(name.into(), Dynamic::from(value));
|
||||
self.indexed = false;
|
||||
self
|
||||
@ -458,7 +462,7 @@ impl Module {
|
||||
#[inline(always)]
|
||||
pub fn set_sub_module(
|
||||
&mut self,
|
||||
name: impl Into<String>,
|
||||
name: impl Into<ImmutableString>,
|
||||
sub_module: impl Into<Shared<Module>>,
|
||||
) -> &mut Self {
|
||||
self.modules.insert(name.into(), sub_module.into());
|
||||
@ -1423,7 +1427,7 @@ impl Module {
|
||||
other.modules.iter().for_each(|(k, v)| {
|
||||
let mut m = Self::new();
|
||||
m.merge_filtered(v, _filter);
|
||||
self.set_sub_module(k, m);
|
||||
self.set_sub_module(k.clone(), m);
|
||||
});
|
||||
#[cfg(feature = "no_function")]
|
||||
self.modules
|
||||
|
@ -826,7 +826,7 @@ fn parse_switch(
|
||||
}
|
||||
}
|
||||
|
||||
let mut table = HashMap::with_capacity_and_hasher(16, StraightHasherBuilder);
|
||||
let mut table = HashMap::new();
|
||||
let mut def_stmt = None;
|
||||
|
||||
loop {
|
||||
@ -915,9 +915,12 @@ fn parse_switch(
|
||||
}
|
||||
}
|
||||
|
||||
let mut final_table = HashMap::with_capacity_and_hasher(table.len(), StraightHasherBuilder);
|
||||
final_table.extend(table.into_iter());
|
||||
|
||||
Ok(Stmt::Switch(
|
||||
item,
|
||||
Box::new((table, def_stmt)),
|
||||
Box::new((final_table, def_stmt)),
|
||||
settings.pos,
|
||||
))
|
||||
}
|
||||
@ -2158,14 +2161,14 @@ fn parse_let(
|
||||
AccessMode::ReadWrite => {
|
||||
let var_name = state.get_interned_string(name.clone());
|
||||
state.stack.push((var_name, AccessMode::ReadWrite));
|
||||
let var_def = Ident::new(name, pos);
|
||||
let var_def = IdentX::new(name, pos);
|
||||
Ok(Stmt::Let(Box::new(var_def), init_expr, export, token_pos))
|
||||
}
|
||||
// const name = { expr:constant }
|
||||
AccessMode::ReadOnly => {
|
||||
let var_name = state.get_interned_string(name.clone());
|
||||
state.stack.push((var_name, AccessMode::ReadOnly));
|
||||
let var_def = Ident::new(name, pos);
|
||||
let var_def = IdentX::new(name, pos);
|
||||
Ok(Stmt::Const(Box::new(var_def), init_expr, export, token_pos))
|
||||
}
|
||||
}
|
||||
|
20
src/scope.rs
20
src/scope.rs
@ -1,8 +1,8 @@
|
||||
//! Module that defines the [`Scope`] type representing a function call-stack scope.
|
||||
|
||||
use crate::dynamic::{AccessMode, Variant};
|
||||
use crate::stdlib::{borrow::Cow, boxed::Box, iter, string::String, vec::Vec};
|
||||
use crate::{Dynamic, StaticVec};
|
||||
use crate::stdlib::{borrow::Cow, boxed::Box, iter, vec::Vec};
|
||||
use crate::{Dynamic, ImmutableString, StaticVec};
|
||||
|
||||
/// Type containing information about the current scope.
|
||||
/// Useful for keeping state between [`Engine`][crate::Engine] evaluation runs.
|
||||
@ -50,7 +50,7 @@ pub struct Scope<'a> {
|
||||
/// Current value of the entry.
|
||||
values: Vec<Dynamic>,
|
||||
/// (Name, aliases) of the entry. The list of aliases is Boxed because it occurs rarely.
|
||||
names: Vec<(Cow<'a, str>, Box<StaticVec<String>>)>,
|
||||
names: Vec<(Cow<'a, str>, Box<StaticVec<ImmutableString>>)>,
|
||||
}
|
||||
|
||||
impl Default for Scope<'_> {
|
||||
@ -364,10 +364,14 @@ impl<'a> Scope<'a> {
|
||||
/// Update the access type of an entry in the [`Scope`].
|
||||
#[cfg(not(feature = "no_module"))]
|
||||
#[inline(always)]
|
||||
pub(crate) fn add_entry_alias(&mut self, index: usize, alias: String) -> &mut Self {
|
||||
pub(crate) fn add_entry_alias(
|
||||
&mut self,
|
||||
index: usize,
|
||||
alias: impl Into<ImmutableString> + PartialEq<ImmutableString>,
|
||||
) -> &mut Self {
|
||||
let entry = self.names.get_mut(index).expect("invalid index in Scope");
|
||||
if !entry.1.contains(&alias) {
|
||||
entry.1.push(alias);
|
||||
if !entry.1.iter().any(|a| &alias == a) {
|
||||
entry.1.push(alias.into());
|
||||
}
|
||||
self
|
||||
}
|
||||
@ -393,7 +397,9 @@ impl<'a> Scope<'a> {
|
||||
/// Get an iterator to entries in the [`Scope`].
|
||||
#[inline(always)]
|
||||
#[allow(dead_code)]
|
||||
pub(crate) fn into_iter(self) -> impl Iterator<Item = (Cow<'a, str>, Dynamic, Vec<String>)> {
|
||||
pub(crate) fn into_iter(
|
||||
self,
|
||||
) -> impl Iterator<Item = (Cow<'a, str>, Dynamic, Vec<ImmutableString>)> {
|
||||
self.names
|
||||
.into_iter()
|
||||
.zip(self.values.into_iter())
|
||||
|
@ -55,7 +55,7 @@ fn test_optimizer_parse() -> Result<(), Box<EvalAltResult>> {
|
||||
|
||||
let ast = engine.compile("{ const DECISION = false; if DECISION { 42 } else { 123 } }")?;
|
||||
|
||||
assert!(format!("{:?}", ast).starts_with(r#"AST([Block([Const(Ident { name: "DECISION", pos: 1:9 }, Some(Unit(0:0)), false, 1:3), Expr(IntegerConstant(123, 1:53))], 1:1)]"#));
|
||||
assert!(format!("{:?}", ast).starts_with(r#"AST([Block([Const(IdentX { name: "DECISION", pos: 1:9 }, Some(Unit(0:0)), false, 1:3), Expr(IntegerConstant(123, 1:53))], 1:1)]"#));
|
||||
|
||||
let ast = engine.compile("if 1 == 2 { 42 }")?;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user