FunctionsLib always exist.

This commit is contained in:
Stephen Chung 2020-04-27 20:43:55 +08:00
parent b3e4659790
commit 43fdf3f962
3 changed files with 29 additions and 42 deletions

View File

@ -804,7 +804,7 @@ impl Engine {
ast.0 ast.0
.iter() .iter()
.try_fold(().into(), |_, stmt| { .try_fold(().into(), |_, stmt| {
self.eval_stmt(scope, Some(ast.1.as_ref()), stmt, 0) self.eval_stmt(scope, ast.1.as_ref(), stmt, 0)
}) })
.or_else(|err| match *err { .or_else(|err| match *err {
EvalAltResult::Return(out, _) => Ok(out), EvalAltResult::Return(out, _) => Ok(out),
@ -867,7 +867,7 @@ impl Engine {
ast.0 ast.0
.iter() .iter()
.try_fold(().into(), |_, stmt| { .try_fold(().into(), |_, stmt| {
self.eval_stmt(scope, Some(ast.1.as_ref()), stmt, 0) self.eval_stmt(scope, ast.1.as_ref(), stmt, 0)
}) })
.map_or_else( .map_or_else(
|err| match *err { |err| match *err {
@ -930,8 +930,7 @@ impl Engine {
.get_function(name, args.len()) .get_function(name, args.len())
.ok_or_else(|| Box::new(EvalAltResult::ErrorFunctionNotFound(name.to_string(), pos)))?; .ok_or_else(|| Box::new(EvalAltResult::ErrorFunctionNotFound(name.to_string(), pos)))?;
let result = let result = self.call_fn_from_lib(Some(scope), fn_lib, fn_def, &mut args, pos, 0)?;
self.call_fn_from_lib(Some(scope), Some(&fn_lib), fn_def, &mut args, pos, 0)?;
let return_type = self.map_type_name(result.type_name()); let return_type = self.map_type_name(result.type_name());

View File

@ -436,21 +436,14 @@ fn default_print(s: &str) {
/// Search for a variable within the scope, returning its value and index inside the Scope /// Search for a variable within the scope, returning its value and index inside the Scope
fn search_scope<'a>( fn search_scope<'a>(
scope: &'a mut Scope, scope: &'a mut Scope,
id: &str, name: &str,
begin: Position, begin: Position,
) -> Result<(&'a mut Dynamic, ScopeEntryType), Box<EvalAltResult>> { ) -> Result<(&'a mut Dynamic, ScopeEntryType), Box<EvalAltResult>> {
let ScopeSource { typ, index, .. } = scope let ScopeSource { typ, index, .. } = scope
.get(id) .get(name)
.ok_or_else(|| Box::new(EvalAltResult::ErrorVariableNotFound(id.into(), begin)))?; .ok_or_else(|| Box::new(EvalAltResult::ErrorVariableNotFound(name.into(), begin)))?;
Ok(( Ok((scope.get_mut(ScopeSource { name, typ, index }), typ))
scope.get_mut(ScopeSource {
name: id,
typ,
index,
}),
typ,
))
} }
impl Engine { impl Engine {
@ -512,7 +505,7 @@ impl Engine {
pub(crate) fn call_fn_raw( pub(crate) fn call_fn_raw(
&self, &self,
scope: Option<&mut Scope>, scope: Option<&mut Scope>,
fn_lib: Option<&FunctionsLib>, fn_lib: &FunctionsLib,
fn_name: &str, fn_name: &str,
args: &mut FnCallArgs, args: &mut FnCallArgs,
def_val: Option<&Dynamic>, def_val: Option<&Dynamic>,
@ -525,10 +518,10 @@ impl Engine {
} }
#[cfg(feature = "no_function")] #[cfg(feature = "no_function")]
const fn_lib: Option<&FunctionsLib> = None; const fn_lib: &FunctionsLib = None;
// First search in script-defined functions (can override built-in) // First search in script-defined functions (can override built-in)
if let Some(fn_def) = fn_lib.and_then(|lib| lib.get_function(fn_name, args.len())) { if let Some(fn_def) = fn_lib.get_function(fn_name, args.len()) {
return self.call_fn_from_lib(scope, fn_lib, fn_def, args, pos, level); return self.call_fn_from_lib(scope, fn_lib, fn_def, args, pos, level);
} }
@ -606,7 +599,7 @@ impl Engine {
pub(crate) fn call_fn_from_lib( pub(crate) fn call_fn_from_lib(
&self, &self,
scope: Option<&mut Scope>, scope: Option<&mut Scope>,
fn_lib: Option<&FunctionsLib>, fn_lib: &FunctionsLib,
fn_def: &FnDef, fn_def: &FnDef,
args: &mut FnCallArgs, args: &mut FnCallArgs,
pos: Position, pos: Position,
@ -666,7 +659,7 @@ impl Engine {
} }
// Has a system function an override? // Has a system function an override?
fn has_override(&self, fn_lib: Option<&FunctionsLib>, name: &str) -> bool { fn has_override(&self, fn_lib: &FunctionsLib, name: &str) -> bool {
let hash = calc_fn_hash(name, once(TypeId::of::<String>())); let hash = calc_fn_hash(name, once(TypeId::of::<String>()));
// First check registered functions // First check registered functions
@ -674,13 +667,13 @@ impl Engine {
// Then check packages // Then check packages
|| self.packages.iter().any(|p| p.functions.contains_key(&hash)) || self.packages.iter().any(|p| p.functions.contains_key(&hash))
// Then check script-defined functions // Then check script-defined functions
|| fn_lib.map_or(false, |lib| lib.has_function(name, 1)) || fn_lib.has_function(name, 1)
} }
// Perform an actual function call, taking care of special functions // Perform an actual function call, taking care of special functions
fn exec_fn_call( fn exec_fn_call(
&self, &self,
fn_lib: Option<&FunctionsLib>, fn_lib: &FunctionsLib,
fn_name: &str, fn_name: &str,
args: &mut [&mut Dynamic], args: &mut [&mut Dynamic],
def_val: Option<&Dynamic>, def_val: Option<&Dynamic>,
@ -709,7 +702,7 @@ impl Engine {
fn eval_script_expr( fn eval_script_expr(
&self, &self,
scope: &mut Scope, scope: &mut Scope,
fn_lib: Option<&FunctionsLib>, fn_lib: &FunctionsLib,
script: &Dynamic, script: &Dynamic,
pos: Position, pos: Position,
) -> Result<Dynamic, Box<EvalAltResult>> { ) -> Result<Dynamic, Box<EvalAltResult>> {
@ -732,15 +725,13 @@ impl Engine {
))); )));
} }
if let Some(lib) = fn_lib { #[cfg(feature = "sync")]
#[cfg(feature = "sync")] {
{ ast.1 = Arc::new(fn_lib.clone());
ast.1 = Arc::new(lib.clone()); }
} #[cfg(not(feature = "sync"))]
#[cfg(not(feature = "sync"))] {
{ ast.1 = Rc::new(fn_lib.clone());
ast.1 = Rc::new(lib.clone());
}
} }
// Evaluate the AST // Evaluate the AST
@ -751,7 +742,7 @@ impl Engine {
/// Chain-evaluate a dot/index chain. /// Chain-evaluate a dot/index chain.
fn eval_dot_index_chain_helper( fn eval_dot_index_chain_helper(
&self, &self,
fn_lib: Option<&FunctionsLib>, fn_lib: &FunctionsLib,
mut target: Target, mut target: Target,
rhs: &Expr, rhs: &Expr,
idx_values: &mut StaticVec, idx_values: &mut StaticVec,
@ -896,7 +887,7 @@ impl Engine {
fn eval_dot_index_chain( fn eval_dot_index_chain(
&self, &self,
scope: &mut Scope, scope: &mut Scope,
fn_lib: Option<&FunctionsLib>, fn_lib: &FunctionsLib,
dot_lhs: &Expr, dot_lhs: &Expr,
dot_rhs: &Expr, dot_rhs: &Expr,
is_index: bool, is_index: bool,
@ -969,7 +960,7 @@ impl Engine {
fn eval_indexed_chain( fn eval_indexed_chain(
&self, &self,
scope: &mut Scope, scope: &mut Scope,
fn_lib: Option<&FunctionsLib>, fn_lib: &FunctionsLib,
expr: &Expr, expr: &Expr,
idx_values: &mut StaticVec, idx_values: &mut StaticVec,
size: usize, size: usize,
@ -1083,7 +1074,7 @@ impl Engine {
fn eval_in_expr( fn eval_in_expr(
&self, &self,
scope: &mut Scope, scope: &mut Scope,
fn_lib: Option<&FunctionsLib>, fn_lib: &FunctionsLib,
lhs: &Expr, lhs: &Expr,
rhs: &Expr, rhs: &Expr,
level: usize, level: usize,
@ -1136,7 +1127,7 @@ impl Engine {
fn eval_expr( fn eval_expr(
&self, &self,
scope: &mut Scope, scope: &mut Scope,
fn_lib: Option<&FunctionsLib>, fn_lib: &FunctionsLib,
expr: &Expr, expr: &Expr,
level: usize, level: usize,
) -> Result<Dynamic, Box<EvalAltResult>> { ) -> Result<Dynamic, Box<EvalAltResult>> {
@ -1325,7 +1316,7 @@ impl Engine {
pub(crate) fn eval_stmt( pub(crate) fn eval_stmt(
&self, &self,
scope: &mut Scope, scope: &mut Scope,
fn_lib: Option<&FunctionsLib>, fn_lib: &FunctionsLib,
stmt: &Stmt, stmt: &Stmt,
level: usize, level: usize,
) -> Result<Dynamic, Box<EvalAltResult>> { ) -> Result<Dynamic, Box<EvalAltResult>> {

View File

@ -392,10 +392,7 @@ impl Default for Scope<'_> {
} }
} }
impl<'a, K> iter::Extend<(K, EntryType, Dynamic)> for Scope<'a> impl<'a, K: Into<Cow<'a, str>>> iter::Extend<(K, EntryType, Dynamic)> for Scope<'a> {
where
K: Into<Cow<'a, str>>,
{
fn extend<T: IntoIterator<Item = (K, EntryType, Dynamic)>>(&mut self, iter: T) { fn extend<T: IntoIterator<Item = (K, EntryType, Dynamic)>>(&mut self, iter: T) {
self.0 self.0
.extend(iter.into_iter().map(|(name, typ, value)| Entry { .extend(iter.into_iter().map(|(name, typ, value)| Entry {