Add more range API's.

This commit is contained in:
Stephen Chung 2021-12-15 22:12:51 +08:00
parent 59a9ff0b0f
commit abbfa3777d
5 changed files with 42 additions and 28 deletions

View File

@ -5,6 +5,7 @@ Version 1.4.0
=============
This version adds support for integer _ranges_ via the `..` and `..=` operators.
Many standard API's are extended with range parameters where appropriate.
New features
------------

View File

@ -1057,6 +1057,12 @@ impl StmtBlock {
pub fn len(&self) -> usize {
self.0.len()
}
/// Get the statements of this statements block.
#[inline(always)]
#[must_use]
pub fn statements(&self) -> &[Stmt] {
&self.0
}
/// Get the position (location of the beginning `{`) of this statements block.
#[inline(always)]
#[must_use]

View File

@ -471,11 +471,6 @@ fn optimize_stmt(stmt: &mut Stmt, state: &mut OptimizerState, preserve_result: b
// switch const { case if condition => stmt, _ => def } => if condition { stmt } else { def }
optimize_expr(&mut condition, state, false);
let def_pos = if x.1.position().is_none() {
*pos
} else {
x.1.position()
};
let def_stmt =
optimize_stmt_block(mem::take(&mut *x.1), state, true, true, false);
@ -483,16 +478,16 @@ fn optimize_stmt(stmt: &mut Stmt, state: &mut OptimizerState, preserve_result: b
condition,
Box::new((
mem::take(&mut block.1),
Stmt::Block(def_stmt.into_boxed_slice(), def_pos).into(),
Stmt::Block(def_stmt.into_boxed_slice(), x.1.position().or_else(*pos))
.into(),
)),
match_expr.position(),
);
} else {
// Promote the matched case
let new_pos = block.1.position();
let statements =
optimize_stmt_block(mem::take(&mut *block.1), state, true, true, false);
*stmt = Stmt::Block(statements.into_boxed_slice(), new_pos);
*stmt = Stmt::Block(statements.into_boxed_slice(), block.1.position());
}
state.set_dirty();
@ -519,29 +514,27 @@ fn optimize_stmt(stmt: &mut Stmt, state: &mut OptimizerState, preserve_result: b
// switch const { range if condition => stmt, _ => def } => if condition { stmt } else { def }
optimize_expr(&mut condition, state, false);
let def_block = mem::take(&mut *x.1);
let def_stmt = optimize_stmt_block(def_block, state, true, true, false);
let def_pos = if x.1.position().is_none() {
*pos
} else {
x.1.position()
};
let def_stmt =
optimize_stmt_block(mem::take(&mut *x.1), state, true, true, false);
*stmt = Stmt::If(
condition,
Box::new((
mem::take(stmt_block),
Stmt::Block(def_stmt.into_boxed_slice(), def_pos).into(),
Stmt::Block(
def_stmt.into_boxed_slice(),
x.1.position().or_else(*pos),
)
.into(),
)),
match_expr.position(),
);
} else {
// Promote the matched case
let new_pos = stmt_block.position();
let statements = mem::take(&mut **stmt_block);
let statements =
optimize_stmt_block(statements, state, true, true, false);
*stmt = Stmt::Block(statements.into_boxed_slice(), new_pos);
*stmt =
Stmt::Block(statements.into_boxed_slice(), stmt_block.position());
}
state.set_dirty();
@ -551,10 +544,9 @@ fn optimize_stmt(stmt: &mut Stmt, state: &mut OptimizerState, preserve_result: b
// Multiple ranges - clear the table and just keep the right ranges
if !table.is_empty() {
state.set_dirty();
table.clear();
}
table.clear();
let old_ranges_len = ranges.len();
ranges.retain(|&mut (start, end, inclusive, _, _)| {
@ -585,13 +577,8 @@ fn optimize_stmt(stmt: &mut Stmt, state: &mut OptimizerState, preserve_result: b
// Promote the default case
state.set_dirty();
let def_pos = if x.1.position().is_none() {
*pos
} else {
x.1.position()
};
let def_stmt = optimize_stmt_block(mem::take(&mut *x.1), state, true, true, false);
*stmt = Stmt::Block(def_stmt.into_boxed_slice(), def_pos);
*stmt = Stmt::Block(def_stmt.into_boxed_slice(), x.1.position().or_else(*pos));
}
// switch
Stmt::Switch(match_expr, x, _) => {

View File

@ -542,10 +542,15 @@ mod range_functions {
range.contains(&value)
}
#[rhai_fn(get = "is_inclusive", name = "is_inclusive", pure)]
pub fn range_is_inclusive(range: &mut ExclusiveRange) -> bool {
pub fn is_inclusive(range: &mut ExclusiveRange) -> bool {
let _range = range;
false
}
#[rhai_fn(get = "is_exclusive", name = "is_exclusive", pure)]
pub fn is_exclusive(range: &mut ExclusiveRange) -> bool {
let _range = range;
true
}
#[rhai_fn(get = "is_empty", name = "is_empty", pure)]
pub fn is_empty(range: &mut ExclusiveRange) -> bool {
range.is_empty()
@ -571,4 +576,9 @@ mod range_functions {
let _range = range;
true
}
#[rhai_fn(get = "is_exclusive", name = "is_exclusive", pure)]
pub fn is_exclusive_inclusive(range: &mut InclusiveRange) -> bool {
let _range = range;
false
}
}

View File

@ -213,6 +213,16 @@ impl Position {
#[cfg(feature = "no_position")]
return true;
}
/// Returns an fallback [`Position`] if it is [`NONE`][Position::NONE]?
#[inline]
#[must_use]
pub const fn or_else(self, pos: Self) -> Self {
if self.is_none() {
pos
} else {
self
}
}
/// Print this [`Position`] for debug purposes.
#[inline]
pub(crate) fn debug_print(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result {