Remove no_stdlib feature in favor of Engine::new_raw().

This commit is contained in:
Stephen Chung
2020-04-08 10:19:03 +08:00
parent e0bb2e5c97
commit bcff6bfd71
12 changed files with 191 additions and 136 deletions

View File

@@ -387,8 +387,30 @@ impl<'e> Engine<'e> {
/// # }
/// ```
pub fn compile_with_scope(&self, scope: &Scope, input: &str) -> Result<AST, ParseError> {
self.compile_with_scope_and_optimization_level(
scope,
input,
#[cfg(not(feature = "no_optimize"))]
self.optimization_level,
)
}
/// Compile a string into an `AST` using own scope at a specific optimization level.
pub(crate) fn compile_with_scope_and_optimization_level(
&self,
scope: &Scope,
input: &str,
#[cfg(not(feature = "no_optimize"))] optimization_level: OptimizationLevel,
) -> Result<AST, ParseError> {
let tokens_stream = lex(input);
parse(&mut tokens_stream.peekable(), self, scope)
parse(
&mut tokens_stream.peekable(),
self,
scope,
#[cfg(not(feature = "no_optimize"))]
optimization_level,
)
}
/// Read the contents of a file into a string.
@@ -800,8 +822,14 @@ impl<'e> Engine<'e> {
pub fn consume_with_scope(&self, scope: &mut Scope, input: &str) -> Result<(), EvalAltResult> {
let tokens_stream = lex(input);
let ast = parse(&mut tokens_stream.peekable(), self, scope)
.map_err(EvalAltResult::ErrorParsing)?;
let ast = parse(
&mut tokens_stream.peekable(),
self,
scope,
#[cfg(not(feature = "no_optimize"))]
self.optimization_level,
)
.map_err(EvalAltResult::ErrorParsing)?;
self.consume_ast_with_scope(scope, &ast)
}
@@ -837,7 +865,6 @@ impl<'e> Engine<'e> {
///
/// ```
/// # fn main() -> Result<(), rhai::EvalAltResult> {
/// # #[cfg(not(feature = "no_stdlib"))]
/// # #[cfg(not(feature = "no_function"))]
/// # {
/// use rhai::{Engine, Scope};

View File

@@ -757,8 +757,7 @@ macro_rules! reg_fn2y {
/// Register the built-in library.
impl Engine<'_> {
#[cfg(not(feature = "no_stdlib"))]
pub(crate) fn register_stdlib(&mut self) {
pub fn register_stdlib(&mut self) {
#[cfg(not(feature = "no_float"))]
{
// Advanced math functions

View File

@@ -283,28 +283,25 @@ pub struct Engine<'e> {
impl Default for Engine<'_> {
fn default() -> Self {
// User-friendly names for built-in types
let type_names = [
#[cfg(not(feature = "no_index"))]
(type_name::<Array>(), "array"),
#[cfg(not(feature = "no_object"))]
(type_name::<Map>(), "map"),
(type_name::<String>(), "string"),
(type_name::<Dynamic>(), "dynamic"),
(type_name::<Variant>(), "variant"),
]
.iter()
.map(|(k, v)| (k.to_string(), v.to_string()))
.collect();
// Create the new scripting Engine
let mut engine = Engine {
functions: None,
type_iterators: None,
type_names: Some(type_names),
on_print: Some(Box::new(default_print)), // default print/debug implementations
type_names: None,
// default print/debug implementations
#[cfg(not(feature = "no_std"))]
on_print: Some(Box::new(default_print)),
#[cfg(not(feature = "no_std"))]
on_debug: Some(Box::new(default_print)),
// default print/debug implementations
#[cfg(feature = "no_std")]
on_print: None,
#[cfg(feature = "no_std")]
on_debug: None,
// optimization level
#[cfg(not(feature = "no_optimize"))]
#[cfg(not(feature = "optimize_full"))]
optimization_level: OptimizationLevel::Simple,
@@ -316,10 +313,11 @@ impl Default for Engine<'_> {
max_call_stack_depth: MAX_CALL_STACK_DEPTH,
};
engine.fill_type_names();
engine.register_core_lib();
#[cfg(not(feature = "no_stdlib"))]
engine.register_stdlib(); // Register the standard library when no_stdlib is not set
engine.register_stdlib();
engine
}
@@ -354,6 +352,24 @@ fn extract_prop_from_setter(fn_name: &str) -> Option<&str> {
}
impl Engine<'_> {
fn fill_type_names(&mut self) {
// User-friendly names for built-in types
self.type_names = Some(
[
#[cfg(not(feature = "no_index"))]
(type_name::<Array>(), "array"),
#[cfg(not(feature = "no_object"))]
(type_name::<Map>(), "map"),
(type_name::<String>(), "string"),
(type_name::<Dynamic>(), "dynamic"),
(type_name::<Variant>(), "variant"),
]
.iter()
.map(|(k, v)| (k.to_string(), v.to_string()))
.collect(),
);
}
/// Create a new `Engine`
pub fn new() -> Self {
// fn abc<F: Fn() + Send + Sync>(f: F) {
@@ -364,7 +380,7 @@ impl Engine<'_> {
Default::default()
}
/// Create a new `Engine` with minimal configurations - i.e. without pretty-print type names etc.
/// Create a new `Engine` with minimal configurations without the standard library etc.
pub fn new_raw() -> Self {
let mut engine = Engine {
functions: None,
@@ -384,11 +400,9 @@ impl Engine<'_> {
max_call_stack_depth: MAX_CALL_STACK_DEPTH,
};
engine.fill_type_names();
engine.register_core_lib();
#[cfg(not(feature = "no_stdlib"))]
engine.register_stdlib(); // Register the standard library when no_stdlib is not set
engine
}
@@ -1487,13 +1501,24 @@ impl Engine<'_> {
})?;
// Compile the script text
let mut ast = self.compile(script).map_err(EvalAltResult::ErrorParsing)?;
// No optimizations because we only run it once
let mut ast = self
.compile_with_scope_and_optimization_level(
&Scope::new(),
script,
#[cfg(not(feature = "no_optimize"))]
OptimizationLevel::None,
)
.map_err(EvalAltResult::ErrorParsing)?;
// If new functions are defined within the eval string, it is an error
if ast.1.len() > 0 {
return Err(EvalAltResult::ErrorParsing(
ParseErrorType::WrongFnDefinition.into_err(pos),
));
#[cfg(not(feature = "no_function"))]
{
if ast.1.len() > 0 {
return Err(EvalAltResult::ErrorParsing(
ParseErrorType::WrongFnDefinition.into_err(pos),
));
}
}
if let Some(lib) = fn_lib {
@@ -1760,11 +1785,6 @@ impl Engine<'_> {
/// Print/debug to stdout
#[cfg(not(feature = "no_std"))]
#[cfg(not(feature = "no_stdlib"))]
fn default_print(s: &str) {
println!("{}", s);
}
/// No-op
#[cfg(any(feature = "no_std", feature = "no_stdlib"))]
fn default_print(_: &str) {}

View File

@@ -40,7 +40,6 @@
//!
//! | Feature | Description |
//! | ------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
//! | `no_stdlib` | Exclude the standard library of utility functions in the build, and only include the minimum necessary functionalities. Standard types are not affected. |
//! | `unchecked` | Exclude arithmetic checking (such as overflows and division by zero). Beware that a bad script may panic the entire system! |
//! | `no_function` | Disable script-defined functions if not needed. |
//! | `no_index` | Disable arrays and indexing features if not needed. |

View File

@@ -6,7 +6,7 @@ use crate::error::{LexError, ParseError, ParseErrorType};
use crate::scope::{EntryType as ScopeEntryType, Scope};
#[cfg(not(feature = "no_optimize"))]
use crate::optimize::optimize_into_ast;
use crate::optimize::{optimize_into_ast, OptimizationLevel};
use crate::stdlib::{
borrow::Cow,
@@ -2866,19 +2866,14 @@ pub fn parse<'a, 'e>(
input: &mut Peekable<TokenIterator<'a>>,
engine: &Engine<'e>,
scope: &Scope,
#[cfg(not(feature = "no_optimize"))] optimization_level: OptimizationLevel,
) -> Result<AST, ParseError> {
let (statements, functions) = parse_global_level(input)?;
Ok(
// Optimize AST
#[cfg(not(feature = "no_optimize"))]
optimize_into_ast(
engine,
scope,
statements,
functions,
engine.optimization_level,
),
optimize_into_ast(engine, scope, statements, functions, optimization_level),
//
// Do not optimize AST if `no_optimize`
#[cfg(feature = "no_optimize")]