Minor fine tuning.

This commit is contained in:
Stephen Chung
2020-03-22 10:18:16 +08:00
parent f51864e190
commit b6320c0eef
8 changed files with 103 additions and 47 deletions

View File

@@ -50,8 +50,8 @@ impl<'e> Engine<'e> {
/// }
///
/// impl TestStruct {
/// fn new() -> Self { TestStruct { field: 1 } }
/// fn update(&mut self) { self.field += 41; }
/// fn new() -> Self { TestStruct { field: 1 } }
/// fn update(&mut self, offset: i64) { self.field += offset; }
/// }
///
/// # fn main() -> Result<(), rhai::EvalAltResult> {
@@ -64,11 +64,11 @@ impl<'e> Engine<'e> {
///
/// engine.register_fn("new_ts", TestStruct::new);
///
/// // Register method on the type.
/// // Use `register_fn` to register methods on the type.
/// engine.register_fn("update", TestStruct::update);
///
/// assert_eq!(
/// engine.eval::<TestStruct>("let x = new_ts(); x.update(); x")?.field,
/// engine.eval::<TestStruct>("let x = new_ts(); x.update(41); x")?.field,
/// 42
/// );
/// # Ok(())
@@ -138,6 +138,8 @@ impl<'e> Engine<'e> {
/// Register a getter function for a member of a registered type with the `Engine`.
///
/// The function signature must start with `&mut self` and not `&self`.
///
/// # Example
///
/// ```
@@ -148,6 +150,8 @@ impl<'e> Engine<'e> {
///
/// impl TestStruct {
/// fn new() -> Self { TestStruct { field: 1 } }
///
/// // Even a getter must start with `&mut self` and not `&self`.
/// fn get_field(&mut self) -> i64 { self.field }
/// }
///
@@ -222,6 +226,8 @@ impl<'e> Engine<'e> {
/// Shorthand for registering both getter and setter functions
/// of a registered type with the `Engine`.
///
/// All function signatures must start with `&mut self` and not `&self`.
///
/// # Example
///
/// ```
@@ -231,8 +237,9 @@ impl<'e> Engine<'e> {
/// }
///
/// impl TestStruct {
/// fn new() -> Self { TestStruct { field: 1 } }
/// fn new() -> Self { TestStruct { field: 1 } }
/// fn get_field(&mut self) -> i64 { self.field }
/// // Even a getter must start with `&mut self` and not `&self`.
/// fn set_field(&mut self, new_val: i64) { self.field = new_val; }
/// }
///

View File

@@ -3,6 +3,7 @@
#![allow(non_snake_case)]
use crate::any::{Any, Dynamic};
use crate::parser::INT;
#[cfg(not(feature = "no_index"))]
use crate::engine::Array;
@@ -36,11 +37,8 @@ impl_std_args!(Array);
#[cfg(not(feature = "only_i64"))]
impl_std_args!(u8, i8, u16, i16, u32, i32, u64, i64);
#[cfg(feature = "only_i32")]
impl_std_args!(i32);
#[cfg(feature = "only_i64")]
impl_std_args!(i64);
#[cfg(any(feature = "only_i32", feature = "only_i64"))]
impl_std_args!(INT);
#[cfg(not(feature = "no_float"))]
impl_std_args!(f32, f64);

View File

@@ -1,16 +1,13 @@
//! Main module defining the script evaluation `Engine`.
use crate::any::{Any, AnyExt, Dynamic, Variant};
use crate::parser::{Expr, FnDef, Position, ReturnType, Stmt};
use crate::parser::{Expr, FnDef, Position, ReturnType, Stmt, INT};
use crate::result::EvalAltResult;
use crate::scope::{Scope, ScopeSource, VariableType};
#[cfg(not(feature = "no_optimize"))]
use crate::optimize::OptimizationLevel;
#[cfg(not(feature = "no_index"))]
use crate::INT;
use crate::stdlib::{
any::{type_name, TypeId},
borrow::Cow,
@@ -1156,7 +1153,7 @@ impl Engine<'_> {
}
// If-else statement
Stmt::IfElse(guard, if_body, else_body) => self
Stmt::IfThenElse(guard, if_body, else_body) => self
.eval_expr(scope, guard)?
.downcast::<bool>()
.map_err(|_| EvalAltResult::ErrorLogicGuard(guard.position()))

View File

@@ -79,7 +79,7 @@ impl State<'_> {
fn optimize_stmt<'a>(stmt: Stmt, state: &mut State<'a>, preserve_result: bool) -> Stmt {
match stmt {
// if expr { Noop }
Stmt::IfElse(expr, if_block, None) if matches!(*if_block, Stmt::Noop(_)) => {
Stmt::IfThenElse(expr, if_block, None) if matches!(*if_block, Stmt::Noop(_)) => {
state.set_dirty();
let pos = expr.position();
@@ -94,7 +94,7 @@ fn optimize_stmt<'a>(stmt: Stmt, state: &mut State<'a>, preserve_result: bool) -
}
}
// if expr { if_block }
Stmt::IfElse(expr, if_block, None) => match *expr {
Stmt::IfThenElse(expr, if_block, None) => match *expr {
// if false { if_block } -> Noop
Expr::False(pos) => {
state.set_dirty();
@@ -103,20 +103,20 @@ fn optimize_stmt<'a>(stmt: Stmt, state: &mut State<'a>, preserve_result: bool) -
// if true { if_block } -> if_block
Expr::True(_) => optimize_stmt(*if_block, state, true),
// if expr { if_block }
expr => Stmt::IfElse(
expr => Stmt::IfThenElse(
Box::new(optimize_expr(expr, state)),
Box::new(optimize_stmt(*if_block, state, true)),
None,
),
},
// if expr { if_block } else { else_block }
Stmt::IfElse(expr, if_block, Some(else_block)) => match *expr {
Stmt::IfThenElse(expr, if_block, Some(else_block)) => match *expr {
// if false { if_block } else { else_block } -> else_block
Expr::False(_) => optimize_stmt(*else_block, state, true),
// if true { if_block } else { else_block } -> if_block
Expr::True(_) => optimize_stmt(*if_block, state, true),
// if expr { if_block } else { else_block }
expr => Stmt::IfElse(
expr => Stmt::IfThenElse(
Box::new(optimize_expr(expr, state)),
Box::new(optimize_stmt(*if_block, state, true)),
match optimize_stmt(*else_block, state, true) {
@@ -584,8 +584,9 @@ pub fn optimize_into_ast(
AST(
match engine.optimization_level {
OptimizationLevel::None => statements,
OptimizationLevel::Simple => optimize(statements, engine, &scope),
OptimizationLevel::Full => optimize(statements, engine, &scope),
OptimizationLevel::Simple | OptimizationLevel::Full => {
optimize(statements, engine, &scope)
}
},
functions
.into_iter()

View File

@@ -204,7 +204,7 @@ pub enum Stmt {
/// No-op.
Noop(Position),
/// if expr { stmt } else { stmt }
IfElse(Box<Expr>, Box<Stmt>, Option<Box<Stmt>>),
IfThenElse(Box<Expr>, Box<Stmt>, Option<Box<Stmt>>),
/// while expr { stmt }
While(Box<Expr>, Box<Stmt>),
/// loop { stmt }
@@ -235,7 +235,7 @@ impl Stmt {
| Stmt::Block(_, pos)
| Stmt::Break(pos)
| Stmt::ReturnWithVal(_, _, pos) => *pos,
Stmt::IfElse(expr, _, _) | Stmt::Expr(expr) => expr.position(),
Stmt::IfThenElse(expr, _, _) | Stmt::Expr(expr) => expr.position(),
Stmt::While(_, stmt) | Stmt::Loop(stmt) | Stmt::For(_, _, stmt) => stmt.position(),
}
}
@@ -243,7 +243,7 @@ impl Stmt {
/// Is this statement self-terminated (i.e. no need for a semicolon terminator)?
pub fn is_self_terminated(&self) -> bool {
match self {
Stmt::IfElse(_, _, _)
Stmt::IfThenElse(_, _, _)
| Stmt::While(_, _)
| Stmt::Loop(_)
| Stmt::For(_, _, _)
@@ -265,10 +265,10 @@ impl Stmt {
match self {
Stmt::Noop(_) => true,
Stmt::Expr(expr) => expr.is_pure(),
Stmt::IfElse(guard, if_block, Some(else_block)) => {
Stmt::IfThenElse(guard, if_block, Some(else_block)) => {
guard.is_pure() && if_block.is_pure() && else_block.is_pure()
}
Stmt::IfElse(guard, block, None) | Stmt::While(guard, block) => {
Stmt::IfThenElse(guard, block, None) | Stmt::While(guard, block) => {
guard.is_pure() && block.is_pure()
}
Stmt::Loop(block) => block.is_pure(),
@@ -2020,7 +2020,11 @@ fn parse_if<'a>(
None
};
Ok(Stmt::IfElse(Box::new(guard), Box::new(if_body), else_body))
Ok(Stmt::IfThenElse(
Box::new(guard),
Box::new(if_body),
else_body,
))
}
/// Parse a while loop.