Add short-cut to !.
This commit is contained in:
parent
fc4c8731f0
commit
acadb58f4f
@ -52,6 +52,9 @@ pub const FN_ANONYMOUS: &str = "anon$";
|
|||||||
/// function to compare two [`Dynamic`] values.
|
/// function to compare two [`Dynamic`] values.
|
||||||
pub const OP_EQUALS: &str = Token::EqualsTo.literal_syntax();
|
pub const OP_EQUALS: &str = Token::EqualsTo.literal_syntax();
|
||||||
|
|
||||||
|
/// Standard not operator.
|
||||||
|
pub const OP_NOT: &str = Token::Bang.literal_syntax();
|
||||||
|
|
||||||
/// Standard concatenation operator.
|
/// Standard concatenation operator.
|
||||||
///
|
///
|
||||||
/// Used primarily to build up interpolated strings.
|
/// Used primarily to build up interpolated strings.
|
||||||
|
@ -325,9 +325,9 @@ impl Engine {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// # Main Entry-Point
|
/// # Main Entry-Point (Native by Name)
|
||||||
///
|
///
|
||||||
/// Call a native Rust function registered with the [`Engine`].
|
/// Call a native Rust function registered with the [`Engine`] by name.
|
||||||
///
|
///
|
||||||
/// # WARNING
|
/// # WARNING
|
||||||
///
|
///
|
||||||
@ -543,9 +543,9 @@ impl Engine {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// # Main Entry-Point
|
/// # Main Entry-Point (By Name)
|
||||||
///
|
///
|
||||||
/// Perform an actual function call, native Rust or scripted, taking care of special functions.
|
/// Perform an actual function call, native Rust or scripted, by name, taking care of special functions.
|
||||||
///
|
///
|
||||||
/// # WARNING
|
/// # WARNING
|
||||||
///
|
///
|
||||||
@ -1463,6 +1463,8 @@ impl Engine {
|
|||||||
self.eval_global_statements(global, caches, scope, statements)
|
self.eval_global_statements(global, caches, scope, statements)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// # Main Entry-Point (`FnCallExpr`)
|
||||||
|
///
|
||||||
/// Evaluate a function call expression.
|
/// Evaluate a function call expression.
|
||||||
pub(crate) fn eval_fn_call_expr(
|
pub(crate) fn eval_fn_call_expr(
|
||||||
&self,
|
&self,
|
||||||
@ -1486,6 +1488,22 @@ impl Engine {
|
|||||||
|
|
||||||
let op_token = op_token.clone();
|
let op_token = op_token.clone();
|
||||||
|
|
||||||
|
// Short-circuit native unary operator call if under Fast Operators mode
|
||||||
|
if op_token == Token::Bang && self.fast_operators() && args.len() == 1 {
|
||||||
|
let mut value = self
|
||||||
|
.get_arg_value(global, caches, scope, this_ptr, &args[0])?
|
||||||
|
.0
|
||||||
|
.flatten();
|
||||||
|
|
||||||
|
return value.as_bool().and_then(|r| Ok((!r).into())).or_else(|_| {
|
||||||
|
let operand = &mut [&mut value];
|
||||||
|
self.exec_fn_call(
|
||||||
|
global, caches, None, name, op_token, *hashes, operand, false, false, pos,
|
||||||
|
)
|
||||||
|
.map(|(v, ..)| v)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// Short-circuit native binary operator call if under Fast Operators mode
|
// Short-circuit native binary operator call if under Fast Operators mode
|
||||||
if op_token != NO_TOKEN && self.fast_operators() && args.len() == 2 {
|
if op_token != NO_TOKEN && self.fast_operators() && args.len() == 2 {
|
||||||
let mut lhs = self
|
let mut lhs = self
|
||||||
|
@ -4,7 +4,9 @@
|
|||||||
use crate::ast::{
|
use crate::ast::{
|
||||||
ASTFlags, Expr, OpAssignment, Stmt, StmtBlock, StmtBlockContainer, SwitchCasesCollection,
|
ASTFlags, Expr, OpAssignment, Stmt, StmtBlock, StmtBlockContainer, SwitchCasesCollection,
|
||||||
};
|
};
|
||||||
use crate::engine::{KEYWORD_DEBUG, KEYWORD_EVAL, KEYWORD_FN_PTR, KEYWORD_PRINT, KEYWORD_TYPE_OF};
|
use crate::engine::{
|
||||||
|
KEYWORD_DEBUG, KEYWORD_EVAL, KEYWORD_FN_PTR, KEYWORD_PRINT, KEYWORD_TYPE_OF, OP_NOT,
|
||||||
|
};
|
||||||
use crate::eval::{Caches, GlobalRuntimeState};
|
use crate::eval::{Caches, GlobalRuntimeState};
|
||||||
use crate::func::builtin::get_builtin_binary_op_fn;
|
use crate::func::builtin::get_builtin_binary_op_fn;
|
||||||
use crate::func::hashing::get_hasher;
|
use crate::func::hashing::get_hasher;
|
||||||
@ -1065,6 +1067,20 @@ fn optimize_expr(expr: &mut Expr, state: &mut OptimizerState, _chaining: bool) {
|
|||||||
*expr = mem::take(&mut x.lhs);
|
*expr = mem::take(&mut x.lhs);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// !true or !false
|
||||||
|
Expr::FnCall(x,..)
|
||||||
|
if x.name == OP_NOT
|
||||||
|
&& x.args.len() == 1
|
||||||
|
&& matches!(x.args[0], Expr::BoolConstant(..))
|
||||||
|
=> {
|
||||||
|
state.set_dirty();
|
||||||
|
if let Expr::BoolConstant(b, pos) = x.args[0] {
|
||||||
|
*expr = Expr::BoolConstant(!b, pos)
|
||||||
|
} else {
|
||||||
|
unreachable!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// eval!
|
// eval!
|
||||||
Expr::FnCall(x, ..) if x.name == KEYWORD_EVAL => {
|
Expr::FnCall(x, ..) if x.name == KEYWORD_EVAL => {
|
||||||
state.propagate_constants = false;
|
state.propagate_constants = false;
|
||||||
|
Loading…
Reference in New Issue
Block a user