Streamline data types.
This commit is contained in:
parent
ac52d3cd87
commit
26ad454cb1
@ -721,7 +721,7 @@ pub enum Stmt {
|
|||||||
/// This variant does not map to any language structure. It is currently only used only to
|
/// This variant does not map to any language structure. It is currently only used only to
|
||||||
/// convert normal variables into shared variables when they are _captured_ by a closure.
|
/// convert normal variables into shared variables when they are _captured_ by a closure.
|
||||||
#[cfg(not(feature = "no_closure"))]
|
#[cfg(not(feature = "no_closure"))]
|
||||||
Share(Box<crate::FnArgsVec<(crate::ImmutableString, Option<NonZeroUsize>, Position)>>),
|
Share(Box<crate::FnArgsVec<(crate::ast::Ident, Option<NonZeroUsize>)>>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Stmt {
|
impl Default for Stmt {
|
||||||
@ -816,7 +816,7 @@ impl Stmt {
|
|||||||
Self::Export(.., pos) => *pos,
|
Self::Export(.., pos) => *pos,
|
||||||
|
|
||||||
#[cfg(not(feature = "no_closure"))]
|
#[cfg(not(feature = "no_closure"))]
|
||||||
Self::Share(x) => x[0].2,
|
Self::Share(x) => x[0].0.pos,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/// Override the [position][Position] of this statement.
|
/// Override the [position][Position] of this statement.
|
||||||
@ -848,7 +848,7 @@ impl Stmt {
|
|||||||
Self::Export(.., pos) => *pos = new_pos,
|
Self::Export(.., pos) => *pos = new_pos,
|
||||||
|
|
||||||
#[cfg(not(feature = "no_closure"))]
|
#[cfg(not(feature = "no_closure"))]
|
||||||
Self::Share(x) => x.iter_mut().for_each(|(_, _, pos)| *pos = new_pos),
|
Self::Share(x) => x.iter_mut().for_each(|(x, _)| x.pos = new_pos),
|
||||||
}
|
}
|
||||||
|
|
||||||
self
|
self
|
||||||
|
@ -927,10 +927,10 @@ impl Engine {
|
|||||||
// Share statement
|
// Share statement
|
||||||
#[cfg(not(feature = "no_closure"))]
|
#[cfg(not(feature = "no_closure"))]
|
||||||
Stmt::Share(x) => {
|
Stmt::Share(x) => {
|
||||||
for (name, index, pos) in &**x {
|
for (var, index) in &**x {
|
||||||
if let Some(index) = index
|
if let Some(index) = index
|
||||||
.map(|n| scope.len() - n.get())
|
.map(|n| scope.len() - n.get())
|
||||||
.or_else(|| scope.search(name))
|
.or_else(|| scope.search(&var.name))
|
||||||
{
|
{
|
||||||
let val = scope.get_mut_by_index(index);
|
let val = scope.get_mut_by_index(index);
|
||||||
|
|
||||||
@ -939,7 +939,9 @@ impl Engine {
|
|||||||
*val = std::mem::take(val).into_shared();
|
*val = std::mem::take(val).into_shared();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return Err(ERR::ErrorVariableNotFound(name.to_string(), *pos).into());
|
return Err(
|
||||||
|
ERR::ErrorVariableNotFound(var.name.to_string(), var.pos).into()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1986,23 +1986,35 @@ impl Module {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Get an iterator to the sub-modules in the [`Module`].
|
/// Get an iterator to the sub-modules in the [`Module`].
|
||||||
#[inline]
|
#[inline(always)]
|
||||||
pub fn iter_sub_modules(&self) -> impl Iterator<Item = (&str, &SharedModule)> {
|
pub fn iter_sub_modules(&self) -> impl Iterator<Item = (&str, &SharedModule)> {
|
||||||
|
self.iter_sub_modules_raw().map(|(k, m)| (k.as_str(), m))
|
||||||
|
}
|
||||||
|
/// Get an iterator to the sub-modules in the [`Module`].
|
||||||
|
#[inline]
|
||||||
|
pub(crate) fn iter_sub_modules_raw(
|
||||||
|
&self,
|
||||||
|
) -> impl Iterator<Item = (&Identifier, &SharedModule)> {
|
||||||
self.modules
|
self.modules
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.flatten()
|
.flatten()
|
||||||
.map(|(k, m)| (k.as_str(), m))
|
.map(|(k, m)| (k, m))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get an iterator to the variables in the [`Module`].
|
/// Get an iterator to the variables in the [`Module`].
|
||||||
#[inline]
|
#[inline(always)]
|
||||||
pub fn iter_var(&self) -> impl Iterator<Item = (&str, &Dynamic)> {
|
pub fn iter_var(&self) -> impl Iterator<Item = (&str, &Dynamic)> {
|
||||||
|
self.iter_var_raw().map(|(k, v)| (k.as_str(), v))
|
||||||
|
}
|
||||||
|
/// Get an iterator to the variables in the [`Module`].
|
||||||
|
#[inline]
|
||||||
|
pub(crate) fn iter_var_raw(&self) -> impl Iterator<Item = (&Identifier, &Dynamic)> {
|
||||||
self.variables
|
self.variables
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.flatten()
|
.flatten()
|
||||||
.map(|(k, v)| (k.as_str(), v))
|
.map(|(k, v)| (k, v))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get an iterator to the functions in the [`Module`].
|
/// Get an iterator to the functions in the [`Module`].
|
||||||
|
@ -14,10 +14,9 @@ use crate::func::builtin::get_builtin_binary_op_fn;
|
|||||||
use crate::func::hashing::get_hasher;
|
use crate::func::hashing::get_hasher;
|
||||||
use crate::module::ModuleFlags;
|
use crate::module::ModuleFlags;
|
||||||
use crate::tokenizer::Token;
|
use crate::tokenizer::Token;
|
||||||
use crate::types::dynamic::AccessMode;
|
|
||||||
use crate::{
|
use crate::{
|
||||||
calc_fn_hash, calc_fn_hash_full, Dynamic, Engine, FnPtr, Identifier, ImmutableString, Position,
|
calc_fn_hash, calc_fn_hash_full, Dynamic, Engine, FnPtr, ImmutableString, Position, Scope,
|
||||||
Scope, StaticVec, AST,
|
StaticVec, AST,
|
||||||
};
|
};
|
||||||
#[cfg(feature = "no_std")]
|
#[cfg(feature = "no_std")]
|
||||||
use std::prelude::v1::*;
|
use std::prelude::v1::*;
|
||||||
@ -54,8 +53,8 @@ impl Default for OptimizationLevel {
|
|||||||
struct OptimizerState<'a> {
|
struct OptimizerState<'a> {
|
||||||
/// Has the [`AST`] been changed during this pass?
|
/// Has the [`AST`] been changed during this pass?
|
||||||
changed: bool,
|
changed: bool,
|
||||||
/// Collection of constants to use for eager function evaluations.
|
/// Collection of variables/constants to use for eager function evaluations.
|
||||||
variables: StaticVec<(Identifier, AccessMode, Option<Dynamic>)>,
|
variables: StaticVec<(ImmutableString, Option<Dynamic>)>,
|
||||||
/// Activate constants propagation?
|
/// Activate constants propagation?
|
||||||
propagate_constants: bool,
|
propagate_constants: bool,
|
||||||
/// An [`Engine`] instance for eager function evaluation.
|
/// An [`Engine`] instance for eager function evaluation.
|
||||||
@ -115,14 +114,11 @@ impl<'a> OptimizerState<'a> {
|
|||||||
self.variables.truncate(len);
|
self.variables.truncate(len);
|
||||||
}
|
}
|
||||||
/// Add a new variable to the list.
|
/// Add a new variable to the list.
|
||||||
|
///
|
||||||
|
/// `Some(value)` if constant, `None` or otherwise.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn push_var(
|
pub fn push_var(&mut self, name: ImmutableString, value: Option<Dynamic>) {
|
||||||
&mut self,
|
self.variables.push((name, value));
|
||||||
name: impl Into<Identifier>,
|
|
||||||
access: AccessMode,
|
|
||||||
value: Option<Dynamic>,
|
|
||||||
) {
|
|
||||||
self.variables.push((name.into(), access, value));
|
|
||||||
}
|
}
|
||||||
/// Look up a constant from the list.
|
/// Look up a constant from the list.
|
||||||
#[inline]
|
#[inline]
|
||||||
@ -131,12 +127,9 @@ impl<'a> OptimizerState<'a> {
|
|||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (n, access, value) in self.variables.iter().rev() {
|
for (n, value) in self.variables.iter().rev() {
|
||||||
if n == name {
|
if n.as_str() == name {
|
||||||
return match access {
|
return value.as_ref();
|
||||||
AccessMode::ReadWrite => None,
|
|
||||||
AccessMode::ReadOnly => value.as_ref(),
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -237,16 +230,13 @@ fn optimize_stmt_block(
|
|||||||
optimize_expr(&mut x.1, state, false);
|
optimize_expr(&mut x.1, state, false);
|
||||||
|
|
||||||
if x.1.is_constant() {
|
if x.1.is_constant() {
|
||||||
state.push_var(
|
state
|
||||||
x.0.as_str(),
|
.push_var(x.0.name.clone(), Some(x.1.get_literal_value().unwrap()));
|
||||||
AccessMode::ReadOnly,
|
|
||||||
x.1.get_literal_value(),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Add variables into the state
|
// Add variables into the state
|
||||||
optimize_expr(&mut x.1, state, false);
|
optimize_expr(&mut x.1, state, false);
|
||||||
state.push_var(x.0.as_str(), AccessMode::ReadWrite, None);
|
state.push_var(x.0.name.clone(), None);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Optimize the statement
|
// Optimize the statement
|
||||||
@ -858,7 +848,7 @@ fn optimize_stmt(stmt: &mut Stmt, state: &mut OptimizerState, preserve_result: b
|
|||||||
#[cfg(not(feature = "no_closure"))]
|
#[cfg(not(feature = "no_closure"))]
|
||||||
Stmt::Share(x) => {
|
Stmt::Share(x) => {
|
||||||
let len = x.len();
|
let len = x.len();
|
||||||
x.retain(|(v, _, _)| !state.find_constant(v).is_some());
|
x.retain(|(v, _)| !state.find_constant(v).is_some());
|
||||||
if x.len() != len {
|
if x.len() != len {
|
||||||
state.set_dirty();
|
state.set_dirty();
|
||||||
}
|
}
|
||||||
@ -1335,20 +1325,14 @@ impl Engine {
|
|||||||
.iter()
|
.iter()
|
||||||
.rev()
|
.rev()
|
||||||
.flat_map(|m| m.iter_var())
|
.flat_map(|m| m.iter_var())
|
||||||
.for_each(|(name, value)| {
|
.for_each(|(name, value)| state.push_var(name.into(), Some(value.clone())));
|
||||||
state.push_var(name, AccessMode::ReadOnly, Some(value.clone()))
|
|
||||||
});
|
|
||||||
|
|
||||||
// Add constants and variables from the scope
|
// Add constants and variables from the scope
|
||||||
scope
|
scope
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.flat_map(Scope::iter)
|
.flat_map(Scope::iter)
|
||||||
.for_each(|(name, constant, value)| {
|
.for_each(|(name, constant, value)| {
|
||||||
if constant {
|
state.push_var(name.into(), if constant { Some(value) } else { None });
|
||||||
state.push_var(name, AccessMode::ReadOnly, Some(value));
|
|
||||||
} else {
|
|
||||||
state.push_var(name, AccessMode::ReadWrite, None);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
optimize_stmt_block(statements, &mut state, true, false, true)
|
optimize_stmt_block(statements, &mut state, true, false, true)
|
||||||
|
@ -3781,9 +3781,9 @@ impl Engine {
|
|||||||
statements.push(Stmt::Share(
|
statements.push(Stmt::Share(
|
||||||
externals
|
externals
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|Ident { name, pos }| {
|
.map(|var| {
|
||||||
let (index, _) = parent.access_var(&name, lib, pos);
|
let (index, _) = parent.access_var(&var.name, lib, var.pos);
|
||||||
(name, index, pos)
|
(var, index)
|
||||||
})
|
})
|
||||||
.collect::<crate::FnArgsVec<_>>()
|
.collect::<crate::FnArgsVec<_>>()
|
||||||
.into(),
|
.into(),
|
||||||
|
@ -182,8 +182,6 @@ fn test_optimizer_reoptimize() -> Result<(), Box<EvalAltResult>> {
|
|||||||
let scope: Scope = ast.iter_literal_variables(true, false).collect();
|
let scope: Scope = ast.iter_literal_variables(true, false).collect();
|
||||||
let ast = engine.optimize_ast(&scope, ast, OptimizationLevel::Simple);
|
let ast = engine.optimize_ast(&scope, ast, OptimizationLevel::Simple);
|
||||||
|
|
||||||
println!("{ast:#?}");
|
|
||||||
|
|
||||||
assert_eq!(engine.eval_ast::<INT>(&ast)?, 84);
|
assert_eq!(engine.eval_ast::<INT>(&ast)?, 84);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
Loading…
Reference in New Issue
Block a user