Add version to repl.

This commit is contained in:
Stephen Chung 2021-04-21 17:39:45 +08:00
parent 956c57e9d6
commit cc546fcaab
2 changed files with 80 additions and 77 deletions

View File

@ -55,8 +55,9 @@ fn print_help() {
}
fn main() {
println!("Rhai REPL tool");
println!("==============");
let title = format!("Rhai REPL tool (version {})", env!("CARGO_PKG_VERSION"));
println!("{}", title);
println!("{0:=<1$}", "", title.len());
print_help();
// Initialize scripting engine

View File

@ -574,6 +574,7 @@ impl State {
self.scope_level == 0
}
/// Get a mutable reference to the current function resolution cache.
#[inline(always)]
pub fn fn_resolution_cache_mut(&mut self) -> &mut FnResolutionCache {
if self.fn_resolution_caches.0.is_empty() {
self.fn_resolution_caches.0.push(BTreeMap::new());
@ -582,6 +583,7 @@ impl State {
}
/// Push an empty function resolution cache onto the stack and make it current.
#[allow(dead_code)]
#[inline(always)]
pub fn push_fn_resolution_cache(&mut self) {
self.fn_resolution_caches
.0
@ -592,6 +594,7 @@ impl State {
/// # Panics
///
/// Panics if there are no more function resolution cache in the stack.
#[inline(always)]
pub fn pop_fn_resolution_cache(&mut self) {
let mut cache = self.fn_resolution_caches.0.pop().unwrap();
cache.clear();
@ -1915,7 +1918,11 @@ impl Engine {
_ => unreachable!("expression cannot be evaluated: {:?}", expr),
};
self.check_data_size(result, expr.position())
#[cfg(not(feature = "unchecked"))]
self.check_data_size(&result)
.map_err(|err| err.fill_position(expr.position()))?;
result
}
/// Evaluate a statements block.
@ -2166,29 +2173,26 @@ impl Engine {
}
// If statement
Stmt::If(expr, x, _) => self
.eval_expr(scope, mods, state, lib, this_ptr, expr, level)?
.as_bool()
.map_err(|err| self.make_type_mismatch_err::<bool>(err, expr.position()))
.and_then(|guard_val| {
if guard_val {
if !x.0.is_empty() {
self.eval_stmt_block(
scope, mods, state, lib, this_ptr, &x.0, true, level,
)
} else {
Ok(Dynamic::UNIT)
}
Stmt::If(expr, x, _) => {
let guard_val = self
.eval_expr(scope, mods, state, lib, this_ptr, expr, level)?
.as_bool()
.map_err(|err| self.make_type_mismatch_err::<bool>(err, expr.position()))?;
if guard_val {
if !x.0.is_empty() {
self.eval_stmt_block(scope, mods, state, lib, this_ptr, &x.0, true, level)
} else {
if !x.1.is_empty() {
self.eval_stmt_block(
scope, mods, state, lib, this_ptr, &x.1, true, level,
)
} else {
Ok(Dynamic::UNIT)
}
Ok(Dynamic::UNIT)
}
}),
} else {
if !x.1.is_empty() {
self.eval_stmt_block(scope, mods, state, lib, this_ptr, &x.1, true, level)
} else {
Ok(Dynamic::UNIT)
}
}
}
// Switch statement
Stmt::Switch(match_expr, x, _) => {
@ -2258,17 +2262,16 @@ impl Engine {
if !condition {
return Ok(Dynamic::UNIT);
}
if body.is_empty() {
continue;
}
match self.eval_stmt_block(scope, mods, state, lib, this_ptr, body, true, level) {
Ok(_) => (),
Err(err) => match *err {
EvalAltResult::LoopBreak(false, _) => (),
EvalAltResult::LoopBreak(true, _) => return Ok(Dynamic::UNIT),
_ => return Err(err),
},
if !body.is_empty() {
match self.eval_stmt_block(scope, mods, state, lib, this_ptr, body, true, level)
{
Ok(_) => (),
Err(err) => match *err {
EvalAltResult::LoopBreak(false, _) => (),
EvalAltResult::LoopBreak(true, _) => return Ok(Dynamic::UNIT),
_ => return Err(err),
},
}
}
},
@ -2286,18 +2289,13 @@ impl Engine {
}
}
if self
let condition = self
.eval_expr(scope, mods, state, lib, this_ptr, expr, level)?
.as_bool()
.map_err(|err| self.make_type_mismatch_err::<bool>(err, expr.position()))?
{
if !*is_while {
return Ok(Dynamic::UNIT);
}
} else {
if *is_while {
return Ok(Dynamic::UNIT);
}
.map_err(|err| self.make_type_mismatch_err::<bool>(err, expr.position()))?;
if condition ^ *is_while {
return Ok(Dynamic::UNIT);
}
},
@ -2364,9 +2362,11 @@ impl Engine {
continue;
}
match self.eval_stmt_block(
let result = self.eval_stmt_block(
scope, mods, state, lib, this_ptr, statements, true, level,
) {
);
match result {
Ok(_) => (),
Err(err) => match *err {
EvalAltResult::LoopBreak(false, _) => (),
@ -2477,25 +2477,25 @@ impl Engine {
}
// Return value
Stmt::Return(ReturnType::Return, Some(expr), pos) => {
let value = self
.eval_expr(scope, mods, state, lib, this_ptr, expr, level)?
.flatten();
EvalAltResult::Return(value, *pos).into()
}
Stmt::Return(ReturnType::Return, Some(expr), pos) => EvalAltResult::Return(
self.eval_expr(scope, mods, state, lib, this_ptr, expr, level)?
.flatten(),
*pos,
)
.into(),
// Empty return
Stmt::Return(ReturnType::Return, None, pos) => {
EvalAltResult::Return(Default::default(), *pos).into()
EvalAltResult::Return(Dynamic::UNIT, *pos).into()
}
// Throw value
Stmt::Return(ReturnType::Exception, Some(expr), pos) => {
let value = self
.eval_expr(scope, mods, state, lib, this_ptr, expr, level)?
.flatten();
EvalAltResult::ErrorRuntime(value, *pos).into()
}
Stmt::Return(ReturnType::Exception, Some(expr), pos) => EvalAltResult::ErrorRuntime(
self.eval_expr(scope, mods, state, lib, this_ptr, expr, level)?
.flatten(),
*pos,
)
.into(),
// Empty throw
Stmt::Return(ReturnType::Exception, None, pos) => {
@ -2640,24 +2640,18 @@ impl Engine {
}
};
self.check_data_size(result, stmt.position())
}
#[cfg(not(feature = "unchecked"))]
self.check_data_size(&result)
.map_err(|err| err.fill_position(stmt.position()))?;
/// Check a result to ensure that the data size is within allowable limit.
/// [`Position`] in [`EvalAltResult`] may be None and should be set afterwards.
#[cfg(feature = "unchecked")]
#[inline(always)]
fn check_data_size(&self, result: RhaiResult, _pos: Position) -> RhaiResult {
result
}
/// Check a result to ensure that the data size is within allowable limit.
#[cfg(not(feature = "unchecked"))]
#[inline(always)]
fn check_data_size(&self, result: RhaiResult, pos: Position) -> RhaiResult {
// Simply return all errors
fn check_data_size(&self, result: &RhaiResult) -> Result<(), Box<EvalAltResult>> {
if result.is_err() {
return result;
return Ok(());
}
// If no data size limits, just return
@ -2672,7 +2666,7 @@ impl Engine {
}
if !_has_limit {
return result;
return Ok(());
}
// Recursively calculate the size of a value (especially `Array` and `Map`)
@ -2734,7 +2728,11 @@ impl Engine {
.max_string_size
.map_or(usize::MAX, NonZeroUsize::get)
{
return EvalAltResult::ErrorDataTooLarge("Length of string".to_string(), pos).into();
return EvalAltResult::ErrorDataTooLarge(
"Length of string".to_string(),
Position::NONE,
)
.into();
}
#[cfg(not(feature = "no_index"))]
@ -2744,7 +2742,8 @@ impl Engine {
.max_array_size
.map_or(usize::MAX, NonZeroUsize::get)
{
return EvalAltResult::ErrorDataTooLarge("Size of array".to_string(), pos).into();
return EvalAltResult::ErrorDataTooLarge("Size of array".to_string(), Position::NONE)
.into();
}
#[cfg(not(feature = "no_object"))]
@ -2754,14 +2753,17 @@ impl Engine {
.max_map_size
.map_or(usize::MAX, NonZeroUsize::get)
{
return EvalAltResult::ErrorDataTooLarge("Size of object map".to_string(), pos).into();
return EvalAltResult::ErrorDataTooLarge(
"Size of object map".to_string(),
Position::NONE,
)
.into();
}
result
Ok(())
}
/// Check if the number of operations stay within limit.
#[inline]
pub(crate) fn inc_operations(
&self,
state: &mut State,