Merge data type mismatch errors.
This commit is contained in:
parent
b67a743306
commit
82d48df734
@ -11,13 +11,13 @@ Breaking changes
|
|||||||
* `Module::iter_script_fn_info` is removed and merged into `Module::iter_script_fn`.
|
* `Module::iter_script_fn_info` is removed and merged into `Module::iter_script_fn`.
|
||||||
* The `merge_namespaces` parameter to `Module::eval_ast_as_new` is removed and now defaults to `true`.
|
* The `merge_namespaces` parameter to `Module::eval_ast_as_new` is removed and now defaults to `true`.
|
||||||
* `GlobalFileModuleResolver` is removed because its performance gain over the `FileModuleResolver` is no longer very significant.
|
* `GlobalFileModuleResolver` is removed because its performance gain over the `FileModuleResolver` is no longer very significant.
|
||||||
* `EvalAltResult::ErrorCharMismatch` is renamed to `EvalAltResult::ErrorMismatchDataType`.
|
* The following `EvalAltResult` variants are removed and merged into `EvalAltResult::ErrorMismatchDataType`: `ErrorCharMismatch`, `ErrorNumericIndexExpr`, `ErrorStringIndexExpr`, `ErrorImportExpr`, `ErrorLogicGuard`, `ErrorBooleanArgMismatch`
|
||||||
|
|
||||||
New features
|
New features
|
||||||
------------
|
------------
|
||||||
|
|
||||||
* `OptimizationLevel::Simple` now eagerly evaluates built-in binary operators of primary types (if not overloaded).
|
* `OptimizationLevel::Simple` now eagerly evaluates built-in binary operators of primary types (if not overloaded).
|
||||||
* Added `is_def_var()` to detect if variable is defined and `is_def_fn()` to detect if script function is defined.
|
* Added `is_def_var()` to detect if variable is defined, and `is_def_fn()` to detect if script function is defined.
|
||||||
* Added `Module::get_script_fn` to get a scripted function in a module, if any, based on name and number of parameters.
|
* Added `Module::get_script_fn` to get a scripted function in a module, if any, based on name and number of parameters.
|
||||||
|
|
||||||
|
|
||||||
|
129
src/engine.rs
129
src/engine.rs
@ -7,7 +7,7 @@ use crate::fn_native::{Callback, FnPtr};
|
|||||||
use crate::module::{Module, ModuleRef};
|
use crate::module::{Module, ModuleRef};
|
||||||
use crate::optimize::OptimizationLevel;
|
use crate::optimize::OptimizationLevel;
|
||||||
use crate::packages::{Package, PackagesCollection, StandardPackage};
|
use crate::packages::{Package, PackagesCollection, StandardPackage};
|
||||||
use crate::parser::{Expr, ReturnType, Stmt};
|
use crate::parser::{Expr, ReturnType, Stmt, INT};
|
||||||
use crate::r#unsafe::unsafe_cast_var_name_to_lifetime;
|
use crate::r#unsafe::unsafe_cast_var_name_to_lifetime;
|
||||||
use crate::result::EvalAltResult;
|
use crate::result::EvalAltResult;
|
||||||
use crate::scope::{EntryType as ScopeEntryType, Scope};
|
use crate::scope::{EntryType as ScopeEntryType, Scope};
|
||||||
@ -33,6 +33,7 @@ use crate::utils::ImmutableString;
|
|||||||
use crate::any::DynamicWriteLock;
|
use crate::any::DynamicWriteLock;
|
||||||
|
|
||||||
use crate::stdlib::{
|
use crate::stdlib::{
|
||||||
|
any::type_name,
|
||||||
boxed::Box,
|
boxed::Box,
|
||||||
collections::{HashMap, HashSet},
|
collections::{HashMap, HashSet},
|
||||||
fmt, format,
|
fmt, format,
|
||||||
@ -243,7 +244,7 @@ impl Target<'_> {
|
|||||||
#[cfg(not(feature = "no_index"))]
|
#[cfg(not(feature = "no_index"))]
|
||||||
Self::StringChar(_, _, ch) => {
|
Self::StringChar(_, _, ch) => {
|
||||||
let new_val = ch.clone();
|
let new_val = ch.clone();
|
||||||
self.set_value(new_val, Position::none(), Position::none())
|
self.set_value((new_val, Position::none()), Position::none())
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -251,15 +252,14 @@ impl Target<'_> {
|
|||||||
/// Update the value of the `Target`.
|
/// Update the value of the `Target`.
|
||||||
pub fn set_value(
|
pub fn set_value(
|
||||||
&mut self,
|
&mut self,
|
||||||
new_val: Dynamic,
|
new_val: (Dynamic, Position),
|
||||||
target_pos: Position,
|
target_pos: Position,
|
||||||
new_pos: Position,
|
|
||||||
) -> Result<(), Box<EvalAltResult>> {
|
) -> Result<(), Box<EvalAltResult>> {
|
||||||
match self {
|
match self {
|
||||||
Self::Ref(r) => **r = new_val,
|
Self::Ref(r) => **r = new_val.0,
|
||||||
#[cfg(not(feature = "no_closure"))]
|
#[cfg(not(feature = "no_closure"))]
|
||||||
#[cfg(not(feature = "no_object"))]
|
#[cfg(not(feature = "no_object"))]
|
||||||
Self::LockGuard((r, _)) => **r = new_val,
|
Self::LockGuard((r, _)) => **r = new_val.0,
|
||||||
Self::Value(_) => {
|
Self::Value(_) => {
|
||||||
return EvalAltResult::ErrorAssignmentToUnknownLHS(target_pos).into();
|
return EvalAltResult::ErrorAssignmentToUnknownLHS(target_pos).into();
|
||||||
}
|
}
|
||||||
@ -268,11 +268,11 @@ impl Target<'_> {
|
|||||||
let mut s = string.write_lock::<ImmutableString>().unwrap();
|
let mut s = string.write_lock::<ImmutableString>().unwrap();
|
||||||
|
|
||||||
// Replace the character at the specified index position
|
// Replace the character at the specified index position
|
||||||
let new_ch = new_val.as_char().map_err(|err| {
|
let new_ch = new_val.0.as_char().map_err(|err| {
|
||||||
Box::new(EvalAltResult::ErrorMismatchDataType(
|
Box::new(EvalAltResult::ErrorMismatchDataType(
|
||||||
err.to_string(),
|
err.to_string(),
|
||||||
"char".to_string(),
|
"char".to_string(),
|
||||||
new_pos,
|
new_val.1,
|
||||||
))
|
))
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
@ -713,8 +713,7 @@ impl Engine {
|
|||||||
idx_values: &mut StaticVec<Dynamic>,
|
idx_values: &mut StaticVec<Dynamic>,
|
||||||
chain_type: ChainType,
|
chain_type: ChainType,
|
||||||
level: usize,
|
level: usize,
|
||||||
new_val: Option<Dynamic>,
|
new_val: Option<(Dynamic, Position)>,
|
||||||
new_pos: Position,
|
|
||||||
) -> Result<(Dynamic, bool), Box<EvalAltResult>> {
|
) -> Result<(Dynamic, bool), Box<EvalAltResult>> {
|
||||||
if chain_type == ChainType::None {
|
if chain_type == ChainType::None {
|
||||||
panic!();
|
panic!();
|
||||||
@ -747,7 +746,7 @@ impl Engine {
|
|||||||
|
|
||||||
self.eval_dot_index_chain_helper(
|
self.eval_dot_index_chain_helper(
|
||||||
state, lib, this_ptr, obj_ptr, expr, idx_values, next_chain, level,
|
state, lib, this_ptr, obj_ptr, expr, idx_values, next_chain, level,
|
||||||
new_val, new_pos,
|
new_val,
|
||||||
)
|
)
|
||||||
.map_err(|err| err.new_position(*pos))
|
.map_err(|err| err.new_position(*pos))
|
||||||
}
|
}
|
||||||
@ -761,7 +760,7 @@ impl Engine {
|
|||||||
{
|
{
|
||||||
// Indexed value is a reference - update directly
|
// Indexed value is a reference - update directly
|
||||||
Ok(ref mut obj_ptr) => {
|
Ok(ref mut obj_ptr) => {
|
||||||
obj_ptr.set_value(new_val.unwrap(), rhs.position(), new_pos)?;
|
obj_ptr.set_value(new_val.unwrap(), rhs.position())?;
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
Err(err) => match *err {
|
Err(err) => match *err {
|
||||||
@ -777,7 +776,7 @@ impl Engine {
|
|||||||
if let Some(mut new_val) = _call_setter {
|
if let Some(mut new_val) = _call_setter {
|
||||||
let val = target.as_mut();
|
let val = target.as_mut();
|
||||||
let val_type_name = val.type_name();
|
let val_type_name = val.type_name();
|
||||||
let args = &mut [val, &mut idx_val2, &mut new_val];
|
let args = &mut [val, &mut idx_val2, &mut new_val.0];
|
||||||
|
|
||||||
self.exec_fn_call(
|
self.exec_fn_call(
|
||||||
state, lib, FN_IDX_SET, 0, args, is_ref, true, false, None, &None,
|
state, lib, FN_IDX_SET, 0, args, is_ref, true, false, None, &None,
|
||||||
@ -825,7 +824,7 @@ impl Engine {
|
|||||||
let mut val = self
|
let mut val = self
|
||||||
.get_indexed_mut(state, lib, target, index, *pos, true, false, level)?;
|
.get_indexed_mut(state, lib, target, index, *pos, true, false, level)?;
|
||||||
|
|
||||||
val.set_value(new_val.unwrap(), rhs.position(), new_pos)?;
|
val.set_value(new_val.unwrap(), rhs.position())?;
|
||||||
Ok((Default::default(), true))
|
Ok((Default::default(), true))
|
||||||
}
|
}
|
||||||
// {xxx:map}.id
|
// {xxx:map}.id
|
||||||
@ -842,7 +841,7 @@ impl Engine {
|
|||||||
Expr::Property(x) if new_val.is_some() => {
|
Expr::Property(x) if new_val.is_some() => {
|
||||||
let ((_, _, setter), pos) = x.as_ref();
|
let ((_, _, setter), pos) = x.as_ref();
|
||||||
let mut new_val = new_val;
|
let mut new_val = new_val;
|
||||||
let mut args = [target.as_mut(), new_val.as_mut().unwrap()];
|
let mut args = [target.as_mut(), &mut new_val.as_mut().unwrap().0];
|
||||||
self.exec_fn_call(
|
self.exec_fn_call(
|
||||||
state, lib, setter, 0, &mut args, is_ref, true, false, None, &None,
|
state, lib, setter, 0, &mut args, is_ref, true, false, None, &None,
|
||||||
level,
|
level,
|
||||||
@ -893,7 +892,7 @@ impl Engine {
|
|||||||
|
|
||||||
self.eval_dot_index_chain_helper(
|
self.eval_dot_index_chain_helper(
|
||||||
state, lib, this_ptr, &mut val, expr, idx_values, next_chain, level,
|
state, lib, this_ptr, &mut val, expr, idx_values, next_chain, level,
|
||||||
new_val, new_pos,
|
new_val,
|
||||||
)
|
)
|
||||||
.map_err(|err| err.new_position(*pos))
|
.map_err(|err| err.new_position(*pos))
|
||||||
}
|
}
|
||||||
@ -927,7 +926,6 @@ impl Engine {
|
|||||||
next_chain,
|
next_chain,
|
||||||
level,
|
level,
|
||||||
new_val,
|
new_val,
|
||||||
new_pos,
|
|
||||||
)
|
)
|
||||||
.map_err(|err| err.new_position(*pos))?;
|
.map_err(|err| err.new_position(*pos))?;
|
||||||
|
|
||||||
@ -967,7 +965,7 @@ impl Engine {
|
|||||||
|
|
||||||
self.eval_dot_index_chain_helper(
|
self.eval_dot_index_chain_helper(
|
||||||
state, lib, this_ptr, target, expr, idx_values, next_chain,
|
state, lib, this_ptr, target, expr, idx_values, next_chain,
|
||||||
level, new_val, new_pos,
|
level, new_val,
|
||||||
)
|
)
|
||||||
.map_err(|err| err.new_position(*pos))
|
.map_err(|err| err.new_position(*pos))
|
||||||
}
|
}
|
||||||
@ -997,8 +995,7 @@ impl Engine {
|
|||||||
this_ptr: &mut Option<&mut Dynamic>,
|
this_ptr: &mut Option<&mut Dynamic>,
|
||||||
expr: &Expr,
|
expr: &Expr,
|
||||||
level: usize,
|
level: usize,
|
||||||
new_val: Option<Dynamic>,
|
new_val: Option<(Dynamic, Position)>,
|
||||||
new_pos: Position,
|
|
||||||
) -> Result<Dynamic, Box<EvalAltResult>> {
|
) -> Result<Dynamic, Box<EvalAltResult>> {
|
||||||
let ((dot_lhs, dot_rhs, op_pos), chain_type) = match expr {
|
let ((dot_lhs, dot_rhs, op_pos), chain_type) = match expr {
|
||||||
Expr::Index(x) => (x.as_ref(), ChainType::Index),
|
Expr::Index(x) => (x.as_ref(), ChainType::Index),
|
||||||
@ -1034,8 +1031,7 @@ impl Engine {
|
|||||||
|
|
||||||
let obj_ptr = &mut target.into();
|
let obj_ptr = &mut target.into();
|
||||||
self.eval_dot_index_chain_helper(
|
self.eval_dot_index_chain_helper(
|
||||||
state, lib, &mut None, obj_ptr, dot_rhs, idx_values, chain_type, level,
|
state, lib, &mut None, obj_ptr, dot_rhs, idx_values, chain_type, level, new_val,
|
||||||
new_val, new_pos,
|
|
||||||
)
|
)
|
||||||
.map(|(v, _)| v)
|
.map(|(v, _)| v)
|
||||||
.map_err(|err| err.new_position(*op_pos))
|
.map_err(|err| err.new_position(*op_pos))
|
||||||
@ -1050,7 +1046,6 @@ impl Engine {
|
|||||||
let obj_ptr = &mut val.into();
|
let obj_ptr = &mut val.into();
|
||||||
self.eval_dot_index_chain_helper(
|
self.eval_dot_index_chain_helper(
|
||||||
state, lib, this_ptr, obj_ptr, dot_rhs, idx_values, chain_type, level, new_val,
|
state, lib, this_ptr, obj_ptr, dot_rhs, idx_values, chain_type, level, new_val,
|
||||||
new_pos,
|
|
||||||
)
|
)
|
||||||
.map(|(v, _)| v)
|
.map(|(v, _)| v)
|
||||||
.map_err(|err| err.new_position(*op_pos))
|
.map_err(|err| err.new_position(*op_pos))
|
||||||
@ -1159,7 +1154,7 @@ impl Engine {
|
|||||||
// val_array[idx]
|
// val_array[idx]
|
||||||
let index = idx
|
let index = idx
|
||||||
.as_int()
|
.as_int()
|
||||||
.map_err(|_| EvalAltResult::ErrorNumericIndexExpr(idx_pos))?;
|
.map_err(|err| self.make_type_mismatch_err::<INT>(err, idx_pos))?;
|
||||||
|
|
||||||
let arr_len = arr.len();
|
let arr_len = arr.len();
|
||||||
|
|
||||||
@ -1178,15 +1173,15 @@ impl Engine {
|
|||||||
Dynamic(Union::Map(map)) => {
|
Dynamic(Union::Map(map)) => {
|
||||||
// val_map[idx]
|
// val_map[idx]
|
||||||
Ok(if _create {
|
Ok(if _create {
|
||||||
let index = idx
|
let index = idx.take_immutable_string().map_err(|err| {
|
||||||
.take_immutable_string()
|
self.make_type_mismatch_err::<ImmutableString>(err, idx_pos)
|
||||||
.map_err(|_| EvalAltResult::ErrorStringIndexExpr(idx_pos))?;
|
})?;
|
||||||
|
|
||||||
map.entry(index).or_insert_with(Default::default).into()
|
map.entry(index).or_insert_with(Default::default).into()
|
||||||
} else {
|
} else {
|
||||||
let index = idx
|
let index = idx.read_lock::<ImmutableString>().ok_or_else(|| {
|
||||||
.read_lock::<ImmutableString>()
|
self.make_type_mismatch_err::<ImmutableString>("", idx_pos)
|
||||||
.ok_or_else(|| EvalAltResult::ErrorStringIndexExpr(idx_pos))?;
|
})?;
|
||||||
|
|
||||||
map.get_mut(&*index)
|
map.get_mut(&*index)
|
||||||
.map(Target::from)
|
.map(Target::from)
|
||||||
@ -1200,7 +1195,7 @@ impl Engine {
|
|||||||
let chars_len = s.chars().count();
|
let chars_len = s.chars().count();
|
||||||
let index = idx
|
let index = idx
|
||||||
.as_int()
|
.as_int()
|
||||||
.map_err(|_| EvalAltResult::ErrorNumericIndexExpr(idx_pos))?;
|
.map_err(|err| self.make_type_mismatch_err::<INT>(err, idx_pos))?;
|
||||||
|
|
||||||
if index >= 0 {
|
if index >= 0 {
|
||||||
let offset = index as usize;
|
let offset = index as usize;
|
||||||
@ -1438,9 +1433,9 @@ impl Engine {
|
|||||||
let mut rhs_val =
|
let mut rhs_val =
|
||||||
self.eval_expr(scope, mods, state, lib, this_ptr, rhs_expr, level)?;
|
self.eval_expr(scope, mods, state, lib, this_ptr, rhs_expr, level)?;
|
||||||
|
|
||||||
let (_new_val, _new_pos) = if op.is_empty() {
|
let _new_val = if op.is_empty() {
|
||||||
// Normal assignment
|
// Normal assignment
|
||||||
(Some(rhs_val), rhs_expr.position())
|
Some((rhs_val, rhs_expr.position()))
|
||||||
} else {
|
} else {
|
||||||
// Op-assignment - always map to `lhs = lhs op rhs`
|
// Op-assignment - always map to `lhs = lhs op rhs`
|
||||||
let op = &op[..op.len() - 1]; // extract operator without =
|
let op = &op[..op.len() - 1]; // extract operator without =
|
||||||
@ -1456,7 +1451,7 @@ impl Engine {
|
|||||||
.map(|(v, _)| v)
|
.map(|(v, _)| v)
|
||||||
.map_err(|err| err.new_position(*op_pos))?;
|
.map_err(|err| err.new_position(*op_pos))?;
|
||||||
|
|
||||||
(Some(result), rhs_expr.position())
|
Some((result, rhs_expr.position()))
|
||||||
};
|
};
|
||||||
|
|
||||||
match lhs_expr {
|
match lhs_expr {
|
||||||
@ -1466,7 +1461,7 @@ impl Engine {
|
|||||||
#[cfg(not(feature = "no_index"))]
|
#[cfg(not(feature = "no_index"))]
|
||||||
Expr::Index(_) => {
|
Expr::Index(_) => {
|
||||||
self.eval_dot_index_chain(
|
self.eval_dot_index_chain(
|
||||||
scope, mods, state, lib, this_ptr, lhs_expr, level, _new_val, _new_pos,
|
scope, mods, state, lib, this_ptr, lhs_expr, level, _new_val,
|
||||||
)?;
|
)?;
|
||||||
Ok(Default::default())
|
Ok(Default::default())
|
||||||
}
|
}
|
||||||
@ -1474,7 +1469,7 @@ impl Engine {
|
|||||||
#[cfg(not(feature = "no_object"))]
|
#[cfg(not(feature = "no_object"))]
|
||||||
Expr::Dot(_) => {
|
Expr::Dot(_) => {
|
||||||
self.eval_dot_index_chain(
|
self.eval_dot_index_chain(
|
||||||
scope, mods, state, lib, this_ptr, lhs_expr, level, _new_val, _new_pos,
|
scope, mods, state, lib, this_ptr, lhs_expr, level, _new_val,
|
||||||
)?;
|
)?;
|
||||||
Ok(Default::default())
|
Ok(Default::default())
|
||||||
}
|
}
|
||||||
@ -1491,31 +1486,15 @@ impl Engine {
|
|||||||
|
|
||||||
// lhs[idx_expr]
|
// lhs[idx_expr]
|
||||||
#[cfg(not(feature = "no_index"))]
|
#[cfg(not(feature = "no_index"))]
|
||||||
Expr::Index(_) => self.eval_dot_index_chain(
|
Expr::Index(_) => {
|
||||||
scope,
|
self.eval_dot_index_chain(scope, mods, state, lib, this_ptr, expr, level, None)
|
||||||
mods,
|
}
|
||||||
state,
|
|
||||||
lib,
|
|
||||||
this_ptr,
|
|
||||||
expr,
|
|
||||||
level,
|
|
||||||
None,
|
|
||||||
Position::none(),
|
|
||||||
),
|
|
||||||
|
|
||||||
// lhs.dot_rhs
|
// lhs.dot_rhs
|
||||||
#[cfg(not(feature = "no_object"))]
|
#[cfg(not(feature = "no_object"))]
|
||||||
Expr::Dot(_) => self.eval_dot_index_chain(
|
Expr::Dot(_) => {
|
||||||
scope,
|
self.eval_dot_index_chain(scope, mods, state, lib, this_ptr, expr, level, None)
|
||||||
mods,
|
}
|
||||||
state,
|
|
||||||
lib,
|
|
||||||
this_ptr,
|
|
||||||
expr,
|
|
||||||
level,
|
|
||||||
None,
|
|
||||||
Position::none(),
|
|
||||||
),
|
|
||||||
|
|
||||||
#[cfg(not(feature = "no_index"))]
|
#[cfg(not(feature = "no_index"))]
|
||||||
Expr::Array(x) => Ok(Dynamic(Union::Array(Box::new(
|
Expr::Array(x) => Ok(Dynamic(Union::Array(Box::new(
|
||||||
@ -1562,16 +1541,12 @@ impl Engine {
|
|||||||
Ok((self
|
Ok((self
|
||||||
.eval_expr(scope, mods, state, lib, this_ptr, lhs, level)?
|
.eval_expr(scope, mods, state, lib, this_ptr, lhs, level)?
|
||||||
.as_bool()
|
.as_bool()
|
||||||
.map_err(|_| {
|
.map_err(|err| self.make_type_mismatch_err::<bool>(err, lhs.position()))?
|
||||||
EvalAltResult::ErrorBooleanArgMismatch("AND".into(), lhs.position())
|
|
||||||
})?
|
|
||||||
&& // Short-circuit using &&
|
&& // Short-circuit using &&
|
||||||
self
|
self
|
||||||
.eval_expr(scope, mods, state, lib, this_ptr, rhs, level)?
|
.eval_expr(scope, mods, state, lib, this_ptr, rhs, level)?
|
||||||
.as_bool()
|
.as_bool()
|
||||||
.map_err(|_| {
|
.map_err(|err| self.make_type_mismatch_err::<bool>(err, rhs.position()))?)
|
||||||
EvalAltResult::ErrorBooleanArgMismatch("AND".into(), rhs.position())
|
|
||||||
})?)
|
|
||||||
.into())
|
.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1580,16 +1555,12 @@ impl Engine {
|
|||||||
Ok((self
|
Ok((self
|
||||||
.eval_expr(scope, mods, state, lib, this_ptr, lhs, level)?
|
.eval_expr(scope, mods, state, lib, this_ptr, lhs, level)?
|
||||||
.as_bool()
|
.as_bool()
|
||||||
.map_err(|_| {
|
.map_err(|err| self.make_type_mismatch_err::<bool>(err, lhs.position()))?
|
||||||
EvalAltResult::ErrorBooleanArgMismatch("OR".into(), lhs.position())
|
|
||||||
})?
|
|
||||||
|| // Short-circuit using ||
|
|| // Short-circuit using ||
|
||||||
self
|
self
|
||||||
.eval_expr(scope, mods, state, lib, this_ptr, rhs, level)?
|
.eval_expr(scope, mods, state, lib, this_ptr, rhs, level)?
|
||||||
.as_bool()
|
.as_bool()
|
||||||
.map_err(|_| {
|
.map_err(|err| self.make_type_mismatch_err::<bool>(err, rhs.position()))?)
|
||||||
EvalAltResult::ErrorBooleanArgMismatch("OR".into(), rhs.position())
|
|
||||||
})?)
|
|
||||||
.into())
|
.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1671,7 +1642,7 @@ impl Engine {
|
|||||||
|
|
||||||
self.eval_expr(scope, mods, state, lib, this_ptr, expr, level)?
|
self.eval_expr(scope, mods, state, lib, this_ptr, expr, level)?
|
||||||
.as_bool()
|
.as_bool()
|
||||||
.map_err(|_| EvalAltResult::ErrorLogicGuard(expr.position()).into())
|
.map_err(|err| self.make_type_mismatch_err::<bool>(err, expr.position()))
|
||||||
.and_then(|guard_val| {
|
.and_then(|guard_val| {
|
||||||
if guard_val {
|
if guard_val {
|
||||||
self.eval_stmt(scope, mods, state, lib, this_ptr, if_block, level)
|
self.eval_stmt(scope, mods, state, lib, this_ptr, if_block, level)
|
||||||
@ -1704,7 +1675,9 @@ impl Engine {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(false) => return Ok(Default::default()),
|
Ok(false) => return Ok(Default::default()),
|
||||||
Err(_) => return EvalAltResult::ErrorLogicGuard(expr.position()).into(),
|
Err(err) => {
|
||||||
|
return Err(self.make_type_mismatch_err::<bool>(err, expr.position()))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -1873,7 +1846,7 @@ impl Engine {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
EvalAltResult::ErrorImportExpr(expr.position()).into()
|
Err(self.make_type_mismatch_err::<ImmutableString>("", expr.position()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2068,4 +2041,14 @@ impl Engine {
|
|||||||
.and_then(|t| t.get(name).map(String::as_str))
|
.and_then(|t| t.get(name).map(String::as_str))
|
||||||
.unwrap_or_else(|| map_std_type_name(name))
|
.unwrap_or_else(|| map_std_type_name(name))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Make a Box<EvalAltResult<ErrorMismatchDataType>>.
|
||||||
|
pub fn make_type_mismatch_err<T>(&self, typ: &str, pos: Position) -> Box<EvalAltResult> {
|
||||||
|
EvalAltResult::ErrorMismatchDataType(
|
||||||
|
typ.into(),
|
||||||
|
self.map_type_name(type_name::<T>()).into(),
|
||||||
|
pos,
|
||||||
|
)
|
||||||
|
.into()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -844,15 +844,6 @@ impl Engine {
|
|||||||
capture: bool,
|
capture: bool,
|
||||||
level: usize,
|
level: usize,
|
||||||
) -> Result<Dynamic, Box<EvalAltResult>> {
|
) -> Result<Dynamic, Box<EvalAltResult>> {
|
||||||
fn make_type_err<T>(engine: &Engine, typ: &str, pos: Position) -> Box<EvalAltResult> {
|
|
||||||
EvalAltResult::ErrorMismatchDataType(
|
|
||||||
typ.into(),
|
|
||||||
engine.map_type_name(type_name::<T>()).into(),
|
|
||||||
pos,
|
|
||||||
)
|
|
||||||
.into()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handle Fn()
|
// Handle Fn()
|
||||||
if name == KEYWORD_FN_PTR && args_expr.len() == 1 {
|
if name == KEYWORD_FN_PTR && args_expr.len() == 1 {
|
||||||
let hash_fn = calc_fn_hash(empty(), name, 1, once(TypeId::of::<ImmutableString>()));
|
let hash_fn = calc_fn_hash(empty(), name, 1, once(TypeId::of::<ImmutableString>()));
|
||||||
@ -864,7 +855,9 @@ impl Engine {
|
|||||||
|
|
||||||
return arg_value
|
return arg_value
|
||||||
.take_immutable_string()
|
.take_immutable_string()
|
||||||
.map_err(|typ| make_type_err::<ImmutableString>(self, typ, expr.position()))
|
.map_err(|typ| {
|
||||||
|
self.make_type_mismatch_err::<ImmutableString>(typ, expr.position())
|
||||||
|
})
|
||||||
.and_then(|s| FnPtr::try_from(s))
|
.and_then(|s| FnPtr::try_from(s))
|
||||||
.map(Into::<Dynamic>::into)
|
.map(Into::<Dynamic>::into)
|
||||||
.map_err(|err| err.new_position(expr.position()));
|
.map_err(|err| err.new_position(expr.position()));
|
||||||
@ -877,8 +870,7 @@ impl Engine {
|
|||||||
let arg_value = self.eval_expr(scope, mods, state, lib, this_ptr, expr, level)?;
|
let arg_value = self.eval_expr(scope, mods, state, lib, this_ptr, expr, level)?;
|
||||||
|
|
||||||
if !arg_value.is::<FnPtr>() {
|
if !arg_value.is::<FnPtr>() {
|
||||||
return Err(make_type_err::<FnPtr>(
|
return Err(self.make_type_mismatch_err::<FnPtr>(
|
||||||
self,
|
|
||||||
self.map_type_name(arg_value.type_name()),
|
self.map_type_name(arg_value.type_name()),
|
||||||
expr.position(),
|
expr.position(),
|
||||||
));
|
));
|
||||||
@ -932,8 +924,7 @@ impl Engine {
|
|||||||
// Recalculate hash
|
// Recalculate hash
|
||||||
hash_script = calc_fn_hash(empty(), name, curry.len() + args_expr.len(), empty());
|
hash_script = calc_fn_hash(empty(), name, curry.len() + args_expr.len(), empty());
|
||||||
} else {
|
} else {
|
||||||
return Err(make_type_err::<FnPtr>(
|
return Err(self.make_type_mismatch_err::<FnPtr>(
|
||||||
self,
|
|
||||||
self.map_type_name(arg_value.type_name()),
|
self.map_type_name(arg_value.type_name()),
|
||||||
expr.position(),
|
expr.position(),
|
||||||
));
|
));
|
||||||
@ -947,9 +938,9 @@ impl Engine {
|
|||||||
if !self.has_override(lib, hash_fn, hash_script, pub_only) {
|
if !self.has_override(lib, hash_fn, hash_script, pub_only) {
|
||||||
let expr = args_expr.get(0).unwrap();
|
let expr = args_expr.get(0).unwrap();
|
||||||
let arg_value = self.eval_expr(scope, mods, state, lib, this_ptr, expr, level)?;
|
let arg_value = self.eval_expr(scope, mods, state, lib, this_ptr, expr, level)?;
|
||||||
let var_name = arg_value
|
let var_name = arg_value.as_str().map_err(|err| {
|
||||||
.as_str()
|
self.make_type_mismatch_err::<ImmutableString>(err, expr.position())
|
||||||
.map_err(|err| make_type_err::<ImmutableString>(self, err, expr.position()))?;
|
})?;
|
||||||
if var_name.is_empty() {
|
if var_name.is_empty() {
|
||||||
return Ok(false.into());
|
return Ok(false.into());
|
||||||
} else {
|
} else {
|
||||||
@ -979,11 +970,11 @@ impl Engine {
|
|||||||
self.eval_expr(scope, mods, state, lib, this_ptr, num_params_expr, level)?;
|
self.eval_expr(scope, mods, state, lib, this_ptr, num_params_expr, level)?;
|
||||||
|
|
||||||
let fn_name = arg0_value.as_str().map_err(|err| {
|
let fn_name = arg0_value.as_str().map_err(|err| {
|
||||||
make_type_err::<ImmutableString>(self, err, fn_name_expr.position())
|
self.make_type_mismatch_err::<ImmutableString>(err, fn_name_expr.position())
|
||||||
|
})?;
|
||||||
|
let num_params = arg1_value.as_int().map_err(|err| {
|
||||||
|
self.make_type_mismatch_err::<INT>(err, num_params_expr.position())
|
||||||
})?;
|
})?;
|
||||||
let num_params = arg1_value
|
|
||||||
.as_int()
|
|
||||||
.map_err(|err| make_type_err::<INT>(self, err, num_params_expr.position()))?;
|
|
||||||
|
|
||||||
if fn_name.is_empty() || num_params < 0 {
|
if fn_name.is_empty() || num_params < 0 {
|
||||||
return Ok(false.into());
|
return Ok(false.into());
|
||||||
@ -1003,9 +994,9 @@ impl Engine {
|
|||||||
let prev_len = scope.len();
|
let prev_len = scope.len();
|
||||||
let expr = args_expr.get(0).unwrap();
|
let expr = args_expr.get(0).unwrap();
|
||||||
let arg_value = self.eval_expr(scope, mods, state, lib, this_ptr, expr, level)?;
|
let arg_value = self.eval_expr(scope, mods, state, lib, this_ptr, expr, level)?;
|
||||||
let script = arg_value
|
let script = arg_value.as_str().map_err(|typ| {
|
||||||
.as_str()
|
self.make_type_mismatch_err::<ImmutableString>(typ, expr.position())
|
||||||
.map_err(|typ| make_type_err::<ImmutableString>(self, typ, expr.position()))?;
|
})?;
|
||||||
let result = if !script.is_empty() {
|
let result = if !script.is_empty() {
|
||||||
self.eval_script_expr(scope, mods, state, lib, script, level + 1)
|
self.eval_script_expr(scope, mods, state, lib, script, level + 1)
|
||||||
.map_err(|err| err.new_position(expr.position()))
|
.map_err(|err| err.new_position(expr.position()))
|
||||||
|
@ -34,21 +34,26 @@ pub enum EvalAltResult {
|
|||||||
#[cfg(not(target_arch = "wasm32"))]
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
ErrorReadingScriptFile(PathBuf, Position, std::io::Error),
|
ErrorReadingScriptFile(PathBuf, Position, std::io::Error),
|
||||||
|
|
||||||
/// Call to an unknown function. Wrapped value is the signature of the function.
|
/// Usage of an unknown variable. Wrapped value is the variable name.
|
||||||
|
ErrorVariableNotFound(String, Position),
|
||||||
|
/// Call to an unknown function. Wrapped value is the function signature.
|
||||||
ErrorFunctionNotFound(String, Position),
|
ErrorFunctionNotFound(String, Position),
|
||||||
/// An error has occurred inside a called function.
|
/// An error has occurred inside a called function.
|
||||||
/// Wrapped values are the name of the function and the interior error.
|
/// Wrapped values are the function name and the interior error.
|
||||||
ErrorInFunctionCall(String, Box<EvalAltResult>, Position),
|
ErrorInFunctionCall(String, Box<EvalAltResult>, Position),
|
||||||
|
/// Usage of an unknown module. Wrapped value is the module name.
|
||||||
|
ErrorModuleNotFound(String, Position),
|
||||||
/// An error has occurred while loading a module.
|
/// An error has occurred while loading a module.
|
||||||
/// Wrapped value are the name of the module and the interior error.
|
/// Wrapped value are the module name and the interior error.
|
||||||
ErrorInModule(String, Box<EvalAltResult>, Position),
|
ErrorInModule(String, Box<EvalAltResult>, Position),
|
||||||
/// Access to `this` that is not bound.
|
/// Access to `this` that is not bound.
|
||||||
ErrorUnboundThis(Position),
|
ErrorUnboundThis(Position),
|
||||||
/// Non-boolean operand encountered for boolean operator. Wrapped value is the operator.
|
|
||||||
ErrorBooleanArgMismatch(String, Position),
|
|
||||||
/// Data is not of the required type.
|
/// Data is not of the required type.
|
||||||
/// Wrapped values are the type requested and type of the actual result.
|
/// Wrapped values are the type requested and type of the actual result.
|
||||||
ErrorMismatchDataType(String, String, Position),
|
ErrorMismatchDataType(String, String, Position),
|
||||||
|
/// Returned type is not the same as the required output type.
|
||||||
|
/// Wrapped values are the type requested and type of the actual result.
|
||||||
|
ErrorMismatchOutputType(String, String, Position),
|
||||||
/// Array access out-of-bounds.
|
/// Array access out-of-bounds.
|
||||||
/// Wrapped values are the current number of elements in the array and the index number.
|
/// Wrapped values are the current number of elements in the array and the index number.
|
||||||
ErrorArrayBounds(usize, INT, Position),
|
ErrorArrayBounds(usize, INT, Position),
|
||||||
@ -56,33 +61,19 @@ pub enum EvalAltResult {
|
|||||||
/// Wrapped values are the current number of characters in the string and the index number.
|
/// Wrapped values are the current number of characters in the string and the index number.
|
||||||
ErrorStringBounds(usize, INT, Position),
|
ErrorStringBounds(usize, INT, Position),
|
||||||
/// Trying to index into a type that is not an array, an object map, or a string, and has no indexer function defined.
|
/// Trying to index into a type that is not an array, an object map, or a string, and has no indexer function defined.
|
||||||
|
/// Wrapped value is the type name.
|
||||||
ErrorIndexingType(String, Position),
|
ErrorIndexingType(String, Position),
|
||||||
/// Trying to index into an array or string with an index that is not `i64`.
|
|
||||||
ErrorNumericIndexExpr(Position),
|
|
||||||
/// Trying to index into a map with an index that is not `String`.
|
|
||||||
ErrorStringIndexExpr(Position),
|
|
||||||
/// Trying to import with an expression that is not `String`.
|
|
||||||
ErrorImportExpr(Position),
|
|
||||||
/// Invalid arguments for `in` operator.
|
/// Invalid arguments for `in` operator.
|
||||||
ErrorInExpr(Position),
|
ErrorInExpr(Position),
|
||||||
/// The guard expression in an `if` or `while` statement does not return a boolean value.
|
|
||||||
ErrorLogicGuard(Position),
|
|
||||||
/// The `for` statement encounters a type that is not an iterator.
|
/// The `for` statement encounters a type that is not an iterator.
|
||||||
ErrorFor(Position),
|
ErrorFor(Position),
|
||||||
/// Usage of an unknown variable. Wrapped value is the name of the variable.
|
/// Data race detected when accessing a variable. Wrapped value is the variable name.
|
||||||
ErrorVariableNotFound(String, Position),
|
|
||||||
/// Usage of an unknown module. Wrapped value is the name of the module.
|
|
||||||
ErrorModuleNotFound(String, Position),
|
|
||||||
/// Data race detected when accessing a variable. Wrapped value is the name of the variable.
|
|
||||||
ErrorDataRace(String, Position),
|
ErrorDataRace(String, Position),
|
||||||
/// Assignment to an inappropriate LHS (left-hand-side) expression.
|
/// Assignment to an inappropriate LHS (left-hand-side) expression.
|
||||||
ErrorAssignmentToUnknownLHS(Position),
|
ErrorAssignmentToUnknownLHS(Position),
|
||||||
/// Assignment to a constant variable.
|
/// Assignment to a constant variable. Wrapped value is the variable name.
|
||||||
ErrorAssignmentToConstant(String, Position),
|
ErrorAssignmentToConstant(String, Position),
|
||||||
/// Returned type is not the same as the required output type.
|
/// Inappropriate property access. Wrapped value is the property name.
|
||||||
/// Wrapped values are the type requested and type of the actual result.
|
|
||||||
ErrorMismatchOutputType(String, String, Position),
|
|
||||||
/// Inappropriate member access.
|
|
||||||
ErrorDotExpr(String, Position),
|
ErrorDotExpr(String, Position),
|
||||||
/// Arithmetic error encountered. Wrapped value is the error message.
|
/// Arithmetic error encountered. Wrapped value is the error message.
|
||||||
ErrorArithmetic(String, Position),
|
ErrorArithmetic(String, Position),
|
||||||
@ -92,7 +83,7 @@ pub enum EvalAltResult {
|
|||||||
ErrorTooManyModules(Position),
|
ErrorTooManyModules(Position),
|
||||||
/// Call stack over maximum limit.
|
/// Call stack over maximum limit.
|
||||||
ErrorStackOverflow(Position),
|
ErrorStackOverflow(Position),
|
||||||
/// Data value over maximum size limit. Wrapped values are the data type, maximum size and current size.
|
/// Data value over maximum size limit. Wrapped values are the type name, maximum size and current size.
|
||||||
ErrorDataTooLarge(String, usize, usize, Position),
|
ErrorDataTooLarge(String, usize, usize, Position),
|
||||||
/// The script is prematurely terminated.
|
/// The script is prematurely terminated.
|
||||||
ErrorTerminated(Position),
|
ErrorTerminated(Position),
|
||||||
@ -120,16 +111,10 @@ impl EvalAltResult {
|
|||||||
Self::ErrorInModule(_, _, _) => "Error in module",
|
Self::ErrorInModule(_, _, _) => "Error in module",
|
||||||
Self::ErrorFunctionNotFound(_, _) => "Function not found",
|
Self::ErrorFunctionNotFound(_, _) => "Function not found",
|
||||||
Self::ErrorUnboundThis(_) => "'this' is not bound",
|
Self::ErrorUnboundThis(_) => "'this' is not bound",
|
||||||
Self::ErrorBooleanArgMismatch(_, _) => "Boolean operator expects boolean operands",
|
|
||||||
Self::ErrorMismatchDataType(_, _, _) => "Data type is incorrect",
|
Self::ErrorMismatchDataType(_, _, _) => "Data type is incorrect",
|
||||||
Self::ErrorNumericIndexExpr(_) => {
|
|
||||||
"Indexing into an array or string expects an integer index"
|
|
||||||
}
|
|
||||||
Self::ErrorStringIndexExpr(_) => "Indexing into an object map expects a string index",
|
|
||||||
Self::ErrorIndexingType(_, _) => {
|
Self::ErrorIndexingType(_, _) => {
|
||||||
"Indexing can only be performed on an array, an object map, a string, or a type with an indexer function defined"
|
"Indexing can only be performed on an array, an object map, a string, or a type with an indexer function defined"
|
||||||
}
|
}
|
||||||
Self::ErrorImportExpr(_) => "Importing a module expects a string path",
|
|
||||||
Self::ErrorArrayBounds(_, index, _) if *index < 0 => {
|
Self::ErrorArrayBounds(_, index, _) if *index < 0 => {
|
||||||
"Array access expects non-negative index"
|
"Array access expects non-negative index"
|
||||||
}
|
}
|
||||||
@ -140,7 +125,6 @@ impl EvalAltResult {
|
|||||||
}
|
}
|
||||||
Self::ErrorStringBounds(0, _, _) => "Empty string has nothing to index",
|
Self::ErrorStringBounds(0, _, _) => "Empty string has nothing to index",
|
||||||
Self::ErrorStringBounds(_, _, _) => "String index out of bounds",
|
Self::ErrorStringBounds(_, _, _) => "String index out of bounds",
|
||||||
Self::ErrorLogicGuard(_) => "Boolean value expected",
|
|
||||||
Self::ErrorFor(_) => "For loop expects an array, object map, or range",
|
Self::ErrorFor(_) => "For loop expects an array, object map, or range",
|
||||||
Self::ErrorVariableNotFound(_, _) => "Variable not found",
|
Self::ErrorVariableNotFound(_, _) => "Variable not found",
|
||||||
Self::ErrorModuleNotFound(_, _) => "Module not found",
|
Self::ErrorModuleNotFound(_, _) => "Module not found",
|
||||||
@ -198,11 +182,7 @@ impl fmt::Display for EvalAltResult {
|
|||||||
Self::ErrorDotExpr(s, _) if !s.is_empty() => write!(f, "{}", s)?,
|
Self::ErrorDotExpr(s, _) if !s.is_empty() => write!(f, "{}", s)?,
|
||||||
|
|
||||||
Self::ErrorIndexingType(_, _)
|
Self::ErrorIndexingType(_, _)
|
||||||
| Self::ErrorNumericIndexExpr(_)
|
|
||||||
| Self::ErrorStringIndexExpr(_)
|
|
||||||
| Self::ErrorUnboundThis(_)
|
| Self::ErrorUnboundThis(_)
|
||||||
| Self::ErrorImportExpr(_)
|
|
||||||
| Self::ErrorLogicGuard(_)
|
|
||||||
| Self::ErrorFor(_)
|
| Self::ErrorFor(_)
|
||||||
| Self::ErrorAssignmentToUnknownLHS(_)
|
| Self::ErrorAssignmentToUnknownLHS(_)
|
||||||
| Self::ErrorInExpr(_)
|
| Self::ErrorInExpr(_)
|
||||||
@ -218,6 +198,9 @@ impl fmt::Display for EvalAltResult {
|
|||||||
Self::ErrorMismatchOutputType(r, s, _) => {
|
Self::ErrorMismatchOutputType(r, s, _) => {
|
||||||
write!(f, "Output type is incorrect: {} (expecting {})", r, s)?
|
write!(f, "Output type is incorrect: {} (expecting {})", r, s)?
|
||||||
}
|
}
|
||||||
|
Self::ErrorMismatchDataType(r, s, _) if r.is_empty() => {
|
||||||
|
write!(f, "Data type is incorrect, expecting {}", s)?
|
||||||
|
}
|
||||||
Self::ErrorMismatchDataType(r, s, _) => {
|
Self::ErrorMismatchDataType(r, s, _) => {
|
||||||
write!(f, "Data type is incorrect: {} (expecting {})", r, s)?
|
write!(f, "Data type is incorrect: {} (expecting {})", r, s)?
|
||||||
}
|
}
|
||||||
@ -226,9 +209,6 @@ impl fmt::Display for EvalAltResult {
|
|||||||
Self::ErrorLoopBreak(_, _) => f.write_str(desc)?,
|
Self::ErrorLoopBreak(_, _) => f.write_str(desc)?,
|
||||||
Self::Return(_, _) => f.write_str(desc)?,
|
Self::Return(_, _) => f.write_str(desc)?,
|
||||||
|
|
||||||
Self::ErrorBooleanArgMismatch(op, _) => {
|
|
||||||
write!(f, "{} operator expects boolean operands", op)?
|
|
||||||
}
|
|
||||||
Self::ErrorArrayBounds(_, index, _) if *index < 0 => {
|
Self::ErrorArrayBounds(_, index, _) if *index < 0 => {
|
||||||
write!(f, "{}: {} < 0", desc, index)?
|
write!(f, "{}: {} < 0", desc, index)?
|
||||||
}
|
}
|
||||||
@ -293,15 +273,10 @@ impl EvalAltResult {
|
|||||||
| Self::ErrorInFunctionCall(_, _, pos)
|
| Self::ErrorInFunctionCall(_, _, pos)
|
||||||
| Self::ErrorInModule(_, _, pos)
|
| Self::ErrorInModule(_, _, pos)
|
||||||
| Self::ErrorUnboundThis(pos)
|
| Self::ErrorUnboundThis(pos)
|
||||||
| Self::ErrorBooleanArgMismatch(_, pos)
|
|
||||||
| Self::ErrorMismatchDataType(_, _, pos)
|
| Self::ErrorMismatchDataType(_, _, pos)
|
||||||
| Self::ErrorArrayBounds(_, _, pos)
|
| Self::ErrorArrayBounds(_, _, pos)
|
||||||
| Self::ErrorStringBounds(_, _, pos)
|
| Self::ErrorStringBounds(_, _, pos)
|
||||||
| Self::ErrorIndexingType(_, pos)
|
| Self::ErrorIndexingType(_, pos)
|
||||||
| Self::ErrorNumericIndexExpr(pos)
|
|
||||||
| Self::ErrorStringIndexExpr(pos)
|
|
||||||
| Self::ErrorImportExpr(pos)
|
|
||||||
| Self::ErrorLogicGuard(pos)
|
|
||||||
| Self::ErrorFor(pos)
|
| Self::ErrorFor(pos)
|
||||||
| Self::ErrorVariableNotFound(_, pos)
|
| Self::ErrorVariableNotFound(_, pos)
|
||||||
| Self::ErrorModuleNotFound(_, pos)
|
| Self::ErrorModuleNotFound(_, pos)
|
||||||
@ -335,15 +310,10 @@ impl EvalAltResult {
|
|||||||
| Self::ErrorInFunctionCall(_, _, pos)
|
| Self::ErrorInFunctionCall(_, _, pos)
|
||||||
| Self::ErrorInModule(_, _, pos)
|
| Self::ErrorInModule(_, _, pos)
|
||||||
| Self::ErrorUnboundThis(pos)
|
| Self::ErrorUnboundThis(pos)
|
||||||
| Self::ErrorBooleanArgMismatch(_, pos)
|
|
||||||
| Self::ErrorMismatchDataType(_, _, pos)
|
| Self::ErrorMismatchDataType(_, _, pos)
|
||||||
| Self::ErrorArrayBounds(_, _, pos)
|
| Self::ErrorArrayBounds(_, _, pos)
|
||||||
| Self::ErrorStringBounds(_, _, pos)
|
| Self::ErrorStringBounds(_, _, pos)
|
||||||
| Self::ErrorIndexingType(_, pos)
|
| Self::ErrorIndexingType(_, pos)
|
||||||
| Self::ErrorNumericIndexExpr(pos)
|
|
||||||
| Self::ErrorStringIndexExpr(pos)
|
|
||||||
| Self::ErrorImportExpr(pos)
|
|
||||||
| Self::ErrorLogicGuard(pos)
|
|
||||||
| Self::ErrorFor(pos)
|
| Self::ErrorFor(pos)
|
||||||
| Self::ErrorVariableNotFound(_, pos)
|
| Self::ErrorVariableNotFound(_, pos)
|
||||||
| Self::ErrorModuleNotFound(_, pos)
|
| Self::ErrorModuleNotFound(_, pos)
|
||||||
|
@ -35,9 +35,7 @@ fn test_custom_syntax() -> Result<(), Box<EvalAltResult>> {
|
|||||||
if !engine
|
if !engine
|
||||||
.eval_expression_tree(context, scope, expr)?
|
.eval_expression_tree(context, scope, expr)?
|
||||||
.as_bool()
|
.as_bool()
|
||||||
.map_err(|_| {
|
.map_err(|err| engine.make_type_mismatch_err::<bool>(err, expr.position()))?
|
||||||
EvalAltResult::ErrorBooleanArgMismatch("do-while".into(), expr.position())
|
|
||||||
})?
|
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user