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