Remove IndexSourceType.

This commit is contained in:
Stephen Chung 2020-04-16 00:05:07 +08:00
parent 674d6c856f
commit c799a4567a

View File

@ -60,14 +60,6 @@ pub const FUNC_TO_STRING: &str = "to_string";
pub const FUNC_GETTER: &str = "get$"; pub const FUNC_GETTER: &str = "get$";
pub const FUNC_SETTER: &str = "set$"; pub const FUNC_SETTER: &str = "set$";
#[derive(Debug, Eq, PartialEq, Hash, Clone, Copy)]
enum IndexSourceType {
Expression,
String,
Array,
Map,
}
#[derive(Debug, Eq, PartialEq, Hash, Clone)] #[derive(Debug, Eq, PartialEq, Hash, Clone)]
enum IndexValue { enum IndexValue {
Num(usize), Num(usize),
@ -608,7 +600,7 @@ impl Engine<'_> {
}; };
self.get_indexed_value(scope, fn_lib, &value, idx_expr, *op_pos, level) self.get_indexed_value(scope, fn_lib, &value, idx_expr, *op_pos, level)
.map(|(val, _, _)| val) .map(|(val, _)| val)
} }
// xxx.dot_lhs.rhs // xxx.dot_lhs.rhs
@ -645,7 +637,7 @@ impl Engine<'_> {
}; };
self.get_indexed_value(scope, fn_lib, &val, idx_expr, *op_pos, level) self.get_indexed_value(scope, fn_lib, &val, idx_expr, *op_pos, level)
.and_then(|(mut val, _, _)| { .and_then(|(mut val, _)| {
let target = Target::from(&mut val); let target = Target::from(&mut val);
self.get_dot_val_helper(scope, fn_lib, target, rhs, level) self.get_dot_val_helper(scope, fn_lib, target, rhs, level)
}) })
@ -689,7 +681,7 @@ impl Engine<'_> {
// idx_lhs[idx_expr].??? // idx_lhs[idx_expr].???
Expr::Index(idx_lhs, idx_expr, op_pos) => { Expr::Index(idx_lhs, idx_expr, op_pos) => {
let (idx_src_type, src, index, mut val) = let (src, index, mut val) =
self.eval_index_expr(scope, fn_lib, idx_lhs, idx_expr, *op_pos, level)?; self.eval_index_expr(scope, fn_lib, idx_lhs, idx_expr, *op_pos, level)?;
let target = Target::from(&mut val); let target = Target::from(&mut val);
let value = self.get_dot_val_helper(scope, fn_lib, target, dot_rhs, level); let value = self.get_dot_val_helper(scope, fn_lib, target, dot_rhs, level);
@ -707,7 +699,6 @@ impl Engine<'_> {
Some(ScopeEntryType::Normal) => { Some(ScopeEntryType::Normal) => {
Self::update_indexed_var_in_scope( Self::update_indexed_var_in_scope(
idx_src_type,
scope, scope,
src.unwrap(), src.unwrap(),
index, index,
@ -747,7 +738,7 @@ impl Engine<'_> {
idx_expr: &Expr, idx_expr: &Expr,
op_pos: Position, op_pos: Position,
level: usize, level: usize,
) -> Result<(Dynamic, IndexSourceType, IndexValue), EvalAltResult> { ) -> Result<(Dynamic, IndexValue), EvalAltResult> {
let idx_pos = idx_expr.position(); let idx_pos = idx_expr.position();
// val_array[idx] // val_array[idx]
@ -759,13 +750,7 @@ impl Engine<'_> {
return if index >= 0 { return if index >= 0 {
arr.get(index as usize) arr.get(index as usize)
.map(|v| { .map(|v| (v.clone(), IndexValue::from_num(index)))
(
v.clone(),
IndexSourceType::Array,
IndexValue::from_num(index),
)
})
.ok_or_else(|| EvalAltResult::ErrorArrayBounds(arr.len(), index, idx_pos)) .ok_or_else(|| EvalAltResult::ErrorArrayBounds(arr.len(), index, idx_pos))
} else { } else {
Err(EvalAltResult::ErrorArrayBounds(arr.len(), index, idx_pos)) Err(EvalAltResult::ErrorArrayBounds(arr.len(), index, idx_pos))
@ -783,7 +768,6 @@ impl Engine<'_> {
map.get(&index) map.get(&index)
.cloned() .cloned()
.unwrap_or_else(|| Dynamic::from_unit()), .unwrap_or_else(|| Dynamic::from_unit()),
IndexSourceType::Map,
IndexValue::from_str(index), IndexValue::from_str(index),
)); ));
} }
@ -798,13 +782,7 @@ impl Engine<'_> {
return if index >= 0 { return if index >= 0 {
s.chars() s.chars()
.nth(index as usize) .nth(index as usize)
.map(|ch| { .map(|ch| (Dynamic::from_char(ch), IndexValue::from_num(index)))
(
Dynamic::from_char(ch),
IndexSourceType::String,
IndexValue::from_num(index),
)
})
.ok_or_else(|| { .ok_or_else(|| {
EvalAltResult::ErrorStringBounds(s.chars().count(), index, idx_pos) EvalAltResult::ErrorStringBounds(s.chars().count(), index, idx_pos)
}) })
@ -833,15 +811,7 @@ impl Engine<'_> {
idx_expr: &Expr, idx_expr: &Expr,
op_pos: Position, op_pos: Position,
level: usize, level: usize,
) -> Result< ) -> Result<(Option<ScopeSource<'a>>, IndexValue, Dynamic), EvalAltResult> {
(
IndexSourceType,
Option<ScopeSource<'a>>,
IndexValue,
Dynamic,
),
EvalAltResult,
> {
match lhs { match lhs {
// id[idx_expr] // id[idx_expr]
Expr::Variable(id, _) => { Expr::Variable(id, _) => {
@ -854,11 +824,10 @@ impl Engine<'_> {
val, val,
) = Self::search_scope(scope, &id, lhs.position())?; ) = Self::search_scope(scope, &id, lhs.position())?;
let (val, idx_src_type, index) = let (val, index) =
self.get_indexed_value(scope, fn_lib, &val, idx_expr, op_pos, level)?; self.get_indexed_value(scope, fn_lib, &val, idx_expr, op_pos, level)?;
Ok(( Ok((
idx_src_type,
Some(ScopeSource { Some(ScopeSource {
name: &id, name: &id,
typ: src_type, typ: src_type,
@ -874,7 +843,7 @@ impl Engine<'_> {
let val = self.eval_expr(scope, fn_lib, expr, level)?; let val = self.eval_expr(scope, fn_lib, expr, level)?;
self.get_indexed_value(scope, fn_lib, &val, idx_expr, op_pos, level) self.get_indexed_value(scope, fn_lib, &val, idx_expr, op_pos, level)
.map(|(val, _, index)| (IndexSourceType::Expression, None, index, val)) .map(|(val, index)| (None, index, val))
} }
} }
} }
@ -894,30 +863,24 @@ impl Engine<'_> {
/// Update the value at an index position in a variable inside the scope /// Update the value at an index position in a variable inside the scope
fn update_indexed_var_in_scope( fn update_indexed_var_in_scope(
idx_src_type: IndexSourceType,
scope: &mut Scope, scope: &mut Scope,
src: ScopeSource, src: ScopeSource,
idx: IndexValue, idx: IndexValue,
new_val: (Dynamic, Position), new_val: (Dynamic, Position),
) -> Result<Dynamic, EvalAltResult> { ) -> Result<Dynamic, EvalAltResult> {
match idx_src_type { let target = scope.get_mut(src);
match &mut target.0 {
// array_id[idx] = val // array_id[idx] = val
IndexSourceType::Array => { Union::Array(arr) => {
let arr = scope.get_mut_by_type::<Array>(src);
arr[idx.as_num()] = new_val.0; arr[idx.as_num()] = new_val.0;
Ok(Dynamic::from_unit())
} }
// map_id[idx] = val // map_id[idx] = val
IndexSourceType::Map => { Union::Map(map) => {
let arr = scope.get_mut_by_type::<Map>(src); map.insert(idx.as_str(), new_val.0);
arr.insert(idx.as_str(), new_val.0);
Ok(Dynamic::from_unit())
} }
// string_id[idx] = val // string_id[idx] = val
IndexSourceType::String => { Union::Str(s) => {
let s = scope.get_mut_by_type::<String>(src);
let pos = new_val.1; let pos = new_val.1;
// Value must be a character // Value must be a character
let ch = new_val let ch = new_val
@ -925,11 +888,12 @@ impl Engine<'_> {
.as_char() .as_char()
.map_err(|_| EvalAltResult::ErrorCharMismatch(pos))?; .map_err(|_| EvalAltResult::ErrorCharMismatch(pos))?;
Self::str_replace_char(s, idx.as_num(), ch); Self::str_replace_char(s, idx.as_num(), ch);
Ok(Dynamic::from_unit())
} }
// All other variable types should be an error
IndexSourceType::Expression => panic!("expression cannot be indexed for update"), _ => panic!("invalid type for indexing: {}", target.type_name()),
} }
Ok(Dynamic::from_unit())
} }
/// Update the value at an index position /// Update the value at an index position
@ -939,14 +903,14 @@ impl Engine<'_> {
new_val: Dynamic, new_val: Dynamic,
pos: Position, pos: Position,
) -> Result<Dynamic, EvalAltResult> { ) -> Result<Dynamic, EvalAltResult> {
match target { match &mut target.0 {
Dynamic(Union::Array(ref mut arr)) => { Union::Array(arr) => {
arr[idx.as_num()] = new_val; arr[idx.as_num()] = new_val;
} }
Dynamic(Union::Map(ref mut map)) => { Union::Map(map) => {
map.insert(idx.as_str(), new_val); map.insert(idx.as_str(), new_val);
} }
Dynamic(Union::Str(ref mut s)) => { Union::Str(s) => {
// Value must be a character // Value must be a character
let ch = new_val let ch = new_val
.as_char() .as_char()
@ -955,7 +919,7 @@ impl Engine<'_> {
Self::str_replace_char(s, idx.as_num(), ch); Self::str_replace_char(s, idx.as_num(), ch);
} }
// All other variable types should be an error // All other variable types should be an error
_ => panic!("array, map or string source type expected for indexing"), _ => panic!("invalid type for indexing: {}", target.type_name()),
} }
Ok(target) Ok(target)
@ -986,7 +950,7 @@ impl Engine<'_> {
let fn_name = make_getter(id); let fn_name = make_getter(id);
self.call_fn_raw(None, fn_lib, &fn_name, &mut [this_ptr], None, *pos, 0) self.call_fn_raw(None, fn_lib, &fn_name, &mut [this_ptr], None, *pos, 0)
.and_then(|val| { .and_then(|val| {
let (_, _, index) = self let (_, index) = self
.get_indexed_value(scope, fn_lib, &val, idx_expr, *op_pos, level)?; .get_indexed_value(scope, fn_lib, &val, idx_expr, *op_pos, level)?;
Self::update_indexed_value(val, index, new_val.0.clone(), new_val.1) Self::update_indexed_value(val, index, new_val.0.clone(), new_val.1)
@ -1030,7 +994,7 @@ impl Engine<'_> {
let fn_name = make_getter(id); let fn_name = make_getter(id);
self.call_fn_raw(None, fn_lib, &fn_name, &mut [this_ptr], None, *pos, 0) self.call_fn_raw(None, fn_lib, &fn_name, &mut [this_ptr], None, *pos, 0)
.and_then(|v| { .and_then(|v| {
let (mut value, _, index) = self.get_indexed_value( let (mut value, index) = self.get_indexed_value(
scope, fn_lib, &v, idx_expr, *op_pos, level, scope, fn_lib, &v, idx_expr, *op_pos, level,
)?; )?;
@ -1111,7 +1075,7 @@ impl Engine<'_> {
// lhs[idx_expr].??? // lhs[idx_expr].???
// TODO - Allow chaining of indexing! // TODO - Allow chaining of indexing!
Expr::Index(lhs, idx_expr, op_pos) => { Expr::Index(lhs, idx_expr, op_pos) => {
let (idx_src_type, src, index, mut target) = let (src, index, mut target) =
self.eval_index_expr(scope, fn_lib, lhs, idx_expr, *op_pos, level)?; self.eval_index_expr(scope, fn_lib, lhs, idx_expr, *op_pos, level)?;
let val_pos = new_val.1; let val_pos = new_val.1;
let this_ptr = &mut target; let this_ptr = &mut target;
@ -1131,7 +1095,6 @@ impl Engine<'_> {
Some(ScopeEntryType::Normal) => { Some(ScopeEntryType::Normal) => {
Self::update_indexed_var_in_scope( Self::update_indexed_var_in_scope(
idx_src_type,
scope, scope,
src.unwrap(), src.unwrap(),
index, index,
@ -1270,7 +1233,7 @@ impl Engine<'_> {
// idx_lhs[idx_expr] = rhs // idx_lhs[idx_expr] = rhs
#[cfg(not(feature = "no_index"))] #[cfg(not(feature = "no_index"))]
Expr::Index(idx_lhs, idx_expr, op_pos) => { Expr::Index(idx_lhs, idx_expr, op_pos) => {
let (idx_src_type, src, index, _) = let (src, index, _) =
self.eval_index_expr(scope, fn_lib, idx_lhs, idx_expr, *op_pos, level)?; self.eval_index_expr(scope, fn_lib, idx_lhs, idx_expr, *op_pos, level)?;
match src.map(|x| x.typ) { match src.map(|x| x.typ) {
@ -1286,7 +1249,6 @@ impl Engine<'_> {
} }
Some(ScopeEntryType::Normal) => Ok(Self::update_indexed_var_in_scope( Some(ScopeEntryType::Normal) => Ok(Self::update_indexed_var_in_scope(
idx_src_type,
scope, scope,
src.unwrap(), src.unwrap(),
index, index,
@ -1317,7 +1279,7 @@ impl Engine<'_> {
#[cfg(not(feature = "no_index"))] #[cfg(not(feature = "no_index"))]
Expr::Index(lhs, idx_expr, op_pos) => self Expr::Index(lhs, idx_expr, op_pos) => self
.eval_index_expr(scope, fn_lib, lhs, idx_expr, *op_pos, level) .eval_index_expr(scope, fn_lib, lhs, idx_expr, *op_pos, level)
.map(|(_, _, _, x)| x), .map(|(_, _, x)| x),
#[cfg(not(feature = "no_object"))] #[cfg(not(feature = "no_object"))]
Expr::Dot(lhs, rhs, _) => self.get_dot_val(scope, fn_lib, lhs, rhs, level), Expr::Dot(lhs, rhs, _) => self.get_dot_val(scope, fn_lib, lhs, rhs, level),