Merge branch 'master' into namespace

This commit is contained in:
Stephen Chung
2020-05-05 20:42:16 +08:00
5 changed files with 144 additions and 23 deletions

View File

@@ -70,6 +70,7 @@ pub const KEYWORD_EVAL: &str = "eval";
pub const FUNC_TO_STRING: &str = "to_string";
pub const FUNC_GETTER: &str = "get$";
pub const FUNC_SETTER: &str = "set$";
pub const FUNC_INDEXER: &str = "$index$";
/// A type that encapsulates a mutation target for an expression with side effects.
enum Target<'a> {
@@ -521,6 +522,11 @@ impl Engine {
});
}
// Return default value (if any)
if let Some(val) = def_val {
return Ok(val.clone());
}
// Getter function not found?
if let Some(prop) = extract_prop_from_getter(fn_name) {
return Err(Box::new(EvalAltResult::ErrorDotExpr(
@@ -537,17 +543,20 @@ impl Engine {
)));
}
// Return default value (if any)
if let Some(val) = def_val {
return Ok(val.clone());
}
// Raise error
let types_list: Vec<_> = args
.iter()
.map(|name| self.map_type_name(name.type_name()))
.collect();
// Getter function not found?
if fn_name == FUNC_INDEXER {
return Err(Box::new(EvalAltResult::ErrorFunctionNotFound(
format!("[]({})", types_list.join(", ")),
pos,
)));
}
// Raise error
Err(Box::new(EvalAltResult::ErrorFunctionNotFound(
format!("{} ({})", fn_name, types_list.join(", ")),
pos,
@@ -729,20 +738,20 @@ impl Engine {
Expr::Index(idx, idx_rhs, pos) => {
let is_index = matches!(rhs, Expr::Index(_,_,_));
let indexed_val = self.get_indexed_mut(obj, idx_val, idx.position(), op_pos, false)?;
let indexed_val = self.get_indexed_mut(fn_lib, obj, idx_val, idx.position(), op_pos, false)?;
self.eval_dot_index_chain_helper(
fn_lib, indexed_val, idx_rhs.as_ref(), idx_values, is_index, *pos, level, new_val
)
}
// xxx[rhs] = new_val
_ if new_val.is_some() => {
let mut indexed_val = self.get_indexed_mut(obj, idx_val, rhs.position(), op_pos, true)?;
let mut indexed_val = self.get_indexed_mut(fn_lib, obj, idx_val, rhs.position(), op_pos, true)?;
indexed_val.set_value(new_val.unwrap(), rhs.position())?;
Ok((Default::default(), true))
}
// xxx[rhs]
_ => self
.get_indexed_mut(obj, idx_val, rhs.position(), op_pos, false)
.get_indexed_mut(fn_lib, obj, idx_val, rhs.position(), op_pos, false)
.map(|v| (v.clone_into_dynamic(), false))
}
} else {
@@ -762,14 +771,14 @@ impl Engine {
// {xxx:map}.id = ???
Expr::Property(id, pos) if obj.is::<Map>() && new_val.is_some() => {
let mut indexed_val =
self.get_indexed_mut(obj, id.to_string().into(), *pos, op_pos, true)?;
self.get_indexed_mut(fn_lib, obj, id.to_string().into(), *pos, op_pos, true)?;
indexed_val.set_value(new_val.unwrap(), rhs.position())?;
Ok((Default::default(), true))
}
// {xxx:map}.id
Expr::Property(id, pos) if obj.is::<Map>() => {
let indexed_val =
self.get_indexed_mut(obj, id.to_string().into(), *pos, op_pos, false)?;
self.get_indexed_mut(fn_lib, obj, id.to_string().into(), *pos, op_pos, false)?;
Ok((indexed_val.clone_into_dynamic(), false))
}
// xxx.id = ??? a
@@ -791,7 +800,7 @@ impl Engine {
let is_index = matches!(rhs, Expr::Index(_,_,_));
let indexed_val = if let Expr::Property(id, pos) = dot_lhs.as_ref() {
self.get_indexed_mut(obj, id.to_string().into(), *pos, op_pos, false)?
self.get_indexed_mut(fn_lib, obj, id.to_string().into(), *pos, op_pos, false)?
} else {
// Syntax error
return Err(Box::new(EvalAltResult::ErrorDotExpr(
@@ -955,8 +964,9 @@ impl Engine {
/// Get the value at the indexed position of a base type
fn get_indexed_mut<'a>(
&self,
fn_lib: &FunctionsLib,
val: &'a mut Dynamic,
idx: Dynamic,
mut idx: Dynamic,
idx_pos: Position,
op_pos: Position,
create: bool,
@@ -1029,11 +1039,18 @@ impl Engine {
}
}
// Error - cannot be indexed
_ => Err(Box::new(EvalAltResult::ErrorIndexingType(
type_name.to_string(),
op_pos,
))),
_ => {
let args = &mut [val, &mut idx];
self.exec_fn_call(fn_lib, FUNC_INDEXER, args, None, op_pos, 0)
.map(|v| v.into())
.map_err(|_| {
Box::new(EvalAltResult::ErrorIndexingType(
// Error - cannot be indexed
type_name.to_string(),
op_pos,
))
})
}
}
}