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