Split no_stdlib and no_std into two features.

This commit is contained in:
Stephen Chung 2020-03-18 12:04:26 +08:00
commit a9c65a962c
11 changed files with 49 additions and 30 deletions

View File

@ -7,7 +7,7 @@ cargo test --verbose
if [ "$TRAVIS_RUST_VERSION" = "nightly" ]
then
cargo build --verbose --features no_stdlib
cargo test --verbose --features no_stdlib
cargo build --verbose --features no_std
cargo test --verbose --features no_std
fi

View File

@ -23,6 +23,7 @@ num-traits = "0.2.11"
default = [ "optimize_full" ]
debug_msgs = [] # print debug messages on function registrations and calls
unchecked = [] # unchecked arithmetic
no_stdlib = [] # no standard library of utility functions
no_index = [] # no arrays and indexing
no_float = [] # no floating-point
no_function = [] # no script-defined functions
@ -31,13 +32,13 @@ optimize_full = [] # set optimization level to Full (default is Simple)
only_i32 = [] # set INT=i32 (useful for 32-bit systems)
only_i64 = [] # set INT=i64 (default) and disable support for all other integer types
# no standard library of utility functions
no_stdlib = [ "num-traits/libm", "hashbrown", "core-error", "libm" ]
# compiling for no-std
no_std = [ "num-traits/libm", "hashbrown", "core-error", "libm" ]
[profile.release]
lto = "fat"
codegen-units = 1
#opt-level = "z" # optimize for size
opt-level = "z" # optimize for size
[dependencies.libm]
version = "0.2.1"

13
examples/no_std.rs Normal file
View File

@ -0,0 +1,13 @@
#![cfg_attr(feature = "no_std", no_std)]
use rhai::{Engine, EvalAltResult};
fn main() -> Result<(), EvalAltResult> {
let mut engine = Engine::new();
let result = engine.eval::<i64>("40 + 2")?;
assert_eq!(result, 42);
Ok(())
}

View File

@ -19,7 +19,7 @@ use crate::stdlib::{
sync::Arc,
vec::Vec,
};
#[cfg(not(feature = "no_stdlib"))]
#[cfg(not(feature = "no_std"))]
use crate::stdlib::{fs::File, io::prelude::*, path::PathBuf};
impl<'e> Engine<'e> {
@ -117,7 +117,7 @@ impl<'e> Engine<'e> {
parse(&mut tokens_stream.peekable(), self, scope)
}
#[cfg(not(feature = "no_stdlib"))]
#[cfg(not(feature = "no_std"))]
fn read_file(path: PathBuf) -> Result<String, EvalAltResult> {
let mut f = File::open(path.clone())
.map_err(|err| EvalAltResult::ErrorReadingScriptFile(path.clone(), err))?;
@ -130,14 +130,14 @@ impl<'e> Engine<'e> {
}
/// Compile a file into an AST.
#[cfg(not(feature = "no_stdlib"))]
#[cfg(not(feature = "no_std"))]
pub fn compile_file(&self, path: PathBuf) -> Result<AST, EvalAltResult> {
self.compile_file_with_scope(&Scope::new(), path)
}
/// Compile a file into an AST using own scope.
/// The scope is useful for passing constants into the script for optimization.
#[cfg(not(feature = "no_stdlib"))]
#[cfg(not(feature = "no_std"))]
pub fn compile_file_with_scope(
&self,
scope: &Scope,
@ -150,13 +150,13 @@ impl<'e> Engine<'e> {
}
/// Evaluate a file.
#[cfg(not(feature = "no_stdlib"))]
#[cfg(not(feature = "no_std"))]
pub fn eval_file<T: Any + Clone>(&mut self, path: PathBuf) -> Result<T, EvalAltResult> {
Self::read_file(path).and_then(|contents| self.eval::<T>(&contents))
}
/// Evaluate a file with own scope.
#[cfg(not(feature = "no_stdlib"))]
#[cfg(not(feature = "no_std"))]
pub fn eval_file_with_scope<T: Any + Clone>(
&mut self,
scope: &mut Scope,
@ -237,7 +237,7 @@ impl<'e> Engine<'e> {
///
/// Note - if `retain_functions` is set to `true`, functions defined by previous scripts are _retained_
/// and not cleared from run to run.
#[cfg(not(feature = "no_stdlib"))]
#[cfg(not(feature = "no_std"))]
pub fn consume_file(
&mut self,
retain_functions: bool,
@ -251,7 +251,7 @@ impl<'e> Engine<'e> {
///
/// Note - if `retain_functions` is set to `true`, functions defined by previous scripts are _retained_
/// and not cleared from run to run.
#[cfg(not(feature = "no_stdlib"))]
#[cfg(not(feature = "no_std"))]
pub fn consume_file_with_scope(
&mut self,
scope: &mut Scope,

View File

@ -2,13 +2,14 @@
//! _standard library_ of utility functions.
use crate::any::Any;
#[cfg(not(feature = "no_index"))]
use crate::engine::Array;
use crate::engine::Engine;
use crate::fn_register::{RegisterDynamicFn, RegisterFn, RegisterResultFn};
use crate::parser::{Position, INT};
use crate::result::EvalAltResult;
#[cfg(not(feature = "no_index"))]
use crate::engine::Array;
#[cfg(not(feature = "no_float"))]
use crate::parser::FLOAT;
@ -23,6 +24,7 @@ use crate::stdlib::{
format,
ops::{Add, BitAnd, BitOr, BitXor, Div, Mul, Neg, Range, Rem, Shl, Shr, Sub},
string::{String, ToString},
vec::Vec,
{i32, i64, u32},
};
@ -645,7 +647,6 @@ impl Engine<'_> {
}
}
#[cfg(not(feature = "no_stdlib"))]
macro_rules! reg_fn2x {
($self:expr, $x:expr, $op:expr, $v:ty, $r:ty, $( $y:ty ),*) => (
$(
@ -654,7 +655,6 @@ macro_rules! reg_fn2x {
)
}
#[cfg(not(feature = "no_stdlib"))]
macro_rules! reg_fn2y {
($self:expr, $x:expr, $op:expr, $v:ty, $r:ty, $( $y:ty ),*) => (
$(

View File

@ -1,5 +1,7 @@
//! Helper module which defines `FnArgs` to make function calling easier.
#![allow(non_snake_case)]
use crate::any::{Any, Dynamic};
use crate::stdlib::{string::String, vec, vec::Vec};

View File

@ -1182,11 +1182,12 @@ 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(feature = "no_stdlib")]
#[cfg(any(feature = "no_std", feature = "no_stdlib"))]
fn default_print(_: &str) {}

View File

@ -1,5 +1,7 @@
//! Module which defines the function registration mechanism.
#![allow(non_snake_case)]
use crate::any::{Any, Dynamic};
use crate::engine::{Engine, FnCallArgs};
use crate::parser::Position;

View File

@ -16,7 +16,7 @@
//!
//! And the Rust part:
//!
//! ```rust,ignore
//! ```rust,no_run
//! use rhai::{Engine, EvalAltResult, RegisterFn};
//!
//! fn main() -> Result<(), EvalAltResult>
@ -29,6 +29,7 @@
//!
//! engine.register_fn("compute_something", compute_something);
//!
//! # #[cfg(not(feature = "no_std"))]
//! assert_eq!(engine.eval_file::<bool>("my_script.rhai".into())?, true);
//!
//! Ok(())
@ -37,10 +38,9 @@
//!
//! [Check out the README on GitHub for more information!](https://github.com/jonathandturner/rhai)
#![cfg_attr(feature = "no_stdlib", no_std)]
#![allow(non_snake_case)]
#![cfg_attr(feature = "no_std", no_std)]
#[cfg(feature = "no_stdlib")]
#[cfg(feature = "no_std")]
extern crate alloc;
// needs to be here, because order matters for macros

View File

@ -10,7 +10,7 @@ use crate::stdlib::{
string::{String, ToString},
};
#[cfg(not(feature = "no_stdlib"))]
#[cfg(not(feature = "no_std"))]
use crate::stdlib::path::PathBuf;
/// Evaluation result.
@ -54,7 +54,7 @@ pub enum EvalAltResult {
/// Wrapped value is the type of the actual result.
ErrorMismatchOutputType(String, Position),
/// Error reading from a script file. Wrapped value is the path of the script file.
#[cfg(not(feature = "no_stdlib"))]
#[cfg(not(feature = "no_std"))]
ErrorReadingScriptFile(PathBuf, std::io::Error),
/// Inappropriate member access.
ErrorDotExpr(String, Position),
@ -101,7 +101,7 @@ impl EvalAltResult {
}
Self::ErrorAssignmentToConstant(_, _) => "Assignment to a constant variable",
Self::ErrorMismatchOutputType(_, _) => "Output type is incorrect",
#[cfg(not(feature = "no_stdlib"))]
#[cfg(not(feature = "no_std"))]
Self::ErrorReadingScriptFile(_, _) => "Cannot read from script file",
Self::ErrorDotExpr(_, _) => "Malformed dot expression",
Self::ErrorArithmetic(_, _) => "Arithmetic error",
@ -136,7 +136,7 @@ impl fmt::Display for EvalAltResult {
}
Self::ErrorLoopBreak(pos) => write!(f, "{} ({})", desc, pos),
Self::Return(_, pos) => write!(f, "{} ({})", desc, pos),
#[cfg(not(feature = "no_stdlib"))]
#[cfg(not(feature = "no_std"))]
Self::ErrorReadingScriptFile(path, err) => {
write!(f, "{} '{}': {}", desc, path.display(), err)
}
@ -209,7 +209,7 @@ impl<T: AsRef<str>> From<T> for EvalAltResult {
impl EvalAltResult {
pub fn position(&self) -> Position {
match self {
#[cfg(not(feature = "no_stdlib"))]
#[cfg(not(feature = "no_std"))]
Self::ErrorReadingScriptFile(_, _) => Position::none(),
Self::ErrorParsing(err) => err.position(),
@ -238,7 +238,7 @@ impl EvalAltResult {
pub(crate) fn set_position(&mut self, new_position: Position) {
match self {
#[cfg(not(feature = "no_stdlib"))]
#[cfg(not(feature = "no_std"))]
Self::ErrorReadingScriptFile(_, _) => (),
Self::ErrorParsing(ParseError(_, ref mut pos))

View File

@ -1,6 +1,6 @@
//! Helper module which defines most of the needed features from `std` for `no-std` builds.
#[cfg(feature = "no_stdlib")]
#[cfg(feature = "no_std")]
mod inner {
pub use core::{
any, arch, array, ascii, cell, char, clone, cmp, convert, default, f32, f64, ffi, fmt,
@ -17,7 +17,7 @@ mod inner {
}
}
#[cfg(not(feature = "no_stdlib"))]
#[cfg(not(feature = "no_std"))]
mod inner {
pub use std::*;
}