Optimize Fn construct.
This commit is contained in:
parent
d3cfb3c605
commit
131147c65d
@ -13,8 +13,8 @@ use crate::stdlib::{
|
|||||||
};
|
};
|
||||||
use crate::token::is_valid_identifier;
|
use crate::token::is_valid_identifier;
|
||||||
use crate::{
|
use crate::{
|
||||||
calc_fn_hash, Dynamic, Engine, EvalAltResult, EvalContext, ImmutableString, Module, Position,
|
calc_fn_hash, Dynamic, Engine, EvalAltResult, EvalContext, Identifier, ImmutableString, Module,
|
||||||
RhaiResult, StaticVec,
|
Position, RhaiResult, StaticVec,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Trait that maps to `Send + Sync` only under the `sync` feature.
|
/// Trait that maps to `Send + Sync` only under the `sync` feature.
|
||||||
@ -252,20 +252,17 @@ pub type FnCallArgs<'a> = [&'a mut Dynamic];
|
|||||||
/// A general function pointer, which may carry additional (i.e. curried) argument values
|
/// A general function pointer, which may carry additional (i.e. curried) argument values
|
||||||
/// to be passed onto a function during a call.
|
/// to be passed onto a function during a call.
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct FnPtr(ImmutableString, StaticVec<Dynamic>);
|
pub struct FnPtr(Identifier, StaticVec<Dynamic>);
|
||||||
|
|
||||||
impl FnPtr {
|
impl FnPtr {
|
||||||
/// Create a new function pointer.
|
/// Create a new function pointer.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn new(name: impl Into<ImmutableString>) -> Result<Self, Box<EvalAltResult>> {
|
pub fn new(name: impl Into<Identifier>) -> Result<Self, Box<EvalAltResult>> {
|
||||||
name.into().try_into()
|
name.into().try_into()
|
||||||
}
|
}
|
||||||
/// Create a new function pointer without checking its parameters.
|
/// Create a new function pointer without checking its parameters.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub(crate) fn new_unchecked(
|
pub(crate) fn new_unchecked(name: impl Into<Identifier>, curry: StaticVec<Dynamic>) -> Self {
|
||||||
name: impl Into<ImmutableString>,
|
|
||||||
curry: StaticVec<Dynamic>,
|
|
||||||
) -> Self {
|
|
||||||
Self(name.into(), curry)
|
Self(name.into(), curry)
|
||||||
}
|
}
|
||||||
/// Get the name of the function.
|
/// Get the name of the function.
|
||||||
@ -275,12 +272,12 @@ impl FnPtr {
|
|||||||
}
|
}
|
||||||
/// Get the name of the function.
|
/// Get the name of the function.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub(crate) fn get_fn_name(&self) -> &ImmutableString {
|
pub(crate) fn get_fn_name(&self) -> &Identifier {
|
||||||
&self.0
|
&self.0
|
||||||
}
|
}
|
||||||
/// Get the underlying data of the function pointer.
|
/// Get the underlying data of the function pointer.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub(crate) fn take_data(self) -> (ImmutableString, StaticVec<Dynamic>) {
|
pub(crate) fn take_data(self) -> (Identifier, StaticVec<Dynamic>) {
|
||||||
(self.0, self.1)
|
(self.0, self.1)
|
||||||
}
|
}
|
||||||
/// Get the curried arguments.
|
/// Get the curried arguments.
|
||||||
@ -362,11 +359,11 @@ impl fmt::Display for FnPtr {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TryFrom<ImmutableString> for FnPtr {
|
impl TryFrom<Identifier> for FnPtr {
|
||||||
type Error = Box<EvalAltResult>;
|
type Error = Box<EvalAltResult>;
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn try_from(value: ImmutableString) -> Result<Self, Self::Error> {
|
fn try_from(value: Identifier) -> Result<Self, Self::Error> {
|
||||||
if is_valid_identifier(value.chars()) {
|
if is_valid_identifier(value.chars()) {
|
||||||
Ok(Self(value, Default::default()))
|
Ok(Self(value, Default::default()))
|
||||||
} else {
|
} else {
|
||||||
@ -375,12 +372,22 @@ impl TryFrom<ImmutableString> for FnPtr {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl TryFrom<ImmutableString> for FnPtr {
|
||||||
|
type Error = Box<EvalAltResult>;
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
fn try_from(value: ImmutableString) -> Result<Self, Self::Error> {
|
||||||
|
let s: Identifier = value.into();
|
||||||
|
Self::try_from(s)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl TryFrom<String> for FnPtr {
|
impl TryFrom<String> for FnPtr {
|
||||||
type Error = Box<EvalAltResult>;
|
type Error = Box<EvalAltResult>;
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn try_from(value: String) -> Result<Self, Self::Error> {
|
fn try_from(value: String) -> Result<Self, Self::Error> {
|
||||||
let s: ImmutableString = value.into();
|
let s: Identifier = value.into();
|
||||||
Self::try_from(s)
|
Self::try_from(s)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -390,7 +397,7 @@ impl TryFrom<&str> for FnPtr {
|
|||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn try_from(value: &str) -> Result<Self, Self::Error> {
|
fn try_from(value: &str) -> Result<Self, Self::Error> {
|
||||||
let s: ImmutableString = value.into();
|
let s: Identifier = value.into();
|
||||||
Self::try_from(s)
|
Self::try_from(s)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
use crate::ast::{Expr, Stmt, StmtBlock};
|
use crate::ast::{Expr, Stmt, StmtBlock};
|
||||||
use crate::dynamic::AccessMode;
|
use crate::dynamic::AccessMode;
|
||||||
use crate::engine::{KEYWORD_DEBUG, KEYWORD_EVAL, KEYWORD_PRINT, KEYWORD_TYPE_OF};
|
use crate::engine::{KEYWORD_DEBUG, KEYWORD_EVAL, KEYWORD_FN_PTR, KEYWORD_PRINT, KEYWORD_TYPE_OF};
|
||||||
use crate::fn_builtin::get_builtin_binary_op_fn;
|
use crate::fn_builtin::get_builtin_binary_op_fn;
|
||||||
use crate::parser::map_dynamic_to_expr;
|
use crate::parser::map_dynamic_to_expr;
|
||||||
use crate::stdlib::{
|
use crate::stdlib::{
|
||||||
@ -794,6 +794,22 @@ fn optimize_expr(expr: &mut Expr, state: &mut State) {
|
|||||||
Expr::FnCall(x, _) if x.name == KEYWORD_EVAL => {
|
Expr::FnCall(x, _) if x.name == KEYWORD_EVAL => {
|
||||||
state.propagate_constants = false;
|
state.propagate_constants = false;
|
||||||
}
|
}
|
||||||
|
// Fn
|
||||||
|
Expr::FnCall(x, pos)
|
||||||
|
if x.namespace.is_none() // Non-qualified
|
||||||
|
&& state.optimization_level == OptimizationLevel::Simple // simple optimizations
|
||||||
|
&& x.num_args() == 1
|
||||||
|
&& matches!(x.args[0], Expr::StringConstant(_, _))
|
||||||
|
&& x.name == KEYWORD_FN_PTR
|
||||||
|
=> {
|
||||||
|
if let Expr::StringConstant(s, _) = mem::take(&mut x.args[0]) {
|
||||||
|
state.set_dirty();
|
||||||
|
*expr = Expr::FnPointer(s, *pos);
|
||||||
|
} else {
|
||||||
|
unreachable!();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Do not call some special keywords
|
// Do not call some special keywords
|
||||||
Expr::FnCall(x, _) if DONT_EVAL_KEYWORDS.contains(&x.name.as_ref()) => {
|
Expr::FnCall(x, _) if DONT_EVAL_KEYWORDS.contains(&x.name.as_ref()) => {
|
||||||
x.args.iter_mut().for_each(|a| optimize_expr(a, state));
|
x.args.iter_mut().for_each(|a| optimize_expr(a, state));
|
||||||
|
Loading…
Reference in New Issue
Block a user