From 02057ef1d2b828f905533c25b30f3029ca78bd0a Mon Sep 17 00:00:00 2001 From: Stephen Chung Date: Wed, 24 Feb 2021 23:23:32 +0800 Subject: [PATCH] Avoid double checking of builtin's. --- src/fn_call.rs | 30 +++++++++++++----------------- src/token.rs | 12 ++++++++++++ 2 files changed, 25 insertions(+), 17 deletions(-) diff --git a/src/fn_call.rs b/src/fn_call.rs index 9b730c7f..c39d90cd 100644 --- a/src/fn_call.rs +++ b/src/fn_call.rs @@ -21,6 +21,7 @@ use crate::stdlib::{ string::ToString, vec::Vec, }; +use crate::token::is_assignment_operator; use crate::utils::combine_hashes; use crate::{ calc_native_fn_hash, calc_script_fn_hash, Dynamic, Engine, EvalAltResult, FnPtr, @@ -285,25 +286,20 @@ impl Engine { // See if it is built in. if args.len() == 2 && !args[0].is_variant() && !args[1].is_variant() { - match run_builtin_binary_op(fn_name, args[0], args[1])? { - Some(v) => return Ok((v, false)), - None => (), - } + if is_assignment_operator(fn_name) { + if is_ref { + // Op-assignment + let (first, second) = args.split_first_mut().unwrap(); - // Op-assignment? - if is_ref { - match fn_name { - _ if fn_name.len() <= 1 => (), - "==" | "!=" | ">=" | "<=" => (), - _ if fn_name.ends_with('=') => { - let (first, second) = args.split_first_mut().unwrap(); - - match run_builtin_op_assignment(fn_name, first, second[0])? { - Some(_) => return Ok((Dynamic::UNIT, false)), - None => (), - } + match run_builtin_op_assignment(fn_name, first, second[0])? { + Some(_) => return Ok((Dynamic::UNIT, false)), + None => (), } - _ => (), + } + } else { + match run_builtin_binary_op(fn_name, args[0], args[1])? { + Some(v) => return Ok((v, false)), + None => (), } } } diff --git a/src/token.rs b/src/token.rs index 7221027c..7e2c7b42 100644 --- a/src/token.rs +++ b/src/token.rs @@ -1657,24 +1657,36 @@ pub fn is_valid_identifier(name: impl Iterator) -> bool { first_alphabetic } +/// Is a text string an assignment operator? +pub fn is_assignment_operator(op: &str) -> bool { + match op { + "+=" | "-=" | "*=" | "/=" | "<<=" | ">>=" | "&=" | "|=" | "^=" | "%=" | "**=" => true, + _ => false, + } +} + +/// Is a character valid to start an identifier? #[cfg(feature = "unicode-xid-ident")] #[inline(always)] pub fn is_id_first_alphabetic(x: char) -> bool { unicode_xid::UnicodeXID::is_xid_start(x) } +/// Is a character valid for an identifier? #[cfg(feature = "unicode-xid-ident")] #[inline(always)] pub fn is_id_continue(x: char) -> bool { unicode_xid::UnicodeXID::is_xid_continue(x) } +/// Is a character valid to start an identifier? #[cfg(not(feature = "unicode-xid-ident"))] #[inline(always)] pub fn is_id_first_alphabetic(x: char) -> bool { x.is_ascii_alphabetic() } +/// Is a character valid for an identifier? #[cfg(not(feature = "unicode-xid-ident"))] #[inline(always)] pub fn is_id_continue(x: char) -> bool {