commit
c18a6451f4
20
RELEASES.md
20
RELEASES.md
@ -10,6 +10,9 @@ It also allows exposing selected module functions (usually methods) to the globa
|
|||||||
This is very convenient when encapsulating the API of a custom Rust type into a module while having methods
|
This is very convenient when encapsulating the API of a custom Rust type into a module while having methods
|
||||||
and iterators registered on the custom type work normally.
|
and iterators registered on the custom type work normally.
|
||||||
|
|
||||||
|
A new `gen_fn_signatures` API enables enumerating the registered functions of an `Engine` for documentation purposes.
|
||||||
|
It also prepares the way for a future reflection API.
|
||||||
|
|
||||||
Bug fixes
|
Bug fixes
|
||||||
---------
|
---------
|
||||||
|
|
||||||
@ -19,18 +22,23 @@ Breaking changes
|
|||||||
----------------
|
----------------
|
||||||
|
|
||||||
* `Module::set_fn`, `Module::set_raw_fn` and `Module::set_fn_XXX_mut` all take an additional parameter of `FnNamespace`.
|
* `Module::set_fn`, `Module::set_raw_fn` and `Module::set_fn_XXX_mut` all take an additional parameter of `FnNamespace`.
|
||||||
* `unless` is now a reserved keyword.
|
* `Module::set_fn` takes a further parameter with a list of parameter names and types, if any.
|
||||||
|
* `Module::get_sub_module_mut` is removed.
|
||||||
|
* `begin`, `end`, `unless` are now reserved keywords.
|
||||||
|
* `EvalPackage` is removed in favor of `Engine::disable_symbol`.
|
||||||
|
|
||||||
New features
|
New features
|
||||||
------------
|
------------
|
||||||
|
|
||||||
* `switch` statement.
|
* New `switch` statement.
|
||||||
* `do ... while` and `do ... until` statement.
|
* New `do ... while` and `do ... until` statements.
|
||||||
* `Engine::register_module` to register a module as a sub-module in the global namespace.
|
* New `Engine::gen_fn_signatures`, `Module::gen_fn_signatures` and `PackagesCollection::gen_fn_signatures` to generate a list of signatures for functions registered.
|
||||||
* `set_exported_global_fn!` macro to register a plugin function and expose it to the global namespace.
|
* New `Engine::register_module` to register a module as a sub-module in the global namespace.
|
||||||
|
* New `set_exported_global_fn!` macro to register a plugin function and expose it to the global namespace.
|
||||||
* `Module::set_fn_XXX_mut` can expose a module function to the global namespace. This is convenient when registering an API for a custom type.
|
* `Module::set_fn_XXX_mut` can expose a module function to the global namespace. This is convenient when registering an API for a custom type.
|
||||||
* `Module::set_getter_fn`, `Module::set_setter_fn`, `Module::set_indexer_get_fn`, `Module::set_indexer_set_fn` all expose the function to the global namespace by default. This is convenient when registering an API for a custom type.
|
* `Module::set_getter_fn`, `Module::set_setter_fn`, `Module::set_indexer_get_fn`, `Module::set_indexer_set_fn` all expose the function to the global namespace by default. This is convenient when registering an API for a custom type.
|
||||||
* `#[rhai_fn(global)]` and `#[rhai_fn(internal)]` attributes to determine whether a function defined in a plugin module should be exposed to the global namespace. This is convenient when defining an API for a custom type.
|
* New `Module::update_fn_param_names` to update a module function's parameter names and types.
|
||||||
|
* New `#[rhai_fn(global)]` and `#[rhai_fn(internal)]` attributes to determine whether a function defined in a plugin module should be exposed to the global namespace. This is convenient when defining an API for a custom type.
|
||||||
|
|
||||||
Enhancements
|
Enhancements
|
||||||
------------
|
------------
|
||||||
|
@ -12,7 +12,7 @@ use std::format;
|
|||||||
|
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
|
|
||||||
use quote::{quote, quote_spanned};
|
use quote::{quote, quote_spanned, ToTokens};
|
||||||
use syn::{
|
use syn::{
|
||||||
parse::{Parse, ParseStream, Parser},
|
parse::{Parse, ParseStream, Parser},
|
||||||
spanned::Spanned,
|
spanned::Spanned,
|
||||||
@ -83,6 +83,10 @@ pub(crate) fn flatten_type_groups(ty: &syn::Type) -> &syn::Type {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn print_type(ty: &syn::Type) -> String {
|
||||||
|
ty.to_token_stream().to_string().replace("& ", "&")
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default)]
|
||||||
pub(crate) struct ExportedFnParams {
|
pub(crate) struct ExportedFnParams {
|
||||||
pub name: Option<Vec<String>>,
|
pub name: Option<Vec<String>>,
|
||||||
@ -576,6 +580,7 @@ impl ExportedFn {
|
|||||||
syn::Ident::new(&format!("rhai_fn_{}", self.name()), self.name().span());
|
syn::Ident::new(&format!("rhai_fn_{}", self.name()), self.name().span());
|
||||||
let impl_block = self.generate_impl("Token");
|
let impl_block = self.generate_impl("Token");
|
||||||
let callable_block = self.generate_callable("Token");
|
let callable_block = self.generate_callable("Token");
|
||||||
|
let input_names_block = self.generate_input_names("Token");
|
||||||
let input_types_block = self.generate_input_types("Token");
|
let input_types_block = self.generate_input_types("Token");
|
||||||
let dyn_result_fn_block = self.generate_dynamic_fn();
|
let dyn_result_fn_block = self.generate_dynamic_fn();
|
||||||
quote! {
|
quote! {
|
||||||
@ -585,6 +590,7 @@ impl ExportedFn {
|
|||||||
struct Token();
|
struct Token();
|
||||||
#impl_block
|
#impl_block
|
||||||
#callable_block
|
#callable_block
|
||||||
|
#input_names_block
|
||||||
#input_types_block
|
#input_types_block
|
||||||
#dyn_result_fn_block
|
#dyn_result_fn_block
|
||||||
}
|
}
|
||||||
@ -655,6 +661,19 @@ impl ExportedFn {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn generate_input_names(&self, on_type_name: &str) -> proc_macro2::TokenStream {
|
||||||
|
let token_name: syn::Ident = syn::Ident::new(on_type_name, self.name().span());
|
||||||
|
let input_names_fn_name: syn::Ident = syn::Ident::new(
|
||||||
|
format!("{}_input_names", on_type_name.to_lowercase()).as_str(),
|
||||||
|
self.name().span(),
|
||||||
|
);
|
||||||
|
quote! {
|
||||||
|
pub fn #input_names_fn_name() -> Box<[&'static str]> {
|
||||||
|
#token_name().input_names()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn generate_input_types(&self, on_type_name: &str) -> proc_macro2::TokenStream {
|
pub fn generate_input_types(&self, on_type_name: &str) -> proc_macro2::TokenStream {
|
||||||
let token_name: syn::Ident = syn::Ident::new(on_type_name, self.name().span());
|
let token_name: syn::Ident = syn::Ident::new(on_type_name, self.name().span());
|
||||||
let input_types_fn_name: syn::Ident = syn::Ident::new(
|
let input_types_fn_name: syn::Ident = syn::Ident::new(
|
||||||
@ -680,6 +699,7 @@ impl ExportedFn {
|
|||||||
|
|
||||||
let mut unpack_stmts: Vec<syn::Stmt> = Vec::new();
|
let mut unpack_stmts: Vec<syn::Stmt> = Vec::new();
|
||||||
let mut unpack_exprs: Vec<syn::Expr> = Vec::new();
|
let mut unpack_exprs: Vec<syn::Expr> = Vec::new();
|
||||||
|
let mut input_type_names: Vec<String> = Vec::new();
|
||||||
let mut input_type_exprs: Vec<syn::Expr> = Vec::new();
|
let mut input_type_exprs: Vec<syn::Expr> = Vec::new();
|
||||||
let skip_first_arg;
|
let skip_first_arg;
|
||||||
|
|
||||||
@ -693,8 +713,9 @@ impl ExportedFn {
|
|||||||
let first_arg = self.arg_list().next().unwrap();
|
let first_arg = self.arg_list().next().unwrap();
|
||||||
let var = syn::Ident::new("arg0", proc_macro2::Span::call_site());
|
let var = syn::Ident::new("arg0", proc_macro2::Span::call_site());
|
||||||
match first_arg {
|
match first_arg {
|
||||||
syn::FnArg::Typed(pattern) => {
|
syn::FnArg::Typed(syn::PatType { pat, ty, .. }) => {
|
||||||
let arg_type = match flatten_type_groups(pattern.ty.as_ref()) {
|
let arg_name = format!("{}: {}", pat.to_token_stream(), print_type(ty));
|
||||||
|
let arg_type = match flatten_type_groups(ty.as_ref()) {
|
||||||
syn::Type::Reference(syn::TypeReference { ref elem, .. }) => elem.as_ref(),
|
syn::Type::Reference(syn::TypeReference { ref elem, .. }) => elem.as_ref(),
|
||||||
p => p,
|
p => p,
|
||||||
};
|
};
|
||||||
@ -706,6 +727,7 @@ impl ExportedFn {
|
|||||||
})
|
})
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
);
|
);
|
||||||
|
input_type_names.push(arg_name);
|
||||||
input_type_exprs.push(
|
input_type_exprs.push(
|
||||||
syn::parse2::<syn::Expr>(quote_spanned!(
|
syn::parse2::<syn::Expr>(quote_spanned!(
|
||||||
arg_type.span()=> TypeId::of::<#arg_type>()
|
arg_type.span()=> TypeId::of::<#arg_type>()
|
||||||
@ -731,9 +753,10 @@ impl ExportedFn {
|
|||||||
let is_string;
|
let is_string;
|
||||||
let is_ref;
|
let is_ref;
|
||||||
match arg {
|
match arg {
|
||||||
syn::FnArg::Typed(pattern) => {
|
syn::FnArg::Typed(syn::PatType { pat, ty, .. }) => {
|
||||||
let arg_type = pattern.ty.as_ref();
|
let arg_name = format!("{}: {}", pat.to_token_stream(), print_type(ty));
|
||||||
let downcast_span = match flatten_type_groups(pattern.ty.as_ref()) {
|
let arg_type = ty.as_ref();
|
||||||
|
let downcast_span = match flatten_type_groups(arg_type) {
|
||||||
syn::Type::Reference(syn::TypeReference {
|
syn::Type::Reference(syn::TypeReference {
|
||||||
mutability: None,
|
mutability: None,
|
||||||
ref elem,
|
ref elem,
|
||||||
@ -767,6 +790,7 @@ impl ExportedFn {
|
|||||||
})
|
})
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
);
|
);
|
||||||
|
input_type_names.push(arg_name);
|
||||||
if !is_string {
|
if !is_string {
|
||||||
input_type_exprs.push(
|
input_type_exprs.push(
|
||||||
syn::parse2::<syn::Expr>(quote_spanned!(
|
syn::parse2::<syn::Expr>(quote_spanned!(
|
||||||
@ -837,6 +861,9 @@ impl ExportedFn {
|
|||||||
fn is_method_call(&self) -> bool { #is_method_call }
|
fn is_method_call(&self) -> bool { #is_method_call }
|
||||||
fn is_variadic(&self) -> bool { false }
|
fn is_variadic(&self) -> bool { false }
|
||||||
fn clone_boxed(&self) -> Box<dyn PluginFunction> { Box::new(#type_name()) }
|
fn clone_boxed(&self) -> Box<dyn PluginFunction> { Box::new(#type_name()) }
|
||||||
|
fn input_names(&self) -> Box<[&'static str]> {
|
||||||
|
new_vec![#(#input_type_names),*].into_boxed_slice()
|
||||||
|
}
|
||||||
fn input_types(&self) -> Box<[TypeId]> {
|
fn input_types(&self) -> Box<[TypeId]> {
|
||||||
new_vec![#(#input_type_exprs),*].into_boxed_slice()
|
new_vec![#(#input_type_exprs),*].into_boxed_slice()
|
||||||
}
|
}
|
||||||
|
@ -340,6 +340,7 @@ pub fn set_exported_fn(args: proc_macro::TokenStream) -> proc_macro::TokenStream
|
|||||||
let gen_mod_path = crate::register::generated_module_path(&rust_modpath);
|
let gen_mod_path = crate::register::generated_module_path(&rust_modpath);
|
||||||
let tokens = quote! {
|
let tokens = quote! {
|
||||||
#module_expr.set_fn(#export_name, FnNamespace::Internal, FnAccess::Public,
|
#module_expr.set_fn(#export_name, FnNamespace::Internal, FnAccess::Public,
|
||||||
|
Some(#gen_mod_path::token_input_names().as_ref()),
|
||||||
#gen_mod_path::token_input_types().as_ref(),
|
#gen_mod_path::token_input_types().as_ref(),
|
||||||
#gen_mod_path::token_callable());
|
#gen_mod_path::token_callable());
|
||||||
};
|
};
|
||||||
@ -381,6 +382,7 @@ pub fn set_exported_global_fn(args: proc_macro::TokenStream) -> proc_macro::Toke
|
|||||||
let gen_mod_path = crate::register::generated_module_path(&rust_modpath);
|
let gen_mod_path = crate::register::generated_module_path(&rust_modpath);
|
||||||
let tokens = quote! {
|
let tokens = quote! {
|
||||||
#module_expr.set_fn(#export_name, FnNamespace::Global, FnAccess::Public,
|
#module_expr.set_fn(#export_name, FnNamespace::Global, FnAccess::Public,
|
||||||
|
Some(#gen_mod_path::token_input_names().as_ref()),
|
||||||
#gen_mod_path::token_input_types().as_ref(),
|
#gen_mod_path::token_input_types().as_ref(),
|
||||||
#gen_mod_path::token_callable());
|
#gen_mod_path::token_callable());
|
||||||
};
|
};
|
||||||
|
@ -3,8 +3,9 @@ use std::collections::HashMap;
|
|||||||
use quote::{quote, ToTokens};
|
use quote::{quote, ToTokens};
|
||||||
|
|
||||||
use crate::attrs::ExportScope;
|
use crate::attrs::ExportScope;
|
||||||
use crate::function::flatten_type_groups;
|
use crate::function::{
|
||||||
use crate::function::{ExportedFn, FnNamespaceAccess, FnSpecialAccess};
|
flatten_type_groups, print_type, ExportedFn, FnNamespaceAccess, FnSpecialAccess,
|
||||||
|
};
|
||||||
use crate::module::Module;
|
use crate::module::Module;
|
||||||
|
|
||||||
pub(crate) type ExportedConst = (String, Box<syn::Type>, syn::Expr);
|
pub(crate) type ExportedConst = (String, Box<syn::Type>, syn::Expr);
|
||||||
@ -82,6 +83,16 @@ pub(crate) fn generate_body(
|
|||||||
let reg_names = function.exported_names();
|
let reg_names = function.exported_names();
|
||||||
let mut namespace = FnNamespaceAccess::Internal;
|
let mut namespace = FnNamespaceAccess::Internal;
|
||||||
|
|
||||||
|
let fn_input_names: Vec<String> = function
|
||||||
|
.arg_list()
|
||||||
|
.map(|fnarg| match fnarg {
|
||||||
|
syn::FnArg::Receiver(_) => panic!("internal error: receiver fn outside impl!?"),
|
||||||
|
syn::FnArg::Typed(syn::PatType { pat, ty, .. }) => {
|
||||||
|
format!("{}: {}", pat.to_token_stream(), print_type(ty))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
let fn_input_types: Vec<syn::Expr> = function
|
let fn_input_types: Vec<syn::Expr> = function
|
||||||
.arg_list()
|
.arg_list()
|
||||||
.map(|fnarg| match fnarg {
|
.map(|fnarg| match fnarg {
|
||||||
@ -117,6 +128,7 @@ pub(crate) fn generate_body(
|
|||||||
},
|
},
|
||||||
t => t.clone(),
|
t => t.clone(),
|
||||||
};
|
};
|
||||||
|
|
||||||
syn::parse2::<syn::Expr>(quote! {
|
syn::parse2::<syn::Expr>(quote! {
|
||||||
core::any::TypeId::of::<#arg_type>()})
|
core::any::TypeId::of::<#arg_type>()})
|
||||||
.unwrap()
|
.unwrap()
|
||||||
@ -138,7 +150,8 @@ pub(crate) fn generate_body(
|
|||||||
);
|
);
|
||||||
set_fn_stmts.push(
|
set_fn_stmts.push(
|
||||||
syn::parse2::<syn::Stmt>(quote! {
|
syn::parse2::<syn::Stmt>(quote! {
|
||||||
m.set_fn(#fn_literal, FnNamespace::#ns_str, FnAccess::Public, &[#(#fn_input_types),*],
|
m.set_fn(#fn_literal, FnNamespace::#ns_str, FnAccess::Public,
|
||||||
|
Some(&[#(#fn_input_names),*]), &[#(#fn_input_types),*],
|
||||||
#fn_token_name().into());
|
#fn_token_name().into());
|
||||||
})
|
})
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
@ -151,6 +164,7 @@ pub(crate) fn generate_body(
|
|||||||
});
|
});
|
||||||
gen_fn_tokens.push(function.generate_impl(&fn_token_name.to_string()));
|
gen_fn_tokens.push(function.generate_impl(&fn_token_name.to_string()));
|
||||||
gen_fn_tokens.push(function.generate_callable(&fn_token_name.to_string()));
|
gen_fn_tokens.push(function.generate_callable(&fn_token_name.to_string()));
|
||||||
|
gen_fn_tokens.push(function.generate_input_names(&fn_token_name.to_string()));
|
||||||
gen_fn_tokens.push(function.generate_input_types(&fn_token_name.to_string()));
|
gen_fn_tokens.push(function.generate_input_types(&fn_token_name.to_string()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -162,6 +176,7 @@ pub(crate) fn generate_body(
|
|||||||
pub fn rhai_module_generate() -> Module {
|
pub fn rhai_module_generate() -> Module {
|
||||||
let mut m = Module::new();
|
let mut m = Module::new();
|
||||||
rhai_generate_into_module(&mut m, false);
|
rhai_generate_into_module(&mut m, false);
|
||||||
|
m.build_index();
|
||||||
m
|
m
|
||||||
}
|
}
|
||||||
#[allow(unused_mut)]
|
#[allow(unused_mut)]
|
||||||
@ -194,9 +209,7 @@ pub(crate) fn check_rename_collisions(fns: &Vec<ExportedFn>) -> Result<(), syn::
|
|||||||
.fold(name.to_string(), |mut argstr, fnarg| {
|
.fold(name.to_string(), |mut argstr, fnarg| {
|
||||||
let type_string: String = match fnarg {
|
let type_string: String = match fnarg {
|
||||||
syn::FnArg::Receiver(_) => unimplemented!("receiver rhai_fns not implemented"),
|
syn::FnArg::Receiver(_) => unimplemented!("receiver rhai_fns not implemented"),
|
||||||
syn::FnArg::Typed(syn::PatType { ref ty, .. }) => {
|
syn::FnArg::Typed(syn::PatType { ref ty, .. }) => print_type(ty),
|
||||||
ty.as_ref().to_token_stream().to_string()
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
argstr.push('.');
|
argstr.push('.');
|
||||||
argstr.push_str(&type_string);
|
argstr.push_str(&type_string);
|
||||||
|
@ -286,6 +286,9 @@ mod generate_tests {
|
|||||||
fn is_method_call(&self) -> bool { false }
|
fn is_method_call(&self) -> bool { false }
|
||||||
fn is_variadic(&self) -> bool { false }
|
fn is_variadic(&self) -> bool { false }
|
||||||
fn clone_boxed(&self) -> Box<dyn PluginFunction> { Box::new(Token()) }
|
fn clone_boxed(&self) -> Box<dyn PluginFunction> { Box::new(Token()) }
|
||||||
|
fn input_names(&self) -> Box<[&'static str]> {
|
||||||
|
new_vec![].into_boxed_slice()
|
||||||
|
}
|
||||||
fn input_types(&self) -> Box<[TypeId]> {
|
fn input_types(&self) -> Box<[TypeId]> {
|
||||||
new_vec![].into_boxed_slice()
|
new_vec![].into_boxed_slice()
|
||||||
}
|
}
|
||||||
@ -293,6 +296,9 @@ mod generate_tests {
|
|||||||
pub fn token_callable() -> CallableFunction {
|
pub fn token_callable() -> CallableFunction {
|
||||||
Token().into()
|
Token().into()
|
||||||
}
|
}
|
||||||
|
pub fn token_input_names() -> Box<[&'static str]> {
|
||||||
|
Token().input_names()
|
||||||
|
}
|
||||||
pub fn token_input_types() -> Box<[TypeId]> {
|
pub fn token_input_types() -> Box<[TypeId]> {
|
||||||
Token().input_types()
|
Token().input_types()
|
||||||
}
|
}
|
||||||
@ -328,6 +334,9 @@ mod generate_tests {
|
|||||||
fn is_method_call(&self) -> bool { false }
|
fn is_method_call(&self) -> bool { false }
|
||||||
fn is_variadic(&self) -> bool { false }
|
fn is_variadic(&self) -> bool { false }
|
||||||
fn clone_boxed(&self) -> Box<dyn PluginFunction> { Box::new(Token()) }
|
fn clone_boxed(&self) -> Box<dyn PluginFunction> { Box::new(Token()) }
|
||||||
|
fn input_names(&self) -> Box<[&'static str]> {
|
||||||
|
new_vec!["x: usize"].into_boxed_slice()
|
||||||
|
}
|
||||||
fn input_types(&self) -> Box<[TypeId]> {
|
fn input_types(&self) -> Box<[TypeId]> {
|
||||||
new_vec![TypeId::of::<usize>()].into_boxed_slice()
|
new_vec![TypeId::of::<usize>()].into_boxed_slice()
|
||||||
}
|
}
|
||||||
@ -335,6 +344,9 @@ mod generate_tests {
|
|||||||
pub fn token_callable() -> CallableFunction {
|
pub fn token_callable() -> CallableFunction {
|
||||||
Token().into()
|
Token().into()
|
||||||
}
|
}
|
||||||
|
pub fn token_input_names() -> Box<[&'static str]> {
|
||||||
|
Token().input_names()
|
||||||
|
}
|
||||||
pub fn token_input_types() -> Box<[TypeId]> {
|
pub fn token_input_types() -> Box<[TypeId]> {
|
||||||
Token().input_types()
|
Token().input_types()
|
||||||
}
|
}
|
||||||
@ -370,6 +382,9 @@ mod generate_tests {
|
|||||||
fn is_method_call(&self) -> bool { false }
|
fn is_method_call(&self) -> bool { false }
|
||||||
fn is_variadic(&self) -> bool { false }
|
fn is_variadic(&self) -> bool { false }
|
||||||
fn clone_boxed(&self) -> Box<dyn PluginFunction> { Box::new(Token()) }
|
fn clone_boxed(&self) -> Box<dyn PluginFunction> { Box::new(Token()) }
|
||||||
|
fn input_names(&self) -> Box<[&'static str]> {
|
||||||
|
new_vec!["x: usize"].into_boxed_slice()
|
||||||
|
}
|
||||||
fn input_types(&self) -> Box<[TypeId]> {
|
fn input_types(&self) -> Box<[TypeId]> {
|
||||||
new_vec![TypeId::of::<usize>()].into_boxed_slice()
|
new_vec![TypeId::of::<usize>()].into_boxed_slice()
|
||||||
}
|
}
|
||||||
@ -377,6 +392,9 @@ mod generate_tests {
|
|||||||
pub fn token_callable() -> CallableFunction {
|
pub fn token_callable() -> CallableFunction {
|
||||||
Token().into()
|
Token().into()
|
||||||
}
|
}
|
||||||
|
pub fn token_input_names() -> Box<[&'static str]> {
|
||||||
|
Token().input_names()
|
||||||
|
}
|
||||||
pub fn token_input_types() -> Box<[TypeId]> {
|
pub fn token_input_types() -> Box<[TypeId]> {
|
||||||
Token().input_types()
|
Token().input_types()
|
||||||
}
|
}
|
||||||
@ -414,6 +432,9 @@ mod generate_tests {
|
|||||||
fn is_method_call(&self) -> bool { false }
|
fn is_method_call(&self) -> bool { false }
|
||||||
fn is_variadic(&self) -> bool { false }
|
fn is_variadic(&self) -> bool { false }
|
||||||
fn clone_boxed(&self) -> Box<dyn PluginFunction> { Box::new(Token()) }
|
fn clone_boxed(&self) -> Box<dyn PluginFunction> { Box::new(Token()) }
|
||||||
|
fn input_names(&self) -> Box<[&'static str]> {
|
||||||
|
new_vec![].into_boxed_slice()
|
||||||
|
}
|
||||||
fn input_types(&self) -> Box<[TypeId]> {
|
fn input_types(&self) -> Box<[TypeId]> {
|
||||||
new_vec![].into_boxed_slice()
|
new_vec![].into_boxed_slice()
|
||||||
}
|
}
|
||||||
@ -421,6 +442,9 @@ mod generate_tests {
|
|||||||
pub fn token_callable() -> CallableFunction {
|
pub fn token_callable() -> CallableFunction {
|
||||||
Token().into()
|
Token().into()
|
||||||
}
|
}
|
||||||
|
pub fn token_input_names() -> Box<[&'static str]> {
|
||||||
|
Token().input_names()
|
||||||
|
}
|
||||||
pub fn token_input_types() -> Box<[TypeId]> {
|
pub fn token_input_types() -> Box<[TypeId]> {
|
||||||
Token().input_types()
|
Token().input_types()
|
||||||
}
|
}
|
||||||
@ -452,6 +476,9 @@ mod generate_tests {
|
|||||||
fn is_method_call(&self) -> bool { false }
|
fn is_method_call(&self) -> bool { false }
|
||||||
fn is_variadic(&self) -> bool { false }
|
fn is_variadic(&self) -> bool { false }
|
||||||
fn clone_boxed(&self) -> Box<dyn PluginFunction> { Box::new(MyType()) }
|
fn clone_boxed(&self) -> Box<dyn PluginFunction> { Box::new(MyType()) }
|
||||||
|
fn input_names(&self) -> Box<[&'static str]> {
|
||||||
|
new_vec!["x: usize"].into_boxed_slice()
|
||||||
|
}
|
||||||
fn input_types(&self) -> Box<[TypeId]> {
|
fn input_types(&self) -> Box<[TypeId]> {
|
||||||
new_vec![TypeId::of::<usize>()].into_boxed_slice()
|
new_vec![TypeId::of::<usize>()].into_boxed_slice()
|
||||||
}
|
}
|
||||||
@ -485,6 +512,9 @@ mod generate_tests {
|
|||||||
fn is_method_call(&self) -> bool { false }
|
fn is_method_call(&self) -> bool { false }
|
||||||
fn is_variadic(&self) -> bool { false }
|
fn is_variadic(&self) -> bool { false }
|
||||||
fn clone_boxed(&self) -> Box<dyn PluginFunction> { Box::new(Token()) }
|
fn clone_boxed(&self) -> Box<dyn PluginFunction> { Box::new(Token()) }
|
||||||
|
fn input_names(&self) -> Box<[&'static str]> {
|
||||||
|
new_vec!["x: usize", "y: usize"].into_boxed_slice()
|
||||||
|
}
|
||||||
fn input_types(&self) -> Box<[TypeId]> {
|
fn input_types(&self) -> Box<[TypeId]> {
|
||||||
new_vec![TypeId::of::<usize>(),
|
new_vec![TypeId::of::<usize>(),
|
||||||
TypeId::of::<usize>()].into_boxed_slice()
|
TypeId::of::<usize>()].into_boxed_slice()
|
||||||
@ -493,6 +523,9 @@ mod generate_tests {
|
|||||||
pub fn token_callable() -> CallableFunction {
|
pub fn token_callable() -> CallableFunction {
|
||||||
Token().into()
|
Token().into()
|
||||||
}
|
}
|
||||||
|
pub fn token_input_names() -> Box<[&'static str]> {
|
||||||
|
Token().input_names()
|
||||||
|
}
|
||||||
pub fn token_input_types() -> Box<[TypeId]> {
|
pub fn token_input_types() -> Box<[TypeId]> {
|
||||||
Token().input_types()
|
Token().input_types()
|
||||||
}
|
}
|
||||||
@ -529,6 +562,9 @@ mod generate_tests {
|
|||||||
fn is_method_call(&self) -> bool { true }
|
fn is_method_call(&self) -> bool { true }
|
||||||
fn is_variadic(&self) -> bool { false }
|
fn is_variadic(&self) -> bool { false }
|
||||||
fn clone_boxed(&self) -> Box<dyn PluginFunction> { Box::new(Token()) }
|
fn clone_boxed(&self) -> Box<dyn PluginFunction> { Box::new(Token()) }
|
||||||
|
fn input_names(&self) -> Box<[&'static str]> {
|
||||||
|
new_vec!["x: &mut usize", "y: usize"].into_boxed_slice()
|
||||||
|
}
|
||||||
fn input_types(&self) -> Box<[TypeId]> {
|
fn input_types(&self) -> Box<[TypeId]> {
|
||||||
new_vec![TypeId::of::<usize>(),
|
new_vec![TypeId::of::<usize>(),
|
||||||
TypeId::of::<usize>()].into_boxed_slice()
|
TypeId::of::<usize>()].into_boxed_slice()
|
||||||
@ -537,6 +573,9 @@ mod generate_tests {
|
|||||||
pub fn token_callable() -> CallableFunction {
|
pub fn token_callable() -> CallableFunction {
|
||||||
Token().into()
|
Token().into()
|
||||||
}
|
}
|
||||||
|
pub fn token_input_names() -> Box<[&'static str]> {
|
||||||
|
Token().input_names()
|
||||||
|
}
|
||||||
pub fn token_input_types() -> Box<[TypeId]> {
|
pub fn token_input_types() -> Box<[TypeId]> {
|
||||||
Token().input_types()
|
Token().input_types()
|
||||||
}
|
}
|
||||||
@ -573,6 +612,9 @@ mod generate_tests {
|
|||||||
fn is_method_call(&self) -> bool { false }
|
fn is_method_call(&self) -> bool { false }
|
||||||
fn is_variadic(&self) -> bool { false }
|
fn is_variadic(&self) -> bool { false }
|
||||||
fn clone_boxed(&self) -> Box<dyn PluginFunction> { Box::new(Token()) }
|
fn clone_boxed(&self) -> Box<dyn PluginFunction> { Box::new(Token()) }
|
||||||
|
fn input_names(&self) -> Box<[&'static str]> {
|
||||||
|
new_vec!["message: &str"].into_boxed_slice()
|
||||||
|
}
|
||||||
fn input_types(&self) -> Box<[TypeId]> {
|
fn input_types(&self) -> Box<[TypeId]> {
|
||||||
new_vec![TypeId::of::<ImmutableString>()].into_boxed_slice()
|
new_vec![TypeId::of::<ImmutableString>()].into_boxed_slice()
|
||||||
}
|
}
|
||||||
@ -580,6 +622,9 @@ mod generate_tests {
|
|||||||
pub fn token_callable() -> CallableFunction {
|
pub fn token_callable() -> CallableFunction {
|
||||||
Token().into()
|
Token().into()
|
||||||
}
|
}
|
||||||
|
pub fn token_input_names() -> Box<[&'static str]> {
|
||||||
|
Token().input_names()
|
||||||
|
}
|
||||||
pub fn token_input_types() -> Box<[TypeId]> {
|
pub fn token_input_types() -> Box<[TypeId]> {
|
||||||
Token().input_types()
|
Token().input_types()
|
||||||
}
|
}
|
||||||
|
@ -257,6 +257,7 @@ mod generate_tests {
|
|||||||
pub fn rhai_module_generate() -> Module {
|
pub fn rhai_module_generate() -> Module {
|
||||||
let mut m = Module::new();
|
let mut m = Module::new();
|
||||||
rhai_generate_into_module(&mut m, false);
|
rhai_generate_into_module(&mut m, false);
|
||||||
|
m.build_index();
|
||||||
m
|
m
|
||||||
}
|
}
|
||||||
#[allow(unused_mut)]
|
#[allow(unused_mut)]
|
||||||
@ -291,11 +292,12 @@ mod generate_tests {
|
|||||||
pub fn rhai_module_generate() -> Module {
|
pub fn rhai_module_generate() -> Module {
|
||||||
let mut m = Module::new();
|
let mut m = Module::new();
|
||||||
rhai_generate_into_module(&mut m, false);
|
rhai_generate_into_module(&mut m, false);
|
||||||
|
m.build_index();
|
||||||
m
|
m
|
||||||
}
|
}
|
||||||
#[allow(unused_mut)]
|
#[allow(unused_mut)]
|
||||||
pub fn rhai_generate_into_module(m: &mut Module, flatten: bool) {
|
pub fn rhai_generate_into_module(m: &mut Module, flatten: bool) {
|
||||||
m.set_fn("get_mystic_number", FnNamespace::Internal, FnAccess::Public, &[],
|
m.set_fn("get_mystic_number", FnNamespace::Internal, FnAccess::Public, Some(&[]), &[],
|
||||||
get_mystic_number_token().into());
|
get_mystic_number_token().into());
|
||||||
if flatten {} else {}
|
if flatten {} else {}
|
||||||
}
|
}
|
||||||
@ -313,6 +315,9 @@ mod generate_tests {
|
|||||||
fn clone_boxed(&self) -> Box<dyn PluginFunction> {
|
fn clone_boxed(&self) -> Box<dyn PluginFunction> {
|
||||||
Box::new(get_mystic_number_token())
|
Box::new(get_mystic_number_token())
|
||||||
}
|
}
|
||||||
|
fn input_names(&self) -> Box<[&'static str]> {
|
||||||
|
new_vec![].into_boxed_slice()
|
||||||
|
}
|
||||||
fn input_types(&self) -> Box<[TypeId]> {
|
fn input_types(&self) -> Box<[TypeId]> {
|
||||||
new_vec![].into_boxed_slice()
|
new_vec![].into_boxed_slice()
|
||||||
}
|
}
|
||||||
@ -320,6 +325,9 @@ mod generate_tests {
|
|||||||
pub fn get_mystic_number_token_callable() -> CallableFunction {
|
pub fn get_mystic_number_token_callable() -> CallableFunction {
|
||||||
get_mystic_number_token().into()
|
get_mystic_number_token().into()
|
||||||
}
|
}
|
||||||
|
pub fn get_mystic_number_token_input_names() -> Box<[&'static str]> {
|
||||||
|
get_mystic_number_token().input_names()
|
||||||
|
}
|
||||||
pub fn get_mystic_number_token_input_types() -> Box<[TypeId]> {
|
pub fn get_mystic_number_token_input_types() -> Box<[TypeId]> {
|
||||||
get_mystic_number_token().input_types()
|
get_mystic_number_token().input_types()
|
||||||
}
|
}
|
||||||
@ -352,11 +360,12 @@ mod generate_tests {
|
|||||||
pub fn rhai_module_generate() -> Module {
|
pub fn rhai_module_generate() -> Module {
|
||||||
let mut m = Module::new();
|
let mut m = Module::new();
|
||||||
rhai_generate_into_module(&mut m, false);
|
rhai_generate_into_module(&mut m, false);
|
||||||
|
m.build_index();
|
||||||
m
|
m
|
||||||
}
|
}
|
||||||
#[allow(unused_mut)]
|
#[allow(unused_mut)]
|
||||||
pub fn rhai_generate_into_module(m: &mut Module, flatten: bool) {
|
pub fn rhai_generate_into_module(m: &mut Module, flatten: bool) {
|
||||||
m.set_fn("add_one_to", FnNamespace::Global, FnAccess::Public, &[core::any::TypeId::of::<INT>()],
|
m.set_fn("add_one_to", FnNamespace::Global, FnAccess::Public, Some(&["x: INT"]), &[core::any::TypeId::of::<INT>()],
|
||||||
add_one_to_token().into());
|
add_one_to_token().into());
|
||||||
if flatten {} else {}
|
if flatten {} else {}
|
||||||
}
|
}
|
||||||
@ -375,6 +384,9 @@ mod generate_tests {
|
|||||||
fn clone_boxed(&self) -> Box<dyn PluginFunction> {
|
fn clone_boxed(&self) -> Box<dyn PluginFunction> {
|
||||||
Box::new(add_one_to_token())
|
Box::new(add_one_to_token())
|
||||||
}
|
}
|
||||||
|
fn input_names(&self) -> Box<[&'static str]> {
|
||||||
|
new_vec!["x: INT"].into_boxed_slice()
|
||||||
|
}
|
||||||
fn input_types(&self) -> Box<[TypeId]> {
|
fn input_types(&self) -> Box<[TypeId]> {
|
||||||
new_vec![TypeId::of::<INT>()].into_boxed_slice()
|
new_vec![TypeId::of::<INT>()].into_boxed_slice()
|
||||||
}
|
}
|
||||||
@ -382,6 +394,9 @@ mod generate_tests {
|
|||||||
pub fn add_one_to_token_callable() -> CallableFunction {
|
pub fn add_one_to_token_callable() -> CallableFunction {
|
||||||
add_one_to_token().into()
|
add_one_to_token().into()
|
||||||
}
|
}
|
||||||
|
pub fn add_one_to_token_input_names() -> Box<[&'static str]> {
|
||||||
|
add_one_to_token().input_names()
|
||||||
|
}
|
||||||
pub fn add_one_to_token_input_types() -> Box<[TypeId]> {
|
pub fn add_one_to_token_input_types() -> Box<[TypeId]> {
|
||||||
add_one_to_token().input_types()
|
add_one_to_token().input_types()
|
||||||
}
|
}
|
||||||
@ -413,11 +428,12 @@ mod generate_tests {
|
|||||||
pub fn rhai_module_generate() -> Module {
|
pub fn rhai_module_generate() -> Module {
|
||||||
let mut m = Module::new();
|
let mut m = Module::new();
|
||||||
rhai_generate_into_module(&mut m, false);
|
rhai_generate_into_module(&mut m, false);
|
||||||
|
m.build_index();
|
||||||
m
|
m
|
||||||
}
|
}
|
||||||
#[allow(unused_mut)]
|
#[allow(unused_mut)]
|
||||||
pub fn rhai_generate_into_module(m: &mut Module, flatten: bool) {
|
pub fn rhai_generate_into_module(m: &mut Module, flatten: bool) {
|
||||||
m.set_fn("add_one_to", FnNamespace::Internal, FnAccess::Public, &[core::any::TypeId::of::<INT>()],
|
m.set_fn("add_one_to", FnNamespace::Internal, FnAccess::Public, Some(&["x: INT"]), &[core::any::TypeId::of::<INT>()],
|
||||||
add_one_to_token().into());
|
add_one_to_token().into());
|
||||||
if flatten {} else {}
|
if flatten {} else {}
|
||||||
}
|
}
|
||||||
@ -436,6 +452,9 @@ mod generate_tests {
|
|||||||
fn clone_boxed(&self) -> Box<dyn PluginFunction> {
|
fn clone_boxed(&self) -> Box<dyn PluginFunction> {
|
||||||
Box::new(add_one_to_token())
|
Box::new(add_one_to_token())
|
||||||
}
|
}
|
||||||
|
fn input_names(&self) -> Box<[&'static str]> {
|
||||||
|
new_vec!["x: INT"].into_boxed_slice()
|
||||||
|
}
|
||||||
fn input_types(&self) -> Box<[TypeId]> {
|
fn input_types(&self) -> Box<[TypeId]> {
|
||||||
new_vec![TypeId::of::<INT>()].into_boxed_slice()
|
new_vec![TypeId::of::<INT>()].into_boxed_slice()
|
||||||
}
|
}
|
||||||
@ -443,6 +462,9 @@ mod generate_tests {
|
|||||||
pub fn add_one_to_token_callable() -> CallableFunction {
|
pub fn add_one_to_token_callable() -> CallableFunction {
|
||||||
add_one_to_token().into()
|
add_one_to_token().into()
|
||||||
}
|
}
|
||||||
|
pub fn add_one_to_token_input_names() -> Box<[&'static str]> {
|
||||||
|
add_one_to_token().input_names()
|
||||||
|
}
|
||||||
pub fn add_one_to_token_input_types() -> Box<[TypeId]> {
|
pub fn add_one_to_token_input_types() -> Box<[TypeId]> {
|
||||||
add_one_to_token().input_types()
|
add_one_to_token().input_types()
|
||||||
}
|
}
|
||||||
@ -485,14 +507,15 @@ mod generate_tests {
|
|||||||
pub fn rhai_module_generate() -> Module {
|
pub fn rhai_module_generate() -> Module {
|
||||||
let mut m = Module::new();
|
let mut m = Module::new();
|
||||||
rhai_generate_into_module(&mut m, false);
|
rhai_generate_into_module(&mut m, false);
|
||||||
|
m.build_index();
|
||||||
m
|
m
|
||||||
}
|
}
|
||||||
#[allow(unused_mut)]
|
#[allow(unused_mut)]
|
||||||
pub fn rhai_generate_into_module(m: &mut Module, flatten: bool) {
|
pub fn rhai_generate_into_module(m: &mut Module, flatten: bool) {
|
||||||
m.set_fn("add_n", FnNamespace::Internal, FnAccess::Public, &[core::any::TypeId::of::<INT>()],
|
m.set_fn("add_n", FnNamespace::Internal, FnAccess::Public, Some(&["x: INT"]), &[core::any::TypeId::of::<INT>()],
|
||||||
add_one_to_token().into());
|
add_one_to_token().into());
|
||||||
m.set_fn("add_n", FnNamespace::Internal, FnAccess::Public, &[core::any::TypeId::of::<INT>(),
|
m.set_fn("add_n", FnNamespace::Internal, FnAccess::Public, Some(&["x: INT", "y: INT"]),
|
||||||
core::any::TypeId::of::<INT>()],
|
&[core::any::TypeId::of::<INT>(), core::any::TypeId::of::<INT>()],
|
||||||
add_n_to_token().into());
|
add_n_to_token().into());
|
||||||
if flatten {} else {}
|
if flatten {} else {}
|
||||||
}
|
}
|
||||||
@ -511,6 +534,9 @@ mod generate_tests {
|
|||||||
fn clone_boxed(&self) -> Box<dyn PluginFunction> {
|
fn clone_boxed(&self) -> Box<dyn PluginFunction> {
|
||||||
Box::new(add_one_to_token())
|
Box::new(add_one_to_token())
|
||||||
}
|
}
|
||||||
|
fn input_names(&self) -> Box<[&'static str]> {
|
||||||
|
new_vec!["x: INT"].into_boxed_slice()
|
||||||
|
}
|
||||||
fn input_types(&self) -> Box<[TypeId]> {
|
fn input_types(&self) -> Box<[TypeId]> {
|
||||||
new_vec![TypeId::of::<INT>()].into_boxed_slice()
|
new_vec![TypeId::of::<INT>()].into_boxed_slice()
|
||||||
}
|
}
|
||||||
@ -518,6 +544,9 @@ mod generate_tests {
|
|||||||
pub fn add_one_to_token_callable() -> CallableFunction {
|
pub fn add_one_to_token_callable() -> CallableFunction {
|
||||||
add_one_to_token().into()
|
add_one_to_token().into()
|
||||||
}
|
}
|
||||||
|
pub fn add_one_to_token_input_names() -> Box<[&'static str]> {
|
||||||
|
add_one_to_token().input_names()
|
||||||
|
}
|
||||||
pub fn add_one_to_token_input_types() -> Box<[TypeId]> {
|
pub fn add_one_to_token_input_types() -> Box<[TypeId]> {
|
||||||
add_one_to_token().input_types()
|
add_one_to_token().input_types()
|
||||||
}
|
}
|
||||||
@ -538,6 +567,9 @@ mod generate_tests {
|
|||||||
fn clone_boxed(&self) -> Box<dyn PluginFunction> {
|
fn clone_boxed(&self) -> Box<dyn PluginFunction> {
|
||||||
Box::new(add_n_to_token())
|
Box::new(add_n_to_token())
|
||||||
}
|
}
|
||||||
|
fn input_names(&self) -> Box<[&'static str]> {
|
||||||
|
new_vec!["x: INT", "y: INT"].into_boxed_slice()
|
||||||
|
}
|
||||||
fn input_types(&self) -> Box<[TypeId]> {
|
fn input_types(&self) -> Box<[TypeId]> {
|
||||||
new_vec![TypeId::of::<INT>(),
|
new_vec![TypeId::of::<INT>(),
|
||||||
TypeId::of::<INT>()].into_boxed_slice()
|
TypeId::of::<INT>()].into_boxed_slice()
|
||||||
@ -546,6 +578,9 @@ mod generate_tests {
|
|||||||
pub fn add_n_to_token_callable() -> CallableFunction {
|
pub fn add_n_to_token_callable() -> CallableFunction {
|
||||||
add_n_to_token().into()
|
add_n_to_token().into()
|
||||||
}
|
}
|
||||||
|
pub fn add_n_to_token_input_names() -> Box<[&'static str]> {
|
||||||
|
add_n_to_token().input_names()
|
||||||
|
}
|
||||||
pub fn add_n_to_token_input_types() -> Box<[TypeId]> {
|
pub fn add_n_to_token_input_types() -> Box<[TypeId]> {
|
||||||
add_n_to_token().input_types()
|
add_n_to_token().input_types()
|
||||||
}
|
}
|
||||||
@ -577,12 +612,13 @@ mod generate_tests {
|
|||||||
pub fn rhai_module_generate() -> Module {
|
pub fn rhai_module_generate() -> Module {
|
||||||
let mut m = Module::new();
|
let mut m = Module::new();
|
||||||
rhai_generate_into_module(&mut m, false);
|
rhai_generate_into_module(&mut m, false);
|
||||||
|
m.build_index();
|
||||||
m
|
m
|
||||||
}
|
}
|
||||||
#[allow(unused_mut)]
|
#[allow(unused_mut)]
|
||||||
pub fn rhai_generate_into_module(m: &mut Module, flatten: bool) {
|
pub fn rhai_generate_into_module(m: &mut Module, flatten: bool) {
|
||||||
m.set_fn("add_together", FnNamespace::Internal, FnAccess::Public, &[core::any::TypeId::of::<INT>(),
|
m.set_fn("add_together", FnNamespace::Internal, FnAccess::Public, Some(&["x: INT", "y: INT"]),
|
||||||
core::any::TypeId::of::<INT>()],
|
&[core::any::TypeId::of::<INT>(), core::any::TypeId::of::<INT>()],
|
||||||
add_together_token().into());
|
add_together_token().into());
|
||||||
if flatten {} else {}
|
if flatten {} else {}
|
||||||
}
|
}
|
||||||
@ -602,6 +638,9 @@ mod generate_tests {
|
|||||||
fn clone_boxed(&self) -> Box<dyn PluginFunction> {
|
fn clone_boxed(&self) -> Box<dyn PluginFunction> {
|
||||||
Box::new(add_together_token())
|
Box::new(add_together_token())
|
||||||
}
|
}
|
||||||
|
fn input_names(&self) -> Box<[&'static str]> {
|
||||||
|
new_vec!["x: INT", "y: INT"].into_boxed_slice()
|
||||||
|
}
|
||||||
fn input_types(&self) -> Box<[TypeId]> {
|
fn input_types(&self) -> Box<[TypeId]> {
|
||||||
new_vec![TypeId::of::<INT>(),
|
new_vec![TypeId::of::<INT>(),
|
||||||
TypeId::of::<INT>()].into_boxed_slice()
|
TypeId::of::<INT>()].into_boxed_slice()
|
||||||
@ -610,6 +649,9 @@ mod generate_tests {
|
|||||||
pub fn add_together_token_callable() -> CallableFunction {
|
pub fn add_together_token_callable() -> CallableFunction {
|
||||||
add_together_token().into()
|
add_together_token().into()
|
||||||
}
|
}
|
||||||
|
pub fn add_together_token_input_names() -> Box<[&'static str]> {
|
||||||
|
add_together_token().input_names()
|
||||||
|
}
|
||||||
pub fn add_together_token_input_types() -> Box<[TypeId]> {
|
pub fn add_together_token_input_types() -> Box<[TypeId]> {
|
||||||
add_together_token().input_types()
|
add_together_token().input_types()
|
||||||
}
|
}
|
||||||
@ -642,18 +684,19 @@ mod generate_tests {
|
|||||||
pub fn rhai_module_generate() -> Module {
|
pub fn rhai_module_generate() -> Module {
|
||||||
let mut m = Module::new();
|
let mut m = Module::new();
|
||||||
rhai_generate_into_module(&mut m, false);
|
rhai_generate_into_module(&mut m, false);
|
||||||
|
m.build_index();
|
||||||
m
|
m
|
||||||
}
|
}
|
||||||
#[allow(unused_mut)]
|
#[allow(unused_mut)]
|
||||||
pub fn rhai_generate_into_module(m: &mut Module, flatten: bool) {
|
pub fn rhai_generate_into_module(m: &mut Module, flatten: bool) {
|
||||||
m.set_fn("add", FnNamespace::Internal, FnAccess::Public, &[core::any::TypeId::of::<INT>(),
|
m.set_fn("add", FnNamespace::Internal, FnAccess::Public, Some(&["x: INT", "y: INT"]),
|
||||||
core::any::TypeId::of::<INT>()],
|
&[core::any::TypeId::of::<INT>(), core::any::TypeId::of::<INT>()],
|
||||||
add_together_token().into());
|
add_together_token().into());
|
||||||
m.set_fn("+", FnNamespace::Internal, FnAccess::Public, &[core::any::TypeId::of::<INT>(),
|
m.set_fn("+", FnNamespace::Internal, FnAccess::Public, Some(&["x: INT", "y: INT"]),
|
||||||
core::any::TypeId::of::<INT>()],
|
&[core::any::TypeId::of::<INT>(), core::any::TypeId::of::<INT>()],
|
||||||
add_together_token().into());
|
add_together_token().into());
|
||||||
m.set_fn("add_together", FnNamespace::Internal, FnAccess::Public, &[core::any::TypeId::of::<INT>(),
|
m.set_fn("add_together", FnNamespace::Internal, FnAccess::Public, Some(&["x: INT", "y: INT"]),
|
||||||
core::any::TypeId::of::<INT>()],
|
&[core::any::TypeId::of::<INT>(), core::any::TypeId::of::<INT>()],
|
||||||
add_together_token().into());
|
add_together_token().into());
|
||||||
if flatten {} else {}
|
if flatten {} else {}
|
||||||
}
|
}
|
||||||
@ -673,6 +716,9 @@ mod generate_tests {
|
|||||||
fn clone_boxed(&self) -> Box<dyn PluginFunction> {
|
fn clone_boxed(&self) -> Box<dyn PluginFunction> {
|
||||||
Box::new(add_together_token())
|
Box::new(add_together_token())
|
||||||
}
|
}
|
||||||
|
fn input_names(&self) -> Box<[&'static str]> {
|
||||||
|
new_vec!["x: INT", "y: INT"].into_boxed_slice()
|
||||||
|
}
|
||||||
fn input_types(&self) -> Box<[TypeId]> {
|
fn input_types(&self) -> Box<[TypeId]> {
|
||||||
new_vec![TypeId::of::<INT>(),
|
new_vec![TypeId::of::<INT>(),
|
||||||
TypeId::of::<INT>()].into_boxed_slice()
|
TypeId::of::<INT>()].into_boxed_slice()
|
||||||
@ -681,6 +727,9 @@ mod generate_tests {
|
|||||||
pub fn add_together_token_callable() -> CallableFunction {
|
pub fn add_together_token_callable() -> CallableFunction {
|
||||||
add_together_token().into()
|
add_together_token().into()
|
||||||
}
|
}
|
||||||
|
pub fn add_together_token_input_names() -> Box<[&'static str]> {
|
||||||
|
add_together_token().input_names()
|
||||||
|
}
|
||||||
pub fn add_together_token_input_types() -> Box<[TypeId]> {
|
pub fn add_together_token_input_types() -> Box<[TypeId]> {
|
||||||
add_together_token().input_types()
|
add_together_token().input_types()
|
||||||
}
|
}
|
||||||
@ -714,6 +763,7 @@ mod generate_tests {
|
|||||||
pub fn rhai_module_generate() -> Module {
|
pub fn rhai_module_generate() -> Module {
|
||||||
let mut m = Module::new();
|
let mut m = Module::new();
|
||||||
rhai_generate_into_module(&mut m, false);
|
rhai_generate_into_module(&mut m, false);
|
||||||
|
m.build_index();
|
||||||
m
|
m
|
||||||
}
|
}
|
||||||
#[allow(unused_mut)]
|
#[allow(unused_mut)]
|
||||||
@ -745,6 +795,7 @@ mod generate_tests {
|
|||||||
pub fn rhai_module_generate() -> Module {
|
pub fn rhai_module_generate() -> Module {
|
||||||
let mut m = Module::new();
|
let mut m = Module::new();
|
||||||
rhai_generate_into_module(&mut m, false);
|
rhai_generate_into_module(&mut m, false);
|
||||||
|
m.build_index();
|
||||||
m
|
m
|
||||||
}
|
}
|
||||||
#[allow(unused_mut)]
|
#[allow(unused_mut)]
|
||||||
@ -778,6 +829,7 @@ mod generate_tests {
|
|||||||
pub fn rhai_module_generate() -> Module {
|
pub fn rhai_module_generate() -> Module {
|
||||||
let mut m = Module::new();
|
let mut m = Module::new();
|
||||||
rhai_generate_into_module(&mut m, false);
|
rhai_generate_into_module(&mut m, false);
|
||||||
|
m.build_index();
|
||||||
m
|
m
|
||||||
}
|
}
|
||||||
#[allow(unused_mut)]
|
#[allow(unused_mut)]
|
||||||
@ -813,6 +865,7 @@ mod generate_tests {
|
|||||||
pub fn rhai_module_generate() -> Module {
|
pub fn rhai_module_generate() -> Module {
|
||||||
let mut m = Module::new();
|
let mut m = Module::new();
|
||||||
rhai_generate_into_module(&mut m, false);
|
rhai_generate_into_module(&mut m, false);
|
||||||
|
m.build_index();
|
||||||
m
|
m
|
||||||
}
|
}
|
||||||
#[allow(unused_mut)]
|
#[allow(unused_mut)]
|
||||||
@ -848,6 +901,7 @@ mod generate_tests {
|
|||||||
pub fn rhai_module_generate() -> Module {
|
pub fn rhai_module_generate() -> Module {
|
||||||
let mut m = Module::new();
|
let mut m = Module::new();
|
||||||
rhai_generate_into_module(&mut m, false);
|
rhai_generate_into_module(&mut m, false);
|
||||||
|
m.build_index();
|
||||||
m
|
m
|
||||||
}
|
}
|
||||||
#[allow(unused_mut)]
|
#[allow(unused_mut)]
|
||||||
@ -889,11 +943,12 @@ mod generate_tests {
|
|||||||
pub fn rhai_module_generate() -> Module {
|
pub fn rhai_module_generate() -> Module {
|
||||||
let mut m = Module::new();
|
let mut m = Module::new();
|
||||||
rhai_generate_into_module(&mut m, false);
|
rhai_generate_into_module(&mut m, false);
|
||||||
|
m.build_index();
|
||||||
m
|
m
|
||||||
}
|
}
|
||||||
#[allow(unused_mut)]
|
#[allow(unused_mut)]
|
||||||
pub fn rhai_generate_into_module(m: &mut Module, flatten: bool) {
|
pub fn rhai_generate_into_module(m: &mut Module, flatten: bool) {
|
||||||
m.set_fn("get_mystic_number", FnNamespace::Internal, FnAccess::Public, &[],
|
m.set_fn("get_mystic_number", FnNamespace::Internal, FnAccess::Public, Some(&[]), &[],
|
||||||
get_mystic_number_token().into());
|
get_mystic_number_token().into());
|
||||||
if flatten {} else {}
|
if flatten {} else {}
|
||||||
}
|
}
|
||||||
@ -911,6 +966,9 @@ mod generate_tests {
|
|||||||
fn clone_boxed(&self) -> Box<dyn PluginFunction> {
|
fn clone_boxed(&self) -> Box<dyn PluginFunction> {
|
||||||
Box::new(get_mystic_number_token())
|
Box::new(get_mystic_number_token())
|
||||||
}
|
}
|
||||||
|
fn input_names(&self) -> Box<[&'static str]> {
|
||||||
|
new_vec![].into_boxed_slice()
|
||||||
|
}
|
||||||
fn input_types(&self) -> Box<[TypeId]> {
|
fn input_types(&self) -> Box<[TypeId]> {
|
||||||
new_vec![].into_boxed_slice()
|
new_vec![].into_boxed_slice()
|
||||||
}
|
}
|
||||||
@ -918,6 +976,9 @@ mod generate_tests {
|
|||||||
pub fn get_mystic_number_token_callable() -> CallableFunction {
|
pub fn get_mystic_number_token_callable() -> CallableFunction {
|
||||||
get_mystic_number_token().into()
|
get_mystic_number_token().into()
|
||||||
}
|
}
|
||||||
|
pub fn get_mystic_number_token_input_names() -> Box<[&'static str]> {
|
||||||
|
get_mystic_number_token().input_names()
|
||||||
|
}
|
||||||
pub fn get_mystic_number_token_input_types() -> Box<[TypeId]> {
|
pub fn get_mystic_number_token_input_types() -> Box<[TypeId]> {
|
||||||
get_mystic_number_token().input_types()
|
get_mystic_number_token().input_types()
|
||||||
}
|
}
|
||||||
@ -945,6 +1006,7 @@ mod generate_tests {
|
|||||||
pub fn rhai_module_generate() -> Module {
|
pub fn rhai_module_generate() -> Module {
|
||||||
let mut m = Module::new();
|
let mut m = Module::new();
|
||||||
rhai_generate_into_module(&mut m, false);
|
rhai_generate_into_module(&mut m, false);
|
||||||
|
m.build_index();
|
||||||
m
|
m
|
||||||
}
|
}
|
||||||
#[allow(unused_mut)]
|
#[allow(unused_mut)]
|
||||||
@ -979,12 +1041,13 @@ mod generate_tests {
|
|||||||
pub fn rhai_module_generate() -> Module {
|
pub fn rhai_module_generate() -> Module {
|
||||||
let mut m = Module::new();
|
let mut m = Module::new();
|
||||||
rhai_generate_into_module(&mut m, false);
|
rhai_generate_into_module(&mut m, false);
|
||||||
|
m.build_index();
|
||||||
m
|
m
|
||||||
}
|
}
|
||||||
#[allow(unused_mut)]
|
#[allow(unused_mut)]
|
||||||
pub fn rhai_generate_into_module(m: &mut Module, flatten: bool) {
|
pub fn rhai_generate_into_module(m: &mut Module, flatten: bool) {
|
||||||
m.set_fn("print_out_to", FnNamespace::Internal, FnAccess::Public,
|
m.set_fn("print_out_to", FnNamespace::Internal, FnAccess::Public,
|
||||||
&[core::any::TypeId::of::<ImmutableString>()],
|
Some(&["x: &str"]), &[core::any::TypeId::of::<ImmutableString>()],
|
||||||
print_out_to_token().into());
|
print_out_to_token().into());
|
||||||
if flatten {} else {}
|
if flatten {} else {}
|
||||||
}
|
}
|
||||||
@ -1003,6 +1066,9 @@ mod generate_tests {
|
|||||||
fn clone_boxed(&self) -> Box<dyn PluginFunction> {
|
fn clone_boxed(&self) -> Box<dyn PluginFunction> {
|
||||||
Box::new(print_out_to_token())
|
Box::new(print_out_to_token())
|
||||||
}
|
}
|
||||||
|
fn input_names(&self) -> Box<[&'static str]> {
|
||||||
|
new_vec!["x: &str"].into_boxed_slice()
|
||||||
|
}
|
||||||
fn input_types(&self) -> Box<[TypeId]> {
|
fn input_types(&self) -> Box<[TypeId]> {
|
||||||
new_vec![TypeId::of::<ImmutableString>()].into_boxed_slice()
|
new_vec![TypeId::of::<ImmutableString>()].into_boxed_slice()
|
||||||
}
|
}
|
||||||
@ -1010,6 +1076,9 @@ mod generate_tests {
|
|||||||
pub fn print_out_to_token_callable() -> CallableFunction {
|
pub fn print_out_to_token_callable() -> CallableFunction {
|
||||||
print_out_to_token().into()
|
print_out_to_token().into()
|
||||||
}
|
}
|
||||||
|
pub fn print_out_to_token_input_names() -> Box<[&'static str]> {
|
||||||
|
print_out_to_token().input_names()
|
||||||
|
}
|
||||||
pub fn print_out_to_token_input_types() -> Box<[TypeId]> {
|
pub fn print_out_to_token_input_types() -> Box<[TypeId]> {
|
||||||
print_out_to_token().input_types()
|
print_out_to_token().input_types()
|
||||||
}
|
}
|
||||||
@ -1041,12 +1110,13 @@ mod generate_tests {
|
|||||||
pub fn rhai_module_generate() -> Module {
|
pub fn rhai_module_generate() -> Module {
|
||||||
let mut m = Module::new();
|
let mut m = Module::new();
|
||||||
rhai_generate_into_module(&mut m, false);
|
rhai_generate_into_module(&mut m, false);
|
||||||
|
m.build_index();
|
||||||
m
|
m
|
||||||
}
|
}
|
||||||
#[allow(unused_mut)]
|
#[allow(unused_mut)]
|
||||||
pub fn rhai_generate_into_module(m: &mut Module, flatten: bool) {
|
pub fn rhai_generate_into_module(m: &mut Module, flatten: bool) {
|
||||||
m.set_fn("print_out_to", FnNamespace::Internal, FnAccess::Public,
|
m.set_fn("print_out_to", FnNamespace::Internal, FnAccess::Public,
|
||||||
&[core::any::TypeId::of::<ImmutableString>()],
|
Some(&["x: String"]), &[core::any::TypeId::of::<ImmutableString>()],
|
||||||
print_out_to_token().into());
|
print_out_to_token().into());
|
||||||
if flatten {} else {}
|
if flatten {} else {}
|
||||||
}
|
}
|
||||||
@ -1065,6 +1135,9 @@ mod generate_tests {
|
|||||||
fn clone_boxed(&self) -> Box<dyn PluginFunction> {
|
fn clone_boxed(&self) -> Box<dyn PluginFunction> {
|
||||||
Box::new(print_out_to_token())
|
Box::new(print_out_to_token())
|
||||||
}
|
}
|
||||||
|
fn input_names(&self) -> Box<[&'static str]> {
|
||||||
|
new_vec!["x: String"].into_boxed_slice()
|
||||||
|
}
|
||||||
fn input_types(&self) -> Box<[TypeId]> {
|
fn input_types(&self) -> Box<[TypeId]> {
|
||||||
new_vec![TypeId::of::<ImmutableString>()].into_boxed_slice()
|
new_vec![TypeId::of::<ImmutableString>()].into_boxed_slice()
|
||||||
}
|
}
|
||||||
@ -1072,6 +1145,9 @@ mod generate_tests {
|
|||||||
pub fn print_out_to_token_callable() -> CallableFunction {
|
pub fn print_out_to_token_callable() -> CallableFunction {
|
||||||
print_out_to_token().into()
|
print_out_to_token().into()
|
||||||
}
|
}
|
||||||
|
pub fn print_out_to_token_input_names() -> Box<[&'static str]> {
|
||||||
|
print_out_to_token().input_names()
|
||||||
|
}
|
||||||
pub fn print_out_to_token_input_types() -> Box<[TypeId]> {
|
pub fn print_out_to_token_input_types() -> Box<[TypeId]> {
|
||||||
print_out_to_token().input_types()
|
print_out_to_token().input_types()
|
||||||
}
|
}
|
||||||
@ -1103,12 +1179,13 @@ mod generate_tests {
|
|||||||
pub fn rhai_module_generate() -> Module {
|
pub fn rhai_module_generate() -> Module {
|
||||||
let mut m = Module::new();
|
let mut m = Module::new();
|
||||||
rhai_generate_into_module(&mut m, false);
|
rhai_generate_into_module(&mut m, false);
|
||||||
|
m.build_index();
|
||||||
m
|
m
|
||||||
}
|
}
|
||||||
#[allow(unused_mut)]
|
#[allow(unused_mut)]
|
||||||
pub fn rhai_generate_into_module(m: &mut Module, flatten: bool) {
|
pub fn rhai_generate_into_module(m: &mut Module, flatten: bool) {
|
||||||
m.set_fn("increment", FnNamespace::Internal, FnAccess::Public,
|
m.set_fn("increment", FnNamespace::Internal, FnAccess::Public,
|
||||||
&[core::any::TypeId::of::<FLOAT>()],
|
Some(&["x: &mut FLOAT"]), &[core::any::TypeId::of::<FLOAT>()],
|
||||||
increment_token().into());
|
increment_token().into());
|
||||||
if flatten {} else {}
|
if flatten {} else {}
|
||||||
}
|
}
|
||||||
@ -1127,6 +1204,9 @@ mod generate_tests {
|
|||||||
fn clone_boxed(&self) -> Box<dyn PluginFunction> {
|
fn clone_boxed(&self) -> Box<dyn PluginFunction> {
|
||||||
Box::new(increment_token())
|
Box::new(increment_token())
|
||||||
}
|
}
|
||||||
|
fn input_names(&self) -> Box<[&'static str]> {
|
||||||
|
new_vec!["x: &mut FLOAT"].into_boxed_slice()
|
||||||
|
}
|
||||||
fn input_types(&self) -> Box<[TypeId]> {
|
fn input_types(&self) -> Box<[TypeId]> {
|
||||||
new_vec![TypeId::of::<FLOAT>()].into_boxed_slice()
|
new_vec![TypeId::of::<FLOAT>()].into_boxed_slice()
|
||||||
}
|
}
|
||||||
@ -1134,6 +1214,9 @@ mod generate_tests {
|
|||||||
pub fn increment_token_callable() -> CallableFunction {
|
pub fn increment_token_callable() -> CallableFunction {
|
||||||
increment_token().into()
|
increment_token().into()
|
||||||
}
|
}
|
||||||
|
pub fn increment_token_input_names() -> Box<[&'static str]> {
|
||||||
|
increment_token().input_names()
|
||||||
|
}
|
||||||
pub fn increment_token_input_types() -> Box<[TypeId]> {
|
pub fn increment_token_input_types() -> Box<[TypeId]> {
|
||||||
increment_token().input_types()
|
increment_token().input_types()
|
||||||
}
|
}
|
||||||
@ -1168,12 +1251,13 @@ mod generate_tests {
|
|||||||
pub fn rhai_module_generate() -> Module {
|
pub fn rhai_module_generate() -> Module {
|
||||||
let mut m = Module::new();
|
let mut m = Module::new();
|
||||||
rhai_generate_into_module(&mut m, false);
|
rhai_generate_into_module(&mut m, false);
|
||||||
|
m.build_index();
|
||||||
m
|
m
|
||||||
}
|
}
|
||||||
#[allow(unused_mut)]
|
#[allow(unused_mut)]
|
||||||
pub fn rhai_generate_into_module(m: &mut Module, flatten: bool) {
|
pub fn rhai_generate_into_module(m: &mut Module, flatten: bool) {
|
||||||
m.set_fn("increment", FnNamespace::Internal, FnAccess::Public,
|
m.set_fn("increment", FnNamespace::Internal, FnAccess::Public,
|
||||||
&[core::any::TypeId::of::<FLOAT>()],
|
Some(&["x: &mut FLOAT"]), &[core::any::TypeId::of::<FLOAT>()],
|
||||||
increment_token().into());
|
increment_token().into());
|
||||||
if flatten {} else {}
|
if flatten {} else {}
|
||||||
}
|
}
|
||||||
@ -1192,6 +1276,9 @@ mod generate_tests {
|
|||||||
fn clone_boxed(&self) -> Box<dyn PluginFunction> {
|
fn clone_boxed(&self) -> Box<dyn PluginFunction> {
|
||||||
Box::new(increment_token())
|
Box::new(increment_token())
|
||||||
}
|
}
|
||||||
|
fn input_names(&self) -> Box<[&'static str]> {
|
||||||
|
new_vec!["x: &mut FLOAT"].into_boxed_slice()
|
||||||
|
}
|
||||||
fn input_types(&self) -> Box<[TypeId]> {
|
fn input_types(&self) -> Box<[TypeId]> {
|
||||||
new_vec![TypeId::of::<FLOAT>()].into_boxed_slice()
|
new_vec![TypeId::of::<FLOAT>()].into_boxed_slice()
|
||||||
}
|
}
|
||||||
@ -1199,6 +1286,9 @@ mod generate_tests {
|
|||||||
pub fn increment_token_callable() -> CallableFunction {
|
pub fn increment_token_callable() -> CallableFunction {
|
||||||
increment_token().into()
|
increment_token().into()
|
||||||
}
|
}
|
||||||
|
pub fn increment_token_input_names() -> Box<[&'static str]> {
|
||||||
|
increment_token().input_names()
|
||||||
|
}
|
||||||
pub fn increment_token_input_types() -> Box<[TypeId]> {
|
pub fn increment_token_input_types() -> Box<[TypeId]> {
|
||||||
increment_token().input_types()
|
increment_token().input_types()
|
||||||
}
|
}
|
||||||
@ -1209,6 +1299,7 @@ mod generate_tests {
|
|||||||
pub fn rhai_module_generate() -> Module {
|
pub fn rhai_module_generate() -> Module {
|
||||||
let mut m = Module::new();
|
let mut m = Module::new();
|
||||||
rhai_generate_into_module(&mut m, false);
|
rhai_generate_into_module(&mut m, false);
|
||||||
|
m.build_index();
|
||||||
m
|
m
|
||||||
}
|
}
|
||||||
#[allow(unused_mut)]
|
#[allow(unused_mut)]
|
||||||
@ -1253,12 +1344,13 @@ mod generate_tests {
|
|||||||
pub fn rhai_module_generate() -> Module {
|
pub fn rhai_module_generate() -> Module {
|
||||||
let mut m = Module::new();
|
let mut m = Module::new();
|
||||||
rhai_generate_into_module(&mut m, false);
|
rhai_generate_into_module(&mut m, false);
|
||||||
|
m.build_index();
|
||||||
m
|
m
|
||||||
}
|
}
|
||||||
#[allow(unused_mut)]
|
#[allow(unused_mut)]
|
||||||
pub fn rhai_generate_into_module(m: &mut Module, flatten: bool) {
|
pub fn rhai_generate_into_module(m: &mut Module, flatten: bool) {
|
||||||
m.set_fn("increment", FnNamespace::Internal, FnAccess::Public,
|
m.set_fn("increment", FnNamespace::Internal, FnAccess::Public,
|
||||||
&[core::any::TypeId::of::<FLOAT>()],
|
Some(&["x: &mut FLOAT"]), &[core::any::TypeId::of::<FLOAT>()],
|
||||||
increment_token().into());
|
increment_token().into());
|
||||||
if flatten {} else {}
|
if flatten {} else {}
|
||||||
}
|
}
|
||||||
@ -1277,6 +1369,9 @@ mod generate_tests {
|
|||||||
fn clone_boxed(&self) -> Box<dyn PluginFunction> {
|
fn clone_boxed(&self) -> Box<dyn PluginFunction> {
|
||||||
Box::new(increment_token())
|
Box::new(increment_token())
|
||||||
}
|
}
|
||||||
|
fn input_names(&self) -> Box<[&'static str]> {
|
||||||
|
new_vec!["x: &mut FLOAT"].into_boxed_slice()
|
||||||
|
}
|
||||||
fn input_types(&self) -> Box<[TypeId]> {
|
fn input_types(&self) -> Box<[TypeId]> {
|
||||||
new_vec![TypeId::of::<FLOAT>()].into_boxed_slice()
|
new_vec![TypeId::of::<FLOAT>()].into_boxed_slice()
|
||||||
}
|
}
|
||||||
@ -1284,6 +1379,9 @@ mod generate_tests {
|
|||||||
pub fn increment_token_callable() -> CallableFunction {
|
pub fn increment_token_callable() -> CallableFunction {
|
||||||
increment_token().into()
|
increment_token().into()
|
||||||
}
|
}
|
||||||
|
pub fn increment_token_input_names() -> Box<[&'static str]> {
|
||||||
|
increment_token().input_names()
|
||||||
|
}
|
||||||
pub fn increment_token_input_types() -> Box<[TypeId]> {
|
pub fn increment_token_input_types() -> Box<[TypeId]> {
|
||||||
increment_token().input_types()
|
increment_token().input_types()
|
||||||
}
|
}
|
||||||
@ -1294,6 +1392,7 @@ mod generate_tests {
|
|||||||
pub fn rhai_module_generate() -> Module {
|
pub fn rhai_module_generate() -> Module {
|
||||||
let mut m = Module::new();
|
let mut m = Module::new();
|
||||||
rhai_generate_into_module(&mut m, false);
|
rhai_generate_into_module(&mut m, false);
|
||||||
|
m.build_index();
|
||||||
m
|
m
|
||||||
}
|
}
|
||||||
#[allow(unused_mut)]
|
#[allow(unused_mut)]
|
||||||
@ -1337,11 +1436,12 @@ mod generate_tests {
|
|||||||
pub fn rhai_module_generate() -> Module {
|
pub fn rhai_module_generate() -> Module {
|
||||||
let mut m = Module::new();
|
let mut m = Module::new();
|
||||||
rhai_generate_into_module(&mut m, false);
|
rhai_generate_into_module(&mut m, false);
|
||||||
|
m.build_index();
|
||||||
m
|
m
|
||||||
}
|
}
|
||||||
#[allow(unused_mut)]
|
#[allow(unused_mut)]
|
||||||
pub fn rhai_generate_into_module(m: &mut Module, flatten: bool) {
|
pub fn rhai_generate_into_module(m: &mut Module, flatten: bool) {
|
||||||
m.set_fn("get$square", FnNamespace::Internal, FnAccess::Public, &[core::any::TypeId::of::<u64>()],
|
m.set_fn("get$square", FnNamespace::Internal, FnAccess::Public, Some(&["x: &mut u64"]), &[core::any::TypeId::of::<u64>()],
|
||||||
int_foo_token().into());
|
int_foo_token().into());
|
||||||
if flatten {} else {}
|
if flatten {} else {}
|
||||||
}
|
}
|
||||||
@ -1360,6 +1460,9 @@ mod generate_tests {
|
|||||||
fn clone_boxed(&self) -> Box<dyn PluginFunction> {
|
fn clone_boxed(&self) -> Box<dyn PluginFunction> {
|
||||||
Box::new(int_foo_token())
|
Box::new(int_foo_token())
|
||||||
}
|
}
|
||||||
|
fn input_names(&self) -> Box<[&'static str]> {
|
||||||
|
new_vec!["x: &mut u64"].into_boxed_slice()
|
||||||
|
}
|
||||||
fn input_types(&self) -> Box<[TypeId]> {
|
fn input_types(&self) -> Box<[TypeId]> {
|
||||||
new_vec![TypeId::of::<u64>()].into_boxed_slice()
|
new_vec![TypeId::of::<u64>()].into_boxed_slice()
|
||||||
}
|
}
|
||||||
@ -1367,6 +1470,9 @@ mod generate_tests {
|
|||||||
pub fn int_foo_token_callable() -> CallableFunction {
|
pub fn int_foo_token_callable() -> CallableFunction {
|
||||||
int_foo_token().into()
|
int_foo_token().into()
|
||||||
}
|
}
|
||||||
|
pub fn int_foo_token_input_names() -> Box<[&'static str]> {
|
||||||
|
int_foo_token().input_names()
|
||||||
|
}
|
||||||
pub fn int_foo_token_input_types() -> Box<[TypeId]> {
|
pub fn int_foo_token_input_types() -> Box<[TypeId]> {
|
||||||
int_foo_token().input_types()
|
int_foo_token().input_types()
|
||||||
}
|
}
|
||||||
@ -1399,13 +1505,14 @@ mod generate_tests {
|
|||||||
pub fn rhai_module_generate() -> Module {
|
pub fn rhai_module_generate() -> Module {
|
||||||
let mut m = Module::new();
|
let mut m = Module::new();
|
||||||
rhai_generate_into_module(&mut m, false);
|
rhai_generate_into_module(&mut m, false);
|
||||||
|
m.build_index();
|
||||||
m
|
m
|
||||||
}
|
}
|
||||||
#[allow(unused_mut)]
|
#[allow(unused_mut)]
|
||||||
pub fn rhai_generate_into_module(m: &mut Module, flatten: bool) {
|
pub fn rhai_generate_into_module(m: &mut Module, flatten: bool) {
|
||||||
m.set_fn("square", FnNamespace::Internal, FnAccess::Public, &[core::any::TypeId::of::<u64>()],
|
m.set_fn("square", FnNamespace::Internal, FnAccess::Public, Some(&["x: &mut u64"]), &[core::any::TypeId::of::<u64>()],
|
||||||
int_foo_token().into());
|
int_foo_token().into());
|
||||||
m.set_fn("get$square", FnNamespace::Internal, FnAccess::Public, &[core::any::TypeId::of::<u64>()],
|
m.set_fn("get$square", FnNamespace::Internal, FnAccess::Public, Some(&["x: &mut u64"]), &[core::any::TypeId::of::<u64>()],
|
||||||
int_foo_token().into());
|
int_foo_token().into());
|
||||||
if flatten {} else {}
|
if flatten {} else {}
|
||||||
}
|
}
|
||||||
@ -1424,6 +1531,9 @@ mod generate_tests {
|
|||||||
fn clone_boxed(&self) -> Box<dyn PluginFunction> {
|
fn clone_boxed(&self) -> Box<dyn PluginFunction> {
|
||||||
Box::new(int_foo_token())
|
Box::new(int_foo_token())
|
||||||
}
|
}
|
||||||
|
fn input_names(&self) -> Box<[&'static str]> {
|
||||||
|
new_vec!["x: &mut u64"].into_boxed_slice()
|
||||||
|
}
|
||||||
fn input_types(&self) -> Box<[TypeId]> {
|
fn input_types(&self) -> Box<[TypeId]> {
|
||||||
new_vec![TypeId::of::<u64>()].into_boxed_slice()
|
new_vec![TypeId::of::<u64>()].into_boxed_slice()
|
||||||
}
|
}
|
||||||
@ -1431,6 +1541,9 @@ mod generate_tests {
|
|||||||
pub fn int_foo_token_callable() -> CallableFunction {
|
pub fn int_foo_token_callable() -> CallableFunction {
|
||||||
int_foo_token().into()
|
int_foo_token().into()
|
||||||
}
|
}
|
||||||
|
pub fn int_foo_token_input_names() -> Box<[&'static str]> {
|
||||||
|
int_foo_token().input_names()
|
||||||
|
}
|
||||||
pub fn int_foo_token_input_types() -> Box<[TypeId]> {
|
pub fn int_foo_token_input_types() -> Box<[TypeId]> {
|
||||||
int_foo_token().input_types()
|
int_foo_token().input_types()
|
||||||
}
|
}
|
||||||
@ -1463,13 +1576,13 @@ mod generate_tests {
|
|||||||
pub fn rhai_module_generate() -> Module {
|
pub fn rhai_module_generate() -> Module {
|
||||||
let mut m = Module::new();
|
let mut m = Module::new();
|
||||||
rhai_generate_into_module(&mut m, false);
|
rhai_generate_into_module(&mut m, false);
|
||||||
|
m.build_index();
|
||||||
m
|
m
|
||||||
}
|
}
|
||||||
#[allow(unused_mut)]
|
#[allow(unused_mut)]
|
||||||
pub fn rhai_generate_into_module(m: &mut Module, flatten: bool) {
|
pub fn rhai_generate_into_module(m: &mut Module, flatten: bool) {
|
||||||
m.set_fn("set$squared", FnNamespace::Internal, FnAccess::Public,
|
m.set_fn("set$squared", FnNamespace::Internal, FnAccess::Public, Some(&["x: &mut u64", "y: u64"]),
|
||||||
&[core::any::TypeId::of::<u64>(),
|
&[core::any::TypeId::of::<u64>(), core::any::TypeId::of::<u64>()],
|
||||||
core::any::TypeId::of::<u64>()],
|
|
||||||
int_foo_token().into());
|
int_foo_token().into());
|
||||||
if flatten {} else {}
|
if flatten {} else {}
|
||||||
}
|
}
|
||||||
@ -1489,6 +1602,9 @@ mod generate_tests {
|
|||||||
fn clone_boxed(&self) -> Box<dyn PluginFunction> {
|
fn clone_boxed(&self) -> Box<dyn PluginFunction> {
|
||||||
Box::new(int_foo_token())
|
Box::new(int_foo_token())
|
||||||
}
|
}
|
||||||
|
fn input_names(&self) -> Box<[&'static str]> {
|
||||||
|
new_vec!["x: &mut u64", "y: u64"].into_boxed_slice()
|
||||||
|
}
|
||||||
fn input_types(&self) -> Box<[TypeId]> {
|
fn input_types(&self) -> Box<[TypeId]> {
|
||||||
new_vec![TypeId::of::<u64>(), TypeId::of::<u64>()].into_boxed_slice()
|
new_vec![TypeId::of::<u64>(), TypeId::of::<u64>()].into_boxed_slice()
|
||||||
}
|
}
|
||||||
@ -1496,6 +1612,9 @@ mod generate_tests {
|
|||||||
pub fn int_foo_token_callable() -> CallableFunction {
|
pub fn int_foo_token_callable() -> CallableFunction {
|
||||||
int_foo_token().into()
|
int_foo_token().into()
|
||||||
}
|
}
|
||||||
|
pub fn int_foo_token_input_names() -> Box<[&'static str]> {
|
||||||
|
int_foo_token().input_names()
|
||||||
|
}
|
||||||
pub fn int_foo_token_input_types() -> Box<[TypeId]> {
|
pub fn int_foo_token_input_types() -> Box<[TypeId]> {
|
||||||
int_foo_token().input_types()
|
int_foo_token().input_types()
|
||||||
}
|
}
|
||||||
@ -1528,17 +1647,16 @@ mod generate_tests {
|
|||||||
pub fn rhai_module_generate() -> Module {
|
pub fn rhai_module_generate() -> Module {
|
||||||
let mut m = Module::new();
|
let mut m = Module::new();
|
||||||
rhai_generate_into_module(&mut m, false);
|
rhai_generate_into_module(&mut m, false);
|
||||||
|
m.build_index();
|
||||||
m
|
m
|
||||||
}
|
}
|
||||||
#[allow(unused_mut)]
|
#[allow(unused_mut)]
|
||||||
pub fn rhai_generate_into_module(m: &mut Module, flatten: bool) {
|
pub fn rhai_generate_into_module(m: &mut Module, flatten: bool) {
|
||||||
m.set_fn("set_sq", FnNamespace::Internal, FnAccess::Public,
|
m.set_fn("set_sq", FnNamespace::Internal, FnAccess::Public, Some(&["x: &mut u64", "y: u64"]),
|
||||||
&[core::any::TypeId::of::<u64>(),
|
&[core::any::TypeId::of::<u64>(), core::any::TypeId::of::<u64>()],
|
||||||
core::any::TypeId::of::<u64>()],
|
|
||||||
int_foo_token().into());
|
int_foo_token().into());
|
||||||
m.set_fn("set$squared", FnNamespace::Internal, FnAccess::Public,
|
m.set_fn("set$squared", FnNamespace::Internal, FnAccess::Public, Some(&["x: &mut u64", "y: u64"]),
|
||||||
&[core::any::TypeId::of::<u64>(),
|
&[core::any::TypeId::of::<u64>(), core::any::TypeId::of::<u64>()],
|
||||||
core::any::TypeId::of::<u64>()],
|
|
||||||
int_foo_token().into());
|
int_foo_token().into());
|
||||||
if flatten {} else {}
|
if flatten {} else {}
|
||||||
}
|
}
|
||||||
@ -1558,6 +1676,9 @@ mod generate_tests {
|
|||||||
fn clone_boxed(&self) -> Box<dyn PluginFunction> {
|
fn clone_boxed(&self) -> Box<dyn PluginFunction> {
|
||||||
Box::new(int_foo_token())
|
Box::new(int_foo_token())
|
||||||
}
|
}
|
||||||
|
fn input_names(&self) -> Box<[&'static str]> {
|
||||||
|
new_vec!["x: &mut u64", "y: u64"].into_boxed_slice()
|
||||||
|
}
|
||||||
fn input_types(&self) -> Box<[TypeId]> {
|
fn input_types(&self) -> Box<[TypeId]> {
|
||||||
new_vec![TypeId::of::<u64>(), TypeId::of::<u64>()].into_boxed_slice()
|
new_vec![TypeId::of::<u64>(), TypeId::of::<u64>()].into_boxed_slice()
|
||||||
}
|
}
|
||||||
@ -1565,6 +1686,9 @@ mod generate_tests {
|
|||||||
pub fn int_foo_token_callable() -> CallableFunction {
|
pub fn int_foo_token_callable() -> CallableFunction {
|
||||||
int_foo_token().into()
|
int_foo_token().into()
|
||||||
}
|
}
|
||||||
|
pub fn int_foo_token_input_names() -> Box<[&'static str]> {
|
||||||
|
int_foo_token().input_names()
|
||||||
|
}
|
||||||
pub fn int_foo_token_input_types() -> Box<[TypeId]> {
|
pub fn int_foo_token_input_types() -> Box<[TypeId]> {
|
||||||
int_foo_token().input_types()
|
int_foo_token().input_types()
|
||||||
}
|
}
|
||||||
@ -1597,11 +1721,13 @@ mod generate_tests {
|
|||||||
pub fn rhai_module_generate() -> Module {
|
pub fn rhai_module_generate() -> Module {
|
||||||
let mut m = Module::new();
|
let mut m = Module::new();
|
||||||
rhai_generate_into_module(&mut m, false);
|
rhai_generate_into_module(&mut m, false);
|
||||||
|
m.build_index();
|
||||||
m
|
m
|
||||||
}
|
}
|
||||||
#[allow(unused_mut)]
|
#[allow(unused_mut)]
|
||||||
pub fn rhai_generate_into_module(m: &mut Module, flatten: bool) {
|
pub fn rhai_generate_into_module(m: &mut Module, flatten: bool) {
|
||||||
m.set_fn("index$get$", FnNamespace::Internal, FnAccess::Public,
|
m.set_fn("index$get$", FnNamespace::Internal, FnAccess::Public,
|
||||||
|
Some(&["x: &mut MyCollection", "i: u64"]),
|
||||||
&[core::any::TypeId::of::<MyCollection>(),
|
&[core::any::TypeId::of::<MyCollection>(),
|
||||||
core::any::TypeId::of::<u64>()],
|
core::any::TypeId::of::<u64>()],
|
||||||
get_by_index_token().into());
|
get_by_index_token().into());
|
||||||
@ -1623,6 +1749,9 @@ mod generate_tests {
|
|||||||
fn clone_boxed(&self) -> Box<dyn PluginFunction> {
|
fn clone_boxed(&self) -> Box<dyn PluginFunction> {
|
||||||
Box::new(get_by_index_token())
|
Box::new(get_by_index_token())
|
||||||
}
|
}
|
||||||
|
fn input_names(&self) -> Box<[&'static str]> {
|
||||||
|
new_vec!["x: &mut MyCollection", "i: u64"].into_boxed_slice()
|
||||||
|
}
|
||||||
fn input_types(&self) -> Box<[TypeId]> {
|
fn input_types(&self) -> Box<[TypeId]> {
|
||||||
new_vec![TypeId::of::<MyCollection>(),
|
new_vec![TypeId::of::<MyCollection>(),
|
||||||
TypeId::of::<u64>()].into_boxed_slice()
|
TypeId::of::<u64>()].into_boxed_slice()
|
||||||
@ -1631,6 +1760,9 @@ mod generate_tests {
|
|||||||
pub fn get_by_index_token_callable() -> CallableFunction {
|
pub fn get_by_index_token_callable() -> CallableFunction {
|
||||||
get_by_index_token().into()
|
get_by_index_token().into()
|
||||||
}
|
}
|
||||||
|
pub fn get_by_index_token_input_names() -> Box<[&'static str]> {
|
||||||
|
get_by_index_token().input_names()
|
||||||
|
}
|
||||||
pub fn get_by_index_token_input_types() -> Box<[TypeId]> {
|
pub fn get_by_index_token_input_types() -> Box<[TypeId]> {
|
||||||
get_by_index_token().input_types()
|
get_by_index_token().input_types()
|
||||||
}
|
}
|
||||||
@ -1663,15 +1795,18 @@ mod generate_tests {
|
|||||||
pub fn rhai_module_generate() -> Module {
|
pub fn rhai_module_generate() -> Module {
|
||||||
let mut m = Module::new();
|
let mut m = Module::new();
|
||||||
rhai_generate_into_module(&mut m, false);
|
rhai_generate_into_module(&mut m, false);
|
||||||
|
m.build_index();
|
||||||
m
|
m
|
||||||
}
|
}
|
||||||
#[allow(unused_mut)]
|
#[allow(unused_mut)]
|
||||||
pub fn rhai_generate_into_module(m: &mut Module, flatten: bool) {
|
pub fn rhai_generate_into_module(m: &mut Module, flatten: bool) {
|
||||||
m.set_fn("get", FnNamespace::Internal, FnAccess::Public,
|
m.set_fn("get", FnNamespace::Internal, FnAccess::Public,
|
||||||
|
Some(&["x: &mut MyCollection", "i: u64"]),
|
||||||
&[core::any::TypeId::of::<MyCollection>(),
|
&[core::any::TypeId::of::<MyCollection>(),
|
||||||
core::any::TypeId::of::<u64>()],
|
core::any::TypeId::of::<u64>()],
|
||||||
get_by_index_token().into());
|
get_by_index_token().into());
|
||||||
m.set_fn("index$get$", FnNamespace::Internal, FnAccess::Public,
|
m.set_fn("index$get$", FnNamespace::Internal, FnAccess::Public,
|
||||||
|
Some(&["x: &mut MyCollection", "i: u64"]),
|
||||||
&[core::any::TypeId::of::<MyCollection>(),
|
&[core::any::TypeId::of::<MyCollection>(),
|
||||||
core::any::TypeId::of::<u64>()],
|
core::any::TypeId::of::<u64>()],
|
||||||
get_by_index_token().into());
|
get_by_index_token().into());
|
||||||
@ -1693,6 +1828,9 @@ mod generate_tests {
|
|||||||
fn clone_boxed(&self) -> Box<dyn PluginFunction> {
|
fn clone_boxed(&self) -> Box<dyn PluginFunction> {
|
||||||
Box::new(get_by_index_token())
|
Box::new(get_by_index_token())
|
||||||
}
|
}
|
||||||
|
fn input_names(&self) -> Box<[&'static str]> {
|
||||||
|
new_vec!["x: &mut MyCollection", "i: u64"].into_boxed_slice()
|
||||||
|
}
|
||||||
fn input_types(&self) -> Box<[TypeId]> {
|
fn input_types(&self) -> Box<[TypeId]> {
|
||||||
new_vec![TypeId::of::<MyCollection>(),
|
new_vec![TypeId::of::<MyCollection>(),
|
||||||
TypeId::of::<u64>()].into_boxed_slice()
|
TypeId::of::<u64>()].into_boxed_slice()
|
||||||
@ -1701,6 +1839,9 @@ mod generate_tests {
|
|||||||
pub fn get_by_index_token_callable() -> CallableFunction {
|
pub fn get_by_index_token_callable() -> CallableFunction {
|
||||||
get_by_index_token().into()
|
get_by_index_token().into()
|
||||||
}
|
}
|
||||||
|
pub fn get_by_index_token_input_names() -> Box<[&'static str]> {
|
||||||
|
get_by_index_token().input_names()
|
||||||
|
}
|
||||||
pub fn get_by_index_token_input_types() -> Box<[TypeId]> {
|
pub fn get_by_index_token_input_types() -> Box<[TypeId]> {
|
||||||
get_by_index_token().input_types()
|
get_by_index_token().input_types()
|
||||||
}
|
}
|
||||||
@ -1733,11 +1874,13 @@ mod generate_tests {
|
|||||||
pub fn rhai_module_generate() -> Module {
|
pub fn rhai_module_generate() -> Module {
|
||||||
let mut m = Module::new();
|
let mut m = Module::new();
|
||||||
rhai_generate_into_module(&mut m, false);
|
rhai_generate_into_module(&mut m, false);
|
||||||
|
m.build_index();
|
||||||
m
|
m
|
||||||
}
|
}
|
||||||
#[allow(unused_mut)]
|
#[allow(unused_mut)]
|
||||||
pub fn rhai_generate_into_module(m: &mut Module, flatten: bool) {
|
pub fn rhai_generate_into_module(m: &mut Module, flatten: bool) {
|
||||||
m.set_fn("index$set$", FnNamespace::Internal, FnAccess::Public,
|
m.set_fn("index$set$", FnNamespace::Internal, FnAccess::Public,
|
||||||
|
Some(&["x: &mut MyCollection", "i: u64", "item: FLOAT"]),
|
||||||
&[core::any::TypeId::of::<MyCollection>(),
|
&[core::any::TypeId::of::<MyCollection>(),
|
||||||
core::any::TypeId::of::<u64>(),
|
core::any::TypeId::of::<u64>(),
|
||||||
core::any::TypeId::of::<FLOAT>()],
|
core::any::TypeId::of::<FLOAT>()],
|
||||||
@ -1761,6 +1904,9 @@ mod generate_tests {
|
|||||||
fn clone_boxed(&self) -> Box<dyn PluginFunction> {
|
fn clone_boxed(&self) -> Box<dyn PluginFunction> {
|
||||||
Box::new(set_by_index_token())
|
Box::new(set_by_index_token())
|
||||||
}
|
}
|
||||||
|
fn input_names(&self) -> Box<[&'static str]> {
|
||||||
|
new_vec!["x: &mut MyCollection", "i: u64", "item: FLOAT"].into_boxed_slice()
|
||||||
|
}
|
||||||
fn input_types(&self) -> Box<[TypeId]> {
|
fn input_types(&self) -> Box<[TypeId]> {
|
||||||
new_vec![TypeId::of::<MyCollection>(),
|
new_vec![TypeId::of::<MyCollection>(),
|
||||||
TypeId::of::<u64>(),
|
TypeId::of::<u64>(),
|
||||||
@ -1770,6 +1916,9 @@ mod generate_tests {
|
|||||||
pub fn set_by_index_token_callable() -> CallableFunction {
|
pub fn set_by_index_token_callable() -> CallableFunction {
|
||||||
set_by_index_token().into()
|
set_by_index_token().into()
|
||||||
}
|
}
|
||||||
|
pub fn set_by_index_token_input_names() -> Box<[&'static str]> {
|
||||||
|
set_by_index_token().input_names()
|
||||||
|
}
|
||||||
pub fn set_by_index_token_input_types() -> Box<[TypeId]> {
|
pub fn set_by_index_token_input_types() -> Box<[TypeId]> {
|
||||||
set_by_index_token().input_types()
|
set_by_index_token().input_types()
|
||||||
}
|
}
|
||||||
@ -1802,16 +1951,19 @@ mod generate_tests {
|
|||||||
pub fn rhai_module_generate() -> Module {
|
pub fn rhai_module_generate() -> Module {
|
||||||
let mut m = Module::new();
|
let mut m = Module::new();
|
||||||
rhai_generate_into_module(&mut m, false);
|
rhai_generate_into_module(&mut m, false);
|
||||||
|
m.build_index();
|
||||||
m
|
m
|
||||||
}
|
}
|
||||||
#[allow(unused_mut)]
|
#[allow(unused_mut)]
|
||||||
pub fn rhai_generate_into_module(m: &mut Module, flatten: bool) {
|
pub fn rhai_generate_into_module(m: &mut Module, flatten: bool) {
|
||||||
m.set_fn("set", FnNamespace::Internal, FnAccess::Public,
|
m.set_fn("set", FnNamespace::Internal, FnAccess::Public,
|
||||||
|
Some(&["x: &mut MyCollection", "i: u64", "item: FLOAT"]),
|
||||||
&[core::any::TypeId::of::<MyCollection>(),
|
&[core::any::TypeId::of::<MyCollection>(),
|
||||||
core::any::TypeId::of::<u64>(),
|
core::any::TypeId::of::<u64>(),
|
||||||
core::any::TypeId::of::<FLOAT>()],
|
core::any::TypeId::of::<FLOAT>()],
|
||||||
set_by_index_token().into());
|
set_by_index_token().into());
|
||||||
m.set_fn("index$set$", FnNamespace::Internal, FnAccess::Public,
|
m.set_fn("index$set$", FnNamespace::Internal, FnAccess::Public,
|
||||||
|
Some(&["x: &mut MyCollection", "i: u64", "item: FLOAT"]),
|
||||||
&[core::any::TypeId::of::<MyCollection>(),
|
&[core::any::TypeId::of::<MyCollection>(),
|
||||||
core::any::TypeId::of::<u64>(),
|
core::any::TypeId::of::<u64>(),
|
||||||
core::any::TypeId::of::<FLOAT>()],
|
core::any::TypeId::of::<FLOAT>()],
|
||||||
@ -1835,6 +1987,9 @@ mod generate_tests {
|
|||||||
fn clone_boxed(&self) -> Box<dyn PluginFunction> {
|
fn clone_boxed(&self) -> Box<dyn PluginFunction> {
|
||||||
Box::new(set_by_index_token())
|
Box::new(set_by_index_token())
|
||||||
}
|
}
|
||||||
|
fn input_names(&self) -> Box<[&'static str]> {
|
||||||
|
new_vec!["x: &mut MyCollection", "i: u64", "item: FLOAT"].into_boxed_slice()
|
||||||
|
}
|
||||||
fn input_types(&self) -> Box<[TypeId]> {
|
fn input_types(&self) -> Box<[TypeId]> {
|
||||||
new_vec![TypeId::of::<MyCollection>(),
|
new_vec![TypeId::of::<MyCollection>(),
|
||||||
TypeId::of::<u64>(),
|
TypeId::of::<u64>(),
|
||||||
@ -1844,6 +1999,9 @@ mod generate_tests {
|
|||||||
pub fn set_by_index_token_callable() -> CallableFunction {
|
pub fn set_by_index_token_callable() -> CallableFunction {
|
||||||
set_by_index_token().into()
|
set_by_index_token().into()
|
||||||
}
|
}
|
||||||
|
pub fn set_by_index_token_input_names() -> Box<[&'static str]> {
|
||||||
|
set_by_index_token().input_names()
|
||||||
|
}
|
||||||
pub fn set_by_index_token_input_types() -> Box<[TypeId]> {
|
pub fn set_by_index_token_input_types() -> Box<[TypeId]> {
|
||||||
set_by_index_token().input_types()
|
set_by_index_token().input_types()
|
||||||
}
|
}
|
||||||
@ -1874,6 +2032,7 @@ mod generate_tests {
|
|||||||
pub fn rhai_module_generate() -> Module {
|
pub fn rhai_module_generate() -> Module {
|
||||||
let mut m = Module::new();
|
let mut m = Module::new();
|
||||||
rhai_generate_into_module(&mut m, false);
|
rhai_generate_into_module(&mut m, false);
|
||||||
|
m.build_index();
|
||||||
m
|
m
|
||||||
}
|
}
|
||||||
#[allow(unused_mut)]
|
#[allow(unused_mut)]
|
||||||
@ -1888,6 +2047,7 @@ mod generate_tests {
|
|||||||
pub fn rhai_module_generate() -> Module {
|
pub fn rhai_module_generate() -> Module {
|
||||||
let mut m = Module::new();
|
let mut m = Module::new();
|
||||||
rhai_generate_into_module(&mut m, false);
|
rhai_generate_into_module(&mut m, false);
|
||||||
|
m.build_index();
|
||||||
m
|
m
|
||||||
}
|
}
|
||||||
#[allow(unused_mut)]
|
#[allow(unused_mut)]
|
||||||
@ -1928,6 +2088,7 @@ mod generate_tests {
|
|||||||
pub fn rhai_module_generate() -> Module {
|
pub fn rhai_module_generate() -> Module {
|
||||||
let mut m = Module::new();
|
let mut m = Module::new();
|
||||||
rhai_generate_into_module(&mut m, false);
|
rhai_generate_into_module(&mut m, false);
|
||||||
|
m.build_index();
|
||||||
m
|
m
|
||||||
}
|
}
|
||||||
#[allow(unused_mut)]
|
#[allow(unused_mut)]
|
||||||
@ -1944,6 +2105,7 @@ mod generate_tests {
|
|||||||
pub fn rhai_module_generate() -> Module {
|
pub fn rhai_module_generate() -> Module {
|
||||||
let mut m = Module::new();
|
let mut m = Module::new();
|
||||||
rhai_generate_into_module(&mut m, false);
|
rhai_generate_into_module(&mut m, false);
|
||||||
|
m.build_index();
|
||||||
m
|
m
|
||||||
}
|
}
|
||||||
#[allow(unused_mut)]
|
#[allow(unused_mut)]
|
||||||
@ -1958,6 +2120,7 @@ mod generate_tests {
|
|||||||
pub fn rhai_module_generate() -> Module {
|
pub fn rhai_module_generate() -> Module {
|
||||||
let mut m = Module::new();
|
let mut m = Module::new();
|
||||||
rhai_generate_into_module(&mut m, false);
|
rhai_generate_into_module(&mut m, false);
|
||||||
|
m.build_index();
|
||||||
m
|
m
|
||||||
}
|
}
|
||||||
#[allow(unused_mut)]
|
#[allow(unused_mut)]
|
||||||
@ -2024,6 +2187,7 @@ mod generate_tests {
|
|||||||
pub fn rhai_module_generate() -> Module {
|
pub fn rhai_module_generate() -> Module {
|
||||||
let mut m = Module::new();
|
let mut m = Module::new();
|
||||||
rhai_generate_into_module(&mut m, false);
|
rhai_generate_into_module(&mut m, false);
|
||||||
|
m.build_index();
|
||||||
m
|
m
|
||||||
}
|
}
|
||||||
#[allow(unused_mut)]
|
#[allow(unused_mut)]
|
||||||
@ -2040,6 +2204,7 @@ mod generate_tests {
|
|||||||
pub fn rhai_module_generate() -> Module {
|
pub fn rhai_module_generate() -> Module {
|
||||||
let mut m = Module::new();
|
let mut m = Module::new();
|
||||||
rhai_generate_into_module(&mut m, false);
|
rhai_generate_into_module(&mut m, false);
|
||||||
|
m.build_index();
|
||||||
m
|
m
|
||||||
}
|
}
|
||||||
#[allow(unused_mut)]
|
#[allow(unused_mut)]
|
||||||
@ -2054,6 +2219,7 @@ mod generate_tests {
|
|||||||
pub fn rhai_module_generate() -> Module {
|
pub fn rhai_module_generate() -> Module {
|
||||||
let mut m = Module::new();
|
let mut m = Module::new();
|
||||||
rhai_generate_into_module(&mut m, false);
|
rhai_generate_into_module(&mut m, false);
|
||||||
|
m.build_index();
|
||||||
m
|
m
|
||||||
}
|
}
|
||||||
#[allow(unused_mut)]
|
#[allow(unused_mut)]
|
||||||
@ -2077,6 +2243,7 @@ mod generate_tests {
|
|||||||
pub fn rhai_module_generate() -> Module {
|
pub fn rhai_module_generate() -> Module {
|
||||||
let mut m = Module::new();
|
let mut m = Module::new();
|
||||||
rhai_generate_into_module(&mut m, false);
|
rhai_generate_into_module(&mut m, false);
|
||||||
|
m.build_index();
|
||||||
m
|
m
|
||||||
}
|
}
|
||||||
#[allow(unused_mut)]
|
#[allow(unused_mut)]
|
||||||
@ -2091,6 +2258,7 @@ mod generate_tests {
|
|||||||
pub fn rhai_module_generate() -> Module {
|
pub fn rhai_module_generate() -> Module {
|
||||||
let mut m = Module::new();
|
let mut m = Module::new();
|
||||||
rhai_generate_into_module(&mut m, false);
|
rhai_generate_into_module(&mut m, false);
|
||||||
|
m.build_index();
|
||||||
m
|
m
|
||||||
}
|
}
|
||||||
#[allow(unused_mut)]
|
#[allow(unused_mut)]
|
||||||
@ -2116,6 +2284,7 @@ mod generate_tests {
|
|||||||
pub fn rhai_module_generate() -> Module {
|
pub fn rhai_module_generate() -> Module {
|
||||||
let mut m = Module::new();
|
let mut m = Module::new();
|
||||||
rhai_generate_into_module(&mut m, false);
|
rhai_generate_into_module(&mut m, false);
|
||||||
|
m.build_index();
|
||||||
m
|
m
|
||||||
}
|
}
|
||||||
#[allow(unused_mut)]
|
#[allow(unused_mut)]
|
||||||
@ -2132,6 +2301,7 @@ mod generate_tests {
|
|||||||
pub fn rhai_module_generate() -> Module {
|
pub fn rhai_module_generate() -> Module {
|
||||||
let mut m = Module::new();
|
let mut m = Module::new();
|
||||||
rhai_generate_into_module(&mut m, false);
|
rhai_generate_into_module(&mut m, false);
|
||||||
|
m.build_index();
|
||||||
m
|
m
|
||||||
}
|
}
|
||||||
#[allow(unused_mut)]
|
#[allow(unused_mut)]
|
||||||
@ -2146,6 +2316,7 @@ mod generate_tests {
|
|||||||
pub fn rhai_module_generate() -> Module {
|
pub fn rhai_module_generate() -> Module {
|
||||||
let mut m = Module::new();
|
let mut m = Module::new();
|
||||||
rhai_generate_into_module(&mut m, false);
|
rhai_generate_into_module(&mut m, false);
|
||||||
|
m.build_index();
|
||||||
m
|
m
|
||||||
}
|
}
|
||||||
#[allow(unused_mut)]
|
#[allow(unused_mut)]
|
||||||
@ -2167,6 +2338,7 @@ mod generate_tests {
|
|||||||
pub fn rhai_module_generate() -> Module {
|
pub fn rhai_module_generate() -> Module {
|
||||||
let mut m = Module::new();
|
let mut m = Module::new();
|
||||||
rhai_generate_into_module(&mut m, false);
|
rhai_generate_into_module(&mut m, false);
|
||||||
|
m.build_index();
|
||||||
m
|
m
|
||||||
}
|
}
|
||||||
#[allow(unused_mut)]
|
#[allow(unused_mut)]
|
||||||
|
@ -97,7 +97,7 @@ The Rhai Scripting Language
|
|||||||
19. [Modules](language/modules/index.md)
|
19. [Modules](language/modules/index.md)
|
||||||
1. [Export Variables, Functions and Sub-Modules](language/modules/export.md)
|
1. [Export Variables, Functions and Sub-Modules](language/modules/export.md)
|
||||||
2. [Import Modules](language/modules/import.md)
|
2. [Import Modules](language/modules/import.md)
|
||||||
20. [Eval Statement](language/eval.md)
|
20. [Eval Function](language/eval.md)
|
||||||
6. [Safety and Protection](safety/index.md)
|
6. [Safety and Protection](safety/index.md)
|
||||||
1. [Checked Arithmetic](safety/checked.md)
|
1. [Checked Arithmetic](safety/checked.md)
|
||||||
2. [Sand-Boxing](safety/sandbox.md)
|
2. [Sand-Boxing](safety/sandbox.md)
|
||||||
|
@ -9,8 +9,6 @@ Keywords List
|
|||||||
| `false` | boolean false literal | | no | |
|
| `false` | boolean false literal | | no | |
|
||||||
| `let` | variable declaration | | no | |
|
| `let` | variable declaration | | no | |
|
||||||
| `const` | constant declaration | | no | |
|
| `const` | constant declaration | | no | |
|
||||||
| `is_def_var` | is a variable declared? | | yes | yes |
|
|
||||||
| `is_shared` | is a value shared? | [`no_closure`] | yes | no |
|
|
||||||
| `if` | if statement | | no | |
|
| `if` | if statement | | no | |
|
||||||
| `else` | else block of if statement | | no | |
|
| `else` | else block of if statement | | no | |
|
||||||
| `switch` | matching | | no | |
|
| `switch` | matching | | no | |
|
||||||
@ -35,7 +33,6 @@ Keywords List
|
|||||||
| `call` | call a [function pointer] | | yes | no |
|
| `call` | call a [function pointer] | | yes | no |
|
||||||
| `curry` | curry a [function pointer] | | yes | no |
|
| `curry` | curry a [function pointer] | | yes | no |
|
||||||
| `this` | reference to base object for method call | [`no_function`] | no | |
|
| `this` | reference to base object for method call | [`no_function`] | no | |
|
||||||
| `is_def_fn` | is a scripted function defined? | [`no_function`] | yes | yes |
|
|
||||||
| `type_of` | get type name of value | | yes | yes |
|
| `type_of` | get type name of value | | yes | yes |
|
||||||
| `print` | print value | | yes | yes |
|
| `print` | print value | | yes | yes |
|
||||||
| `debug` | print value in debug format | | yes | yes |
|
| `debug` | print value in debug format | | yes | yes |
|
||||||
@ -49,6 +46,8 @@ Reserved Keywords
|
|||||||
| --------- | --------------------- |
|
| --------- | --------------------- |
|
||||||
| `var` | variable declaration |
|
| `var` | variable declaration |
|
||||||
| `static` | variable declaration |
|
| `static` | variable declaration |
|
||||||
|
| `begin` | block scope |
|
||||||
|
| `end` | block scope |
|
||||||
| `shared` | share value |
|
| `shared` | share value |
|
||||||
| `each` | looping |
|
| `each` | looping |
|
||||||
| `then` | control flow |
|
| `then` | control flow |
|
||||||
|
@ -34,23 +34,28 @@ It is very useful to have a constant value hold a [custom type], which essential
|
|||||||
as a [_singleton_](../patterns/singleton.md).
|
as a [_singleton_](../patterns/singleton.md).
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
use rhai::{Engine, Scope};
|
use rhai::{Engine, Scope, RegisterFn};
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
struct TestStruct(i64); // custom type
|
struct TestStruct(i64); // custom type
|
||||||
|
|
||||||
let engine = Engine::new()
|
let mut engine = Engine::new();
|
||||||
|
|
||||||
|
engine
|
||||||
.register_type_with_name::<TestStruct>("TestStruct") // register custom type
|
.register_type_with_name::<TestStruct>("TestStruct") // register custom type
|
||||||
.register_get_set("value",
|
.register_get("value", |obj: &mut TestStruct| obj.0), // property getter
|
||||||
|obj: &mut TestStruct| obj.0, // property getter
|
.register_fn("update_value",
|
||||||
|obj: &mut TestStruct, value: i64| obj.0 = value // property setter
|
|obj: &mut TestStruct, value: i64| obj.0 = value // mutating method
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut scope = Scope::new(); // create custom scope
|
let mut scope = Scope::new(); // create custom scope
|
||||||
|
|
||||||
scope.push_constant("MY_NUMBER", TestStruct(123_i64)); // add constant variable
|
scope.push_constant("MY_NUMBER", TestStruct(123_i64)); // add constant variable
|
||||||
|
|
||||||
engine.consume_with_scope(&mut scope, r"
|
// Beware: constant objects can still be modified via a method call!
|
||||||
MY_NUMBER.value = 42; // constant objects can be modified
|
engine.consume_with_scope(&mut scope,
|
||||||
|
r"
|
||||||
|
MY_NUMBER.update_value(42);
|
||||||
print(MY_NUMBER.value); // prints 42
|
print(MY_NUMBER.value); // prints 42
|
||||||
")?;
|
")?;
|
||||||
```
|
```
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
`eval` Statement
|
`eval` Function
|
||||||
===============
|
===============
|
||||||
|
|
||||||
{{#include ../links.md}}
|
{{#include ../links.md}}
|
||||||
@ -60,7 +60,13 @@ print(x);
|
|||||||
--------------
|
--------------
|
||||||
|
|
||||||
For those who subscribe to the (very sensible) motto of ["`eval` is evil"](http://linterrors.com/js/eval-is-evil),
|
For those who subscribe to the (very sensible) motto of ["`eval` is evil"](http://linterrors.com/js/eval-is-evil),
|
||||||
disable `eval` by overloading it, probably with something that throws.
|
disable `eval` using [`Engine::disable_symbol`][disable keywords and operators]:
|
||||||
|
|
||||||
|
```rust
|
||||||
|
engine.disable_symbol("eval"); // disable usage of 'eval'
|
||||||
|
```
|
||||||
|
|
||||||
|
`eval` can also be disabled by overloading it, probably with something that throws:
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
fn eval(script) { throw "eval is evil! I refuse to run " + script }
|
fn eval(script) { throw "eval is evil! I refuse to run " + script }
|
||||||
@ -75,20 +81,3 @@ engine.register_result_fn("eval", |script: String| -> Result<(), Box<EvalAltResu
|
|||||||
Err(format!("eval is evil! I refuse to run {}", script).into())
|
Err(format!("eval is evil! I refuse to run {}", script).into())
|
||||||
});
|
});
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
`EvalPackage`
|
|
||||||
-------------
|
|
||||||
|
|
||||||
There is even a package named [`EvalPackage`][packages] which implements the disabling override:
|
|
||||||
|
|
||||||
```rust
|
|
||||||
use rhai::Engine;
|
|
||||||
use rhai::packages::Package // load the 'Package' trait to use packages
|
|
||||||
use rhai::packages::EvalPackage; // the 'eval' package disables 'eval'
|
|
||||||
|
|
||||||
let mut engine = Engine::new();
|
|
||||||
let package = EvalPackage::new(); // create the package
|
|
||||||
|
|
||||||
engine.load_package(package.get()); // load the package
|
|
||||||
```
|
|
||||||
|
@ -104,7 +104,7 @@ This is similar to Rust and many other modern languages, such as JavaScript's `f
|
|||||||
`is_def_fn`
|
`is_def_fn`
|
||||||
-----------
|
-----------
|
||||||
|
|
||||||
Use `is_def_fn` to detect if a function is defined (and therefore callable), based on its name
|
Use `is_def_fn` to detect if a Rhai function is defined (and therefore callable), based on its name
|
||||||
and the number of parameters.
|
and the number of parameters.
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
|
@ -5,21 +5,22 @@ Keywords
|
|||||||
|
|
||||||
The following are reserved keywords in Rhai:
|
The following are reserved keywords in Rhai:
|
||||||
|
|
||||||
| Active keywords | Reserved keywords | Usage | Inactive under feature |
|
| Active keywords | Reserved keywords | Usage | Inactive under feature |
|
||||||
| ------------------------------------------------- | ---------------------------------------------------------- | ---------------------- | :--------------------: |
|
| ---------------------------------------------------------------- | ---------------------------------------------------------- | ---------------------- | :--------------------: |
|
||||||
| `true`, `false` | | boolean constants | |
|
| `true`, `false` | | constants | |
|
||||||
| `let`, `const` | `var`, `static` | variable declarations | |
|
| `let`, `const` | `var`, `static` | variables | |
|
||||||
| `is_shared` | | shared values | [`no_closure`] |
|
| | `begin`, `end` | block scopes | |
|
||||||
| `if`, `else` | `then`, `goto`, `exit` | control flow | |
|
| `is_shared` | | shared values | [`no_closure`] |
|
||||||
| | `switch`, `match`, `case` | matching | |
|
| `if`, `else` | `then`, `unless`, `goto`, `exit` | control flow | |
|
||||||
| `while`, `loop`, `for`, `in`, `continue`, `break` | `do`, `each` | looping | |
|
| `switch` | `match`, `case` | switching and matching | |
|
||||||
| `fn`, `private` | `public`, `new` | functions | [`no_function`] |
|
| `do`, `while`, `loop`, `until`, `for`, `in`, `continue`, `break` | `each` | looping | |
|
||||||
| `return` | | return values | |
|
| `fn`, `private` | `public`, `new` | functions | [`no_function`] |
|
||||||
| `throw`, `try`, `catch` | | throw/catch exceptions | |
|
| `return` | | return values | |
|
||||||
| `import`, `export`, `as` | `use`, `with`, `module`, `package` | modules/packages | [`no_module`] |
|
| `throw`, `try`, `catch` | | throw/catch exceptions | |
|
||||||
| `Fn`, `call`, `curry` | | function pointers | |
|
| `import`, `export`, `as` | `use`, `with`, `module`, `package` | modules/packages | [`no_module`] |
|
||||||
| | `spawn`, `thread`, `go`, `sync`, `async`, `await`, `yield` | threading/async | |
|
| `Fn`, `call`, `curry` | | function pointers | |
|
||||||
| `type_of`, `print`, `debug`, `eval` | | special functions | |
|
| | `spawn`, `thread`, `go`, `sync`, `async`, `await`, `yield` | threading/async | |
|
||||||
| | `default`, `void`, `null`, `nil` | special values | |
|
| `type_of`, `print`, `debug`, `eval` | | special functions | |
|
||||||
|
| | `default`, `void`, `null`, `nil` | special values | |
|
||||||
|
|
||||||
Keywords cannot become the name of a [function] or [variable], even when they are disabled.
|
Keywords cannot become the name of a [function] or [variable], even when they are disabled.
|
||||||
|
@ -9,7 +9,7 @@ Terminated by '`;`'
|
|||||||
Statements are terminated by semicolons '`;`' and they are mandatory,
|
Statements are terminated by semicolons '`;`' and they are mandatory,
|
||||||
except for the _last_ statement in a _block_ (enclosed by '`{`' .. '`}`' pairs) where it can be omitted.
|
except for the _last_ statement in a _block_ (enclosed by '`{`' .. '`}`' pairs) where it can be omitted.
|
||||||
|
|
||||||
Semicolons can also be omitted if the statement contains a block itself
|
Semicolons can also be omitted if the statement ends with a block itself
|
||||||
(e.g. the `if`, `while`, `for` and `loop` statements).
|
(e.g. the `if`, `while`, `for` and `loop` statements).
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
@ -35,6 +35,8 @@ Statement Expression
|
|||||||
A statement can be used anywhere where an expression is expected. These are called, for lack of a more
|
A statement can be used anywhere where an expression is expected. These are called, for lack of a more
|
||||||
creative name, "statement expressions."
|
creative name, "statement expressions."
|
||||||
|
|
||||||
The _last_ statement of a statement block is _always_ the block's return value when used as a statement.
|
The _last_ statement of a statement block is _always_ the block's return value when used as a statement,
|
||||||
|
_regardless_ of whether it is terminated by a semicolon or not. This is different from Rust where,
|
||||||
|
if the last statement is terminated by a semicolon, the block's return value is taken to be `()`.
|
||||||
|
|
||||||
If the last statement has no return value (e.g. variable definitions, assignments) then it is assumed to be [`()`].
|
If the last statement has no return value (e.g. variable definitions, assignments) then it is assumed to be [`()`].
|
||||||
|
@ -50,7 +50,7 @@ impl ModuleResolver for MyModuleResolver {
|
|||||||
// Return EvalAltResult::ErrorInModule upon loading error
|
// Return EvalAltResult::ErrorInModule upon loading error
|
||||||
EvalAltResult::ErrorInModule(path.into(), Box::new(err), pos).into()
|
EvalAltResult::ErrorInModule(path.into(), Box::new(err), pos).into()
|
||||||
)?;
|
)?;
|
||||||
my_module.build_index(); // index it
|
my_module.build_index(); // index it
|
||||||
Rc::new(my_module) // make it shared
|
Rc::new(my_module) // make it shared
|
||||||
} else {
|
} else {
|
||||||
// Return EvalAltResult::ErrorModuleNotFound if the path is invalid
|
// Return EvalAltResult::ErrorModuleNotFound if the path is invalid
|
||||||
|
@ -19,7 +19,6 @@ Built-In Packages
|
|||||||
| `BasicArrayPackage` | basic [array] functions (not available under `no_index`) | no | yes |
|
| `BasicArrayPackage` | basic [array] functions (not available under `no_index`) | no | yes |
|
||||||
| `BasicMapPackage` | basic [object map] functions (not available under `no_object`) | no | yes |
|
| `BasicMapPackage` | basic [object map] functions (not available under `no_object`) | no | yes |
|
||||||
| `BasicFnPackage` | basic methods for [function pointers]. | yes | yes |
|
| `BasicFnPackage` | basic methods for [function pointers]. | yes | yes |
|
||||||
| `EvalPackage` | disable [`eval`] | no | no |
|
|
||||||
| `CorePackage` | basic essentials | yes | yes |
|
| `CorePackage` | basic essentials | yes | yes |
|
||||||
| `StandardPackage` | standard library (default for `Engine::new`) | no | yes |
|
| `StandardPackage` | standard library (default for `Engine::new`) | no | yes |
|
||||||
|
|
||||||
|
@ -42,6 +42,7 @@ fn print_help() {
|
|||||||
println!("help => print this help");
|
println!("help => print this help");
|
||||||
println!("quit, exit => quit");
|
println!("quit, exit => quit");
|
||||||
println!("scope => print all variables in the scope");
|
println!("scope => print all variables in the scope");
|
||||||
|
println!("functions => print all functions defined");
|
||||||
println!("ast => print the last AST");
|
println!("ast => print the last AST");
|
||||||
println!("astu => print the last raw, un-optimized AST");
|
println!("astu => print the last raw, un-optimized AST");
|
||||||
println!(r"end a line with '\' to continue to the next line.");
|
println!(r"end a line with '\' to continue to the next line.");
|
||||||
@ -133,6 +134,21 @@ fn main() {
|
|||||||
println!("{:#?}\n", &ast);
|
println!("{:#?}\n", &ast);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
"functions" => {
|
||||||
|
// print a list of all registered functions
|
||||||
|
engine
|
||||||
|
.gen_fn_signatures(false)
|
||||||
|
.into_iter()
|
||||||
|
.for_each(|f| println!("{}", f));
|
||||||
|
|
||||||
|
#[cfg(not(feature = "no_function"))]
|
||||||
|
main_ast
|
||||||
|
.iter_functions()
|
||||||
|
.for_each(|(_, _, _, _, f)| println!("{}", f));
|
||||||
|
|
||||||
|
println!();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -100,7 +100,7 @@ impl fmt::Display for ScriptFnDef {
|
|||||||
.iter()
|
.iter()
|
||||||
.map(|s| s.as_str())
|
.map(|s| s.as_str())
|
||||||
.collect::<Vec<_>>()
|
.collect::<Vec<_>>()
|
||||||
.join(",")
|
.join(", ")
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1154,8 +1154,8 @@ mod tests {
|
|||||||
assert_eq!(size_of::<crate::ast::Stmt>(), 32);
|
assert_eq!(size_of::<crate::ast::Stmt>(), 32);
|
||||||
assert_eq!(size_of::<Option<crate::ast::Stmt>>(), 32);
|
assert_eq!(size_of::<Option<crate::ast::Stmt>>(), 32);
|
||||||
assert_eq!(size_of::<crate::Scope>(), 72);
|
assert_eq!(size_of::<crate::Scope>(), 72);
|
||||||
assert_eq!(size_of::<crate::LexError>(), 32);
|
assert_eq!(size_of::<crate::LexError>(), 56);
|
||||||
assert_eq!(size_of::<crate::ParseError>(), 16);
|
assert_eq!(size_of::<crate::ParseError>(), 16);
|
||||||
assert_eq!(size_of::<crate::EvalAltResult>(), 64);
|
assert_eq!(size_of::<crate::EvalAltResult>(), 72);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -95,24 +95,25 @@ impl Imports {
|
|||||||
self.0.as_mut().unwrap().truncate(size);
|
self.0.as_mut().unwrap().truncate(size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/// Get an iterator to this stack of imported modules.
|
/// Get an iterator to this stack of imported modules in reverse order.
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub fn iter(&self) -> impl Iterator<Item = (&str, Shared<Module>)> {
|
pub fn iter(&self) -> impl Iterator<Item = (&str, Shared<Module>)> {
|
||||||
self.0.iter().flat_map(|lib| {
|
self.0.iter().flat_map(|lib| {
|
||||||
lib.iter()
|
lib.iter()
|
||||||
|
.rev()
|
||||||
.map(|(name, module)| (name.as_str(), module.clone()))
|
.map(|(name, module)| (name.as_str(), module.clone()))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
/// Get an iterator to this stack of imported modules.
|
/// Get an iterator to this stack of imported modules in reverse order.
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub(crate) fn iter_raw<'a>(
|
pub(crate) fn iter_raw<'a>(
|
||||||
&'a self,
|
&'a self,
|
||||||
) -> impl Iterator<Item = (ImmutableString, Shared<Module>)> + 'a {
|
) -> impl Iterator<Item = (ImmutableString, Shared<Module>)> + 'a {
|
||||||
self.0.iter().flat_map(|lib| lib.iter().cloned())
|
self.0.iter().flat_map(|lib| lib.iter().rev().cloned())
|
||||||
}
|
}
|
||||||
/// Get a consuming iterator to this stack of imported modules.
|
/// Get a consuming iterator to this stack of imported modules in reverse order.
|
||||||
pub fn into_iter(self) -> impl Iterator<Item = (ImmutableString, Shared<Module>)> {
|
pub fn into_iter(self) -> impl Iterator<Item = (ImmutableString, Shared<Module>)> {
|
||||||
self.0.into_iter().flat_map(|lib| lib.into_iter())
|
self.0.into_iter().flat_map(|lib| lib.into_iter().rev())
|
||||||
}
|
}
|
||||||
/// Add a stream of imported modules.
|
/// Add a stream of imported modules.
|
||||||
pub fn extend(&mut self, stream: impl Iterator<Item = (ImmutableString, Shared<Module>)>) {
|
pub fn extend(&mut self, stream: impl Iterator<Item = (ImmutableString, Shared<Module>)>) {
|
||||||
@ -178,9 +179,7 @@ pub const KEYWORD_FN_PTR_CURRY: &str = "curry";
|
|||||||
#[cfg(not(feature = "no_closure"))]
|
#[cfg(not(feature = "no_closure"))]
|
||||||
pub const KEYWORD_IS_SHARED: &str = "is_shared";
|
pub const KEYWORD_IS_SHARED: &str = "is_shared";
|
||||||
pub const KEYWORD_IS_DEF_VAR: &str = "is_def_var";
|
pub const KEYWORD_IS_DEF_VAR: &str = "is_def_var";
|
||||||
pub const KEYWORD_IS_DEF_FN: &str = "is_def_fn";
|
|
||||||
pub const KEYWORD_THIS: &str = "this";
|
pub const KEYWORD_THIS: &str = "this";
|
||||||
pub const FN_TO_STRING: &str = "to_string";
|
|
||||||
#[cfg(not(feature = "no_object"))]
|
#[cfg(not(feature = "no_object"))]
|
||||||
pub const FN_GET: &str = "get$";
|
pub const FN_GET: &str = "get$";
|
||||||
#[cfg(not(feature = "no_object"))]
|
#[cfg(not(feature = "no_object"))]
|
||||||
|
@ -7,8 +7,10 @@ use crate::optimize::OptimizationLevel;
|
|||||||
use crate::stdlib::{
|
use crate::stdlib::{
|
||||||
any::{type_name, TypeId},
|
any::{type_name, TypeId},
|
||||||
boxed::Box,
|
boxed::Box,
|
||||||
|
format,
|
||||||
hash::{Hash, Hasher},
|
hash::{Hash, Hasher},
|
||||||
string::String,
|
string::String,
|
||||||
|
vec::Vec,
|
||||||
};
|
};
|
||||||
use crate::utils::get_hasher;
|
use crate::utils::get_hasher;
|
||||||
use crate::{
|
use crate::{
|
||||||
@ -1515,7 +1517,7 @@ impl Engine {
|
|||||||
.into()
|
.into()
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
/// Call a script function defined in an [`AST`] with multiple `Dynamic` arguments
|
/// Call a script function defined in an [`AST`] with multiple [`Dynamic`] arguments
|
||||||
/// and optionally a value for binding to the `this` pointer.
|
/// and optionally a value for binding to the `this` pointer.
|
||||||
///
|
///
|
||||||
/// ## WARNING
|
/// ## WARNING
|
||||||
@ -1578,7 +1580,7 @@ impl Engine {
|
|||||||
|
|
||||||
self.call_fn_dynamic_raw(scope, &[lib.as_ref()], name, &mut this_ptr, args.as_mut())
|
self.call_fn_dynamic_raw(scope, &[lib.as_ref()], name, &mut this_ptr, args.as_mut())
|
||||||
}
|
}
|
||||||
/// Call a script function defined in an [`AST`] with multiple `Dynamic` arguments.
|
/// Call a script function defined in an [`AST`] with multiple [`Dynamic`] arguments.
|
||||||
///
|
///
|
||||||
/// ## WARNING
|
/// ## WARNING
|
||||||
///
|
///
|
||||||
@ -1646,6 +1648,27 @@ impl Engine {
|
|||||||
let stmt = crate::stdlib::mem::take(ast.statements_mut());
|
let stmt = crate::stdlib::mem::take(ast.statements_mut());
|
||||||
crate::optimize::optimize_into_ast(self, scope, stmt, lib, optimization_level)
|
crate::optimize::optimize_into_ast(self, scope, stmt, lib, optimization_level)
|
||||||
}
|
}
|
||||||
|
/// Generate a list of all registered functions.
|
||||||
|
///
|
||||||
|
/// The ordering is:
|
||||||
|
/// 1) Functions registered into the global namespace
|
||||||
|
/// 2) Functions in registered sub-modules
|
||||||
|
/// 3) Functions in packages
|
||||||
|
pub fn gen_fn_signatures(&self, include_packages: bool) -> Vec<String> {
|
||||||
|
let mut signatures: Vec<_> = Default::default();
|
||||||
|
|
||||||
|
signatures.extend(self.global_namespace.gen_fn_signatures());
|
||||||
|
|
||||||
|
self.global_sub_modules.iter().for_each(|(name, m)| {
|
||||||
|
signatures.extend(m.gen_fn_signatures().map(|f| format!("{}::{}", name, f)))
|
||||||
|
});
|
||||||
|
|
||||||
|
if include_packages {
|
||||||
|
signatures.extend(self.packages.gen_fn_signatures());
|
||||||
|
}
|
||||||
|
|
||||||
|
signatures
|
||||||
|
}
|
||||||
/// Provide a callback that will be invoked before each variable access.
|
/// Provide a callback that will be invoked before each variable access.
|
||||||
///
|
///
|
||||||
/// ## Return Value of Callback
|
/// ## Return Value of Callback
|
||||||
|
@ -3,8 +3,7 @@
|
|||||||
use crate::ast::{Expr, Stmt};
|
use crate::ast::{Expr, Stmt};
|
||||||
use crate::engine::{
|
use crate::engine::{
|
||||||
search_imports, Imports, State, KEYWORD_DEBUG, KEYWORD_EVAL, KEYWORD_FN_PTR,
|
search_imports, Imports, State, KEYWORD_DEBUG, KEYWORD_EVAL, KEYWORD_FN_PTR,
|
||||||
KEYWORD_FN_PTR_CALL, KEYWORD_FN_PTR_CURRY, KEYWORD_IS_DEF_FN, KEYWORD_IS_DEF_VAR,
|
KEYWORD_FN_PTR_CALL, KEYWORD_FN_PTR_CURRY, KEYWORD_IS_DEF_VAR, KEYWORD_PRINT, KEYWORD_TYPE_OF,
|
||||||
KEYWORD_PRINT, KEYWORD_TYPE_OF,
|
|
||||||
};
|
};
|
||||||
use crate::fn_native::FnCallArgs;
|
use crate::fn_native::FnCallArgs;
|
||||||
use crate::module::NamespaceRef;
|
use crate::module::NamespaceRef;
|
||||||
@ -419,7 +418,7 @@ impl Engine {
|
|||||||
#[inline]
|
#[inline]
|
||||||
pub(crate) fn has_override_by_name_and_arguments(
|
pub(crate) fn has_override_by_name_and_arguments(
|
||||||
&self,
|
&self,
|
||||||
mods: &Imports,
|
mods: Option<&Imports>,
|
||||||
lib: &[&Module],
|
lib: &[&Module],
|
||||||
fn_name: &str,
|
fn_name: &str,
|
||||||
arg_types: impl AsRef<[TypeId]>,
|
arg_types: impl AsRef<[TypeId]>,
|
||||||
@ -436,7 +435,7 @@ impl Engine {
|
|||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub(crate) fn has_override(
|
pub(crate) fn has_override(
|
||||||
&self,
|
&self,
|
||||||
mods: &Imports,
|
mods: Option<&Imports>,
|
||||||
lib: &[&Module],
|
lib: &[&Module],
|
||||||
hash_fn: u64,
|
hash_fn: u64,
|
||||||
hash_script: u64,
|
hash_script: u64,
|
||||||
@ -454,8 +453,7 @@ impl Engine {
|
|||||||
|| self.packages.contains_fn(hash_script)
|
|| self.packages.contains_fn(hash_script)
|
||||||
|| self.packages.contains_fn(hash_fn)
|
|| self.packages.contains_fn(hash_fn)
|
||||||
// Then check imported modules
|
// Then check imported modules
|
||||||
|| mods.contains_fn(hash_script)
|
|| mods.map(|m| m.contains_fn(hash_script) || m.contains_fn(hash_fn)).unwrap_or(false)
|
||||||
|| mods.contains_fn(hash_fn)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Perform an actual function call, native Rust or scripted, taking care of special functions.
|
/// Perform an actual function call, native Rust or scripted, taking care of special functions.
|
||||||
@ -494,7 +492,7 @@ impl Engine {
|
|||||||
// type_of
|
// type_of
|
||||||
KEYWORD_TYPE_OF
|
KEYWORD_TYPE_OF
|
||||||
if args.len() == 1
|
if args.len() == 1
|
||||||
&& !self.has_override(mods, lib, hash_fn, hash_script, pub_only) =>
|
&& !self.has_override(Some(mods), lib, hash_fn, hash_script, pub_only) =>
|
||||||
{
|
{
|
||||||
Ok((
|
Ok((
|
||||||
self.map_type_name(args[0].type_name()).to_string().into(),
|
self.map_type_name(args[0].type_name()).to_string().into(),
|
||||||
@ -506,7 +504,7 @@ impl Engine {
|
|||||||
// by a function pointer so it isn't caught at parse time.
|
// by a function pointer so it isn't caught at parse time.
|
||||||
KEYWORD_FN_PTR | KEYWORD_EVAL
|
KEYWORD_FN_PTR | KEYWORD_EVAL
|
||||||
if args.len() == 1
|
if args.len() == 1
|
||||||
&& !self.has_override(mods, lib, hash_fn, hash_script, pub_only) =>
|
&& !self.has_override(Some(mods), lib, hash_fn, hash_script, pub_only) =>
|
||||||
{
|
{
|
||||||
EvalAltResult::ErrorRuntime(
|
EvalAltResult::ErrorRuntime(
|
||||||
format!(
|
format!(
|
||||||
@ -521,7 +519,7 @@ impl Engine {
|
|||||||
|
|
||||||
// Script-like function found
|
// Script-like function found
|
||||||
#[cfg(not(feature = "no_function"))]
|
#[cfg(not(feature = "no_function"))]
|
||||||
_ if self.has_override(mods, lib, 0, hash_script, pub_only) => {
|
_ if self.has_override(Some(mods), lib, 0, hash_script, pub_only) => {
|
||||||
// Get function
|
// Get function
|
||||||
let func = lib
|
let func = lib
|
||||||
.iter()
|
.iter()
|
||||||
@ -856,7 +854,7 @@ impl Engine {
|
|||||||
let hash_fn =
|
let hash_fn =
|
||||||
calc_native_fn_hash(empty(), fn_name, once(TypeId::of::<ImmutableString>()));
|
calc_native_fn_hash(empty(), fn_name, once(TypeId::of::<ImmutableString>()));
|
||||||
|
|
||||||
if !self.has_override(mods, lib, hash_fn, hash_script, pub_only) {
|
if !self.has_override(Some(mods), lib, hash_fn, hash_script, pub_only) {
|
||||||
// Fn - only in function call style
|
// Fn - only in function call style
|
||||||
return self
|
return self
|
||||||
.eval_expr(scope, mods, state, lib, this_ptr, &args_expr[0], level)?
|
.eval_expr(scope, mods, state, lib, this_ptr, &args_expr[0], level)?
|
||||||
@ -912,7 +910,7 @@ impl Engine {
|
|||||||
|
|
||||||
if name == KEYWORD_FN_PTR_CALL
|
if name == KEYWORD_FN_PTR_CALL
|
||||||
&& args_expr.len() >= 1
|
&& args_expr.len() >= 1
|
||||||
&& !self.has_override(mods, lib, 0, hash_script, pub_only)
|
&& !self.has_override(Some(mods), lib, 0, hash_script, pub_only)
|
||||||
{
|
{
|
||||||
let fn_ptr = self.eval_expr(scope, mods, state, lib, this_ptr, &args_expr[0], level)?;
|
let fn_ptr = self.eval_expr(scope, mods, state, lib, this_ptr, &args_expr[0], level)?;
|
||||||
|
|
||||||
@ -942,7 +940,7 @@ impl Engine {
|
|||||||
if name == KEYWORD_IS_DEF_VAR && args_expr.len() == 1 {
|
if name == KEYWORD_IS_DEF_VAR && args_expr.len() == 1 {
|
||||||
let hash_fn = calc_native_fn_hash(empty(), name, once(TypeId::of::<ImmutableString>()));
|
let hash_fn = calc_native_fn_hash(empty(), name, once(TypeId::of::<ImmutableString>()));
|
||||||
|
|
||||||
if !self.has_override(mods, lib, hash_fn, hash_script, pub_only) {
|
if !self.has_override(Some(mods), lib, hash_fn, hash_script, pub_only) {
|
||||||
let var_name =
|
let var_name =
|
||||||
self.eval_expr(scope, mods, state, lib, this_ptr, &args_expr[0], level)?;
|
self.eval_expr(scope, mods, state, lib, this_ptr, &args_expr[0], level)?;
|
||||||
let var_name = var_name.as_str().map_err(|err| {
|
let var_name = var_name.as_str().map_err(|err| {
|
||||||
@ -952,44 +950,11 @@ impl Engine {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle is_def_fn()
|
|
||||||
if name == KEYWORD_IS_DEF_FN && args_expr.len() == 2 {
|
|
||||||
let hash_fn = calc_native_fn_hash(
|
|
||||||
empty(),
|
|
||||||
name,
|
|
||||||
[TypeId::of::<ImmutableString>(), TypeId::of::<INT>()]
|
|
||||||
.iter()
|
|
||||||
.cloned(),
|
|
||||||
);
|
|
||||||
|
|
||||||
if !self.has_override(mods, lib, hash_fn, hash_script, pub_only) {
|
|
||||||
let fn_name =
|
|
||||||
self.eval_expr(scope, mods, state, lib, this_ptr, &args_expr[0], level)?;
|
|
||||||
let num_params =
|
|
||||||
self.eval_expr(scope, mods, state, lib, this_ptr, &args_expr[1], level)?;
|
|
||||||
|
|
||||||
let fn_name = fn_name.as_str().map_err(|err| {
|
|
||||||
self.make_type_mismatch_err::<ImmutableString>(err, args_expr[0].position())
|
|
||||||
})?;
|
|
||||||
let num_params = num_params.as_int().map_err(|err| {
|
|
||||||
self.make_type_mismatch_err::<INT>(err, args_expr[1].position())
|
|
||||||
})?;
|
|
||||||
|
|
||||||
return Ok(if num_params < 0 {
|
|
||||||
false
|
|
||||||
} else {
|
|
||||||
let hash = calc_script_fn_hash(empty(), fn_name, num_params as usize);
|
|
||||||
lib.iter().any(|&m| m.contains_fn(hash, false))
|
|
||||||
}
|
|
||||||
.into());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handle eval()
|
// Handle eval()
|
||||||
if name == KEYWORD_EVAL && args_expr.len() == 1 {
|
if name == KEYWORD_EVAL && args_expr.len() == 1 {
|
||||||
let hash_fn = calc_native_fn_hash(empty(), name, once(TypeId::of::<ImmutableString>()));
|
let hash_fn = calc_native_fn_hash(empty(), name, once(TypeId::of::<ImmutableString>()));
|
||||||
|
|
||||||
if !self.has_override(mods, lib, hash_fn, hash_script, pub_only) {
|
if !self.has_override(Some(mods), lib, hash_fn, hash_script, pub_only) {
|
||||||
// eval - only in function call style
|
// eval - only in function call style
|
||||||
let prev_len = scope.len();
|
let prev_len = scope.len();
|
||||||
let script =
|
let script =
|
||||||
|
@ -49,8 +49,8 @@ pub type Locked<T> = crate::stdlib::sync::RwLock<T>;
|
|||||||
#[derive(Debug, Copy, Clone)]
|
#[derive(Debug, Copy, Clone)]
|
||||||
pub struct NativeCallContext<'e, 'a, 'm, 'pm: 'm> {
|
pub struct NativeCallContext<'e, 'a, 'm, 'pm: 'm> {
|
||||||
engine: &'e Engine,
|
engine: &'e Engine,
|
||||||
mods: Option<&'a Imports>,
|
pub(crate) mods: Option<&'a Imports>,
|
||||||
lib: &'m [&'pm Module],
|
pub(crate) lib: &'m [&'pm Module],
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'e, 'a, 'm, 'pm: 'm, M: AsRef<[&'pm Module]> + ?Sized> From<(&'e Engine, &'a Imports, &'m M)>
|
impl<'e, 'a, 'm, 'pm: 'm, M: AsRef<[&'pm Module]> + ?Sized> From<(&'e Engine, &'a Imports, &'m M)>
|
||||||
|
@ -187,7 +187,7 @@ macro_rules! def_register {
|
|||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn register_fn(&mut self, name: &str, f: FN) -> &mut Self {
|
fn register_fn(&mut self, name: &str, f: FN) -> &mut Self {
|
||||||
self.global_namespace.set_fn(name, FnNamespace::Global, FnAccess::Public,
|
self.global_namespace.set_fn(name, FnNamespace::Global, FnAccess::Public, None,
|
||||||
&[$(map_type_id::<$par>()),*],
|
&[$(map_type_id::<$par>()),*],
|
||||||
CallableFunction::$abi(make_func!(f : map_dynamic ; $($par => $let => $clone => $arg),*))
|
CallableFunction::$abi(make_func!(f : map_dynamic ; $($par => $let => $clone => $arg),*))
|
||||||
);
|
);
|
||||||
@ -202,7 +202,7 @@ macro_rules! def_register {
|
|||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn register_result_fn(&mut self, name: &str, f: FN) -> &mut Self {
|
fn register_result_fn(&mut self, name: &str, f: FN) -> &mut Self {
|
||||||
self.global_namespace.set_fn(name, FnNamespace::Global, FnAccess::Public,
|
self.global_namespace.set_fn(name, FnNamespace::Global, FnAccess::Public, None,
|
||||||
&[$(map_type_id::<$par>()),*],
|
&[$(map_type_id::<$par>()),*],
|
||||||
CallableFunction::$abi(make_func!(f : map_result ; $($par => $let => $clone => $arg),*))
|
CallableFunction::$abi(make_func!(f : map_result ; $($par => $let => $clone => $arg),*))
|
||||||
);
|
);
|
||||||
|
@ -2,9 +2,7 @@
|
|||||||
|
|
||||||
use crate::ast::{FnAccess, IdentX};
|
use crate::ast::{FnAccess, IdentX};
|
||||||
use crate::dynamic::Variant;
|
use crate::dynamic::Variant;
|
||||||
use crate::fn_native::{
|
use crate::fn_native::{shared_take_or_clone, CallableFunction, FnCallArgs, IteratorFn, SendSync};
|
||||||
shared_make_mut, shared_take_or_clone, CallableFunction, FnCallArgs, IteratorFn, SendSync,
|
|
||||||
};
|
|
||||||
use crate::fn_register::by_value as cast_arg;
|
use crate::fn_register::by_value as cast_arg;
|
||||||
use crate::stdlib::{
|
use crate::stdlib::{
|
||||||
any::TypeId,
|
any::TypeId,
|
||||||
@ -81,7 +79,31 @@ pub struct FuncInfo {
|
|||||||
/// Number of parameters.
|
/// Number of parameters.
|
||||||
pub params: usize,
|
pub params: usize,
|
||||||
/// Parameter types (if applicable).
|
/// Parameter types (if applicable).
|
||||||
pub types: Option<StaticVec<TypeId>>,
|
pub param_types: Option<StaticVec<TypeId>>,
|
||||||
|
/// Parameter names (if available).
|
||||||
|
pub param_names: Option<StaticVec<ImmutableString>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FuncInfo {
|
||||||
|
/// Generate a signature of the function.
|
||||||
|
pub fn gen_signature(&self) -> String {
|
||||||
|
let mut sig = format!("{}(", self.name);
|
||||||
|
|
||||||
|
if let Some(ref names) = self.param_names {
|
||||||
|
let params: Vec<_> = names.iter().map(ImmutableString::to_string).collect();
|
||||||
|
sig.push_str(¶ms.join(", "));
|
||||||
|
} else {
|
||||||
|
for x in 0..self.params {
|
||||||
|
sig.push_str("_");
|
||||||
|
if x < self.params - 1 {
|
||||||
|
sig.push_str(", ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sig.push_str(")");
|
||||||
|
sig
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A module which may contain variables, sub-modules, external Rust functions,
|
/// A module which may contain variables, sub-modules, external Rust functions,
|
||||||
@ -232,6 +254,14 @@ impl Module {
|
|||||||
self.indexed
|
self.indexed
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Generate signatures for all the functions in the module.
|
||||||
|
pub fn gen_fn_signatures<'a>(&'a self) -> impl Iterator<Item = String> + 'a {
|
||||||
|
self.functions
|
||||||
|
.values()
|
||||||
|
.filter(|FuncInfo { access, .. }| !access.is_private())
|
||||||
|
.map(FuncInfo::gen_signature)
|
||||||
|
}
|
||||||
|
|
||||||
/// Does a variable exist in the module?
|
/// Does a variable exist in the module?
|
||||||
///
|
///
|
||||||
/// # Example
|
/// # Example
|
||||||
@ -331,7 +361,8 @@ impl Module {
|
|||||||
namespace: FnNamespace::Internal,
|
namespace: FnNamespace::Internal,
|
||||||
access: fn_def.access,
|
access: fn_def.access,
|
||||||
params: num_params,
|
params: num_params,
|
||||||
types: None,
|
param_types: None,
|
||||||
|
param_names: Some(fn_def.params.clone()),
|
||||||
func: fn_def.into(),
|
func: fn_def.into(),
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
@ -399,23 +430,6 @@ impl Module {
|
|||||||
self.modules.get(name).map(|m| m.as_ref())
|
self.modules.get(name).map(|m| m.as_ref())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get a mutable reference to a sub-module.
|
|
||||||
///
|
|
||||||
/// # Example
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// use rhai::Module;
|
|
||||||
///
|
|
||||||
/// let mut module = Module::new();
|
|
||||||
/// let sub_module = Module::new();
|
|
||||||
/// module.set_sub_module("question", sub_module);
|
|
||||||
/// assert!(module.get_sub_module_mut("question").is_some());
|
|
||||||
/// ```
|
|
||||||
#[inline(always)]
|
|
||||||
pub fn get_sub_module_mut(&mut self, name: &str) -> Option<&mut Module> {
|
|
||||||
self.modules.get_mut(name).map(shared_make_mut)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Set a sub-module into the module.
|
/// Set a sub-module into the module.
|
||||||
///
|
///
|
||||||
/// If there is an existing sub-module of the same name, it is replaced.
|
/// If there is an existing sub-module of the same name, it is replaced.
|
||||||
@ -469,6 +483,17 @@ impl Module {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Update the parameter names and types in a registered function.
|
||||||
|
///
|
||||||
|
/// The [`u64`] hash is calculated either by the function [`crate::calc_native_fn_hash`] or
|
||||||
|
/// the function [`crate::calc_script_fn_hash`].
|
||||||
|
pub fn update_fn_param_names(&mut self, hash_fn: u64, arg_names: &[&str]) -> &mut Self {
|
||||||
|
if let Some(f) = self.functions.get_mut(&hash_fn) {
|
||||||
|
f.param_names = Some(arg_names.iter().map(|&n| n.into()).collect());
|
||||||
|
}
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
/// Set a Rust function into the module, returning a hash key.
|
/// Set a Rust function into the module, returning a hash key.
|
||||||
///
|
///
|
||||||
/// If there is an existing Rust function of the same hash, it is replaced.
|
/// If there is an existing Rust function of the same hash, it is replaced.
|
||||||
@ -481,6 +506,7 @@ impl Module {
|
|||||||
name: impl Into<String>,
|
name: impl Into<String>,
|
||||||
namespace: FnNamespace,
|
namespace: FnNamespace,
|
||||||
access: FnAccess,
|
access: FnAccess,
|
||||||
|
arg_names: Option<&[&str]>,
|
||||||
arg_types: &[TypeId],
|
arg_types: &[TypeId],
|
||||||
func: CallableFunction,
|
func: CallableFunction,
|
||||||
) -> u64 {
|
) -> u64 {
|
||||||
@ -507,7 +533,8 @@ impl Module {
|
|||||||
namespace,
|
namespace,
|
||||||
access,
|
access,
|
||||||
params: params.len(),
|
params: params.len(),
|
||||||
types: Some(params),
|
param_types: Some(params),
|
||||||
|
param_names: arg_names.map(|p| p.iter().map(|&v| v.into()).collect()),
|
||||||
func: func.into(),
|
func: func.into(),
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
@ -595,6 +622,7 @@ impl Module {
|
|||||||
name,
|
name,
|
||||||
namespace,
|
namespace,
|
||||||
access,
|
access,
|
||||||
|
None,
|
||||||
arg_types,
|
arg_types,
|
||||||
CallableFunction::from_method(Box::new(f)),
|
CallableFunction::from_method(Box::new(f)),
|
||||||
)
|
)
|
||||||
@ -625,6 +653,7 @@ impl Module {
|
|||||||
name,
|
name,
|
||||||
FnNamespace::Internal,
|
FnNamespace::Internal,
|
||||||
FnAccess::Public,
|
FnAccess::Public,
|
||||||
|
None,
|
||||||
&arg_types,
|
&arg_types,
|
||||||
CallableFunction::from_pure(Box::new(f)),
|
CallableFunction::from_pure(Box::new(f)),
|
||||||
)
|
)
|
||||||
@ -657,6 +686,7 @@ impl Module {
|
|||||||
name,
|
name,
|
||||||
FnNamespace::Internal,
|
FnNamespace::Internal,
|
||||||
FnAccess::Public,
|
FnAccess::Public,
|
||||||
|
None,
|
||||||
&arg_types,
|
&arg_types,
|
||||||
CallableFunction::from_pure(Box::new(f)),
|
CallableFunction::from_pure(Box::new(f)),
|
||||||
)
|
)
|
||||||
@ -692,6 +722,7 @@ impl Module {
|
|||||||
name,
|
name,
|
||||||
namespace,
|
namespace,
|
||||||
FnAccess::Public,
|
FnAccess::Public,
|
||||||
|
None,
|
||||||
&arg_types,
|
&arg_types,
|
||||||
CallableFunction::from_method(Box::new(f)),
|
CallableFunction::from_method(Box::new(f)),
|
||||||
)
|
)
|
||||||
@ -757,6 +788,7 @@ impl Module {
|
|||||||
name,
|
name,
|
||||||
FnNamespace::Internal,
|
FnNamespace::Internal,
|
||||||
FnAccess::Public,
|
FnAccess::Public,
|
||||||
|
None,
|
||||||
&arg_types,
|
&arg_types,
|
||||||
CallableFunction::from_pure(Box::new(f)),
|
CallableFunction::from_pure(Box::new(f)),
|
||||||
)
|
)
|
||||||
@ -799,6 +831,7 @@ impl Module {
|
|||||||
name,
|
name,
|
||||||
namespace,
|
namespace,
|
||||||
FnAccess::Public,
|
FnAccess::Public,
|
||||||
|
None,
|
||||||
&arg_types,
|
&arg_types,
|
||||||
CallableFunction::from_method(Box::new(f)),
|
CallableFunction::from_method(Box::new(f)),
|
||||||
)
|
)
|
||||||
@ -919,6 +952,7 @@ impl Module {
|
|||||||
name,
|
name,
|
||||||
FnNamespace::Internal,
|
FnNamespace::Internal,
|
||||||
FnAccess::Public,
|
FnAccess::Public,
|
||||||
|
None,
|
||||||
&arg_types,
|
&arg_types,
|
||||||
CallableFunction::from_pure(Box::new(f)),
|
CallableFunction::from_pure(Box::new(f)),
|
||||||
)
|
)
|
||||||
@ -967,6 +1001,7 @@ impl Module {
|
|||||||
name,
|
name,
|
||||||
namespace,
|
namespace,
|
||||||
FnAccess::Public,
|
FnAccess::Public,
|
||||||
|
None,
|
||||||
&arg_types,
|
&arg_types,
|
||||||
CallableFunction::from_method(Box::new(f)),
|
CallableFunction::from_method(Box::new(f)),
|
||||||
)
|
)
|
||||||
@ -1027,6 +1062,7 @@ impl Module {
|
|||||||
crate::engine::FN_IDX_SET,
|
crate::engine::FN_IDX_SET,
|
||||||
FnNamespace::Internal,
|
FnNamespace::Internal,
|
||||||
FnAccess::Public,
|
FnAccess::Public,
|
||||||
|
None,
|
||||||
&arg_types,
|
&arg_types,
|
||||||
CallableFunction::from_method(Box::new(f)),
|
CallableFunction::from_method(Box::new(f)),
|
||||||
)
|
)
|
||||||
@ -1119,6 +1155,7 @@ impl Module {
|
|||||||
name,
|
name,
|
||||||
FnNamespace::Internal,
|
FnNamespace::Internal,
|
||||||
FnAccess::Public,
|
FnAccess::Public,
|
||||||
|
None,
|
||||||
&arg_types,
|
&arg_types,
|
||||||
CallableFunction::from_pure(Box::new(f)),
|
CallableFunction::from_pure(Box::new(f)),
|
||||||
)
|
)
|
||||||
@ -1174,6 +1211,7 @@ impl Module {
|
|||||||
name,
|
name,
|
||||||
namespace,
|
namespace,
|
||||||
FnAccess::Public,
|
FnAccess::Public,
|
||||||
|
None,
|
||||||
&arg_types,
|
&arg_types,
|
||||||
CallableFunction::from_method(Box::new(f)),
|
CallableFunction::from_method(Box::new(f)),
|
||||||
)
|
)
|
||||||
@ -1537,6 +1575,8 @@ impl Module {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
module.build_index();
|
||||||
|
|
||||||
Ok(module)
|
Ok(module)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1544,8 +1584,7 @@ impl Module {
|
|||||||
/// variables and functions as one flattened namespace.
|
/// variables and functions as one flattened namespace.
|
||||||
///
|
///
|
||||||
/// If the module is already indexed, this method has no effect.
|
/// If the module is already indexed, this method has no effect.
|
||||||
#[cfg(not(feature = "no_module"))]
|
pub fn build_index(&mut self) -> &mut Self {
|
||||||
pub fn build_index(&mut self) {
|
|
||||||
// Collect a particular module.
|
// Collect a particular module.
|
||||||
fn index_module<'a>(
|
fn index_module<'a>(
|
||||||
module: &'a Module,
|
module: &'a Module,
|
||||||
@ -1586,7 +1625,7 @@ impl Module {
|
|||||||
name,
|
name,
|
||||||
namespace,
|
namespace,
|
||||||
params,
|
params,
|
||||||
types,
|
param_types: types,
|
||||||
func,
|
func,
|
||||||
..
|
..
|
||||||
},
|
},
|
||||||
@ -1645,6 +1684,8 @@ impl Module {
|
|||||||
self.all_type_iterators = type_iterators;
|
self.all_type_iterators = type_iterators;
|
||||||
self.indexed = true;
|
self.indexed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Does a type iterator exist in the entire module tree?
|
/// Does a type iterator exist in the entire module tree?
|
||||||
|
@ -159,12 +159,10 @@ impl ModuleResolver for FileModuleResolver {
|
|||||||
_ => Box::new(EvalAltResult::ErrorInModule(path.to_string(), err, pos)),
|
_ => Box::new(EvalAltResult::ErrorInModule(path.to_string(), err, pos)),
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
let mut m = Module::eval_ast_as_new(scope, &ast, engine).map_err(|err| {
|
let m = Module::eval_ast_as_new(scope, &ast, engine).map_err(|err| {
|
||||||
Box::new(EvalAltResult::ErrorInModule(path.to_string(), err, pos))
|
Box::new(EvalAltResult::ErrorInModule(path.to_string(), err, pos))
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
m.build_index();
|
|
||||||
|
|
||||||
module = Some(m.into());
|
module = Some(m.into());
|
||||||
module_ref = module.clone();
|
module_ref = module.clone();
|
||||||
};
|
};
|
||||||
|
@ -1,10 +1,7 @@
|
|||||||
//! Module implementing the AST optimizer.
|
//! Module implementing the AST optimizer.
|
||||||
|
|
||||||
use crate::ast::{Expr, ScriptFnDef, Stmt};
|
use crate::ast::{Expr, ScriptFnDef, Stmt};
|
||||||
use crate::engine::{
|
use crate::engine::{KEYWORD_DEBUG, KEYWORD_EVAL, KEYWORD_PRINT, KEYWORD_TYPE_OF};
|
||||||
KEYWORD_DEBUG, KEYWORD_EVAL, KEYWORD_IS_DEF_FN, KEYWORD_IS_DEF_VAR, KEYWORD_PRINT,
|
|
||||||
KEYWORD_TYPE_OF,
|
|
||||||
};
|
|
||||||
use crate::fn_call::run_builtin_binary_op;
|
use crate::fn_call::run_builtin_binary_op;
|
||||||
use crate::parser::map_dynamic_to_expr;
|
use crate::parser::map_dynamic_to_expr;
|
||||||
use crate::stdlib::{
|
use crate::stdlib::{
|
||||||
@ -467,11 +464,9 @@ fn optimize_stmt(stmt: &mut Stmt, state: &mut State, preserve_result: bool) {
|
|||||||
fn optimize_expr(expr: &mut Expr, state: &mut State) {
|
fn optimize_expr(expr: &mut Expr, state: &mut State) {
|
||||||
// These keywords are handled specially
|
// These keywords are handled specially
|
||||||
const DONT_EVAL_KEYWORDS: &[&str] = &[
|
const DONT_EVAL_KEYWORDS: &[&str] = &[
|
||||||
KEYWORD_PRINT, // side effects
|
KEYWORD_PRINT, // side effects
|
||||||
KEYWORD_DEBUG, // side effects
|
KEYWORD_DEBUG, // side effects
|
||||||
KEYWORD_EVAL, // arbitrary scripts
|
KEYWORD_EVAL, // arbitrary scripts
|
||||||
KEYWORD_IS_DEF_FN, // functions collection is volatile
|
|
||||||
KEYWORD_IS_DEF_VAR, // variables scope is volatile
|
|
||||||
];
|
];
|
||||||
|
|
||||||
match expr {
|
match expr {
|
||||||
@ -650,7 +645,7 @@ fn optimize_expr(expr: &mut Expr, state: &mut State) {
|
|||||||
let arg_types: StaticVec<_> = arg_values.iter().map(Dynamic::type_id).collect();
|
let arg_types: StaticVec<_> = arg_values.iter().map(Dynamic::type_id).collect();
|
||||||
|
|
||||||
// Search for overloaded operators (can override built-in).
|
// Search for overloaded operators (can override built-in).
|
||||||
if !state.engine.has_override_by_name_and_arguments(&state.engine.global_sub_modules, state.lib, x.name.as_ref(), arg_types.as_ref(), false) {
|
if !state.engine.has_override_by_name_and_arguments(Some(&state.engine.global_sub_modules), state.lib, x.name.as_ref(), arg_types.as_ref(), false) {
|
||||||
if let Some(result) = run_builtin_binary_op(x.name.as_ref(), &arg_values[0], &arg_values[1])
|
if let Some(result) = run_builtin_binary_op(x.name.as_ref(), &arg_values[0], &arg_values[1])
|
||||||
.ok().flatten()
|
.ok().flatten()
|
||||||
.and_then(|result| map_dynamic_to_expr(result, *pos))
|
.and_then(|result| map_dynamic_to_expr(result, *pos))
|
||||||
|
@ -1,14 +0,0 @@
|
|||||||
use crate::plugin::*;
|
|
||||||
use crate::{def_package, Dynamic, EvalAltResult, ImmutableString};
|
|
||||||
|
|
||||||
def_package!(crate:EvalPackage:"Disable 'eval'.", lib, {
|
|
||||||
combine_with_exported_module!(lib, "eval", eval_override);
|
|
||||||
});
|
|
||||||
|
|
||||||
#[export_module]
|
|
||||||
mod eval_override {
|
|
||||||
#[rhai_fn(return_raw)]
|
|
||||||
pub fn eval(_script: ImmutableString) -> Result<Dynamic, Box<EvalAltResult>> {
|
|
||||||
Err("eval is evil!".into())
|
|
||||||
}
|
|
||||||
}
|
|
@ -48,7 +48,8 @@ macro_rules! reg_range {
|
|||||||
($lib:expr, $x:expr, $( $y:ty ),*) => (
|
($lib:expr, $x:expr, $( $y:ty ),*) => (
|
||||||
$(
|
$(
|
||||||
$lib.set_iterator::<Range<$y>>();
|
$lib.set_iterator::<Range<$y>>();
|
||||||
$lib.set_fn_2($x, get_range::<$y>);
|
let hash = $lib.set_fn_2($x, get_range::<$y>);
|
||||||
|
$lib.update_fn_param_names(hash, &[concat!("from: ", stringify!($y)), concat!("to: ", stringify!($y))]);
|
||||||
)*
|
)*
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -59,14 +60,16 @@ macro_rules! reg_step {
|
|||||||
($lib:expr, $x:expr, $( $y:ty ),*) => (
|
($lib:expr, $x:expr, $( $y:ty ),*) => (
|
||||||
$(
|
$(
|
||||||
$lib.set_iterator::<StepRange<$y>>();
|
$lib.set_iterator::<StepRange<$y>>();
|
||||||
$lib.set_fn_3($x, get_step_range::<$y>);
|
let hash = $lib.set_fn_3($x, get_step_range::<$y>);
|
||||||
|
$lib.update_fn_param_names(hash, &[concat!("from: ", stringify!($y)), concat!("to: ", stringify!($y)), concat!("step: ", stringify!($y))]);
|
||||||
)*
|
)*
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
def_package!(crate:BasicIteratorPackage:"Basic range iterators.", lib, {
|
def_package!(crate:BasicIteratorPackage:"Basic range iterators.", lib, {
|
||||||
lib.set_iterator::<Range<INT>>();
|
lib.set_iterator::<Range<INT>>();
|
||||||
lib.set_fn_2("range", get_range::<INT>);
|
let hash = lib.set_fn_2("range", get_range::<INT>);
|
||||||
|
lib.update_fn_param_names(hash, &["from: INT", "to: INT"]);
|
||||||
|
|
||||||
#[cfg(not(feature = "only_i32"))]
|
#[cfg(not(feature = "only_i32"))]
|
||||||
#[cfg(not(feature = "only_i64"))]
|
#[cfg(not(feature = "only_i64"))]
|
||||||
@ -79,7 +82,8 @@ def_package!(crate:BasicIteratorPackage:"Basic range iterators.", lib, {
|
|||||||
}
|
}
|
||||||
|
|
||||||
lib.set_iterator::<StepRange<INT>>();
|
lib.set_iterator::<StepRange<INT>>();
|
||||||
lib.set_fn_3("range", get_step_range::<INT>);
|
let hash = lib.set_fn_3("range", get_step_range::<INT>);
|
||||||
|
lib.update_fn_param_names(hash, &["from: INT", "to: INT", "step: INT"]);
|
||||||
|
|
||||||
#[cfg(not(feature = "only_i32"))]
|
#[cfg(not(feature = "only_i32"))]
|
||||||
#[cfg(not(feature = "only_i64"))]
|
#[cfg(not(feature = "only_i64"))]
|
||||||
|
@ -1,12 +1,11 @@
|
|||||||
//! Module containing all built-in _packages_ available to Rhai, plus facilities to define custom packages.
|
//! Module containing all built-in _packages_ available to Rhai, plus facilities to define custom packages.
|
||||||
|
|
||||||
use crate::fn_native::{CallableFunction, IteratorFn};
|
use crate::fn_native::{CallableFunction, IteratorFn};
|
||||||
use crate::stdlib::any::TypeId;
|
use crate::stdlib::{any::TypeId, string::String};
|
||||||
use crate::{Module, Shared, StaticVec};
|
use crate::{Module, Shared, StaticVec};
|
||||||
|
|
||||||
pub(crate) mod arithmetic;
|
pub(crate) mod arithmetic;
|
||||||
mod array_basic;
|
mod array_basic;
|
||||||
mod eval;
|
|
||||||
mod fn_basic;
|
mod fn_basic;
|
||||||
mod iter_basic;
|
mod iter_basic;
|
||||||
mod logic;
|
mod logic;
|
||||||
@ -21,7 +20,6 @@ mod time_basic;
|
|||||||
pub use arithmetic::ArithmeticPackage;
|
pub use arithmetic::ArithmeticPackage;
|
||||||
#[cfg(not(feature = "no_index"))]
|
#[cfg(not(feature = "no_index"))]
|
||||||
pub use array_basic::BasicArrayPackage;
|
pub use array_basic::BasicArrayPackage;
|
||||||
pub use eval::EvalPackage;
|
|
||||||
pub use fn_basic::BasicFnPackage;
|
pub use fn_basic::BasicFnPackage;
|
||||||
pub use iter_basic::BasicIteratorPackage;
|
pub use iter_basic::BasicIteratorPackage;
|
||||||
pub use logic::LogicPackage;
|
pub use logic::LogicPackage;
|
||||||
@ -89,6 +87,15 @@ impl PackagesCollection {
|
|||||||
.as_ref()
|
.as_ref()
|
||||||
.and_then(|x| x.iter().find_map(|p| p.get_iter(id)))
|
.and_then(|x| x.iter().find_map(|p| p.get_iter(id)))
|
||||||
}
|
}
|
||||||
|
/// Get an iterator over all the packages in the [`PackagesCollection`].
|
||||||
|
pub(crate) fn iter(&self) -> impl Iterator<Item = &PackageLibrary> {
|
||||||
|
self.0.iter().flat_map(|p| p.iter())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Generate signatures for all the functions in the [`PackagesCollection`].
|
||||||
|
pub fn gen_fn_signatures<'a>(&'a self) -> impl Iterator<Item = String> + 'a {
|
||||||
|
self.iter().flat_map(|m| m.gen_fn_signatures())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Macro that makes it easy to define a _package_ (which is basically a shared module)
|
/// Macro that makes it easy to define a _package_ (which is basically a shared module)
|
||||||
@ -133,6 +140,7 @@ macro_rules! def_package {
|
|||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
let mut module = $root::Module::new_with_capacity(1024);
|
let mut module = $root::Module::new_with_capacity(1024);
|
||||||
<Self as $root::packages::Package>::init(&mut module);
|
<Self as $root::packages::Package>::init(&mut module);
|
||||||
|
module.build_index();
|
||||||
Self(module.into())
|
Self(module.into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,9 +4,34 @@ use super::iter_basic::BasicIteratorPackage;
|
|||||||
use super::logic::LogicPackage;
|
use super::logic::LogicPackage;
|
||||||
use super::string_basic::BasicStringPackage;
|
use super::string_basic::BasicStringPackage;
|
||||||
|
|
||||||
use crate::def_package;
|
use crate::fn_native::{CallableFunction, FnCallArgs};
|
||||||
|
use crate::stdlib::{any::TypeId, boxed::Box, iter::empty};
|
||||||
|
use crate::{
|
||||||
|
calc_script_fn_hash, def_package, FnAccess, FnNamespace, ImmutableString, NativeCallContext,
|
||||||
|
INT,
|
||||||
|
};
|
||||||
|
|
||||||
def_package!(crate:CorePackage:"_Core_ package containing basic facilities.", lib, {
|
def_package!(crate:CorePackage:"_Core_ package containing basic facilities.", lib, {
|
||||||
|
#[cfg(not(feature = "no_function"))]
|
||||||
|
{
|
||||||
|
let f = |ctx: NativeCallContext, args: &mut FnCallArgs| {
|
||||||
|
let num_params = args[1].clone().cast::<INT>();
|
||||||
|
let fn_name = args[0].as_str().unwrap();
|
||||||
|
|
||||||
|
Ok(if num_params < 0 {
|
||||||
|
false.into()
|
||||||
|
} else {
|
||||||
|
let hash_script = calc_script_fn_hash(empty(), fn_name, num_params as usize);
|
||||||
|
ctx.engine().has_override(ctx.mods, ctx.lib, 0, hash_script, true).into()
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
|
lib.set_fn("is_def_fn", FnNamespace::Global, FnAccess::Public,
|
||||||
|
Some(&["fn_name: &str", "num_params: INT"]),
|
||||||
|
&[TypeId::of::<ImmutableString>(), TypeId::of::<INT>()],
|
||||||
|
CallableFunction::from_method(Box::new(f)));
|
||||||
|
}
|
||||||
|
|
||||||
ArithmeticPackage::init(lib);
|
ArithmeticPackage::init(lib);
|
||||||
LogicPackage::init(lib);
|
LogicPackage::init(lib);
|
||||||
BasicStringPackage::init(lib);
|
BasicStringPackage::init(lib);
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#![allow(non_snake_case)]
|
#![allow(non_snake_case)]
|
||||||
|
|
||||||
use crate::engine::{FN_TO_STRING, KEYWORD_DEBUG, KEYWORD_PRINT};
|
use crate::engine::{KEYWORD_DEBUG, KEYWORD_PRINT};
|
||||||
use crate::plugin::*;
|
use crate::plugin::*;
|
||||||
use crate::stdlib::{
|
use crate::stdlib::{
|
||||||
fmt::{Debug, Display},
|
fmt::{Debug, Display},
|
||||||
@ -32,7 +32,7 @@ macro_rules! gen_functions {
|
|||||||
|
|
||||||
macro_rules! reg_print_functions {
|
macro_rules! reg_print_functions {
|
||||||
($mod_name:ident += $root:ident ; $($arg_type:ident),+) => { $(
|
($mod_name:ident += $root:ident ; $($arg_type:ident),+) => { $(
|
||||||
set_exported_fn!($mod_name, FN_TO_STRING, $root::$arg_type::to_string_func);
|
set_exported_fn!($mod_name, "to_string", $root::$arg_type::to_string_func);
|
||||||
set_exported_fn!($mod_name, KEYWORD_PRINT, $root::$arg_type::to_string_func);
|
set_exported_fn!($mod_name, KEYWORD_PRINT, $root::$arg_type::to_string_func);
|
||||||
)* }
|
)* }
|
||||||
}
|
}
|
||||||
|
@ -32,7 +32,7 @@ pub enum LexError {
|
|||||||
/// An identifier is in an invalid format.
|
/// An identifier is in an invalid format.
|
||||||
MalformedIdentifier(String),
|
MalformedIdentifier(String),
|
||||||
/// Bad symbol encountered when tokenizing the script text.
|
/// Bad symbol encountered when tokenizing the script text.
|
||||||
ImproperSymbol(String),
|
ImproperSymbol(String, String),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Error for LexError {}
|
impl Error for LexError {}
|
||||||
@ -47,7 +47,10 @@ impl fmt::Display for LexError {
|
|||||||
Self::MalformedIdentifier(s) => write!(f, "{}: '{}'", self.desc(), s),
|
Self::MalformedIdentifier(s) => write!(f, "{}: '{}'", self.desc(), s),
|
||||||
Self::UnterminatedString => f.write_str(self.desc()),
|
Self::UnterminatedString => f.write_str(self.desc()),
|
||||||
Self::StringTooLong(max) => write!(f, "{} ({})", self.desc(), max),
|
Self::StringTooLong(max) => write!(f, "{} ({})", self.desc(), max),
|
||||||
Self::ImproperSymbol(s) => f.write_str(s),
|
Self::ImproperSymbol(s, d) if d.is_empty() => {
|
||||||
|
write!(f, "Invalid symbol encountered: '{}'", s)
|
||||||
|
}
|
||||||
|
Self::ImproperSymbol(_, d) => f.write_str(d),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -62,7 +65,7 @@ impl LexError {
|
|||||||
Self::MalformedNumber(_) => "Invalid number",
|
Self::MalformedNumber(_) => "Invalid number",
|
||||||
Self::MalformedChar(_) => "Invalid character",
|
Self::MalformedChar(_) => "Invalid character",
|
||||||
Self::MalformedIdentifier(_) => "Variable name is not proper",
|
Self::MalformedIdentifier(_) => "Variable name is not proper",
|
||||||
Self::ImproperSymbol(_) => "Invalid symbol encountered",
|
Self::ImproperSymbol(_, _) => "Invalid symbol encountered",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/// Convert a `&LexError` into a [`ParseError`].
|
/// Convert a `&LexError` into a [`ParseError`].
|
||||||
|
@ -46,11 +46,11 @@ struct ParseState<'e> {
|
|||||||
strings: HashMap<String, ImmutableString>,
|
strings: HashMap<String, ImmutableString>,
|
||||||
/// Encapsulates a local stack with variable names to simulate an actual runtime scope.
|
/// Encapsulates a local stack with variable names to simulate an actual runtime scope.
|
||||||
stack: Vec<(ImmutableString, ScopeEntryType)>,
|
stack: Vec<(ImmutableString, ScopeEntryType)>,
|
||||||
|
/// Size of the local variables stack upon entry of the current block scope.
|
||||||
|
entry_stack_len: usize,
|
||||||
/// Tracks a list of external variables (variables that are not explicitly declared in the scope).
|
/// Tracks a list of external variables (variables that are not explicitly declared in the scope).
|
||||||
#[cfg(not(feature = "no_closure"))]
|
#[cfg(not(feature = "no_closure"))]
|
||||||
externals: HashMap<ImmutableString, Position>,
|
externals: HashMap<ImmutableString, Position>,
|
||||||
/// Always search for variables instead of direct indexing into the scope.
|
|
||||||
always_search: bool,
|
|
||||||
/// An indicator that disables variable capturing into externals one single time
|
/// An indicator that disables variable capturing into externals one single time
|
||||||
/// up until the nearest consumed Identifier token.
|
/// up until the nearest consumed Identifier token.
|
||||||
/// If set to false the next call to `access_var` will not capture the variable.
|
/// If set to false the next call to `access_var` will not capture the variable.
|
||||||
@ -94,7 +94,7 @@ impl<'e> ParseState<'e> {
|
|||||||
allow_capture: true,
|
allow_capture: true,
|
||||||
strings: HashMap::with_capacity(64),
|
strings: HashMap::with_capacity(64),
|
||||||
stack: Vec::with_capacity(16),
|
stack: Vec::with_capacity(16),
|
||||||
always_search: false,
|
entry_stack_len: 0,
|
||||||
#[cfg(not(feature = "no_module"))]
|
#[cfg(not(feature = "no_module"))]
|
||||||
modules: Default::default(),
|
modules: Default::default(),
|
||||||
}
|
}
|
||||||
@ -110,12 +110,22 @@ impl<'e> ParseState<'e> {
|
|||||||
/// Return `None` when the variable name is not found in the `stack`.
|
/// Return `None` when the variable name is not found in the `stack`.
|
||||||
#[inline]
|
#[inline]
|
||||||
fn access_var(&mut self, name: &str, _pos: Position) -> Option<NonZeroUsize> {
|
fn access_var(&mut self, name: &str, _pos: Position) -> Option<NonZeroUsize> {
|
||||||
|
let mut barrier = false;
|
||||||
|
|
||||||
let index = self
|
let index = self
|
||||||
.stack
|
.stack
|
||||||
.iter()
|
.iter()
|
||||||
.rev()
|
.rev()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.find(|(_, (n, _))| *n == name)
|
.find(|(_, (n, _))| {
|
||||||
|
if n.is_empty() {
|
||||||
|
// Do not go beyond empty variable names
|
||||||
|
barrier = true;
|
||||||
|
false
|
||||||
|
} else {
|
||||||
|
*n == name
|
||||||
|
}
|
||||||
|
})
|
||||||
.and_then(|(i, _)| NonZeroUsize::new(i + 1));
|
.and_then(|(i, _)| NonZeroUsize::new(i + 1));
|
||||||
|
|
||||||
#[cfg(not(feature = "no_closure"))]
|
#[cfg(not(feature = "no_closure"))]
|
||||||
@ -127,7 +137,7 @@ impl<'e> ParseState<'e> {
|
|||||||
self.allow_capture = true
|
self.allow_capture = true
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.always_search {
|
if barrier {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
index
|
index
|
||||||
@ -985,11 +995,8 @@ fn parse_primary(
|
|||||||
// Access to `this` as a variable is OK
|
// Access to `this` as a variable is OK
|
||||||
Token::Reserved(s) if s == KEYWORD_THIS && *next_token != Token::LeftParen => {
|
Token::Reserved(s) if s == KEYWORD_THIS && *next_token != Token::LeftParen => {
|
||||||
if !settings.is_function_scope {
|
if !settings.is_function_scope {
|
||||||
return Err(PERR::BadInput(LexError::ImproperSymbol(format!(
|
let msg = format!("'{}' can only be used in functions", s);
|
||||||
"'{}' can only be used in functions",
|
return Err(PERR::BadInput(LexError::ImproperSymbol(s, msg)).into_err(settings.pos));
|
||||||
s
|
|
||||||
)))
|
|
||||||
.into_err(settings.pos));
|
|
||||||
} else {
|
} else {
|
||||||
let var_name_def = IdentX::new(state.get_interned_string(s), settings.pos);
|
let var_name_def = IdentX::new(state.get_interned_string(s), settings.pos);
|
||||||
Expr::Variable(Box::new((None, None, 0, var_name_def)))
|
Expr::Variable(Box::new((None, None, 0, var_name_def)))
|
||||||
@ -1035,6 +1042,7 @@ fn parse_primary(
|
|||||||
LexError::UnexpectedInput(Token::Bang.syntax().to_string()).into_err(token_pos)
|
LexError::UnexpectedInput(Token::Bang.syntax().to_string()).into_err(token_pos)
|
||||||
} else {
|
} else {
|
||||||
PERR::BadInput(LexError::ImproperSymbol(
|
PERR::BadInput(LexError::ImproperSymbol(
|
||||||
|
"!".to_string(),
|
||||||
"'!' cannot be used to call module functions".to_string(),
|
"'!' cannot be used to call module functions".to_string(),
|
||||||
))
|
))
|
||||||
.into_err(token_pos)
|
.into_err(token_pos)
|
||||||
@ -1323,6 +1331,7 @@ fn make_assignment_stmt<'a>(
|
|||||||
}
|
}
|
||||||
// ??? && ??? = rhs, ??? || ??? = rhs
|
// ??? && ??? = rhs, ??? || ??? = rhs
|
||||||
Expr::And(_, _) | Expr::Or(_, _) => Err(PERR::BadInput(LexError::ImproperSymbol(
|
Expr::And(_, _) | Expr::Or(_, _) => Err(PERR::BadInput(LexError::ImproperSymbol(
|
||||||
|
"=".to_string(),
|
||||||
"Possibly a typo of '=='?".to_string(),
|
"Possibly a typo of '=='?".to_string(),
|
||||||
))
|
))
|
||||||
.into_err(pos)),
|
.into_err(pos)),
|
||||||
@ -1428,10 +1437,13 @@ fn make_dot_expr(
|
|||||||
&& [crate::engine::KEYWORD_FN_PTR, crate::engine::KEYWORD_EVAL]
|
&& [crate::engine::KEYWORD_FN_PTR, crate::engine::KEYWORD_EVAL]
|
||||||
.contains(&x.name.as_ref()) =>
|
.contains(&x.name.as_ref()) =>
|
||||||
{
|
{
|
||||||
return Err(PERR::BadInput(LexError::ImproperSymbol(format!(
|
return Err(PERR::BadInput(LexError::ImproperSymbol(
|
||||||
"'{}' should not be called in method style. Try {}(...);",
|
x.name.to_string(),
|
||||||
x.name, x.name
|
format!(
|
||||||
)))
|
"'{}' should not be called in method style. Try {}(...);",
|
||||||
|
x.name, x.name
|
||||||
|
),
|
||||||
|
))
|
||||||
.into_err(pos));
|
.into_err(pos));
|
||||||
}
|
}
|
||||||
// lhs.func!(...)
|
// lhs.func!(...)
|
||||||
@ -1789,11 +1801,13 @@ fn parse_custom_syntax(
|
|||||||
// Adjust the variables stack
|
// Adjust the variables stack
|
||||||
match syntax.scope_delta {
|
match syntax.scope_delta {
|
||||||
delta if delta > 0 => {
|
delta if delta > 0 => {
|
||||||
|
// Add enough empty variable names to the stack.
|
||||||
|
// Empty variable names act as a barrier so earlier variables will not be matched.
|
||||||
|
// Variable searches stop at the first empty variable name.
|
||||||
state.stack.resize(
|
state.stack.resize(
|
||||||
state.stack.len() + delta as usize,
|
state.stack.len() + delta as usize,
|
||||||
("".into(), ScopeEntryType::Normal),
|
("".into(), ScopeEntryType::Normal),
|
||||||
);
|
);
|
||||||
state.always_search = true;
|
|
||||||
}
|
}
|
||||||
delta if delta < 0 && state.stack.len() <= delta.abs() as usize => state.stack.clear(),
|
delta if delta < 0 && state.stack.len() <= delta.abs() as usize => state.stack.clear(),
|
||||||
delta if delta < 0 => state
|
delta if delta < 0 => state
|
||||||
@ -1920,20 +1934,22 @@ fn ensure_not_statement_expr(input: &mut TokenStream, type_name: &str) -> Result
|
|||||||
fn ensure_not_assignment(input: &mut TokenStream) -> Result<(), ParseError> {
|
fn ensure_not_assignment(input: &mut TokenStream) -> Result<(), ParseError> {
|
||||||
match input.peek().unwrap() {
|
match input.peek().unwrap() {
|
||||||
(Token::Equals, pos) => Err(PERR::BadInput(LexError::ImproperSymbol(
|
(Token::Equals, pos) => Err(PERR::BadInput(LexError::ImproperSymbol(
|
||||||
|
"=".to_string(),
|
||||||
"Possibly a typo of '=='?".to_string(),
|
"Possibly a typo of '=='?".to_string(),
|
||||||
))
|
))
|
||||||
.into_err(*pos)),
|
.into_err(*pos)),
|
||||||
(Token::PlusAssign, pos)
|
(token @ Token::PlusAssign, pos)
|
||||||
| (Token::MinusAssign, pos)
|
| (token @ Token::MinusAssign, pos)
|
||||||
| (Token::MultiplyAssign, pos)
|
| (token @ Token::MultiplyAssign, pos)
|
||||||
| (Token::DivideAssign, pos)
|
| (token @ Token::DivideAssign, pos)
|
||||||
| (Token::LeftShiftAssign, pos)
|
| (token @ Token::LeftShiftAssign, pos)
|
||||||
| (Token::RightShiftAssign, pos)
|
| (token @ Token::RightShiftAssign, pos)
|
||||||
| (Token::ModuloAssign, pos)
|
| (token @ Token::ModuloAssign, pos)
|
||||||
| (Token::PowerOfAssign, pos)
|
| (token @ Token::PowerOfAssign, pos)
|
||||||
| (Token::AndAssign, pos)
|
| (token @ Token::AndAssign, pos)
|
||||||
| (Token::OrAssign, pos)
|
| (token @ Token::OrAssign, pos)
|
||||||
| (Token::XOrAssign, pos) => Err(PERR::BadInput(LexError::ImproperSymbol(
|
| (token @ Token::XOrAssign, pos) => Err(PERR::BadInput(LexError::ImproperSymbol(
|
||||||
|
token.syntax().to_string(),
|
||||||
"Expecting a boolean expression, not an assignment".to_string(),
|
"Expecting a boolean expression, not an assignment".to_string(),
|
||||||
))
|
))
|
||||||
.into_err(*pos)),
|
.into_err(*pos)),
|
||||||
@ -2293,8 +2309,9 @@ fn parse_block(
|
|||||||
settings.ensure_level_within_max_limit(state.max_expr_depth)?;
|
settings.ensure_level_within_max_limit(state.max_expr_depth)?;
|
||||||
|
|
||||||
let mut statements = Vec::with_capacity(8);
|
let mut statements = Vec::with_capacity(8);
|
||||||
let prev_always_search = state.always_search;
|
|
||||||
let prev_stack_len = state.stack.len();
|
let prev_entry_stack_len = state.entry_stack_len;
|
||||||
|
state.entry_stack_len = state.stack.len();
|
||||||
|
|
||||||
#[cfg(not(feature = "no_module"))]
|
#[cfg(not(feature = "no_module"))]
|
||||||
let prev_mods_len = state.modules.len();
|
let prev_mods_len = state.modules.len();
|
||||||
@ -2338,15 +2355,12 @@ fn parse_block(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
state.stack.truncate(prev_stack_len);
|
state.stack.truncate(state.entry_stack_len);
|
||||||
|
state.entry_stack_len = prev_entry_stack_len;
|
||||||
|
|
||||||
#[cfg(not(feature = "no_module"))]
|
#[cfg(not(feature = "no_module"))]
|
||||||
state.modules.truncate(prev_mods_len);
|
state.modules.truncate(prev_mods_len);
|
||||||
|
|
||||||
// The impact of new local variables goes away at the end of a block
|
|
||||||
// because any new variables introduced will go out of scope
|
|
||||||
state.always_search = prev_always_search;
|
|
||||||
|
|
||||||
Ok(Stmt::Block(statements, settings.pos))
|
Ok(Stmt::Block(statements, settings.pos))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,6 +33,9 @@ pub trait PluginFunction {
|
|||||||
/// Convert a plugin function into a boxed trait object.
|
/// Convert a plugin function into a boxed trait object.
|
||||||
fn clone_boxed(&self) -> Box<dyn PluginFunction>;
|
fn clone_boxed(&self) -> Box<dyn PluginFunction>;
|
||||||
|
|
||||||
|
/// Return a boxed slice of the names of the function's parameters.
|
||||||
|
fn input_names(&self) -> Box<[&'static str]>;
|
||||||
|
|
||||||
/// Return a boxed slice of type ID's of the function's parameters.
|
/// Return a boxed slice of type ID's of the function's parameters.
|
||||||
fn input_types(&self) -> Box<[TypeId]>;
|
fn input_types(&self) -> Box<[TypeId]>;
|
||||||
}
|
}
|
||||||
|
@ -120,7 +120,7 @@ pub fn from_dynamic<'de, T: Deserialize<'de>>(
|
|||||||
impl Error for Box<EvalAltResult> {
|
impl Error for Box<EvalAltResult> {
|
||||||
fn custom<T: fmt::Display>(err: T) -> Self {
|
fn custom<T: fmt::Display>(err: T) -> Self {
|
||||||
EvalAltResult::ErrorParsing(
|
EvalAltResult::ErrorParsing(
|
||||||
ParseErrorType::BadInput(LexError::ImproperSymbol(err.to_string())),
|
ParseErrorType::BadInput(LexError::ImproperSymbol("".to_string(), err.to_string())),
|
||||||
Position::NONE,
|
Position::NONE,
|
||||||
)
|
)
|
||||||
.into()
|
.into()
|
||||||
|
@ -137,11 +137,14 @@ impl Engine {
|
|||||||
.map(|v| v.is_keyword() || v.is_reserved())
|
.map(|v| v.is_keyword() || v.is_reserved())
|
||||||
.unwrap_or(false) =>
|
.unwrap_or(false) =>
|
||||||
{
|
{
|
||||||
return Err(LexError::ImproperSymbol(format!(
|
return Err(LexError::ImproperSymbol(
|
||||||
"Improper symbol for custom syntax at position #{}: '{}'",
|
s.to_string(),
|
||||||
segments.len() + 1,
|
format!(
|
||||||
s
|
"Improper symbol for custom syntax at position #{}: '{}'",
|
||||||
))
|
segments.len() + 1,
|
||||||
|
s
|
||||||
|
),
|
||||||
|
)
|
||||||
.into_err(Position::NONE)
|
.into_err(Position::NONE)
|
||||||
.into());
|
.into());
|
||||||
}
|
}
|
||||||
@ -154,11 +157,14 @@ impl Engine {
|
|||||||
}
|
}
|
||||||
// Anything else is an error
|
// Anything else is an error
|
||||||
_ => {
|
_ => {
|
||||||
return Err(LexError::ImproperSymbol(format!(
|
return Err(LexError::ImproperSymbol(
|
||||||
"Improper symbol for custom syntax at position #{}: '{}'",
|
s.to_string(),
|
||||||
segments.len() + 1,
|
format!(
|
||||||
s
|
"Improper symbol for custom syntax at position #{}: '{}'",
|
||||||
))
|
segments.len() + 1,
|
||||||
|
s
|
||||||
|
),
|
||||||
|
)
|
||||||
.into_err(Position::NONE)
|
.into_err(Position::NONE)
|
||||||
.into());
|
.into());
|
||||||
}
|
}
|
||||||
|
58
src/token.rs
58
src/token.rs
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
use crate::engine::{
|
use crate::engine::{
|
||||||
KEYWORD_DEBUG, KEYWORD_EVAL, KEYWORD_FN_PTR, KEYWORD_FN_PTR_CALL, KEYWORD_FN_PTR_CURRY,
|
KEYWORD_DEBUG, KEYWORD_EVAL, KEYWORD_FN_PTR, KEYWORD_FN_PTR_CALL, KEYWORD_FN_PTR_CURRY,
|
||||||
KEYWORD_IS_DEF_FN, KEYWORD_IS_DEF_VAR, KEYWORD_PRINT, KEYWORD_THIS, KEYWORD_TYPE_OF,
|
KEYWORD_PRINT, KEYWORD_THIS, KEYWORD_TYPE_OF,
|
||||||
};
|
};
|
||||||
use crate::stdlib::{
|
use crate::stdlib::{
|
||||||
borrow::Cow,
|
borrow::Cow,
|
||||||
@ -532,18 +532,13 @@ impl Token {
|
|||||||
"import" | "export" | "as" => Reserved(syntax.into()),
|
"import" | "export" | "as" => Reserved(syntax.into()),
|
||||||
|
|
||||||
"===" | "!==" | "->" | "<-" | ":=" | "::<" | "(*" | "*)" | "#" | "public" | "new"
|
"===" | "!==" | "->" | "<-" | ":=" | "::<" | "(*" | "*)" | "#" | "public" | "new"
|
||||||
| "use" | "module" | "package" | "var" | "static" | "shared" | "with" | "each"
|
| "use" | "module" | "package" | "var" | "static" | "begin" | "end" | "shared"
|
||||||
| "then" | "goto" | "unless" | "exit" | "match" | "case" | "default" | "void"
|
| "with" | "each" | "then" | "goto" | "unless" | "exit" | "match" | "case"
|
||||||
| "null" | "nil" | "spawn" | "thread" | "go" | "sync" | "async" | "await" | "yield" => {
|
| "default" | "void" | "null" | "nil" | "spawn" | "thread" | "go" | "sync"
|
||||||
Reserved(syntax.into())
|
| "async" | "await" | "yield" => Reserved(syntax.into()),
|
||||||
}
|
|
||||||
|
|
||||||
KEYWORD_PRINT | KEYWORD_DEBUG | KEYWORD_TYPE_OF | KEYWORD_EVAL | KEYWORD_FN_PTR
|
KEYWORD_PRINT | KEYWORD_DEBUG | KEYWORD_TYPE_OF | KEYWORD_EVAL | KEYWORD_FN_PTR
|
||||||
| KEYWORD_FN_PTR_CALL | KEYWORD_FN_PTR_CURRY | KEYWORD_IS_DEF_VAR
|
| KEYWORD_FN_PTR_CALL | KEYWORD_FN_PTR_CURRY | KEYWORD_THIS => Reserved(syntax.into()),
|
||||||
| KEYWORD_IS_DEF_FN | KEYWORD_THIS => Reserved(syntax.into()),
|
|
||||||
|
|
||||||
#[cfg(not(feature = "no_closure"))]
|
|
||||||
crate::engine::KEYWORD_IS_SHARED => Reserved(syntax.into()),
|
|
||||||
|
|
||||||
_ => return None,
|
_ => return None,
|
||||||
})
|
})
|
||||||
@ -1514,12 +1509,8 @@ fn get_identifier(
|
|||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn is_keyword_function(name: &str) -> bool {
|
pub fn is_keyword_function(name: &str) -> bool {
|
||||||
match name {
|
match name {
|
||||||
#[cfg(not(feature = "no_closure"))]
|
|
||||||
crate::engine::KEYWORD_IS_SHARED => true,
|
|
||||||
KEYWORD_PRINT | KEYWORD_DEBUG | KEYWORD_TYPE_OF | KEYWORD_EVAL | KEYWORD_FN_PTR
|
KEYWORD_PRINT | KEYWORD_DEBUG | KEYWORD_TYPE_OF | KEYWORD_EVAL | KEYWORD_FN_PTR
|
||||||
| KEYWORD_FN_PTR_CALL | KEYWORD_FN_PTR_CURRY | KEYWORD_IS_DEF_VAR | KEYWORD_IS_DEF_FN => {
|
| KEYWORD_FN_PTR_CALL | KEYWORD_FN_PTR_CURRY => true,
|
||||||
true
|
|
||||||
}
|
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1529,8 +1520,7 @@ pub fn is_keyword_function(name: &str) -> bool {
|
|||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn can_override_keyword(name: &str) -> bool {
|
pub fn can_override_keyword(name: &str) -> bool {
|
||||||
match name {
|
match name {
|
||||||
KEYWORD_PRINT | KEYWORD_DEBUG | KEYWORD_TYPE_OF | KEYWORD_EVAL | KEYWORD_FN_PTR
|
KEYWORD_PRINT | KEYWORD_DEBUG | KEYWORD_TYPE_OF | KEYWORD_EVAL | KEYWORD_FN_PTR => true,
|
||||||
| KEYWORD_IS_DEF_VAR | KEYWORD_IS_DEF_FN => true,
|
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1658,39 +1648,41 @@ impl<'a> Iterator for TokenIterator<'a, '_> {
|
|||||||
Some((Token::Reserved(s), pos)) => Some((match
|
Some((Token::Reserved(s), pos)) => Some((match
|
||||||
(s.as_str(), self.engine.custom_keywords.contains_key(&s))
|
(s.as_str(), self.engine.custom_keywords.contains_key(&s))
|
||||||
{
|
{
|
||||||
("===", false) => Token::LexError(LERR::ImproperSymbol(
|
("===", false) => Token::LexError(LERR::ImproperSymbol(s,
|
||||||
"'===' is not a valid operator. This is not JavaScript! Should it be '=='?".to_string(),
|
"'===' is not a valid operator. This is not JavaScript! Should it be '=='?".to_string(),
|
||||||
)),
|
)),
|
||||||
("!==", false) => Token::LexError(LERR::ImproperSymbol(
|
("!==", false) => Token::LexError(LERR::ImproperSymbol(s,
|
||||||
"'!==' is not a valid operator. This is not JavaScript! Should it be '!='?".to_string(),
|
"'!==' is not a valid operator. This is not JavaScript! Should it be '!='?".to_string(),
|
||||||
)),
|
)),
|
||||||
("->", false) => Token::LexError(LERR::ImproperSymbol(
|
("->", false) => Token::LexError(LERR::ImproperSymbol(s,
|
||||||
"'->' is not a valid symbol. This is not C or C++!".to_string())),
|
"'->' is not a valid symbol. This is not C or C++!".to_string())),
|
||||||
("<-", false) => Token::LexError(LERR::ImproperSymbol(
|
("<-", false) => Token::LexError(LERR::ImproperSymbol(s,
|
||||||
"'<-' is not a valid symbol. This is not Go! Should it be '<='?".to_string(),
|
"'<-' is not a valid symbol. This is not Go! Should it be '<='?".to_string(),
|
||||||
)),
|
)),
|
||||||
(":=", false) => Token::LexError(LERR::ImproperSymbol(
|
(":=", false) => Token::LexError(LERR::ImproperSymbol(s,
|
||||||
"':=' is not a valid assignment operator. This is not Go! Should it be simply '='?".to_string(),
|
"':=' is not a valid assignment operator. This is not Go or Pascal! Should it be simply '='?".to_string(),
|
||||||
)),
|
)),
|
||||||
("::<", false) => Token::LexError(LERR::ImproperSymbol(
|
("::<", false) => Token::LexError(LERR::ImproperSymbol(s,
|
||||||
"'::<>' is not a valid symbol. This is not Rust! Should it be '::'?".to_string(),
|
"'::<>' is not a valid symbol. This is not Rust! Should it be '::'?".to_string(),
|
||||||
)),
|
)),
|
||||||
("(*", false) | ("*)", false) => Token::LexError(LERR::ImproperSymbol(
|
("(*", false) | ("*)", false) | ("begin", false) | ("end", false) => Token::LexError(LERR::ImproperSymbol(s,
|
||||||
"'(* .. *)' is not a valid comment format. This is not Pascal! Should it be '/* .. */'?".to_string(),
|
"'(* .. *)' is not a valid comment format. This is not Pascal! Should it be '/* .. */'?".to_string(),
|
||||||
)),
|
)),
|
||||||
("#", false) => Token::LexError(LERR::ImproperSymbol(
|
("#", false) => Token::LexError(LERR::ImproperSymbol(s,
|
||||||
"'#' is not a valid symbol. Should it be '#{'?".to_string(),
|
"'#' is not a valid symbol. Should it be '#{'?".to_string(),
|
||||||
)),
|
)),
|
||||||
// Reserved keyword/operator that is custom.
|
// Reserved keyword/operator that is custom.
|
||||||
(_, true) => Token::Custom(s),
|
(_, true) => Token::Custom(s),
|
||||||
// Reserved operator that is not custom.
|
// Reserved operator that is not custom.
|
||||||
(token, false) if !is_valid_identifier(token.chars()) => Token::LexError(LERR::ImproperSymbol(
|
(token, false) if !is_valid_identifier(token.chars()) => {
|
||||||
format!("'{}' is a reserved symbol", token)
|
let msg = format!("'{}' is a reserved symbol", token);
|
||||||
)),
|
Token::LexError(LERR::ImproperSymbol(s, msg))
|
||||||
|
},
|
||||||
// Reserved keyword that is not custom and disabled.
|
// Reserved keyword that is not custom and disabled.
|
||||||
(token, false) if self.engine.disabled_symbols.contains(token) => Token::LexError(LERR::ImproperSymbol(
|
(token, false) if self.engine.disabled_symbols.contains(token) => {
|
||||||
format!("reserved symbol '{}' is disabled", token)
|
let msg = format!("reserved symbol '{}' is disabled", token);
|
||||||
)),
|
Token::LexError(LERR::ImproperSymbol(s, msg))
|
||||||
|
},
|
||||||
// Reserved keyword/operator that is not custom.
|
// Reserved keyword/operator that is not custom.
|
||||||
(_, false) => Token::Reserved(s),
|
(_, false) => Token::Reserved(s),
|
||||||
}, pos)),
|
}, pos)),
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use rhai::{Engine, EvalAltResult, ParseErrorType, Scope, INT};
|
use rhai::{Engine, EvalAltResult, ParseErrorType, RegisterFn, Scope, INT};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_constant() -> Result<(), Box<EvalAltResult>> {
|
fn test_constant() -> Result<(), Box<EvalAltResult>> {
|
||||||
@ -62,3 +62,36 @@ fn test_var_is_def() -> Result<(), Box<EvalAltResult>> {
|
|||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(not(feature = "no_object"))]
|
||||||
|
#[test]
|
||||||
|
fn test_constant_mut() -> Result<(), Box<EvalAltResult>> {
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
struct TestStruct(INT); // custom type
|
||||||
|
|
||||||
|
let mut engine = Engine::new();
|
||||||
|
|
||||||
|
engine
|
||||||
|
.register_type_with_name::<TestStruct>("TestStruct")
|
||||||
|
.register_get("value", |obj: &mut TestStruct| obj.0)
|
||||||
|
.register_fn("update_value", |obj: &mut TestStruct, value: INT| {
|
||||||
|
obj.0 = value
|
||||||
|
});
|
||||||
|
|
||||||
|
let mut scope = Scope::new();
|
||||||
|
|
||||||
|
scope.push_constant("MY_NUMBER", TestStruct(123));
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
engine.eval_with_scope::<INT>(
|
||||||
|
&mut scope,
|
||||||
|
r"
|
||||||
|
MY_NUMBER.update_value(42);
|
||||||
|
MY_NUMBER.value
|
||||||
|
",
|
||||||
|
)?,
|
||||||
|
42
|
||||||
|
);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use rhai::{Engine, EvalAltResult, Scope, INT};
|
use rhai::{Engine, EvalAltResult, LexError, ParseErrorType, RegisterFn, Scope, INT};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_eval() -> Result<(), Box<EvalAltResult>> {
|
fn test_eval() -> Result<(), Box<EvalAltResult>> {
|
||||||
@ -98,10 +98,34 @@ fn test_eval_override() -> Result<(), Box<EvalAltResult>> {
|
|||||||
fn eval(x) { x } // reflect the script back
|
fn eval(x) { x } // reflect the script back
|
||||||
|
|
||||||
eval("40 + 2")
|
eval("40 + 2")
|
||||||
"#
|
"#
|
||||||
)?,
|
)?,
|
||||||
"40 + 2"
|
"40 + 2"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
let mut engine = Engine::new();
|
||||||
|
|
||||||
|
// Reflect the script back
|
||||||
|
engine.register_fn("eval", |script: &str| script.to_string());
|
||||||
|
|
||||||
|
assert_eq!(engine.eval::<String>(r#"eval("40 + 2")"#)?, "40 + 2");
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_eval_disabled() -> Result<(), Box<EvalAltResult>> {
|
||||||
|
let mut engine = Engine::new();
|
||||||
|
|
||||||
|
engine.disable_symbol("eval");
|
||||||
|
|
||||||
|
assert!(matches!(
|
||||||
|
*engine
|
||||||
|
.compile(r#"eval("40 + 2")"#)
|
||||||
|
.expect_err("should error")
|
||||||
|
.0,
|
||||||
|
ParseErrorType::BadInput(LexError::ImproperSymbol(err, _)) if err == "eval"
|
||||||
|
));
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -79,6 +79,7 @@ fn test_custom_syntax() -> Result<(), Box<EvalAltResult>> {
|
|||||||
.expect_err("should error")
|
.expect_err("should error")
|
||||||
.0,
|
.0,
|
||||||
ParseErrorType::BadInput(LexError::ImproperSymbol(
|
ParseErrorType::BadInput(LexError::ImproperSymbol(
|
||||||
|
"!".to_string(),
|
||||||
"Improper symbol for custom syntax at position #1: '!'".to_string()
|
"Improper symbol for custom syntax at position #1: '!'".to_string()
|
||||||
))
|
))
|
||||||
);
|
);
|
||||||
@ -100,6 +101,7 @@ fn test_custom_syntax_raw() -> Result<(), Box<EvalAltResult>> {
|
|||||||
s => Err(ParseError(
|
s => Err(ParseError(
|
||||||
Box::new(ParseErrorType::BadInput(LexError::ImproperSymbol(
|
Box::new(ParseErrorType::BadInput(LexError::ImproperSymbol(
|
||||||
s.to_string(),
|
s.to_string(),
|
||||||
|
"".to_string(),
|
||||||
))),
|
))),
|
||||||
Position::NONE,
|
Position::NONE,
|
||||||
)),
|
)),
|
||||||
@ -128,7 +130,7 @@ fn test_custom_syntax_raw() -> Result<(), Box<EvalAltResult>> {
|
|||||||
assert_eq!(engine.eval::<INT>("(hello kitty) + foo")?, 1041);
|
assert_eq!(engine.eval::<INT>("(hello kitty) + foo")?, 1041);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
*engine.compile("hello hey").expect_err("should error").0,
|
*engine.compile("hello hey").expect_err("should error").0,
|
||||||
ParseErrorType::BadInput(LexError::ImproperSymbol("hey".to_string()))
|
ParseErrorType::BadInput(LexError::ImproperSymbol("hey".to_string(), "".to_string()))
|
||||||
);
|
);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
Loading…
Reference in New Issue
Block a user