Minor refactors.
This commit is contained in:
parent
1b3d5aeb53
commit
99118fe2c3
@ -17,6 +17,11 @@ Bug fixes
|
|||||||
* Exporting a variable that contains a local function pointer (including anonymous function or closure) now raises a runtime error.
|
* Exporting a variable that contains a local function pointer (including anonymous function or closure) now raises a runtime error.
|
||||||
* Full optimization is now skipped for method calls.
|
* Full optimization is now skipped for method calls.
|
||||||
|
|
||||||
|
New features
|
||||||
|
------------
|
||||||
|
|
||||||
|
* [Type aliases](https://doc.rust-lang.org/reference/items/type-aliases.html) in plugin modules are now used as friendly names for custom types. This makes plugin modules more self-contained when they are used to define a custom type's API.
|
||||||
|
|
||||||
Enhancements
|
Enhancements
|
||||||
------------
|
------------
|
||||||
|
|
||||||
|
@ -269,7 +269,7 @@ pub fn exported_module(module_path: proc_macro::TokenStream) -> proc_macro::Toke
|
|||||||
pub fn combine_with_exported_module(args: proc_macro::TokenStream) -> proc_macro::TokenStream {
|
pub fn combine_with_exported_module(args: proc_macro::TokenStream) -> proc_macro::TokenStream {
|
||||||
match crate::register::parse_register_macro(args) {
|
match crate::register::parse_register_macro(args) {
|
||||||
Ok((module_expr, _export_name, module_path)) => proc_macro::TokenStream::from(quote! {
|
Ok((module_expr, _export_name, module_path)) => proc_macro::TokenStream::from(quote! {
|
||||||
#module_path::rhai_generate_into_module(#module_expr, true);
|
#module_path::rhai_generate_into_module(#module_expr, true)
|
||||||
}),
|
}),
|
||||||
Err(e) => e.to_compile_error().into(),
|
Err(e) => e.to_compile_error().into(),
|
||||||
}
|
}
|
||||||
@ -303,7 +303,7 @@ pub fn register_exported_fn(args: proc_macro::TokenStream) -> proc_macro::TokenS
|
|||||||
Ok((engine_expr, export_name, rust_mod_path)) => {
|
Ok((engine_expr, export_name, rust_mod_path)) => {
|
||||||
let gen_mod_path = crate::register::generated_module_path(&rust_mod_path);
|
let gen_mod_path = crate::register::generated_module_path(&rust_mod_path);
|
||||||
proc_macro::TokenStream::from(quote! {
|
proc_macro::TokenStream::from(quote! {
|
||||||
#engine_expr.register_result_fn(#export_name, #gen_mod_path::dynamic_result_fn);
|
#engine_expr.register_result_fn(#export_name, #gen_mod_path::dynamic_result_fn)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
Err(e) => e.to_compile_error().into(),
|
Err(e) => e.to_compile_error().into(),
|
||||||
@ -352,7 +352,7 @@ pub fn set_exported_fn(args: proc_macro::TokenStream) -> proc_macro::TokenStream
|
|||||||
#module_expr.set_fn(#export_name, FnNamespace::Internal, FnAccess::Public,
|
#module_expr.set_fn(#export_name, FnNamespace::Internal, FnAccess::Public,
|
||||||
#param_names,
|
#param_names,
|
||||||
&#gen_mod_path::Token::param_types(),
|
&#gen_mod_path::Token::param_types(),
|
||||||
#gen_mod_path::Token().into());
|
#gen_mod_path::Token().into())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
Err(e) => e.to_compile_error().into(),
|
Err(e) => e.to_compile_error().into(),
|
||||||
@ -401,7 +401,7 @@ pub fn set_exported_global_fn(args: proc_macro::TokenStream) -> proc_macro::Toke
|
|||||||
#module_expr.set_fn(#export_name, FnNamespace::Global, FnAccess::Public,
|
#module_expr.set_fn(#export_name, FnNamespace::Global, FnAccess::Public,
|
||||||
#param_names,
|
#param_names,
|
||||||
&#gen_mod_path::Token::param_types(),
|
&#gen_mod_path::Token::param_types(),
|
||||||
#gen_mod_path::Token().into());
|
#gen_mod_path::Token().into())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
Err(e) => e.to_compile_error().into(),
|
Err(e) => e.to_compile_error().into(),
|
||||||
|
@ -140,20 +140,18 @@ impl Parse for Module {
|
|||||||
for item in content.iter() {
|
for item in content.iter() {
|
||||||
match item {
|
match item {
|
||||||
syn::Item::Const(syn::ItemConst {
|
syn::Item::Const(syn::ItemConst {
|
||||||
vis,
|
vis: syn::Visibility::Public(..),
|
||||||
ref expr,
|
ref expr,
|
||||||
ident,
|
ident,
|
||||||
attrs,
|
attrs,
|
||||||
ty,
|
ty,
|
||||||
..
|
..
|
||||||
}) if matches!(vis, syn::Visibility::Public(..)) => {
|
}) => consts.push(ExportedConst {
|
||||||
consts.push(ExportedConst {
|
name: ident.to_string(),
|
||||||
name: ident.to_string(),
|
typ: ty.clone(),
|
||||||
typ: ty.clone(),
|
expr: expr.as_ref().clone(),
|
||||||
expr: expr.as_ref().clone(),
|
cfg_attrs: crate::attrs::collect_cfg_attr(&attrs),
|
||||||
cfg_attrs: crate::attrs::collect_cfg_attr(&attrs),
|
}),
|
||||||
})
|
|
||||||
}
|
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -161,18 +159,16 @@ impl Parse for Module {
|
|||||||
for item in content.iter() {
|
for item in content.iter() {
|
||||||
match item {
|
match item {
|
||||||
syn::Item::Type(syn::ItemType {
|
syn::Item::Type(syn::ItemType {
|
||||||
vis,
|
vis: syn::Visibility::Public(..),
|
||||||
ident,
|
ident,
|
||||||
attrs,
|
attrs,
|
||||||
ty,
|
ty,
|
||||||
..
|
..
|
||||||
}) if matches!(vis, syn::Visibility::Public(..)) => {
|
}) => custom_types.push(ExportedType {
|
||||||
custom_types.push(ExportedType {
|
name: ident.to_string(),
|
||||||
name: ident.to_string(),
|
typ: ty.clone(),
|
||||||
typ: ty.clone(),
|
cfg_attrs: crate::attrs::collect_cfg_attr(&attrs),
|
||||||
cfg_attrs: crate::attrs::collect_cfg_attr(&attrs),
|
}),
|
||||||
})
|
|
||||||
}
|
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -115,33 +115,34 @@ impl Engine {
|
|||||||
|
|
||||||
let mut ast = self.compile_scripts_with_scope(scope, &[script])?;
|
let mut ast = self.compile_scripts_with_scope(scope, &[script])?;
|
||||||
|
|
||||||
if let Some(ref module_resolver) = self.module_resolver {
|
let mut resolver = StaticModuleResolver::new();
|
||||||
let mut resolver = StaticModuleResolver::new();
|
let mut imports = BTreeSet::new();
|
||||||
let mut imports = BTreeSet::new();
|
|
||||||
|
|
||||||
collect_imports(&ast, &resolver, &mut imports);
|
collect_imports(&ast, &resolver, &mut imports);
|
||||||
|
|
||||||
if !imports.is_empty() {
|
if !imports.is_empty() {
|
||||||
while let Some(path) = imports.iter().next() {
|
while let Some(path) = imports.iter().next() {
|
||||||
let path = path.clone();
|
let path = path.clone();
|
||||||
|
|
||||||
match module_resolver.resolve_ast(self, None, &path, crate::Position::NONE) {
|
match self
|
||||||
Some(Ok(module_ast)) => {
|
.module_resolver
|
||||||
collect_imports(&module_ast, &resolver, &mut imports)
|
.resolve_ast(self, None, &path, crate::Position::NONE)
|
||||||
}
|
{
|
||||||
Some(err) => return err,
|
Some(Ok(module_ast)) => collect_imports(&module_ast, &resolver, &mut imports),
|
||||||
None => (),
|
Some(err) => return err,
|
||||||
}
|
None => (),
|
||||||
|
|
||||||
let module =
|
|
||||||
module_resolver.resolve(self, None, &path, crate::Position::NONE)?;
|
|
||||||
let module = shared_take_or_clone(module);
|
|
||||||
|
|
||||||
imports.remove(&path);
|
|
||||||
resolver.insert(path, module);
|
|
||||||
}
|
}
|
||||||
ast.set_resolver(resolver);
|
|
||||||
|
let module =
|
||||||
|
self.module_resolver
|
||||||
|
.resolve(self, None, &path, crate::Position::NONE)?;
|
||||||
|
|
||||||
|
let module = shared_take_or_clone(module);
|
||||||
|
|
||||||
|
imports.remove(&path);
|
||||||
|
resolver.insert(path, module);
|
||||||
}
|
}
|
||||||
|
ast.set_resolver(resolver);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(ast)
|
Ok(ast)
|
||||||
|
@ -282,7 +282,7 @@ impl Engine {
|
|||||||
/// ```
|
/// ```
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn on_print(&mut self, callback: impl Fn(&str) + SendSync + 'static) -> &mut Self {
|
pub fn on_print(&mut self, callback: impl Fn(&str) + SendSync + 'static) -> &mut Self {
|
||||||
self.print = Some(Box::new(callback));
|
self.print = Box::new(callback);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
/// Override default action of `debug` (print to stdout using [`println!`])
|
/// Override default action of `debug` (print to stdout using [`println!`])
|
||||||
@ -332,7 +332,7 @@ impl Engine {
|
|||||||
&mut self,
|
&mut self,
|
||||||
callback: impl Fn(&str, Option<&str>, Position) + SendSync + 'static,
|
callback: impl Fn(&str, Option<&str>, Position) + SendSync + 'static,
|
||||||
) -> &mut Self {
|
) -> &mut Self {
|
||||||
self.debug = Some(Box::new(callback));
|
self.debug = Box::new(callback);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
/// _(debugging)_ Register a callback for debugging.
|
/// _(debugging)_ Register a callback for debugging.
|
||||||
|
@ -71,7 +71,7 @@ impl Engine {
|
|||||||
&mut self,
|
&mut self,
|
||||||
resolver: impl crate::ModuleResolver + 'static,
|
resolver: impl crate::ModuleResolver + 'static,
|
||||||
) -> &mut Self {
|
) -> &mut Self {
|
||||||
self.module_resolver = Some(Box::new(resolver));
|
self.module_resolver = Box::new(resolver);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -150,9 +150,10 @@ impl AST {
|
|||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn source(&self) -> Option<&str> {
|
pub fn source(&self) -> Option<&str> {
|
||||||
match self.source.as_str() {
|
if self.source.is_empty() {
|
||||||
"" => None,
|
None
|
||||||
s => Some(s),
|
} else {
|
||||||
|
Some(self.source.as_str())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/// Get a reference to the source.
|
/// Get a reference to the source.
|
||||||
|
@ -89,6 +89,26 @@ pub struct ConditionalStmtBlock {
|
|||||||
pub statements: StmtBlock,
|
pub statements: StmtBlock,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<B: Into<StmtBlock>> From<B> for ConditionalStmtBlock {
|
||||||
|
#[inline(always)]
|
||||||
|
fn from(value: B) -> Self {
|
||||||
|
Self {
|
||||||
|
condition: None,
|
||||||
|
statements: value.into(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<B: Into<StmtBlock>> From<(Expr, B)> for ConditionalStmtBlock {
|
||||||
|
#[inline(always)]
|
||||||
|
fn from(value: (Expr, B)) -> Self {
|
||||||
|
Self {
|
||||||
|
condition: Some(value.0),
|
||||||
|
statements: value.1.into(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<B: Into<StmtBlock>> From<(Option<Expr>, B)> for ConditionalStmtBlock {
|
impl<B: Into<StmtBlock>> From<(Option<Expr>, B)> for ConditionalStmtBlock {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn from(value: (Option<Expr>, B)) -> Self {
|
fn from(value: (Option<Expr>, B)) -> Self {
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
//! Main module defining the script evaluation [`Engine`].
|
//! Main module defining the script evaluation [`Engine`].
|
||||||
|
|
||||||
use crate::api::custom_syntax::CustomSyntax;
|
use crate::api::custom_syntax::CustomSyntax;
|
||||||
|
use crate::api::options::LanguageOptions;
|
||||||
use crate::func::native::{
|
use crate::func::native::{
|
||||||
OnDebugCallback, OnDefVarCallback, OnParseTokenCallback, OnPrintCallback, OnVarCallback,
|
OnDebugCallback, OnDefVarCallback, OnParseTokenCallback, OnPrintCallback, OnVarCallback,
|
||||||
};
|
};
|
||||||
@ -102,7 +103,7 @@ pub struct Engine {
|
|||||||
|
|
||||||
/// A module resolution service.
|
/// A module resolution service.
|
||||||
#[cfg(not(feature = "no_module"))]
|
#[cfg(not(feature = "no_module"))]
|
||||||
pub(crate) module_resolver: Option<Box<dyn crate::ModuleResolver>>,
|
pub(crate) module_resolver: Box<dyn crate::ModuleResolver>,
|
||||||
|
|
||||||
/// A map mapping type names to pretty-print names.
|
/// A map mapping type names to pretty-print names.
|
||||||
pub(crate) custom_types: CustomTypesCollection,
|
pub(crate) custom_types: CustomTypesCollection,
|
||||||
@ -124,9 +125,9 @@ pub struct Engine {
|
|||||||
pub(crate) token_mapper: Option<Box<OnParseTokenCallback>>,
|
pub(crate) token_mapper: Option<Box<OnParseTokenCallback>>,
|
||||||
|
|
||||||
/// Callback closure for implementing the `print` command.
|
/// Callback closure for implementing the `print` command.
|
||||||
pub(crate) print: Option<Box<OnPrintCallback>>,
|
pub(crate) print: Box<OnPrintCallback>,
|
||||||
/// Callback closure for implementing the `debug` command.
|
/// Callback closure for implementing the `debug` command.
|
||||||
pub(crate) debug: Option<Box<OnDebugCallback>>,
|
pub(crate) debug: Box<OnDebugCallback>,
|
||||||
/// Callback closure for progress reporting.
|
/// Callback closure for progress reporting.
|
||||||
#[cfg(not(feature = "unchecked"))]
|
#[cfg(not(feature = "unchecked"))]
|
||||||
pub(crate) progress: Option<Box<crate::func::native::OnProgressCallback>>,
|
pub(crate) progress: Option<Box<crate::func::native::OnProgressCallback>>,
|
||||||
@ -135,7 +136,7 @@ pub struct Engine {
|
|||||||
pub(crate) optimization_level: OptimizationLevel,
|
pub(crate) optimization_level: OptimizationLevel,
|
||||||
|
|
||||||
/// Language options.
|
/// Language options.
|
||||||
pub(crate) options: crate::api::options::LanguageOptions,
|
pub(crate) options: LanguageOptions,
|
||||||
|
|
||||||
/// Max limits.
|
/// Max limits.
|
||||||
#[cfg(not(feature = "unchecked"))]
|
#[cfg(not(feature = "unchecked"))]
|
||||||
@ -157,8 +158,7 @@ impl fmt::Debug for Engine {
|
|||||||
f.field("global_modules", &self.global_modules);
|
f.field("global_modules", &self.global_modules);
|
||||||
|
|
||||||
#[cfg(not(feature = "no_module"))]
|
#[cfg(not(feature = "no_module"))]
|
||||||
f.field("global_sub_modules", &self.global_sub_modules)
|
f.field("global_sub_modules", &self.global_sub_modules);
|
||||||
.field("module_resolver", &self.module_resolver.is_some());
|
|
||||||
|
|
||||||
f.field("type_names", &self.custom_types)
|
f.field("type_names", &self.custom_types)
|
||||||
.field("disabled_symbols", &self.disabled_symbols)
|
.field("disabled_symbols", &self.disabled_symbols)
|
||||||
@ -166,9 +166,7 @@ impl fmt::Debug for Engine {
|
|||||||
.field("custom_syntax", &(!self.custom_syntax.is_empty()))
|
.field("custom_syntax", &(!self.custom_syntax.is_empty()))
|
||||||
.field("def_var_filter", &self.def_var_filter.is_some())
|
.field("def_var_filter", &self.def_var_filter.is_some())
|
||||||
.field("resolve_var", &self.resolve_var.is_some())
|
.field("resolve_var", &self.resolve_var.is_some())
|
||||||
.field("token_mapper", &self.token_mapper.is_some())
|
.field("token_mapper", &self.token_mapper.is_some());
|
||||||
.field("print", &self.print.is_some())
|
|
||||||
.field("debug", &self.debug.is_some());
|
|
||||||
|
|
||||||
#[cfg(not(feature = "unchecked"))]
|
#[cfg(not(feature = "unchecked"))]
|
||||||
f.field("progress", &self.progress.is_some());
|
f.field("progress", &self.progress.is_some());
|
||||||
@ -226,16 +224,15 @@ impl Engine {
|
|||||||
#[cfg(not(feature = "no_std"))]
|
#[cfg(not(feature = "no_std"))]
|
||||||
#[cfg(not(target_family = "wasm"))]
|
#[cfg(not(target_family = "wasm"))]
|
||||||
{
|
{
|
||||||
engine.module_resolver =
|
engine.module_resolver = Box::new(crate::module::resolvers::FileModuleResolver::new());
|
||||||
Some(Box::new(crate::module::resolvers::FileModuleResolver::new()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// default print/debug implementations
|
// default print/debug implementations
|
||||||
#[cfg(not(feature = "no_std"))]
|
#[cfg(not(feature = "no_std"))]
|
||||||
#[cfg(not(target_family = "wasm"))]
|
#[cfg(not(target_family = "wasm"))]
|
||||||
{
|
{
|
||||||
engine.print = Some(Box::new(|s| println!("{}", s)));
|
engine.print = Box::new(|s| println!("{}", s));
|
||||||
engine.debug = Some(Box::new(|s, source, pos| {
|
engine.debug = Box::new(|s, source, pos| {
|
||||||
if let Some(source) = source {
|
if let Some(source) = source {
|
||||||
println!("{} @ {:?} | {}", source, pos, s);
|
println!("{} @ {:?} | {}", source, pos, s);
|
||||||
} else if pos.is_none() {
|
} else if pos.is_none() {
|
||||||
@ -243,7 +240,7 @@ impl Engine {
|
|||||||
} else {
|
} else {
|
||||||
println!("{:?} | {}", pos, s);
|
println!("{:?} | {}", pos, s);
|
||||||
}
|
}
|
||||||
}));
|
});
|
||||||
}
|
}
|
||||||
#[cfg(any(feature = "no_std", target_family = "wasm"))]
|
#[cfg(any(feature = "no_std", target_family = "wasm"))]
|
||||||
{
|
{
|
||||||
@ -269,7 +266,7 @@ impl Engine {
|
|||||||
global_sub_modules: BTreeMap::new(),
|
global_sub_modules: BTreeMap::new(),
|
||||||
|
|
||||||
#[cfg(not(feature = "no_module"))]
|
#[cfg(not(feature = "no_module"))]
|
||||||
module_resolver: None,
|
module_resolver: Box::new(crate::module::resolvers::DummyModuleResolver::new()),
|
||||||
|
|
||||||
custom_types: CustomTypesCollection::new(),
|
custom_types: CustomTypesCollection::new(),
|
||||||
empty_string: ImmutableString::new(),
|
empty_string: ImmutableString::new(),
|
||||||
@ -281,15 +278,15 @@ impl Engine {
|
|||||||
resolve_var: None,
|
resolve_var: None,
|
||||||
token_mapper: None,
|
token_mapper: None,
|
||||||
|
|
||||||
print: None,
|
print: Box::new(|_| {}),
|
||||||
debug: None,
|
debug: Box::new(|_, _, _| {}),
|
||||||
|
|
||||||
#[cfg(not(feature = "unchecked"))]
|
#[cfg(not(feature = "unchecked"))]
|
||||||
progress: None,
|
progress: None,
|
||||||
|
|
||||||
optimization_level: OptimizationLevel::default(),
|
optimization_level: OptimizationLevel::default(),
|
||||||
|
|
||||||
options: crate::api::options::LanguageOptions::new(),
|
options: LanguageOptions::new(),
|
||||||
|
|
||||||
#[cfg(not(feature = "unchecked"))]
|
#[cfg(not(feature = "unchecked"))]
|
||||||
limits: crate::api::limits::Limits::new(),
|
limits: crate::api::limits::Limits::new(),
|
||||||
|
@ -35,9 +35,10 @@ impl<'x, 'px, 'm, 'pm, 'pt> EvalContext<'_, 'x, 'px, 'm, 'pm, '_, '_, '_, '_, 'p
|
|||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn source(&self) -> Option<&str> {
|
pub fn source(&self) -> Option<&str> {
|
||||||
match self.global.source.as_str() {
|
if self.global.source.is_empty() {
|
||||||
"" => None,
|
None
|
||||||
s => Some(s),
|
} else {
|
||||||
|
Some(self.global.source.as_str())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/// The current [`Scope`].
|
/// The current [`Scope`].
|
||||||
|
@ -28,7 +28,7 @@ pub struct EvalState<'a> {
|
|||||||
/// Stack of function resolution caches.
|
/// Stack of function resolution caches.
|
||||||
fn_resolution_caches: StaticVec<FnResolutionCache>,
|
fn_resolution_caches: StaticVec<FnResolutionCache>,
|
||||||
/// Take care of the lifetime parameter
|
/// Take care of the lifetime parameter
|
||||||
dummy: PhantomData<Option<&'a ()>>,
|
dummy: PhantomData<&'a ()>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl EvalState<'_> {
|
impl EvalState<'_> {
|
||||||
|
@ -244,9 +244,10 @@ impl GlobalRuntimeState<'_> {
|
|||||||
#[inline]
|
#[inline]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn source(&self) -> Option<&str> {
|
pub fn source(&self) -> Option<&str> {
|
||||||
match self.source.as_str() {
|
if self.source.is_empty() {
|
||||||
"" => None,
|
None
|
||||||
s => Some(s),
|
} else {
|
||||||
|
Some(self.source.as_str())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/// Get the pre-calculated index getter hash.
|
/// Get the pre-calculated index getter hash.
|
||||||
|
@ -952,9 +952,10 @@ impl Engine {
|
|||||||
result => Some(result),
|
result => Some(result),
|
||||||
})
|
})
|
||||||
.or_else(|| {
|
.or_else(|| {
|
||||||
self.module_resolver
|
Some(
|
||||||
.as_ref()
|
self.module_resolver
|
||||||
.map(|r| r.resolve_raw(self, global, &path, path_pos))
|
.resolve_raw(self, global, &path, path_pos),
|
||||||
|
)
|
||||||
})
|
})
|
||||||
.unwrap_or_else(|| {
|
.unwrap_or_else(|| {
|
||||||
Err(ERR::ErrorModuleNotFound(path.to_string(), path_pos).into())
|
Err(ERR::ErrorModuleNotFound(path.to_string(), path_pos).into())
|
||||||
|
@ -464,30 +464,23 @@ impl Engine {
|
|||||||
// See if the function match print/debug (which requires special processing)
|
// See if the function match print/debug (which requires special processing)
|
||||||
return Ok(match name {
|
return Ok(match name {
|
||||||
KEYWORD_PRINT => {
|
KEYWORD_PRINT => {
|
||||||
if let Some(ref print) = self.print {
|
let text = result.into_immutable_string().map_err(|typ| {
|
||||||
let text = result.into_immutable_string().map_err(|typ| {
|
let t = self.map_type_name(type_name::<ImmutableString>()).into();
|
||||||
let t = self.map_type_name(type_name::<ImmutableString>()).into();
|
ERR::ErrorMismatchOutputType(t, typ.into(), pos)
|
||||||
ERR::ErrorMismatchOutputType(t, typ.into(), pos)
|
})?;
|
||||||
})?;
|
((&*self.print)(&text).into(), false)
|
||||||
(print(&text).into(), false)
|
|
||||||
} else {
|
|
||||||
(Dynamic::UNIT, false)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
KEYWORD_DEBUG => {
|
KEYWORD_DEBUG => {
|
||||||
if let Some(ref debug) = self.debug {
|
let text = result.into_immutable_string().map_err(|typ| {
|
||||||
let text = result.into_immutable_string().map_err(|typ| {
|
let t = self.map_type_name(type_name::<ImmutableString>()).into();
|
||||||
let t = self.map_type_name(type_name::<ImmutableString>()).into();
|
ERR::ErrorMismatchOutputType(t, typ.into(), pos)
|
||||||
ERR::ErrorMismatchOutputType(t, typ.into(), pos)
|
})?;
|
||||||
})?;
|
let source = if global.source.is_empty() {
|
||||||
let source = match global.source.as_str() {
|
None
|
||||||
"" => None,
|
|
||||||
s => Some(s),
|
|
||||||
};
|
|
||||||
(debug(&text, source, pos).into(), false)
|
|
||||||
} else {
|
} else {
|
||||||
(Dynamic::UNIT, false)
|
Some(global.source.as_str())
|
||||||
}
|
};
|
||||||
|
((&*self.debug)(&text, source, pos).into(), false)
|
||||||
}
|
}
|
||||||
_ => (result, is_method),
|
_ => (result, is_method),
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user