Simplify code by removing redirections.

This commit is contained in:
Stephen Chung 2020-02-29 17:10:51 +08:00
parent 8723eedca9
commit c9daab3754
2 changed files with 72 additions and 72 deletions

View File

@ -36,7 +36,7 @@ pub enum EvalAltResult {
impl EvalAltResult {
fn as_str(&self) -> Option<&str> {
Some(match *self {
Some(match self {
EvalAltResult::ErrorCantOpenScriptFile(ref s)
| EvalAltResult::ErrorVariableNotFound(ref s)
| EvalAltResult::ErrorFunctionNotFound(ref s)
@ -51,22 +51,22 @@ impl PartialEq for EvalAltResult {
use EvalAltResult::*;
match (self, other) {
(&ErrorParseError(ref a), &ErrorParseError(ref b)) => a == b,
(&ErrorFunctionNotFound(ref a), &ErrorFunctionNotFound(ref b)) => a == b,
(&ErrorFunctionArgMismatch, &ErrorFunctionArgMismatch) => true,
(&ErrorIndexMismatch, &ErrorIndexMismatch) => true,
(&ErrorArrayMismatch, &ErrorArrayMismatch) => true,
(&ErrorArrayOutOfBounds(max1, index1), &ErrorArrayOutOfBounds(max2, index2)) => {
(ErrorParseError(ref a), ErrorParseError(ref b)) => a == b,
(ErrorFunctionNotFound(ref a), ErrorFunctionNotFound(ref b)) => a == b,
(ErrorFunctionArgMismatch, ErrorFunctionArgMismatch) => true,
(ErrorIndexMismatch, ErrorIndexMismatch) => true,
(ErrorArrayMismatch, ErrorArrayMismatch) => true,
(ErrorArrayOutOfBounds(max1, index1), ErrorArrayOutOfBounds(max2, index2)) => {
max1 == max2 && index1 == index2
}
(&ErrorIfGuardMismatch, &ErrorIfGuardMismatch) => true,
(&ErrorForMismatch, &ErrorForMismatch) => true,
(&ErrorVariableNotFound(ref a), &ErrorVariableNotFound(ref b)) => a == b,
(&ErrorAssignmentToUnknownLHS, &ErrorAssignmentToUnknownLHS) => true,
(&ErrorMismatchOutputType(ref a), &ErrorMismatchOutputType(ref b)) => a == b,
(&ErrorCantOpenScriptFile(ref a), &ErrorCantOpenScriptFile(ref b)) => a == b,
(&ErrorMalformedDotExpression, &ErrorMalformedDotExpression) => true,
(&LoopBreak, &LoopBreak) => true,
(ErrorIfGuardMismatch, ErrorIfGuardMismatch) => true,
(ErrorForMismatch, ErrorForMismatch) => true,
(ErrorVariableNotFound(ref a), ErrorVariableNotFound(ref b)) => a == b,
(ErrorAssignmentToUnknownLHS, ErrorAssignmentToUnknownLHS) => true,
(ErrorMismatchOutputType(ref a), ErrorMismatchOutputType(ref b)) => a == b,
(ErrorCantOpenScriptFile(ref a), ErrorCantOpenScriptFile(ref b)) => a == b,
(ErrorMalformedDotExpression, ErrorMalformedDotExpression) => true,
(LoopBreak, LoopBreak) => true,
_ => false,
}
}
@ -74,16 +74,18 @@ impl PartialEq for EvalAltResult {
impl Error for EvalAltResult {
fn description(&self) -> &str {
match *self {
match self {
EvalAltResult::ErrorParseError(ref p) => p.description(),
EvalAltResult::ErrorFunctionNotFound(_) => "Function not found",
EvalAltResult::ErrorFunctionArgMismatch => "Function argument types do not match",
EvalAltResult::ErrorIndexMismatch => "Array access expects integer index",
EvalAltResult::ErrorArrayMismatch => "Indexing can only be performed on an array",
EvalAltResult::ErrorArrayOutOfBounds(_, index) if index < 0 => {
EvalAltResult::ErrorArrayOutOfBounds(_, ref index) if *index < 0 => {
"Array access expects non-negative index"
}
EvalAltResult::ErrorArrayOutOfBounds(max, _) if max == 0 => "Access of empty array",
EvalAltResult::ErrorArrayOutOfBounds(ref max, _) if *max == 0 => {
"Access of empty array"
}
EvalAltResult::ErrorArrayOutOfBounds(_, _) => "Array index out of bounds",
EvalAltResult::ErrorIfGuardMismatch => "If guards expect boolean expression",
EvalAltResult::ErrorForMismatch => "For loops expect array",
@ -330,8 +332,8 @@ impl Engine {
) -> Result<Dynamic, EvalAltResult> {
use std::iter::once;
match *dot_rhs {
Expr::FunctionCall(ref fn_name, ref args) => {
match dot_rhs {
Expr::FunctionCall(fn_name, args) => {
let mut args: Array = args
.iter()
.map(|arg| self.eval_expr(scope, arg))
@ -342,12 +344,12 @@ impl Engine {
self.call_fn_raw(fn_name.to_owned(), args)
}
Expr::Identifier(ref id) => {
Expr::Identifier(id) => {
let get_fn_name = "get$".to_string() + id;
self.call_fn_raw(get_fn_name, vec![this_ptr])
}
Expr::Index(ref id, ref idx_raw) => {
Expr::Index(id, idx_raw) => {
let idx = self.eval_expr(scope, idx_raw)?;
let get_fn_name = "get$".to_string() + id;
@ -368,7 +370,7 @@ impl Engine {
.ok_or(EvalAltResult::ErrorArrayOutOfBounds(arr.len(), x)),
})
}
Expr::Dot(ref inner_lhs, ref inner_rhs) => match **inner_lhs {
Expr::Dot(inner_lhs, inner_rhs) => match **inner_lhs {
Expr::Identifier(ref id) => {
let get_fn_name = "get$".to_string() + id;
self.call_fn_raw(get_fn_name, vec![this_ptr])
@ -392,7 +394,7 @@ impl Engine {
.iter_mut()
.enumerate()
.rev()
.find(|&(_, &mut (ref name, _))| *id == *name)
.find(|&(_, &mut (ref name, _))| id == name)
.ok_or_else(|| EvalAltResult::ErrorVariableNotFound(id.to_owned()))
.and_then(move |(idx, &mut (_, ref mut val))| map(val.as_mut()).map(|val| (idx, val)))
}
@ -431,8 +433,8 @@ impl Engine {
dot_lhs: &Expr,
dot_rhs: &Expr,
) -> Result<Dynamic, EvalAltResult> {
match *dot_lhs {
Expr::Identifier(ref id) => {
match dot_lhs {
Expr::Identifier(id) => {
let (sc_idx, mut target) = Self::search_scope(scope, id, |x| Ok(x.into_dynamic()))?;
let value = self.get_dot_val_helper(scope, target.as_mut(), dot_rhs);
@ -442,7 +444,7 @@ impl Engine {
value
}
Expr::Index(ref id, ref idx_raw) => {
Expr::Index(id, idx_raw) => {
let (sc_idx, idx, mut target) = self.array_value(scope, id, idx_raw)?;
let value = self.get_dot_val_helper(scope, target.as_mut(), dot_rhs);
@ -462,12 +464,12 @@ impl Engine {
dot_rhs: &Expr,
mut source_val: Dynamic,
) -> Result<Dynamic, EvalAltResult> {
match *dot_rhs {
Expr::Identifier(ref id) => {
match dot_rhs {
Expr::Identifier(id) => {
let set_fn_name = "set$".to_string() + id;
self.call_fn_raw(set_fn_name, vec![this_ptr, source_val.as_mut()])
}
Expr::Dot(ref inner_lhs, ref inner_rhs) => match **inner_lhs {
Expr::Dot(inner_lhs, inner_rhs) => match **inner_lhs {
Expr::Identifier(ref id) => {
let get_fn_name = "get$".to_string() + id;
self.call_fn_raw(get_fn_name, vec![this_ptr])
@ -494,8 +496,8 @@ impl Engine {
dot_rhs: &Expr,
source_val: Dynamic,
) -> Result<Dynamic, EvalAltResult> {
match *dot_lhs {
Expr::Identifier(ref id) => {
match dot_lhs {
Expr::Identifier(id) => {
let (sc_idx, mut target) = Self::search_scope(scope, id, |x| Ok(x.into_dynamic()))?;
let value = self.set_dot_val_helper(target.as_mut(), dot_rhs, source_val);
@ -505,7 +507,7 @@ impl Engine {
value
}
Expr::Index(ref id, ref idx_raw) => {
Expr::Index(id, idx_raw) => {
let (sc_idx, idx, mut target) = self.array_value(scope, id, idx_raw)?;
let value = self.set_dot_val_helper(target.as_mut(), dot_rhs, source_val);
@ -520,29 +522,27 @@ impl Engine {
}
fn eval_expr(&self, scope: &mut Scope, expr: &Expr) -> Result<Dynamic, EvalAltResult> {
match *expr {
Expr::IntegerConstant(i) => Ok(Box::new(i)),
Expr::FloatConstant(i) => Ok(Box::new(i)),
Expr::StringConstant(ref s) => Ok(Box::new(s.clone())),
Expr::CharConstant(ref c) => Ok(Box::new(*c)),
Expr::Identifier(ref id) => {
match expr {
Expr::IntegerConstant(i) => Ok(Box::new(*i)),
Expr::FloatConstant(i) => Ok(Box::new(*i)),
Expr::StringConstant(s) => Ok(Box::new(s.clone())),
Expr::CharConstant(c) => Ok(Box::new(*c)),
Expr::Identifier(id) => {
for &mut (ref name, ref mut val) in &mut scope.iter_mut().rev() {
if *id == *name {
if id == name {
return Ok(val.clone());
}
}
Err(EvalAltResult::ErrorVariableNotFound(id.clone()))
}
Expr::Index(ref id, ref idx_raw) => {
self.array_value(scope, id, idx_raw).map(|(_, _, x)| x)
}
Expr::Assignment(ref id, ref rhs) => {
Expr::Index(id, idx_raw) => self.array_value(scope, id, idx_raw).map(|(_, _, x)| x),
Expr::Assignment(ref id, rhs) => {
let rhs_val = self.eval_expr(scope, rhs)?;
match **id {
Expr::Identifier(ref n) => {
for &mut (ref name, ref mut val) in &mut scope.iter_mut().rev() {
if *n == *name {
if n == name {
*val = rhs_val;
return Ok(Box::new(()));
@ -551,10 +551,10 @@ impl Engine {
Err(EvalAltResult::ErrorVariableNotFound(n.clone()))
}
Expr::Index(ref id, ref idx_raw) => {
let idx = self.eval_expr(scope, idx_raw)?;
let idx = self.eval_expr(scope, &idx_raw)?;
for &mut (ref name, ref mut val) in &mut scope.iter_mut().rev() {
if *id == *name {
if id == name {
return if let Some(&i) = idx.downcast_ref::<i64>() {
if let Some(arr_typed) =
(*val).downcast_mut() as Option<&mut Array>
@ -587,8 +587,8 @@ impl Engine {
_ => Err(EvalAltResult::ErrorAssignmentToUnknownLHS),
}
}
Expr::Dot(ref lhs, ref rhs) => self.get_dot_val(scope, lhs, rhs),
Expr::Array(ref contents) => {
Expr::Dot(lhs, rhs) => self.get_dot_val(scope, lhs, rhs),
Expr::Array(contents) => {
let mut arr = Vec::new();
for item in &(*contents) {
@ -598,7 +598,7 @@ impl Engine {
Ok(Box::new(arr))
}
Expr::FunctionCall(ref fn_name, ref args) => self.call_fn_raw(
Expr::FunctionCall(fn_name, args) => self.call_fn_raw(
fn_name.to_owned(),
args.iter()
.map(|ex| self.eval_expr(scope, ex))
@ -614,9 +614,9 @@ impl Engine {
}
fn eval_stmt(&self, scope: &mut Scope, stmt: &Stmt) -> Result<Dynamic, EvalAltResult> {
match *stmt {
Stmt::Expr(ref e) => self.eval_expr(scope, e),
Stmt::Block(ref b) => {
match stmt {
Stmt::Expr(e) => self.eval_expr(scope, e),
Stmt::Block(b) => {
let prev_len = scope.len();
let mut last_result: Result<Dynamic, EvalAltResult> = Ok(Box::new(()));
@ -634,7 +634,7 @@ impl Engine {
last_result
}
Stmt::If(ref guard, ref body) => {
Stmt::If(guard, body) => {
let guard_result = self.eval_expr(scope, guard)?;
match guard_result.downcast::<bool>() {
Ok(g) => {
@ -647,7 +647,7 @@ impl Engine {
Err(_) => Err(EvalAltResult::ErrorIfGuardMismatch),
}
}
Stmt::IfElse(ref guard, ref body, ref else_body) => {
Stmt::IfElse(guard, body, else_body) => {
let guard_result = self.eval_expr(scope, guard)?;
match guard_result.downcast::<bool>() {
Ok(g) => {
@ -660,7 +660,7 @@ impl Engine {
Err(_) => Err(EvalAltResult::ErrorIfGuardMismatch),
}
}
Stmt::While(ref guard, ref body) => loop {
Stmt::While(guard, body) => loop {
let guard_result = self.eval_expr(scope, guard)?;
match guard_result.downcast::<bool>() {
Ok(g) => {
@ -677,14 +677,14 @@ impl Engine {
Err(_) => return Err(EvalAltResult::ErrorIfGuardMismatch),
}
},
Stmt::Loop(ref body) => loop {
Stmt::Loop(body) => loop {
match self.eval_stmt(scope, body) {
Err(EvalAltResult::LoopBreak) => return Ok(Box::new(())),
Err(x) => return Err(x),
_ => (),
}
},
Stmt::For(ref name, ref expr, ref body) => {
Stmt::For(name, expr, body) => {
let arr = self.eval_expr(scope, expr)?;
let tid = Any::type_id(&*arr);
if let Some(iter_fn) = self.type_iterators.get(&tid) {
@ -706,13 +706,13 @@ impl Engine {
}
Stmt::Break => Err(EvalAltResult::LoopBreak),
Stmt::Return => Err(EvalAltResult::Return(Box::new(()))),
Stmt::ReturnWithVal(ref a) => {
Stmt::ReturnWithVal(a) => {
let result = self.eval_expr(scope, a)?;
Err(EvalAltResult::Return(result))
}
Stmt::Let(ref name, ref init) => {
match *init {
Some(ref v) => {
Stmt::Let(name, init) => {
match init {
Some(v) => {
let i = self.eval_expr(scope, v)?;
scope.push((name.clone(), i));
}

View File

@ -1074,11 +1074,11 @@ fn parse_array_expr<'a>(input: &mut Peekable<TokenIterator<'a>>) -> Result<Expr,
fn parse_primary<'a>(input: &mut Peekable<TokenIterator<'a>>) -> Result<Expr, ParseError> {
match input.next() {
Some((token, line, pos)) => match token {
Token::IntegerConstant(ref x) => Ok(Expr::IntegerConstant(*x)),
Token::FloatConstant(ref x) => Ok(Expr::FloatConstant(*x)),
Token::StringConst(ref s) => Ok(Expr::StringConstant(s.clone())),
Token::CharConstant(ref c) => Ok(Expr::CharConstant(*c)),
Token::Identifier(ref s) => parse_ident_expr(s.clone(), input),
Token::IntegerConstant(x) => Ok(Expr::IntegerConstant(x)),
Token::FloatConstant(x) => Ok(Expr::FloatConstant(x)),
Token::StringConst(s) => Ok(Expr::StringConstant(s)),
Token::CharConstant(c) => Ok(Expr::CharConstant(c)),
Token::Identifier(s) => parse_ident_expr(s, input),
Token::LeftParen => parse_paren_expr(input),
Token::LeftBracket => parse_array_expr(input),
Token::True => Ok(Expr::True),
@ -1312,7 +1312,7 @@ fn parse_for<'a>(input: &mut Peekable<TokenIterator<'a>>) -> Result<Stmt, ParseE
input.next();
let name = match input.next() {
Some((Token::Identifier(ref s), _, _)) => s.clone(),
Some((Token::Identifier(s), _, _)) => s,
Some((token, line, pos)) => {
return Err(ParseError(PERR::VarExpectsIdentifier(token), line, pos))
}
@ -1338,7 +1338,7 @@ fn parse_var<'a>(input: &mut Peekable<TokenIterator<'a>>) -> Result<Stmt, ParseE
input.next();
let name = match input.next() {
Some((Token::Identifier(ref s), _, _)) => s.clone(),
Some((Token::Identifier(s), _, _)) => s,
Some((token, line, pos)) => {
return Err(ParseError(PERR::VarExpectsIdentifier(token), line, pos))
}
@ -1429,7 +1429,7 @@ fn parse_fn<'a>(input: &mut Peekable<TokenIterator<'a>>) -> Result<FnDef, ParseE
input.next();
let name = match input.next() {
Some((Token::Identifier(ref s), _, _)) => s.clone(),
Some((Token::Identifier(s), _, _)) => s,
Some((token, line, pos)) => return Err(ParseError(PERR::FnMissingName(token), line, pos)),
None => return Err(ParseError(PERR::FnMissingName(Token::None), 0, 0)),
};
@ -1457,8 +1457,8 @@ fn parse_fn<'a>(input: &mut Peekable<TokenIterator<'a>>) -> Result<FnDef, ParseE
match input.next() {
Some((Token::RightParen, _, _)) => break,
Some((Token::Comma, _, _)) => (),
Some((Token::Identifier(ref s), _, _)) => {
params.push(s.clone());
Some((Token::Identifier(s), _, _)) => {
params.push(s);
}
Some((_, line, pos)) => return Err(ParseError(PERR::MalformedCallExpr, line, pos)),
None => return Err(ParseError(PERR::MalformedCallExpr, 0, 0)),