Add more range API's.
This commit is contained in:
parent
59a9ff0b0f
commit
abbfa3777d
@ -5,6 +5,7 @@ Version 1.4.0
|
|||||||
=============
|
=============
|
||||||
|
|
||||||
This version adds support for integer _ranges_ via the `..` and `..=` operators.
|
This version adds support for integer _ranges_ via the `..` and `..=` operators.
|
||||||
|
Many standard API's are extended with range parameters where appropriate.
|
||||||
|
|
||||||
New features
|
New features
|
||||||
------------
|
------------
|
||||||
|
@ -1057,6 +1057,12 @@ impl StmtBlock {
|
|||||||
pub fn len(&self) -> usize {
|
pub fn len(&self) -> usize {
|
||||||
self.0.len()
|
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.
|
/// Get the position (location of the beginning `{`) of this statements block.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
|
@ -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 }
|
// switch const { case if condition => stmt, _ => def } => if condition { stmt } else { def }
|
||||||
optimize_expr(&mut condition, state, false);
|
optimize_expr(&mut condition, state, false);
|
||||||
|
|
||||||
let def_pos = if x.1.position().is_none() {
|
|
||||||
*pos
|
|
||||||
} else {
|
|
||||||
x.1.position()
|
|
||||||
};
|
|
||||||
let def_stmt =
|
let def_stmt =
|
||||||
optimize_stmt_block(mem::take(&mut *x.1), state, true, true, false);
|
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,
|
condition,
|
||||||
Box::new((
|
Box::new((
|
||||||
mem::take(&mut block.1),
|
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(),
|
match_expr.position(),
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
// Promote the matched case
|
// Promote the matched case
|
||||||
let new_pos = block.1.position();
|
|
||||||
let statements =
|
let statements =
|
||||||
optimize_stmt_block(mem::take(&mut *block.1), state, true, true, false);
|
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();
|
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 }
|
// switch const { range if condition => stmt, _ => def } => if condition { stmt } else { def }
|
||||||
optimize_expr(&mut condition, state, false);
|
optimize_expr(&mut condition, state, false);
|
||||||
|
|
||||||
let def_block = mem::take(&mut *x.1);
|
let def_stmt =
|
||||||
let def_stmt = optimize_stmt_block(def_block, state, true, true, false);
|
optimize_stmt_block(mem::take(&mut *x.1), state, true, true, false);
|
||||||
let def_pos = if x.1.position().is_none() {
|
|
||||||
*pos
|
|
||||||
} else {
|
|
||||||
x.1.position()
|
|
||||||
};
|
|
||||||
|
|
||||||
*stmt = Stmt::If(
|
*stmt = Stmt::If(
|
||||||
condition,
|
condition,
|
||||||
Box::new((
|
Box::new((
|
||||||
mem::take(stmt_block),
|
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(),
|
match_expr.position(),
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
// Promote the matched case
|
// Promote the matched case
|
||||||
let new_pos = stmt_block.position();
|
|
||||||
let statements = mem::take(&mut **stmt_block);
|
let statements = mem::take(&mut **stmt_block);
|
||||||
let statements =
|
let statements =
|
||||||
optimize_stmt_block(statements, state, true, true, false);
|
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();
|
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
|
// Multiple ranges - clear the table and just keep the right ranges
|
||||||
if !table.is_empty() {
|
if !table.is_empty() {
|
||||||
state.set_dirty();
|
state.set_dirty();
|
||||||
|
table.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
table.clear();
|
|
||||||
|
|
||||||
let old_ranges_len = ranges.len();
|
let old_ranges_len = ranges.len();
|
||||||
|
|
||||||
ranges.retain(|&mut (start, end, inclusive, _, _)| {
|
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
|
// Promote the default case
|
||||||
state.set_dirty();
|
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);
|
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
|
// switch
|
||||||
Stmt::Switch(match_expr, x, _) => {
|
Stmt::Switch(match_expr, x, _) => {
|
||||||
|
@ -542,10 +542,15 @@ mod range_functions {
|
|||||||
range.contains(&value)
|
range.contains(&value)
|
||||||
}
|
}
|
||||||
#[rhai_fn(get = "is_inclusive", name = "is_inclusive", pure)]
|
#[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;
|
let _range = range;
|
||||||
false
|
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)]
|
#[rhai_fn(get = "is_empty", name = "is_empty", pure)]
|
||||||
pub fn is_empty(range: &mut ExclusiveRange) -> bool {
|
pub fn is_empty(range: &mut ExclusiveRange) -> bool {
|
||||||
range.is_empty()
|
range.is_empty()
|
||||||
@ -571,4 +576,9 @@ mod range_functions {
|
|||||||
let _range = range;
|
let _range = range;
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
#[rhai_fn(get = "is_exclusive", name = "is_exclusive", pure)]
|
||||||
|
pub fn is_exclusive_inclusive(range: &mut InclusiveRange) -> bool {
|
||||||
|
let _range = range;
|
||||||
|
false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -213,6 +213,16 @@ impl Position {
|
|||||||
#[cfg(feature = "no_position")]
|
#[cfg(feature = "no_position")]
|
||||||
return true;
|
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.
|
/// Print this [`Position`] for debug purposes.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub(crate) fn debug_print(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
pub(crate) fn debug_print(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
Loading…
Reference in New Issue
Block a user