Flatten data structures and more aggressive inlining.
This commit is contained in:
parent
352408fd36
commit
cbad703b00
87
src/ast.rs
87
src/ast.rs
@ -11,7 +11,6 @@ use crate::stdlib::{
|
|||||||
num::NonZeroUsize,
|
num::NonZeroUsize,
|
||||||
ops::{Add, AddAssign},
|
ops::{Add, AddAssign},
|
||||||
string::String,
|
string::String,
|
||||||
vec,
|
|
||||||
vec::Vec,
|
vec::Vec,
|
||||||
};
|
};
|
||||||
use crate::token::Token;
|
use crate::token::Token;
|
||||||
@ -61,9 +60,9 @@ pub struct ScriptFnDef {
|
|||||||
pub params: StaticVec<ImmutableString>,
|
pub params: StaticVec<ImmutableString>,
|
||||||
/// Access to external variables.
|
/// Access to external variables.
|
||||||
#[cfg(not(feature = "no_closure"))]
|
#[cfg(not(feature = "no_closure"))]
|
||||||
pub externals: Vec<ImmutableString>,
|
pub externals: StaticVec<ImmutableString>,
|
||||||
/// Function doc-comments (if any).
|
/// Function doc-comments (if any).
|
||||||
pub comments: Vec<String>,
|
pub comments: StaticVec<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for ScriptFnDef {
|
impl fmt::Display for ScriptFnDef {
|
||||||
@ -149,7 +148,7 @@ pub struct AST {
|
|||||||
/// Source of the [`AST`].
|
/// Source of the [`AST`].
|
||||||
source: Option<ImmutableString>,
|
source: Option<ImmutableString>,
|
||||||
/// Global statements.
|
/// Global statements.
|
||||||
statements: Vec<Stmt>,
|
body: StmtBlock,
|
||||||
/// Script-defined functions.
|
/// Script-defined functions.
|
||||||
functions: Shared<Module>,
|
functions: Shared<Module>,
|
||||||
/// Embedded module resolver, if any.
|
/// Embedded module resolver, if any.
|
||||||
@ -162,7 +161,7 @@ impl Default for AST {
|
|||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
source: None,
|
source: None,
|
||||||
statements: Vec::with_capacity(16),
|
body: Default::default(),
|
||||||
functions: Default::default(),
|
functions: Default::default(),
|
||||||
#[cfg(not(feature = "no_module"))]
|
#[cfg(not(feature = "no_module"))]
|
||||||
resolver: None,
|
resolver: None,
|
||||||
@ -179,7 +178,10 @@ impl AST {
|
|||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
source: None,
|
source: None,
|
||||||
|
body: StmtBlock {
|
||||||
statements: statements.into_iter().collect(),
|
statements: statements.into_iter().collect(),
|
||||||
|
pos: Position::NONE,
|
||||||
|
},
|
||||||
functions: functions.into(),
|
functions: functions.into(),
|
||||||
#[cfg(not(feature = "no_module"))]
|
#[cfg(not(feature = "no_module"))]
|
||||||
resolver: None,
|
resolver: None,
|
||||||
@ -194,7 +196,10 @@ impl AST {
|
|||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
source: Some(source.into()),
|
source: Some(source.into()),
|
||||||
|
body: StmtBlock {
|
||||||
statements: statements.into_iter().collect(),
|
statements: statements.into_iter().collect(),
|
||||||
|
pos: Position::NONE,
|
||||||
|
},
|
||||||
functions: functions.into(),
|
functions: functions.into(),
|
||||||
#[cfg(not(feature = "no_module"))]
|
#[cfg(not(feature = "no_module"))]
|
||||||
resolver: None,
|
resolver: None,
|
||||||
@ -231,7 +236,7 @@ impl AST {
|
|||||||
#[cfg(not(feature = "internals"))]
|
#[cfg(not(feature = "internals"))]
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub(crate) fn statements(&self) -> &[Stmt] {
|
pub(crate) fn statements(&self) -> &[Stmt] {
|
||||||
&self.statements
|
&self.body.statements
|
||||||
}
|
}
|
||||||
/// _(INTERNALS)_ Get the statements.
|
/// _(INTERNALS)_ Get the statements.
|
||||||
/// Exported under the `internals` feature only.
|
/// Exported under the `internals` feature only.
|
||||||
@ -244,8 +249,8 @@ impl AST {
|
|||||||
/// Get a mutable reference to the statements.
|
/// Get a mutable reference to the statements.
|
||||||
#[cfg(not(feature = "no_optimize"))]
|
#[cfg(not(feature = "no_optimize"))]
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub(crate) fn statements_mut(&mut self) -> &mut Vec<Stmt> {
|
pub(crate) fn statements_mut(&mut self) -> &mut StaticVec<Stmt> {
|
||||||
&mut self.statements
|
&mut self.body.statements
|
||||||
}
|
}
|
||||||
/// Get the internal shared [`Module`] containing all script-defined functions.
|
/// Get the internal shared [`Module`] containing all script-defined functions.
|
||||||
#[cfg(not(feature = "internals"))]
|
#[cfg(not(feature = "internals"))]
|
||||||
@ -333,7 +338,7 @@ impl AST {
|
|||||||
functions.merge_filtered(&self.functions, &filter);
|
functions.merge_filtered(&self.functions, &filter);
|
||||||
Self {
|
Self {
|
||||||
source: self.source.clone(),
|
source: self.source.clone(),
|
||||||
statements: Default::default(),
|
body: Default::default(),
|
||||||
functions: functions.into(),
|
functions: functions.into(),
|
||||||
#[cfg(not(feature = "no_module"))]
|
#[cfg(not(feature = "no_module"))]
|
||||||
resolver: self.resolver.clone(),
|
resolver: self.resolver.clone(),
|
||||||
@ -345,7 +350,7 @@ impl AST {
|
|||||||
pub fn clone_statements_only(&self) -> Self {
|
pub fn clone_statements_only(&self) -> Self {
|
||||||
Self {
|
Self {
|
||||||
source: self.source.clone(),
|
source: self.source.clone(),
|
||||||
statements: self.statements.clone(),
|
body: self.body.clone(),
|
||||||
functions: Default::default(),
|
functions: Default::default(),
|
||||||
#[cfg(not(feature = "no_module"))]
|
#[cfg(not(feature = "no_module"))]
|
||||||
resolver: self.resolver.clone(),
|
resolver: self.resolver.clone(),
|
||||||
@ -515,20 +520,19 @@ impl AST {
|
|||||||
filter: impl Fn(FnNamespace, FnAccess, bool, &str, usize) -> bool,
|
filter: impl Fn(FnNamespace, FnAccess, bool, &str, usize) -> bool,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let Self {
|
let Self {
|
||||||
statements,
|
body, functions, ..
|
||||||
functions,
|
|
||||||
..
|
|
||||||
} = self;
|
} = self;
|
||||||
|
|
||||||
let ast = match (statements.is_empty(), other.statements.is_empty()) {
|
let merged = match (body.is_empty(), other.body.is_empty()) {
|
||||||
(false, false) => {
|
(false, false) => {
|
||||||
let mut statements = statements.clone();
|
let mut body = body.clone();
|
||||||
statements.extend(other.statements.iter().cloned());
|
body.statements
|
||||||
statements
|
.extend(other.body.statements.iter().cloned());
|
||||||
|
body
|
||||||
}
|
}
|
||||||
(false, true) => statements.clone(),
|
(false, true) => body.clone(),
|
||||||
(true, false) => other.statements.clone(),
|
(true, false) => other.body.clone(),
|
||||||
(true, true) => vec![],
|
(true, true) => Default::default(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let source = other.source.clone().or_else(|| self.source.clone());
|
let source = other.source.clone().or_else(|| self.source.clone());
|
||||||
@ -537,9 +541,9 @@ impl AST {
|
|||||||
functions.merge_filtered(&other.functions, &filter);
|
functions.merge_filtered(&other.functions, &filter);
|
||||||
|
|
||||||
if let Some(source) = source {
|
if let Some(source) = source {
|
||||||
Self::new_with_source(ast, functions, source)
|
Self::new_with_source(merged.statements, functions, source)
|
||||||
} else {
|
} else {
|
||||||
Self::new(ast, functions)
|
Self::new(merged.statements, functions)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/// Combine one [`AST`] with another. The second [`AST`] is consumed.
|
/// Combine one [`AST`] with another. The second [`AST`] is consumed.
|
||||||
@ -599,7 +603,10 @@ impl AST {
|
|||||||
other: Self,
|
other: Self,
|
||||||
filter: impl Fn(FnNamespace, FnAccess, bool, &str, usize) -> bool,
|
filter: impl Fn(FnNamespace, FnAccess, bool, &str, usize) -> bool,
|
||||||
) -> &mut Self {
|
) -> &mut Self {
|
||||||
self.statements.extend(other.statements.into_iter());
|
self.body
|
||||||
|
.statements
|
||||||
|
.extend(other.body.statements.into_iter());
|
||||||
|
|
||||||
if !other.functions.is_empty() {
|
if !other.functions.is_empty() {
|
||||||
shared_make_mut(&mut self.functions).merge_filtered(&other.functions, &filter);
|
shared_make_mut(&mut self.functions).merge_filtered(&other.functions, &filter);
|
||||||
}
|
}
|
||||||
@ -673,7 +680,7 @@ impl AST {
|
|||||||
/// Clear all statements in the [`AST`], leaving only function definitions.
|
/// Clear all statements in the [`AST`], leaving only function definitions.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn clear_statements(&mut self) {
|
pub fn clear_statements(&mut self) {
|
||||||
self.statements = vec![];
|
self.body = Default::default();
|
||||||
}
|
}
|
||||||
/// Recursively walk the [`AST`], including function bodies (if any).
|
/// Recursively walk the [`AST`], including function bodies (if any).
|
||||||
#[cfg(not(feature = "internals"))]
|
#[cfg(not(feature = "internals"))]
|
||||||
@ -810,7 +817,7 @@ impl<'a> From<&'a Expr> for ASTNode<'a> {
|
|||||||
/// # Volatile Data Structure
|
/// # Volatile Data Structure
|
||||||
///
|
///
|
||||||
/// This type is volatile and may change.
|
/// This type is volatile and may change.
|
||||||
#[derive(Debug, Clone, Hash)]
|
#[derive(Clone, Hash, Default)]
|
||||||
pub struct StmtBlock {
|
pub struct StmtBlock {
|
||||||
pub statements: StaticVec<Stmt>,
|
pub statements: StaticVec<Stmt>,
|
||||||
pub pos: Position,
|
pub pos: Position,
|
||||||
@ -818,15 +825,27 @@ pub struct StmtBlock {
|
|||||||
|
|
||||||
impl StmtBlock {
|
impl StmtBlock {
|
||||||
/// Is this statements block empty?
|
/// Is this statements block empty?
|
||||||
|
#[inline(always)]
|
||||||
pub fn is_empty(&self) -> bool {
|
pub fn is_empty(&self) -> bool {
|
||||||
self.statements.is_empty()
|
self.statements.is_empty()
|
||||||
}
|
}
|
||||||
/// Number of statements in this statements block.
|
/// Number of statements in this statements block.
|
||||||
|
#[inline(always)]
|
||||||
pub fn len(&self) -> usize {
|
pub fn len(&self) -> usize {
|
||||||
self.statements.len()
|
self.statements.len()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl fmt::Debug for StmtBlock {
|
||||||
|
#[inline(always)]
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
if !self.pos.is_none() {
|
||||||
|
write!(f, "{} @ ", self.pos)?;
|
||||||
|
}
|
||||||
|
fmt::Debug::fmt(&self.statements, f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// _(INTERNALS)_ A statement.
|
/// _(INTERNALS)_ A statement.
|
||||||
/// Exported under the `internals` feature only.
|
/// Exported under the `internals` feature only.
|
||||||
///
|
///
|
||||||
@ -1242,6 +1261,7 @@ pub struct FloatWrapper(FLOAT);
|
|||||||
|
|
||||||
#[cfg(not(feature = "no_float"))]
|
#[cfg(not(feature = "no_float"))]
|
||||||
impl Hash for FloatWrapper {
|
impl Hash for FloatWrapper {
|
||||||
|
#[inline(always)]
|
||||||
fn hash<H: crate::stdlib::hash::Hasher>(&self, state: &mut H) {
|
fn hash<H: crate::stdlib::hash::Hasher>(&self, state: &mut H) {
|
||||||
self.0.to_ne_bytes().hash(state);
|
self.0.to_ne_bytes().hash(state);
|
||||||
}
|
}
|
||||||
@ -1249,6 +1269,7 @@ impl Hash for FloatWrapper {
|
|||||||
|
|
||||||
#[cfg(not(feature = "no_float"))]
|
#[cfg(not(feature = "no_float"))]
|
||||||
impl AsRef<FLOAT> for FloatWrapper {
|
impl AsRef<FLOAT> for FloatWrapper {
|
||||||
|
#[inline(always)]
|
||||||
fn as_ref(&self) -> &FLOAT {
|
fn as_ref(&self) -> &FLOAT {
|
||||||
&self.0
|
&self.0
|
||||||
}
|
}
|
||||||
@ -1256,6 +1277,7 @@ impl AsRef<FLOAT> for FloatWrapper {
|
|||||||
|
|
||||||
#[cfg(not(feature = "no_float"))]
|
#[cfg(not(feature = "no_float"))]
|
||||||
impl AsMut<FLOAT> for FloatWrapper {
|
impl AsMut<FLOAT> for FloatWrapper {
|
||||||
|
#[inline(always)]
|
||||||
fn as_mut(&mut self) -> &mut FLOAT {
|
fn as_mut(&mut self) -> &mut FLOAT {
|
||||||
&mut self.0
|
&mut self.0
|
||||||
}
|
}
|
||||||
@ -1265,6 +1287,7 @@ impl AsMut<FLOAT> for FloatWrapper {
|
|||||||
impl crate::stdlib::ops::Deref for FloatWrapper {
|
impl crate::stdlib::ops::Deref for FloatWrapper {
|
||||||
type Target = FLOAT;
|
type Target = FLOAT;
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
fn deref(&self) -> &Self::Target {
|
fn deref(&self) -> &Self::Target {
|
||||||
&self.0
|
&self.0
|
||||||
}
|
}
|
||||||
@ -1272,6 +1295,7 @@ impl crate::stdlib::ops::Deref for FloatWrapper {
|
|||||||
|
|
||||||
#[cfg(not(feature = "no_float"))]
|
#[cfg(not(feature = "no_float"))]
|
||||||
impl crate::stdlib::ops::DerefMut for FloatWrapper {
|
impl crate::stdlib::ops::DerefMut for FloatWrapper {
|
||||||
|
#[inline(always)]
|
||||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||||
&mut self.0
|
&mut self.0
|
||||||
}
|
}
|
||||||
@ -1279,6 +1303,7 @@ impl crate::stdlib::ops::DerefMut for FloatWrapper {
|
|||||||
|
|
||||||
#[cfg(not(feature = "no_float"))]
|
#[cfg(not(feature = "no_float"))]
|
||||||
impl fmt::Debug for FloatWrapper {
|
impl fmt::Debug for FloatWrapper {
|
||||||
|
#[inline(always)]
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
fmt::Display::fmt(self, f)
|
fmt::Display::fmt(self, f)
|
||||||
}
|
}
|
||||||
@ -1286,6 +1311,7 @@ impl fmt::Debug for FloatWrapper {
|
|||||||
|
|
||||||
#[cfg(not(feature = "no_float"))]
|
#[cfg(not(feature = "no_float"))]
|
||||||
impl fmt::Display for FloatWrapper {
|
impl fmt::Display for FloatWrapper {
|
||||||
|
#[inline(always)]
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
#[cfg(feature = "no_std")]
|
#[cfg(feature = "no_std")]
|
||||||
use num_traits::Float;
|
use num_traits::Float;
|
||||||
@ -1301,6 +1327,7 @@ impl fmt::Display for FloatWrapper {
|
|||||||
|
|
||||||
#[cfg(not(feature = "no_float"))]
|
#[cfg(not(feature = "no_float"))]
|
||||||
impl From<FLOAT> for FloatWrapper {
|
impl From<FLOAT> for FloatWrapper {
|
||||||
|
#[inline(always)]
|
||||||
fn from(value: FLOAT) -> Self {
|
fn from(value: FLOAT) -> Self {
|
||||||
Self::new(value)
|
Self::new(value)
|
||||||
}
|
}
|
||||||
@ -1310,6 +1337,7 @@ impl From<FLOAT> for FloatWrapper {
|
|||||||
impl FromStr for FloatWrapper {
|
impl FromStr for FloatWrapper {
|
||||||
type Err = <FLOAT as FromStr>::Err;
|
type Err = <FLOAT as FromStr>::Err;
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||||
FLOAT::from_str(s).map(Into::<Self>::into)
|
FLOAT::from_str(s).map(Into::<Self>::into)
|
||||||
}
|
}
|
||||||
@ -1317,6 +1345,7 @@ impl FromStr for FloatWrapper {
|
|||||||
|
|
||||||
#[cfg(not(feature = "no_float"))]
|
#[cfg(not(feature = "no_float"))]
|
||||||
impl FloatWrapper {
|
impl FloatWrapper {
|
||||||
|
#[inline(always)]
|
||||||
pub const fn new(value: FLOAT) -> Self {
|
pub const fn new(value: FLOAT) -> Self {
|
||||||
Self(value)
|
Self(value)
|
||||||
}
|
}
|
||||||
@ -1384,6 +1413,7 @@ impl Expr {
|
|||||||
/// Get the [`Dynamic`] value of a constant expression.
|
/// Get the [`Dynamic`] value of a constant expression.
|
||||||
///
|
///
|
||||||
/// Returns [`None`] if the expression is not constant.
|
/// Returns [`None`] if the expression is not constant.
|
||||||
|
#[inline]
|
||||||
pub fn get_constant_value(&self) -> Option<Dynamic> {
|
pub fn get_constant_value(&self) -> Option<Dynamic> {
|
||||||
Some(match self {
|
Some(match self {
|
||||||
Self::DynamicConstant(x, _) => x.as_ref().clone(),
|
Self::DynamicConstant(x, _) => x.as_ref().clone(),
|
||||||
@ -1434,6 +1464,7 @@ impl Expr {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
/// Get the [position][Position] of the expression.
|
/// Get the [position][Position] of the expression.
|
||||||
|
#[inline]
|
||||||
pub fn position(&self) -> Position {
|
pub fn position(&self) -> Position {
|
||||||
match self {
|
match self {
|
||||||
#[cfg(not(feature = "no_float"))]
|
#[cfg(not(feature = "no_float"))]
|
||||||
@ -1462,6 +1493,7 @@ impl Expr {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
/// Override the [position][Position] of the expression.
|
/// Override the [position][Position] of the expression.
|
||||||
|
#[inline]
|
||||||
pub fn set_position(&mut self, new_pos: Position) -> &mut Self {
|
pub fn set_position(&mut self, new_pos: Position) -> &mut Self {
|
||||||
match self {
|
match self {
|
||||||
#[cfg(not(feature = "no_float"))]
|
#[cfg(not(feature = "no_float"))]
|
||||||
@ -1490,6 +1522,7 @@ impl Expr {
|
|||||||
/// Is the expression pure?
|
/// Is the expression pure?
|
||||||
///
|
///
|
||||||
/// A pure expression has no side effects.
|
/// A pure expression has no side effects.
|
||||||
|
#[inline]
|
||||||
pub fn is_pure(&self) -> bool {
|
pub fn is_pure(&self) -> bool {
|
||||||
match self {
|
match self {
|
||||||
Self::Array(x, _) => x.iter().all(Self::is_pure),
|
Self::Array(x, _) => x.iter().all(Self::is_pure),
|
||||||
@ -1516,6 +1549,7 @@ impl Expr {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
/// Is the expression a constant?
|
/// Is the expression a constant?
|
||||||
|
#[inline]
|
||||||
pub fn is_constant(&self) -> bool {
|
pub fn is_constant(&self) -> bool {
|
||||||
match self {
|
match self {
|
||||||
#[cfg(not(feature = "no_float"))]
|
#[cfg(not(feature = "no_float"))]
|
||||||
@ -1539,6 +1573,7 @@ impl Expr {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
/// Is a particular [token][Token] allowed as a postfix operator to this expression?
|
/// Is a particular [token][Token] allowed as a postfix operator to this expression?
|
||||||
|
#[inline]
|
||||||
pub fn is_valid_postfix(&self, token: &Token) -> bool {
|
pub fn is_valid_postfix(&self, token: &Token) -> bool {
|
||||||
match token {
|
match token {
|
||||||
#[cfg(not(feature = "no_object"))]
|
#[cfg(not(feature = "no_object"))]
|
||||||
@ -1591,7 +1626,7 @@ impl Expr {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
/// Recursively walk this expression.
|
/// Recursively walk this expression.
|
||||||
#[inline(always)]
|
#[inline]
|
||||||
pub fn walk<'a>(&'a self, path: &mut Vec<ASTNode<'a>>, on_node: &mut impl FnMut(&[ASTNode])) {
|
pub fn walk<'a>(&'a self, path: &mut Vec<ASTNode<'a>>, on_node: &mut impl FnMut(&[ASTNode])) {
|
||||||
path.push(self.into());
|
path.push(self.into());
|
||||||
on_node(path);
|
on_node(path);
|
||||||
|
@ -1832,7 +1832,7 @@ impl Engine {
|
|||||||
let lib = Default::default();
|
let lib = Default::default();
|
||||||
|
|
||||||
let stmt = crate::stdlib::mem::take(ast.statements_mut());
|
let stmt = crate::stdlib::mem::take(ast.statements_mut());
|
||||||
crate::optimize::optimize_into_ast(self, scope, stmt, lib, optimization_level)
|
crate::optimize::optimize_into_ast(self, scope, stmt.into_vec(), lib, optimization_level)
|
||||||
}
|
}
|
||||||
/// Generate a list of all registered functions.
|
/// Generate a list of all registered functions.
|
||||||
///
|
///
|
||||||
|
@ -192,7 +192,7 @@ pub use token::{get_next_token, parse_string_literal, InputStream, Token, Tokeni
|
|||||||
#[deprecated = "this type is volatile and may change"]
|
#[deprecated = "this type is volatile and may change"]
|
||||||
pub use ast::{
|
pub use ast::{
|
||||||
ASTNode, BinaryExpr, CustomExpr, Expr, FloatWrapper, FnCallExpr, FnHash, Ident, OpAssignment,
|
ASTNode, BinaryExpr, CustomExpr, Expr, FloatWrapper, FnCallExpr, FnHash, Ident, OpAssignment,
|
||||||
ReturnType, ScriptFnDef, Stmt,
|
ReturnType, ScriptFnDef, Stmt, StmtBlock,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[cfg(feature = "internals")]
|
#[cfg(feature = "internals")]
|
||||||
|
@ -39,6 +39,7 @@ pub enum FnNamespace {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Default for FnNamespace {
|
impl Default for FnNamespace {
|
||||||
|
#[inline(always)]
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self::Internal
|
Self::Internal
|
||||||
}
|
}
|
||||||
@ -150,6 +151,7 @@ pub struct Module {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Module {
|
impl Default for Module {
|
||||||
|
#[inline(always)]
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
id: None,
|
id: None,
|
||||||
@ -226,6 +228,7 @@ impl AsRef<Module> for Module {
|
|||||||
impl<M: AsRef<Module>> Add<M> for &Module {
|
impl<M: AsRef<Module>> Add<M> for &Module {
|
||||||
type Output = Module;
|
type Output = Module;
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
fn add(self, rhs: M) -> Self::Output {
|
fn add(self, rhs: M) -> Self::Output {
|
||||||
let mut module = self.clone();
|
let mut module = self.clone();
|
||||||
module.merge(rhs.as_ref());
|
module.merge(rhs.as_ref());
|
||||||
@ -236,6 +239,7 @@ impl<M: AsRef<Module>> Add<M> for &Module {
|
|||||||
impl<M: AsRef<Module>> Add<M> for Module {
|
impl<M: AsRef<Module>> Add<M> for Module {
|
||||||
type Output = Self;
|
type Output = Self;
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
fn add(mut self, rhs: M) -> Self::Output {
|
fn add(mut self, rhs: M) -> Self::Output {
|
||||||
self.merge(rhs.as_ref());
|
self.merge(rhs.as_ref());
|
||||||
self
|
self
|
||||||
@ -243,6 +247,7 @@ impl<M: AsRef<Module>> Add<M> for Module {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<M: Into<Module>> AddAssign<M> for Module {
|
impl<M: Into<Module>> AddAssign<M> for Module {
|
||||||
|
#[inline(always)]
|
||||||
fn add_assign(&mut self, rhs: M) {
|
fn add_assign(&mut self, rhs: M) {
|
||||||
self.combine(rhs.into());
|
self.combine(rhs.into());
|
||||||
}
|
}
|
||||||
@ -1953,16 +1958,19 @@ impl Module {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Does a type iterator exist in the entire module tree?
|
/// Does a type iterator exist in the entire module tree?
|
||||||
|
#[inline(always)]
|
||||||
pub fn contains_qualified_iter(&self, id: TypeId) -> bool {
|
pub fn contains_qualified_iter(&self, id: TypeId) -> bool {
|
||||||
self.all_type_iterators.contains_key(&id)
|
self.all_type_iterators.contains_key(&id)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Does a type iterator exist in the module?
|
/// Does a type iterator exist in the module?
|
||||||
|
#[inline(always)]
|
||||||
pub fn contains_iter(&self, id: TypeId) -> bool {
|
pub fn contains_iter(&self, id: TypeId) -> bool {
|
||||||
self.type_iterators.contains_key(&id)
|
self.type_iterators.contains_key(&id)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set a type iterator into the [`Module`].
|
/// Set a type iterator into the [`Module`].
|
||||||
|
#[inline(always)]
|
||||||
pub fn set_iter(&mut self, typ: TypeId, func: IteratorFn) -> &mut Self {
|
pub fn set_iter(&mut self, typ: TypeId, func: IteratorFn) -> &mut Self {
|
||||||
self.type_iterators.insert(typ, func);
|
self.type_iterators.insert(typ, func);
|
||||||
self.indexed = false;
|
self.indexed = false;
|
||||||
@ -1971,6 +1979,7 @@ impl Module {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Set a type iterator into the [`Module`].
|
/// Set a type iterator into the [`Module`].
|
||||||
|
#[inline(always)]
|
||||||
pub fn set_iterable<T>(&mut self) -> &mut Self
|
pub fn set_iterable<T>(&mut self) -> &mut Self
|
||||||
where
|
where
|
||||||
T: Variant + Clone + IntoIterator,
|
T: Variant + Clone + IntoIterator,
|
||||||
@ -1982,6 +1991,7 @@ impl Module {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Set an iterator type into the [`Module`] as a type iterator.
|
/// Set an iterator type into the [`Module`] as a type iterator.
|
||||||
|
#[inline(always)]
|
||||||
pub fn set_iterator<T>(&mut self) -> &mut Self
|
pub fn set_iterator<T>(&mut self) -> &mut Self
|
||||||
where
|
where
|
||||||
T: Variant + Clone + Iterator,
|
T: Variant + Clone + Iterator,
|
||||||
@ -1993,11 +2003,13 @@ impl Module {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Get the specified type iterator.
|
/// Get the specified type iterator.
|
||||||
|
#[inline(always)]
|
||||||
pub(crate) fn get_qualified_iter(&self, id: TypeId) -> Option<IteratorFn> {
|
pub(crate) fn get_qualified_iter(&self, id: TypeId) -> Option<IteratorFn> {
|
||||||
self.all_type_iterators.get(&id).cloned()
|
self.all_type_iterators.get(&id).cloned()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the specified type iterator.
|
/// Get the specified type iterator.
|
||||||
|
#[inline(always)]
|
||||||
pub(crate) fn get_iter(&self, id: TypeId) -> Option<IteratorFn> {
|
pub(crate) fn get_iter(&self, id: TypeId) -> Option<IteratorFn> {
|
||||||
self.type_iterators.get(&id).cloned()
|
self.type_iterators.get(&id).cloned()
|
||||||
}
|
}
|
||||||
@ -2021,6 +2033,7 @@ pub struct NamespaceRef {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Debug for NamespaceRef {
|
impl fmt::Debug for NamespaceRef {
|
||||||
|
#[inline(always)]
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
if let Some(index) = self.index {
|
if let Some(index) = self.index {
|
||||||
write!(f, "{} -> ", index)?;
|
write!(f, "{} -> ", index)?;
|
||||||
@ -2040,18 +2053,21 @@ impl fmt::Debug for NamespaceRef {
|
|||||||
impl Deref for NamespaceRef {
|
impl Deref for NamespaceRef {
|
||||||
type Target = StaticVec<Ident>;
|
type Target = StaticVec<Ident>;
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
fn deref(&self) -> &Self::Target {
|
fn deref(&self) -> &Self::Target {
|
||||||
&self.path
|
&self.path
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DerefMut for NamespaceRef {
|
impl DerefMut for NamespaceRef {
|
||||||
|
#[inline(always)]
|
||||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||||
&mut self.path
|
&mut self.path
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for NamespaceRef {
|
impl fmt::Display for NamespaceRef {
|
||||||
|
#[inline(always)]
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
for Ident { name, .. } in self.path.iter() {
|
for Ident { name, .. } in self.path.iter() {
|
||||||
write!(f, "{}{}", name, Token::DoubleColon.syntax())?;
|
write!(f, "{}{}", name, Token::DoubleColon.syntax())?;
|
||||||
@ -2061,6 +2077,7 @@ impl fmt::Display for NamespaceRef {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl From<StaticVec<Ident>> for NamespaceRef {
|
impl From<StaticVec<Ident>> for NamespaceRef {
|
||||||
|
#[inline(always)]
|
||||||
fn from(path: StaticVec<Ident>) -> Self {
|
fn from(path: StaticVec<Ident>) -> Self {
|
||||||
Self { index: None, path }
|
Self { index: None, path }
|
||||||
}
|
}
|
||||||
@ -2068,11 +2085,13 @@ impl From<StaticVec<Ident>> for NamespaceRef {
|
|||||||
|
|
||||||
impl NamespaceRef {
|
impl NamespaceRef {
|
||||||
/// Get the [`Scope`][crate::Scope] index offset.
|
/// Get the [`Scope`][crate::Scope] index offset.
|
||||||
|
#[inline(always)]
|
||||||
pub(crate) fn index(&self) -> Option<NonZeroUsize> {
|
pub(crate) fn index(&self) -> Option<NonZeroUsize> {
|
||||||
self.index
|
self.index
|
||||||
}
|
}
|
||||||
/// Set the [`Scope`][crate::Scope] index offset.
|
/// Set the [`Scope`][crate::Scope] index offset.
|
||||||
#[cfg(not(feature = "no_module"))]
|
#[cfg(not(feature = "no_module"))]
|
||||||
|
#[inline(always)]
|
||||||
pub(crate) fn set_index(&mut self, index: Option<NonZeroUsize>) {
|
pub(crate) fn set_index(&mut self, index: Option<NonZeroUsize>) {
|
||||||
self.index = index
|
self.index = index
|
||||||
}
|
}
|
||||||
|
@ -38,6 +38,7 @@ pub enum LexError {
|
|||||||
impl Error for LexError {}
|
impl Error for LexError {}
|
||||||
|
|
||||||
impl fmt::Display for LexError {
|
impl fmt::Display for LexError {
|
||||||
|
#[inline(always)]
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
match self {
|
match self {
|
||||||
Self::UnexpectedInput(s) => write!(f, "Unexpected '{}'", s),
|
Self::UnexpectedInput(s) => write!(f, "Unexpected '{}'", s),
|
||||||
@ -293,7 +294,7 @@ pub struct ParseError(pub Box<ParseErrorType>, pub Position);
|
|||||||
impl Error for ParseError {}
|
impl Error for ParseError {}
|
||||||
|
|
||||||
impl fmt::Display for ParseError {
|
impl fmt::Display for ParseError {
|
||||||
#[inline]
|
#[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, f)?;
|
fmt::Display::fmt(&self.0, f)?;
|
||||||
|
|
||||||
|
@ -2434,7 +2434,7 @@ fn parse_stmt(
|
|||||||
) -> Result<Stmt, ParseError> {
|
) -> Result<Stmt, ParseError> {
|
||||||
use AccessMode::{ReadOnly, ReadWrite};
|
use AccessMode::{ReadOnly, ReadWrite};
|
||||||
|
|
||||||
let mut _comments: Vec<String> = Default::default();
|
let mut _comments: StaticVec<String> = Default::default();
|
||||||
|
|
||||||
#[cfg(not(feature = "no_function"))]
|
#[cfg(not(feature = "no_function"))]
|
||||||
{
|
{
|
||||||
@ -2678,7 +2678,7 @@ fn parse_fn(
|
|||||||
lib: &mut FunctionsLib,
|
lib: &mut FunctionsLib,
|
||||||
access: FnAccess,
|
access: FnAccess,
|
||||||
mut settings: ParseSettings,
|
mut settings: ParseSettings,
|
||||||
comments: Vec<String>,
|
comments: StaticVec<String>,
|
||||||
) -> Result<ScriptFnDef, ParseError> {
|
) -> Result<ScriptFnDef, ParseError> {
|
||||||
#[cfg(not(feature = "unchecked"))]
|
#[cfg(not(feature = "unchecked"))]
|
||||||
settings.ensure_level_within_max_limit(state.max_expr_depth)?;
|
settings.ensure_level_within_max_limit(state.max_expr_depth)?;
|
||||||
|
@ -116,16 +116,19 @@ pub(crate) fn combine_hashes(a: u64, b: u64) -> u64 {
|
|||||||
pub struct HashableHashMap<K, T, H: BuildHasher>(HashMap<K, T, H>);
|
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> {
|
impl<K, T, H: BuildHasher> From<HashMap<K, T, H>> for HashableHashMap<K, T, H> {
|
||||||
|
#[inline(always)]
|
||||||
fn from(value: HashMap<K, T, H>) -> Self {
|
fn from(value: HashMap<K, T, H>) -> Self {
|
||||||
Self(value)
|
Self(value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl<K, T, H: BuildHasher> AsRef<HashMap<K, T, H>> for HashableHashMap<K, T, H> {
|
impl<K, T, H: BuildHasher> AsRef<HashMap<K, T, H>> for HashableHashMap<K, T, H> {
|
||||||
|
#[inline(always)]
|
||||||
fn as_ref(&self) -> &HashMap<K, T, H> {
|
fn as_ref(&self) -> &HashMap<K, T, H> {
|
||||||
&self.0
|
&self.0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl<K, T, H: BuildHasher> AsMut<HashMap<K, T, H>> for HashableHashMap<K, T, H> {
|
impl<K, T, H: BuildHasher> AsMut<HashMap<K, T, H>> for HashableHashMap<K, T, H> {
|
||||||
|
#[inline(always)]
|
||||||
fn as_mut(&mut self) -> &mut HashMap<K, T, H> {
|
fn as_mut(&mut self) -> &mut HashMap<K, T, H> {
|
||||||
&mut self.0
|
&mut self.0
|
||||||
}
|
}
|
||||||
@ -133,21 +136,25 @@ impl<K, T, H: BuildHasher> AsMut<HashMap<K, T, H>> for HashableHashMap<K, T, H>
|
|||||||
impl<K, T, H: BuildHasher> Deref for HashableHashMap<K, T, H> {
|
impl<K, T, H: BuildHasher> Deref for HashableHashMap<K, T, H> {
|
||||||
type Target = HashMap<K, T, H>;
|
type Target = HashMap<K, T, H>;
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
fn deref(&self) -> &Self::Target {
|
fn deref(&self) -> &Self::Target {
|
||||||
&self.0
|
&self.0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl<K, T, H: BuildHasher> DerefMut for HashableHashMap<K, T, H> {
|
impl<K, T, H: BuildHasher> DerefMut for HashableHashMap<K, T, H> {
|
||||||
|
#[inline(always)]
|
||||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||||
&mut self.0
|
&mut self.0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl<K: Debug, T: Debug, H: BuildHasher> Debug for HashableHashMap<K, T, H> {
|
impl<K: Debug, T: Debug, H: BuildHasher> Debug for HashableHashMap<K, T, H> {
|
||||||
|
#[inline(always)]
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
self.0.fmt(f)
|
self.0.fmt(f)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl<K: Hash + Ord, T: Hash, H: BuildHasher> Hash for HashableHashMap<K, T, H> {
|
impl<K: Hash + Ord, T: Hash, H: BuildHasher> Hash for HashableHashMap<K, T, H> {
|
||||||
|
#[inline(always)]
|
||||||
fn hash<B: Hasher>(&self, state: &mut B) {
|
fn hash<B: Hasher>(&self, state: &mut B) {
|
||||||
let mut keys: Vec<_> = self.0.keys().collect();
|
let mut keys: Vec<_> = self.0.keys().collect();
|
||||||
keys.sort();
|
keys.sort();
|
||||||
|
@ -55,20 +55,18 @@ 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 { source: None, statements: [Block([Const(BoolConstant(false, 1:20), Ident("DECISION" @ 1:9), false, 1:3), Expr(IntegerConstant(123, 1:53))], 1:1)], functions: Module("#));
|
assert!(format!("{:?}", ast).starts_with(r#"AST { source: None, body: [Block([Const(BoolConstant(false, 1:20), Ident("DECISION" @ 1:9), false, 1:3), Expr(IntegerConstant(123, 1:53))], 1:1)], functions: Module("#));
|
||||||
|
|
||||||
let ast = engine.compile("if 1 == 2 { 42 }")?;
|
let ast = engine.compile("if 1 == 2 { 42 }")?;
|
||||||
|
|
||||||
assert!(
|
assert!(format!("{:?}", ast).starts_with("AST { source: None, body: [], functions: Module("));
|
||||||
format!("{:?}", ast).starts_with("AST { source: None, statements: [], functions: Module(")
|
|
||||||
);
|
|
||||||
|
|
||||||
engine.set_optimization_level(OptimizationLevel::Full);
|
engine.set_optimization_level(OptimizationLevel::Full);
|
||||||
|
|
||||||
let ast = engine.compile("abs(-42)")?;
|
let ast = engine.compile("abs(-42)")?;
|
||||||
|
|
||||||
assert!(format!("{:?}", ast)
|
assert!(format!("{:?}", ast)
|
||||||
.starts_with(r"AST { source: None, statements: [Expr(IntegerConstant(42, 1:1))]"));
|
.starts_with(r"AST { source: None, body: [Expr(IntegerConstant(42, 1:1))]"));
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user